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
208 changes: 208 additions & 0 deletions .fusa-reqs.json
Original file line number Diff line number Diff line change
Expand Up @@ -3503,6 +3503,214 @@
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-LINEP-001",
"title": "LIN's ep_type id is 0x06",
"text": "rcp::endpoint::kEndpointTypeLin shall equal 0x06.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-LINEP-002",
"title": "LIN is a raw-byte-pusher with no frame-level concepts",
"text": "rcp::lin::LinEndpoint::transfer shall record the exact byte sequences passed as out_bytes and in_bytes, retrievable via last_sent()/last_received(), performing no checksum selection, PID generation, schedule-table lookup, or any other LIN frame-structure interpretation of either sequence, including for an empty byte sequence.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-LINEP-003",
"title": "LIN TransferComplete and NoResponse trigger signals",
"text": "rcp::lin::LinEndpoint::transfer shall notify only TransferComplete for a responded transfer (responded=true) and shall notify only NoResponse and return LinErrc::no_response for an unresponded transfer (responded=false).",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-LINEP-004",
"title": "LinErrc is a distinct error category with a non-empty message",
"text": "rcp::lin::make_error_code(LinErrc::no_response) shall report rcp::lin::lin_category() as its category and shall have a non-empty diagnostic message.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-CANEP-001",
"title": "CAN's ep_type id is 0x0B",
"text": "rcp::endpoint::kEndpointTypeCan shall equal 0x0B.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-CANEP-002",
"title": "CAN identifier range validation",
"text": "rcp::can::validate_identifier shall accept a CanIdentifier whose value is within its own width's range (0..0x7FF for extended=false, 0..0x1FFFFFFF for extended=true) and shall return CanErrc::identifier_out_of_range for a value exceeding that range.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-CANEP-003",
"title": "CAN frame-format payload ceilings, data frames only",
"text": "rcp::can::validate_frame shall accept a CanDataFrame whose data length is within its FrameFormat's own ceiling (kMaxClassicalPayload=8 for Classical, kMaxFdPayload=64 for Fd) and shall return CanErrc::payload_exceeds_format_limit when that ceiling is exceeded; this header shall define no remote-frame request or response shape.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-CANEP-004",
"title": "CAN XL accepted single-AVTPDU payload limitation",
"text": "rcp::can::validate_frame shall accept a FrameFormat::Xl frame whose data length is within kMaxXlPayloadSingleAvtpdu, shall return CanErrc::xl_payload_exceeds_single_avtpdu_bound for a length between kMaxXlPayloadSingleAvtpdu (exclusive) and kMaxXlPayloadSpec (inclusive), and shall return CanErrc::payload_exceeds_format_limit for a length exceeding kMaxXlPayloadSpec (2054), consistent with ROADMAP.md milestone 52's already-decided fragmentation no-go.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-CANEP-005",
"title": "CAN per-phase bit-timing register sets",
"text": "rcp::can::CanEndpoint::configure_bit_timing shall store the arbitration, fd_data, and xl_data CanBitTimingPhase register sets independently of one another, retrievable unchanged via bit_timing().",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-CANEP-006",
"title": "CAN-XL-specific acceptance/receive filters",
"text": "rcp::can::CanEndpoint::receive shall accept every frame when its format-scoped filter bank is empty, shall drop a frame matching no entry in that bank when the bank is non-empty (per rcp::can::acceptance_filter_matches's masked-id comparison), and shall match a FrameFormat::Xl frame against xl_receive_filters rather than the general acceptance_filters bank whenever xl_receive_filters is non-empty.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-CANEP-007",
"title": "CAN has no trigger-signal table; CanErrc is a distinct error category",
"text": "rcp::can::CanEndpoint shall expose no TriggerRegistry accessor or signal-id helper, unlike every other device-facing endpoint type in this codebase, and rcp::can::make_error_code(CanErrc::identifier_out_of_range) shall report rcp::can::can_category() as its category with a non-empty diagnostic message.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-ISELED-001",
"title": "ISELED's ep_type id is 0x0C",
"text": "rcp::endpoint::kEndpointTypeIseled shall equal 0x0C.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-ISELED-002",
"title": "ISELED Instruction/Address/Data request and Address/Data(/CRC) response shape",
"text": "rcp::iseled::IseledEndpoint::transact shall record the exact IseledRequest (instruction/address/data) and IseledResponse (address/data/optional native_crc) fields passed to it, retrievable via last_request()/last_response().",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-ISELED-003",
"title": "ISELED native CRC is additional to, not a replacement for, the general E2E CRC",
"text": "rcp::iseled::verify_native_crc shall succeed without error when IseledResponse::native_crc is std::nullopt, shall succeed when native_crc equals compute_native_crc8(crc_coverage_bytes(response)), and shall return IseledErrc::native_crc_mismatch when it does not; this header shall have no dependency on and shall not call into rcp/e2e.hpp.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-ISELED-004",
"title": "ISELED TransferComplete and NativeCrcError trigger signals",
"text": "rcp::iseled::IseledEndpoint::transact shall notify only TransferComplete for a transaction whose response native CRC verifies (or carries none), and shall notify only NativeCrcError and return IseledErrc::native_crc_mismatch for a transaction whose response native CRC does not verify.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-ISELED-005",
"title": "IseledErrc is a distinct error category with a non-empty message",
"text": "rcp::iseled::make_error_code(IseledErrc::native_crc_mismatch) shall report rcp::iseled::iseled_category() as its category and shall have a non-empty diagnostic message.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-MDIO-001",
"title": "MDIO's ep_type id is 0x0D",
"text": "rcp::endpoint::kEndpointTypeMdio shall equal 0x0D.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-MDIO-002",
"title": "MDIO address-range validation",
"text": "rcp::mdio::validate_request shall return MdioErrc::phy_address_out_of_range for phy_address > kMaxPhyAddress, MdioErrc::device_or_reg_out_of_range for device_or_reg > kMaxDeviceOrRegField, and shall accept every field at or below its own bound.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-MDIO-003",
"title": "MDIO Clause22 flat register write-then-read round-trip",
"text": "rcp::mdio::MdioEndpoint::handle_request shall, for MdioClause::Clause22, return the value most recently written to a given (phy_address, device_or_reg) register on a subsequent read, and shall return 0 for a register that has never been written.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-MDIO-004",
"title": "MDIO Clause45 device+register addressing is distinct from Clause22's address space",
"text": "rcp::mdio::MdioEndpoint::handle_request shall key a Clause45 access on (phy_address, device_or_reg, register_address) such that it never observes a value written via MdioClause::Clause22 at the same phy_address/device_or_reg bit pattern, or vice versa, and shall notify TransferComplete on every request regardless of clause.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-MDIO-005",
"title": "MdioErrc is a distinct error category with a non-empty message",
"text": "rcp::mdio::make_error_code(MdioErrc::phy_address_out_of_range) shall report rcp::mdio::mdio_category() as its category and shall have a non-empty diagnostic message.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-WAKEUP-001",
"title": "Wakeup control's ep_type id is 0x01",
"text": "rcp::endpoint::kEndpointTypeWakeup shall equal 0x01.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-WAKEUP-002",
"title": "SleepCMD is a fixed opcode, distinct from rcp::sequencer's RequestTypeOpcode taxonomy",
"text": "rcp::wakeup::kSleepCmd shall equal 0xA5; rcp::wakeup::decode_sleep_cmd shall accept only that exact byte value and return WakeupErrc::not_sleep_cmd for every other byte (including 0x8x safety-tagged sequencer opcode bytes); rcp::wakeup::WakeupEndpoint::handle_sleep_cmd shall transition to asleep on kSleepCmd and shall leave state unchanged and return an error for any other byte.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-WAKEUP-003",
"title": "Wake-source pin monitoring",
"text": "rcp::wakeup::WakeupEndpoint::record_wake_source_event shall set the corresponding bit in wake_source_pins() and shall clear is_asleep(), and clear_wake_source_pins() shall reset the accumulated mask to 0 without affecting is_asleep() or the handshake-pending state.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-WAKEUP-004",
"title": "Repeating WakeUp message handshake for hot-start-from-Sleep",
"text": "rcp::wakeup::WakeupEndpoint::record_wake_source_event shall arm wakeup_message_pending() until acknowledge_wakeup() is called, wakeup_message_pending() shall continue reporting true across repeated calls while armed, and handle_sleep_cmd(kSleepCmd) shall clear any handshake left pending from a prior wake cycle.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-WAKEUP-005",
"title": "WakeupErrc is a distinct error category with a non-empty message",
"text": "rcp::wakeup::make_error_code(WakeupErrc::not_sleep_cmd) shall report rcp::wakeup::wakeup_category() as its category and shall have a non-empty diagnostic message.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
}
]
}
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.6.0
VERSION 2.7.0
DESCRIPTION "Remote Control Protocol for automotive zonal architecture (C++)"
HOMEPAGE_URL "https://github.com/SoundMatt/cpp-RCP"
LANGUAGES CXX
Expand Down
60 changes: 60 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,66 @@ exist."

