You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 7facb88
Browse filesBrowse the repository at this point in the historyBrowse files
fix: v2.22.0 — ACF_GBB message_timestamp is spliced between the header quadlets (#100)
encode_acf_gbb/decode_acf_gbb placed the 64-bit message_timestamp after the
complete 8-byte shared Message Info header (wire octet 8). TC18 splices it
between that header's two 4-byte quadlets (wire octet 4), which pushes
evt/rsv/hs/cs/transaction_num/op/rsp/err/ms/read_size_or_segment_num from
octet 8 to octet 12. Total message length was unaffected, and this codec
round-tripped against itself perfectly, which is why neither the v2.19.0
bit-packing pass nor the v2.20.0 acf_msg_length pass caught it — but every
ACF_GBB message this library emitted was unreadable by a conformant peer,
and every ACF_GBB E2E CRC was computed over the wrong byte sequence.
ACF_ABB is unaffected: it has no timestamp field.
Verified against the specification PDF's own figures (rendered at high DPI
and read directly, not inferred from this codec) four independent ways:
the single-ACF_GBB CRC-coverage figure's three-row "Byte Message Info"
group (quadlet 0, 64-bit message_time_stamp, quadlet 1); that figure's own
stated acf_msg_length 0x07 = 28 octets, which only closes as
4 + 8 + 4 + 8 + 4 (its ACF_ABB counterpart states 0x05 = 20 = 4 + 4 + 8 + 4);
the compound-request figure, where the mtv=0 repurposing fields occupy
octets 4..11 between the same two quadlets; and the response-field table,
which lists message_timestamp between byte_bus_id and evt.
- acf.hpp: new kAcfHeaderQuadletLen/kAcfGbbTimestampOffset/
kAcfGbbSecondQuadletOffset/kAcfGbbMessageInfoLen and
encode_acf_gbb_message_info/decode_acf_gbb_message_info, which own the
spliced byte geometry and delegate all bit packing to the existing
encode/decode_acf_message_info. encode_acf_gbb, decode_acf_gbb and
decode_acf_messages route through them.
- e2e.hpp: coverage_buffer hand-serialized the same wrong order; it now
calls acf::encode_acf_gbb_message_info, so the CRC-covered bytes equal
the transmitted bytes by construction.
- udp.hpp/l2.hpp/record.hpp needed no change (all route through the codec,
no hardcoded offsets). request.hpp needed none either (it deals in the
slot's value, not its position) and gained only a comment.
- tests: test_acf.cpp and test_e2e.cpp had pinned the bug as correct by
reading back the encoder's own output. Rewritten around literal
spec-derived octet positions with the derivation spelled out, plus a new
full-message conformance vector reproducing the CRC-coverage figure's
message octet for octet and asserted in both directions. Mutation-checked:
restoring the old offsets fails 4 test cases.
- .fusa-reqs.json: REQ-WIRE-005/REQ-E2E-002 now state exact octet positions
(REQ-E2E-002 also still said "10-byte ACF shared header", stale since
v2.19.0 made it 8); REQ-SEQ-001 records where the repurposed slot sits.
Wire-format-breaking for ACF_GBB only; no public API signature changes.
kVersion/CMakeLists.txt 2.21.0 -> 2.22.0. Build clean, ctest 53/53.
Signed-off-by: Matt <47545907+SoundMatt@users.noreply.github.com>
Copy file name to clipboardExpand all lines: .fusa-reqs.json
+6-6Lines changed: 6 additions & 6 deletions
Original file line number
Diff line number
Diff line change
@@ -267,7 +267,7 @@
267
267
{
268
268
"id": "REQ-E2E-002",
269
269
"title": "CRC coverage buffer layout",
270
-
"text": "rcp::e2e::coverage_buffer shall assemble, in order, the 8-byte big-endian stream_id, the 4-byte big-endian avtp_timestamp (zero-filled when std::nullopt is passed, the NTSCF stand-in), the 10-byte ACF shared header, and the payload; rcp::e2e::compute_crc shall compute the CRC over exactly that buffer.",
270
+
"text": "rcp::e2e::coverage_buffer shall assemble, in order, the 8-byte big-endian stream_id, the 4-byte big-endian avtp_timestamp (zero-filled when std::nullopt is passed, the NTSCF stand-in), the ACF Message Info block in its exact on-the-wire byte order, and the payload; rcp::e2e::compute_crc shall compute the CRC over exactly that buffer. The Message Info block is the contiguous 8-byte shared header for ACF_ABB, and for ACF_GBB is the 16-byte form in which the 64-bit big-endian message_timestamp is spliced between the shared header's two quadlets (block octets 0-3 = quadlet 0, octets 4-11 = message_timestamp, octets 12-15 = quadlet 1), so that the CRC covers byte-for-byte the octets rcp::acf::encode_acf_gbb transmits.",
271
271
"standard": "iso26262",
272
272
"level": "ASIL-B",
273
273
"asil": "ASIL-B"
@@ -1923,7 +1923,7 @@
1923
1923
{
1924
1924
"id": "REQ-WIRE-005",
1925
1925
"title": "ACF_GBB carries a 64-bit message_timestamp",
1926
-
"text": "encode_acf_gbb/decode_acf_gbb shall round-trip the shared ACF header, a 64-bit message_timestamp value, and the payload unchanged for an ACF_GBB (0x0D) message.",
1926
+
"text": "encode_acf_gbb/decode_acf_gbb shall round-trip the shared ACF header, a 64-bit message_timestamp value, and the payload unchanged for an ACF_GBB (0x0D) message, and shall place them on the wire in the order octets 0-3 = shared-header quadlet 0 (acf_msg_type/acf_msg_length/pad/mtv/rsv/byte_bus_id), octets 4-11 = message_timestamp big-endian, octets 12-15 = shared-header quadlet 1 (evt/rsv/hs/cs/transaction_num/op/rsp/err/ms/read_size_or_segment_num), octets 16 onwards = byte_msg_payload.",
"text": "rcp::acf::ControlFlags shall define FlagAck/FlagRead/FlagWrite/FlagResponse/FlagError/FlagMoreSegments at bit values 0x80/0x40/0x20/0x10/0x08/0x04 respectively, matching RELAY spec §15.5's Go definition exactly; rcp::acf::to_message/from_message shall convert between AcfMessageInfo and the RELAY spec §15.5 canonical Message shape, preserving byte_bus_id, transaction_num, read_size_or_segment, and body, and carrying message_timestamp only for the ACF_GBB encoding.",
"text": "rcp::acf::ControlFlags shall define FlagAck/FlagRead/FlagWrite/FlagResponse/FlagError/FlagMoreSegments at bit values 0x80/0x40/0x20/0x10/0x08/0x04 respectively, matching RELAY spec \u00a715.5's Go definition exactly; rcp::acf::to_message/from_message shall convert between AcfMessageInfo and the RELAY spec \u00a715.5 canonical Message shape, preserving byte_bus_id, transaction_num, read_size_or_segment, and body, and carrying message_timestamp only for the ACF_GBB encoding.",
"text": "rcp::request::decode_request_type shall return RequestErrc::timestamp_not_repurposed when mtv is true, shall return RequestErrc::unknown_request_type when the top byte of message_timestamp is not one of the 8 defined opcodes, and shall otherwise recover the opcode and the remaining 7 parameter bytes exactly as produced by encode_request_type for the same inputs; rcp::request::make_conditional_request shall always build an ACF_GBB AcfMessageInfo with mtv clear.",
2614
+
"text": "rcp::request::decode_request_type shall return RequestErrc::timestamp_not_repurposed when mtv is true, shall return RequestErrc::unknown_request_type when the top byte of message_timestamp is not one of the 8 defined opcodes, and shall otherwise recover the opcode and the remaining 7 parameter bytes exactly as produced by encode_request_type for the same inputs; rcp::request::make_conditional_request shall always build an ACF_GBB AcfMessageInfo with mtv clear. The repurposed slot is the ACF_GBB message_timestamp slot at wire octets 4-11 (see REQ-WIRE-005), whose first octet carries the opcode.",
2615
2615
"standard": "iso26262",
2616
2616
"level": "ASIL-B",
2617
2617
"asil": "ASIL-B"
@@ -2987,7 +2987,7 @@
2987
2987
{
2988
2988
"id": "REQ-L2-007",
2989
2989
"title": "MultiFrame round-trips two ACF_ABB messages packed into one L2 frame",
2990
-
"text": "rcp::l2::encode_l2_multi_frame/decode_l2_multi_frame shall round-trip two or more ACF_ABB/ACF_GBB messages packed into a single Ethernet frame's AVTPDU, per extraction §12.9.1.1's multiple-requests-in-one-frame requirement, the same as rcp::udp::MultiFrame's equivalent guarantee.",
2990
+
"text": "rcp::l2::encode_l2_multi_frame/decode_l2_multi_frame shall round-trip two or more ACF_ABB/ACF_GBB messages packed into a single Ethernet frame's AVTPDU, per extraction \u00a712.9.1.1's multiple-requests-in-one-frame requirement, the same as rcp::udp::MultiFrame's equivalent guarantee.",
|`<rcp/acf.hpp>`| TC18 wire codec, message half — ACF_ABB/ACF_GBB message format, `AcfMessageInfo`. ACF_ABB Message Info is 8 contiguous octets; ACF_GBB is 16, with the 64-bit `message_timestamp` spliced between the header's two quadlets (octets 0–3 quadlet 0, 4–11 timestamp, 12–15 quadlet 1) — corrected in v2.22.0, see ROADMAP.md milestone 66|
26
26
|`<rcp/regmap.hpp>`| RC Server register-map model (generic + functional config, EP0) |
27
27
|`<rcp/lifecycle.hpp>`| RC Server lifecycle state machine |
@@ -134,6 +134,8 @@ work, since every endpoint type's functional config block depends on it.
134
134
|**Phase 16**| v2.18.0 | Certification refresh | HARA/TARA/FMEA/formal verification/audit pack regenerated against the new requirement set |
135
135
|**Phase 16**| v2.19.0 | Wire format conformance fix pass |`avtp.hpp`/`acf.hpp` NTSCF/TSCF/ACF Message Info bit-packing re-derived from the specification's own header diagrams; `e2e.hpp` CRC coverage and numeric error-code mapping corrected to match |
136
136
|**Phase 16**| v2.20.0 | TC18 conformance fix pass II |`acf_msg_length` actually computed; multiple-requests-in-one-frame (§12.9.1.1) supported; error responses carry a Table 27 error code; GPIO exact-length payload check; ISELED gains a real wire codec; PWM_IN rising/falling-edge triggers; `control_data_length` validated |
137
+
|**Phase 16**| v2.21.0 | L2 (native Ethernet) transport + UDP Annex J conformance fix | New `l2.hpp` raw-Ethernet transport (EtherType 0x22F0); `udp.hpp` gains Annex J's 4-byte encapsulation sequence number and port 17221 default |
138
+
|**Phase 16**| v2.22.0 | ACF_GBB `message_timestamp` wire-position fix | The 64-bit `message_timestamp` is spliced *between* the ACF Message Info header's two quadlets (octet 4), not appended after both (octet 8); `e2e.hpp` CRC coverage follows; wire-breaking for ACF_GBB only |
137
139
|**Phase 16**| v3.0.0 |**TC18 RCP — General Availability**| First release where cpp-RCP *is* the OPEN Alliance TC18 Remote Control Protocol |
138
140
139
141
---
@@ -175,7 +177,9 @@ incrementally through v2.6.0 per the Phase 13 introduction above.
0 commit comments