Files
uopi/pkg/ca/proto/opcodes.go
T
2026-04-30 23:01:01 +02:00

141 lines
3.9 KiB
Go

// Package proto contains the low-level Channel Access wire-protocol constants,
// header codec, and DBR type decode functions. All types are big-endian as
// required by the CA specification.
package proto
// CA command opcodes (uint16, first field of every message header).
const (
CmdVersion = 0 // version negotiation (first message on every TCP connection)
CmdEventAdd = 1 // subscribe to value updates / server event push
CmdEventCancel = 2 // cancel subscription
CmdWrite = 4 // put value (fire-and-forget, no server reply)
CmdSearch = 6 // UDP: locate IOC hosting a PV
CmdNotFound = 14 // UDP: IOC does not host the requested PV
CmdReadNotify = 15 // get value with callback (async GET)
CmdCreateChan = 18 // create channel on TCP circuit
CmdWriteNotify = 19 // put value with acknowledgement
CmdClientName = 20 // announce client username (sent after VERSION)
CmdHostName = 21 // announce client hostname (sent after VERSION)
CmdAccessRights = 22 // server → client: access rights bitmask
CmdEcho = 23 // heartbeat ping/pong
CmdCreateFail = 26 // server → client: CREATE_CHAN failed
CmdServerDisc = 27 // server → client: server shutting down
)
// CA minor protocol revision announced during the VERSION handshake.
// Corresponds to CA 4.13, supported by EPICS 3.14+ and all EPICS 7 servers.
const MinorVersion = 13
// Default CA port (TCP and UDP).
const DefaultPort = 5064
// Search reply data_type values.
const (
SearchReply = 10 // DO_REPLY: ask server to respond
SearchNoReply = 5 // DONT_REPLY: suppress response (used by repeater)
)
// AccessRights bitmask values (parameter2 of CmdAccessRights message).
const (
AccessRead = 1 << 0
AccessWrite = 1 << 1
)
// DBE event mask bits used in the 16-byte EVENT_ADD payload.
const (
DBEValue = 0x01 // trigger on any value change
DBEAlarm = 0x04 // trigger on alarm state change
DBEDefault = DBEValue | DBEAlarm
)
// ---- DBF field types (native IOC field type, reported in CREATE_CHAN reply) ----
const (
DBFString = 0
DBFShort = 1 // also DBFInt
DBFFloat = 2
DBFEnum = 3
DBFChar = 4
DBFLong = 5
DBFDouble = 6
)
// ---- DBR request types ----
// Plain value types (used in WRITE).
const (
DBRString = 0
DBRShort = 1
DBRFloat = 2
DBREnum = 3
DBRChar = 4
DBRLong = 5
DBRDouble = 6
)
// 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 = 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).
const (
DBRCtrlString = 28
DBRCtrlShort = 29
DBRCtrlFloat = 30
DBRCtrlEnum = 31
DBRCtrlChar = 32
DBRCtrlLong = 33
DBRCtrlDouble = 34
)
// NativeTimeType maps a DBF field type to the corresponding DBR_TIME_* type
// that should be used for monitor subscriptions.
func NativeTimeType(dbfType int, elementCount int) uint16 {
switch dbfType {
case DBFDouble:
return DBRTimeDouble
case DBFFloat:
return DBRTimeFloat
case DBFLong:
return DBRTimeLong
case DBFShort:
return DBRTimeShort
case DBFEnum:
return DBRTimeEnum
case DBFString:
return DBRTimeString
case DBFChar:
if elementCount > 1 {
return DBRTimeString // waveform of chars treated as string
}
return DBRTimeChar
default:
return DBRTimeDouble
}
}
// NativeCtrlType maps a DBF field type to the corresponding DBR_CTRL_* type
// that should be used for metadata gets.
func NativeCtrlType(dbfType int) uint16 {
switch dbfType {
case DBFDouble, DBFFloat:
return DBRCtrlDouble
case DBFLong, DBFShort, DBFChar:
return DBRCtrlLong
case DBFEnum:
return DBRCtrlEnum
case DBFString:
return DBRCtrlString
default:
return DBRCtrlDouble
}
}