Appendix F — OpenLCB Specification Traceability
This appendix maps OpenLCB specification requirements to the implementing source files and documentation chapters. It is intended to verify spec coverage, identify unimplemented requirements, and aid compliance auditing.
Spec documents (Standards "S" + Technical Notes "TN") are located in OpenLcb Documents/standards/. Unreleased standards (Stream Transport, TCP/IP Transport) are in drafts/ and not yet implemented.
F.1 Message Network Standard (MessageNetworkS.pdf)
| Spec Section | Requirement | Source File(s) | Ch |
| 3.1 | All messages shall contain source Node ID and MTI | openlcb_types.h (openlcb_msg_t) | 3 |
| 3.1.2 | Message fully decodable from MTI flag bits | openlcb_defines.h | 3 |
| 3.2 | Nodes start in Uninitialized state | openlcb_node.h (openlcb_node_state_t) | 5 |
| 3.2 | Uninitialized node shall not transmit except Init Complete | openlcb_login_statemachine.c | 9 |
| 3.3 | Node ID in data content shall be full 48-bit on all transports | openlcb_utilities.c | 7 |
| 3.3.4 | Nodes shall process OIR even if not all contents provided | protocol_message_network.c | 12 |
| 3.3.5 | Nodes shall process Terminate Due to Error even if incomplete | protocol_message_network.c | 12 |
| 3.3.7 | Missing Protocol Support Reply bits interpreted as zero | protocol_message_network.c | 12 |
| 3.4 | All nodes shall take part in all standard interactions | openlcb_main_statemachine.c | 8 |
| 3.4.1 | Newly functional nodes shall send Init Complete | openlcb_login_statemachine.c | 9 |
| 3.4.2 | Addressed Verify Node ID replies Verified Node ID | protocol_message_network.c | 12 |
| 3.4.2 | Global Verify Node ID replies Verified Node ID | protocol_message_network.c | 12 |
| 3.5.1 | Unknown addressed MTI sends OIR | openlcb_main_statemachine.c | 8 |
| 3.5.3 | Error during addressed interaction sends Terminate Due to Error | protocol_message_network.c | 12 |
| 3.5.4 | Detect incoming message with own Source Node ID indicates error | protocol_message_network.c | 12 |
| 3.6 | Global messages forwarded to all nodes | openlcb_main_statemachine.c | 8 |
| 7.3.1.3 | First/Middle CAN frames carry 8 data bytes | can_tx_message_handler.c | 11 |
| 7.3.7 | CAN message frames sent consecutively | can_tx_statemachine.c | 11 |
F.2 Event Transport Standard (EventTransportS.pdf)
| Spec Section | Requirement | Source File(s) | Ch |
| 5 | Messages only sent when node is Initialized | openlcb_login_statemachine.c | 9 |
| 6 | Before PCER, node shall emit Producer Identified | openlcb_login_statemachine.c | 9 |
| 6.1 | To produce event, emit PCER with Event ID | protocol_event_transport.c | 13 |
| 6.2 | On Identify Events, reply with all Producer/Consumer Identified | protocol_event_transport.c | 13 |
| 6.3 | On Identify Producer, reply if produced | protocol_event_transport.c | 13 |
| 6.4 | On Identify Consumer, reply if consumed | protocol_event_transport.c | 13 |
| 7 | PCER with payload CAN frames sent together | can_tx_statemachine.c | 11 |
F.3 Datagram Transport Standard (DatagramTransportS.pdf)
| Spec Section | Requirement | Source File(s) | Ch |
| 4.2 | Reserved Datagram OK flag bits sent as zero | protocol_datagram_handler.c | 14 |
| 6 | Valid Datagram received sends Datagram OK or Rejected | protocol_datagram_handler.c | 14 |
| 6.1 | Shall not send second Datagram before reply/timeout | protocol_datagram_handler.c | 14 |
| 6.2 | Permanent Error: abandon, do not resend | protocol_datagram_handler.c | 14 |
| 7.2 | Maintain Datagram-started state for each receiving datagram | can_rx_message_handler.c | 11 |
| 7.3.1 | No lower-priority frames between datagram frames | can_tx_statemachine.c | 11 |
| 7.3.2 | Invalid datagram frame sequence sends Rejected | can_rx_message_handler.c | 11 |
F.4 CAN Frame Transfer Standard (CanFrameTransferS.pdf)
| Spec Section | Requirement | Source File(s) | Ch |
| 3 | Each node shall have unique NodeID | openlcb_node.h | 5 |
| 4 | CAN extended format only (29-bit header) | can_types.h | 3b |
| 5 | Nodes start in Inhibited state | can_login_statemachine.c | 22 |
| 6.2.1 | Alias reservation: CID7/6/5/4, wait 200ms, RID | can_login_message_handler.c | 22 |
| 6.2.1 | Restart reservation if matching alias received | can_rx_message_handler.c | 22 |
| 6.2.2 | Inhibited to Permitted: reserved alias + transmit AMD | can_login_message_handler.c | 22 |
| 6.2.3 | AME with matching Node ID replies AMD | can_rx_message_handler.c | 11 |
| 6.2.3 | AME with no data: discard cached alias mappings | alias_mappings.c, alias_mapping_listener.c | 19, 20 |
| 6.2.4 | On receiving AMR, stop using that alias within 100ms | alias_mappings.c | 19 |
| 6.2.5 | Compare source alias in each received frame against reserved | can_rx_statemachine.c | 11 |
| 6.3 | Alias values shall not be zero | can_login_message_handler.c | 22 |
F.5 Simple Node Information Protocol (SimpleNodeInformationS.pdf)
| Spec Section | Requirement | Source File(s) | Ch |
| 5.1 | Mfg name max 41 bytes null-terminated | protocol_snip.c | 15 |
| 5.1 | Model name max 41 bytes null-terminated | protocol_snip.c | 15 |
| 5.1 | HW version max 21 bytes null-terminated | protocol_snip.c | 15 |
| 5.1 | SW version max 21 bytes null-terminated | protocol_snip.c | 15 |
| 5.1 | User name max 63 bytes null-terminated | protocol_snip.c | 15 |
| 5.1 | User description max 64 bytes null-terminated | protocol_snip.c | 15 |
| 6.1 | SNIP support indicated in Protocol Support Reply | protocol_message_network.c | 12 |
| 6.3 | SNIP Reply constant; change requires re-initialization | protocol_snip.c | 15 |
F.6 Memory Configuration Standard (MemoryConfigurationS.pdf)
| Spec Section | Requirement | Source File(s) | Ch |
| 4.1 | 32-bit addresses, byte-addressable | protocol_config_mem_read_handler.c | 14 |
| 4.4 | Read command: Reply Pending in Datagram OK | protocol_config_mem_read_handler.c | 14 |
| 4.5 | Read reply may return less data but at least 1 byte | protocol_config_mem_read_handler.c | 14 |
| 4.24 | Reset/Reboot returns to power-on-reset state | protocol_config_mem_operations_handler.c | 14 |
| 4.25 | Factory Reset: Node ID in payload for redundancy | protocol_config_mem_operations_handler.c | 14 |
F.7 Train Control Protocol (TrainControlS.pdf)
| Spec Section | Requirement | Source File(s) | Ch |
| 3 | Train Control node shall implement Event Transport and SNIP | protocol_event_transport.c, protocol_snip.c | 13, 15 |
| 4.3 | P bit = 0 for Throttle-to-Train, P bit = 1 for Train-to-Listener | protocol_train_handler.c | 17 |
| 5 | E-Stop state entered on E-Stop command, exited on Set Speed | protocol_train_handler.c | 17 |
| 6.1 | Non-Controller commands produce Terminate Due to Error | protocol_train_handler.c | 17 |
| 6.1 | Listener messages (P=1) shall never be rejected | protocol_train_handler.c | 17 |
| 6.2 | E-Stop sets Speed 0, preserves direction | protocol_train_handler.c | 17 |
| 6.5 | Set speed always forwarded to listeners; Reverse flag flips direction | protocol_train_handler.c | 17 |
| 6.6 | Heartbeat timeout sets Speed 0 | protocol_train_handler.c | 17 |
F.8 Train Search Protocol (TrainSearchS.pdf)
| Spec Section | Requirement | Source File(s) | Ch |
| 5.1 | Event ID range 09.00.99.FF.xx reserved for Train Search | openlcb_defines.h | 3 |
| 5.2 | Search query: 6 nibbles MSB-first | openlcb_utilities.c | 7 |
| 6.1 | Match produces Producer Identified | protocol_train_search_handler.c | 17 |
| 6.2 | Allocate bit: create Train Node if no reply in 200ms | protocol_train_search_handler.c | 17 |
F.9 Broadcast Time Protocol (BroadcastTimeS.pdf)
| Spec Section | Requirement | Source File(s) | Ch |
| 4 | Upper 6 bytes of event ID from specified clock range | openlcb_defines.h, openlcb_utilities.c | 3, 7 |
| 6.1 | Clock generator sends Range Identified at startup | openlcb_application_broadcast_time.c | 18 |
| 6.2 | Running clock sends Report Time at least once/hour | openlcb_application_broadcast_time.c | 18 |
| 6.4 | Query Event triggers synchronization sequence | protocol_broadcast_time_handler.c | 18 |
| 6.5 | Set commands produce Report event | protocol_broadcast_time_handler.c | 18 |
F.10 CDI Standard (ConfigurationDescriptionInformationS.pdf)
| Spec Section | Requirement | Source File(s) | Ch |
| 4 | CDI invariant while node has Initialized connections | protocol_config_mem_read_handler.c | 16 |
| 5.1.1 | SNIP Reply matches CDI identification element | protocol_snip.c | 15 |
| 5.1.4.2 | Integer stored unsigned unless min < 0, big-endian | Application config memory | 16 |
| 5.1.4.4 | Event ID stored big-endian | openlcb_utilities.c | 7 |
F.11 FDI Standard (FunctionDescriptionInformationS.pdf)
| Spec Section | Requirement | Source File(s) | Ch |
| 4 | FDI constant while node Initialized | protocol_config_mem_read_handler.c | 16 |
| 5.1.4 | Function number 0-16777215 | protocol_train_handler.c | 17 |
F.12 Firmware Upgrade Standard (FirmwareUpgradeS.pdf)
| Spec Section | Requirement | Source File(s) | Ch |
| 5.2 | Freeze command transitions to Firmware Upgrade | protocol_config_mem_operations_handler.c | 14 |
| 5.2 | Unfreeze transitions to Operating | protocol_config_mem_operations_handler.c | 14 |
| 5.3 | Firmware Upgrade Protocol bit in PSI | protocol_message_network.c | 12 |
| 5.4.2 | Datagram transfer: 64-byte writes at offset 0 | protocol_config_mem_write_handler.c | 14 |
F.13 Unique Identifiers Standard (UniqueIdentifiersS.pdf)
| Spec Section | Requirement | Source File(s) | Ch |
| 4 | Unique Identifier is 6 bytes, MSB transmitted first | openlcb_types.h | 3 |
| 4 | Every node shall have a Unique Identifier as Node ID | openlcb_node.h | 5 |
F.14 Event Identifiers Standard (EventIdentifiersS.pdf)
| Spec Section | Requirement | Source File(s) | Ch |
| 4 | Event identifier is 8 bytes, MSB first | openlcb_types.h | 3 |
| 4 | Byte order significant, MSB transmitted first | openlcb_utilities.c | 7 |
| 5 | Well-known events allocated per table | openlcb_defines.h | 3 |
F.15 CAN Physical Layer Standard (CanPhysicalS.pdf)
Hardware-level requirements (bus termination, cable, connector, bit rate). Implemented by CAN transceiver hardware, not by this library. Application wiring guide references these requirements (Ch 23, Ch 28).
F.16 Unreleased Standards (in drafts/)
| Standard | Status |
| Stream Transport | Draft -- not yet released, not implemented |
| TCP/IP Transport | Draft -- not yet released, not implemented |