Releases: SoundMatt/cpp-RCP
Release list
v2.6.0 — E2E CRC Safe Points & Safety-Request Variants
Phase 13 milestone 50. Replaces rcp/e2e.hpp with the specification's actual end-to-end CRC (32-bit, polynomial 0xF4ACFB13, both input/output reflected) and its exact stream_id + avtp_timestamp + ACF header + payload coverage/length-adjustment rule; adds per-endpoint opt-in CRC safe mode, the safety-tagged (0x8x) compound/compound-wait/triggered request variants gated on safe-state entry, and the full per-request-stream watchdog/safe-state register set in rcp/regmap.hpp. This is the milestone the Phase 13 introduction names as "the point at which the mandatory baseline plus safe-points exist," building on v2.5.0's conditional-request taxonomy and sequencer.
See ROADMAP.md's "Done (v2.6.0)" entry under milestone 50 for full details, and PR #43 for the change itself.
v2.5.0 — Conditional-Request Taxonomy & Sequencers
Phase 13 milestone 49. Implements the conditional-request taxonomy (compound, compound-wait, triggered, chained, timed) via the mtv=0 message_timestamp-repurposing trick over ACF_GBB, the three cancellation kinds and their shared semantics, the sequencer-state behavior layer, and the full pending → started → under_execution → finalized request lifecycle, building on v2.4.0's endpoint types.
See ROADMAP.md's "Done (v2.5.0)" entry under milestone 49 for full details, and PR #42 for the change itself.
v2.4.0 — Basic Endpoint Types II: I2C, UART, ADC, PWM_OUT, PWM_IN
Phase 13 milestone 48. Adds I2C (ep_type 0x04), UART (ep_type 0x05), ADC (ep_type 0x09), PWM_OUT (ep_type 0x07), and PWM_IN (ep_type 0x08) endpoint types, building on v2.3.0's endpoint-registration/request-dispatch scaffolding.
See ROADMAP.md's "Done (v2.4.0)" entry under milestone 48 for full details, and PR #41 for the change itself.
v2.3.0 — Basic Endpoint Types I: GPIO & SPI
v2.3.0 — Basic Endpoint Types I: GPIO & SPI (Phase 13 milestone 47)
Third endpoint-facing milestone of the full OPEN Alliance TC18 Remote Control Protocol replacement (see ROADMAP.md), building on v2.0.0's wire codec, v2.1.0's lifecycle/register-map model, and v2.2.0's discovery mechanism. Establishes the endpoint-registration/request-dispatch pattern every later endpoint type reuses.
What changed
- New
rcp/endpoint.hpp: shared scaffolding —ep_typeid constants (kEndpointTypeGpio,kEndpointTypeSpi, with the remaining v2.4.0/v2.7.0 ids named in comments),write_semantics_ofdecodingAcfMessageInfo::evt_opinto the 8-wayWriteSemanticsenum,saturating_add/saturating_subtracttemplates,apply_bitmask_writecovering the six value-combining semantics (Replace/Or/And/Xor/Add/Subtract, Reserved rejected, Reconfigure left to each endpoint type), and a genericTriggerRegistryenable/notify/drain trigger-signal table. - New
rcp/gpio.hpp: GPIO (ep_type 0x02) — 4-byte big-endian pin bitmask payload codec,apply_gpio_writecompleting the 8-way semantics (Reconfigure retargets a separate pin-direction mask), per-pin change/rising/falling triggers (evaluate_gpio_triggers), a functional-config codec againstregmap::EndpointFunctionalConfig's opaque blob, andGpioEndpointtying it together into one request-dispatch entry point. - New
rcp/spi.hpp: SPI (ep_type 0x03) —channel_ofdecodingevt[2:0]as a 0-5 channel selector,SpiEndpoint::transferfor raw full-duplex PICO-out/POCI-in byte exchange with CsAssert/TransferComplete/CsDeassert trigger signals, andcompound_wait_matchesimplementing the compound-wait status-byte truncation rule (first 4 of up to 20 bytes) as scaffolding for the v2.5.0 compound-wait request kind. - New
REQ-ENDPOINT-001..006,REQ-GPIO-001..008,REQ-SPI-001..005requirements (.fusa-reqs.json), tested intests/test_endpoint.cpp,tests/test_gpio.cpp,tests/test_spi.cpp.
Scope note
Per ROADMAP.md, this milestone covers only GPIO and SPI — the two simplest request/response shapes. I²C, UART, ADC, PWM_OUT, and PWM_IN follow at v2.4.0.
Verification
All 35 ctest suites pass (45 new Catch2 test cases across the 3 new suites); all 20 CI checks green on PR #40 (full build matrix across Linux/macOS/Windows × clang/gcc/msvc, clang-tidy, coverage, relay conform, and the full cpp-FuSa safety/security/traceability lifecycle including 100% requirement coverage).
Full diff: v2.2.0...v2.3.0
v2.1.0 — RC Server lifecycle & register-map model
v2.1.0 — RC Server lifecycle & register-map model (Phase 13 milestone 45)
Second milestone of the full OPEN Alliance TC18 Remote Control Protocol replacement (see ROADMAP.md), building directly on v2.0.0's wire codec.
What changed
- New
rcp/lifecycle.hpp:- The 3-state RC Server lifecycle machine —
HW_UNCONFIGURED(0x00),HW_CONFIGURED(0x55),RCP_CONFIGURED(0xAA) - Forward-only, single-step
advance()transitions (no skipping, no going backward except via explicitdeconfigure()) - The
HW_CFG_INCONSISTENT/RCP_CFG_INCONSISTENTplausibility checks gating each transition - Independent generic/functional config-block locking, tied to lifecycle state
- The 3-state RC Server lifecycle machine —
- New
rcp/regmap.hpp:- The generic (server-owned, pin-mapping/queue-size) vs. functional (endpoint-type-specific) config split — a hard prerequisite every endpoint milestone from v2.3.0 onward depends on
- General bootstrap register fields: magic number, protocol version, vendor/device ID, endpoint count, stream/queue capacity,
svr_implemented_options, and pointer/capacity fields for the five bootstrap tables - HW pin-mapping config, request-stream config (including the
rx_wd_*/rx_safety_measurefields — present now, wired up for real at v2.6.0), the EP-ID/byte_bus_idmapping table (client-ordering risk flagged explicitly in comments, not server-enforced), and response/ack queue config - Persistent 8-bit sequencer-state storage (used starting v2.5.0)
Ep0— the RC Server acting as a pseudo-endpoint: whole-register-map read (unrestricted) and write (root-client-only viaclaim_root_client/svr_root_client_index), plus per-endpoint write restriction for every other client- The four mandatory register-map error codes as
rcp::regmap::RegMapErrc:UNAUTHORIZED_ACCESS,LOCKED_MEM_ACCESS,REQUEST_REJECTED,INVALID_PARAMETER
- New
REQ-LIFECYCLE-001..006andREQ-REGMAP-001..014requirements (.fusa-reqs.json), tested intests/test_lifecycle.cppandtests/test_regmap.cpp. rcp/rcp.hpp's pre-replacement Zone/Command/Controller/Registry model is unchanged in behavior — its header comment now points at the new replacement headers — since roughly three dozen other headers still build against it and aren't rebound until their own later milestones (v2.9.0 onward per the Release Plan).
Scope note
Per ROADMAP.md, this milestone is the lifecycle/register-map foundation only: no discovery, endpoint types, conditional requests, or E2E safe-state behavior is included (those are v2.2.0+). Field widths, the register-map magic-number value, and the locking policy are this implementation's own design choices for realizing the described behavior; no discovery mechanism or endpoint type exists yet to exercise the register map end-to-end over the wire.
Verification
44/44 ctest suites pass (clang, Debug/Release, C++17/C++20); all 20 CI checks green (full build matrix across Linux/macOS/Windows × clang/gcc/msvc, clang-tidy, coverage, relay conform, and the full cpp-FuSa safety/security/traceability lifecycle including 100% requirement coverage).
Full diff: v2.0.0...v2.1.0
v2.0.0 — TC18 wire format core
v2.0.0 — TC18 wire format core (Phase 13 milestone 44)
First milestone of the full OPEN Alliance TC18 Remote Control Protocol replacement (see ROADMAP.md). Breaking: rcp/wire.hpp's wire format is entirely replaced.
What changed
rcp/wire.hppis rebuilt from scratch as an IEEE 1722 AVTPDU/ACF codec:- NTSCF and TSCF AVTPDU headers (encode/decode, subtype validation)
- ACF_ABB (
0x0E, no timestamp) and ACF_GBB (0x0D, 64-bitmessage_timestamp) message framing - The shared
byte_message_infofields:acf_msg_type,acf_msg_length,pad,mtv,byte_bus_id,evt(ack + 3-bit sub-opcode),hs,cs,transaction_num,op,rsp,err,ms, and the dual-purposeread_size/segment_numfield StreamId(MAC + locally-assigned suffix) andbyte_bus_idaddressing, withmake_response()structurally enforcing the "echo byte_bus_id/transaction_num back unchanged" rule- The mandatory standard request kind and the four response semantic types (acknowledge / write / read / error)
avtp_timestamp/message_timestampwith an explicit fallback rule (effective_timestamp) returningstd::nulloptrather than defaulting to zero- No dependency on
rcp.hpp's Zone/Command/Controller/Registry model; no transport assumption (Ethernet, IEEE1722-over-UDP/IP, or CAN all supported later)
- The old 16-byte frame codec is preserved byte-for-byte as
rcp/legacy_wire.hppsorcp/udp.hppkeeps building/working until its own v2.13.0 rebuild. - New
REQ-WIRE-001..014requirements (.fusa-reqs.json), tested intests/test_wire.cpp; oldREQ-UDP-*tests moved unchanged totests/test_legacy_wire.cpp.
Scope note
Per ROADMAP.md, this is a pure wire-codec milestone: no RC Server lifecycle, register-map, discovery, or endpoint behavior is included (those are v2.1.0+), and full bit-for-bit conformance against other TC18 implementations isn't claimed until v2.6.0.
Verification
42/42 ctest suites pass (clang/gcc, Debug/Release); all 20 CI checks green (full build matrix across Linux/macOS/Windows × clang/gcc/msvc, clang-tidy, coverage, relay conform, and the full cpp-FuSa safety/security/traceability lifecycle including 100% requirement coverage).
Full diff: v1.2.0...v2.0.0
v1.2.0
v1.2.0 — backlog sweep
Fixes every open issue on this repo as of 2026-07-27 (#28–#34).
New capability
- #28 —
sendnow implements the RELAY spec §11.2 protocol-flags form for RCP:--zone <name> --type <cmdtype> [--payload <hex>], alongside the existingsend --format jsonstreaming sink (crossbar spoke). Both dispatch to the same in-process mock zone-controller registry.
Fixes
- #29 —
TARA.mdand the cpfusa-generatedtara.mdcase-collided on case-insensitive filesystems (macOS/Windows default), silently dropping one file's content on checkout. Renamed the hand-authored file toTARA-ANALYSIS.md. - #30 — Closed a TOCTOU race in
mock::Controller::subscribe(): asubscribe()call concurrent withclose()could return success instead ofErrClosed(RELAY spec §6.2/6.3/6.6). Added a concurrent regression test. - #31 —
capabilitiesnow emitsprotocol/protocol_int, matchingversionand the spec §12.2 single-protocol-implementation convention. - #32 —
command_latency_test's safety-timing gate no longer keys its threshold off theCIenvironment variable (an unreliable proxy for "quiet scheduler" that produced a spurious failure on a sandboxed non-CI run); it now applies a single generous, uniform threshold. - #33 — Bumped
kRelaySpecVersion1.10 → 1.11 (RELAY's current stable spec). - #34 — README's Headers table expanded from 2 of ~43 public headers to a full, concern-grouped index (Core/RELAY integration, Protocol bridges, RCP control-plane concerns, Transports).
Left open
- #23 — "Feature parity: port remaining go-RCP tooling packages" is an architectural decision (port vs. declare out-of-scope in favor of cpp-FuSa), not a code-fixable gap. Left open with an explanatory comment; needs a maintainer decision.
Verification
41/41 ctest suites pass; relay conform --strict PASS at spec 1.11; all 19 CI jobs green (build matrix across Linux/macOS/Windows × clang/gcc/msvc, clang-tidy, coverage, and the full cpp-FuSa safety/security lifecycle).
Full diff: v1.1.0...v1.2.0
v1.1.0 — RELAY spec v1.10 uplift (crossbar send sink + continuous conformance)
Uplifts cpp-RCP to RELAY spec v1.10. Closes #21, #25, #26.
Highlights
- Crossbar send sink (#21, §11.2):
cpp-rcp send --format jsonreadsrelay.MessageNDJSON on stdin and publishes each — cpp-RCP can now be arelay crossbardestination, not only a source. Malformed/undeliverable lines are skipped non-fatally. Self-contained JSON reader + base64 decode, no new dependency. New REQ-CLI-005 (traced + tested). - Library architecture (#25, §13.7): added the
relay::INodecross-language node-interface alias; bumpedkRelaySpecVersion1.0 → 1.10. - Continuous conformance (#26, §20.1): CI
cpfusa tracegate tightened to 100% requirement coverage;relay conform --strictgate (added in v1.0.2) continues to gate every PR.
Verification
- 332/332 requirements traced (100%); 41 ctest suites green;
relay conform --strictPASS at spec 1.10. kVersion→ 1.1.0.
Remaining open: #23 (feature-parity ports — deferred architectural decision). convert/interop tooling-conformance (§20.3) intentionally not declared.
v1.0.2 — RELAY conform CI conformance gate
Patch release adding RELAY conformance enforcement to CI.
Highlights
- New CI gate
relay conform (RELAY §12 conformance)(issue #18): every PR now checks out the authoritativeSoundMatt/RELAYvalidator, builds thecpp-rcpCLI, and runsrelay conform --strict— version/capabilities/status documents are gated against the RELAY spec on every change. rcp::kVersion→ 1.0.2; CMake project version synced. No library behaviour change; RELAYspec_versionunchanged at 1.0.
Builds on v1.0.1 (100% FuSa/cyber requirement test coverage). PRs #22 (gate) + #24 (release).
v1.0.1 — 100% FuSa/cyber requirement test coverage
Patch release marking full requirement→test traceability.
Highlights
- 331/331 requirements test-traced (100%), up from 51% (166/322): 314 ISO 26262 (FuSa) + 8 IEC 62443 (cyber) + 9 RELAY/CLI conformance.
- Every module now has a
tests/test_<module>.cpp; 41 CTest suites, 323 TEST_CASEs. - Added tests for the 14 previously-untested modules (CAN/DDS/DoIP/gRPC/LIN/MQTT/REST/SOME-IP/UDS bridges, TSN, mDNS, powerstate, TLS) and filled requirement gaps in 12 existing suites (thread-safety, failover, latency budget, multi-chunk OTA, value semantics, context deadlines).
- Declared the previously-undeclared CLI/RELAY conformance requirements and corrected
fusa:testtraceability tags. rcp::kVersion→ 1.0.1; CMake project version synced. RELAYspec_versionunchanged at 1.0; no library behaviour change.
PRs #19 (coverage) + #20 (release). CI green on the full 5-platform matrix plus cpfusa trace/cyber/verify gates.