10#include "rte/oal/memory/rte_mem_util.h"
11#include "rte/utils/buffer/rte_buffer.h"
12#include "rte/utils/cast/rte_cast.h"
13#include "rte/oal/log/rte_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, rte_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, rte_example_site_t site,
58 const char *role_tag);
61 rte_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 rte_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 rte_log_write_event(RTE_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 rte_log_write_event(RTE_LOG_LEVEL_ERROR, site_config_name(site), cycle,
"C", role_tag,
200 "IL_STATUS",
"malformed or out-of-range", NULL);
211 RTE_EXAMPLE_LOG(
"[%s] cycle %u: malformed or unexpected-kind envelope from C (IL relay)\n", role_tag,
213 rte_log_write_event(RTE_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 RTE_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_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;
276 g_pending_route_event_count = 0U;
289static bool il_wire_decode(
const uint8_t in[RBC_ENVELOPE_WIRE_SIZE], rbc_envelope_t *out_env)
292 rbc_envelope_t decoded;
294 const uint16_t expected_l_message =
295 (uint16_t)(IL_WIRE_HEADER_SIZE + IL_WIRE_CONTENT_SIZE_ROUTE_IDENTITY);
297 bool is_route_status_report;
299 is_route_add = (in[0] == (uint8_t)RBC_MSG_ROUTE_ADD);
300 is_route_status_report = (in[0] == (uint8_t)RBC_MSG_ROUTE_STATUS_REPORT);
301 if (!is_route_add && !is_route_status_report && (in[0] != (uint8_t)RBC_MSG_ROUTE_RELEASE))
305 rte_mem_set(&decoded, 0,
sizeof(decoded));
306 decoded.kind = (rbc_msg_kind_t)in[0];
308 if (rte_buffer_init(&buf, (uint8_t *)in, RBC_ENVELOPE_WIRE_SIZE) != RTE_STATUS_OK)
312 (void)rte_buffer_set_length(&buf, RBC_ENVELOPE_WIRE_SIZE);
314 if (rte_buffer_read_u16_le(&buf, 4U, &l_message) != RTE_STATUS_OK)
318 if (l_message != expected_l_message)
322 decoded.l_message = l_message;
323 decoded.nid_message = in[2];
324 decoded.train_id = in[1];
326 if ((rte_buffer_read_u32_le(&buf, 8U, &decoded.t_train) != RTE_STATUS_OK)
327 || (rte_buffer_read_u32_le(&buf, 80U, &decoded.start_signal) != RTE_STATUS_OK)
328 || (rte_buffer_read_u32_le(&buf, 84U, &decoded.end_signal) != RTE_STATUS_OK))
332 if (is_route_status_report)
338 if (rte_buffer_read_u32_le(&buf, 92U, &decoded.route_status) != RTE_STATUS_OK)
345 if ((rte_buffer_read_u32_le(&buf, 24U, &decoded.route_len) != RTE_STATUS_OK)
346 || (rte_buffer_read_u32_le(&buf, 88U, &decoded.route_type) != RTE_STATUS_OK))
359static void il_wire_encode(uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t train_id, uint32_t start_signal,
360 uint32_t end_signal, uint32_t route_status)
363 uint16_t l_message = (uint16_t)(IL_WIRE_HEADER_SIZE + IL_WIRE_CONTENT_SIZE_ROUTE_IDENTITY);
365 rte_mem_set(out, 0, RBC_ENVELOPE_WIRE_SIZE);
366 (void)rte_buffer_init(&buf, out, RBC_ENVELOPE_WIRE_SIZE);
367 out[0] = (uint8_t)RBC_MSG_TRAIN_POSITION_IN_ROUTE;
371 (void)rte_buffer_set_length(&buf, 4U);
372 (void)rte_buffer_write_u16_le(&buf, l_message);
373 (void)rte_buffer_write_u16_le(&buf, 0U);
374 (void)rte_buffer_write_u32_le(&buf, 0U);
375 (void)rte_buffer_set_length(&buf, 80U);
376 (void)rte_buffer_write_u32_le(&buf, start_signal);
377 (void)rte_buffer_write_u32_le(&buf, end_signal);
378 (void)rte_buffer_write_u32_le(&buf, 0U);
379 (void)rte_buffer_write_u32_le(&buf, route_status);
402static bool handle_route_add(ab_gp_db_t *db,
const rbc_envelope_t *env, uint32_t cycle, rte_example_site_t site,
403 const char *role_tag)
410 "[%s] cycle %u: ROUTE_ADD for unknown route (start_signal=%u end_signal=%u) - dropping\n", role_tag,
411 cycle, (
unsigned int)env->start_signal, (
unsigned int)env->end_signal);
412 rte_log_write_event(RTE_LOG_LEVEL_ERROR, site_config_name(site), cycle,
"IL", role_tag,
"ROUTE_ADD",
413 "unknown route", NULL);
416 if (!ab_gp_db_route_exists(db, layout->
id))
422 RTE_EXAMPLE_LOG(
"[%s] cycle %u: [ONLINE] route %u tracked (type=%u) - MA grant awaits GP's own "
423 "position-based connect\n",
424 role_tag, cycle, (
unsigned int)layout->
id, (
unsigned int)env->route_type);
425 rte_log_write_event(RTE_LOG_LEVEL_INFO, site_config_name(site), cycle,
"IL", role_tag,
"ROUTE_ADD",
"tracked",
445 rte_example_site_t site,
const char *role_tag)
448 ab_gp_route_context_t rctx;
453 "[%s] cycle %u: ROUTE_RELEASE for unknown route (start_signal=%u end_signal=%u) - dropping\n", role_tag,
454 cycle, (
unsigned int)env->start_signal, (
unsigned int)env->end_signal);
455 rte_log_write_event(RTE_LOG_LEVEL_ERROR, site_config_name(site), cycle,
"IL", role_tag,
"ROUTE_RELEASE",
456 "unknown route", NULL);
459 if (!ab_gp_db_route_exists(db, layout->
id))
461 RTE_EXAMPLE_LOG(
"[%s] cycle %u: ROUTE_RELEASE for route %u - not tracked, acknowledging noTrain\n", role_tag,
462 cycle, (
unsigned int)layout->
id);
471 (void)ab_gp_db_get_route_context(db, layout->
id, &rctx);
490 RTE_EXAMPLE_LOG(
"[%s] cycle %u: route %u removed from DB\n", role_tag, cycle, (
unsigned int)layout->
id);
491 rte_log_write_event(RTE_LOG_LEVEL_INFO, site_config_name(site), cycle,
"IL", role_tag,
"ROUTE_REMOVED",
494 RTE_EXAMPLE_LOG(
"[%s] cycle %u: route %u released\n", role_tag, cycle, (
unsigned int)layout->
id);
495 rte_log_write_event(RTE_LOG_LEVEL_INFO, site_config_name(site), cycle,
"IL", role_tag,
"ROUTE_RELEASE",
520 "[%s] cycle %u: ROUTE_STATUS_REPORT start_signal=%u end_signal=%u route_status=%u (route %s)\n", role_tag,
521 cycle, (
unsigned int)env->start_signal, (
unsigned int)env->end_signal, (
unsigned int)env->route_status,
522 known ?
"known" :
"UNKNOWN to this site's own layout");
536 rte_example_site_t site,
const char *role_tag)
546 RTE_LOG_WRITE_EVENT_F(RTE_LOG_LEVEL_WARNING, site_config_name(site), cycle,
"IL", role_tag,
548 "no route_id (=%d) - command ignored (route_type=%d route_status=%d release=%d)",
549 (
int)cmd->
route_id, (
int)cmd->route_type, (
int)cmd->route_status,
550 cmd->release_route_request ? 1 : 0);
555 want_route = (!cmd->release_route_request) && (cmd->route_type == RBC_IL_ROUTE_TYPE_LOCKED);
564 if (!ab_gp_db_route_exists(db, route_id))
571 && (layout->
id == route_id))
581 RTE_LOG_WRITE_EVENT_F(RTE_LOG_LEVEL_ERROR, site_config_name(site), cycle,
"IL", role_tag,
583 "route %u (start_signal=%d end_signal=%d) unknown to this site's layout - rejecting",
592 if ((!want_route) && ab_gp_db_route_exists(db, route_id))
613 uint8_t alloc_train = 0U;
617 if (ab_gp_db_route_exists(db, route_id))
619 ab_gp_route_context_t rctx;
620 if (ab_gp_db_get_route_context(db, route_id, &rctx))
622 alloc_train = rctx.train_id;
623 has_ma = rctx.used_in_ma;
626 rstatus = (alloc_train != 0U) ? (uint32_t)RBC_ROUTE_STATUS_TRAIN_IN_ROUTE
627 : (uint32_t)RBC_ROUTE_STATUS_NO_TRAIN;
645 if ((st->il_status == RBC_IL_STATUS_DOWN) || (st->il_status == RBC_IL_STATUS_RESTARTING))
647 RTE_EXAMPLE_LOG(
"[%s] cycle %u: IL_STATUS=%s - route state trust HOLD not implemented yet (stub)\n",
649 (st->il_status == RBC_IL_STATUS_DOWN) ?
"DOWN" :
"RESTARTING");
653 RTE_EXAMPLE_LOG(
"[%s] cycle %u: IL_STATUS=UP\n", role_tag, cycle);
662 uint32_t end_signal, uint32_t route_status,
bool train_has_ma,
668 const uint8_t max_events = (uint8_t)(AB_GP_IL_MAX_PENDING_OUTPUTS / 2U);
670 for (i = 0U; i < g_pending_route_event_count; i++)
672 if ((g_pending_route_events[i].route_id == route_id) &&
673 (g_pending_route_events[i].train_id == train_id) &&
674 (g_pending_route_events[i].route_status == route_status) &&
675 (g_pending_route_events[i].fsm_state == fsm_state))
680 if (g_pending_route_event_count >= max_events)
682 RTE_EXAMPLE_LOG(
"IL: pending route-indication queue full - dropping event for train %u\n",
683 (
unsigned int)train_id);
686 g_pending_route_events[g_pending_route_event_count].train_id = train_id;
687 g_pending_route_events[g_pending_route_event_count].route_id = route_id;
688 g_pending_route_events[g_pending_route_event_count].start_signal = start_signal;
689 g_pending_route_events[g_pending_route_event_count].end_signal = end_signal;
690 g_pending_route_events[g_pending_route_event_count].route_status = route_status;
691 g_pending_route_events[g_pending_route_event_count].train_has_ma = train_has_ma;
692 g_pending_route_events[g_pending_route_event_count].fsm_state = fsm_state;
693 g_pending_route_events[g_pending_route_event_count].fsm_is_stub = route_fsm_state_is_stub(fsm_state);
694 g_pending_route_event_count++;
712 const ab_gp_route_context_t *ctx, ab_gp_route_update_type_t update_type)
715 uint32_t route_status;
717 if ((ctx == NULL) || (ctx->id == 0U))
721 if ((update_type != AB_ROUTE_CONNECTED) && (update_type != AB_ROUTE_DISCONNECTED))
725 route_status = (update_type == AB_ROUTE_CONNECTED) ? (uint32_t)RBC_ROUTE_STATUS_TRAIN_IN_ROUTE
726 : (uint32_t)RBC_ROUTE_STATUS_NO_TRAIN;
727 RTE_EXAMPLE_LOG(
"[%s] IL notified: route %u %s train %u\n",
g_ga_role_tag, (
unsigned int)ctx->id,
728 (update_type == AB_ROUTE_CONNECTED) ?
"connected to" :
"disconnected from",
729 (
unsigned int)ctx->train_id);
736 if ((sessions == NULL) || (db == NULL) || (ctx->train_id == 0U))
751 if (update_type == AB_ROUTE_CONNECTED)
768 ab_gp_train_context_t tctx_pos;
770 if (ab_gp_get_train_context(sessions, db, ctx->train_id, &tctx_pos))
772 uint32_t total_m = ab_gp_proc_ma_remaining_length_m(layout, tctx_pos.nid_lrbg, tctx_pos.d_lrbg);
774 total_m = (total_m > RTE_EXAMPLE_MA_OVERLAP_M) ? (total_m - RTE_EXAMPLE_MA_OVERLAP_M) : 0U;
775 (void)ab_gp_train_session_set_granted_length(sessions, ctx->train_id, total_m);
779 (void)ab_gp_train_session_add_granted_length(sessions, ctx->train_id, layout->
length_m);
781 (void)ab_gp_train_session_increment_ma_seq(sessions, ctx->train_id);
784 AB_GA_CHECKPOINT_MARK();
785 (void)ab_gp_train_session_set_ma_pending_send(sessions, ctx->train_id,
true);
786 (void)ab_gp_train_session_set_ma_acked(sessions, ctx->train_id,
false);
794 ab_gp_train_context_t tctx;
796 (void)ab_gp_get_train_context(sessions, db, ctx->train_id, &tctx);
797 if (tctx.route_count == 0U)
799 rte_log_write_event(RTE_LOG_LEVEL_DEBUG,
"-", 0U,
"IL",
g_ga_role_tag,
"ROUTE_DISCONNECT_ZEROED_MA",
800 "no routes remain for this train - granted_length reset to 0", NULL);
801 (void)ab_gp_train_session_set_granted_length(sessions, ctx->train_id, 0U);
802 (void)ab_gp_train_session_set_ctc_ma_granted_sent(sessions, ctx->train_id,
false);
813 uint32_t total_m = ab_gp_proc_ma_remaining_length_m(last, tctx.nid_lrbg, tctx.d_lrbg);
815 total_m = (total_m > RTE_EXAMPLE_MA_OVERLAP_M) ? (total_m - RTE_EXAMPLE_MA_OVERLAP_M) : 0U;
816 if (total_m < tctx.granted_length)
818 rte_log_write_event(RTE_LOG_LEVEL_DEBUG,
"-", 0U,
"IL",
g_ga_role_tag,
819 "ROUTE_DISCONNECT_SHRUNK_MA",
820 "granted_length re-derived from the last remaining route", NULL);
821 (void)ab_gp_train_session_set_granted_length(sessions, ctx->train_id, total_m);
829 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_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 bool handle_il_route_cmd(ab_gp_db_t *db, const ab_ga_il_route_cmd_t *cmd, uint32_t cycle, rte_example_site_t site, const char *role_tag)
Processes a dedicated RBC_MSG_IL_ROUTE_CMD (kind 25).
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.
static bool handle_route_add(ab_gp_db_t *db, const rbc_envelope_t *env, uint32_t cycle, rte_example_site_t site, const char *role_tag)
Processes an inbound ROUTE_ADD command from Interlocking.
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...
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...
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...
void ab_ga_il_confirm_outputs_sent(void)
Clears the pending-route-event queue ab_ga_il_build_outputs() just built from - call ONLY once those ...
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, rte_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_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_...
static bool handle_route_release(ab_gp_db_t *db, const rbc_envelope_t *env, uint32_t cycle, rte_example_site_t site, const char *role_tag)
Processes an inbound ROUTE_RELEASE command from Interlocking.
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[]
const ab_site_ga_route_layout_t * ab_site_ga_get_route(uint16_t route_id)
Looks up a route by its ID.
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.