RTE RBC 2oo2 Reference Application 0.1.0 build 0006685
SIL 4 2oo2 Dual-Site Fault-Tolerant ERTMS Radio Block Centre Reference Architecture
Loading...
Searching...
No Matches
ab_gp_channel_negotiate.h File Reference

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 dependency graph for ab_gp_channel_negotiate.h:
This graph shows which files directly or indirectly include this file:

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().

Detailed Description

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.

Function Documentation

◆ ab_gp_channel_negotiate_init()

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()).

Parameters
ctxContext to initialize ctx->neg_* fields into (including ctx->is_online, the startup outcome). Must not be NULL.
Returns
RTE_STATUS_OK on success; the underlying link/dual_channel/ negotiator failure status otherwise, or RTE_STATUS_TIMEOUT if negotiation did not settle within RTE_EXAMPLE_CONNECT_TIMEOUT_MS.

Definition at line 554 of file ab_gp_channel_negotiate.c.

◆ ab_gp_channel_negotiate_execute()

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).

Parameters
ctxInitialized context. Must not be NULL.
cycleThis AB cycle's number, for logging only.

Definition at line 625 of file ab_gp_channel_negotiate.c.

◆ ab_gp_channel_negotiate_flush_faulted()

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.

Parameters
ctxInitialized context, with ctx->own_faulted already true. Must not be NULL.

Definition at line 673 of file ab_gp_channel_negotiate.c.

◆ ab_gp_channel_negotiate_shutdown()

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.

◆ ab_gp_channel_negotiate_service_link()

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.

◆ ab_gp_channel_negotiate_sync_standby()

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.

◆ ab_gp_channel_negotiate_on_takeover_confirm()

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.

◆ ab_gp_channel_negotiate_on_startup_ts_frame()

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().

Parameters
ctxInitialized context; NULL is ignored.
payloadThe frame's payload (the byte after the kind).
sizeNumber of payload bytes available.

Definition at line 532 of file ab_gp_channel_negotiate.c.