Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 24 additions & 24 deletions .fusa-reqs.json
Original file line number Diff line number Diff line change
Expand Up @@ -754,96 +754,96 @@
},
{
"id": "REQ-UDP-001",
"title": "Header magic bytes 'RC'",
"text": "All wire frames shall begin with the two-byte sequence 0x52 ('R'), 0x43 ('C').",
"title": "Frame round-trips an NTSCF-framed ACF_ABB request",
"text": "rcp::udp::encode_frame/decode_frame shall round-trip a Frame carrying an NTSCF header (rcp::avtp::NtscfHeader) wrapping an ACF_ABB message (rcp::acf::AcfMessageInfo) unchanged: stream_id, sequence_num, the request's byte_bus_id/transaction_num/op, and its payload shall all be recoverable from the encoded bytes.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-UDP-002",
"title": "Protocol version field",
"text": "All wire frames shall carry the protocol version (currently 0x01) in byte 2.",
"title": "Frame round-trips a TSCF-framed request with avtp_timestamp",
"text": "rcp::udp::encode_frame/decode_frame shall round-trip a Frame carrying a TSCF header (rcp::avtp::TscfHeader), including its timestamp_valid flag and 32-bit avtp_timestamp, unchanged.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-UDP-003",
"title": "Message type field",
"text": "Byte 3 of every wire frame shall encode the message type: Command, Response, Status, Subscribe, or Unsubscribe.",
"title": "Frame round-trips an ACF_GBB message_timestamp",
"text": "rcp::udp::encode_frame/decode_frame shall round-trip a Frame whose AcfMessageInfo::acf_msg_type is kAcfMsgTypeGbb, including its mtv flag, 64-bit message_timestamp, and payload, unchanged.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-UDP-004",
"title": "Zone field",
"text": "Bytes 4 of every wire frame shall encode the target Zone as a uint8.",
"title": "decode_frame rejects a buffer shorter than the AVTPDU header",
"text": "rcp::udp::decode_frame shall return a non-zero std::error_code when given fewer bytes than the AVTPDU header (NTSCF or TSCF, selected by the subtype byte) requires.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-UDP-005",
"title": "CommandType field for commands",
"text": "Bytes 5\u20136 of Command frames shall encode the CommandType as a big-endian uint16.",
"title": "decode_frame rejects a buffer shorter than the ACF common header",
"text": "rcp::udp::decode_frame shall return a non-zero std::error_code when the AVTPDU header decodes successfully but fewer bytes than the 10-byte ACF common header (rcp::acf::kAcfCommonHeaderLen) remain.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-UDP-006",
"title": "Priority/Status field",
"text": "Byte 7 shall encode Priority for Command frames, ResponseStatus for Response frames, and Healthy flag for Status frames.",
"title": "decode_frame rejects an unrecognized ACF message type",
"text": "rcp::udp::decode_frame shall return a non-zero std::error_code when the byte immediately following a valid AVTPDU header is neither rcp::acf::kAcfMsgTypeAbb nor rcp::acf::kAcfMsgTypeGbb.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-UDP-007",
"title": "Command/response ID field",
"text": "Bytes 8\u201311 shall encode the Command or Response ID as a big-endian uint32.",
"title": "Server dispatches a decoded request through its handler and answers the sender",
"text": "rcp::udp::Server shall decode each inbound UDP datagram as a Frame, invoke its registered Handler with the decoded AcfMessageInfo and payload, and send the handler's response back to the originating sender address, framed under the same NTSCF/TSCF header kind the request arrived under.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-UDP-008",
"title": "Payload length field",
"text": "Bytes 12\u201315 shall encode the payload byte count as a big-endian uint32.",
"title": "Server answers Acknowledge by default when no handler is registered",
"text": "rcp::udp::Server shall respond to a decoded request with rcp::acf::ResponseKind::Acknowledge when no Handler has been set via set_handler.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-UDP-009",
"title": "Payload follows header",
"text": "The variable-length payload shall immediately follow the 16-byte header.",
"title": "Server assigns stable per-sender client ids",
"text": "rcp::udp::Server shall pass the same opaque client id to its Handler for every request originating from the same sender address, and a distinct id for a request from a different sender address.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-UDP-010",
"title": "Big-endian multi-byte fields",
"text": "All multi-byte fields in wire frames shall be encoded in big-endian (network) byte order.",
"title": "Client::request returns ErrTimeout when no response arrives",
"text": "rcp::udp::Client::request shall return rcp::ErrTimeout when the supplied rcp::Context's deadline elapses before a matching response frame is received.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-UDP-011",
"title": "Frame validation rejects bad magic",
"text": "The decoder shall return an error if frame bytes 0\u20131 are not 0x52, 0x43.",
"title": "Client::request correlates concurrent requests by byte_bus_id/transaction_num",
"text": "rcp::udp::Client::request shall match each inbound response frame to the pending request whose AcfMessageInfo::byte_bus_id and AcfMessageInfo::transaction_num it echoes, so that two outstanding requests with distinct (byte_bus_id, transaction_num) pairs each receive their own response.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-UDP-012",
"title": "Frame validation rejects bad version",
"text": "The decoder shall return an error if the version byte does not equal the supported protocol version.",
"title": "Server and Client close() are idempotent and requests after close fail",
"text": "rcp::udp::Server::close and rcp::udp::Client::close shall be safe to call more than once without blocking indefinitely or crashing, and rcp::udp::Client::request shall return rcp::ErrClosed once the Client has been closed.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.21)

project(cpp-rcp
VERSION 2.12.0
VERSION 2.13.0
DESCRIPTION "Remote Control Protocol for automotive zonal architecture (C++)"
HOMEPAGE_URL "https://github.com/SoundMatt/cpp-RCP"
LANGUAGES CXX
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,12 @@ reference.

| Header | Description |
|---|---|
| `<rcp/udp.hpp>` | Pure-C++ UDP transport for the RCP protocol (still framed via `<rcp/legacy_wire.hpp>` until v2.13.0) |
| `<rcp/udp.hpp>` | Native IEEE 1722-over-UDP/IP transport (Annex J): `Server`/`Client` carry AVTPDU (NTSCF/TSCF) + ACF_ABB/ACF_GBB frames over UDP sockets (ROADMAP.md v2.13.0) |
| `<rcp/tls.hpp>` | Mutual TLS transport for zone controller communication |
| `<rcp/shmem.hpp>` | Zero-copy intra-host command delivery via shared in-process memory |
| `<rcp/tsn.hpp>` | IEEE 802.1Qbv-aware UDP transport adapter for hard real-time Ethernet |
| `<rcp/avtp.hpp>` | TC18 wire codec, framing half — IEEE 1722 AVTPDU (NTSCF/TSCF) header framing (ROADMAP.md v2.0.0) |
| `<rcp/acf.hpp>` | TC18 wire codec, message half — ACF_ABB/ACF_GBB message format (ROADMAP.md v2.0.0) |
| `<rcp/legacy_wire.hpp>` | Pre-replacement 16-byte frame codec, kept only for `<rcp/udp.hpp>`'s internal use until it is rebuilt at v2.13.0 |
| `<rcp/sim.hpp>` | Timing-realistic RC Server simulator for SiL/HIL testing — wraps `<rcp/mock.hpp>` with latency/jitter and Fault/Recover controls, watchdog wired via `<rcp/watchdog.hpp>` (ROADMAP.md v2.12.0) |

## Build
Expand Down
39 changes: 39 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,45 @@ disclaimers in `rcp/regmap.hpp`, `rcp/lifecycle.hpp`, `rcp/gpio.hpp`, and
it *is* the old wire format this whole roadmap replaces
- Depends on: Wire format core (v2.0.0)

**Done (v2.13.0):** `rcp/udp.hpp` is replaced in full, per the Satellite
Package Disposition table's entry for this file — the bespoke `R`/`C`-magic
16-byte Zone/Command/Response/Status frame this file used to carry
(`rcp/legacy_wire.hpp`) is discarded outright, not adapted, matching the
roadmap's own call for this milestone. `udp::Frame`/`encode_frame`/
`decode_frame` compose `rcp/avtp.hpp`'s NTSCF/TSCF header codec with
`rcp/acf.hpp`'s ACF_ABB/ACF_GBB message codec into one AVTPDU, carried as
the UDP datagram payload unmodified — this implementation's own reading of
IEEE 1722 Annex J's UDP/IP encapsulation, consistent with `rcp/avtp.hpp`'s
own header comment that its framing is transport-agnostic by design; no
additional encapsulation header is layered on top. `udp::Server` binds a UDP
socket, decodes each inbound datagram as a `Frame`, dispatches the carried
ACF request to a caller-supplied `Handler` shaped to match
`rcp::mock::Server::dispatch`'s signature (v2.12.0) so that simulator can be
wired up as this transport's handler directly, and answers the sender under
the same NTSCF/TSCF header kind the request arrived under; distinct sender
addresses are assigned stable, distinct opaque client ids, first-seen order.
`udp::Client` connects to one server address and correlates each response by
the `(byte_bus_id, transaction_num)` echo rule `rcp/acf.hpp`'s
`make_response` documents, rather than a locally invented request id — the
new addressing model has no analog of the old `Command::id`. Neither class
builds on `rcp.hpp`'s `Zone`/`Command`/`Controller`/`Registry` model, per
that file's own header comment that nothing new should; `udp::Registry`'s
old Zone-keyed controller-collection role has no replacement here since
addressing moved to stream/byte_bus_id. Grepping the tree for consumers of
the old `udp::ZoneServer`/`udp::Controller`/`udp::Registry` API before this
change found none beyond this file's own (now-deleted) test and
`rcp/tsn.hpp`'s doc comment — `rcp/tsn.hpp` itself only ever depended on the
generic `rcp::Controller` interface plus a raw socket fd, never on `udp::`
types directly — so no legacy-shim split file was needed here, unlike
`rcp/mock.hpp`'s at v2.12.0; `rcp/legacy_wire.hpp` is deleted outright in the
same change. New coverage lives in `tests/test_udp.cpp` (`REQ-UDP-001..012`,
entirely rewritten under the same file/prefix identity as the discarded
pre-replacement coverage, the same convention `tests/test_sim.cpp`'s
`REQ-SIM-001..007` rewrite followed at v2.12.0), traced in `.fusa-reqs.json`.
Full bit-for-bit conformance against other TC18/Annex-J implementations is
not claimed, same as the equivalent disclaimers in `rcp/avtp.hpp`,
`rcp/acf.hpp`, and `rcp/discovery.hpp`.

### 58. Auxiliary Transport & Cross-Cutting Rebind (v2.14.0)

- `mdns.hpp`: narrow its scope to the UDP/IP transport variant specifically
Expand Down
14 changes: 8 additions & 6 deletions include/rcp/avtp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
//
// ROADMAP.md milestone 44, "Wire Format Core (v2.0.0)": this header (plus
// rcp/acf.hpp) replaces the old bespoke 16-byte frame this file used to
// define (now preserved as-is, unrenamed in behavior, under
// rcp/legacy_wire.hpp for rcp/udp.hpp's benefit until the transport itself
// is rebuilt at v2.13.0). Originally landed as a single rcp/wire.hpp; split
// into rcp/avtp.hpp (this file, AVTPDU header framing) and rcp/acf.hpp
// (ACF_ABB/ACF_GBB message format) per RELAY spec §13.7.2's standard
// module-name registry, which names these two concerns separately.
// define (preserved as-is, unrenamed in behavior, under rcp/legacy_wire.hpp
// for rcp/udp.hpp's benefit from v2.0.0 through v2.12.0, until rcp/udp.hpp
// was itself rebuilt directly on this header and rcp/acf.hpp — and
// rcp/legacy_wire.hpp deleted outright — at milestone 57, v2.13.0).
// Originally landed as a single rcp/wire.hpp; split into rcp/avtp.hpp (this
// file, AVTPDU header framing) and rcp/acf.hpp (ACF_ABB/ACF_GBB message
// format) per RELAY spec §13.7.2's standard module-name registry, which
// names these two concerns separately.
//
// Scope note: this module is a pure wire codec. It has no dependency on
// rcp.hpp's Zone/Command/Controller/Registry model, and no dependency on any
Expand Down
Loading
Loading