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_types.h
Go to the documentation of this file.
1#ifndef RTE_EXAMPLE_AB_GP_CHANNEL_TYPES_H
2#define RTE_EXAMPLE_AB_GP_CHANNEL_TYPES_H
3
10
11#include <stdbool.h>
12#include <stdint.h>
13
14#include "rte/app/appmanager/rte_appmanager.h"
15#include "rte/redundancy/channel_service/rte_channel_service.h"
16#include "rte/redundancy/channel_link/rte_channel.h"
17#include "rte/redundancy/checksum/rte_checksum.h"
18#include "rte/redundancy/cross_comparator/rte_cross_comparator.h"
19#include "rte/redundancy/config/rte_redundancy_config.h"
20#include "rte/redundancy/dual/rte_dual_channel.h"
21#include "rte/redundancy/dual/rte_dual_negotiator.h"
22#include "rte/redundancy/site_role/rte_site_role.h"
23#include "rte/oal/memory/rte_mem_util.h"
24#include "rte/oal/netlink/rte_netlink.h"
25#include "rte/utils/status/rte_status.h"
26#include "rte/oal/timer/rte_timer.h"
27#include "rte/utils/types/rte_types.h"
28#include "rte/redundancy/voter/rte_voter.h"
29#include "rte/redundancy/watchdog/rte_watchdog.h"
30
33#include "ab_gp_config.h"
34#include "../db/ab_gp_db.h"
36#include "ab_gp_saf_train.h"
38#include "ab_gp_cycle_ticks.h"
39#include "ab_gp_sibling_state.h"
40
41#define AB_SAMPLE_WIRE_SIZE \
42 (4U + ((uint32_t)RTE_EXAMPLE_MAX_TRAINS * RTE_EXAMPLE_TRAIN_SESSION_WIRE_SIZE) + 8U)
43
44#define PEER_MSG_KIND_AB_SAMPLE 1U
45#define PEER_MSG_KIND_CHECKPOINT_REQUEST 2U
46#define PEER_MSG_KIND_CHECKPOINT_REPLY 3U
47#define PEER_MSG_KIND_SITE_STATE 4U
52#define PEER_MSG_KIND_KM114_DIGEST 5U
56#define PEER_MSG_KIND_SAF_RB 6U
64#define PEER_MSG_KIND_STARTUP_TS 7U
65
66#define PEER_LINK_PAYLOAD_SIZE \
67 ((AB_SAMPLE_WIRE_SIZE > sizeof(rte_vital_message_t)) ? AB_SAMPLE_WIRE_SIZE : sizeof(rte_vital_message_t))
68
69#define PEER_WIRE_FRAME_SIZE (1U + PEER_LINK_PAYLOAD_SIZE)
70
72#define AB_GP_DEFERRED_PEER_FRAMES 4U
73
87#define AB_GP_STAGED_SEND_BYTES_SIZE \
88 ((PEER_WIRE_FRAME_SIZE > (uint32_t)RBC_TRAIN_ENVELOPE_WIRE_SIZE) ? PEER_WIRE_FRAME_SIZE \
89 : (uint32_t)RBC_TRAIN_ENVELOPE_WIRE_SIZE)
90
112#define AB_GP_MAX_STAGED_SENDS_PER_CYCLE 16U
113
120
129
133typedef struct ab_gp_com_s
134{
135 rte_channel_service_t peer_channel;
136 rte_channel_service_t crosscompare_channel;
137 /* ADR-036: ONE relay link per {kind} (was per {kind, instance}) -
138 * every train's Train/IL traffic multiplexes onto the one link and
139 * A/B route by the envelope's own train_id. */
141 /* ISS-020: limits the cycle thread's open attempts of relay_channel[RTE_EXAMPLE_RELAY_KIND_UTIL] while the
142 * status service is unreachable (ab_gp_util_link_gate.h). Zeroed with the context in ab_gp_channel_open_link(). */
145
148typedef void (*ab_gp_com_envelope_cb)(void *user_ctx, rte_example_relay_kind_t kind, uint8_t index, const uint8_t *bytes);
149typedef void (*ab_gp_com_peer_frame_cb)(void *user_ctx, uint8_t kind, const uint8_t *payload, size_t size);
150
154typedef struct ab_gp_channel_context_s
155{
158 char role_tag_buf[16];
159 const char *role_tag;
160 /* RCA/OCORA Phase 8 (see docs/rca/ at the workspace root and TODO.md's
161 * "RCA/OCORA compatibility" section): the resolved app-level
162 * redundancy topology config, loaded once at startup
163 * (ab_gp_channel_open_link()) from etc/config/redundancy.json (or
164 * RTE_REDUNDANCY_CONFIG_FILE). GP validates this against what it can
165 * actually run today (2oo2/2oo2_redundant, replica_count==2 only -
166 * ab_gp_channel_open_link() fails fast, not silently, on anything
167 * else) and logs it for visibility - not yet wired to actually change
168 * how many peer channels are opened or which comparator runs (still
169 * always exactly one ab-peer link + rte_cross_comparator) - that
170 * remains real, not-yet-started follow-up work, see TODO.md. */
171 rte_redundancy_config_t redundancy;
172 /* rte_channel_config_t::name for ctx->checkpoint_vc (e.g.
173 * "ChannelAtoB"/"ChannelBtoA") - a caller-owned pointer per that
174 * field's own doc, so it needs storage that outlives the channel;
175 * this buffer, embedded in ctx, does. Filled once by
176 * ab_gp_channel_checkpoint_setup(). */
178
179 /* Transport subsystem */
182
184
187
188 rte_timestamp_ms_t checkpoint_relaxed_until_ms;
189
190 /* Inter-site site role (ADR-040): the link, negotiation, partner supervision, takeover and standby sync are
191 * Platform_RTE's rte_site_role service; this channel is its Site Role Client (ab_gp_channel_negotiate.c).
192 * is_online mirrors rte_site_role_is_online() (set at start and on every reported change); own_faulted and
193 * single_mode are this channel's local facts, handed to the service each cycle. */
194 rte_timestamp_ms_t startup_timestamp_ms;
195 rte_timestamp_ms_t sibling_startup_timestamp_ms;
197 rte_site_role_t site_role;
201
204
207
210 struct
211 {
214 } neg_peer_extra;
215
216
219
220 /* --- Built-in AppManager checkpoint rendezvous, jitter-tolerant path
221 * (ab_gp_channel_checkpoint.c; RTE_EXAMPLE_AB_CHECKPOINT_LOOKBACK_CYCLES;
222 * docs/TIMING_AND_DATA_LOSS_ANALYSIS.md finding 10) ---
223 *
224 * The most recent CHECKPOINT_REPLY (this side's own arrival echoed
225 * back by the peer) and CHECKPOINT_REQUEST (the peer's own arrival)
226 * that the per-cycle peer pump (pre_execute's on_peer_frame_received)
227 * drained while ab_gp_channel_checkpoint_backend_recv() was NOT
228 * blocked. Retained (a REPLY here used to be dropped) so backend_recv
229 * can offer them as confirmation candidates: the REPLY carries this
230 * side's id and confirms any idle cycle (constant folded signature);
231 * the REQUEST carries the peer's id and confirms an active cycle when
232 * both channels took the same path. A stale id is still rejected by
233 * rte_checkpoint.c's reply_confirms_checkpoint(). */
235 uint8_t cached_checkpoint_reply[sizeof(rte_vital_message_t)];
237 uint8_t cached_checkpoint_request[sizeof(rte_vital_message_t)];
238
239 /* Cycle number (ctx->cyc_cycle) of the most recent CHECKPOINT_REQUEST
240 * or CHECKPOINT_REPLY seen from the peer, by either the pump or
241 * backend_recv's own poll. 0 = none seen yet. backend_recv treats
242 * "peer exchanged a checkpoint frame within the last
243 * RTE_EXAMPLE_AB_CHECKPOINT_LOOKBACK_CYCLES cycles" as this cycle's
244 * confirmation when a fresh round trip did not land in-window - see
245 * that constant's own doc. */
247
248 /* The exact rte_vital_message_t bytes backend_send() was last asked
249 * to send (this cycle's own arrival, built by rte_channel_checkpoint()
250 * for this cycle's checkpoint_id). backend_recv() returns these
251 * verbatim to satisfy the lookback path - they verify against the
252 * current checkpoint_id by construction. */
254 uint8_t last_sent_checkpoint_arrival[sizeof(rte_vital_message_t)];
255
256 rte_watchdog_t watchdog;
260
261 rte_timer_storage_t cycle_timer_storage;
262 rte_timer_handle_t cycle_timer_handle;
264 rte_timestamp_ms_t last_cycle_wall_ms;
265
266 /* Train and Route database subsystems */
269
270 /* Checkpoint subsystem */
272 rte_channel_t checkpoint_vc;
273 rte_voter_t checkpoint_voter;
274 rte_appmanager_checkpoint_config_t checkpoint_cfg;
275
276 /* Cross-compare subsystem - RCA/OCORA Phase 2b: no rte_channel_t
277 * "sources" needed any more, rte_cross_comparator_execute_buffers()
278 * takes local/peer bytes directly (see ab_gp_channel_crosscompare.c). */
279 rte_cross_comparator_t xcompare_cmp;
282
283 uint32_t cycle;
284
285 /* Per-cycle orchestration scratch */
286 uint32_t cyc_cycle;
293
296
297 /* Train-link SaF termination (ab_gp_saf_train.h); disabled unless RTE_SAFECOMM_TRAIN_RBC_ID is set. */
299
300 /* Peer-link control frames (PEER_MSG_KIND_SAF_RB, PEER_MSG_KIND_KM114_DIGEST) that the checkpoint rendezvous read
301 * off the shared peer link while waiting for its own frame; pre_execute replays them through the normal peer
302 * handler next cycle instead of losing them. */
305
306 /* Stage-then-commit output queue (ADR-034) - see ab_gp_channel_stage.h */
310
311void ab_gp_channel_sleep_ms(unsigned int ms);
312rte_status_t ab_gp_channel_shutdown(void *context);
313
314#endif /* RTE_EXAMPLE_AB_GP_CHANNEL_TYPES_H */
rte_status_t ab_gp_channel_shutdown(void *context)
rte_appmanager_operations_t::shutdown hook.
#define PEER_WIRE_FRAME_SIZE
#define AB_GP_STAGED_SEND_BYTES_SIZE
The staged-send queue's own per-entry buffer width - must fit the WIDEST frame ANY caller ever stages...
#define AB_GP_MAX_STAGED_SENDS_PER_CYCLE
Stage-then-commit output queue (ADR-034) - see ab_gp_channel_stage.h.
ab_gp_stage_dest_kind_t
@ AB_GP_STAGE_DEST_RELAY
@ AB_GP_STAGE_DEST_CROSSCOMPARE
@ AB_GP_STAGE_DEST_PEER
#define AB_GP_DEFERRED_PEER_FRAMES
Capacity of ab_gp_channel_context_t::deferred_peer_frames.
void(*) ab_gp_com_peer_frame_cb(void *user_ctx, uint8_t kind, const uint8_t *payload, size_t size)
void ab_gp_channel_sleep_ms(unsigned int ms)
void(*) ab_gp_com_envelope_cb(void *user_ctx, rte_example_relay_kind_t kind, uint8_t index, const uint8_t *bytes)
Zero-dependency, statically-allocated configuration parser for Role A/B.
A/B cycle tick count shared by the cycle timer callback and the cycle thread (ISS-051).
A/B's own simplified Train/Route database - fixed-size arrays describing the domain objects logic/ (p...
Train link safe communication (Subset-037 SaF) terminated inside A and B - REQ-SC-001,...
The A/B sibling's last site-state frame (PEER_MSG_KIND_SITE_STATE), kept raw and handed to Platform_R...
A/B's own train lifecycle handling against db/'s runtime table.
#define RTE_EXAMPLE_SITE_EXTRA_PAYLOAD_SIZE
#define RTE_EXAMPLE_MAX_TRAINS
The RBC Train/IL/CTC scenario's shared wire envelope (ADR-029) - one fixed-size struct/frame reused f...
West/East site identity and the per-site config derived from it (ports, container host lookup) - see ...
#define RTE_EXAMPLE_RELAY_KIND_COUNT
Definition site_config.h:50
rte_example_site_t
Definition site_config.h:20
rte_example_relay_kind_t
Which client type a C<->A/C<->B relay link/port belongs to - this project's own dedicated-channel-per...
Definition site_config.h:39
ab_gp_train_session_t sessions[RTE_EXAMPLE_MAX_TRAINS]
Central application context owned by composition root (main.c).
uint8_t deferred_peer_frames[AB_GP_DEFERRED_PEER_FRAMES][PEER_WIRE_FRAME_SIZE]
ab_gp_sibling_state_t peer_site_state
rte_appmanager_checkpoint_config_t checkpoint_cfg
uint8_t last_sent_checkpoint_arrival[sizeof(rte_vital_message_t)]
ab_gp_train_session_t sessions[RTE_EXAMPLE_MAX_TRAINS]
bool cyc_position_reply_due[RTE_EXAMPLE_MAX_TRAINS]
rte_timestamp_ms_t sibling_startup_timestamp_ms
ab_gp_cycle_ticks_t cycle_ticks
uint8_t adopt_pending[RTE_EXAMPLE_MAX_TRAINS]
uint32_t cyc_msg_type_due[RTE_EXAMPLE_MAX_TRAINS]
rte_timestamp_ms_t startup_timestamp_ms
uint8_t site_role_rx[RTE_EXAMPLE_SITE_EXTRA_PAYLOAD_SIZE]
rte_redundancy_config_t redundancy
rte_cross_comparator_t xcompare_cmp
ab_gp_train_session_t cyc_peer_sessions[RTE_EXAMPLE_MAX_TRAINS]
rte_timestamp_ms_t checkpoint_relaxed_until_ms
uint8_t cached_checkpoint_reply[sizeof(rte_vital_message_t)]
uint8_t xcompare_skip_count[RTE_EXAMPLE_MAX_TRAINS]
rte_timer_handle_t cycle_timer_handle
uint8_t cached_checkpoint_request[sizeof(rte_vital_message_t)]
rte_timestamp_ms_t last_cycle_wall_ms
uint8_t site_role_tx[RTE_EXAMPLE_SITE_EXTRA_PAYLOAD_SIZE]
ab_gp_staged_send_t staged_sends[AB_GP_MAX_STAGED_SENDS_PER_CYCLE]
rte_timer_storage_t cycle_timer_storage
Communication transport abstraction holding only network service channels.
ab_gp_util_link_gate_t util_gate
rte_channel_service_t relay_channel[RTE_EXAMPLE_RELAY_KIND_COUNT]
rte_channel_service_t peer_channel
rte_channel_service_t crosscompare_channel
Tick count and the mutex that guards it. Not volatile: every access to count holds the mutex.
One channel's train-link SaF termination.
ab_gp_stage_dest_kind_t dest_kind
uint8_t bytes[AB_GP_STAGED_SEND_BYTES_SIZE]
rte_example_relay_kind_t relay_kind