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_ertms_engine.c
Go to the documentation of this file.
1
5
7#include "rte/oal/memory/rte_mem_util.h"
8
10
12{
13 uint8_t i;
14
15 (void)db;
16 for (i = 0U; i < (uint8_t)RTE_EXAMPLE_MAX_TRAINS; i++)
17 {
18 ab_gp_proc_session_init(&s_train_contexts[i], (uint8_t)(i + 1U), 0U);
22 }
23}
24
25/* REQ-RBC-005: the only index into s_train_contexts[] by train_id; an out-of-range value returns NULL and never
26 * indexes. The wire-supplied train_id reaching it was already range-checked, and an out-of-range one logged and
27 * dropped, upstream (ab_gp_proc_dispatch_train_inbound(), ab_gp_train_apply_envelope()). */
29{
30 if (train_id < 1U || train_id > (uint8_t)RTE_EXAMPLE_MAX_TRAINS)
31 {
32 return NULL;
33 }
34 return &s_train_contexts[train_id - 1U];
35}
36
37void ab_gp_ertms_engine_step(ab_gp_db_t *db, uint32_t cycle, uint32_t timestamp_ms, uint32_t elapsed_ms)
38{
39 uint8_t i;
41
42 (void)cycle;
43 (void)timestamp_ms;
44
45 for (i = 0U; i < (uint8_t)RTE_EXAMPLE_MAX_TRAINS; i++)
46 {
47 ctx = &s_train_contexts[i];
48
49 if (db != NULL)
50 {
51 bool db_connected = ab_gp_db_train_is_connected(db, (uint8_t)(i + 1U));
52 /* Deliberately does NOT auto-drive session_state to INITIATED
53 * off db_connected alone (that was this function's own prior
54 * behaviour, removed once ab_gp_proc_dispatch.c started
55 * reacting to a REAL inbound Msg 155 instead) - db_connected
56 * only means the transport slot exists (P0/TRAIN_CONNECT,
57 * transport-layer), which is deliberately independent of and
58 * underneath the real Subset-026 application session this
59 * state machine tracks; auto-driving here would report
60 * INITIATED before the train ever actually sends Msg 155.
61 * Termination stays symmetric with the OLD transport-level
62 * disconnect, though - a dropped slot must still tear down
63 * whatever session state was riding on it, real Msg 156 or
64 * not. */
65 if (!db_connected && ctx->session_state != AB_GP_ERTMS_SESSION_IDLE)
66 {
68 }
69 }
70
72 {
73 /* Check contact supervision timer (T_NVCONTACT) - real bug fixed
74 * here: this used to pass a literal 0U for timeout_limit_ms,
75 * which check_timeout()'s own "0 = supervision off" guard
76 * silently accepted forever, so the timer accumulated
77 * (contact_timer_ms += elapsed_ms) but never once compared
78 * against anything - see RTE_EXAMPLE_ERTMS_CONTACT_TIMEOUT_MS's
79 * own doc (common_config.h) for the found-live account and why
80 * this default is a placeholder pending real per-train National
81 * Values storage. */
83 }
84 }
85}
86
87bool ab_gp_ertms_calc_ma_for_route(uint8_t train_id, uint16_t route_id, uint32_t ma_seq)
88{
90 const ab_site_ga_route_layout_t *layout;
91
92 if (ctx == NULL)
93 {
94 return false;
95 }
96
97 layout = ab_site_ga_get_route(route_id);
98 if (layout == NULL)
99 {
100 return false;
101 }
102
103 return ab_gp_proc_ma_compute(ctx, layout, ma_seq);
104}
105
106bool ab_gp_ertms_extend_ma_for_route(uint8_t train_id, uint16_t route_id)
107{
109 const ab_site_ga_route_layout_t *layout;
110
111 if (ctx == NULL)
112 {
113 return false;
114 }
115
116 layout = ab_site_ga_get_route(route_id);
117 if (layout == NULL)
118 {
119 return false;
120 }
121
122 return ab_gp_proc_ma_extend(ctx, layout);
123}
124
126 uint32_t l_train_m,
127 uint32_t v_maxtrain_kmh,
128 uint8_t m_axleload,
129 uint8_t m_loadinggauge,
130 bool m_airtight,
131 uint32_t timestamp_ms)
132{
134 if (ctx == NULL)
135 {
136 return false;
137 }
138
139 return ab_gp_proc_train_data_validate(ctx, l_train_m, v_maxtrain_kmh, m_axleload, m_loadinggauge, m_airtight, timestamp_ms);
140}
141
143 uint32_t nid_lrbg,
144 uint32_t d_lrbg_m,
145 rbc_q_dirlrbg_t q_dirlrbg,
146 uint32_t v_train_kmh,
147 uint32_t m_mode,
148 uint32_t m_level,
149 uint32_t cycle,
150 uint32_t timestamp_ms)
151{
153 if (ctx == NULL)
154 {
155 return false;
156 }
157
158 return ab_gp_proc_position_update(ctx, nid_lrbg, d_lrbg_m, q_dirlrbg, v_train_kmh, m_mode, m_level, cycle, timestamp_ms);
159}
160
162 bool is_conditional,
163 uint8_t nid_em,
164 uint32_t d_ref_m,
165 uint32_t d_es_m)
166{
168 if (ctx == NULL)
169 {
170 return false;
171 }
172
173 if (is_conditional)
174 {
175 return ab_gp_proc_emergency_stop_issue_ces(ctx, nid_em, d_ref_m, d_es_m);
176 }
177 else
178 {
179 return ab_gp_proc_emergency_stop_issue_ues(ctx, nid_em);
180 }
181}
182
183bool ab_gp_ertms_revoke_emergency_stop(uint8_t train_id, uint8_t nid_em)
184{
186 if (ctx == NULL)
187 {
188 return false;
189 }
190
191 return ab_gp_proc_emergency_stop_revoke(ctx, nid_em);
192}
193
194bool ab_gp_ertms_request_shunting(uint8_t train_id)
195{
197 if (ctx == NULL)
198 {
199 return false;
200 }
201
202 return ab_gp_proc_shunting_request(ctx);
203}
204
205bool ab_gp_ertms_authorize_shunting(uint8_t train_id, bool authorized)
206{
208 if (ctx == NULL)
209 {
210 return false;
211 }
212
213 return ab_gp_proc_shunting_authorize(ctx, authorized);
214}
215
216bool ab_gp_ertms_terminate_mission(uint8_t train_id, ab_gp_db_t *db)
217{
219 if (ctx == NULL)
220 {
221 return false;
222 }
223
224 return ab_gp_proc_eom_handle(ctx, db);
225}
226
227bool ab_gp_ertms_add_tsr(uint8_t train_id,
228 uint8_t nid_tsr,
229 uint32_t v_tsr_kmh,
230 uint32_t d_start_m,
231 uint32_t d_end_m)
232{
234 if (ctx == NULL)
235 {
236 return false;
237 }
238
239 return ab_gp_proc_tsr_add(ctx, nid_tsr, v_tsr_kmh, d_start_m, d_end_m);
240}
241
242bool ab_gp_ertms_remove_tsr(uint8_t train_id, uint8_t nid_tsr)
243{
245 if (ctx == NULL)
246 {
247 return false;
248 }
249
250 return ab_gp_proc_tsr_remove(ctx, nid_tsr);
251}
252
253bool ab_gp_ertms_send_text_message(uint8_t train_id,
254 uint8_t nid_textmessage,
255 uint8_t q_textclass,
256 uint8_t q_textconfirm,
257 uint32_t duration_s,
258 const char *text,
260{
262 if (ctx == NULL)
263 {
264 return false;
265 }
266
267 return ab_gp_proc_text_message_send(ctx, nid_textmessage, q_textclass, q_textconfirm, duration_s, text, out_p72);
268}
269
270bool ab_gp_ertms_handle_text_ack(uint8_t train_id,
271 uint8_t nid_textmessage,
272 uint32_t timestamp_ms)
273{
275 if (ctx == NULL)
276 {
277 return false;
278 }
279
280 return ab_gp_proc_text_message_handle_ack(ctx, nid_textmessage, timestamp_ms);
281}
282
283bool ab_gp_ertms_announce_handover(uint8_t train_id,
284 uint16_t target_nid_c,
285 uint16_t target_nid_rbc,
286 uint64_t target_nid_radio,
287 uint32_t d_rbctr_m)
288{
290 if (ctx == NULL)
291 {
292 return false;
293 }
294
295 return ab_gp_proc_handover_announce(ctx, target_nid_c, target_nid_rbc, target_nid_radio, d_rbctr_m);
296}
297
298bool ab_gp_ertms_complete_handover(uint8_t train_id)
299{
301 if (ctx == NULL)
302 {
303 return false;
304 }
305
307}
308
bool ab_gp_db_train_is_connected(const ab_gp_db_t *db, uint8_t train_id)
Checks if a train has an active connection session in the DB.
Definition ab_gp_db.c:435
bool ab_gp_ertms_remove_tsr(uint8_t train_id, uint8_t nid_tsr)
Removes an active Temporary Speed Restriction (Packet 66) for a train path.
bool ab_gp_ertms_add_tsr(uint8_t train_id, uint8_t nid_tsr, uint32_t v_tsr_kmh, uint32_t d_start_m, uint32_t d_end_m)
Adds a Temporary Speed Restriction (Packet 65) for a train path.
ab_gp_ertms_train_context_t * ab_gp_ertms_engine_get_train_context(uint8_t train_id)
Retrieves the ERTMS procedure context for a given train slot.
bool ab_gp_ertms_handle_text_ack(uint8_t train_id, uint8_t nid_textmessage, uint32_t timestamp_ms)
Handles driver acknowledgement of a text message (Msg 146/158).
bool ab_gp_ertms_calc_ma_for_route(uint8_t train_id, uint16_t route_id, uint32_t ma_seq)
Computes a Movement Authority for a train on a given route.
bool ab_gp_ertms_complete_handover(uint8_t train_id)
Completes the RBC handover procedure for a train.
static ab_gp_ertms_train_context_t s_train_contexts[RTE_EXAMPLE_MAX_TRAINS]
bool ab_gp_ertms_request_shunting(uint8_t train_id)
Requests shunting authorization for a train.
bool ab_gp_ertms_update_train_position(uint8_t train_id, uint32_t nid_lrbg, uint32_t d_lrbg_m, rbc_q_dirlrbg_t q_dirlrbg, uint32_t v_train_kmh, uint32_t m_mode, uint32_t m_level, uint32_t cycle, uint32_t timestamp_ms)
Updates train position and evaluates segment/route occupancy.
bool ab_gp_ertms_revoke_emergency_stop(uint8_t train_id, uint8_t nid_em)
Revokes an active emergency stop for a train.
bool ab_gp_ertms_validate_train_data(uint8_t train_id, uint32_t l_train_m, uint32_t v_maxtrain_kmh, uint8_t m_axleload, uint8_t m_loadinggauge, bool m_airtight, uint32_t timestamp_ms)
Validates train characteristics against site route topology.
bool ab_gp_ertms_authorize_shunting(uint8_t train_id, bool authorized)
Authorizes or rejects shunting mode for a train.
void ab_gp_ertms_engine_init(ab_gp_db_t *db)
Initializes the ERTMS procedure engine and all train contexts.
bool ab_gp_ertms_trigger_emergency_stop(uint8_t train_id, bool is_conditional, uint8_t nid_em, uint32_t d_ref_m, uint32_t d_es_m)
Triggers an emergency stop (UES or CES) for a train.
bool ab_gp_ertms_extend_ma_for_route(uint8_t train_id, uint16_t route_id)
Extends an existing Movement Authority with an additional route.
bool ab_gp_ertms_send_text_message(uint8_t train_id, uint8_t nid_textmessage, uint8_t q_textclass, uint8_t q_textconfirm, uint32_t duration_s, const char *text, rbc_packet_72_text_message_t *out_p72)
Sends a Driver Text Message (Packet 72) to a train.
bool ab_gp_ertms_announce_handover(uint8_t train_id, uint16_t target_nid_c, uint16_t target_nid_rbc, uint64_t target_nid_radio, uint32_t d_rbctr_m)
Announces an RBC handover transition order (Packet 131) for a train.
bool ab_gp_ertms_terminate_mission(uint8_t train_id, ab_gp_db_t *db)
Handles End of Mission teardown for a train.
void ab_gp_ertms_engine_step(ab_gp_db_t *db, uint32_t cycle, uint32_t timestamp_ms, uint32_t elapsed_ms)
Executes one cyclic evaluation of all active ERTMS train procedures.
Unified ERTMS Subset-026 Chapter 5 Operational Procedure Orchestrator.
bool ab_gp_proc_emergency_stop_revoke(ab_gp_ertms_train_context_t *ctx, uint8_t nid_em)
Revokes an active Emergency Stop (Msg 18) once hazard is cleared.
bool ab_gp_proc_emergency_stop_issue_ues(ab_gp_ertms_train_context_t *ctx, uint8_t nid_em)
Issues an Unconditional Emergency Stop (UES - Msg 16) to the train.
bool ab_gp_proc_emergency_stop_issue_ces(ab_gp_ertms_train_context_t *ctx, uint8_t nid_em, uint32_t d_ref_m, uint32_t d_emergencystop_m)
Issues a Conditional Emergency Stop (CES - Msg 15) to the train.
bool ab_gp_proc_eom_handle(ab_gp_ertms_train_context_t *ctx, ab_gp_db_t *db)
Handles inbound End of Mission notification (Msg 150).
void ab_gp_proc_handover_init(ab_gp_ertms_train_context_t *ctx)
Initializes handover context for a train slot.
bool ab_gp_proc_handover_announce(ab_gp_ertms_train_context_t *ctx, uint16_t target_nid_c, uint16_t target_nid_rbc, uint64_t target_nid_radio, uint32_t d_rbctr_m)
Announces an upcoming boundary transition to a neighboring RBC.
bool ab_gp_proc_handover_complete(ab_gp_ertms_train_context_t *ctx)
Completes the handover and marks session transferred.
bool ab_gp_proc_ma_extend(ab_gp_ertms_train_context_t *ctx, const ab_site_ga_route_layout_t *additional_route)
Extends an existing Movement Authority with an additional connected route.
bool ab_gp_proc_ma_compute(ab_gp_ertms_train_context_t *ctx, const ab_site_ga_route_layout_t *route, uint32_t ma_seq)
Computes and grants a new Movement Authority based on site track layout.
bool ab_gp_proc_position_update(ab_gp_ertms_train_context_t *ctx, uint32_t nid_lrbg, uint32_t d_lrbg_m, rbc_q_dirlrbg_t q_dirlrbg, uint32_t v_train_kmh, uint32_t m_mode, uint32_t m_level, uint32_t cycle, uint32_t timestamp_ms)
Processes an inbound Position Report (Msg 136 + Packet 0).
bool ab_gp_proc_session_check_timeout(ab_gp_ertms_train_context_t *ctx, uint32_t elapsed_ms, uint32_t timeout_limit_ms, ab_gp_db_t *db)
Supervises the communication contact timer (T_NVCONTACT).
bool ab_gp_proc_session_handle_termination(ab_gp_ertms_train_context_t *ctx, ab_gp_db_t *db)
Handles session termination (Msg 156 / Msg 41).
void ab_gp_proc_session_init(ab_gp_ertms_train_context_t *ctx, uint8_t train_id, uint32_t nid_engine)
Initializes the ERTMS procedure context for a train slot.
bool ab_gp_proc_shunting_request(ab_gp_ertms_train_context_t *ctx)
Handles inbound Shunting Request (Msg 130).
bool ab_gp_proc_shunting_authorize(ab_gp_ertms_train_context_t *ctx, bool authorized)
Authorizes or rejects shunting mode for the train.
bool ab_gp_proc_text_message_handle_ack(ab_gp_ertms_train_context_t *ctx, uint8_t nid_textmessage, uint32_t timestamp_ms)
Handles driver acknowledgement of a text message (Msg 146 / Msg 158).
void ab_gp_proc_text_message_init(ab_gp_ertms_train_context_t *ctx)
Initializes text message tracking for a train context.
bool ab_gp_proc_text_message_send(ab_gp_ertms_train_context_t *ctx, uint8_t nid_textmessage, uint8_t q_textclass, uint8_t q_textconfirm, uint32_t duration_s, const char *text, rbc_packet_72_text_message_t *out_p72)
Dispatches a plain text message to the driver DMI (Subset-026 ยง5.12 / Packet 72).
bool ab_gp_proc_train_data_validate(ab_gp_ertms_train_context_t *ctx, uint32_t l_train_m, uint32_t v_maxtrain_kmh, uint8_t m_axleload, uint8_t m_loadinggauge, bool m_airtight, uint32_t timestamp_ms)
Validates inbound Train Data (Msg 129 + Packet 11) against site topology limits.
bool ab_gp_proc_tsr_remove(ab_gp_ertms_train_context_t *ctx, uint8_t nid_tsr)
Removes an active Temporary Speed Restriction from the train's path.
bool ab_gp_proc_tsr_add(ab_gp_ertms_train_context_t *ctx, uint8_t nid_tsr, uint32_t v_tsr_kmh, uint32_t d_start_m, uint32_t d_end_m)
Adds a new Temporary Speed Restriction to the train's supervised path.
void ab_gp_proc_tsr_init(ab_gp_ertms_train_context_t *ctx)
Initializes the TSR records for a train context.
#define RTE_EXAMPLE_ERTMS_CONTACT_TIMEOUT_MS
#define RTE_EXAMPLE_MAX_TRAINS
rbc_q_dirlrbg_t
Balise Group Orientation (Q_DIRLRBG) Subset-026 Section 7.5.1.16: 0 = Reverse 1 = Nominal 2 = Unknown...
@ AB_GP_ERTMS_SESSION_IDLE
Complete ERTMS state and procedure context for one train slot.
ab_gp_ertms_session_state_t session_state