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
72 changes: 72 additions & 0 deletions .fusa-reqs.json
Original file line number Diff line number Diff line change
Expand Up @@ -2927,6 +2927,78 @@
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-DISC-001",
"title": "Discovery request framing \u2014 byte_bus_id 0, register-map address 0",
"text": "rcp::discovery::make_discovery_request shall build an unconditional ACF_ABB read (op=false) targeting byte_bus_id 0 (kDiscoveryByteBusId), and kDiscoveryRegisterAddress shall be 0, fixing discovery reads at the general bootstrap/magic-number register-map region.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-DISC-002",
"title": "Discovery is NTSCF-only; a TSCF-headed discovery request is dropped",
"text": "rcp::discovery::encode_discovery_request shall always produce an NTSCF-headed frame, and rcp::discovery::decode_discovery_request shall return DiscoveryErrc::tscf_headed_request_dropped without decoding further when given a frame whose AVTPDU subtype byte is TSCF.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-DISC-003",
"title": "The first discovery request claims the discovery stream",
"text": "DiscoveryClaim::on_discovery_request shall return ClaimOutcome::Claimed and record `client` as the claim holder when no active claim currently exists and server_state is HwUnconfigured or HwConfigured.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-DISC-004",
"title": "The discovery claim lapses after Discovery_TimeOut",
"text": "DiscoveryClaim shall treat a claim as lapsed once (now - claimed_at) is at least Discovery_TimeOut (kDefaultTimeout, ~20ms by default), after which may_configure shall return false for the prior holder and a subsequent discovery request from any client shall be able to claim the stream anew.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-DISC-005",
"title": "A claim does not block concurrent discovery reads from other clients",
"text": "DiscoveryClaim::on_discovery_request from a client other than the active holder shall return ClaimOutcome::HeldByOther without altering the existing claim, and shall never affect whether that client's underlying discovery read is answered; the same holder re-requesting before the claim lapses shall return ClaimOutcome::AlreadyHeld.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-DISC-006",
"title": "Only the active claim holder may issue a configuration request",
"text": "DiscoveryClaim::on_configuration_request shall return true and consume (release) the claim only when called by the client currently holding an active, unlapsed claim; a call from any other client shall return false and shall leave an existing other-held claim untouched.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-DISC-007",
"title": "Discovery-stream claiming is scoped to HW_UNCONFIGURED/HW_CONFIGURED",
"text": "DiscoveryClaim::on_discovery_request shall return ClaimOutcome::NotEligible and leave any existing claim state unchanged whenever server_state is RcpConfigured.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-DISC-008",
"title": "DiscoveryErrc is a distinct error category with non-empty messages",
"text": "rcp::discovery::make_error_code(DiscoveryErrc::tscf_headed_request_dropped) shall report rcp::discovery::discovery_category() as its category and shall have a non-empty diagnostic message.",
"standard": "iso26262",
"level": "ASIL-B",
"asil": "ASIL-B"
},
{
"id": "REQ-DISC-009",
"title": "A server answers discovery in every lifecycle state",
"text": "rcp::discovery::should_answer_discovery shall return true for HwUnconfigured, HwConfigured, and RcpConfigured alike, reflecting the mandatory-baseline requirement that discovery is answered regardless of lifecycle state.",
"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.1.0
VERSION 2.2.0
DESCRIPTION "Remote Control Protocol for automotive zonal architecture (C++)"
HOMEPAGE_URL "https://github.com/SoundMatt/cpp-RCP"
LANGUAGES CXX
Expand Down
28 changes: 28 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,34 @@ onward); see the header comment in `rcp.hpp` and the disposition table.

### 46. Discovery (v2.2.0)

**Done (v2.2.0):** `rcp/discovery.hpp` implements the discovery mechanism
described below on top of the three prior milestones without changing any
of them. `make_discovery_request`/`encode_discovery_request` build an
unconditional ACF_ABB read targeting `byte_bus_id 0` (`kDiscoveryByteBusId`,
matching `regmap::kEp0`) at register-map address 0 (`kDiscoveryRegisterAddress`
— the general bootstrap/magic-number field region `rcp/regmap.hpp` already
models), always wrapped in an NTSCF header, riding directly on `rcp/wire.hpp`'s
existing framing with no changes to that codec. `decode_discovery_request`
enforces the NTSCF-only rule by returning
`DiscoveryErrc::tscf_headed_request_dropped` — modeled as a decode failure,
not a flag a caller could forget to check — for any TSCF-headed frame.
`DiscoveryClaim` implements discovery-stream claiming: the first discovery
request accepted while `rcp::lifecycle::ServerLifecycle` reports
`HwUnconfigured`/`HwConfigured` reserves the stream for that client's
configuration writes (`ClaimOutcome::Claimed`); the reservation lapses after
a configurable `Discovery_TimeOut` (`kDefaultTimeout`, ~20 ms default) if no
configuration request follows (`on_configuration_request` returning `false`
once lapsed, freeing the stream for the next claimant); other clients'
concurrent discovery requests are reported as `HeldByOther`/`AlreadyHeld`
without ever touching whether their own reads get answered, since claiming
and read-answering are deliberately independent concerns in this
implementation; and a request in `RcpConfigured` is always `NotEligible`,
since the claiming mechanism itself is scoped to the two pre-RCP-configured
states. `should_answer_discovery` is a trivial always-true function over
`ServerState` — a deliberate, testable single call site documenting the
any-state answering invariant rather than an implicit assumption. New
coverage lives in `tests/test_discovery.cpp` (REQ-DISC-001..009).

- Implement the discovery request: a broadcastable ACF_ABB read addressed
to `byte_bus_id 0`, NTSCF-only (a TSCF-headed discovery request is
dropped), reading from register-map address 0 (extraction §3.5)
Expand Down
Loading
Loading