From 9fdbc6660bba38766217b27991878f967953a501 Mon Sep 17 00:00:00 2001 From: Matt <47545907+SoundMatt@users.noreply.github.com> Date: Tue, 28 Jul 2026 19:04:38 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20v2.15.0=20=E2=80=94=20Application-Layer?= =?UTF-8?q?=20Protocol=20Bridge=20Rebind=20(=C2=A7Phase=2015=20milestone?= =?UTF-8?q?=2059)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rebinds mqttbr.hpp, ddsbr.hpp, someipbr.hpp, restbridge.hpp, grpcbridge.hpp, udsbr.hpp, and doipbr.hpp per ROADMAP.md milestone 59 and the Satellite Package Disposition table's ADAPT entry for each file. Each pre-replacement `Controller : public rcp::Controller` wrapper (keyed by the removed Zone type) becomes a standalone `Bridge` class, the same "primitives, not a wrapped chokepoint" choice rcp/authz.hpp (v2.11.0) and rcp/tsn.hpp/rcp/record.hpp/rcp/observe.hpp (v2.14.0) already made. Addressing moves from Zone to the opaque per-connection stream_key plus avtp::ByteBusId endpoint pair every other Phase 14/15 header keys on since v2.10.0. Each bridge's send() becomes request(), shaped to match rcp/record.hpp's/rcp/observe.hpp's RequestFn — the same client-side send-equivalent call shape as rcp/udp.hpp's Client::request core signature. The old subscribe()/StatusChannel method is dropped with no replacement, since it belonged to rcp::Controller's status-telemetry push model with no analog in the target specification. Every method still returns errc::function_not_supported (close() still succeeds) — no real MQTT/DDS/SOME-IP/REST/gRPC/UDS/DoIP behavior is implemented, exactly as this milestone's scope calls for; each protocol's Config struct is unchanged. canbr.hpp/linbr.hpp are untouched (separate DEPRECATE item at v2.17.0). Grepping the tree for consumers of each file's pre-v2.15.0 API beyond its own test found none, so no legacy-shim split file was needed, same as the v2.13.0/v2.14.0 rebuilds. Tests entirely rewritten under the same file/prefix identity as the discarded pre-replacement coverage, traced in .fusa-reqs.json. version.hpp/CMakeLists.txt bumped to 2.15.0; ROADMAP.md gets a Done note. Verified locally: full build/test (60/60 ctest passing), RELAY conformance gate (relay conform --strict, PASS), and the cpp-FuSa safety suite (check/lint/cyber/trace --req-coverage 100, all 0 errors). Signed-off-by: Matt <47545907+SoundMatt@users.noreply.github.com> --- .fusa-reqs.json | 112 ++++++++++++++++++------------------- CMakeLists.txt | 2 +- ROADMAP.md | 35 ++++++++++++ include/rcp/ddsbr.hpp | 79 +++++++++++++++++++------- include/rcp/doipbr.hpp | 78 ++++++++++++++++++++------ include/rcp/grpcbridge.hpp | 84 ++++++++++++++++++++-------- include/rcp/mqttbr.hpp | 78 +++++++++++++++++++------- include/rcp/restbridge.hpp | 80 +++++++++++++++++++------- include/rcp/someipbr.hpp | 77 ++++++++++++++++++------- include/rcp/udsbr.hpp | 80 ++++++++++++++++++++------ include/rcp/version.hpp | 2 +- tests/test_ddsbr.cpp | 42 +++++++------- tests/test_doipbr.cpp | 42 +++++++------- tests/test_grpcbridge.cpp | 42 +++++++------- tests/test_mqttbr.cpp | 42 +++++++------- tests/test_restbridge.cpp | 43 +++++++------- tests/test_someipbr.cpp | 42 +++++++------- tests/test_udsbr.cpp | 42 +++++++------- 18 files changed, 660 insertions(+), 342 deletions(-) diff --git a/.fusa-reqs.json b/.fusa-reqs.json index f7d8602..18cc905 100644 --- a/.fusa-reqs.json +++ b/.fusa-reqs.json @@ -2394,96 +2394,96 @@ }, { "id": "REQ-GRPC-001", - "title": "GrpcController::send returns function_not_supported when stub", - "text": "GrpcController::send() shall return std::errc::function_not_supported until a concrete gRPC adapter is linked.", + "title": "GrpcBridge::request returns function_not_supported when stub", + "text": "GrpcBridge::request() shall return std::errc::function_not_supported until a concrete gRPC adapter is linked.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-GRPC-002", - "title": "GrpcController::zone returns configured zone", - "text": "GrpcController::zone() shall return the zone supplied at construction.", + "title": "GrpcBridge::stream_key returns configured value", + "text": "GrpcBridge::stream_key() shall return the stream_key supplied at construction.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-GRPC-003", - "title": "GrpcController::subscribe returns function_not_supported when stub", - "text": "GrpcController::subscribe() shall return std::errc::function_not_supported until a concrete gRPC adapter is linked.", + "title": "GrpcBridge::endpoint returns configured value", + "text": "GrpcBridge::endpoint() shall return the avtp::ByteBusId endpoint supplied at construction.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-GRPC-004", - "title": "GrpcController::close returns no error", - "text": "GrpcController::close() shall return a zero error_code (stub has no resources to release).", + "title": "GrpcBridge::close returns no error", + "text": "GrpcBridge::close() shall return a zero error_code (stub has no resources to release).", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-REST-001", - "title": "RestController::send returns function_not_supported when stub", - "text": "RestController::send() shall return std::errc::function_not_supported until an HTTP client adapter is linked.", + "title": "RestBridge::request returns function_not_supported when stub", + "text": "RestBridge::request() shall return std::errc::function_not_supported until an HTTP client adapter is linked.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-REST-002", - "title": "RestController::zone returns configured zone", - "text": "RestController::zone() shall return the zone supplied at construction.", + "title": "RestBridge::stream_key returns configured value", + "text": "RestBridge::stream_key() shall return the stream_key supplied at construction.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-REST-003", - "title": "RestController::subscribe returns function_not_supported when stub", - "text": "RestController::subscribe() shall return std::errc::function_not_supported until an HTTP adapter is linked.", + "title": "RestBridge::endpoint returns configured value", + "text": "RestBridge::endpoint() shall return the avtp::ByteBusId endpoint supplied at construction.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-REST-004", - "title": "RestController::close returns no error", - "text": "RestController::close() shall return a zero error_code.", + "title": "RestBridge::close returns no error", + "text": "RestBridge::close() shall return a zero error_code (stub has no resources to release).", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-SOMEIP-001", - "title": "SomeIpController::send returns function_not_supported when stub", - "text": "SomeIpController::send() shall return std::errc::function_not_supported until a vsomeip adapter is linked.", + "title": "SomeIpBridge::request returns function_not_supported when stub", + "text": "SomeIpBridge::request() shall return std::errc::function_not_supported until the vsomeip adapter is linked.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-SOMEIP-002", - "title": "SomeIpController::zone returns configured zone", - "text": "SomeIpController::zone() shall return the zone supplied at construction.", + "title": "SomeIpBridge::stream_key returns configured value", + "text": "SomeIpBridge::stream_key() shall return the stream_key supplied at construction.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-SOMEIP-003", - "title": "SomeIpController::subscribe returns function_not_supported when stub", - "text": "SomeIpController::subscribe() shall return std::errc::function_not_supported until a vsomeip adapter is linked.", + "title": "SomeIpBridge::endpoint returns configured value", + "text": "SomeIpBridge::endpoint() shall return the avtp::ByteBusId endpoint supplied at construction.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-SOMEIP-004", - "title": "SomeIpController::close returns no error", - "text": "SomeIpController::close() shall return a zero error_code.", + "title": "SomeIpBridge::close returns no error", + "text": "SomeIpBridge::close() shall return a zero error_code (stub has no resources to release).", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" @@ -2522,64 +2522,64 @@ }, { "id": "REQ-DDS-001", - "title": "DdsController::send returns function_not_supported when stub", - "text": "DdsController::send() shall return std::errc::function_not_supported until a DDS adapter is linked.", + "title": "DdsBridge::request returns function_not_supported when stub", + "text": "DdsBridge::request() shall return std::errc::function_not_supported until a concrete DDS backend is linked.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-DDS-002", - "title": "DdsController::zone returns configured zone", - "text": "DdsController::zone() shall return the zone supplied at construction.", + "title": "DdsBridge::stream_key returns configured value", + "text": "DdsBridge::stream_key() shall return the stream_key supplied at construction.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-DDS-003", - "title": "DdsController::subscribe returns function_not_supported when stub", - "text": "DdsController::subscribe() shall return std::errc::function_not_supported until a DDS adapter is linked.", + "title": "DdsBridge::endpoint returns configured value", + "text": "DdsBridge::endpoint() shall return the avtp::ByteBusId endpoint supplied at construction.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-DDS-004", - "title": "DdsController::close returns no error", - "text": "DdsController::close() shall return a zero error_code.", + "title": "DdsBridge::close returns no error", + "text": "DdsBridge::close() shall return a zero error_code (stub has no resources to release).", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-MQTT-001", - "title": "MqttController::send returns function_not_supported when stub", - "text": "MqttController::send() shall return std::errc::function_not_supported until a Paho adapter is linked.", + "title": "MqttBridge::request returns function_not_supported when stub", + "text": "MqttBridge::request() shall return std::errc::function_not_supported until a concrete MQTT backend is linked.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-MQTT-002", - "title": "MqttController::zone returns configured zone", - "text": "MqttController::zone() shall return the zone supplied at construction.", + "title": "MqttBridge::stream_key returns configured value", + "text": "MqttBridge::stream_key() shall return the stream_key supplied at construction.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-MQTT-003", - "title": "MqttController::subscribe returns function_not_supported when stub", - "text": "MqttController::subscribe() shall return std::errc::function_not_supported until a Paho adapter is linked.", + "title": "MqttBridge::endpoint returns configured value", + "text": "MqttBridge::endpoint() shall return the avtp::ByteBusId endpoint supplied at construction.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-MQTT-004", - "title": "MqttController::close returns no error", - "text": "MqttController::close() shall return a zero error_code.", + "title": "MqttBridge::close returns no error", + "text": "MqttBridge::close() shall return a zero error_code (stub has no resources to release).", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" @@ -2618,64 +2618,64 @@ }, { "id": "REQ-UDS-001", - "title": "UdsController::send returns function_not_supported when stub", - "text": "UdsController::send() shall return std::errc::function_not_supported until a UDS stack adapter is linked.", + "title": "UdsBridge::request returns function_not_supported when stub", + "text": "UdsBridge::request() shall return std::errc::function_not_supported until a concrete UDS stack is linked.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-UDS-002", - "title": "UdsController::zone returns configured zone", - "text": "UdsController::zone() shall return the zone supplied at construction.", + "title": "UdsBridge::stream_key returns configured value", + "text": "UdsBridge::stream_key() shall return the stream_key supplied at construction.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-UDS-003", - "title": "UdsController::subscribe returns function_not_supported when stub", - "text": "UdsController::subscribe() shall return std::errc::function_not_supported until a UDS adapter is linked.", + "title": "UdsBridge::endpoint returns configured value", + "text": "UdsBridge::endpoint() shall return the avtp::ByteBusId endpoint supplied at construction.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-UDS-004", - "title": "UdsController::close returns no error", - "text": "UdsController::close() shall return a zero error_code.", + "title": "UdsBridge::close returns no error", + "text": "UdsBridge::close() shall return a zero error_code (stub has no resources to release).", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-DOIP-001", - "title": "DoIpController::send returns function_not_supported when stub", - "text": "DoIpController::send() shall return std::errc::function_not_supported until a DoIP stack adapter is linked.", + "title": "DoIpBridge::request returns function_not_supported when stub", + "text": "DoIpBridge::request() shall return std::errc::function_not_supported until a concrete DoIP stack is linked.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-DOIP-002", - "title": "DoIpController::zone returns configured zone", - "text": "DoIpController::zone() shall return the zone supplied at construction.", + "title": "DoIpBridge::stream_key returns configured value", + "text": "DoIpBridge::stream_key() shall return the stream_key supplied at construction.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-DOIP-003", - "title": "DoIpController::subscribe returns function_not_supported when stub", - "text": "DoIpController::subscribe() shall return std::errc::function_not_supported until a DoIP adapter is linked.", + "title": "DoIpBridge::endpoint returns configured value", + "text": "DoIpBridge::endpoint() shall return the avtp::ByteBusId endpoint supplied at construction.", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" }, { "id": "REQ-DOIP-004", - "title": "DoIpController::close returns no error", - "text": "DoIpController::close() shall return a zero error_code.", + "title": "DoIpBridge::close returns no error", + "text": "DoIpBridge::close() shall return a zero error_code (stub has no resources to release).", "standard": "iso26262", "level": "ASIL-A", "asil": "ASIL-A" diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b917da..c7ce097 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.21) project(cpp-rcp - VERSION 2.14.0 + VERSION 2.15.0 DESCRIPTION "Remote Control Protocol for automotive zonal architecture (C++)" HOMEPAGE_URL "https://github.com/SoundMatt/cpp-RCP" LANGUAGES CXX diff --git a/ROADMAP.md b/ROADMAP.md index 768147e..82d4770 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1187,6 +1187,41 @@ same as the equivalent disclaimers in `rcp/avtp.hpp`, `rcp/acf.hpp`, external dependency (an MQTT/DDS/SOME-IP/UDS library) is unchanged by this rework +**Done (v2.15.0):** All seven files are ADAPTed in place per the Satellite +Package Disposition table's entries — each pre-replacement +`Controller : public rcp::Controller` wrapper (keyed by the removed +`Zone` type) becomes a standalone `Bridge` class, the same +"primitives, not a wrapped chokepoint" choice `rcp/authz.hpp` (v2.11.0) and +`rcp/tsn.hpp`/`rcp/record.hpp`/`rcp/observe.hpp` (v2.14.0) already made — +there is no unified client-side `send()` chokepoint left to wrap. Addressing +moves from `Zone` to the opaque per-connection `stream_key` (typically +`avtp::StreamId::to_u64()`) plus `avtp::ByteBusId` endpoint pair every other +Phase 14/15 header keys on since v2.10.0. Each bridge's pre-replacement +`send()` becomes `request()`, shaped to match `rcp/record.hpp`'s/ +`rcp/observe.hpp`'s `RequestFn` — the same "new client-side send-equivalent +call" shape as `rcp/udp.hpp`'s `Client::request` core signature — so a +caller can address a bridge exactly where it would otherwise address a +transport `Client`; the pre-replacement `subscribe()`/`StatusChannel` +method is dropped with no replacement, since it belonged to +`rcp::Controller`'s status-telemetry push model, which has no analog in the +target specification's request/response shape. Every method still returns +`errc::function_not_supported` (`close()` still succeeds) — no real +MQTT/DDS/SOME-IP/REST/gRPC/UDS/DoIP behavior is implemented here, exactly as +this milestone's own scope states; each protocol's `Config` struct is +unchanged. `canbr.hpp`/`linbr.hpp` are untouched, per this milestone's own +scope note — they remain a separate DEPRECATE item at milestone 61 +(v2.17.0). Grepping the tree for consumers of each file's pre-v2.15.0 API +beyond its own (now-rewritten) test found none, so no legacy-shim split +file was needed for any of the seven, same as `rcp/udp.hpp`'s v2.13.0 +rebuild and the seven files ADAPTed at v2.14.0. New coverage lives in +`tests/test_mqttbr.cpp`, `tests/test_ddsbr.cpp`, `tests/test_someipbr.cpp`, +`tests/test_restbridge.cpp`, `tests/test_grpcbridge.cpp`, +`tests/test_udsbr.cpp`, and `tests/test_doipbr.cpp` (`REQ-MQTT-001..004`, +`REQ-DDS-001..004`, `REQ-SOMEIP-001..004`, `REQ-REST-001..004`, +`REQ-GRPC-001..004`, `REQ-UDS-001..004`, `REQ-DOIP-001..004`), entirely +rewritten under the same file/prefix identity as the discarded +pre-replacement coverage, traced in `.fusa-reqs.json`. + ### 60. C ABI & CLI Rebuild (v2.16.0) - Rebuild `capi.h`/`capi_impl.hpp`: the current C structs diff --git a/include/rcp/ddsbr.hpp b/include/rcp/ddsbr.hpp index 2c62ba7..81b2cdf 100644 --- a/include/rcp/ddsbr.hpp +++ b/include/rcp/ddsbr.hpp @@ -3,17 +3,50 @@ // fusa:req REQ-DDS-003 // fusa:req REQ-DDS-004 -// DDS (Data Distribution Service) protocol bridge interface stub (v0.35.0). +// DDS (Data Distribution Service) protocol bridge interface stub. // -// Publishes RCP commands as DDS typed topics and collects replies from a -// dedicated reply topic. Requires an OMG DDS implementation (e.g. FastDDS, -// Cyclone DDS). All methods return errc::function_not_supported. +// Publishes RC-Client-level requests as DDS typed topics and collects +// replies from a dedicated reply topic. Requires an OMG DDS implementation +// (e.g. FastDDS, Cyclone DDS) to be linked separately. All methods return +// errc::function_not_supported until a concrete backend is linked. +// +// ROADMAP.md milestone 59, "Application-Layer Protocol Bridge Rebind +// (v2.15.0)": this header is ADAPTed, per the Satellite Package +// Disposition table's entry for `ddsbr.hpp` — translating between an RC +// Client's application-level view and the DDS ecosystem is conceptually +// unaffected by which wire protocol RCP itself now speaks, so this is a +// mechanical interface update, not a redesign; the stub had no working +// behavior to preserve in the first place. The pre-replacement +// `DdsController : public rcp::Controller` wrapper (keyed by the removed +// `Zone` type) is dropped for a standalone `DdsBridge`, the same +// "primitives, not a wrapped chokepoint" choice `rcp/authz.hpp` (v2.11.0) +// and `rcp/tsn.hpp`/`rcp/record.hpp`/`rcp/observe.hpp` (v2.14.0) already +// made — there is no unified client-side `send()` chokepoint left to wrap +// (that unification, if any, does not land until the CLI/capi/adapt +// rebuilds at v2.16.0, per those files' own notes). Addressing moves from +// `Zone` to the opaque per-connection `stream_key` (typically +// `avtp::StreamId::to_u64()`) plus `avtp::ByteBusId` pair every other +// Phase 14/15 header keys on since v2.10.0. `DdsBridge::request` takes on +// the pre-replacement wrapper's `send()` role, shaped to match +// `rcp/record.hpp`'s/`rcp/observe.hpp`'s `RequestFn` — the same "new +// client-side send-equivalent call" shape as `rcp/udp.hpp`'s +// `Client::request` core signature — so a caller can address this bridge +// exactly where it would otherwise address a transport `Client`. The old +// `subscribe()`/`StatusChannel` method has no analog here: it belonged to +// `rcp::Controller`'s status-telemetry push model, which is not part of +// the target specification's request/response shape. #pragma once -#include "rcp.hpp" +#include "acf.hpp" +#include "avtp.hpp" +#include "rcp.hpp" // for rcp::Context only — see this header's own scope note above +#include +#include #include #include +#include +#include namespace rcp { namespace ddsbr { @@ -24,30 +57,38 @@ struct Config { std::chrono::milliseconds timeout{500}; }; -class DdsController final : public rcp::Controller { +// DdsBridge stubs the request/response side of a bridge between one RCP +// endpoint (`stream_key` + `endpoint`) and its corresponding pair of DDS +// topics under `cfg.topic_prefix` in DDS domain `cfg.domain_id`. No +// concrete DDS implementation is linked here; every call reports +// errc::function_not_supported. +class DdsBridge { public: - DdsController(Zone zone, Config cfg) : zone_(zone), cfg_(std::move(cfg)) {} - - Zone zone() const noexcept override { return zone_; } + DdsBridge(uint64_t stream_key, avtp::ByteBusId endpoint, Config cfg) + : stream_key_(stream_key), endpoint_(endpoint), cfg_(std::move(cfg)) {} - std::error_code send(const rcp::Context&, const Command&, Response&) override { - return std::make_error_code(std::errc::function_not_supported); - } + uint64_t stream_key() const noexcept { return stream_key_; } + avtp::ByteBusId endpoint() const noexcept { return endpoint_; } - std::error_code subscribe(const rcp::Context&, - std::shared_ptr&) override { + // request is this bridge's client-side send-equivalent call — see this + // file's header comment for why its shape matches rcp/record.hpp's and + // rcp/observe.hpp's RequestFn. + std::error_code request(const rcp::Context&, const acf::AcfMessageInfo&, + const std::vector&, + acf::AcfMessageInfo&, std::vector&) { return std::make_error_code(std::errc::function_not_supported); } - std::error_code close() override { return {}; } + std::error_code close() { return {}; } private: - Zone zone_; - Config cfg_; + uint64_t stream_key_; + avtp::ByteBusId endpoint_; + Config cfg_; }; -inline std::shared_ptr new_controller(Zone zone, Config cfg) { - return std::make_shared(zone, std::move(cfg)); +inline std::shared_ptr new_bridge(uint64_t stream_key, avtp::ByteBusId endpoint, Config cfg) { + return std::make_shared(stream_key, endpoint, std::move(cfg)); } } // namespace ddsbr diff --git a/include/rcp/doipbr.hpp b/include/rcp/doipbr.hpp index f8a68ea..ecfd9aa 100644 --- a/include/rcp/doipbr.hpp +++ b/include/rcp/doipbr.hpp @@ -3,17 +3,54 @@ // fusa:req REQ-DOIP-003 // fusa:req REQ-DOIP-004 -// DoIP (Diagnostics over IP / ISO 13400) bridge interface stub (v0.39.0). +// DoIP (Diagnostics over IP / ISO 13400) bridge interface stub. // // Encapsulates UDS requests inside DoIP diagnostic messages over TCP/IP. -// Requires a DoIP stack integration. All methods return errc::function_not_supported. +// Requires a DoIP stack integration. All methods return +// errc::function_not_supported until a concrete backend is linked. +// +// ROADMAP.md milestone 59, "Application-Layer Protocol Bridge Rebind +// (v2.15.0)": this header is ADAPTed, per the Satellite Package +// Disposition table's entry for `doipbr.hpp` — translating between an RC +// Client's application-level view and a DoIP diagnostic session is +// conceptually unaffected by which wire protocol RCP itself now speaks, so +// this is a mechanical interface update, not a redesign; the stub had no +// working behavior to preserve in the first place. The pre-replacement +// `DoIpController : public rcp::Controller` wrapper (keyed by the removed +// `Zone` type) is dropped for a standalone `DoIpBridge`, the same +// "primitives, not a wrapped chokepoint" choice `rcp/authz.hpp` (v2.11.0) +// and `rcp/tsn.hpp`/`rcp/record.hpp`/`rcp/observe.hpp` (v2.14.0) already +// made — there is no unified client-side `send()` chokepoint left to wrap +// (that unification, if any, does not land until the CLI/capi/adapt +// rebuilds at v2.16.0, per those files' own notes). Addressing moves from +// `Zone` to the opaque per-connection `stream_key` (typically +// `avtp::StreamId::to_u64()`) plus `avtp::ByteBusId` pair every other +// Phase 14/15 header keys on since v2.10.0. `DoIpBridge::request` takes on +// the pre-replacement wrapper's `send()` role, shaped to match +// `rcp/record.hpp`'s/`rcp/observe.hpp`'s `RequestFn` — the same "new +// client-side send-equivalent call" shape as `rcp/udp.hpp`'s +// `Client::request` core signature — so a caller can address this bridge +// exactly where it would otherwise address a transport `Client`. The old +// `subscribe()`/`StatusChannel` method has no analog here: it belonged to +// `rcp::Controller`'s status-telemetry push model, which is not part of +// the target specification's request/response shape. +// +// This header bridges into DoIP's TCP/IP diagnostic-session encapsulation; +// it is unrelated to `rcp/udsbr.hpp`'s UDS service bridge beyond the fact +// that DoIP commonly carries UDS requests — each header stubs its own side +// of that pairing independently. #pragma once -#include "rcp.hpp" +#include "acf.hpp" +#include "avtp.hpp" +#include "rcp.hpp" // for rcp::Context only — see this header's own scope note above +#include #include #include #include +#include +#include namespace rcp { namespace doipbr { @@ -25,30 +62,37 @@ struct Config { std::chrono::milliseconds tcp_timeout{2000}; }; -class DoIpController final : public rcp::Controller { +// DoIpBridge stubs the request/response side of a bridge between one RCP +// endpoint (`stream_key` + `endpoint`) and a DoIP diagnostic session +// against `cfg.server_ip`:`cfg.server_port`. No concrete DoIP stack is +// linked here; every call reports errc::function_not_supported. +class DoIpBridge { public: - DoIpController(Zone zone, Config cfg) : zone_(zone), cfg_(std::move(cfg)) {} - - Zone zone() const noexcept override { return zone_; } + DoIpBridge(uint64_t stream_key, avtp::ByteBusId endpoint, Config cfg) + : stream_key_(stream_key), endpoint_(endpoint), cfg_(std::move(cfg)) {} - std::error_code send(const rcp::Context&, const Command&, Response&) override { - return std::make_error_code(std::errc::function_not_supported); - } + uint64_t stream_key() const noexcept { return stream_key_; } + avtp::ByteBusId endpoint() const noexcept { return endpoint_; } - std::error_code subscribe(const rcp::Context&, - std::shared_ptr&) override { + // request is this bridge's client-side send-equivalent call — see this + // file's header comment for why its shape matches rcp/record.hpp's and + // rcp/observe.hpp's RequestFn. + std::error_code request(const rcp::Context&, const acf::AcfMessageInfo&, + const std::vector&, + acf::AcfMessageInfo&, std::vector&) { return std::make_error_code(std::errc::function_not_supported); } - std::error_code close() override { return {}; } + std::error_code close() { return {}; } private: - Zone zone_; - Config cfg_; + uint64_t stream_key_; + avtp::ByteBusId endpoint_; + Config cfg_; }; -inline std::shared_ptr new_controller(Zone zone, Config cfg) { - return std::make_shared(zone, std::move(cfg)); +inline std::shared_ptr new_bridge(uint64_t stream_key, avtp::ByteBusId endpoint, Config cfg) { + return std::make_shared(stream_key, endpoint, std::move(cfg)); } } // namespace doipbr diff --git a/include/rcp/grpcbridge.hpp b/include/rcp/grpcbridge.hpp index e8af26b..3fb0b2e 100644 --- a/include/rcp/grpcbridge.hpp +++ b/include/rcp/grpcbridge.hpp @@ -3,20 +3,51 @@ // fusa:req REQ-GRPC-003 // fusa:req REQ-GRPC-004 -// gRPC protocol bridge interface stub (v0.31.0). +// gRPC protocol bridge interface stub. // -// GrpcBridge translates between RCP wire frames and gRPC unary/streaming RPCs. -// Full implementation requires a generated gRPC stub from rcp.proto (not -// included here); this header defines the integration surface. +// GrpcBridge translates between RC-Client-level requests/responses and +// gRPC unary/streaming RPCs. Full implementation requires a generated gRPC +// stub from a .proto definition (not included here); this header defines +// the integration surface. All methods return errc::function_not_supported +// until a concrete gRPC adapter is linked. // -// Note: This is a compile-time interface stub. All methods return -// errc::function_not_supported until a concrete gRPC adapter is linked. +// ROADMAP.md milestone 59, "Application-Layer Protocol Bridge Rebind +// (v2.15.0)": this header is ADAPTed, per the Satellite Package +// Disposition table's entry for `grpcbridge.hpp` — translating between an +// RC Client's application-level view and a gRPC remote endpoint is +// conceptually unaffected by which wire protocol RCP itself now speaks, so +// this is a mechanical interface update, not a redesign; the stub had no +// working behavior to preserve in the first place. The pre-replacement +// `GrpcController : public rcp::Controller` wrapper (keyed by the removed +// `Zone` type) is dropped for a standalone `GrpcBridge`, the same +// "primitives, not a wrapped chokepoint" choice `rcp/authz.hpp` (v2.11.0) +// and `rcp/tsn.hpp`/`rcp/record.hpp`/`rcp/observe.hpp` (v2.14.0) already +// made — there is no unified client-side `send()` chokepoint left to wrap +// (that unification, if any, does not land until the CLI/capi/adapt +// rebuilds at v2.16.0, per those files' own notes). Addressing moves from +// `Zone` to the opaque per-connection `stream_key` (typically +// `avtp::StreamId::to_u64()`) plus `avtp::ByteBusId` pair every other +// Phase 14/15 header keys on since v2.10.0. `GrpcBridge::request` takes on +// the pre-replacement wrapper's `send()` role, shaped to match +// `rcp/record.hpp`'s/`rcp/observe.hpp`'s `RequestFn` — the same "new +// client-side send-equivalent call" shape as `rcp/udp.hpp`'s +// `Client::request` core signature — so a caller can address this bridge +// exactly where it would otherwise address a transport `Client`. The old +// `subscribe()`/`StatusChannel` method has no analog here: it belonged to +// `rcp::Controller`'s status-telemetry push model, which is not part of +// the target specification's request/response shape. #pragma once -#include "rcp.hpp" +#include "acf.hpp" +#include "avtp.hpp" +#include "rcp.hpp" // for rcp::Context only — see this header's own scope note above +#include +#include #include #include +#include +#include namespace rcp { namespace grpcbridge { @@ -29,34 +60,39 @@ struct Config { std::chrono::milliseconds rpc_timeout{1000}; }; -// ── GrpcController ──────────────────────────────────────────────────────────── +// ── GrpcBridge ──────────────────────────────────────────────────────────────── -// GrpcController bridges RCP commands to a gRPC remote endpoint. -class GrpcController final : public rcp::Controller { +// GrpcBridge stubs the request/response side of a bridge between one RCP +// endpoint (`stream_key` + `endpoint`) and a gRPC remote endpoint at +// `cfg.server_address`. No generated gRPC stub is linked here; every call +// reports errc::function_not_supported. +class GrpcBridge { public: - GrpcController(Zone zone, Config cfg) - : zone_(zone), cfg_(std::move(cfg)) {} + GrpcBridge(uint64_t stream_key, avtp::ByteBusId endpoint, Config cfg) + : stream_key_(stream_key), endpoint_(endpoint), cfg_(std::move(cfg)) {} - Zone zone() const noexcept override { return zone_; } + uint64_t stream_key() const noexcept { return stream_key_; } + avtp::ByteBusId endpoint() const noexcept { return endpoint_; } - std::error_code send(const rcp::Context&, const Command&, Response&) override { + // request is this bridge's client-side send-equivalent call — see this + // file's header comment for why its shape matches rcp/record.hpp's and + // rcp/observe.hpp's RequestFn. + std::error_code request(const rcp::Context&, const acf::AcfMessageInfo&, + const std::vector&, + acf::AcfMessageInfo&, std::vector&) { return std::make_error_code(std::errc::function_not_supported); } - std::error_code subscribe(const rcp::Context&, - std::shared_ptr&) override { - return std::make_error_code(std::errc::function_not_supported); - } - - std::error_code close() override { return {}; } + std::error_code close() { return {}; } private: - Zone zone_; - Config cfg_; + uint64_t stream_key_; + avtp::ByteBusId endpoint_; + Config cfg_; }; -inline std::shared_ptr new_controller(Zone zone, Config cfg) { - return std::make_shared(zone, std::move(cfg)); +inline std::shared_ptr new_bridge(uint64_t stream_key, avtp::ByteBusId endpoint, Config cfg) { + return std::make_shared(stream_key, endpoint, std::move(cfg)); } } // namespace grpcbridge diff --git a/include/rcp/mqttbr.hpp b/include/rcp/mqttbr.hpp index ab7d594..1a6848f 100644 --- a/include/rcp/mqttbr.hpp +++ b/include/rcp/mqttbr.hpp @@ -3,17 +3,50 @@ // fusa:req REQ-MQTT-003 // fusa:req REQ-MQTT-004 -// MQTT protocol bridge interface stub (v0.36.0). +// MQTT protocol bridge interface stub. // -// Publishes commands to MQTT topics and receives responses from a -// correlation-ID-based reply topic. Requires an MQTT client library -// (e.g. Eclipse Paho). All methods return errc::function_not_supported. +// Publishes RC-Client-level requests to MQTT topics and receives responses +// from a correlation-ID-based reply topic. Requires an MQTT client library +// (e.g. Eclipse Paho) to be linked separately. All methods return +// errc::function_not_supported until a concrete backend is linked. +// +// ROADMAP.md milestone 59, "Application-Layer Protocol Bridge Rebind +// (v2.15.0)": this header is ADAPTed, per the Satellite Package +// Disposition table's entry for `mqttbr.hpp` — translating between an RC +// Client's application-level view and the MQTT ecosystem is conceptually +// unaffected by which wire protocol RCP itself now speaks, so this is a +// mechanical interface update, not a redesign; the stub had no working +// behavior to preserve in the first place. The pre-replacement +// `MqttController : public rcp::Controller` wrapper (keyed by the removed +// `Zone` type) is dropped for a standalone `MqttBridge`, the same +// "primitives, not a wrapped chokepoint" choice `rcp/authz.hpp` (v2.11.0) +// and `rcp/tsn.hpp`/`rcp/record.hpp`/`rcp/observe.hpp` (v2.14.0) already +// made — there is no unified client-side `send()` chokepoint left to wrap +// (that unification, if any, does not land until the CLI/capi/adapt +// rebuilds at v2.16.0, per those files' own notes). Addressing moves from +// `Zone` to the opaque per-connection `stream_key` (typically +// `avtp::StreamId::to_u64()`) plus `avtp::ByteBusId` pair every other +// Phase 14/15 header keys on since v2.10.0. `MqttBridge::request` takes on +// the pre-replacement wrapper's `send()` role, shaped to match +// `rcp/record.hpp`'s/`rcp/observe.hpp`'s `RequestFn` — the same "new +// client-side send-equivalent call" shape as `rcp/udp.hpp`'s +// `Client::request` core signature — so a caller can address this bridge +// exactly where it would otherwise address a transport `Client`. The old +// `subscribe()`/`StatusChannel` method has no analog here: it belonged to +// `rcp::Controller`'s status-telemetry push model, which is not part of +// the target specification's request/response shape. #pragma once -#include "rcp.hpp" +#include "acf.hpp" +#include "avtp.hpp" +#include "rcp.hpp" // for rcp::Context only — see this header's own scope note above +#include +#include #include #include +#include +#include namespace rcp { namespace mqttbr { @@ -25,30 +58,37 @@ struct Config { std::chrono::milliseconds timeout{1000}; }; -class MqttController final : public rcp::Controller { +// MqttBridge stubs the request/response side of a bridge between one RCP +// endpoint (`stream_key` + `endpoint`) and its corresponding MQTT topic +// pair under `cfg.topic_prefix`. No concrete MQTT client is linked here; +// every call reports errc::function_not_supported. +class MqttBridge { public: - MqttController(Zone zone, Config cfg) : zone_(zone), cfg_(std::move(cfg)) {} - - Zone zone() const noexcept override { return zone_; } + MqttBridge(uint64_t stream_key, avtp::ByteBusId endpoint, Config cfg) + : stream_key_(stream_key), endpoint_(endpoint), cfg_(std::move(cfg)) {} - std::error_code send(const rcp::Context&, const Command&, Response&) override { - return std::make_error_code(std::errc::function_not_supported); - } + uint64_t stream_key() const noexcept { return stream_key_; } + avtp::ByteBusId endpoint() const noexcept { return endpoint_; } - std::error_code subscribe(const rcp::Context&, - std::shared_ptr&) override { + // request is this bridge's client-side send-equivalent call — see this + // file's header comment for why its shape matches rcp/record.hpp's and + // rcp/observe.hpp's RequestFn. + std::error_code request(const rcp::Context&, const acf::AcfMessageInfo&, + const std::vector&, + acf::AcfMessageInfo&, std::vector&) { return std::make_error_code(std::errc::function_not_supported); } - std::error_code close() override { return {}; } + std::error_code close() { return {}; } private: - Zone zone_; - Config cfg_; + uint64_t stream_key_; + avtp::ByteBusId endpoint_; + Config cfg_; }; -inline std::shared_ptr new_controller(Zone zone, Config cfg) { - return std::make_shared(zone, std::move(cfg)); +inline std::shared_ptr new_bridge(uint64_t stream_key, avtp::ByteBusId endpoint, Config cfg) { + return std::make_shared(stream_key, endpoint, std::move(cfg)); } } // namespace mqttbr diff --git a/include/rcp/restbridge.hpp b/include/rcp/restbridge.hpp index e20ce12..124ced9 100644 --- a/include/rcp/restbridge.hpp +++ b/include/rcp/restbridge.hpp @@ -3,17 +3,51 @@ // fusa:req REQ-REST-003 // fusa:req REQ-REST-004 -// REST/HTTP protocol bridge interface stub (v0.32.0). +// REST/HTTP protocol bridge interface stub. // -// RestController maps RCP commands to HTTP POST /zones/{zone}/command. -// Requires an HTTP client backend (e.g. libcurl) to be linked separately. -// All methods return errc::function_not_supported until the adapter is linked. +// RestBridge maps RC-Client-level requests to HTTP POST +// /streams/{stream_key}/endpoints/{endpoint}. Requires an HTTP client +// backend (e.g. libcurl) to be linked separately. All methods return +// errc::function_not_supported until the adapter is linked. +// +// ROADMAP.md milestone 59, "Application-Layer Protocol Bridge Rebind +// (v2.15.0)": this header is ADAPTed, per the Satellite Package +// Disposition table's entry for `restbridge.hpp` — translating between an +// RC Client's application-level view and a REST/HTTP endpoint is +// conceptually unaffected by which wire protocol RCP itself now speaks, so +// this is a mechanical interface update, not a redesign; the stub had no +// working behavior to preserve in the first place. The pre-replacement +// `RestController : public rcp::Controller` wrapper (keyed by the removed +// `Zone` type, and the old `/zones/{zone}/command` URL shape it implied) +// is dropped for a standalone `RestBridge`, the same "primitives, not a +// wrapped chokepoint" choice `rcp/authz.hpp` (v2.11.0) and +// `rcp/tsn.hpp`/`rcp/record.hpp`/`rcp/observe.hpp` (v2.14.0) already made — +// there is no unified client-side `send()` chokepoint left to wrap (that +// unification, if any, does not land until the CLI/capi/adapt rebuilds at +// v2.16.0, per those files' own notes). Addressing moves from `Zone` to +// the opaque per-connection `stream_key` (typically +// `avtp::StreamId::to_u64()`) plus `avtp::ByteBusId` pair every other +// Phase 14/15 header keys on since v2.10.0. `RestBridge::request` takes on +// the pre-replacement wrapper's `send()` role, shaped to match +// `rcp/record.hpp`'s/`rcp/observe.hpp`'s `RequestFn` — the same "new +// client-side send-equivalent call" shape as `rcp/udp.hpp`'s +// `Client::request` core signature — so a caller can address this bridge +// exactly where it would otherwise address a transport `Client`. The old +// `subscribe()`/`StatusChannel` method has no analog here: it belonged to +// `rcp::Controller`'s status-telemetry push model, which is not part of +// the target specification's request/response shape. #pragma once -#include "rcp.hpp" +#include "acf.hpp" +#include "avtp.hpp" +#include "rcp.hpp" // for rcp::Context only — see this header's own scope note above +#include +#include #include #include +#include +#include namespace rcp { namespace restbridge { @@ -24,31 +58,37 @@ struct Config { std::chrono::milliseconds request_timeout{1000}; }; -class RestController final : public rcp::Controller { +// RestBridge stubs the request/response side of a bridge between one RCP +// endpoint (`stream_key` + `endpoint`) and an HTTP POST call under +// `cfg.base_url`. No concrete HTTP client backend is linked here; every +// call reports errc::function_not_supported. +class RestBridge { public: - RestController(Zone zone, Config cfg) - : zone_(zone), cfg_(std::move(cfg)) {} - - Zone zone() const noexcept override { return zone_; } + RestBridge(uint64_t stream_key, avtp::ByteBusId endpoint, Config cfg) + : stream_key_(stream_key), endpoint_(endpoint), cfg_(std::move(cfg)) {} - std::error_code send(const rcp::Context&, const Command&, Response&) override { - return std::make_error_code(std::errc::function_not_supported); - } + uint64_t stream_key() const noexcept { return stream_key_; } + avtp::ByteBusId endpoint() const noexcept { return endpoint_; } - std::error_code subscribe(const rcp::Context&, - std::shared_ptr&) override { + // request is this bridge's client-side send-equivalent call — see this + // file's header comment for why its shape matches rcp/record.hpp's and + // rcp/observe.hpp's RequestFn. + std::error_code request(const rcp::Context&, const acf::AcfMessageInfo&, + const std::vector&, + acf::AcfMessageInfo&, std::vector&) { return std::make_error_code(std::errc::function_not_supported); } - std::error_code close() override { return {}; } + std::error_code close() { return {}; } private: - Zone zone_; - Config cfg_; + uint64_t stream_key_; + avtp::ByteBusId endpoint_; + Config cfg_; }; -inline std::shared_ptr new_controller(Zone zone, Config cfg) { - return std::make_shared(zone, std::move(cfg)); +inline std::shared_ptr new_bridge(uint64_t stream_key, avtp::ByteBusId endpoint, Config cfg) { + return std::make_shared(stream_key, endpoint, std::move(cfg)); } } // namespace restbridge diff --git a/include/rcp/someipbr.hpp b/include/rcp/someipbr.hpp index c1f319e..df3ccdb 100644 --- a/include/rcp/someipbr.hpp +++ b/include/rcp/someipbr.hpp @@ -3,17 +3,48 @@ // fusa:req REQ-SOMEIP-003 // fusa:req REQ-SOMEIP-004 -// SOME/IP protocol bridge interface stub (v0.33.0). +// SOME/IP protocol bridge interface stub. // -// Routes RCP commands over SOME/IP service discovery and method calls. -// All methods return errc::function_not_supported until the vsomeip adapter -// is linked (separate optional module). +// Routes RC-Client-level requests over SOME/IP service discovery and +// method calls. All methods return errc::function_not_supported until the +// vsomeip adapter is linked (separate optional module). +// +// ROADMAP.md milestone 59, "Application-Layer Protocol Bridge Rebind +// (v2.15.0)": this header is ADAPTed, per the Satellite Package +// Disposition table's entry for `someipbr.hpp` — translating between an RC +// Client's application-level view and the SOME/IP ecosystem is +// conceptually unaffected by which wire protocol RCP itself now speaks, so +// this is a mechanical interface update, not a redesign; the stub had no +// working behavior to preserve in the first place. The pre-replacement +// `SomeIpController : public rcp::Controller` wrapper (keyed by the +// removed `Zone` type) is dropped for a standalone `SomeIpBridge`, the +// same "primitives, not a wrapped chokepoint" choice `rcp/authz.hpp` +// (v2.11.0) and `rcp/tsn.hpp`/`rcp/record.hpp`/`rcp/observe.hpp` (v2.14.0) +// already made — there is no unified client-side `send()` chokepoint left +// to wrap (that unification, if any, does not land until the CLI/capi/ +// adapt rebuilds at v2.16.0, per those files' own notes). Addressing moves +// from `Zone` to the opaque per-connection `stream_key` (typically +// `avtp::StreamId::to_u64()`) plus `avtp::ByteBusId` pair every other +// Phase 14/15 header keys on since v2.10.0. `SomeIpBridge::request` takes +// on the pre-replacement wrapper's `send()` role, shaped to match +// `rcp/record.hpp`'s/`rcp/observe.hpp`'s `RequestFn` — the same "new +// client-side send-equivalent call" shape as `rcp/udp.hpp`'s +// `Client::request` core signature — so a caller can address this bridge +// exactly where it would otherwise address a transport `Client`. The old +// `subscribe()`/`StatusChannel` method has no analog here: it belonged to +// `rcp::Controller`'s status-telemetry push model, which is not part of +// the target specification's request/response shape. #pragma once -#include "rcp.hpp" +#include "acf.hpp" +#include "avtp.hpp" +#include "rcp.hpp" // for rcp::Context only — see this header's own scope note above +#include #include #include +#include +#include namespace rcp { namespace someipbr { @@ -25,31 +56,37 @@ struct Config { std::chrono::milliseconds timeout{500}; }; -class SomeIpController final : public rcp::Controller { +// SomeIpBridge stubs the request/response side of a bridge between one +// RCP endpoint (`stream_key` + `endpoint`) and a SOME/IP +// service/instance/method triple. No concrete vsomeip adapter is linked +// here; every call reports errc::function_not_supported. +class SomeIpBridge { public: - SomeIpController(Zone zone, Config cfg) - : zone_(zone), cfg_(std::move(cfg)) {} - - Zone zone() const noexcept override { return zone_; } + SomeIpBridge(uint64_t stream_key, avtp::ByteBusId endpoint, Config cfg) + : stream_key_(stream_key), endpoint_(endpoint), cfg_(std::move(cfg)) {} - std::error_code send(const rcp::Context&, const Command&, Response&) override { - return std::make_error_code(std::errc::function_not_supported); - } + uint64_t stream_key() const noexcept { return stream_key_; } + avtp::ByteBusId endpoint() const noexcept { return endpoint_; } - std::error_code subscribe(const rcp::Context&, - std::shared_ptr&) override { + // request is this bridge's client-side send-equivalent call — see this + // file's header comment for why its shape matches rcp/record.hpp's and + // rcp/observe.hpp's RequestFn. + std::error_code request(const rcp::Context&, const acf::AcfMessageInfo&, + const std::vector&, + acf::AcfMessageInfo&, std::vector&) { return std::make_error_code(std::errc::function_not_supported); } - std::error_code close() override { return {}; } + std::error_code close() { return {}; } private: - Zone zone_; - Config cfg_; + uint64_t stream_key_; + avtp::ByteBusId endpoint_; + Config cfg_; }; -inline std::shared_ptr new_controller(Zone zone, Config cfg) { - return std::make_shared(zone, std::move(cfg)); +inline std::shared_ptr new_bridge(uint64_t stream_key, avtp::ByteBusId endpoint, Config cfg) { + return std::make_shared(stream_key, endpoint, std::move(cfg)); } } // namespace someipbr diff --git a/include/rcp/udsbr.hpp b/include/rcp/udsbr.hpp index 1cbfd9d..6253348 100644 --- a/include/rcp/udsbr.hpp +++ b/include/rcp/udsbr.hpp @@ -3,16 +3,53 @@ // fusa:req REQ-UDS-003 // fusa:req REQ-UDS-004 -// UDS (Unified Diagnostic Services / ISO 14229) bridge interface stub (v0.38.0). +// UDS (Unified Diagnostic Services / ISO 14229) bridge interface stub. // -// Wraps RCP commands as UDS service requests (SID 0x31 RoutineControl). -// Requires a UDS stack integration. All methods return errc::function_not_supported. +// Wraps RC-Client-level requests as UDS service requests (SID 0x31 +// RoutineControl). Requires a UDS stack integration. All methods return +// errc::function_not_supported until a concrete backend is linked. +// +// ROADMAP.md milestone 59, "Application-Layer Protocol Bridge Rebind +// (v2.15.0)": this header is ADAPTed, per the Satellite Package +// Disposition table's entry for `udsbr.hpp` — translating between an RC +// Client's application-level view and a UDS service is conceptually +// unaffected by which wire protocol RCP itself now speaks, so this is a +// mechanical interface update, not a redesign; the stub had no working +// behavior to preserve in the first place. The pre-replacement +// `UdsController : public rcp::Controller` wrapper (keyed by the removed +// `Zone` type) is dropped for a standalone `UdsBridge`, the same +// "primitives, not a wrapped chokepoint" choice `rcp/authz.hpp` (v2.11.0) +// and `rcp/tsn.hpp`/`rcp/record.hpp`/`rcp/observe.hpp` (v2.14.0) already +// made — there is no unified client-side `send()` chokepoint left to wrap +// (that unification, if any, does not land until the CLI/capi/adapt +// rebuilds at v2.16.0, per those files' own notes). Addressing moves from +// `Zone` to the opaque per-connection `stream_key` (typically +// `avtp::StreamId::to_u64()`) plus `avtp::ByteBusId` pair every other +// Phase 14/15 header keys on since v2.10.0. `UdsBridge::request` takes on +// the pre-replacement wrapper's `send()` role, shaped to match +// `rcp/record.hpp`'s/`rcp/observe.hpp`'s `RequestFn` — the same "new +// client-side send-equivalent call" shape as `rcp/udp.hpp`'s +// `Client::request` core signature — so a caller can address this bridge +// exactly where it would otherwise address a transport `Client`. The old +// `subscribe()`/`StatusChannel` method has no analog here: it belonged to +// `rcp::Controller`'s status-telemetry push model, which is not part of +// the target specification's request/response shape. +// +// This header bridges into UDS, the diagnostic-services ecosystem; it is +// unrelated to `rcp/doipbr.hpp`'s DoIP transport encapsulation beyond the +// fact that DoIP commonly carries UDS requests over TCP/IP — each header +// stubs its own side of that pairing independently. #pragma once -#include "rcp.hpp" +#include "acf.hpp" +#include "avtp.hpp" +#include "rcp.hpp" // for rcp::Context only — see this header's own scope note above +#include #include #include +#include +#include namespace rcp { namespace udsbr { @@ -23,30 +60,37 @@ struct Config { std::chrono::milliseconds p2ext_timeout{5000}; // extended P2* timeout }; -class UdsController final : public rcp::Controller { +// UdsBridge stubs the request/response side of a bridge between one RCP +// endpoint (`stream_key` + `endpoint`) and a UDS RoutineControl request +// against `cfg.routine_id`. No concrete UDS stack is linked here; every +// call reports errc::function_not_supported. +class UdsBridge { public: - UdsController(Zone zone, Config cfg) : zone_(zone), cfg_(std::move(cfg)) {} - - Zone zone() const noexcept override { return zone_; } + UdsBridge(uint64_t stream_key, avtp::ByteBusId endpoint, Config cfg) + : stream_key_(stream_key), endpoint_(endpoint), cfg_(std::move(cfg)) {} - std::error_code send(const rcp::Context&, const Command&, Response&) override { - return std::make_error_code(std::errc::function_not_supported); - } + uint64_t stream_key() const noexcept { return stream_key_; } + avtp::ByteBusId endpoint() const noexcept { return endpoint_; } - std::error_code subscribe(const rcp::Context&, - std::shared_ptr&) override { + // request is this bridge's client-side send-equivalent call — see this + // file's header comment for why its shape matches rcp/record.hpp's and + // rcp/observe.hpp's RequestFn. + std::error_code request(const rcp::Context&, const acf::AcfMessageInfo&, + const std::vector&, + acf::AcfMessageInfo&, std::vector&) { return std::make_error_code(std::errc::function_not_supported); } - std::error_code close() override { return {}; } + std::error_code close() { return {}; } private: - Zone zone_; - Config cfg_; + uint64_t stream_key_; + avtp::ByteBusId endpoint_; + Config cfg_; }; -inline std::shared_ptr new_controller(Zone zone, Config cfg) { - return std::make_shared(zone, std::move(cfg)); +inline std::shared_ptr new_bridge(uint64_t stream_key, avtp::ByteBusId endpoint, Config cfg) { + return std::make_shared(stream_key, endpoint, std::move(cfg)); } } // namespace udsbr diff --git a/include/rcp/version.hpp b/include/rcp/version.hpp index 25b4251..2cf1d56 100644 --- a/include/rcp/version.hpp +++ b/include/rcp/version.hpp @@ -6,6 +6,6 @@ namespace rcp { // Semantic version of the cpp-RCP implementation (matches the latest git tag). -constexpr std::string_view kVersion = "2.14.0"; +constexpr std::string_view kVersion = "2.15.0"; } // namespace rcp diff --git a/tests/test_ddsbr.cpp b/tests/test_ddsbr.cpp index 240cf03..89d6215 100644 --- a/tests/test_ddsbr.cpp +++ b/tests/test_ddsbr.cpp @@ -3,12 +3,14 @@ // fusa:test REQ-DDS-003 // fusa:test REQ-DDS-004 -// ddsbr protocol-bridge stub conformance tests. +// ddsbr protocol-bridge stub conformance tests (ROADMAP.md milestone 59, +// "Application-Layer Protocol Bridge Rebind", v2.15.0). // -// The DdsController is a compile-time interface stub: until a concrete backend is -// linked, send()/subscribe() return std::errc::function_not_supported, zone() -// reports the configured zone, and close() succeeds. These tests pin that -// contract so callers get a well-defined error rather than undefined behaviour. +// DdsBridge is a compile-time interface stub: until a concrete DDS +// backend is linked, request() returns std::errc::function_not_supported, +// stream_key()/endpoint() report the values supplied at construction, and +// close() succeeds. These tests pin that contract so callers get a +// well-defined error rather than undefined behaviour. #include #include "rcp/ddsbr.hpp" @@ -22,27 +24,25 @@ const std::error_code kUnsupported = std::make_error_code(std::errc::function_not_supported); } // namespace -TEST_CASE("ddsbr: send returns function_not_supported when stub", "[ddsbr][REQ-DDS-001]") { - auto ctrl = ddsbr::new_controller(Zone::FrontLeft, ddsbr::Config{}); - Command cmd; - cmd.zone = Zone::FrontLeft; - cmd.type = CommandType::Set; - Response resp; - REQUIRE(ctrl->send(Context{}, cmd, resp) == kUnsupported); +TEST_CASE("ddsbr: request returns function_not_supported when stub", "[ddsbr][REQ-DDS-001]") { + auto bridge = ddsbr::new_bridge(/*stream_key=*/1, /*endpoint=*/3, ddsbr::Config{}); + auto req = acf::make_standard_request(3, 1, /*write=*/false, /*read_size=*/2); + acf::AcfMessageInfo resp; + std::vector resp_payload; + REQUIRE(bridge->request(Context{}, req, {}, resp, resp_payload) == kUnsupported); } -TEST_CASE("ddsbr: zone returns configured zone", "[ddsbr][REQ-DDS-002]") { - auto ctrl = ddsbr::new_controller(Zone::RearRight, ddsbr::Config{}); - REQUIRE(ctrl->zone() == Zone::RearRight); +TEST_CASE("ddsbr: stream_key returns configured value", "[ddsbr][REQ-DDS-002]") { + auto bridge = ddsbr::new_bridge(42, 3, ddsbr::Config{}); + REQUIRE(bridge->stream_key() == 42); } -TEST_CASE("ddsbr: subscribe returns function_not_supported when stub", "[ddsbr][REQ-DDS-003]") { - auto ctrl = ddsbr::new_controller(Zone::Central, ddsbr::Config{}); - std::shared_ptr ch; - REQUIRE(ctrl->subscribe(Context{}, ch) == kUnsupported); +TEST_CASE("ddsbr: endpoint returns configured value", "[ddsbr][REQ-DDS-003]") { + auto bridge = ddsbr::new_bridge(1, /*endpoint=*/9, ddsbr::Config{}); + REQUIRE(bridge->endpoint() == 9); } TEST_CASE("ddsbr: close returns no error", "[ddsbr][REQ-DDS-004]") { - auto ctrl = ddsbr::new_controller(Zone::FrontRight, ddsbr::Config{}); - REQUIRE_FALSE(ctrl->close()); + auto bridge = ddsbr::new_bridge(1, 3, ddsbr::Config{}); + REQUIRE_FALSE(bridge->close()); } diff --git a/tests/test_doipbr.cpp b/tests/test_doipbr.cpp index fe852cd..30e3d56 100644 --- a/tests/test_doipbr.cpp +++ b/tests/test_doipbr.cpp @@ -3,12 +3,14 @@ // fusa:test REQ-DOIP-003 // fusa:test REQ-DOIP-004 -// doipbr protocol-bridge stub conformance tests. +// doipbr protocol-bridge stub conformance tests (ROADMAP.md milestone 59, +// "Application-Layer Protocol Bridge Rebind", v2.15.0). // -// The DoIpController is a compile-time interface stub: until a concrete backend is -// linked, send()/subscribe() return std::errc::function_not_supported, zone() -// reports the configured zone, and close() succeeds. These tests pin that -// contract so callers get a well-defined error rather than undefined behaviour. +// DoIpBridge is a compile-time interface stub: until a concrete DoIP +// stack is linked, request() returns std::errc::function_not_supported, +// stream_key()/endpoint() report the values supplied at construction, and +// close() succeeds. These tests pin that contract so callers get a +// well-defined error rather than undefined behaviour. #include #include "rcp/doipbr.hpp" @@ -22,27 +24,25 @@ const std::error_code kUnsupported = std::make_error_code(std::errc::function_not_supported); } // namespace -TEST_CASE("doipbr: send returns function_not_supported when stub", "[doipbr][REQ-DOIP-001]") { - auto ctrl = doipbr::new_controller(Zone::FrontLeft, doipbr::Config{}); - Command cmd; - cmd.zone = Zone::FrontLeft; - cmd.type = CommandType::Set; - Response resp; - REQUIRE(ctrl->send(Context{}, cmd, resp) == kUnsupported); +TEST_CASE("doipbr: request returns function_not_supported when stub", "[doipbr][REQ-DOIP-001]") { + auto bridge = doipbr::new_bridge(/*stream_key=*/1, /*endpoint=*/3, doipbr::Config{}); + auto req = acf::make_standard_request(3, 1, /*write=*/false, /*read_size=*/2); + acf::AcfMessageInfo resp; + std::vector resp_payload; + REQUIRE(bridge->request(Context{}, req, {}, resp, resp_payload) == kUnsupported); } -TEST_CASE("doipbr: zone returns configured zone", "[doipbr][REQ-DOIP-002]") { - auto ctrl = doipbr::new_controller(Zone::RearRight, doipbr::Config{}); - REQUIRE(ctrl->zone() == Zone::RearRight); +TEST_CASE("doipbr: stream_key returns configured value", "[doipbr][REQ-DOIP-002]") { + auto bridge = doipbr::new_bridge(42, 3, doipbr::Config{}); + REQUIRE(bridge->stream_key() == 42); } -TEST_CASE("doipbr: subscribe returns function_not_supported when stub", "[doipbr][REQ-DOIP-003]") { - auto ctrl = doipbr::new_controller(Zone::Central, doipbr::Config{}); - std::shared_ptr ch; - REQUIRE(ctrl->subscribe(Context{}, ch) == kUnsupported); +TEST_CASE("doipbr: endpoint returns configured value", "[doipbr][REQ-DOIP-003]") { + auto bridge = doipbr::new_bridge(1, /*endpoint=*/9, doipbr::Config{}); + REQUIRE(bridge->endpoint() == 9); } TEST_CASE("doipbr: close returns no error", "[doipbr][REQ-DOIP-004]") { - auto ctrl = doipbr::new_controller(Zone::FrontRight, doipbr::Config{}); - REQUIRE_FALSE(ctrl->close()); + auto bridge = doipbr::new_bridge(1, 3, doipbr::Config{}); + REQUIRE_FALSE(bridge->close()); } diff --git a/tests/test_grpcbridge.cpp b/tests/test_grpcbridge.cpp index 24d7dbc..9978b3d 100644 --- a/tests/test_grpcbridge.cpp +++ b/tests/test_grpcbridge.cpp @@ -3,12 +3,14 @@ // fusa:test REQ-GRPC-003 // fusa:test REQ-GRPC-004 -// grpcbridge protocol-bridge stub conformance tests. +// grpcbridge protocol-bridge stub conformance tests (ROADMAP.md milestone +// 59, "Application-Layer Protocol Bridge Rebind", v2.15.0). // -// The GrpcController is a compile-time interface stub: until a concrete backend is -// linked, send()/subscribe() return std::errc::function_not_supported, zone() -// reports the configured zone, and close() succeeds. These tests pin that -// contract so callers get a well-defined error rather than undefined behaviour. +// GrpcBridge is a compile-time interface stub: until a concrete gRPC +// adapter is linked, request() returns std::errc::function_not_supported, +// stream_key()/endpoint() report the values supplied at construction, and +// close() succeeds. These tests pin that contract so callers get a +// well-defined error rather than undefined behaviour. #include #include "rcp/grpcbridge.hpp" @@ -22,27 +24,25 @@ const std::error_code kUnsupported = std::make_error_code(std::errc::function_not_supported); } // namespace -TEST_CASE("grpcbridge: send returns function_not_supported when stub", "[grpcbridge][REQ-GRPC-001]") { - auto ctrl = grpcbridge::new_controller(Zone::FrontLeft, grpcbridge::Config{}); - Command cmd; - cmd.zone = Zone::FrontLeft; - cmd.type = CommandType::Set; - Response resp; - REQUIRE(ctrl->send(Context{}, cmd, resp) == kUnsupported); +TEST_CASE("grpcbridge: request returns function_not_supported when stub", "[grpcbridge][REQ-GRPC-001]") { + auto bridge = grpcbridge::new_bridge(/*stream_key=*/1, /*endpoint=*/3, grpcbridge::Config{}); + auto req = acf::make_standard_request(3, 1, /*write=*/false, /*read_size=*/2); + acf::AcfMessageInfo resp; + std::vector resp_payload; + REQUIRE(bridge->request(Context{}, req, {}, resp, resp_payload) == kUnsupported); } -TEST_CASE("grpcbridge: zone returns configured zone", "[grpcbridge][REQ-GRPC-002]") { - auto ctrl = grpcbridge::new_controller(Zone::RearRight, grpcbridge::Config{}); - REQUIRE(ctrl->zone() == Zone::RearRight); +TEST_CASE("grpcbridge: stream_key returns configured value", "[grpcbridge][REQ-GRPC-002]") { + auto bridge = grpcbridge::new_bridge(42, 3, grpcbridge::Config{}); + REQUIRE(bridge->stream_key() == 42); } -TEST_CASE("grpcbridge: subscribe returns function_not_supported when stub", "[grpcbridge][REQ-GRPC-003]") { - auto ctrl = grpcbridge::new_controller(Zone::Central, grpcbridge::Config{}); - std::shared_ptr ch; - REQUIRE(ctrl->subscribe(Context{}, ch) == kUnsupported); +TEST_CASE("grpcbridge: endpoint returns configured value", "[grpcbridge][REQ-GRPC-003]") { + auto bridge = grpcbridge::new_bridge(1, /*endpoint=*/9, grpcbridge::Config{}); + REQUIRE(bridge->endpoint() == 9); } TEST_CASE("grpcbridge: close returns no error", "[grpcbridge][REQ-GRPC-004]") { - auto ctrl = grpcbridge::new_controller(Zone::FrontRight, grpcbridge::Config{}); - REQUIRE_FALSE(ctrl->close()); + auto bridge = grpcbridge::new_bridge(1, 3, grpcbridge::Config{}); + REQUIRE_FALSE(bridge->close()); } diff --git a/tests/test_mqttbr.cpp b/tests/test_mqttbr.cpp index 992cdd8..fdd9fb2 100644 --- a/tests/test_mqttbr.cpp +++ b/tests/test_mqttbr.cpp @@ -3,12 +3,14 @@ // fusa:test REQ-MQTT-003 // fusa:test REQ-MQTT-004 -// mqttbr protocol-bridge stub conformance tests. +// mqttbr protocol-bridge stub conformance tests (ROADMAP.md milestone 59, +// "Application-Layer Protocol Bridge Rebind", v2.15.0). // -// The MqttController is a compile-time interface stub: until a concrete backend is -// linked, send()/subscribe() return std::errc::function_not_supported, zone() -// reports the configured zone, and close() succeeds. These tests pin that -// contract so callers get a well-defined error rather than undefined behaviour. +// MqttBridge is a compile-time interface stub: until a concrete MQTT +// backend is linked, request() returns std::errc::function_not_supported, +// stream_key()/endpoint() report the values supplied at construction, and +// close() succeeds. These tests pin that contract so callers get a +// well-defined error rather than undefined behaviour. #include #include "rcp/mqttbr.hpp" @@ -22,27 +24,25 @@ const std::error_code kUnsupported = std::make_error_code(std::errc::function_not_supported); } // namespace -TEST_CASE("mqttbr: send returns function_not_supported when stub", "[mqttbr][REQ-MQTT-001]") { - auto ctrl = mqttbr::new_controller(Zone::FrontLeft, mqttbr::Config{}); - Command cmd; - cmd.zone = Zone::FrontLeft; - cmd.type = CommandType::Set; - Response resp; - REQUIRE(ctrl->send(Context{}, cmd, resp) == kUnsupported); +TEST_CASE("mqttbr: request returns function_not_supported when stub", "[mqttbr][REQ-MQTT-001]") { + auto bridge = mqttbr::new_bridge(/*stream_key=*/1, /*endpoint=*/3, mqttbr::Config{}); + auto req = acf::make_standard_request(3, 1, /*write=*/false, /*read_size=*/2); + acf::AcfMessageInfo resp; + std::vector resp_payload; + REQUIRE(bridge->request(Context{}, req, {}, resp, resp_payload) == kUnsupported); } -TEST_CASE("mqttbr: zone returns configured zone", "[mqttbr][REQ-MQTT-002]") { - auto ctrl = mqttbr::new_controller(Zone::RearRight, mqttbr::Config{}); - REQUIRE(ctrl->zone() == Zone::RearRight); +TEST_CASE("mqttbr: stream_key returns configured value", "[mqttbr][REQ-MQTT-002]") { + auto bridge = mqttbr::new_bridge(42, 3, mqttbr::Config{}); + REQUIRE(bridge->stream_key() == 42); } -TEST_CASE("mqttbr: subscribe returns function_not_supported when stub", "[mqttbr][REQ-MQTT-003]") { - auto ctrl = mqttbr::new_controller(Zone::Central, mqttbr::Config{}); - std::shared_ptr ch; - REQUIRE(ctrl->subscribe(Context{}, ch) == kUnsupported); +TEST_CASE("mqttbr: endpoint returns configured value", "[mqttbr][REQ-MQTT-003]") { + auto bridge = mqttbr::new_bridge(1, /*endpoint=*/9, mqttbr::Config{}); + REQUIRE(bridge->endpoint() == 9); } TEST_CASE("mqttbr: close returns no error", "[mqttbr][REQ-MQTT-004]") { - auto ctrl = mqttbr::new_controller(Zone::FrontRight, mqttbr::Config{}); - REQUIRE_FALSE(ctrl->close()); + auto bridge = mqttbr::new_bridge(1, 3, mqttbr::Config{}); + REQUIRE_FALSE(bridge->close()); } diff --git a/tests/test_restbridge.cpp b/tests/test_restbridge.cpp index afe5d35..2ba5b6a 100644 --- a/tests/test_restbridge.cpp +++ b/tests/test_restbridge.cpp @@ -3,12 +3,15 @@ // fusa:test REQ-REST-003 // fusa:test REQ-REST-004 -// restbridge protocol-bridge stub conformance tests. +// restbridge protocol-bridge stub conformance tests (ROADMAP.md milestone +// 59, "Application-Layer Protocol Bridge Rebind", v2.15.0). // -// The RestController is a compile-time interface stub: until a concrete backend is -// linked, send()/subscribe() return std::errc::function_not_supported, zone() -// reports the configured zone, and close() succeeds. These tests pin that -// contract so callers get a well-defined error rather than undefined behaviour. +// RestBridge is a compile-time interface stub: until a concrete HTTP +// client backend is linked, request() returns +// std::errc::function_not_supported, stream_key()/endpoint() report the +// values supplied at construction, and close() succeeds. These tests pin +// that contract so callers get a well-defined error rather than undefined +// behaviour. #include #include "rcp/restbridge.hpp" @@ -22,27 +25,25 @@ const std::error_code kUnsupported = std::make_error_code(std::errc::function_not_supported); } // namespace -TEST_CASE("restbridge: send returns function_not_supported when stub", "[restbridge][REQ-REST-001]") { - auto ctrl = restbridge::new_controller(Zone::FrontLeft, restbridge::Config{}); - Command cmd; - cmd.zone = Zone::FrontLeft; - cmd.type = CommandType::Set; - Response resp; - REQUIRE(ctrl->send(Context{}, cmd, resp) == kUnsupported); +TEST_CASE("restbridge: request returns function_not_supported when stub", "[restbridge][REQ-REST-001]") { + auto bridge = restbridge::new_bridge(/*stream_key=*/1, /*endpoint=*/3, restbridge::Config{}); + auto req = acf::make_standard_request(3, 1, /*write=*/false, /*read_size=*/2); + acf::AcfMessageInfo resp; + std::vector resp_payload; + REQUIRE(bridge->request(Context{}, req, {}, resp, resp_payload) == kUnsupported); } -TEST_CASE("restbridge: zone returns configured zone", "[restbridge][REQ-REST-002]") { - auto ctrl = restbridge::new_controller(Zone::RearRight, restbridge::Config{}); - REQUIRE(ctrl->zone() == Zone::RearRight); +TEST_CASE("restbridge: stream_key returns configured value", "[restbridge][REQ-REST-002]") { + auto bridge = restbridge::new_bridge(42, 3, restbridge::Config{}); + REQUIRE(bridge->stream_key() == 42); } -TEST_CASE("restbridge: subscribe returns function_not_supported when stub", "[restbridge][REQ-REST-003]") { - auto ctrl = restbridge::new_controller(Zone::Central, restbridge::Config{}); - std::shared_ptr ch; - REQUIRE(ctrl->subscribe(Context{}, ch) == kUnsupported); +TEST_CASE("restbridge: endpoint returns configured value", "[restbridge][REQ-REST-003]") { + auto bridge = restbridge::new_bridge(1, /*endpoint=*/9, restbridge::Config{}); + REQUIRE(bridge->endpoint() == 9); } TEST_CASE("restbridge: close returns no error", "[restbridge][REQ-REST-004]") { - auto ctrl = restbridge::new_controller(Zone::FrontRight, restbridge::Config{}); - REQUIRE_FALSE(ctrl->close()); + auto bridge = restbridge::new_bridge(1, 3, restbridge::Config{}); + REQUIRE_FALSE(bridge->close()); } diff --git a/tests/test_someipbr.cpp b/tests/test_someipbr.cpp index 9f5162d..cc91592 100644 --- a/tests/test_someipbr.cpp +++ b/tests/test_someipbr.cpp @@ -3,12 +3,14 @@ // fusa:test REQ-SOMEIP-003 // fusa:test REQ-SOMEIP-004 -// someipbr protocol-bridge stub conformance tests. +// someipbr protocol-bridge stub conformance tests (ROADMAP.md milestone +// 59, "Application-Layer Protocol Bridge Rebind", v2.15.0). // -// The SomeIpController is a compile-time interface stub: until a concrete backend is -// linked, send()/subscribe() return std::errc::function_not_supported, zone() -// reports the configured zone, and close() succeeds. These tests pin that -// contract so callers get a well-defined error rather than undefined behaviour. +// SomeIpBridge is a compile-time interface stub: until a concrete vsomeip +// adapter is linked, request() returns std::errc::function_not_supported, +// stream_key()/endpoint() report the values supplied at construction, and +// close() succeeds. These tests pin that contract so callers get a +// well-defined error rather than undefined behaviour. #include #include "rcp/someipbr.hpp" @@ -22,27 +24,25 @@ const std::error_code kUnsupported = std::make_error_code(std::errc::function_not_supported); } // namespace -TEST_CASE("someipbr: send returns function_not_supported when stub", "[someipbr][REQ-SOMEIP-001]") { - auto ctrl = someipbr::new_controller(Zone::FrontLeft, someipbr::Config{}); - Command cmd; - cmd.zone = Zone::FrontLeft; - cmd.type = CommandType::Set; - Response resp; - REQUIRE(ctrl->send(Context{}, cmd, resp) == kUnsupported); +TEST_CASE("someipbr: request returns function_not_supported when stub", "[someipbr][REQ-SOMEIP-001]") { + auto bridge = someipbr::new_bridge(/*stream_key=*/1, /*endpoint=*/3, someipbr::Config{}); + auto req = acf::make_standard_request(3, 1, /*write=*/false, /*read_size=*/2); + acf::AcfMessageInfo resp; + std::vector resp_payload; + REQUIRE(bridge->request(Context{}, req, {}, resp, resp_payload) == kUnsupported); } -TEST_CASE("someipbr: zone returns configured zone", "[someipbr][REQ-SOMEIP-002]") { - auto ctrl = someipbr::new_controller(Zone::RearRight, someipbr::Config{}); - REQUIRE(ctrl->zone() == Zone::RearRight); +TEST_CASE("someipbr: stream_key returns configured value", "[someipbr][REQ-SOMEIP-002]") { + auto bridge = someipbr::new_bridge(42, 3, someipbr::Config{}); + REQUIRE(bridge->stream_key() == 42); } -TEST_CASE("someipbr: subscribe returns function_not_supported when stub", "[someipbr][REQ-SOMEIP-003]") { - auto ctrl = someipbr::new_controller(Zone::Central, someipbr::Config{}); - std::shared_ptr ch; - REQUIRE(ctrl->subscribe(Context{}, ch) == kUnsupported); +TEST_CASE("someipbr: endpoint returns configured value", "[someipbr][REQ-SOMEIP-003]") { + auto bridge = someipbr::new_bridge(1, /*endpoint=*/9, someipbr::Config{}); + REQUIRE(bridge->endpoint() == 9); } TEST_CASE("someipbr: close returns no error", "[someipbr][REQ-SOMEIP-004]") { - auto ctrl = someipbr::new_controller(Zone::FrontRight, someipbr::Config{}); - REQUIRE_FALSE(ctrl->close()); + auto bridge = someipbr::new_bridge(1, 3, someipbr::Config{}); + REQUIRE_FALSE(bridge->close()); } diff --git a/tests/test_udsbr.cpp b/tests/test_udsbr.cpp index a1af522..fdd5351 100644 --- a/tests/test_udsbr.cpp +++ b/tests/test_udsbr.cpp @@ -3,12 +3,14 @@ // fusa:test REQ-UDS-003 // fusa:test REQ-UDS-004 -// udsbr protocol-bridge stub conformance tests. +// udsbr protocol-bridge stub conformance tests (ROADMAP.md milestone 59, +// "Application-Layer Protocol Bridge Rebind", v2.15.0). // -// The UdsController is a compile-time interface stub: until a concrete backend is -// linked, send()/subscribe() return std::errc::function_not_supported, zone() -// reports the configured zone, and close() succeeds. These tests pin that -// contract so callers get a well-defined error rather than undefined behaviour. +// UdsBridge is a compile-time interface stub: until a concrete UDS stack +// is linked, request() returns std::errc::function_not_supported, +// stream_key()/endpoint() report the values supplied at construction, and +// close() succeeds. These tests pin that contract so callers get a +// well-defined error rather than undefined behaviour. #include #include "rcp/udsbr.hpp" @@ -22,27 +24,25 @@ const std::error_code kUnsupported = std::make_error_code(std::errc::function_not_supported); } // namespace -TEST_CASE("udsbr: send returns function_not_supported when stub", "[udsbr][REQ-UDS-001]") { - auto ctrl = udsbr::new_controller(Zone::FrontLeft, udsbr::Config{}); - Command cmd; - cmd.zone = Zone::FrontLeft; - cmd.type = CommandType::Set; - Response resp; - REQUIRE(ctrl->send(Context{}, cmd, resp) == kUnsupported); +TEST_CASE("udsbr: request returns function_not_supported when stub", "[udsbr][REQ-UDS-001]") { + auto bridge = udsbr::new_bridge(/*stream_key=*/1, /*endpoint=*/3, udsbr::Config{}); + auto req = acf::make_standard_request(3, 1, /*write=*/false, /*read_size=*/2); + acf::AcfMessageInfo resp; + std::vector resp_payload; + REQUIRE(bridge->request(Context{}, req, {}, resp, resp_payload) == kUnsupported); } -TEST_CASE("udsbr: zone returns configured zone", "[udsbr][REQ-UDS-002]") { - auto ctrl = udsbr::new_controller(Zone::RearRight, udsbr::Config{}); - REQUIRE(ctrl->zone() == Zone::RearRight); +TEST_CASE("udsbr: stream_key returns configured value", "[udsbr][REQ-UDS-002]") { + auto bridge = udsbr::new_bridge(42, 3, udsbr::Config{}); + REQUIRE(bridge->stream_key() == 42); } -TEST_CASE("udsbr: subscribe returns function_not_supported when stub", "[udsbr][REQ-UDS-003]") { - auto ctrl = udsbr::new_controller(Zone::Central, udsbr::Config{}); - std::shared_ptr ch; - REQUIRE(ctrl->subscribe(Context{}, ch) == kUnsupported); +TEST_CASE("udsbr: endpoint returns configured value", "[udsbr][REQ-UDS-003]") { + auto bridge = udsbr::new_bridge(1, /*endpoint=*/9, udsbr::Config{}); + REQUIRE(bridge->endpoint() == 9); } TEST_CASE("udsbr: close returns no error", "[udsbr][REQ-UDS-004]") { - auto ctrl = udsbr::new_controller(Zone::FrontRight, udsbr::Config{}); - REQUIRE_FALSE(ctrl->close()); + auto bridge = udsbr::new_bridge(1, 3, udsbr::Config{}); + REQUIRE_FALSE(bridge->close()); }