Appendix A — Requirements Catalogue

Generated from documents/requirements/*.yaml at build time. These are the normative requirements the design in this booklet implements; each section corresponds to one requirement file.

Can Protocol

ID Title Shall
REQ-CAN-001 CAN bus transport The protocol shall use the CAN bus as the communication channel between clients and servers. All protocol interactions follow a client-server model where the client initiates requests and the server processes them.
REQ-CAN-002 Extended CAN identifiers The protocol shall use exclusively 29-bit extended CAN identifiers for all transmitted and received frames. Both client and server shall silently discard any frame using an 11-bit standard identifier.
REQ-CAN-003 CAN identifier structure The 29-bit CAN identifier shall encode four fields: a 5-bit priority field (bits 28-24), a 4-bit category field (bits 23-20), an 8-bit message type field (bits 19-12), and a 12-bit node address field (bits 11-0).
REQ-CAN-004 Client-server model The protocol shall follow a client-server architecture where the client is the sole initiator of commands and queries, and the server listens for incoming frames, processes them, and sends responses. The server shall not initiate unsolicited commands to the client.
REQ-CAN-005 Server node identity Each server shall be configured with a unique 12-bit node address (1-4095) that identifies it on the CAN bus. The server shall process only frames addressed to its own node address or to the broadcast address (0x000).
REQ-CAN-006 Multi-server client support The client shall support communication with multiple servers on the same CAN bus by addressing frames to different server node addresses. The client shall maintain independent sequence counters per server.
REQ-CAN-006.1 Single-client server Each server shall serve exactly one client. The server shall maintain a single sequence counter shared by all sequence-validated categories, so concurrent command streams originating from more than one client are not supported and shall be rejected with a sequence error. The relationship is therefore one client to many servers, never many clients to one server.
REQ-CAN-007 Broadcast message support The protocol shall reserve node address 0x000 as the broadcast address. All servers shall accept frames addressed to 0x000 regardless of their configured node address, enabling simultaneous control of multiple servers.
REQ-CAN-008 Default system category The protocol shall define a built-in System category (0x0) that provides heartbeat, command acknowledgement, status request, and category discovery messages. This category shall be available without any application-specific extensions.
REQ-CAN-009 Server heartbeat mechanism The server shall automatically begin transmitting heartbeat frames upon startup. A heartbeat frame shall contain a 1-byte protocol version identifier and shall be sent at the lowest CAN priority level. The server shall transmit a heartbeat at least 1 second after the last message of any kind was sent, acting as a keep-alive during periods of silence. The heartbeat shall not be sent while the server is actively transmitting other messages within the 1-second window.
REQ-CAN-009.1 Client online/offline detection The client shall use received heartbeat frames (and other messages) to determine whether a server is online or offline. When a heartbeat is received from a server, the client shall consider that server online and notify the application layer. When no messages are received from a server within a configurable timeout, the client shall consider that server offline and notify the application layer.
REQ-CAN-010 Protocol version identification The heartbeat frame shall carry a protocol version byte that allows the client to verify wire-format compatibility with the server.
REQ-CAN-011 Command acknowledgement The server shall transmit a 4-byte acknowledgement frame for every processed command, containing the original command’s category, message type, a status code indicating success or the specific error condition (unknown command, invalid payload, invalid state, or sequence error), and an expected-sequence byte (REQ-CAN-037). Messages rejected by rate limiting are the exception: per REQ-CAN-022 they are silently discarded and receive no acknowledgement, since sending one would itself add traffic during the overload condition rate limiting exists to shed.
REQ-CAN-012 Status request The client shall be able to send a status request message to a server. Upon receiving this message, the server shall respond by transmitting a heartbeat message, allowing the client to quickly confirm the server is online without waiting for the next scheduled heartbeat.
REQ-CAN-013 Category-based message dispatch The protocol shall dispatch received frames to handlers based on the category field in the CAN identifier. Each category handler shall be independently registered and shall process only its own message types.
REQ-CAN-014 Application-defined categories The protocol shall allow applications to define additional message categories beyond the built-in System and Firmware Upgrade categories by registering custom category handlers on the server and client. Category identifiers 0x2 to 0xF shall be available to applications. RegisterCategory() shall reject, by returning false without registering, an attempt to register a category whose ID is already registered, or that would exceed canMaxRegisteredCategories (8) categories registered at once on that server or client. This bound exists because the category discovery response (REQ-CAN-008) reports every registered category ID in a single 8-byte frame; it must never truncate.
REQ-CAN-015 Fixed-point data encoding All floating-point values transmitted over CAN shall be encoded as big-endian signed fixed-point integers with defined per-quantity scale factors, with saturation clamping to prevent integer overflow.
REQ-CAN-016 Short payload rejection The server shall reject any command frame whose payload is shorter than the minimum required length for the given message type, and shall respond with an invalid-payload error without applying any state changes.
REQ-CAN-017 Sequence number validation The server shall validate command frames using an 8-bit sequence counter in the first payload byte. The first received command shall be accepted regardless of its sequence value. Subsequent commands shall be accepted only if their sequence number equals the previous sequence number plus one, modulo 256. Out-of-sequence commands shall be rejected with a sequence error response.
REQ-CAN-018 Sequence number wrap-around The sequence counter shall wrap from 255 to 0 without error, allowing continuous operation without sequence resets.
REQ-CAN-019 Sequence bypass per category Individual category handlers shall be able to declare whether they require sequence number validation. Categories or specific message types that do not require sequencing shall bypass validation entirely.
REQ-CAN-020 Unknown message category handling The server shall silently discard any received frame whose category field does not correspond to a registered category handler, without generating any response.
REQ-CAN-021 Unknown message type handling The server shall respond with an unknown-command error when a frame is received with a registered category but an unrecognized message type.
REQ-CAN-022 Message rate limiting The server shall enforce a configurable maximum number of received messages per second. Messages exceeding this limit shall be silently discarded. The rate counter shall be reset automatically every second by an internal timer.
REQ-CAN-023 Node address filtering The server shall process only CAN frames whose node address matches its configured local address or the broadcast address (0x000), and shall silently discard all other frames.
REQ-CAN-024 No dynamic memory allocation The CAN protocol library shall not perform any dynamic memory allocation and shall use only statically-sized data structures.
REQ-CAN-025 Category discovery The client shall be able to send a category list request message to a server. Upon receiving this message, the server shall respond with a category list response containing the IDs of all registered category handlers. The response payload shall list one category ID per byte, limited to the maximum CAN frame payload size (8 bytes). If more than 8 categories are registered, the server shall include only the first 8 in registration order and shall drop the remainder without an error indication; a server needing to expose more than 8 categories is not currently supported.
REQ-CAN-026 Per-server sequence counter on client The client shall maintain independent 8-bit sequence counters for each server node it communicates with. The sequence counter for a node shall start at 0 on the first command and increment by 1 for each subsequent command to that same node. Counters for different nodes shall be independent. Up to 8 server nodes may be tracked simultaneously.
REQ-CAN-027 Server liveness detection The client shall track server liveness independently for each server node. When any frame is received from a source node ID (non-zero), the client shall call OnServerOnline(nodeId) the first time and reset a per-server timeout timer (default 3 s). If no frame is received from a server within the timeout period, the client shall call OnServerOffline(nodeId). Up to 8 server liveness slots may be tracked simultaneously.
REQ-CAN-028 Send queue overflow indication The CanFrameTransport::SendFrame() method shall return true if the frame was successfully sent or enqueued, and false if the internal send queue was full and the frame was dropped. The onDone callback shall not be called when false is returned.
REQ-CAN-029 ISO-TP segmentation support The library shall provide an optional ISO 15765-2 (ISO-TP) transport layer that segments PDUs exceeding 8 bytes into multiple CAN frames and reassembles them at the receiver. The transport layer shall be attachable to CanProtocolServer and CanProtocolClient via AttachIsoTpTransport().
REQ-CAN-030 ISO-TP frame types The ISO-TP implementation shall support all four ISO 15765-2 frame types: Single Frame (SF, PCI nibble 0x0), First Frame (FF, PCI nibble 0x1), Consecutive Frame (CF, PCI nibble 0x2), and Flow Control (FC, PCI nibble 0x3).
REQ-CAN-031 ISO-TP flow control The sender shall wait for a Flow Control (ContinueToSend) frame from the receiver before transmitting Consecutive Frames. The receiver shall emit a Flow Control frame after receiving the First Frame. Block size (BS=0) and separation time (STmin) fields shall be honoured. On Flow Status = Wait, the sender shall restart the N_Bs timer and continue waiting rather than aborting, up to N_WFTmax (16) consecutive Wait frames, after which it shall abort. On Flow Status = Overflow, the sender shall abort immediately.
REQ-CAN-032 ISO-TP N_Bs timeout The sender shall abort an in-progress multi-frame transmission and notify the abort callback with reason nBsTimeout if no Flow Control frame is received within 1000 ms of sending the First Frame or the last block of Consecutive Frames.
REQ-CAN-033 ISO-TP N_Cr timeout The receiver shall abort reassembly and notify the abort callback with reason nCrTimeout if no Consecutive Frame is received within 1000 ms of the previous frame.
REQ-CAN-034 ISO-TP no dynamic memory allocation The ISO-TP transport layer shall not perform any dynamic memory allocation. Channel state and PDU buffers shall use statically-sized storage provided at construction time via IsoTpTransportImpl::WithStorage.
REQ-CAN-035 ISO-TP channel management IsoTpTransportImpl shall support registering multiple independent receive channels identified by a (dataId, fcId) pair. The maximum number of simultaneous channels shall be bounded at compile time via the MaxChannels template parameter (default 4). Registering a channel with a dataId already in use shall return false without modifying state. A channel shall be reclaimable via ReleaseChannel(dataId), allowing its slot to be reused once the application (or the transport itself, on abort) is done with that dataId.
REQ-CAN-036 Server-side client-liveness detection The client shall automatically begin transmitting heartbeat frames upon construction, broadcast to node 0x000, following the same quiet-period keep-alive rule as the server’s own heartbeat (REQ-CAN-009). The server shall restart its client-liveness timeout (default 3 s) on any frame correctly addressed to it, not only heartbeats, since a client sending commands continuously may defer its own heartbeat frame indefinitely; a received heartbeat shall additionally notify the application via CanProtocolServerObserver::Online(). If the timeout elapses without further traffic from the client, the server shall notify CanProtocolServerObserver::Offline(). A server tracks liveness for one client only, consistent with REQ-CAN-006.1.
REQ-CAN-037 Sequence resynchronization on sequence error The sequenceError acknowledgement (REQ-CAN-011) shall carry, in its fourth byte, the sequence number the server expected. On receiving a sequenceError acknowledgement, the client shall adopt that value as its next sequence number for the acknowledging server, so that a single lost frame, or the client’s own sequence state having reset independently of the server, does not leave the two sides unable to recover.
REQ-CAN-038 Command acknowledgement timeout When the client sends a sequence-validated command, it shall start a timer (default 1 s, configurable). If no acknowledgement of any status arrives for that command before the timer elapses, the client shall notify the application via CanProtocolClientObserver::OnCommandAckTimeout(nodeId, category, messageType). Receiving a matching acknowledgement before the timer elapses shall cancel it. The client shall not automatically retry the timed-out command.

Firmware Upgrade

ID Title Shall
REQ-FWU-001 Upgrade session initiation The client shall be able to initiate a firmware upgrade session by sending a Begin Upgrade command containing the total firmware size in bytes (uint32). The server shall reject the request if an upgrade is already in progress (Busy) or the size exceeds available storage (InvalidSize).
REQ-FWU-002 Upgrade session abort The client shall be able to abort a firmware upgrade session at any time by sending an Abort command. The server shall discard any received data and return to the Idle state.
REQ-FWU-003 Block-based data transfer Firmware data shall be transferred in blocks of up to 6 bytes per CAN frame, with each block identified by a uint16 block index (bytes 0–1). Blocks shall be transmitted in ascending order starting from index 0.
REQ-FWU-004 Per-block acknowledgement The server shall acknowledge each received data block with a Data Block Ack containing the block index and a status code. The client shall not consider a block successfully transferred until the corresponding ack with Ok status is received.
REQ-FWU-005 Block write failure handling If the server fails to write a block to flash storage, it shall respond with a WriteError status in the Data Block Ack. The client may retransmit the failed block.
REQ-FWU-006 CRC32 integrity verification After all data blocks have been transferred, the client shall send a Verify command containing the expected CRC32 of the complete firmware image. The server shall compute the CRC32 over the received data and respond with match or mismatch status.
REQ-FWU-007 Firmware activation The client shall be able to command the server to activate the newly uploaded firmware by sending an Activate command. This command shall only be accepted after a successful CRC32 verification (Complete state). The server shall perform the firmware swap and reboot.
REQ-FWU-008 Activation safety The server shall reject Activate commands if the firmware has not been successfully verified (NotReady error), preventing activation of corrupt or incomplete images.
REQ-FWU-009 Upgrade progress query The client shall be able to query the current upgrade state at any time. The server shall respond with the current state, the number of blocks received, and the total number of blocks expected.
REQ-FWU-010 Active firmware preservation The firmware upgrade process shall not overwrite the currently running firmware. Incoming firmware shall be written to a staging area or inactive flash bank, preserving the active image until activation.
REQ-FWU-011 Upgrade state machine The firmware upgrade process shall follow a defined state machine with states: Idle, Receiving, Verifying, Complete, and Error. Commands that are not valid in the current state shall be rejected with an InvalidState error.
REQ-FWU-012 Sequence validation bypass The firmware upgrade category shall not require protocol-level sequence validation (RequiresSequenceValidation = false). Transfer ordering shall be enforced by the explicit block index in each Data Block message, since the protocol’s 8-bit sequence counter is insufficient for the number of blocks in a typical firmware transfer.
REQ-FWU-013 Maximum firmware size The firmware upgrade protocol shall support firmware images up to 393210 bytes (65536 blocks × 6 bytes per block), limited by the uint16 block index field. Transfers exceeding this limit shall be rejected during Begin Upgrade.
REQ-FWU-014 Response message type IDs Response message types within the firmware upgrade category shall use IDs formed by adding 0x80 to the corresponding command message type ID, reserving 0x00–0x7F for commands and 0x80–0xFF for responses.
REQ-FWU-015 Session inactivity timeout The server shall abort a firmware upgrade session if no DataBlock, Verify, Activate, or Abort command is received within a configurable inactivity timeout period (default 30 s) after BeginUpgrade or the last DataBlock. On timeout the server shall transition to Idle state and notify the application via the OnSessionTimeout() observer callback. QueryProgress commands shall not reset the inactivity timer.