Chapter 14 — Datagram Protocol

The Datagram protocol provides reliable 0-72 byte addressed transfers. It is the primary mechanism for configuration memory access (read/write) and is used by CDI, ACDI, and firmware upgrade features.

Source files: src/openlcb/protocol_datagram_handler.c, src/openlcb/protocol_datagram_handler.h

14.1 Two-Phase ACK Protocol

Every datagram request follows a two-phase acknowledgement pattern. The Reply Pending bit (0x80) is always set in the Datagram Received OK reply, indicating that a response datagram will follow:

sequenceDiagram participant Requester participant Server Requester->>Server: Datagram (read/write command) Server-->>Requester: Datagram Received OK (Reply Pending=1) Note over Server: Process command Server->>Requester: Datagram (response data / write OK) Requester-->>Server: Datagram Received OK
Reply Pending always set: In this implementation, the Reply Pending flag (0x80 in the flags byte) is always set. A response datagram is guaranteed to follow every request.

14.2 Address Space Routing

The datagram handler routes incoming datagrams to per-address-space callbacks based on the address space byte. The standard spaces are:

SpaceNameTypical Use
0xFFCDIXML device description (read-only)
0xFEConfiguration MemoryUser-writable settings
0xFDAllFull memory space
0xFCACDI ManufacturerManufacturer info (read-only)
0xFBACDI UserUser name/description
0xFATrain FDIFunction Definition Info (train nodes)
0xF9Train Function ConfigTrain function configuration

14.3 Command Structure

The first byte of the datagram payload identifies the command type, and the second byte identifies the sub-command:

Byte 0 (Command)Meaning
0x20Memory Configuration Protocol
Byte 1 (Sub-command)Operation
0x40Read
0x50Read Reply OK
0x58Read Reply Fail
0x00Write
0x10Write Reply OK
0x18Write Reply Fail
0x08Write Under Mask
0x60Read (Stream)
0x20Write (Stream)
0x80Get Configuration Options
0x82Configuration Options Reply
0x84Get Address Space Info
0x86Address Space Present Reply
0x87Address Space Not Present Reply
0x88Lock/Reserve
0x8ALock/Reserve Reply
0x8CGet Unique ID
0x8EGet Unique ID Reply
0xA0Unfreeze
0xA1Freeze
0xA8Update Complete
0xA9Reset/Reboot
0xAAFactory Reset

14.4 Read Handler Flow

When a Read command arrives, the handler:

  1. Sends Datagram Received OK (Reply Pending = 1).
  2. Extracts the address space byte from the datagram.
  3. Routes to the matching read callback (e.g., memory_read_space_configuration_memory).
  4. If the callback is NULL, sends a Datagram Rejected with SUBCOMMAND_UNKNOWN.

14.5 Write Handler Flow

Write commands follow the same pattern: acknowledge, extract address space, route to the write callback. The Write Under Mask variant allows bitwise modification of configuration memory (useful for flag bytes).

14.6 Retry Logic

When a Datagram Rejected reply is received:

A Datagram Received OK clears the resend flag and frees the stored datagram buffer. The check_timeouts() function scans for timed-out pending datagrams that have exceeded their maximum retry count.

14.7 Configuration Memory Operations

Beyond read/write, the datagram handler supports several configuration management commands:

OperationPurpose
Get OptionsQuery supported write sizes, available address spaces, and capabilities.
Get Address Space InfoQuery size, flags, and description of a specific address space.
Lock/ReserveExclusive access to a node's configuration for multi-step writes.
Freeze / UnfreezePause a node's normal operation while configuration is being updated.
Reset/RebootRequest the node to restart (apply new configuration).
Factory ResetRestore all configuration to factory defaults.