### 51. Remaining Endpoint Types — LIN, CAN (incl. CAN XL), ISELED, MDIO, Wakeup Control (v2.7.0)

**Done (v2.7.0):** `rcp/endpoint.hpp` gains the five remaining `ep_type` id
constants this milestone assigns (`kEndpointTypeWakeup`=`0x01`,
`kEndpointTypeLin`=`0x06`, `kEndpointTypeCan`=`0x0B`,
`kEndpointTypeIseled`=`0x0C`, `kEndpointTypeMdio`=`0x0D`), replacing the
comment placeholder milestone 48 left for them; `0x0A` (DAC) remains
deliberately unallocated per this milestone's explicit DAC-out-of-scope
call. `rcp/lin.hpp` implements the LIN commander (`ep_type 0x06`):
`LinEndpoint::transfer` is a pure raw-byte-pusher — it records exactly the
bytes passed to it in both directions and performs no checksum selection,
PID generation, or schedule-table lookup, deliberately breaking with any
frame-aware assumption the deprecated `linbr.hpp` bridge's era might imply
(that file remains untouched — DEPRECATE, not ADAPT, per the Satellite
Package Disposition table). `rcp/can.hpp` implements the CAN controller
(`ep_type 0x0B`): an explicit `FrameFormat` (Classical/Fd/Xl) selects each
format's own payload ceiling via `max_payload_for`/`validate_frame`, with no
remote-frame shape defined anywhere in the header; CAN XL's payload is
bounded by `kMaxXlPayloadSingleAvtpdu`, a conservative implementation-chosen
ceiling strictly below the specification's own 2054-byte
`kMaxXlPayloadSpec`, consistent with milestone 52's already-decided
fragmentation no-go — a payload between the two is reported via
`CanErrc::xl_payload_exceeds_single_avtpdu_bound` rather than silently
accepted or truncated; `CanBitTimingConfig` carries the three independent
per-phase register sets (arbitration/fd_data/xl_data); `CanEndpoint::receive`
matches CAN-XL frames against a separate `xl_receive_filters` bank distinct
from the general `acceptance_filters` bank; and `CanEndpoint` deliberately
exposes no `TriggerRegistry` at all — the one endpoint type in this codebase
without one, since the specification defines no trigger-signal table for
it. `rcp/iseled.hpp` implements ISELED (`ep_type 0x0C`):
`IseledEndpoint::transact` carries the Instruction/Address/Data request and
Address/Data/optional-native-CRC response shape, with `compute_native_crc8`/
`verify_native_crc` implementing that optional native CRC as a check fully
independent of — and with no dependency on — `rcp/e2e.hpp`'s general
RCP-level E2E CRC from v2.6.0, layered on top of it rather than replacing
any part of it. `rcp/mdio.hpp` implements MDIO (`ep_type 0x0D`):
`MdioRequest`/`MdioResponse` are Clause-22/Clause-45-mode-selected, with
`MdioEndpoint`'s internal `register_key` composition keeping Clause 22's
flat register address space and Clause 45's device+register address space
from ever colliding; this header defines no MDIO-specific functional-config
block, since the extraction calls for none beyond the common
generic/functional split. `rcp/wakeup.hpp` implements Wakeup control
(`ep_type 0x01`): `decode_sleep_cmd`/`WakeupEndpoint::handle_sleep_cmd`
decode the fixed `kSleepCmd` (`0xA5`) opcode via a single byte comparison
with no dependency on `rcp/sequencer.hpp`'s `RequestTypeOpcode` taxonomy;
`record_wake_source_event`/`wake_source_pins` track wake-source pin state;
and `wakeup_message_pending`/`acknowledge_wakeup` model the repeating
`WakeUp` message handshake milestone 53 (v2.9.0, Phase 14) depends on
directly. New coverage lives in `tests/test_lin.cpp` (REQ-LINEP-001..004),
`tests/test_can.cpp` (REQ-CANEP-001..007), `tests/test_iseled.cpp`
(REQ-ISELED-001..005), `tests/test_mdio.cpp` (REQ-MDIO-001..005), and
`tests/test_wakeup.cpp` (REQ-WAKEUP-001..005), traced in `.fusa-reqs.json`.
The `REQ-LINEP-*`/`REQ-CANEP-*` prefixes (rather than `REQ-LIN-*`/
`REQ-CAN-*`) are deliberate: those shorter ids are already in use by the
untouched, deprecated `linbr.hpp`/`canbr.hpp` bridge stubs' own requirements,
and this milestone's native endpoint types needed ids of their own rather
than colliding with them. DAC (`ep_type 0x0A`) has no header, no stub, and
no requirements — left entirely unbuilt per this milestone's explicit scope
call. Full wire-level conformance against other TC18 implementations is
still not claimed — see this file's own disclaimer pattern in
`rcp/wire.hpp`/`rcp/regmap.hpp`/`rcp/sequencer.hpp`/`rcp/e2e.hpp`.

- LIN commander (`ep_type 0x06`): raw-byte-pusher model with no
frame-level concepts (no checksum selection, no PID generation, no
schedule tables) — validate explicitly against any assumption in the
Expand Down
Loading
Loading