|
RTE RBC 2oo2 Reference Application 0.1.0 build 0006685
SIL 4 2oo2 Dual-Site Fault-Tolerant ERTMS Radio Block Centre Reference Architecture
|
Channel A / channel B com layer using native RTE rte_channel_service. More...
#include "ab_gp_channel.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include "rte/redundancy/checkpoint/rte_checkpoint.h"#include "rte/redundancy/channel_service/rte_channel_service.h"#include "rte/redundancy/channel_service/rte_channel_service_flow_osadapter.h"#include "rte/posix_osadapter/rte_posix_osadapter_channel_service.h"#include "rte/protocol_adapter_dds/rte_protocol_adapter_dds.h"#include "rte_osadapter/flow/rte_osadapter_flow.h"#include "rte/oal/log/rte_log.h"#include "rte/oal/memory/rte_mem_util.h"#include "rte/utils/safestate/rte_safestate.h"#include "../../common/common_config.h"#include "../../common/rbc_util_frame.h"#include "ab_gp_channel_checkpoint.h"#include "ab_gp_channel_crosscompare.h"#include "ab_gp_channel_dual.h"#include "ab_gp_channel_negotiate.h"#include "ab_gp_standby_policy.h"#include "ab_gp_channel_types.h"#include "ab_gp_channel_util.h"#include "ab_gp_channel_payload.h"#include "ab_gp_km114_relay.h"#include "../ga_interface/ga_interface.h"#include "../main/ab_gp_ga_hooks.h"#include "../train/ab_gp_train.h"#include "../ertms_procedures/ab_gp_ertms_engine.h"Go to the source code of this file.
Functions | |
| static void | apply_host_env_override (const char *name, const ab_gp_channel_context_t *ctx, rte_netlink_config_t *config) |
| static bool | try_resolve_from_redundancy_config (const ab_gp_channel_context_t *ctx, const char *name, rte_netlink_config_t *config) |
| static bool | try_resolve_from_legacy_config (const ab_gp_channel_context_t *ctx, const char *name, rte_netlink_config_t *config) |
| static bool | relay_kind_from_name (const char *name, rte_example_relay_kind_t *out_kind) |
| static uint32_t | message_size_for_relay_kind (rte_example_relay_kind_t rk) |
| static rte_status_t | resolve_channel_hardcoded_fallback (const ab_gp_channel_context_t *ctx, const char *name, rte_netlink_config_t *config) |
| static void | enforce_hardcoded_port (const ab_gp_channel_context_t *ctx, const char *name, rte_netlink_config_t *config) |
| static rte_status_t | resolve_channel (const char *name, rte_netlink_config_t *config, void *context) |
| static rte_status_t | resolve_channel_flow (const char *name, rte_netlink_config_t *config, void *context) |
| static bool | ab_gp_supports_redundancy (rte_redundancy_topology_t topology, uint32_t replica_count, void *context) |
| static rte_status_t | channel_service_setup_with_retry (rte_channel_service_t *storage, const char *name) |
| static void | cycle_tick_callback (rte_timer_handle_t handle, void *user_ctx) |
| static void | ab_gp_channel_safestate_handler (rte_safestate_level_t level, rte_safestate_reason_t reason, const char *file, int32_t line, const char *message) |
| static void | load_legacy_config (ab_gp_channel_context_t *ctx, rte_example_site_t site, bool is_role_a) |
| Load the legacy .conf config into ctx->config: RTE_CONFIG_FILE override, or the default etc/config/<role>_<site>.conf with an /etc/sapi/... fallback. | |
| static rte_status_t | load_redundancy_config (ab_gp_channel_context_t *ctx, rte_example_site_t site, bool is_role_a) |
| Load the app-level redundancy topology config into ctx->redundancy (RCA/OCORA Phase 8). | |
| static rte_status_t | open_relay_channels (ab_gp_channel_context_t *ctx) |
| Open the relay channel for each rte_example_relay_kind_t. | |
| rte_status_t | ab_gp_channel_open_link (bool is_role_a, rte_example_site_t site, ab_gp_channel_handle_t *out_handle) |
| Opens this process's own A<->B peer channel and C relay channels. | |
| void | ab_gp_channel_close_link (ab_gp_channel_handle_t handle) |
| Full teardown of a channel opened by ab_gp_channel_open_link(). | |
| rte_status_t | ab_gp_channel_checkpoint_setup (ab_gp_channel_handle_t handle) |
| Wires AppManager checkpoint mechanism onto peer channel. | |
| rte_status_t | ab_gp_channel_dual_setup (ab_gp_channel_handle_t handle) |
| Wires dual-transfer liveness watchdog. | |
| const rte_appmanager_checkpoint_config_t * | ab_gp_channel_checkpoint_config (ab_gp_channel_handle_t handle) |
| Accessor for checkpoint config. | |
| rte_status_t | ab_gp_channel_crosscompare_setup (ab_gp_channel_handle_t handle) |
| Creates cross-comparator on an already-open channel. | |
| rte_status_t | ab_gp_channel_init (void *context) |
| rte_appmanager_operations_t::init hook. | |
| rte_status_t | ab_gp_channel_train_codec_setup (ab_gp_channel_handle_t handle) |
| GP-internal registration for train codec. | |
| rte_status_t | ab_gp_channel_ga_setup (ab_gp_channel_handle_t handle) |
| GA registration for ma_logic_adaptation / il / ctc. | |
| void | ab_gp_channel_relay_queues_setup (ab_gp_channel_handle_t handle) |
| Initializes relay queues (no-op in single-threaded channel_service). | |
| rte_status_t | ab_gp_channel_negotiate_setup (ab_gp_channel_handle_t handle) |
| Opens inter-site negotiation link and runs startup tie-break. | |
| rte_status_t | ab_gp_channel_watchdog_setup (ab_gp_channel_handle_t handle) |
| Arms general health watchdog. | |
| rte_status_t | ab_gp_channel_cycle_timer_setup (ab_gp_channel_handle_t handle) |
| Creates and starts periodic cycle timer. | |
| rte_status_t | ab_gp_channel_wait_cycle_tick (ab_gp_channel_handle_t handle) |
| Waits for the periodic cycle timer tick, advances cycle, and refreshes watchdog/checkpoint state. | |
| static rte_status_t | send_util_gated (ab_gp_channel_context_t *ctx, const uint8_t *bytes, size_t size) |
| uint32_t | ab_gp_channel_poll_relays (ab_gp_channel_handle_t handle, ab_gp_com_envelope_cb cb, void *user_ctx) |
Polls all C relay channels non-blockingly and invokes cb for every received envelope. | |
| void | ab_gp_channel_poll_peer (ab_gp_channel_handle_t handle, ab_gp_com_peer_frame_cb cb, void *user_ctx) |
Polls the A<->B peer channel non-blockingly and invokes cb for every received frame. | |
| void | ab_gp_channel_poll_crosscompare (ab_gp_channel_handle_t handle, ab_gp_com_peer_frame_cb cb, void *user_ctx) |
Polls the dedicated A<->B cross-compare channel non-blockingly and invokes cb for every received frame. | |
| rte_status_t | ab_gp_channel_send_crosscompare (ab_gp_channel_handle_t handle, uint8_t kind, const uint8_t *payload, size_t size) |
| Sends a frame over the dedicated A<->B cross-compare channel. | |
| rte_status_t | ab_gp_channel_send_relay (ab_gp_channel_handle_t handle, rte_example_relay_kind_t kind, uint8_t index, const uint8_t *bytes, size_t size) |
| Sends an envelope over a specific C relay channel. | |
| rte_status_t | ab_gp_channel_send_peer (ab_gp_channel_handle_t handle, const uint8_t *bytes, size_t size) |
| Sends a frame over the A<->B peer channel. | |
| ab_gp_saf_train_t * | ab_gp_channel_saf_train (ab_gp_channel_handle_t handle) |
| This channel's train-link SaF termination (ab_gp_saf_train.h), or NULL for a NULL handle. | |
| rte_status_t | ab_gp_channel_saf_train_setup (ab_gp_channel_handle_t handle) |
| Reads RTE_SAFECOMM_TRAIN_RBC_ID and sets up the train-link SaF termination: unset leaves it off (plain ERTMS frames, the behaviour before it existed); set to this RBC's ETCS identity (1..0xFFFFFF, decimal or 0x hex) turns it on. | |
| void | ab_gp_channel_raise_ctc_alarm (ab_gp_channel_handle_t handle, rbc_alarm_severity_t severity, uint32_t code, const char *log_message) |
| Raises a severity-leveled operational alarm: logs it locally (rte_log_write_event(), same structured Site/Cycle/Source/ Destination/Type/Info convention as every other event this codebase logs) AND forwards it to CTC (RBC_MSG_CTC_ALARM, see that kind's own doc in rbc_wire_types.h), so a human dispatcher sees it too, not just this process's own log. | |
| rte_status_t | ab_gp_channel_shutdown (void *context) |
| rte_appmanager_operations_t::shutdown hook. | |
Variables | |
| static ab_gp_channel_context_t | g_ab_ctx |
Channel A / channel B com layer using native RTE rte_channel_service.
Single-threaded cyclic executive transport module conforming to CENELEC EN 50128 SIL 4 safety principles and Single Responsibility Principle (SRP).
Definition in file ab_gp_channel.c.
|
static |
Definition at line 49 of file ab_gp_channel.c.
|
static |
Definition at line 101 of file ab_gp_channel.c.
|
static |
Definition at line 145 of file ab_gp_channel.c.
|
static |
Definition at line 169 of file ab_gp_channel.c.
|
static |
Definition at line 197 of file ab_gp_channel.c.
|
static |
Definition at line 214 of file ab_gp_channel.c.
|
static |
Definition at line 270 of file ab_gp_channel.c.
|
static |
Definition at line 300 of file ab_gp_channel.c.
|
static |
RCA/OCORA Phase 4 (see docs/rca/ at the workspace root and TODO.md's "RCA/OCORA compatibility" section): wraps resolve_channel() unchanged - same host/port/role/message_size resolution GP has always done - and additionally registers a route with the DDS-stub OSAdapter (safeAPIFlowBackendDDS) so rte_flow_open(name) can find it. A real DDS OSAdapter would need no such route (topics are self-describing via discovery); this wrapper is where that stub-specific wiring belongs, not inside rte_channel_service_flow_osadapter itself (deliberately osadapter-agnostic - see that module's own header doc). Every channel this process opens through rte_channel_service (ab-peer, ab-negotiate, ab-relay-*) shares this ONE resolver, since rte_channel_service has exactly one globally-registered OSAdapter per process - wire-compatible with role C's own still-POSIX-backed relay endpoints, since safeAPIFlowBackendDDS's stub delegates directly to rte_netlink with no extra framing (confirmed by reading dds_send()/dds_receive() - a plain passthrough).
Definition at line 339 of file ab_gp_channel.c.
|
static |
RCA/OCORA Phase 8 follow-up (see docs/rca/ and TODO.md): GP declares what it can actually run to rte_redundancy_config itself, via rte_redundancy_config_register_capability() - the Platform (the framework's own load()) then owns rejecting an unsupported config, instead of GP's own call site parsing the result and re-implementing the same allowlist check inline. Matches the "Platform decides, the Application only declares" posture rte_voter/rte_cross_comparator's own safestate-transition ownership already established this session.
Definition at line 357 of file ab_gp_channel.c.
|
static |
RCA/OCORA Phase 4: the flow-backed rte_channel_service_setup() path (through safeAPIFlowBackendDDS's dds_open() -> rte_netlink_open()) waits SYNCHRONOUSLY for the peer's HELLO/ACK handshake inside setup() itself, bounded by config->connect_timeout_ms - a real behavioral difference from safeAPIBackendPosix's own channel_service OSAdapter (osadapter_setup() fires the connect/HELLO and returns immediately, deferring ACK consumption to the first osadapter_read() call, so a slow peer never blocks setup()). Found live: with the same reconnect_attempt_timeout_ms=1000 budget every existing .conf file already specifies, "ab-relay-util" (opened last of the 4 relay channels, so most exposed to a loaded host's scheduling jitter) timed out under machine load while the original POSIX-backed path passed cleanly at identical ports - isolated by literally reverting this file's own change and re-running the same test, not assumed. Fixed the same way ab_gp_channel_negotiate.c's own open_connect_with_retry() already handles this exact class of problem for the site-negotiation link: retry setup() in a bounded loop instead of widening the per-attempt timeout (widening was tried and reverted for the A/B checkpoint rendezvous for the same reason - see this project's own CLAUDE.md "A/B checkpoint rendezvous" section - a wider single budget just delays the same failure, retrying actually recovers from a transient scheduling stall).
Definition at line 396 of file ab_gp_channel.c.
|
static |
Definition at line 426 of file ab_gp_channel.c.
|
static |
Definition at line 433 of file ab_gp_channel.c.
|
static |
Load the legacy .conf config into ctx->config: RTE_CONFIG_FILE override, or the default etc/config/<role>_<site>.conf with an /etc/sapi/... fallback.
Definition at line 465 of file ab_gp_channel.c.
|
static |
Load the app-level redundancy topology config into ctx->redundancy (RCA/OCORA Phase 8).
Absent file (the common case today - no deployment ships one yet) is NOT an error - falls back to the hardcoded 2oo2 defaults matching this file's own actual, only-ever-verified behavior, same "file optional, sensible default" posture load_legacy_config()'s own loading uses. A file that IS present but names a topology GP cannot actually run fails startup outright (RTE_STATUS_NOT_SUPPORTED from load() itself, per ab_gp_supports_redundancy()) - honestly reflecting real capability rather than silently accepting a config GP does not implement.
Definition at line 501 of file ab_gp_channel.c.
|
static |
Open the relay channel for each rte_example_relay_kind_t.
Definition at line 547 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_open_link | ( | bool | is_role_a, |
| rte_example_site_t | site, | ||
| ab_gp_channel_handle_t * | out_handle ) |
Opens this process's own A<->B peer channel and C relay channels.
Definition at line 583 of file ab_gp_channel.c.
| void ab_gp_channel_close_link | ( | ab_gp_channel_handle_t | handle | ) |
Full teardown of a channel opened by ab_gp_channel_open_link().
Definition at line 664 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_checkpoint_setup | ( | ab_gp_channel_handle_t | handle | ) |
Wires AppManager checkpoint mechanism onto peer channel.
Definition at line 672 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_dual_setup | ( | ab_gp_channel_handle_t | handle | ) |
Wires dual-transfer liveness watchdog.
Definition at line 737 of file ab_gp_channel.c.
| const rte_appmanager_checkpoint_config_t * ab_gp_channel_checkpoint_config | ( | ab_gp_channel_handle_t | handle | ) |
Accessor for checkpoint config.
Definition at line 752 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_crosscompare_setup | ( | ab_gp_channel_handle_t | handle | ) |
Creates cross-comparator on an already-open channel.
Definition at line 759 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_init | ( | void * | context | ) |
rte_appmanager_operations_t::init hook.
Definition at line 770 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_train_codec_setup | ( | ab_gp_channel_handle_t | handle | ) |
GP-internal registration for train codec.
Definition at line 788 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_ga_setup | ( | ab_gp_channel_handle_t | handle | ) |
GA registration for ma_logic_adaptation / il / ctc.
Definition at line 804 of file ab_gp_channel.c.
| void ab_gp_channel_relay_queues_setup | ( | ab_gp_channel_handle_t | handle | ) |
Initializes relay queues (no-op in single-threaded channel_service).
Definition at line 818 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_negotiate_setup | ( | ab_gp_channel_handle_t | handle | ) |
Opens inter-site negotiation link and runs startup tie-break.
Definition at line 823 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_watchdog_setup | ( | ab_gp_channel_handle_t | handle | ) |
Arms general health watchdog.
Definition at line 838 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_cycle_timer_setup | ( | ab_gp_channel_handle_t | handle | ) |
Creates and starts periodic cycle timer.
Definition at line 880 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_wait_cycle_tick | ( | ab_gp_channel_handle_t | handle | ) |
Waits for the periodic cycle timer tick, advances cycle, and refreshes watchdog/checkpoint state.
Definition at line 919 of file ab_gp_channel.c.
|
static |
Definition at line 1002 of file ab_gp_channel.c.
| uint32_t ab_gp_channel_poll_relays | ( | ab_gp_channel_handle_t | handle, |
| ab_gp_com_envelope_cb | cb, | ||
| void * | user_ctx ) |
Polls all C relay channels non-blockingly and invokes cb for every received envelope.
Definition at line 1029 of file ab_gp_channel.c.
| void ab_gp_channel_poll_peer | ( | ab_gp_channel_handle_t | handle, |
| ab_gp_com_peer_frame_cb | cb, | ||
| void * | user_ctx ) |
Polls the A<->B peer channel non-blockingly and invokes cb for every received frame.
Definition at line 1116 of file ab_gp_channel.c.
| void ab_gp_channel_poll_crosscompare | ( | ab_gp_channel_handle_t | handle, |
| ab_gp_com_peer_frame_cb | cb, | ||
| void * | user_ctx ) |
Polls the dedicated A<->B cross-compare channel non-blockingly and invokes cb for every received frame.
Definition at line 1135 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_send_crosscompare | ( | ab_gp_channel_handle_t | handle, |
| uint8_t | kind, | ||
| const uint8_t * | payload, | ||
| size_t | size ) |
Sends a frame over the dedicated A<->B cross-compare channel.
Definition at line 1154 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_send_relay | ( | ab_gp_channel_handle_t | handle, |
| rte_example_relay_kind_t | kind, | ||
| uint8_t | index, | ||
| const uint8_t * | bytes, | ||
| size_t | size ) |
Sends an envelope over a specific C relay channel.
Definition at line 1171 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_send_peer | ( | ab_gp_channel_handle_t | handle, |
| const uint8_t * | bytes, | ||
| size_t | size ) |
Sends a frame over the A<->B peer channel.
Definition at line 1221 of file ab_gp_channel.c.
| ab_gp_saf_train_t * ab_gp_channel_saf_train | ( | ab_gp_channel_handle_t | handle | ) |
This channel's train-link SaF termination (ab_gp_saf_train.h), or NULL for a NULL handle.
Definition at line 1233 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_saf_train_setup | ( | ab_gp_channel_handle_t | handle | ) |
Reads RTE_SAFECOMM_TRAIN_RBC_ID and sets up the train-link SaF termination: unset leaves it off (plain ERTMS frames, the behaviour before it existed); set to this RBC's ETCS identity (1..0xFFFFFF, decimal or 0x hex) turns it on.
Definition at line 1240 of file ab_gp_channel.c.
| void ab_gp_channel_raise_ctc_alarm | ( | ab_gp_channel_handle_t | handle, |
| rbc_alarm_severity_t | severity, | ||
| uint32_t | code, | ||
| const char * | log_message ) |
Raises a severity-leveled operational alarm: logs it locally (rte_log_write_event(), same structured Site/Cycle/Source/ Destination/Type/Info convention as every other event this codebase logs) AND forwards it to CTC (RBC_MSG_CTC_ALARM, see that kind's own doc in rbc_wire_types.h), so a human dispatcher sees it too, not just this process's own log.
Sends immediately (bypasses the ADR-034 checkpoint-gated stage queue, ab_gp_channel_stage.h) - callers reacting to an already-decided fault (about to shut down/reboot) must call this BEFORE ab_gp_channel_shutdown() closes the CTC relay socket, or the alarm never leaves the process. Best-effort: a failed send is logged locally (via rte_log_write_event() above) but does not fail the caller's own fault-reaction sequence - see this function's own .c comment for why blocking a reboot on a diagnostic send would be exactly backwards.
| handle | A valid, already-open channel handle. |
| severity | Alarm severity. |
| code | Caller-defined numeric reason/fault code (e.g. a rte_safestate_reason_t or RTE_EXAMPLE_REASON_* value) - carried on the wire as-is. |
| log_message | Human-readable text for the LOCAL log line only (not carried on the wire - see rbc_wire_types.h's own doc on why RBC_MSG_CTC_ALARM stays coded, not free-text, matching every other kind in this enum). May be NULL. |
Definition at line 1290 of file ab_gp_channel.c.
| rte_status_t ab_gp_channel_shutdown | ( | void * | context | ) |
rte_appmanager_operations_t::shutdown hook.
Definition at line 1343 of file ab_gp_channel.c.
|
static |
Definition at line 41 of file ab_gp_channel.c.