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_train.h
Go to the documentation of this file.
1
36#ifndef RTE_EXAMPLE_AB_GP_TRAIN_H
37#define RTE_EXAMPLE_AB_GP_TRAIN_H
38
39#include <stdbool.h>
40#include <stdint.h>
41
42#include "rte/utils/status/rte_status.h"
43
47#include "../db/ab_gp_db.h"
48
77#ifndef TRAIN_SESSION_T_DEFINED
78#define TRAIN_SESSION_T_DEFINED
79typedef struct train_session_s
80{
81 bool in_use;
82 uint8_t train_id;
83 uint32_t cycle;
84 uint32_t d_lrbg;
85 uint32_t granted_length;
86 uint32_t ma_seq;
90 bool ma_acked;
91
92 /* --- ADR-029: sticky (not per-cycle transient) "have I ever sent
93 * this one-time CTC indication yet" flags - local scratch only, NOT
94 * wire/cross-compare relevant, same posture as ma_pending_send above.
95 * Deliberately sticky rather than a cyc_*[] flag set only on the
96 * exact cycle the underlying event happened: should_forward_to_c
97 * (ab_gp_channel_forward_to_c_if_needed()) can legitimately be false on
98 * that exact cycle (e.g. no AGREE yet, right after a fresh connect) -
99 * a transient flag would silently lose the notification forever with
100 * no later cycle to retry it on (found live: a train's own
101 * CTC_CONNECTED notification never arrived because cross-compare
102 * had not AGREED yet on the cycle the connect itself was
103 * processed). Checked and set only at the moment of an actual send,
104 * so they naturally "catch up" whenever should_forward_to_c next
105 * becomes true, however many cycles later that is. */
140
141 /* last_ctc_train_info_(fields) / ctc_train_info_sent (the
142 * RBC_MSG_CTC_TRAIN_INFO on-change comparison snapshot) REMOVED
143 * (interface-simplification
144 * pass) - GA no longer polls this session every cycle and diffs it;
145 * ab_gp_register_train_context_notify() (this file's own "GA
146 * notification" section) pushes a full ab_gp_train_context_t
147 * snapshot exactly when something real changes instead. */
148 uint32_t v_train;
157 uint32_t m_mode;
160#endif
161
171#define RTE_EXAMPLE_TRAIN_SESSION_WIRE_SIZE 19U
172
191rte_status_t ab_gp_train_init(void);
192
200
218
221#ifndef AB_GP_TRAIN_UPDATE_TYPE_T_DEFINED
222#define AB_GP_TRAIN_UPDATE_TYPE_T_DEFINED
240#endif
241
248#ifndef AB_GP_TRAIN_CONTEXT_T_DEFINED
249#define AB_GP_TRAIN_CONTEXT_T_DEFINED
250typedef struct
251{
252 uint8_t train_id;
253 bool in_use;
254 uint32_t cycle;
255 uint32_t d_lrbg;
256 uint32_t nid_lrbg;
257 uint32_t v_train;
258 uint32_t m_mode;
259 uint32_t granted_length;
260 uint32_t ma_seq;
261 bool ma_acked;
262 bool has_ma;
270 bool ma_pending_send;
271 bool ctc_connected_sent;
272 bool ctc_ma_granted_sent;
273 bool ctc_ma_notify_pending;
274 uint16_t route_ids[RTE_EXAMPLE_MAX_ROUTES_PER_TRAIN];
275 uint8_t route_count;
277#endif
278
279#ifndef AB_GP_TRAIN_NOTIFY_FN_DEFINED
280#define AB_GP_TRAIN_NOTIFY_FN_DEFINED
281typedef void (*ab_gp_train_context_notify_fn)(const void *context, const ab_gp_train_context_t *ctx,
282 ab_gp_train_update_type_t update_type);
283#endif
284
286#define AB_GP_TRAIN_MAX_CONTEXT_SUBSCRIBERS 4U
287
292rte_status_t ab_gp_register_train_context_notify(ab_gp_train_context_notify_fn fn, const void *context);
293
307bool ab_gp_get_train_context(const ab_gp_train_session_t sessions[], const ab_gp_db_t *db, uint8_t train_id,
308 ab_gp_train_context_t *out_ctx);
309
325 uint8_t train_id, ab_gp_train_update_type_t update_type);
327
338bool ab_gp_train_add(ab_gp_db_t *db, uint8_t train_id, uint8_t nid_engine);
339
350bool ab_gp_train_remove(ab_gp_db_t *db, uint8_t train_id);
351
359ab_gp_db_train_t *ab_gp_train_find(ab_gp_db_t *db, uint8_t train_id);
360
368bool ab_gp_train_find_by_nid_engine(const ab_gp_db_t *db, uint8_t nid_engine, uint8_t *out_train_id);
369
372bool ab_gp_train_is_connected(const ab_gp_db_t *db, uint8_t train_id);
373
376bool ab_gp_train_get_nid_engine(const ab_gp_db_t *db, uint8_t train_id, uint8_t *out_nid_engine);
377
378/* ab_gp_train_get_has_ma() - REMOVED (dead: zero GP-internal callers,
379 * and GA's own former use is now ab_gp_get_train_context()'s
380 * ->has_ma field). */
381
385bool ab_gp_train_get_route_count(const ab_gp_db_t *db, uint8_t train_id, uint8_t *out_route_count);
386
390bool ab_gp_train_set_nid_engine(ab_gp_db_t *db, uint8_t train_id, uint8_t nid_engine);
391
394bool ab_gp_train_set_has_ma(ab_gp_db_t *db, uint8_t train_id, bool has_ma);
395
398bool ab_gp_train_get_last_position(const ab_gp_db_t *db, uint8_t train_id, uint32_t *out_nid_lrbg);
399
405bool ab_gp_train_set_last_position(ab_gp_db_t *db, uint8_t train_id, uint32_t nid_lrbg);
406
419
426bool ab_gp_train_handle_connect(ab_gp_db_t *db, uint8_t train_id);
427
436bool ab_gp_train_handle_position_report(ab_gp_db_t *db, uint8_t train_id, uint32_t nid_lrbg);
438
462
470void ab_gp_train_build_position_answer(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t train_id, uint32_t cycle,
471 uint32_t d_lrbg, uint32_t msg_type);
472
477void ab_gp_train_build_movement_authority(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t train_id, uint32_t ma_seq,
478 uint32_t ma_length);
479
486typedef struct
487{
488 uint8_t index;
490 char tag[8];
492
495#define AB_GP_TRAIN_MAX_PENDING_OUTPUTS ((uint8_t)(RTE_EXAMPLE_MAX_TRAINS * 2U))
496
524uint8_t ab_gp_train_build_outputs(const ab_gp_train_session_t sessions[], const uint32_t cyc_msg_type_due[],
525 const bool cyc_position_reply_due[],
528
581 const uint8_t env_bytes[RBC_ENVELOPE_WIRE_SIZE], uint32_t cycle, bool is_role_a,
582 rte_example_site_t site, const char *role_tag, uint32_t cyc_msg_type_due[],
583 bool cyc_position_reply_due[]);
584
602
603/* ab_gp_train_session_get_in_use()/_get_d_lrbg()/_get_granted_length() -
604 * REMOVED (later session, on direct request - "it will be enough if GA
605 * can getTrainContext/getRouteContext; setters stay separate since they
606 * require validation"): every one of these individual reads is now a
607 * field on the ONE ab_gp_get_train_context() snapshot above. */
608
613bool ab_gp_train_session_add_granted_length(ab_gp_train_session_t sessions[], uint8_t train_id, uint32_t delta);
614
617bool ab_gp_train_session_set_granted_length(ab_gp_train_session_t sessions[], uint8_t train_id, uint32_t granted_length);
618
621bool ab_gp_train_session_get_ma_seq(const ab_gp_train_session_t sessions[], uint8_t train_id, uint32_t *out_ma_seq);
622
627bool ab_gp_train_session_increment_ma_seq(ab_gp_train_session_t sessions[], uint8_t train_id);
628
629/* ab_gp_train_session_get_ma_pending_send()/_get_ctc_connected_sent()/
630 * _get_ctc_ma_granted_sent()/_get_ctc_ma_notify_pending() - REMOVED, same
631 * reasoning as _get_in_use() etc. above: all four are now fields on
632 * ab_gp_get_train_context()'s own snapshot. The matching SETTERS below
633 * are unaffected - mutation still needs GP's own validation, per the
634 * same direct instruction this whole consolidation follows. */
635
638bool ab_gp_train_session_set_ma_pending_send(ab_gp_train_session_t sessions[], uint8_t train_id, bool pending);
639
642bool ab_gp_train_session_set_ma_acked(ab_gp_train_session_t sessions[], uint8_t train_id, bool acked);
643
646bool ab_gp_train_session_set_ctc_connected_sent(ab_gp_train_session_t sessions[], uint8_t train_id, bool sent);
647
650bool ab_gp_train_session_set_ctc_ma_granted_sent(ab_gp_train_session_t sessions[], uint8_t train_id, bool sent);
651
652/* ab_gp_train_session_{get,set}_ctc_train_info_sent / _last_ctc_train_info /
653 * _get_v_train_m_mode - REMOVED (interface-simplification pass), see
654 * ab_gp_train_session_t's own comment at their old field location. */
655
659bool ab_gp_train_session_set_ctc_ma_notify_pending(ab_gp_train_session_t sessions[], uint8_t train_id, bool pending);
661
662#endif /* RTE_EXAMPLE_AB_GP_TRAIN_H */
A/B's own simplified Train/Route database - fixed-size arrays describing the domain objects logic/ (p...
bool ab_gp_train_handle_connect(ab_gp_db_t *db, uint8_t train_id)
Handles an inbound P0 (connect handshake) - wraps ab_gp_train_add() with the same env->train_id-as-ni...
bool ab_gp_train_add(ab_gp_db_t *db, uint8_t train_id, uint8_t nid_engine)
Adds a train on connect: fills db->trains[train_id-1] with nid_engine, connected=true,...
bool ab_gp_train_remove(ab_gp_db_t *db, uint8_t train_id)
Removes a train on disconnect: resets db->trains[train_id-1] back to its all-zero/disconnected state.
bool ab_gp_train_set_last_position(ab_gp_db_t *db, uint8_t train_id, uint32_t nid_lrbg)
Records this train's own most recently reported NID_LRBG - the write side of the field logic/'s own c...
bool ab_gp_train_apply_envelope(ab_gp_train_session_t sessions[], ab_gp_db_t *db, const uint8_t env_bytes[RBC_ENVELOPE_WIRE_SIZE], uint32_t cycle, bool is_role_a, rte_example_site_t site, const char *role_tag, uint32_t cyc_msg_type_due[], bool cyc_position_reply_due[])
THE single entry point com/'s ab_gp_channel.c calls for every raw envelope popped off its dedicated T...
uint8_t ab_gp_train_build_outputs(const ab_gp_train_session_t sessions[], const uint32_t cyc_msg_type_due[], const bool cyc_position_reply_due[], ab_gp_train_pending_output_t out[AB_GP_TRAIN_MAX_PENDING_OUTPUTS])
Decides which trains need a Train-directed envelope THIS cycle and builds all of them - see this file...
bool ab_gp_train_set_nid_engine(ab_gp_db_t *db, uint8_t train_id, uint8_t nid_engine)
void ab_gp_train_build_movement_authority(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t train_id, uint32_t ma_seq, uint32_t ma_length)
Builds and wire-encodes the outbound M3 (Movement Authority) envelope for train_id (kind=RBC_MSG_M3) ...
ab_gp_db_train_t * ab_gp_train_find(ab_gp_db_t *db, uint8_t train_id)
Finds a connected train's own slot for direct field access.
bool ab_gp_train_find_by_nid_engine(const ab_gp_db_t *db, uint8_t nid_engine, uint8_t *out_train_id)
Reverse lookup: which train_id (if any) is nid_engine currently connected as.
bool ab_gp_train_is_connected(const ab_gp_db_t *db, uint8_t train_id)
void ab_gp_train_build_position_answer(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t train_id, uint32_t cycle, uint32_t d_lrbg, uint32_t msg_type)
Builds and wire-encodes the outbound M24/M15 Position Report answer for train_id (kind=RBC_MSG_M24_M1...
bool ab_gp_train_handle_position_report(ab_gp_db_t *db, uint8_t train_id, uint32_t nid_lrbg)
Handles an inbound M136 (Position Report) - adds the train first (ab_gp_train_handle_connect()) if th...
bool ab_gp_train_get_nid_engine(const ab_gp_db_t *db, uint8_t train_id, uint8_t *out_nid_engine)
bool ab_gp_train_get_route_count(const ab_gp_db_t *db, uint8_t train_id, uint8_t *out_route_count)
rte_status_t ab_gp_train_init(void)
Registers this module's own ab_gp_train_session_t codec as a payload collector with com/ (AB/GP/com/a...
uint32_t ab_gp_train_payload_collector_id(void)
bool ab_gp_train_session_get_ma_seq(const ab_gp_train_session_t sessions[], uint8_t train_id, uint32_t *out_ma_seq)
#define AB_GP_TRAIN_MAX_PENDING_OUTPUTS
#define RTE_EXAMPLE_MAX_ROUTES_PER_TRAIN
#define RBC_ENVELOPE_WIRE_SIZE
rte_status_t ab_gp_register_train_context_notify(ab_gp_train_context_notify_fn fn, const void *context)
Definition ab_gp_train.c:39
bool ab_gp_train_session_set_ctc_ma_granted_sent(ab_gp_train_session_t *sessions, uint8_t train_id, bool sent)
bool ab_gp_train_session_set_ctc_connected_sent(ab_gp_train_session_t *sessions, uint8_t train_id, bool sent)
bool ab_gp_train_session_set_ma_pending_send(ab_gp_train_session_t *sessions, uint8_t train_id, bool pending)
void ab_gp_train_notify_context_changed(const ab_gp_train_session_t *sessions, const ab_gp_db_t *db, uint8_t train_id, ab_gp_train_update_type_t update_type)
void(*) ab_gp_train_context_notify_fn(const void *context, const ab_gp_train_context_t *ctx, ab_gp_train_update_type_t update_type)
bool ab_gp_train_get_last_position(const ab_gp_db_t *db, uint8_t train_id, uint32_t *out_nid_lrbg)
bool ab_gp_train_session_set_ma_acked(ab_gp_train_session_t *sessions, uint8_t train_id, bool acked)
bool ab_gp_train_set_has_ma(ab_gp_db_t *db, uint8_t train_id, bool has_ma)
bool ab_gp_train_session_increment_ma_seq(ab_gp_train_session_t *sessions, uint8_t train_id)
bool ab_gp_train_session_add_granted_length(ab_gp_train_session_t *sessions, uint8_t train_id, uint32_t delta)
bool ab_gp_train_session_set_ctc_ma_notify_pending(ab_gp_train_session_t *sessions, uint8_t train_id, bool pending)
bool ab_gp_train_session_set_granted_length(ab_gp_train_session_t *sessions, uint8_t train_id, uint32_t granted_length)
ab_gp_train_update_type_t
@ AB_TRAIN_REGISTERED
@ AB_TRAIN_REMOVED
@ AB_TRAIN_POSITION
@ AB_TRAIN_EMERGENCY_REACTION_RAISED
@ AB_TRAIN_MA_CHANGED
bool ab_gp_get_train_context(const ab_gp_train_session_t *sessions, const ab_gp_db_t *db, uint8_t train_id, ab_gp_train_context_t *out_ctx)
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 ...
rte_example_site_t
Definition site_config.h:20
One train A/B's simplified database knows about.
Definition ab_gp_db.h:99
uint8_t bytes[RBC_ENVELOPE_WIRE_SIZE]
uint32_t position_reply_msg_type