10#include "safeapi/oal/memory/sapi_mem_util.h"
11#include "safeapi/utils/buffer/sapi_buffer.h"
12#include "safeapi/utils/cast/sapi_cast.h"
13#include "safeapi/oal/log/sapi_log.h"
14#include "ga_interface.h"
19#define IL_WIRE_HEADER_SIZE 12U
20#define IL_WIRE_CONTENT_SIZE_ROUTE_ADD 24U
21#define IL_WIRE_CONTENT_SIZE_ROUTE_IDENTITY (RBC_ENVELOPE_WIRE_SIZE - IL_WIRE_HEADER_SIZE)
30 uint32_t start_signal;
32 uint32_t route_status;
38static bool route_fsm_state_is_stub(uint8_t s)
45static uint8_t g_pending_route_event_count = 0U;
52static bool il_wire_decode(
const uint8_t in[RBC_ENVELOPE_WIRE_SIZE], rbc_envelope_t *out_env);
53static void il_wire_encode(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t train_id, uint32_t start_signal,
54 uint32_t end_signal, uint32_t route_status);
55static bool handle_route_add(ab_gp_db_t *db,
const rbc_envelope_t *env, uint32_t cycle, sapi_example_site_t site,
56 const char *role_tag);
57static bool handle_route_release(ab_gp_db_t *db,
const rbc_envelope_t *env, uint32_t cycle, sapi_example_site_t site,
58 const char *role_tag);
61 sapi_example_site_t site,
const char *role_tag);
64 uint32_t end_signal, uint32_t route_status,
bool train_has_ma,
79 for (i = 0U; i < ab_site_ga_track_layout_count; i++)
83 if (out_layout != NULL)
98 for (i = 0U; i < ab_site_ga_track_layout_count; i++)
103 if (out_layout != NULL)
124bool ab_ga_il_route_add(ab_gp_db_t *db, uint16_t route_id, uint16_t start_signal, uint16_t end_signal)
130 return ab_gp_db_route_add(db, route_id, start_signal, end_signal);
135 return ab_gp_db_route_remove(db, route_id);
140 return ab_gp_db_route_set_status(db, route_id, status);
145 return ab_gp_db_route_set_type(db, route_id, route_type);
150 return ab_gp_db_route_connect_train(db, route_id, train_id);
155 return ab_gp_db_route_disconnect_train(db, route_id);
160 return ab_gp_train_set_has_ma(db, train_id,
true);
164 const uint8_t env_bytes[RBC_ENVELOPE_WIRE_SIZE], uint32_t cycle,
165 sapi_example_site_t site,
const char *role_tag)
167 rbc_envelope_t env_storage;
168 const rbc_envelope_t *env = &env_storage;
181 switch (env_bytes[0])
183 case (uint8_t)RBC_MSG_IL_ROUTE_CMD:
188 sapi_log_write_event(SAPI_LOG_LEVEL_ERROR, site_config_name(site), cycle,
"C", role_tag,
189 "IL_ROUTE_CMD",
"malformed or out-of-range", NULL);
194 case (uint8_t)RBC_MSG_IL_STATUS:
199 sapi_log_write_event(SAPI_LOG_LEVEL_ERROR, site_config_name(site), cycle,
"C", role_tag,
200 "IL_STATUS",
"malformed or out-of-range", NULL);
211 SAFEAPI_EXAMPLE_LOG(
"[%s] cycle %u: malformed or unexpected-kind envelope from C (IL relay)\n", role_tag,
213 sapi_log_write_event(SAPI_LOG_LEVEL_ERROR, site_config_name(site), cycle,
"C", role_tag,
"ENVELOPE",
220 case RBC_MSG_ROUTE_ADD:
222 case RBC_MSG_ROUTE_RELEASE:
224 case RBC_MSG_ROUTE_STATUS_REPORT:
227 SAFEAPI_EXAMPLE_LOG(
"[%s] cycle %u: IL relay envelope kind %d unexpected - dropping\n", role_tag, cycle,
235 uint8_t events = g_pending_route_event_count;
239 for (i = 0U; i < events; i++)
242 const bool train_in_route = (
event->route_status == (uint32_t)RBC_ROUTE_STATUS_TRAIN_IN_ROUTE);
244 uint8_t relay_index = (
event->train_id > 0U) ? (uint8_t)(
event->train_id - 1U) : 0U;
248 il_wire_encode(out[oi].bytes, event->train_id, event->start_signal, event->end_signal, event->route_status);
249 (void)snprintf(out[oi].tag,
sizeof(out[oi].tag),
"TRAIN_POS_IN_ROUTE");
250 out[oi].index = relay_index;
256 ind.
route_id = (int32_t)event->route_id;
260 ind.train_in_route = train_in_route;
261 ind.train_has_ma_in_route =
event->train_has_ma;
262 ind.emergency_in_route =
false;
267 (void)snprintf(out[oi].tag,
sizeof(out[oi].tag),
"IL_ROUTE_IND");
268 out[oi].index = relay_index;
271 g_pending_route_event_count = 0U;
285static bool il_wire_decode(
const uint8_t in[RBC_ENVELOPE_WIRE_SIZE], rbc_envelope_t *out_env)
288 rbc_envelope_t decoded;
290 const uint16_t expected_l_message =
291 (uint16_t)(IL_WIRE_HEADER_SIZE + IL_WIRE_CONTENT_SIZE_ROUTE_IDENTITY);
293 bool is_route_status_report;
295 is_route_add = (in[0] == (uint8_t)RBC_MSG_ROUTE_ADD);
296 is_route_status_report = (in[0] == (uint8_t)RBC_MSG_ROUTE_STATUS_REPORT);
297 if (!is_route_add && !is_route_status_report && (in[0] != (uint8_t)RBC_MSG_ROUTE_RELEASE))
301 sapi_mem_set(&decoded, 0,
sizeof(decoded));
302 decoded.kind = (rbc_msg_kind_t)in[0];
304 if (sapi_buffer_init(&buf, (uint8_t *)in, RBC_ENVELOPE_WIRE_SIZE) != SAPI_STATUS_OK)
308 (void)sapi_buffer_set_length(&buf, RBC_ENVELOPE_WIRE_SIZE);
310 if (sapi_buffer_read_u16_le(&buf, 4U, &l_message) != SAPI_STATUS_OK)
314 if (l_message != expected_l_message)
318 decoded.l_message = l_message;
319 decoded.nid_message = in[2];
320 decoded.train_id = in[1];
322 if ((sapi_buffer_read_u32_le(&buf, 8U, &decoded.t_train) != SAPI_STATUS_OK)
323 || (sapi_buffer_read_u32_le(&buf, 80U, &decoded.start_signal) != SAPI_STATUS_OK)
324 || (sapi_buffer_read_u32_le(&buf, 84U, &decoded.end_signal) != SAPI_STATUS_OK))
328 if (is_route_status_report)
334 if (sapi_buffer_read_u32_le(&buf, 92U, &decoded.route_status) != SAPI_STATUS_OK)
341 if ((sapi_buffer_read_u32_le(&buf, 24U, &decoded.route_len) != SAPI_STATUS_OK)
342 || (sapi_buffer_read_u32_le(&buf, 88U, &decoded.route_type) != SAPI_STATUS_OK))
355static void il_wire_encode(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t train_id, uint32_t start_signal,
356 uint32_t end_signal, uint32_t route_status)
359 uint16_t l_message = (uint16_t)(IL_WIRE_HEADER_SIZE + IL_WIRE_CONTENT_SIZE_ROUTE_IDENTITY);
361 sapi_mem_set(out, 0, RBC_ENVELOPE_WIRE_SIZE);
362 (void)sapi_buffer_init(&buf, out, RBC_ENVELOPE_WIRE_SIZE);
363 out[0] = (uint8_t)RBC_MSG_TRAIN_POSITION_IN_ROUTE;
367 (void)sapi_buffer_set_length(&buf, 4U);
368 (void)sapi_buffer_write_u16_le(&buf, l_message);
369 (void)sapi_buffer_write_u16_le(&buf, 0U);
370 (void)sapi_buffer_write_u32_le(&buf, 0U);
371 (void)sapi_buffer_set_length(&buf, 80U);
372 (void)sapi_buffer_write_u32_le(&buf, start_signal);
373 (void)sapi_buffer_write_u32_le(&buf, end_signal);
374 (void)sapi_buffer_write_u32_le(&buf, 0U);
375 (void)sapi_buffer_write_u32_le(&buf, route_status);
398static bool handle_route_add(ab_gp_db_t *db,
const rbc_envelope_t *env, uint32_t cycle, sapi_example_site_t site,
399 const char *role_tag)
406 "[%s] cycle %u: ROUTE_ADD for unknown route (start_signal=%u end_signal=%u) - dropping\n", role_tag,
407 cycle, (
unsigned int)env->start_signal, (
unsigned int)env->end_signal);
408 sapi_log_write_event(SAPI_LOG_LEVEL_ERROR, site_config_name(site), cycle,
"IL", role_tag,
"ROUTE_ADD",
409 "unknown route", NULL);
412 if (!ab_gp_db_route_exists(db, layout->
id))
418 SAFEAPI_EXAMPLE_LOG(
"[%s] cycle %u: [ONLINE] route %u tracked (type=%u) - MA grant awaits GP's own "
419 "position-based connect\n",
420 role_tag, cycle, (
unsigned int)layout->
id, (
unsigned int)env->route_type);
421 sapi_log_write_event(SAPI_LOG_LEVEL_INFO, site_config_name(site), cycle,
"IL", role_tag,
"ROUTE_ADD",
"tracked",
441 sapi_example_site_t site,
const char *role_tag)
444 ab_gp_route_context_t rctx;
449 "[%s] cycle %u: ROUTE_RELEASE for unknown route (start_signal=%u end_signal=%u) - dropping\n", role_tag,
450 cycle, (
unsigned int)env->start_signal, (
unsigned int)env->end_signal);
451 sapi_log_write_event(SAPI_LOG_LEVEL_ERROR, site_config_name(site), cycle,
"IL", role_tag,
"ROUTE_RELEASE",
452 "unknown route", NULL);
455 if (!ab_gp_db_route_exists(db, layout->
id))
457 SAFEAPI_EXAMPLE_LOG(
"[%s] cycle %u: ROUTE_RELEASE for route %u - not tracked, acknowledging noTrain\n", role_tag,
458 cycle, (
unsigned int)layout->
id);
467 (void)ab_gp_db_get_route_context(db, layout->
id, &rctx);
486 SAFEAPI_EXAMPLE_LOG(
"[%s] cycle %u: route %u removed from DB\n", role_tag, cycle, (
unsigned int)layout->
id);
487 sapi_log_write_event(SAPI_LOG_LEVEL_INFO, site_config_name(site), cycle,
"IL", role_tag,
"ROUTE_REMOVED",
490 SAFEAPI_EXAMPLE_LOG(
"[%s] cycle %u: route %u released\n", role_tag, cycle, (
unsigned int)layout->
id);
491 sapi_log_write_event(SAPI_LOG_LEVEL_INFO, site_config_name(site), cycle,
"IL", role_tag,
"ROUTE_RELEASE",
516 "[%s] cycle %u: ROUTE_STATUS_REPORT start_signal=%u end_signal=%u route_status=%u (route %s)\n", role_tag,
517 cycle, (
unsigned int)env->start_signal, (
unsigned int)env->end_signal, (
unsigned int)env->route_status,
518 known ?
"known" :
"UNKNOWN to this site's own layout");
532 sapi_example_site_t site,
const char *role_tag)
542 SAPI_LOG_WRITE_EVENT_F(SAPI_LOG_LEVEL_WARNING, site_config_name(site), cycle,
"IL", role_tag,
544 "no route_id (=%d) - command ignored (route_type=%d route_status=%d release=%d)",
545 (
int)cmd->
route_id, (
int)cmd->route_type, (
int)cmd->route_status,
546 cmd->release_route_request ? 1 : 0);
551 want_route = (!cmd->release_route_request) && (cmd->route_type == RBC_IL_ROUTE_TYPE_LOCKED);
560 if (!ab_gp_db_route_exists(db, route_id))
567 && (layout->
id == route_id))
577 SAPI_LOG_WRITE_EVENT_F(SAPI_LOG_LEVEL_ERROR, site_config_name(site), cycle,
"IL", role_tag,
579 "route %u (start_signal=%d end_signal=%d) unknown to this site's layout - rejecting",
588 if ((!want_route) && ab_gp_db_route_exists(db, route_id))
609 uint8_t alloc_train = 0U;
613 if (ab_gp_db_route_exists(db, route_id))
615 ab_gp_route_context_t rctx;
616 if (ab_gp_db_get_route_context(db, route_id, &rctx))
618 alloc_train = rctx.train_id;
619 has_ma = rctx.used_in_ma;
622 rstatus = (alloc_train != 0U) ? (uint32_t)RBC_ROUTE_STATUS_TRAIN_IN_ROUTE
623 : (uint32_t)RBC_ROUTE_STATUS_NO_TRAIN;
641 if ((st->il_status == RBC_IL_STATUS_DOWN) || (st->il_status == RBC_IL_STATUS_RESTARTING))
643 SAFEAPI_EXAMPLE_LOG(
"[%s] cycle %u: IL_STATUS=%s - route state trust HOLD not implemented yet (stub)\n",
645 (st->il_status == RBC_IL_STATUS_DOWN) ?
"DOWN" :
"RESTARTING");
649 SAFEAPI_EXAMPLE_LOG(
"[%s] cycle %u: IL_STATUS=UP\n", role_tag, cycle);
658 uint32_t end_signal, uint32_t route_status,
bool train_has_ma,
664 const uint8_t max_events = (uint8_t)(AB_GP_IL_MAX_PENDING_OUTPUTS / 2U);
666 for (i = 0U; i < g_pending_route_event_count; i++)
668 if ((g_pending_route_events[i].route_id == route_id) &&
669 (g_pending_route_events[i].train_id == train_id) &&
670 (g_pending_route_events[i].route_status == route_status) &&
671 (g_pending_route_events[i].fsm_state == fsm_state))
676 if (g_pending_route_event_count >= max_events)
678 SAFEAPI_EXAMPLE_LOG(
"IL: pending route-indication queue full - dropping event for train %u\n",
679 (
unsigned int)train_id);
682 g_pending_route_events[g_pending_route_event_count].train_id = train_id;
683 g_pending_route_events[g_pending_route_event_count].route_id = route_id;
684 g_pending_route_events[g_pending_route_event_count].start_signal = start_signal;
685 g_pending_route_events[g_pending_route_event_count].end_signal = end_signal;
686 g_pending_route_events[g_pending_route_event_count].route_status = route_status;
687 g_pending_route_events[g_pending_route_event_count].train_has_ma = train_has_ma;
688 g_pending_route_events[g_pending_route_event_count].fsm_state = fsm_state;
689 g_pending_route_events[g_pending_route_event_count].fsm_is_stub = route_fsm_state_is_stub(fsm_state);
690 g_pending_route_event_count++;
708 const ab_gp_route_context_t *ctx, ab_gp_route_update_type_t update_type)
711 uint32_t route_status;
713 if ((update_type != AB_ROUTE_CONNECTED) && (update_type != AB_ROUTE_DISCONNECTED))
717 route_status = (update_type == AB_ROUTE_CONNECTED) ? (uint32_t)RBC_ROUTE_STATUS_TRAIN_IN_ROUTE
718 : (uint32_t)RBC_ROUTE_STATUS_NO_TRAIN;
719 SAFEAPI_EXAMPLE_LOG(
"[%s] IL notified: route %u %s train %u\n",
g_ga_role_tag, (
unsigned int)ctx->id,
720 (update_type == AB_ROUTE_CONNECTED) ?
"connected to" :
"disconnected from",
721 (
unsigned int)ctx->train_id);
728 if ((sessions == NULL) || (db == NULL) || (ctx->train_id == 0U))
743 if (update_type == AB_ROUTE_CONNECTED)
755 ab_gp_train_context_t tctx_pos;
756 uint32_t remaining_m = layout->
length_m;
757 bool is_first_route =
true;
759 if (ab_gp_get_train_context(sessions, db, ctx->train_id, &tctx_pos))
761 remaining_m = ab_gp_proc_ma_remaining_length_m(layout, tctx_pos.nid_lrbg, tctx_pos.d_lrbg);
762 is_first_route = (tctx_pos.granted_length == 0U);
772 remaining_m = (remaining_m > SAFEAPI_EXAMPLE_MA_OVERLAP_M)
773 ? (remaining_m - SAFEAPI_EXAMPLE_MA_OVERLAP_M) : 0U;
775 (void)ab_gp_train_session_add_granted_length(sessions, ctx->train_id, remaining_m);
776 (void)ab_gp_train_session_increment_ma_seq(sessions, ctx->train_id);
779 AB_GA_CHECKPOINT_MARK();
780 (void)ab_gp_train_session_set_ma_pending_send(sessions, ctx->train_id,
true);
781 (void)ab_gp_train_session_set_ma_acked(sessions, ctx->train_id,
false);
789 ab_gp_train_context_t tctx;
791 (void)ab_gp_get_train_context(sessions, db, ctx->train_id, &tctx);
792 if (tctx.route_count == 0U)
794 sapi_log_write_event(SAPI_LOG_LEVEL_DEBUG,
"-", 0U,
"IL",
g_ga_role_tag,
"ROUTE_DISCONNECT_ZEROED_MA",
795 "no routes remain for this train - granted_length reset to 0", NULL);
796 (void)ab_gp_train_session_set_granted_length(sessions, ctx->train_id, 0U);
797 (void)ab_gp_train_session_set_ctc_ma_granted_sent(sessions, ctx->train_id,
false);
799 else if (tctx.granted_length >= layout->
length_m)
801 sapi_log_write_event(SAPI_LOG_LEVEL_DEBUG,
"-", 0U,
"IL",
g_ga_role_tag,
"ROUTE_DISCONNECT_SHRUNK_MA",
802 "granted_length reduced by this route's own length", NULL);
803 (void)ab_gp_train_session_set_granted_length(sessions, ctx->train_id, tctx.granted_length - layout->
length_m);
809 ab_gp_train_notify_context_changed(sessions, db, ctx->train_id, AB_TRAIN_MA_CHANGED);
bool ab_ga_il_route_remove(ab_gp_db_t *db, uint16_t route_id)
Removes a tracked route from GP's own route table, freeing its slot - thin wrapper over ga_interface....
bool ab_ga_il_route_add(ab_gp_db_t *db, uint16_t route_id, uint16_t start_signal, uint16_t end_signal)
Adds a new route to GP's own route table, after verifying it via ab_ga_il_route_verify() above - thin...
void ab_ga_il_on_route_context_changed(ab_gp_train_session_t *sessions, ab_gp_db_t *db, const ab_gp_route_context_t *ctx, ab_gp_route_update_type_t update_type)
GA's single dispatch module (ab_ga_dispatch.c) fans every route change here for AB_ROUTE_CONNECTED/AB...
bool ab_ga_il_apply_envelope(const void *context, ab_gp_train_session_t *sessions, ab_gp_db_t *db, const uint8_t env_bytes[RBC_ENVELOPE_WIRE_SIZE], uint32_t cycle, sapi_example_site_t site, const char *role_tag)
THE handler this module registers with GP (ab_gp_register_il_envelope_handler(), ga_interface....
bool ab_ga_il_route_unassign_train(ab_gp_db_t *db, uint16_t route_id)
Reverses ab_ga_il_route_assign_train() - thin wrapper over ga_interface.h's own ab_gp_db_route_discon...
static void il_wire_encode(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t train_id, uint32_t start_signal, uint32_t end_signal, uint32_t route_status)
Encodes a TRAIN_POSITION_IN_ROUTE envelope into raw wire bytes.
bool ab_ga_il_route_verify(uint16_t route_id, uint16_t start_signal, uint16_t end_signal)
Verifies a route as reported by ILSim is OK: it must both exist in this site's own static layout AND ...
static rbc_il_status_t g_il_status
bool ab_ga_il_route_set_status(ab_gp_db_t *db, uint16_t route_id, ab_gp_db_route_il_status_t status)
Updates a tracked route's own il_status - IL's last-reported status for it - thin wrapper over ga_int...
bool ab_ga_il_site_has_route_by_signals(uint16_t start_signal, uint16_t end_signal, const ab_site_ga_route_layout_t **out_layout)
Pure site-layout lookup by route IDENTITY - does a route with this exact (start_signal,...
static bool handle_il_status(const ab_ga_il_status_msg_t *st, uint32_t cycle, const char *role_tag)
Processes a dedicated RBC_MSG_IL_STATUS (kind 26). Tracks IL health; a real hold/hold-off-trust react...
static void enqueue_pending_route_event(uint8_t train_id, uint16_t route_id, uint32_t start_signal, uint32_t end_signal, uint32_t route_status, bool train_has_ma, uint8_t fsm_state)
Appends a route notification event to the pending queue.
bool ab_ga_il_route_assign_train(ab_gp_db_t *db, uint16_t route_id, uint8_t train_id)
Assigns a route to a train - thin wrapper over ga_interface.h's own ab_gp_db_route_connect_train() (w...
static bool handle_route_release(ab_gp_db_t *db, const rbc_envelope_t *env, uint32_t cycle, sapi_example_site_t site, const char *role_tag)
Processes an inbound ROUTE_RELEASE command from Interlocking.
bool ab_ga_il_handle_route_add(ab_gp_db_t *db, uint8_t train_id)
Handles the MA-length-bookkeeping half of an inbound ROUTE_ADD - marks this train as now holding a va...
static bool handle_il_route_cmd(ab_gp_db_t *db, const ab_ga_il_route_cmd_t *cmd, uint32_t cycle, sapi_example_site_t site, const char *role_tag)
Processes a dedicated RBC_MSG_IL_ROUTE_CMD (kind 25).
uint8_t ab_ga_il_build_outputs(ab_gp_il_pending_output_t out[AB_GP_IL_MAX_PENDING_OUTPUTS])
Drains this module's own TrainPositionInRoute event queue (populated by this module's own route-conne...
static bool handle_route_add(ab_gp_db_t *db, const rbc_envelope_t *env, uint32_t cycle, sapi_example_site_t site, const char *role_tag)
Processes an inbound ROUTE_ADD command from Interlocking.
bool ab_ga_il_route_set_type(ab_gp_db_t *db, uint16_t route_id, uint32_t route_type)
Updates a tracked route's own route_type - IL's last-reported supervision mode (rbc_route_type_t: RBC...
static bool handle_route_status_report(const rbc_envelope_t *env, uint32_t cycle, const char *role_tag)
Handles IL's own Phase D periodic route-status broadcast (RBC_MSG_ROUTE_STATUS_REPORT,...
static bool il_wire_decode(const uint8_t in[RBC_ENVELOPE_WIRE_SIZE], rbc_envelope_t *out_env)
Decodes an RBC envelope frame into an rbc_envelope_t structure.
bool ab_ga_il_site_has_route(uint16_t route_id, const ab_site_ga_route_layout_t **out_layout)
Pure site-layout lookup - does route_id exist in this site's own static track layout at all (ab_site_...
A/B's own route handling against GP's own runtime table (via AB/GP/ga_interface/ga_interface....
bool ab_ga_il_wire_decode_route_cmd(const uint8_t frame[RBC_ENVELOPE_WIRE_SIZE], ab_ga_il_route_cmd_t *out)
Decodes + fully range-validates an RBC_MSG_IL_ROUTE_CMD frame.
void ab_ga_il_wire_encode_route_indication(uint8_t frame[RBC_ENVELOPE_WIRE_SIZE], const ab_ga_il_route_indication_t *in)
Encodes an RBC_MSG_IL_ROUTE_INDICATION frame (zero-fills the whole RBC_ENVELOPE_WIRE_SIZE slot first)...
bool ab_ga_il_wire_decode_status(const uint8_t frame[RBC_ENVELOPE_WIRE_SIZE], ab_ga_il_status_msg_t *out)
Decodes + validates an RBC_MSG_IL_STATUS frame. Same contract.
Dedicated IL <-> RBC message payloads and codec (wire kinds RBC_MSG_IL_ROUTE_CMD / RBC_MSG_IL_STATUS ...
ab_ga_route_fsm_result_t ab_ga_route_fsm_step(ab_gp_db_t *db, uint16_t route_id, const ab_ga_il_route_cmd_t *cmd, uint32_t cycle, const char *role_tag)
Applies cmd to the route's FSM: reads the current state via ab_gp_db_route_get_fsm_state(),...
Per-route state machine, driven by IL route commands (RBC_MSG_IL_ROUTE_CMD / ab_ga_il_route_cmd_t).
@ AB_GA_ROUTE_STATE_DEGRADED
@ AB_GA_ROUTE_STATE_NO_ROUTE
const ab_site_ga_route_layout_t ab_site_ga_track_layout[]
Decoded RBC_MSG_IL_ROUTE_CMD payload.
RBC_MSG_IL_ROUTE_INDICATION payload (RBC -> IL).
int32_t allocated_train_nid_engine
rbc_il_emergency_type_t emergency_type
Decoded RBC_MSG_IL_STATUS payload.
Result of applying one IL route command to a route's FSM.
One route's static layout entry (railML interlocking <route>) - GA's own full definition (not a reduc...
Queued route event for IL notification dispatch.