Initial working fully go release
This commit is contained in:
+21
-18
@@ -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
|
||||
}
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user