Initial working fully go release

This commit is contained in:
Martino Ferrari
2026-04-30 23:01:01 +02:00
parent 6e51ffc5e1
commit 90669c5fd6
22 changed files with 2950 additions and 196 deletions
+21 -18
View File
@@ -85,7 +85,7 @@ func caString(b []byte) string {
return string(b[:idx])
}
// DBR_TIME_* wire layouts (all big-endian):
// DBR_TIME_* wire layouts (all big-endian, matching EPICS db_access.h structs):
//
// Common header (12 bytes):
// [0:2] int16 status
@@ -93,13 +93,13 @@ func caString(b []byte) string {
// [4:8] uint32 secPastEpoch
// [8:12] uint32 nsec
//
// DBR_TIME_DOUBLE (type 25): 4-byte RISC pad at [12:16], float64 at [16:24]. Total=24.
// DBR_TIME_FLOAT (type 20): float32 at [12:16]. Total=16.
// DBR_TIME_LONG (type 22): int32 at [12:16]. Total=16.
// DBR_TIME_SHORT (type 19): int16 at [12:14], 2-byte pad [14:16]. Total=16.
// DBR_TIME_ENUM (type 23): uint16 at [12:14], 2-byte pad [14:16]. Total=16.
// DBR_TIME_CHAR (type 24): uint8 at [12:13], 3-byte pad [13:16]. Total=16.
// DBR_TIME_STRING (type 21): [40]byte at [12:52]. Total=52.
// DBR_TIME_STRING (type 14): [40]byte at [12:52]. Total=52.
// DBR_TIME_SHORT (type 15): 2-byte RISC pad at [12:14], int16 at [14:16]. Total=16.
// DBR_TIME_FLOAT (type 16): float32 at [12:16]. Total=16.
// DBR_TIME_ENUM (type 17): 2-byte RISC pad at [12:14], uint16 at [14:16]. Total=16.
// DBR_TIME_CHAR (type 18): RISC_pad0[12:14], RISC_pad1[14], uint8 at [15]. Total=16.
// DBR_TIME_LONG (type 19): int32 at [12:16]. Total=16.
// DBR_TIME_DOUBLE (type 20): 4-byte RISC pad at [12:16], float64 at [16:24]. Total=24.
// DecodeTimeValue decodes a DBR_TIME_* payload.
// dbrType is one of the DBRTime* constants; payload is the full message payload
@@ -158,24 +158,27 @@ func DecodeTimeValue(dbrType uint16, count uint32, payload []byte) (TimeValue, b
tv.Double = float64(tv.Long)
case DBRTimeShort:
// 2-byte RISC pad at [12:14], value at [14:16]
if len(payload) < 16 {
return TimeValue{}, false
}
tv.Short = int16(binary.BigEndian.Uint16(payload[12:]))
tv.Short = int16(binary.BigEndian.Uint16(payload[14:]))
tv.Double = float64(tv.Short)
case DBRTimeEnum:
// 2-byte RISC pad at [12:14], value at [14:16]
if len(payload) < 16 {
return TimeValue{}, false
}
tv.Enum = binary.BigEndian.Uint16(payload[12:])
tv.Enum = binary.BigEndian.Uint16(payload[14:])
tv.Double = float64(tv.Enum)
case DBRTimeChar:
// RISC_pad0[12:14], RISC_pad1[14], value[15] per db_access.h dbr_time_char
if len(payload) < 16 {
return TimeValue{}, false
}
tv.Char = payload[12]
tv.Char = payload[15]
tv.Double = float64(tv.Char)
case DBRTimeString:
@@ -427,15 +430,15 @@ func EncodeString(v string) []byte {
// EncodeEventMask builds the 16-byte payload for a CA_PROTO_EVENT_ADD request.
// mask is typically DBEDefault (DBEValue | DBEAlarm).
//
// Wire layout (16 bytes, all big-endian):
// Wire layout matches caProto.h struct mon_info (all big-endian):
//
// [0:4] float32 m_lval (not used, zero)
// [4:8] float32 p_delta (delta trigger, zero = disabled)
// [8:12] float32 p_final (final trigger, zero = disabled)
// [12:14] int16 p_count (element count, zero = use PV's count)
// [14:16] int16 m_mask (DBE_VALUE | DBE_ALARM | ...)
// [0:4] float32 m_lval (low delta, zero = disabled)
// [4:8] float32 m_hval (high delta, zero = disabled)
// [8:12] float32 m_toval (period between samples, zero = disabled)
// [12:14] uint16 m_mask (DBE_VALUE | DBE_ALARM | ...)
// [14:16] uint16 m_pad (alignment padding)
func EncodeEventMask(mask uint16) []byte {
b := make([]byte, 16)
binary.BigEndian.PutUint16(b[14:], mask) // m_mask is at offset 14, not 12
binary.BigEndian.PutUint16(b[12:], mask) // m_mask is at offset 12 per caProto.h
return b
}
+8 -7
View File
@@ -74,14 +74,15 @@ const (
)
// DBR_TIME_* types (value + timestamp + alarm status; used in EVENT_ADD).
// Numbers from db_access.h: STRING=14, SHORT/INT=15, FLOAT=16, ENUM=17, CHAR=18, LONG=19, DOUBLE=20.
const (
DBRTimeString = 21
DBRTimeShort = 19
DBRTimeFloat = 20
DBRTimeEnum = 23
DBRTimeChar = 24
DBRTimeLong = 22
DBRTimeDouble = 25
DBRTimeString = 14
DBRTimeShort = 15
DBRTimeFloat = 16
DBRTimeEnum = 17
DBRTimeChar = 18
DBRTimeLong = 19
DBRTimeDouble = 20
)
// DBR_CTRL_* types (full control info: units, limits, enum strings; used in READ_NOTIFY).
+6 -6
View File
@@ -159,7 +159,7 @@ func TestDecodeTimeString(t *testing.T) {
func TestDecodeTimeEnum(t *testing.T) {
hdr := buildTimeHeader(0, 0, 0, 0)
val := []byte{0x00, 0x03, 0x00, 0x00} // enum=3 + 2-byte pad
val := []byte{0x00, 0x00, 0x00, 0x03} // 2-byte RISC pad + enum=3
payload := append(hdr, val...)
tv, ok := proto.DecodeTimeValue(proto.DBRTimeEnum, 1, payload)
@@ -307,14 +307,14 @@ func TestEncodeEventMask(t *testing.T) {
if len(b) != 16 {
t.Fatalf("len = %d, want 16", len(b))
}
// m_mask is at offset 14 (after m_lval[0:4], p_delta[4:8], p_final[8:12], p_count[12:14]).
mask := binary.BigEndian.Uint16(b[14:])
// m_mask is at offset 12 per caProto.h struct mon_info.
mask := binary.BigEndian.Uint16(b[12:])
if mask != proto.DBEDefault {
t.Errorf("mask = 0x%02X, want 0x%02X", mask, proto.DBEDefault)
}
// p_count at [12:14] must be zero.
if pc := binary.BigEndian.Uint16(b[12:]); pc != 0 {
t.Errorf("p_count = %d, want 0", pc)
// m_pad at [14:16] must be zero.
if pad := binary.BigEndian.Uint16(b[14:]); pad != 0 {
t.Errorf("m_pad = %d, want 0", pad)
}
}