Skip to content

rewrite(phase3): port can/lin from c-RCP, wire CAN XL fragmentation via fragment.hpp - #136

Merged
SoundMatt merged 1 commit into
rewrite/v3-from-c-rcpfrom
phase3/can-lin
Aug 21, 2026
Merged

SoundMatt merged 1 commit into
rewrite/v3-from-c-rcpfrom
phase3/can-lin

Conversation

@SoundMatt

Copy link
Copy Markdown
Owner

Part of the v3.0.0 ground-up rewrite (#129, ROADMAP.md Phase 17). Second of Phase 3's Wave 1 batches, alongside iseled/i2c and adc/gpio (separate PRs).

can.hpp

Pre-rewrite header was validation-only — its own v2.24.0 ROADMAP.md note said 'no ACF-level wire encode/decode ... anywhere in this codebase'. Ported the real wire codec. FrameFormat widened from an invented 3-value set to c-RCP's real 6-value Table 57 set, each with its own id width derived from format — fixes a real defect where the old extended flag was settable independently of FrameFormat, permitting contradictory states. sync_jump_width type and a default value both corrected to match c-RCP exactly. Ported CanFunctionalConfig + Table 56 EP_func register block, including c-RCP issue #470's enable&clr bit-4 fix (was bit 1) ported forward correctly.

CAN XL fragmentation wired via Phase 1's fragment.hpp — the centerpiece of this batch: request/response fragment-count/encode/decode/reassemble, all built on fragment::plan_count()/plan()/Reassembler. Fixed std::array buffers (2058 octets/256 segments, c-RCP's own bounds), no heap allocation. Tests round-trip a worst-case 2048-octet CAN XL write/read end to end and prove the c-RCP #614/#616 oversized-reassembly lesson holds (kErrTooLarge, not silent truncation).

lin.hpp

None of this existed in the pre-rewrite header: response_matches() (wraps the already-ported acf::compound_wait_match), LinTrigger, LinFunctionalConfig + Table 55 register block, and the real request/response wire codec.

test_can.cpp: 20→43 cases. test_lin.cpp: 12→28 cases.

Call sites touched

None — mock.hpp confirmed unchanged, its own suite passes against the new headers unmodified.

Verified

Full tree rebuilds clean (223/223 targets), 56/56 ctest suites pass (100%) — independently re-verified from a fresh build.

Tracked at #129.

…ia fragment.hpp

Part of the v3.0.0 ground-up rewrite (cpp-RCP #129, ROADMAP.md Phase 17),
branch rewrite/v3-from-c-rcp. Second of Phase 3's Wave 1 batches,
alongside iseled/i2c and adc/gpio (separate PRs).

can.hpp: the pre-rewrite header was validation-only -- its own v2.24.0
ROADMAP.md note said 'no ACF-level wire encode/decode ... anywhere in
this codebase'. Ported the real wire codec from ep_can.c's
rcp_ep_can_encode_frame_request/response, _decode_frame_request/
response. FrameFormat widened from an invented 3-value
{Classical,Fd,Xl} to c-RCP's real 6-value Table 57 set (Cbff/Ceff/Fbff/
Feff/XlClassicalPl/XlNewPl), each with its own 11-/29-bit id width
derived from format -- fixes a real defect where the old
CanIdentifier::extended flag was settable independently of FrameFormat,
permitting contradictory states. CanBitTimingPhase::sync_jump_width
corrected uint16_t->uint8_t; default prescaler corrected 1->0 to match
c-RCP's zero-init contract. Ported CanFunctionalConfig (three bit-
timing sets, delay compensation, xl_filters[4]) and the Table 56
EP_func register block, porting forward c-RCP issue #470's enable&clr
bit-4 fix (was bit 1) directly rather than re-introducing the bug.

CAN XL fragmentation (c-RCP issues #610/#611/#612/#613) wired via
Phase 1's fragment.hpp: frame_request_fragment_count()/
encode_frame_request_fragmented() and the response-side
count/encode/decode/reassemble quartet, all built on
fragment::plan_count()/plan()/Segment and fragment::Reassembler.
Combined-payload and fragment-plan buffers are fixed std::array (2058
octets / 256 segments, c-RCP issue #521's bounds) -- no heap
allocation. Tests round-trip a worst-case 2048-octet CAN XL write
request and read response end to end through Reassembler, and prove
the c-RCP #614/#616 oversized-reassembly lesson holds (kErrTooLarge,
not silent truncation, both immediately and partway through a
multi-fragment sequence).

lin.hpp: ported response_matches() (thin wrapper over the already-
ported acf::compound_wait_match), LinTrigger/trigger_fires(),
LinFunctionalConfig + Table 55 register block, and the real
encode_command_request/decode_command_request/encode_response/
decode_response wire codec -- none of this existed in the pre-rewrite
header.

Fixed-capacity: kXlMaxEncodedLen/kMaxFragmentSegments/kMaxXlFilters all
std::array-backed, ported from c-RCP's own bound constants.
CanDataFrame::data/LinEndpoint's byte buffers deliberately stayed
std::vector<uint8_t> -- mock.hpp assigns from a
const std::vector<uint8_t>&, which wouldn't compile against a fixed
array.

test_can.cpp: 20 -> 43 TEST_CASEs (267 assertions).
test_lin.cpp: 12 -> 28 TEST_CASEs (103 assertions).

Call sites touched: none. mock.hpp confirmed unchanged and its own
test suite passes against the new headers unmodified.

Left as // TODO(phase3-followup) in both headers: once regmap.hpp's
functional-config split is re-derived from c-RCP (Phase 17 item 4),
recompose the five local ep_enable/ep_clear_req_storage/
ep_req_crc_enable/ep_response_ts_enable/ep_suppress_response flags onto
that shared struct instead of carrying local duplicates. can.hpp also
documents (not a TODO, a deferral matching c-RCP's own disposition)
that Table 56's acceptance-filter register region has a genuine
unresolved address-collision defect in the primary source, so this
module's register-block model deliberately stops at kEpFuncLen.

Verified: full tree rebuilds clean (223/223 targets), 56/56 ctest
suites pass (100%) -- independently re-verified from a fresh build, not
just the porting agent's own report.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Matt <47545907+SoundMatt@users.noreply.github.com>
@SoundMatt
SoundMatt merged commit 2eba2ac into rewrite/v3-from-c-rcp Aug 21, 2026
22 checks passed
@SoundMatt
SoundMatt deleted the phase3/can-lin branch August 21, 2026 20:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant