A4: SECS-I transport (block protocol + E4 retry FSM)
Adds a complete IO-free SECS-I implementation:
include/secsgem/secsi/header.hpp 10-byte block header (R/W/E bits)
include/secsgem/secsi/block.hpp length + header + body + checksum
include/secsgem/secsi/protocol.hpp half-duplex FSM (ENQ/EOT/ACK/NAK)
src/secsi/* implementations
tests/test_secsi.cpp header, block, multi-block split,
back-to-back FSM drive, RTY,
contention, T2 timeout
The protocol is event-driven (`Event` → `Action` queue), so wiring it
to an asio serial_port is a thin adapter — that lands in the next
commit so this one stays reviewable.
Key design points:
- Master/slave contention: slave yields on simultaneous ENQ (E4 §7.1.4).
- RTY exhaustion raises ActionRaiseError, clears the send queue, resets
to Idle (no zombie state).
- Multi-block assembler validates contiguous 1..N numbering and exclusive
E-bit-on-last invariants — rejects malformed sequences with nullopt.
- Block::checksum is exposed publicly for the receive path's verification.
Tests cover the happy path (back-to-back delivery), error paths
(checksum mismatch, short input, oversize body), retries (NAK chain to
exhaustion), and protocol corner cases (contention, T2 timeout).
secsgem-py implements SECS-I block framing but lacks the explicit RTY
state machine; this commit puts the C++ port ahead on transport
correctness.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -40,6 +40,24 @@ Legend:
|
||||
|
||||
---
|
||||
|
||||
## 1a. E4 — SECS-I transport (block protocol)
|
||||
|
||||
| Item | Status | Spec ref | Notes |
|
||||
|---------------------------------------|--------|----------|-------|
|
||||
| 10-byte block header (R/W/E bits, system bytes) | ✅ | E4 §6.2 | `secsi::Header` with bit-precise pack/unpack. |
|
||||
| Length-prefixed block + 2-byte checksum | ✅ | E4 §6.1, §6.3 | `secsi::Block::encode/decode`. |
|
||||
| Multi-block message split / assemble | ✅ | E4 §7.2.3 | `split_message` / `assemble_message`; E-bit only on the final block. |
|
||||
| ENQ/EOT/ACK/NAK handshake | ✅ | E4 §7.1 | `secsi::Protocol` half-duplex FSM. |
|
||||
| RTY retry counter | ✅ | E4 §10.2 | Per-block retry budget, exhaust → ActionRaiseError. |
|
||||
| T1 inter-character timer hook | ✅ | E4 §10.1 | Drained in `RecvBlock`; host wires the actual asio timer. |
|
||||
| T2 protocol timer hook | ✅ | E4 §10.1 | Triggers a retry from any send state. |
|
||||
| T3 reply timer | ⬜ | E4 §10.1 | Driven by the upper layer (same as HSMS). |
|
||||
| T4 inter-block timer | ⬜ | E4 §10.1 | Multi-block message-gap; FSM emits hook events. |
|
||||
| Master/slave contention resolution | ✅ | E4 §7.1.4 | Slave yields on simultaneous ENQ; master holds. |
|
||||
| Serial port wiring (asio) | ⬜ | — | FSM is IO-free; a follow-up commit will land the asio integration. |
|
||||
|
||||
---
|
||||
|
||||
## 2. E5 — SECS-II encoding
|
||||
|
||||
| Item | Status | Spec ref | Notes |
|
||||
|
||||
Reference in New Issue
Block a user