|
SafeAPI RBC 2oo2 Generic Application
IL/CTC route and train logic for the safeAPIRBC2oo2 reference RBC
|
Interlocking (IL) Generic Application adapter and wire codec. More...
#include "ab_ga_il.h"#include <stdio.h>#include "safeapi/oal/memory/sapi_mem_util.h"#include "safeapi/utils/buffer/sapi_buffer.h"#include "safeapi/utils/cast/sapi_cast.h"#include "safeapi/oal/log/sapi_log.h"#include "ga_interface.h"#include "ab_ga_il_wire.h"#include "ab_ga_route_fsm.h"Go to the source code of this file.
Data Structures | |
| struct | il_pending_route_event_t |
| Queued route event for IL notification dispatch. More... | |
Macros | |
| #define | IL_WIRE_HEADER_SIZE 12U |
| #define | IL_WIRE_CONTENT_SIZE_ROUTE_ADD 24U |
| #define | IL_WIRE_CONTENT_SIZE_ROUTE_IDENTITY (RBC_ENVELOPE_WIRE_SIZE - IL_WIRE_HEADER_SIZE) |
Functions | |
| static bool | route_fsm_state_is_stub (uint8_t s) |
| 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. | |
| 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. | |
| 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. | |
| 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. | |
| 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, 2s cadence - see ILRBCSim/src/il/il_sim.py's own doc). Deliberately liveness-only for this first cut: logs receipt (proof IL's own cadence is actually reaching AB) without cross-checking @env's reported route_status against AB's own held-route state (ab_gp_db_route_t) - see this session's own plan doc for why that reconciliation is explicitly deferred, not an oversight. Does not touch @db at all - a report AB can't currently match to a known route (start_signal/end_signal not in this site's own layout) is still just logged, never treated as an error the way a real ROUTE_ADD/ROUTE_RELEASE for an unknown route would be, since this is a passive status feed, not a command. | |
| 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). | |
| 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 reaction to DOWN/RESTARTING is stubbed (logged, not acted on). | |
| 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_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_ga_track_layout, ab_site.h)? | |
| 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, end_signal) pair exist in this site's own static track layout? Same shape as ab_ga_il_site_has_route() above, but by signal pair rather than synthetic id - the wire's own route-identity model (rbc_wire_types.h's own doc) - used to resolve an inbound ROUTE_ADD/ROUTE_RELEASE's own start_signal/end_signal fields to this site's internal route_id before touching db->routes[]. | |
| 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 report the same start/end signals the layout itself has for that route id - ILSim is external, untrusted input (same REQ-RBC-002 "reject a
malformed frame, don't index blind" posture already applied to wire input elsewhere in this project), so its own claimed signals are cross-checked against the site's own authoritative layout, not taken on faith. | |
| 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 wrapper over ga_interface.h's own ab_gp_db_route_add(). | |
| 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.h's own ab_gp_db_route_remove(). | |
| 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_interface.h's own ab_gp_db_route_set_status(). Does not touch occupied (a separate, non-IL-sourced concept). | |
| 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_ROUTE_TYPE_FS/_OS/_SH, rbc_wire_types.h) for it - thin wrapper over ga_interface.h's own ab_gp_db_route_set_type(). | |
| 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() (which fires GP's own route-connected notify on success). | |
| 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_disconnect_train(). | |
| 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 valid MA (ab_gp_train_set_has_ma()). Deliberately unaware of route identity/type - that half (resolving/creating the real ab_gp_db_route_t) is handle_route_add()'s own job (ab_ga_il.c, file-static) - this function stays the same narrow "train now has
an MA" bookkeeping step it always was, kept public since ab_ga_il_apply_envelope()'s own ROUTE_ADD path still calls it alongside the newer route-identity handling. | |
| 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.h, via AB/main/ab_ga_dispatch.c's own ab_ga_dispatch_init()) for every raw envelope popped off its dedicated IL relay channel (ROUTE_ADD/ROUTE_RELEASE - see site_config.h's own sapi_example_relay_kind_t doc) - "pure GA" now (later session, on direct request): GP no longer calls this by bare name, only ever through the registered function pointer, so context (unused here - matches ab_gp_il_envelope_handler_fn's own signature purely so this function can be registered directly, no trampoline needed) is always NULL. Wire-decodes the envelope (this module's own il_wire_decode(), ab_ga_il.c) and dispatches by kind to this module's own file-static handle_route_add()/handle_route_release(). | |
| 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-connected/-disconnected notify subscribers, registered from ab_ga_il_init() - see ga_interface.h's own ab_gp_db_register_route_connected_notify()/ _disconnected_notify()) and wire-encodes each into out. Deliberately takes no sessions/db parameters, unlike AB/GP/train/ab_gp_train.h's/AB/GA/ctc/ab_ga_ctc.h's own build_outputs() - everything this needs was already captured into the internal event queue by the notify callbacks at the moment each route-connect/-disconnect actually happened, not re-derived here from current table state. Called from AB/GP/main/post_execute.c's own ab_gp_channel_post_execute() (the real forward-to-C logic, step 3 of that function), same "GP orchestrates, GA builds" pattern CTC/Train already use. | |
| 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_ROUTE_DISCONNECTED - the only two IL cares about (see this file's own module doc). Was two separate GP-registered callbacks (il_on_route_connected/ _disconnected) - collapsed into this one dispatch-driven function on direct request, same rationale as ab_ga_ctc_on_route_context_changed()'s own doc. | |
Variables | |
| static il_pending_route_event_t | g_pending_route_events [AB_GP_IL_MAX_PENDING_OUTPUTS] |
| static uint8_t | g_pending_route_event_count = 0U |
| static rbc_il_status_t | g_il_status = RBC_IL_STATUS_DOWN |
| char * | g_ga_role_tag |
Interlocking (IL) Generic Application adapter and wire codec.
Implements route allocation handling, envelope decoding/encoding, and lifecycle notification routing between IL and GP database.
Definition in file ab_ga_il.c.
| #define IL_WIRE_CONTENT_SIZE_ROUTE_ADD 24U |
Definition at line 20 of file ab_ga_il.c.
| #define IL_WIRE_CONTENT_SIZE_ROUTE_IDENTITY (RBC_ENVELOPE_WIRE_SIZE - IL_WIRE_HEADER_SIZE) |
Definition at line 21 of file ab_ga_il.c.
| #define IL_WIRE_HEADER_SIZE 12U |
Definition at line 19 of file ab_ga_il.c.
| 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.h, via AB/main/ab_ga_dispatch.c's own ab_ga_dispatch_init()) for every raw envelope popped off its dedicated IL relay channel (ROUTE_ADD/ROUTE_RELEASE - see site_config.h's own sapi_example_relay_kind_t doc) - "pure GA" now (later session, on direct request): GP no longer calls this by bare name, only ever through the registered function pointer, so context (unused here - matches ab_gp_il_envelope_handler_fn's own signature purely so this function can be registered directly, no trampoline needed) is always NULL. Wire-decodes the envelope (this module's own il_wire_decode(), ab_ga_il.c) and dispatches by kind to this module's own file-static handle_route_add()/handle_route_release().
| sessions | com's own ab_gp_train_session_t table (opaque to this module - see this file's own module doc) (SAFEAPI_EXAMPLE_MAX_TRAINS entries) - mutated in place via ga_interface.h's own setters. |
| db | AB's own Train/Route database (opaque) - mutated in place. |
| env_bytes | Raw wire bytes, exactly RBC_ENVELOPE_WIRE_SIZE - not yet decoded. |
| cycle | This AB cycle's own number (logging only). |
| site | This channel's own site (logging only). |
| role_tag | This channel's own "A/WEST" etc. tag (logging only). |
Definition at line 163 of file ab_ga_il.c.
| 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-connected/-disconnected notify subscribers, registered from ab_ga_il_init() - see ga_interface.h's own ab_gp_db_register_route_connected_notify()/ _disconnected_notify()) and wire-encodes each into out. Deliberately takes no sessions/db parameters, unlike AB/GP/train/ab_gp_train.h's/AB/GA/ctc/ab_ga_ctc.h's own build_outputs() - everything this needs was already captured into the internal event queue by the notify callbacks at the moment each route-connect/-disconnect actually happened, not re-derived here from current table state. Called from AB/GP/main/post_execute.c's own ab_gp_channel_post_execute() (the real forward-to-C logic, step 3 of that function), same "GP orchestrates, GA builds" pattern CTC/Train already use.
The pending-output element type/capacity this module fills (ab_gp_il_pending_output_t/AB_GP_IL_MAX_PENDING_OUTPUTS) are GP-owned now, declared in ga_interface.h - the "consumer owns the shape" posture ab_gp_route_context_t/ab_gp_train_context_t already take (see that header's own doc).
Deliberately an ACCUMULATING queue, not reset at the top of every cycle - found live: an earlier version of this module did reset it every cycle (before ab_gp_logic_connect_routes_and_trains() could enqueue anything new), reasoning that the non-forwarding channel's own copy needed clearing to avoid filling up in steady state. That reasoning was wrong on two counts: (1) ab_gp_db_route_connect_train()/_disconnect_train() only fire their own notify ONCE, at the genuine state transition - ab_gp_logic_connect_route_for_train()'s own idempotent already_assigned_to_this_train() check means a route already connected is a silent no-op on every later cycle, so nothing re-enqueues repeatedly; (2) the reset was unconditional on EVERY channel, including the currently-forwarding one - an event enqueued on a cycle where should_forward_to_c happened to be false that same cycle (e.g. ab_gp_channel_crosscompare.c's own routine per-train sync-skip window) was silently destroyed by the very next cycle's reset before this function ever got a chance to drain and send it - confirmed live via a real Docker run where "IL notified: route N connected" logged but the IL sim never received the matching TrainPositionInRoute. Instead, this queue simply accumulates (bounded by AB_GP_IL_MAX_PENDING_OUTPUTS' own drop-and-log ceiling below) until a cycle where this function actually runs and drains it - on the non-forwarding channel that may never happen while it stays non-forwarding, which is fine: those events would only become relevant if this channel is later promoted, at which point sending its accumulated history (in order) on first forwarding is correct, not stale.
| out | Destination array, AB_GP_IL_MAX_PENDING_OUTPUTS entries. Must not be NULL. |
out (0..AB_GP_IL_MAX_PENDING_OUTPUTS). Definition at line 233 of file ab_ga_il.c.
| 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 valid MA (ab_gp_train_set_has_ma()). Deliberately unaware of route identity/type - that half (resolving/creating the real ab_gp_db_route_t) is handle_route_add()'s own job (ab_ga_il.c, file-static) - this function stays the same narrow "train now has an MA" bookkeeping step it always was, kept public since ab_ga_il_apply_envelope()'s own ROUTE_ADD path still calls it alongside the newer route-identity handling.
train_id is not a currently-connected train; otherwise true. Definition at line 158 of file ab_ga_il.c.
| 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_ROUTE_DISCONNECTED - the only two IL cares about (see this file's own module doc). Was two separate GP-registered callbacks (il_on_route_connected/ _disconnected) - collapsed into this one dispatch-driven function on direct request, same rationale as ab_ga_ctc_on_route_context_changed()'s own doc.
GA's single dispatch module (safeAPIRBC2oo2GA/src/AB/main/ ab_ga_dispatch.c) is the ONLY thing that registers with GP now (interface-simplification pass) - it owns the ONE route-context subscription and fans AB_ROUTE_CONNECTED/_DISCONNECTED here. AB_ROUTE_ADDED/_STATUS_CHANGED are ignored (IL never cared about those).
GA's single dispatch module (ab_ga_dispatch.c) fans every route change here for AB_ROUTE_CONNECTED/AB_ROUTE_DISCONNECTED - the only two IL cares about (see this file's own module doc). Was two separate GP-registered callbacks (il_on_route_connected/ _disconnected) - collapsed into this one dispatch-driven function on direct request, same rationale as ab_ga_ctc_on_route_context_changed()'s own doc.
Movement Authority granting/shrinking lives HERE now (later session, on direct request: "route<->train connection is GP/GA's own
decision, based on train position - IL's own ROUTE_ADD/ROUTE_RELEASE
wire messages must not dictate which train a route grant applies to"). Previously handle_route_add()/handle_route_release() (this file's own file-static handlers) read env->train_id straight off the wire and granted/shrank MA directly, entirely bypassing GP's own position-based connect gate (ab_gp_logic_connect_routes_and_trains(), AB/GP/ma_logic/ab_gp_logic.c, which already ran every cycle independently, but used to only produce a cosmetic TrainPositionInRoute indication, never an actual MA change) and the registered route-connection VALIDATOR (validate_route_assignment(), AB/ma_logic_adaptation/ab_ga_ma_logic_adaptation.c) that gate is supposed to gate through. Now: handle_route_add() only tracks route existence (adds it to GP's own route table); handle_route_release() only untracks it. The actual MA grant/shrink happens HERE, in reaction to GP's own AB_ROUTE_CONNECTED/_DISCONNECTED notification - i.e. only once GP's position-based sweep has ACTUALLY connected (or disconnected) this route to a specific train, using ctx->train_id (GP's own real, tracked association - db->routes[].train_id, never anything IL supplied on the wire) and layout->length_m (this route's own known length, resolved by ctx->id - never a wire- supplied length either, on the same "IL doesn't dictate this" basis).
| sessions | This channel's own long-lived Train session table - needed now to grant/shrink MA on AB_ROUTE_CONNECTED/_DISCONNECTED (was previously only threaded through the route-connection validator, a different call path). |
| db | This channel's own Train/Route database (opaque) - forwarded to ab_gp_train_notify_context_changed()/ ab_ga_il_handle_route_add() below. |
| ctx | The route's own current-state snapshot - see that struct's own doc, ga_interface.h. |
| update_type | Which kind of change this is - only AB_ROUTE_CONNECTED/_DISCONNECTED are acted on. |
Definition at line 707 of file ab_ga_il.c.
| 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 wrapper over ga_interface.h's own ab_gp_db_route_add().
Definition at line 124 of file ab_ga_il.c.
| 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() (which fires GP's own route-connected notify on success).
| train_id | 1..SAFEAPI_EXAMPLE_MAX_TRAINS (same 1-based convention as ab_gp_train_session_t.train_id). |
route_id is not tracked, train_id is out of range, the route is already used_in_ma (call ab_ga_il_route_unassign_train() first - never silently reassigned), it is already in that same train's route_ids[], or that train's route_ids[] (SAFEAPI_EXAMPLE_MAX_ROUTES_PER_TRAIN) is full. Definition at line 148 of file ab_ga_il.c.
| 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.h's own ab_gp_db_route_remove().
route_id is not tracked, or it is still used_in_ma (call ab_ga_il_route_unassign_train() first - a route actively backing a train's Movement Authority is never silently dropped). Definition at line 133 of file ab_ga_il.c.
| 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_interface.h's own ab_gp_db_route_set_status(). Does not touch occupied (a separate, non-IL-sourced concept).
route_id is not tracked. Definition at line 138 of file ab_ga_il.c.
| 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_ROUTE_TYPE_FS/_OS/_SH, rbc_wire_types.h) for it - thin wrapper over ga_interface.h's own ab_gp_db_route_set_type().
route_id is not tracked. Definition at line 143 of file ab_ga_il.c.
| 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_disconnect_train().
route_id is not tracked, or it is not currently used_in_ma (nothing to unassign). Definition at line 153 of file ab_ga_il.c.
| 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 report the same start/end signals the layout itself has for that route id - ILSim is external, untrusted input (same REQ-RBC-002 "reject a malformed frame, don't index blind" posture already applied to wire input elsewhere in this project), so its own claimed signals are cross-checked against the site's own authoritative layout, not taken on faith.
Definition at line 113 of file ab_ga_il.c.
| 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_ga_track_layout, ab_site.h)?
| route_id | Route identity to look up. 0 always returns false (ab_gp_db.h/ab_site.h's own "no route" sentinel, never a real route id). |
| out_layout | If non-NULL and route_id is found, receives a pointer to that route's own static layout entry (owned by ab_site_ga_track_layout[], not the caller - never free()d). Left unmodified if not found. |
route_id is a real entry in this site's layout. Definition at line 71 of file ab_ga_il.c.
| 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, end_signal) pair exist in this site's own static track layout? Same shape as ab_ga_il_site_has_route() above, but by signal pair rather than synthetic id - the wire's own route-identity model (rbc_wire_types.h's own doc) - used to resolve an inbound ROUTE_ADD/ROUTE_RELEASE's own start_signal/end_signal fields to this site's internal route_id before touching db->routes[].
| out_layout | Same contract as ab_ga_il_site_has_route()'s own. |
Definition at line 93 of file ab_ga_il.c.
|
static |
Appends a route notification event to the pending queue.
Definition at line 657 of file ab_ga_il.c.
|
static |
Processes a dedicated RBC_MSG_IL_ROUTE_CMD (kind 25).
Route-tracking + per-route FSM only (same "IL does not pick which train" posture as handle_route_add()). Real transitions (NO_ROUTE/LOCKED/FS/USED, and release) maintain GP's route table so the position-based MA connect gate keeps working; STUB transitions (OS/SH/DEGRADED) are tracked + logged by the FSM, nothing else.
Definition at line 531 of file ab_ga_il.c.
|
static |
Processes a dedicated RBC_MSG_IL_STATUS (kind 26). Tracks IL health; a real hold/hold-off-trust reaction to DOWN/RESTARTING is stubbed (logged, not acted on).
Definition at line 637 of file ab_ga_il.c.
|
static |
Processes an inbound ROUTE_ADD command from Interlocking.
Route-tracking ONLY now (later session, on direct request: "route<->
train connection is GP/GA's own decision, based on train position -
IL's own ROUTE_ADD must not dictate which train a route grant applies
to"). This used to also grant Movement Authority directly to env->train_id - that entire responsibility moved to ab_ga_il_on_route_context_changed()'s own AB_ROUTE_CONNECTED handling (see that function's own header doc, ab_ga_il.h) - it now fires only once GP's own position-based connect gate (AB_GP_ma_logic/ab_gp_logic.c's own ab_gp_logic_connect_routes_and_trains(), which already ran every cycle independently of this handler) has actually connected this route to a real train, through the registered validator (validate_route_assignment(), ab_ga_ma_logic_adaptation.c). env's own train_id field is therefore deliberately never read here - a route becomes connectable to whichever train GP's own position match finds, not whichever train_id IL happened to put on the wire.
Definition at line 398 of file ab_ga_il.c.
|
static |
Processes an inbound ROUTE_RELEASE command from Interlocking.
Route-untracking ONLY now (later session, on direct request - same reasoning as handle_route_add()'s own updated doc). This used to also shrink/zero Movement Authority directly using env->train_id - that responsibility moved to ab_ga_il_on_route_context_changed()'s own AB_ROUTE_DISCONNECTED handling (ab_ga_il.h), which fires automatically, synchronously, from ab_ga_il_route_unassign_train() below (via GP's own ab_gp_db_route_disconnect_train() notify) - using the route's own REAL tracked train_id (captured by GP before it clears the association), never anything IL supplied on the wire. env's own train_id field is therefore deliberately never read here.
Definition at line 440 of file ab_ga_il.c.
|
static |
Handles IL's own Phase D periodic route-status broadcast (RBC_MSG_ROUTE_STATUS_REPORT, 2s cadence - see ILRBCSim/src/il/il_sim.py's own doc). Deliberately liveness-only for this first cut: logs receipt (proof IL's own cadence is actually reaching AB) without cross-checking @env's reported route_status against AB's own held-route state (ab_gp_db_route_t) - see this session's own plan doc for why that reconciliation is explicitly deferred, not an oversight. Does not touch @db at all - a report AB can't currently match to a known route (start_signal/end_signal not in this site's own layout) is still just logged, never treated as an error the way a real ROUTE_ADD/ROUTE_RELEASE for an unknown route would be, since this is a passive status feed, not a command.
Definition at line 511 of file ab_ga_il.c.
|
static |
Decodes an RBC envelope frame into an rbc_envelope_t structure.
| [in] | in | Raw wire bytes (RBC_ENVELOPE_WIRE_SIZE bytes). |
| [out] | out_env | Decoded envelope structure. |
Definition at line 285 of file ab_ga_il.c.
|
static |
Encodes a TRAIN_POSITION_IN_ROUTE envelope into raw wire bytes.
Definition at line 355 of file ab_ga_il.c.
|
static |
Definition at line 38 of file ab_ga_il.c.
|
extern |
GA-wide role tag, set once at ab_ga_ma_logic_adaptation_init() - see that file's own g_ga_role_tag definition. Used here for logging only, same as every other GA module.
Local makros Local types declarations Local variables declarations Global variables declarations
Definition at line 27 of file ab_ga_ma_logic_adaptation.c.
|
static |
Last IL health reported via RBC_MSG_IL_STATUS. GA-local: nothing outside this module consumes it yet - a DOWN/RESTARTING reaction (holding/refusing route trust) is stubbed, see handle_il_status().
Definition at line 50 of file ab_ga_il.c.
|
static |
Definition at line 45 of file ab_ga_il.c.
|
static |
Definition at line 44 of file ab_ga_il.c.