V4 CA Protocol Specification
EPICS Channel Access Protocol Specification
EPICS Version: 4
Channel Access Protocol Version: 4.15
Author: Jeff Hill
LA-UR-05-8238
Data Types
- All multi-octet primitive types are transmitted in little endian byte order.
- All signed integers use two's complement arithmetic.
- All floating point numbers shall comply with IEEE floating point standards.
Mnemonic | Data Type | Identifier |
---|---|---|
reserved | 0 | |
INT8 | 8 bit signed integer | 1 |
INT16 | 16 bit signed integer | 2 |
INT32 | 32 bit signed integer | 3 |
INT64 | 64 bit signed integer | 4 |
FLOAT32 | 32 bit IEEE floating point | 5 |
FLOAT64 | 64 bit IEEE floating point | 6 |
FLOAT128 | 128 bit IEEE floating point | 7 |
UTF-8 encoded character string | 8 | |
property sequence description | 9 | |
reserved | 10 - 128 |
Mnemonic | Data Type |
---|---|
UINT8 | 8 bit unsigned integer |
UNIT16 | 16 bit unsigned integer |
UINT32 | 32 bit unsigned integer |
UINT64 | 64 bit unsigned integer |
variable length unsigned integer | |
property transport definition | |
dimension sequence description | |
dimension bounds definition | |
array dimension bound |
UINTN, Variable Length Unsigned Integer
The octets below are in little endian order (least significant bits are transmitted before most significant bits).
Data Type | Bit 7, msb | Bits 7 - 0 |
---|---|---|
OCTET | 0 | Bits 0-7 of unsigned integer value |
Data Type | Bit 7, msb | Bits 7 - 0 |
---|---|---|
OCTET | 1 | Bits 0-7 of unsigned integer value |
OCTET | 0 | Bits 8-15 of unsigned integer value |
Data Type | Bit 7, msb | Bits 7 - 0 |
---|---|---|
OCTET | 1 | Bits 0-7 of unsigned integer value |
OCTET | 1 | Bits 8-15 of unsigned integer value |
OCTET | 0 | Bits 16-23 of unsigned integer value |
After 3 octets, the same pattern repeats.
Data Type | msb | Bits 7 - 0 |
---|---|---|
OCTET | 1 | Bits 0-7 of unsigned integer value |
OCTET | 1 | Bits 8-15 of unsigned integer value |
OCTET | 1 | Bits 16-23 of unsigned integer value |
... | 1 | ... |
OCTET N | 0 | Bits N*8-N*9-1 of unsigned integer value |
STRING, UTF-8 Encoded Character String
Data Type | Purpose |
---|---|
UINTN | the number of UTF-8 tokens |
OCTET sequence | UTF-8 encoded character string sequence |
Nill (zero) termination is not included in the string.
PSD, Property Sequence Description
This data type is used to describe a packed sequence of property values, a property sequence (PS), that might be encapsulated within a subsequent message on the same circuit, or in the same datagram. The order that the properties are described in the sequence is exactly the same as the order that the properties will be pushed onto the wire.
Data Type | Purpose |
---|---|
UINTN | Number of properties in sequence |
N Property transport definitions | See below |
PTD, Property Transport Definition
If the dimension
field is zero then property bounds definitions are not included, and the property transported has a scalar representation.
Data Type | Purpose | Value |
---|---|---|
UINTN | Property Id | Sender defined |
UINTN | Data Type Identifier | Sender defined, not 9 |
DSD | Dimension sequence description | Sender defined |
Data Type | Purpose | Value |
---|---|---|
UINTN | Property Id | Sender defined |
UINTN | Data Type Identifier | 9 |
DSD | Dimension sequence description | Sender defined |
PSD | Property sequence description | Sender defined |
DSD, Dimension Sequence Description
Data Type | Purpose | Value |
---|---|---|
UINTN | Specifies that the data is scalar | 0 |
Data Type | Purpose | Value |
---|---|---|
UINTN | Specifies the number of property bounds definitions for array data | N, not zero |
N X DBD | sequence of N property bounds definitions | Sender defined |
DBD, Dimension Bounds Definition
Data Type | Purpose | Value |
---|---|---|
UINTN | Bound Type | 0, fixed bound |
ADB | Array dimension bound | Sender defined |
Data Type | Purpose | Value |
---|---|---|
UINTN | Bound Type | 1, variable bound |
Packaging of arrays on the wire
If the bound type is fixed, then the dimension does not accompany the array data on the wire. If the bound type is variable then any variable dimension information immediately precedes the data on the wire. The order that any dynamic dimensions are described in the dimension sequence description (DSD) is exactly the same order that any dynamic array dimension bound (ADB) will be pushed on to the wire prior to pushing the array data sequence on to the wire.
ADB, Array Dimension Bound
Data Type | Purpose | Value |
---|---|---|
UINTN | First element index | Sender defined |
UINTN | Element count | Sender defined |
Property Hierarchy Path
<property hierarchy path> := <optional white space> . <optional white space> <property name> <optional white space> [ <property hierarchy path> ]
A "." character is employed to separate components of the property hierarchy path. Should the user need to include the "." in a channel name, they can escape the "." character with a back slash "\" character.
Channel
A channel is defined to be a virtual communication path from a client application to a communication receptacle in a service. The communication receptacle is either a process variable or a message passing interface.
Channel Names
Flat (hierarchy challenged) tools like caGet will need to access a property deeply embedded in the property hierarchy as a simple PV.
Therefore, channel names will have the following format.
<communication receptacle name> [ <property hierarchy path> ]
- This syntax may clash with the current state of the version 4 database design.
Message Transport
The protocol is designed for transport via a full duplex octet stream circuit such as is offered by TCP/IP. Clients initiate circuits with servers. All clients and servers initiating a new outgoing octet stream circuit must insert, prior to any other message, a CA Protocol Initiate
message. Certain requests (see documentation for each request) will also be suitable for datagram transport such as is offered by UDP/IP. The CA Protocol Initiate
message must be the first message in any CA protocol datagram prior to any other message in the datagram.
The protocol is asynchronous, and therefore multiple requests can be outstanding (waiting for a response) at the same time. It is expected that quality implementations will combine several messages together into one network frame.
CA Protocol Initiate
This message overlays a similar purposed message employed by previous versions of the protocol thereby retaining potential for client and server libraries to, at runtime, choose between dispatch tables suitable to different protocol revisions. This allows client and server libraries to communicate with multiple peers using both the EPICS version 3 and the EPICS version 4 protocols.
There is no response to this message.
Data Type | Purpose | Value | ||||
---|---|---|---|---|---|---|
UINT16 | reserved | 0 | ||||
UINT16 | reserved | 0 | ||||
UINT16 | requested server dispatch priority where 0 is the lowest priority (executes last) and 255 is the highest priority (executes first), all other values are reserved |
| ||||
UINT16 | protocol minor revision number | 15 | ||||
UINT32 | magic number | 0x5b43415d == '[' 'C' 'A' ']' | ||||
UNIT32 |
Reserved for virtual circuits. A sequence number incrementing with each successive message for datagrams. Clients use this sequence number to detect duplicates and out of order delivery. |
|
The dispatch priority protocol element is relevant only when a client initiates communication with a server. Servers do not request a dispatch priority within its client, and should set this field to zero.
Request / Response Protocol
Request Messages
Request messages are transmitted only by clients. Servers do not transmit request messages. There are two request message forms depending on whether a response is possible, or not.
Data Type | Purpose | Value |
---|---|---|
UINTN | Request identifier | client defined |
OBJID | Request identifier | client defined, 0 - 31 reserved |
OCTETS | Request payload | request dependent |
Data Type | Purpose | Value |
---|---|---|
UINTN | Request identifier | client defined |
OCTETS | Request payload | request dependent |
Response Messages
Response messages are transmitted only by servers. Clients do not transmit response messages.
Solicited Response Messages
Data Type | Purpose | Value |
---|---|---|
UINTN | request identifier | request defined |
OCTETS | response payload | request dependent |
Unsolicited, or Indirectly Solicited, Response Messages
Exception Response
This indirectly solicited response is sent when a request fails in the server.
Data Type | Purpose | Value |
---|---|---|
UINTN | Request identifier | 0 |
UINTN | Exception identifier | failure dependent, see below |
STRING | Failure context message | failure dependent |
UINTN | Copy of request message length | N, request defined, but zero if failure not caused by a request |
N OCTETS | Copy of request message | request defined |
Status Value | Definition | Severity |
---|---|---|
0 | Insufficient memory to complete request | Warning |
1 | Invalid request identifier | Fatal |
2 | Invalid channel name | Warning |
3 | Invalid channel identifier | Fatal |
4 | Invalid property identifier | Fatal |
5 | Invalid property transport sequence identifier | Fatal |
... |
Server Status Beacon
This request is sent by a server to announce periodically its presence, and availability, on the network. This request might be sent over a virtual circuit, or in a datagram. There is no response. The property transport sequence might be predefined at compile time. It is used to identify the server address (including possibly a TCP port) of the sender, and other (possibly site specific) server state variables.
Data Type | Purpose | Value |
---|---|---|
UINTN | Request identifier | 1 |
UINTN | Property sequence identifier | Sender Defined |
PS | Server status parameters | Sender Defined |
Protocol Encapsulation
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | 0 |
UINTN | Encoding | TBD, but to include an unmodified encoding and at least one standard type of compression encoding |
UINTN | Length | N, compressed protocol sequence length |
N OCTETS | Encapsulated protocol octet sequence | Sender defined, format determined by encoding |
The maximum size of an encapsulation probably needs to be specified.
Compression will be useful only when fast computers communicate or relatively slow links.
Define Channel
The client defines a channel in the server for its future use. There is no response unless the request is invalid, or cant be completed.
If at any time a communication endpoint to which a channel is bound ceases to exist, the server must send an Invalid channel identifier
exception responses to all of the appropriate clients indicating that their channel is attached to a defunct resource. After receiving the Invalid channel identifier
exception the client library is no-longer required to close the relevant channel with the server.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | 1 |
UINTN | Channel Identifier | Sender defined |
STRING | Channel Name | Sender defined |
Expunge Channel
The client must expunge any channel from the server that will no-longer be used.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | |
UINTN | Channel Identifier | Sender defined |
Swap Channel Identifiers
Commands the server to assign the process variable associated with channel identifier one to channel underived two and visa-versa. This functionality allows implementation to dynamically adjust frequently used objects to use smaller integer identifiers, and therefore smaller on-the-wire representations.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | |
UINTN | Request identifier | Sender defined |
UINTN | Channel Identifier one | Sender defined |
UINTN | Channel Identifier two | Sender defined |
Data Type | Purpose | Value |
UINTN | Request identifier | Client defined |
Define Property
The client defines a property in the server for its future use. There is no response unless the request is invalid, or cant be completed. Commonly used properties, especially those used by datagram services, will be predefined thereby avoiding any need to define the property before it is used.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | 2 |
UINTN | Property identifier | Sender defined |
STRING | Property name | Sender defined |
Expunge Property
The client must expunge any property from the server that will no-longer be used.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | |
UINTN | Property Identifier | Sender defined |
Swap Property Identifiers
Commands the server to assign the property associated with property identifier one to property underived two and visa-versa. This functionality allows implementation to dynamically adjust frequently used objects to use smaller integer identifiers, and therefore smaller on-the-wire representations.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | |
UINTN | Request identifier | Sender defined |
UINTN | Property Identifier one | Sender defined |
UINTN | Property Identifier two | Sender defined |
Data Type | Purpose | Value |
UINTN | Request identifier | Client defined |
Define Property Transport Sequence
The client defines a property transport sequence in the server for its future use. A property transport sequence exactly describes a stream of octets that will express a sequence of properties in the primitive type and dimension selected by the client. There is no response unless the request is invalid, or cant be completed.
- Commonly used property transport sequences, especially those used by datagram services, might be predefined thereby avoiding any need to define the property transport sequence before it is used.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | 3 |
UINTN | Property sequence identifier | Sender defined |
PSD | Property sequence description, see above | Sender defined |
Expunge Property Transport Sequence
The client must expunge any property transport sequence from the server that will no-longer be used.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | |
UINTN | Property Transport Sequence Identifier | Sender defined |
Swap Property Transport Sequence Identifiers
Commands the server to assign the property transport sequence associated with property identifier one to property transport sequence identifier two and visa-versa. This functionality allows implementmplementation to dynamically adjust frequently used objects to use smaller integer identifiers, and therefore smaller on-the-wire representations.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | |
UINTN | Request identifier | Sender defined |
UINTN | Property Transport Sequence Identifier one | Sender defined |
UINTN | Property Transport Sequence Identifier two | Sender defined |
Data Type | Purpose | Value |
UINTN | Request identifier | Client defined |
Define IO Request Modifier
Define an IO request modifier. There is no response unless the request is invalid, or cant be completed.
The client must cancel any request trigger specification in the server that will no-longer be used.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | 4 |
UINTN | IO request modifier identifier | Sender defined, see below |
STRING | <IO Request Modifier Expression> | Sender defined, see below |
Value | Purpose | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
0 |
| ||||||||||
1 - 32 | reserved | ||||||||||
N > 32 | client library assigned |
IO Request Modifier Expression
<IO Request Modifier Expression> := <Property Match Expression> <IO Request Attribute List>
<Property Match Expression> := [(] [ [<Property Match Expression>] <Boolean Operator> ] <Property Match Specification> [)]
<IO Request Attribute List> := { <IO Request Attribute> [ <IO Request Attribute List> ] }
<IO Request Attribute> := { <Subscription Modifier>, <Minimum Period Spec>, <Maximum Period Spec>, <Minimum Percent Change Between Updates Spec>,
<Property Match Expression> := <Property Name> <Comparison Operator> { <Property Name>, <Channel Name>, <Constant Expression> }
Here are some examples of IO modifier expressions. Parenthesis may be used to enforce order of operations.
(beamGate == 4 ) && ! ( bpm32.beamGate == 7)
beamGate == 4 && triggerTimeOffset ( 3 sec )
beamGate == 4 && eventQueueLength ( 1 ) maxPeriod ( 4 sec )
eventQueueLength ( 1 ) propertyPath ( limits )
eventQueueLength ( 1 ) propertyPath ( xAxisMotor.limits )
Minimum and Maximum Period (applicable only to subscriptions)
timeSpec := <real number>
maxPeriod ( timeSpec )
minPeriod ( timeSpec )
Minimum Percent Change Between Updates (applicable only to subscriptions)
minPercentChange ( <real number> )
Time Based Extraction Criteria (applicable only to subscriptions)
beginTime ( timeSpec )
endTime ( timeSpec )
Maximum Event Queue Length (applicable only to subscriptions)
eventQueueLength ( <integer number> )
Trigger Time Offset (applicable only to subscriptions)
triggerTimeOffset ( timeSpec )
Property Path
propertyPath ( <property hierarchy path> )
- Attributes controlling queueing versus caching behavior of read and writes are probably specified here. Needs more thought.
- Attributes controlling process passive and maximize severity (or their future functional equivalents) are probably specified here. Needs more thought.
Expunge IO Request Modifier
The client must expunge any IO request modifier from the server that will no-longer be used.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | |
UINTN | IO request modifier identifier | Sender defined |
Swap IO Request Modifier Identifiers
Commands the server to assign the trigger specification associated with property identifier one to trigger intensifier two and visa-versa. This functionality allows implementation to dynamically adjust frequently used objects to use smaller integer identifiers, and therefore smaller on-the-wire representations.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | |
UINTN | Request identifier | Sender defined |
UINTN | IO request modifier identifier one | Sender defined |
UINTN | IO request modifier identifier two | Sender defined |
Data Type | Purpose | Value |
UINTN | Request identifier | Client defined |
Channel Write Without Response
The client writes a property transport sequence to a process variable in the service. There is no response unless the request is invalid, or cant be completed.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | 5 |
UNINT | Channel identifier | Sender defined |
UINTN | Property sequence identifier of payload | Sender defined |
UINTN | IO request modifier identifier | Sender defined |
PS | Property payload to be written | Sender defined |
Channel Write With Response
The client writes a property transport sequence to a process variable in the service. There is always a response. A successful response indicates that the request, and all side effects, have completed. An unsuccessful response is an exception response (see above). It indicates that the request could not be completed in entirety, and that the internal state of the channel has not been modified.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | 6 |
UINTN | Request identifier | Sender defined |
UINTN | Channel identifier | Sender defined |
UINTN | Property sequence identifier of payload | Sender defined |
UINTN | IO request modifier identifier | Sender defined |
PS | Property payload to be written | Sender defined |
Data Type | Purpose | Value |
UINTN | Request identifier | Client defined |
Channel Read or Subscribe
The client reads a property transport sequence from a process variable in the service. If the request identifier is 7, there is only one response. Otherwise, if the request identifier is 8, a subscription is created and multiple responses are expected. A successful response includes the specified property transport sequence identifying the current state of the channel when the request was executed by the server. An unsuccessful response is an exception response (see above).
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | 7 or 8 |
UINTN | Request identifier | Sender defined |
UINTN | Channel identifier | Sender defined |
UINTN | Property sequence identifier of response payload | Sender defined |
UINTN | IO request modifier identifier | Sender defined |
Data Type | Purpose | Value |
---|---|---|
UINTN | Request identifier | Client defined |
PS | Property payload read | Client formatted, server defined |
Channel Command
The client sends a command to a message passing interface in the service. A request in the form of a property transport sequence is sent to the message passing interface in the service, and the message passing interface responds with another property transport sequence.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | 9 |
UINTN | Request identifier | Sender defined |
UINTN | Channel identifier | Sender defined |
UINTN | Request property sequence payload identifier | Sender defined |
UINTN | Response property sequence payload identifier | Sender defined |
UINTN | IO request modifier identifier | Sender defined |
PS | Request property payload | Sender defined |
Data Type | Purpose | Value |
---|---|---|
UINTN | Request identifier | Client defined |
PS | Response property payload | Client formatted, server defined |
Cancel Request
Cancel a request in progress. There is no response.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | 10 |
UINTN | Request identifier | identifier of the request to be canceled |
Server Verify
Verify that the server is responsive.
This request might also be accepted to by a datagram server. Typically, a response is mandatory, but a datagram server must never respond to any request of this type in a datagram sent to a broadcast or multicast address.
The property transport sequence is used to identify the condition of the server, and other (possibly site specific) server state variables.
Data Type | Purpose | Value |
---|---|---|
UINTN | Directive | 11 |
UINTN | Request identifier | Sender defined |
UINTN | Property sequence identifier | Sender defined |
Data Type | Purpose | Value |
---|---|---|
OBJID | Request identifier | Client defined |
PS | Server status parameters | Client formatted, server defined |
Design Notes
- A fundamental choice of this design was that all identifiers are assigned by the client. This tends to make state change logic simpler in the client library and, since the server's identifier need not be returned in a response to the client, there will also be less TCP return pipe traffic during setup.
The server might continue to have only one hash table keyed by an {object id, client id} pair. Hopefully, the bucket use distribution for this table can be managed to be reasonably uniform. This type of keying probably slightly increases hashing and distribution overhead so, alternatively, there could be one hash table in the server for each client, contingent possibly on upgraded memory management for the hash table implementation. There is a chance that a request to define a channel will be sent to a server that does not have the named communication receptacle. In that situation the server will send the client an exception, and respond to any subsequent requests specifying a bogus channel identifier with an exception message. The unfortunate drawback to this approach will be the opportunity for a client to briefly think that it is connected when it isn't. We are currently ensuring that disconnect notification arrives within NNN seconds so perhaps brief windows of uncertainty are not unreasonable. Also, this window of uncertainty would exist prior to arrival of the first monitor update so any client that watches the magnitude of a channel should remain in a safe state.
- The flow-control functionality in previous versions of the CA protocol was probably only relevant to GUI applications. It is superseded in this version of the protocol by capabilities allowing clients to set the subscription event queue length?
- Server beacons are used to efficiently inform multiple clients about server state of health while using minimum bandwidth. Multicasts/broadcasts are typically the lowest bandwidth consuming option when sending one message to multiple clients. Server beacons are used to A) inform clients when a newly accessible IOC joins the network, and B) periodically communicate tangible indication of responsiveness to clients with idle TCP circuits.
In this version of the protocol hopefully beacons will be issued using multicast addresses thereby eliminating any need for the CA Repeater daemon. In this version of the protocol additional server state of health properties might be included in the beacon message.
- The current baseline is to not include messages in the CA protocol for authentication purposes. Instead, we prefer to use transport protocol facilities for coarse host based authentication, and integrate public domain kerberos libraries (or some other equivalent) for stronger forms of authentication including user based authentication.
- The current baseline is to employ subordinate properties to communicate the current state of the access rights for a channel.
Will access rights properties need to show up in multiple places in the property hierarchy in order that the access rights might vary depending on what properties are accessed? If so, then how can we provide a consistent interface for clients so that they always know where to find the access rights in the property hierarchy?
- Users will need to monitor the connection state of channels.
Within the protocol there is a channel disconnect exception designating a service disconnect. There might also be a transport circuit disconnect. The user will probably subscribe at the client programming interface for connection state change callbacks using the subscription mechanism. The client library will trap the appropriate exceptions and circuit disconnect state changes forwarding them as synthesized subscription update callbacks at the programming interface.
- The queueing versus caching behavior of write request sent to a channel will be modified by specifying a specialized IO request modifier with the write request.
- The EPICS function block database's process passive and maximize severity link attributes (or their future equivalents) will be manipulated by specifying a specialized IO request modifier.
- It will be necessary to introspect all of (or a subset of) the properties that are available in a channel. This will be accomplished by reading the
propertyList
property of the channel and requesting primitive typePSD
orSTRING
. - There will be situations where the client will prefer to create one channel, but index any part of the property hierarchy. This will be done by specifying the property path in a relevant IO request modifier.
- It will probably also be necessary to obtain a list of all of the communication receptacles in a server. This might be accomplished by sending a request / response command to a specialized PV. Wild cards could be specified in the request parameters and the channel list could be delivered in the response parameters.
- Within future EPICS systems a special property accompanying state change update notification payloads must efficiently indicate the type of state change that has occurred. For example, there are currently "default dead-band state change excursion", "archive dead-band state change excursion", and "alarm state change" state change identifying events. This information will be needed, for example, to improve the implementation of the CA gateway. Starting with version four of EPICS a PSD will define a special type for communicating this information, and a standard property name will be assigned for locating this information in a subscription update payload. This property will also be used in IO request modifiers to filter out state changes that might not be needed.