|
RTE RBC 2oo2 Reference Application 0.1.0 build 0006685
SIL 4 2oo2 Dual-Site Fault-Tolerant ERTMS Radio Block Centre Reference Architecture
|
This channel's own West<->East inter-site negotiation link - see ab_gp_channel.c's file header for how this fits into the overall 6-container topology. Ported from the old standalone SITE role (SITE/site.c, now deleted): the same real rte_dual_channel_t + rte_dual_negotiator_t (ADR-020) startup tie-break and live promotion/demotion/deadlock rules, now driven once per A/B cycle (ab_gp_channel_read_channels()) instead of a standalone heartbeat timer, and mutating ctx->is_online/ctx->own_faulted directly instead of a shared NVM role region - see common_config.h's own doc on why no filesystem sharing is assumed between containers. More...
#include "ab_gp_channel_types.h"Go to the source code of this file.
Functions | |
| rte_status_t | ab_gp_channel_negotiate_init (ab_gp_channel_context_t *ctx) |
| Opens this channel's own inter-site negotiation link (WEST LISTENs, EAST CONNECTs), initializes the dual_channel/negotiator, and runs the startup tie-break until it settles - ported from SITE/site.c's own site_init(). Called once from ab_gp_channel_negotiate_setup() (AB/GP/com/ab_gp_channel.c), after the peer link is already up (the C relay links open later, in ab_gp_channel_relay_tasks_setup()). | |
| void | ab_gp_channel_negotiate_execute (ab_gp_channel_context_t *ctx, uint32_t cycle) |
| Runs one cycle's worth of inter-site negotiation: drives the negotiator's own STATE-frame exchange (diagnostic only), sends this channel's current {faulted, single_mode, state-transfer snapshot} extra payload to its counterpart and receives theirs, then applies the promotion/demotion/both-faulted-deadlock rules - ported from SITE/site.c's own site_execute() body, minus the heartbeat-tick wait (this now runs on ab_gp_channel.c's own AB cycle tick instead of a separate timer). | |
| void | ab_gp_channel_negotiate_flush_faulted (ab_gp_channel_context_t *ctx) |
| Best-effort, synchronous final send of this channel's own {faulted=true, single_mode} extra payload to its inter-site counterpart, BEFORE the negotiation link is torn down. Call this immediately after setting ctx->own_faulted = true and BEFORE ab_gp_channel_shutdown() (which closes the link) - see ab_gp_channel_crosscompare.c's react_to_fault(). | |
| void | ab_gp_channel_negotiate_shutdown (ab_gp_channel_context_t *ctx) |
| void | ab_gp_channel_negotiate_service_link (ab_gp_channel_context_t *ctx) |
| Fast internal-cycle service of the negotiation link (warm/hot standby only). | |
| void | ab_gp_channel_negotiate_sync_standby (ab_gp_channel_context_t *ctx, uint32_t cycle) |
| ONLINE only: send this cycle's post-compute snapshot to STANDBY and wait (bounded by the link's ack timeout) for its acknowledgement. Called from post_execute, i.e. before the staged outputs are committed at the checkpoint stage. | |
| void | ab_gp_channel_negotiate_on_takeover_confirm (ab_gp_channel_context_t *ctx, const char *payload) |
| Records a dispatcher confirmation that the other site is not ONLINE (from Gateway, RBC_UTIL_TOPIC_TAKEOVER_CONFIRM). It only enables a promotion while this channel is STANDBY and its counterpart is unresponsive; it is ignored (and dropped) otherwise, and expires after RTE_SITE_ROLE_TAKEOVER_CONFIRM_VALID_CYCLES cycles. A payload token=<hex> is checked as an authenticated token (ADR-040 step 4b, ab_gp_takeover_key.h); any other payload takes the unauthenticated path, refused when RTE_TAKEOVER_KEY_FILE is set. | |
| void | ab_gp_channel_negotiate_on_startup_ts_frame (ab_gp_channel_context_t *ctx, const uint8_t *payload, size_t size) |
| Handles a PEER_MSG_KIND_STARTUP_TS frame that arrives after ab_gp_channel_negotiate_init() returned (the A/B sibling restarted and asks for the site's startup timestamp - ADR-040 step 5a, ab_gp_startup_timestamp.h). The sibling's value is cached in ctx->sibling_startup_timestamp_ms; a request is answered with a reply carrying ctx->startup_timestamp_ms (not answered while that is 0: the clock was unavailable at start and rte_site_role took its own clock), a reply is cached only. The cached value is not used by this channel: the agreed timestamp of a running channel never changes (rte_site_role resumes it across reconnects). A malformed payload is dropped. Called from pre_execute.c's on_peer_frame_received() and ab_gp_channel_checkpoint.c's poll_for_checkpoint_frame(). | |
This channel's own West<->East inter-site negotiation link - see ab_gp_channel.c's file header for how this fits into the overall 6-container topology. Ported from the old standalone SITE role (SITE/site.c, now deleted): the same real rte_dual_channel_t + rte_dual_negotiator_t (ADR-020) startup tie-break and live promotion/demotion/deadlock rules, now driven once per A/B cycle (ab_gp_channel_read_channels()) instead of a standalone heartbeat timer, and mutating ctx->is_online/ctx->own_faulted directly instead of a shared NVM role region - see common_config.h's own doc on why no filesystem sharing is assumed between containers.
A-WEST<->A-EAST and B-WEST<->B-EAST are two SEPARATE links (one owned by each channel's own ctx->neg_* fields), so site-level negotiation is never a single point of failure the way the old standalone SITE process was - see ab_gp_channel_crosscompare.c for the added consistency check between A's and B's own independently-negotiated outcomes.
Definition in file ab_gp_channel_negotiate.h.
| rte_status_t ab_gp_channel_negotiate_init | ( | ab_gp_channel_context_t * | ctx | ) |
Opens this channel's own inter-site negotiation link (WEST LISTENs, EAST CONNECTs), initializes the dual_channel/negotiator, and runs the startup tie-break until it settles - ported from SITE/site.c's own site_init(). Called once from ab_gp_channel_negotiate_setup() (AB/GP/com/ab_gp_channel.c), after the peer link is already up (the C relay links open later, in ab_gp_channel_relay_tasks_setup()).
| ctx | Context to initialize ctx->neg_* fields into (including ctx->is_online, the startup outcome). Must not be NULL. |
Definition at line 554 of file ab_gp_channel_negotiate.c.
| void ab_gp_channel_negotiate_execute | ( | ab_gp_channel_context_t * | ctx, |
| uint32_t | cycle ) |
Runs one cycle's worth of inter-site negotiation: drives the negotiator's own STATE-frame exchange (diagnostic only), sends this channel's current {faulted, single_mode, state-transfer snapshot} extra payload to its counterpart and receives theirs, then applies the promotion/demotion/both-faulted-deadlock rules - ported from SITE/site.c's own site_execute() body, minus the heartbeat-tick wait (this now runs on ab_gp_channel.c's own AB cycle tick instead of a separate timer).
| ctx | Initialized context. Must not be NULL. |
| cycle | This AB cycle's number, for logging only. |
Definition at line 625 of file ab_gp_channel_negotiate.c.
| void ab_gp_channel_negotiate_flush_faulted | ( | ab_gp_channel_context_t * | ctx | ) |
Best-effort, synchronous final send of this channel's own {faulted=true, single_mode} extra payload to its inter-site counterpart, BEFORE the negotiation link is torn down. Call this immediately after setting ctx->own_faulted = true and BEFORE ab_gp_channel_shutdown() (which closes the link) - see ab_gp_channel_crosscompare.c's react_to_fault().
Without this, a faulting channel's own promotion signal (ctx->own_faulted) would never reach its counterpart at all: the normal per-cycle negotiate step (ab_gp_channel_negotiate_execute()) never gets another chance to run once RTE_SAFESTATE_LEVEL_REBOOT diverts control away for good - unlike the old standalone SITE role (a separate, non-rebooting process that read this site's NVM role fresh every heartbeat regardless of A/B's own lifecycle), this channel's own negotiation link now shares A/B's lifecycle, so the fault has to be flushed out explicitly, once, right here, or the counterpart's promotion rule never fires. Failure is logged only - there is nothing further to retry from a process that is about to reboot anyway.
| ctx | Initialized context, with ctx->own_faulted already true. Must not be NULL. |
Definition at line 673 of file ab_gp_channel_negotiate.c.
| void ab_gp_channel_negotiate_shutdown | ( | ab_gp_channel_context_t * | ctx | ) |
Idempotent: closes the negotiation link/watchdog. Called from ab_gp_channel_shutdown().
Definition at line 678 of file ab_gp_channel_negotiate.c.
| void ab_gp_channel_negotiate_service_link | ( | ab_gp_channel_context_t * | ctx | ) |
Fast internal-cycle service of the negotiation link (warm/hot standby only).
Called every ~10 ms from the wait for the next RBC cycle tick (ab_gp_channel_wait_cycle_tick()), so the peer's frames are received and acknowledged promptly instead of once per RBC cycle. Runs in every standby mode and on both roles; does nothing while the link is down.
Definition at line 637 of file ab_gp_channel_negotiate.c.
| void ab_gp_channel_negotiate_sync_standby | ( | ab_gp_channel_context_t * | ctx, |
| uint32_t | cycle ) |
ONLINE only: send this cycle's post-compute snapshot to STANDBY and wait (bounded by the link's ack timeout) for its acknowledgement. Called from post_execute, i.e. before the staged outputs are committed at the checkpoint stage.
A missing acknowledgement marks STANDBY as not working; ONLINE then stops waiting and retries only every RTE_SITE_ROLE_STANDBY_SYNC_RETRY_CYCLES cycles. Never withholds output. Does nothing in cold mode.
Definition at line 645 of file ab_gp_channel_negotiate.c.
| void ab_gp_channel_negotiate_on_takeover_confirm | ( | ab_gp_channel_context_t * | ctx, |
| const char * | payload ) |
Records a dispatcher confirmation that the other site is not ONLINE (from Gateway, RBC_UTIL_TOPIC_TAKEOVER_CONFIRM). It only enables a promotion while this channel is STANDBY and its counterpart is unresponsive; it is ignored (and dropped) otherwise, and expires after RTE_SITE_ROLE_TAKEOVER_CONFIRM_VALID_CYCLES cycles. A payload token=<hex> is checked as an authenticated token (ADR-040 step 4b, ab_gp_takeover_key.h); any other payload takes the unauthenticated path, refused when RTE_TAKEOVER_KEY_FILE is set.
Definition at line 653 of file ab_gp_channel_negotiate.c.
| void ab_gp_channel_negotiate_on_startup_ts_frame | ( | ab_gp_channel_context_t * | ctx, |
| const uint8_t * | payload, | ||
| size_t | size ) |
Handles a PEER_MSG_KIND_STARTUP_TS frame that arrives after ab_gp_channel_negotiate_init() returned (the A/B sibling restarted and asks for the site's startup timestamp - ADR-040 step 5a, ab_gp_startup_timestamp.h). The sibling's value is cached in ctx->sibling_startup_timestamp_ms; a request is answered with a reply carrying ctx->startup_timestamp_ms (not answered while that is 0: the clock was unavailable at start and rte_site_role took its own clock), a reply is cached only. The cached value is not used by this channel: the agreed timestamp of a running channel never changes (rte_site_role resumes it across reconnects). A malformed payload is dropped. Called from pre_execute.c's on_peer_frame_received() and ab_gp_channel_checkpoint.c's poll_for_checkpoint_frame().
| ctx | Initialized context; NULL is ignored. |
| payload | The frame's payload (the byte after the kind). |
| size | Number of payload bytes available. |
Definition at line 532 of file ab_gp_channel_negotiate.c.