|
RTE RBC 2oo2 Reference Application 0.1.0 build 0006685
SIL 4 2oo2 Dual-Site Fault-Tolerant ERTMS Radio Block Centre Reference Architecture
|
Train lifecycle/find/getters/setters against db/'s runtime table, AND the Train-domain wire codec (train_wire_decode()/ _encode() below) - see ab_gp_train.h. More...
#include "ab_gp_train.h"#include <stdio.h>#include "rte/utils/buffer/rte_buffer.h"#include "rte/utils/cast/rte_cast.h"#include "rte/utils/lifecycle/rte_lifecycle.h"#include "rte/oal/log/rte_log.h"#include "rte/oal/memory/rte_mem_util.h"#include "rte/utils/notify/rte_notify.h"#include "ab_siteGP.h"#include "../com/ab_gp_channel_payload.h"#include "../ertms_procedures/ab_gp_ertms_engine.h"#include "../ertms_procedures/ab_gp_proc_session.h"Go to the source code of this file.
Macros | |
| #define | TRAIN_WIRE_HEADER_SIZE 12U |
| #define | TRAIN_WIRE_CONTENT_SIZE_BASE 24U |
| #define | TRAIN_WIRE_CONTENT_SIZE_M146 (TRAIN_WIRE_CONTENT_SIZE_BASE + 4U) |
| #define | TRAIN_WIRE_CONTENT_SIZE_M136 (TRAIN_WIRE_CONTENT_SIZE_BASE + 4U + 40U) |
Functions | |
| RTE_DECLARE_CALLBACK_LIST (ab_gp_train_context_list_t, ab_gp_train_context_notify_fn, AB_GP_TRAIN_MAX_CONTEXT_SUBSCRIBERS) | |
| static bool | train_id_in_range (uint8_t train_id) |
| rte_status_t | ab_gp_register_train_context_notify (ab_gp_train_context_notify_fn fn, const void *context) |
| static bool | build_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) |
| static void | notify_train_context (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_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) |
| Explicit trigger GA calls (through ga_interface.h) once it has finished a multi-step train-context change it owns the sequencing of - a route grant/release (AB/GA/il/ab_ga_il.c's own handle_route_add()/handle_route_release(), which update granted_length/ma_seq/has_ma across several separate setter calls) being the only real case today. NOT fired automatically from any individual setter - see ab_gp_train_set_has_ma()'s own doc for why firing per-setter would either see a half-updated context or fire multiple times for one logical change. | |
| 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) |
One-shot pull equivalent of the push notification above - the SAME snapshot-building logic (real impl: ab_gp_train.c's own build_train_context(), shared with notify_train_context()), for a caller that just needs train_id's current state right now rather than reacting to a change. Replaces the individual ab_gp_train_session_get_*()/ab_gp_train_get_has_ma() getters GA used to call one field at a time (later session, on direct request - "it will be enough if GA can getTrainContext /
getRouteContext; setters stay separate since they require
validation"). Mutation still goes through the individual setters below - this is READ-ONLY, deliberately. | |
| static uint8_t | train_wire_nid_message_for_kind (rbc_msg_kind_t kind) |
| static uint16_t | train_wire_content_size_for_kind (rbc_msg_kind_t kind) |
| static void | train_wire_encode (uint8_t out[RBC_ENVELOPE_WIRE_SIZE], const rbc_envelope_t *env) |
| static bool | train_wire_decode (const uint8_t in[RBC_ENVELOPE_WIRE_SIZE], rbc_envelope_t *out_env) |
| static bool | nid_engine_connected_elsewhere (const ab_gp_db_t *db, uint8_t nid_engine, uint8_t exclude_train_id) |
| 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, has_ma=false, and an empty route_ids[]/route_count=0. | |
| 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. | |
| 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) |
| 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) |
| bool | ab_gp_train_set_nid_engine (ab_gp_db_t *db, uint8_t train_id, uint8_t nid_engine) |
| bool | ab_gp_train_set_has_ma (ab_gp_db_t *db, uint8_t train_id, bool has_ma) |
| 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_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 cyclic route-connect sweep reads (ab_gp_logic.h). | |
| 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-nid_engine stand-in caveat as that function's own doc. Idempotent (safe to call again for an already-connected train_id - just returns false, changes nothing, same as ab_gp_train_add() itself). | |
| 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 this is the first data seen for it (tolerates M136 arriving before/without a P0, same lenient posture com's own ctx->sessions[] handling takes), then records nid_lrbg via ab_gp_train_set_last_position() if it is nonzero (0 = no real balise reported this cycle, ab_gp_db.h's own sentinel - left unchanged rather than overwritten with "none"). | |
| 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_M15) directly into out. msg_type is RTE_EXAMPLE_MSG_M24 or _M15 (common_config.h) - the caller's own decision, not recomputed here. | |
| 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) directly into out (same contract as ab_gp_train_build_position_answer() above). | |
| static void | handle_envelope_p0 (ab_gp_train_session_t *session, ab_gp_train_session_t sessions[], ab_gp_db_t *db, const rbc_envelope_t *env, uint32_t cycle, rte_example_site_t site, const char *role_tag) |
| RBC_MSG_P0 handler: connect a new session, or no-op (logged at DEBUG) if already in use. | |
| static bool | handle_envelope_m136 (ab_gp_train_session_t *session, ab_gp_train_session_t sessions[], ab_gp_db_t *db, const rbc_envelope_t *env, uint32_t cycle, rte_example_site_t site, const char *role_tag, uint8_t idx, uint32_t cyc_msg_type_due[], bool cyc_position_reply_due[]) |
| RBC_MSG_M136 handler: record position, ack with M24. Sets have_channel_data. | |
| static void | handle_envelope_m146 (ab_gp_train_session_t *session, const rbc_envelope_t *env, uint32_t cycle, rte_example_site_t site, const char *role_tag) |
| RBC_MSG_M146 handler: ack the MA if the sequence number matches. | |
| static void | handle_envelope_disconnect (ab_gp_train_session_t *session, ab_gp_train_session_t sessions[], ab_gp_db_t *db, const rbc_envelope_t *env, uint32_t cycle, rte_example_site_t site, const char *role_tag) |
| RBC_MSG_TRAIN_DISCONNECT handler: release every held route, then remove the train. | |
| 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 Train relay channel (P0/M136/M146 - see site_config.h's own rte_example_relay_kind_t doc) - wire-decodes it (this module's own train_wire_decode(), ab_gp_train.c; the old shared rbc_wire_decode() is retired, see this file's own module doc), applies it to sessions (com's own cross-compare/state-transfer table) and to db, and computes the M24/M15 decision (including the D_LRBG fault-injection scenario) for an M136. com/'s ab_gp_channel.c contains no train-specific logic of its own after this - not even train_id bounds-checking or wire decode, both of which this function does itself (same posture every other entry point in this file already takes). | |
| 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's own "Outbound envelope
building" doc above for the two-layer split this sits on top of. Does not send anything and does not mutate sessions - com/'s ab_gp_channel_forward_to_c_if_needed() owns actually sending each built entry (ab_gp_channel_send_envelope_to_c()) and owns clearing session->ma_pending_send once both this function and AB/GA/ctc/ab_ga_ctc.h's own ab_ga_ctc_build_outputs() have each had their own chance to read it this cycle (the flag is genuinely shared between the two - see ab_gp_channel_forward_to_c_if_needed()'s own doc for why the coordinator, not either domain, clears it). | |
| bool | ab_gp_train_session_add_granted_length (ab_gp_train_session_t sessions[], uint8_t train_id, uint32_t delta) |
Adds delta to this session's own granted_length - exposed as an accumulating setter (not a plain set) since that is the only way il/'s own ROUTE_ADD handling ever changes this field. | |
| bool | ab_gp_train_session_set_granted_length (ab_gp_train_session_t sessions[], uint8_t train_id, uint32_t granted_length) |
| Sets this session's own granted_length directly. | |
| bool | ab_gp_train_session_increment_ma_seq (ab_gp_train_session_t sessions[], uint8_t train_id) |
| Increments this session's own ma_seq by 1 - exposed as an accumulating setter, same rationale as ab_gp_train_session_add_granted_length() above. | |
| bool | ab_gp_train_session_set_ma_pending_send (ab_gp_train_session_t sessions[], uint8_t train_id, bool pending) |
| bool | ab_gp_train_session_set_ma_acked (ab_gp_train_session_t sessions[], uint8_t train_id, bool acked) |
| 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_ctc_ma_granted_sent (ab_gp_train_session_t sessions[], uint8_t train_id, bool sent) |
| bool | ab_gp_train_session_set_ctc_ma_notify_pending (ab_gp_train_session_t sessions[], uint8_t train_id, bool pending) |
| static void | train_sessions_collector_encode (void *context, const void *items, uint8_t *out) |
| static void | train_sessions_collector_decode (void *context, const uint8_t *in, void *out_items) |
| 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/ab_gp_channel_payload.h's own ab_gp_channel_payload_register_collector()) - this module is ab_gp_train_session_t's own real owner, so it is the one that provides the whole-array wire packing/unpacking ab_gp_channel_payload_encode_collector()/_decode_collector() (and, via those, ab_gp_channel_payload_encode_ab_sample()/ _decode_ab_sample()) call for its own slice - the same registration pattern already used between GA and GP, applied here between two GP submodules instead. Setup-phase only, call once from ab_gp_channel_train_codec_setup() (AB/GP/com/ab_gp_channel.c), before any cycle that might touch the peer link can run. | |
| uint32_t | ab_gp_train_payload_collector_id (void) |
Variables | |
| static ab_gp_train_context_list_t | g_train_context_subscribers |
| static ab_gp_channel_payload_collector_id_t | g_train_payload_collector_id |
Train lifecycle/find/getters/setters against db/'s runtime table, AND the Train-domain wire codec (train_wire_decode()/ _encode() below) - see ab_gp_train.h.
Definition in file ab_gp_train.c.
| #define TRAIN_WIRE_HEADER_SIZE 12U |
Definition at line 170 of file ab_gp_train.c.
| #define TRAIN_WIRE_CONTENT_SIZE_BASE 24U |
Definition at line 171 of file ab_gp_train.c.
| #define TRAIN_WIRE_CONTENT_SIZE_M146 (TRAIN_WIRE_CONTENT_SIZE_BASE + 4U) |
Definition at line 172 of file ab_gp_train.c.
| #define TRAIN_WIRE_CONTENT_SIZE_M136 (TRAIN_WIRE_CONTENT_SIZE_BASE + 4U + 40U) |
Definition at line 173 of file ab_gp_train.c.
| RTE_DECLARE_CALLBACK_LIST | ( | ab_gp_train_context_list_t | , |
| ab_gp_train_context_notify_fn | , | ||
| AB_GP_TRAIN_MAX_CONTEXT_SUBSCRIBERS | ) |
|
static |
Defined further down this file - forward-declared here since notify_train_context() (below) needs it before its own real definition is reached.
Definition at line 345 of file ab_gp_train.c.
| rte_status_t ab_gp_register_train_context_notify | ( | ab_gp_train_context_notify_fn | fn, |
| const void * | context ) |
Definition at line 39 of file ab_gp_train.c.
|
static |
Builds train_id's own current-state snapshot (from BOTH sessions and db - a train's real state spans both tables, see ab_gp_train_session_t's own doc). Shared by notify_train_context() (push) and the public ab_gp_get_train_context() (pull) below - one builder, two ways to reach it (later session, on direct request: "it
will be enough if GA can getTrainContext/getRouteContext" - this is that pull path's own implementation).
Definition at line 73 of file ab_gp_train.c.
|
static |
Fires train_id's own current-state snapshot (build_train_context() above) to every subscriber - the ONE notify path every train-context-changing call now goes through (was two separate notify_registered()/notify_status() helpers - collapsed on direct request, see this file's own module doc).
Definition at line 122 of file ab_gp_train.c.
| 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 ) |
Explicit trigger GA calls (through ga_interface.h) once it has finished a multi-step train-context change it owns the sequencing of - a route grant/release (AB/GA/il/ab_ga_il.c's own handle_route_add()/handle_route_release(), which update granted_length/ma_seq/has_ma across several separate setter calls) being the only real case today. NOT fired automatically from any individual setter - see ab_gp_train_set_has_ma()'s own doc for why firing per-setter would either see a half-updated context or fire multiple times for one logical change.
| update_type | Always AB_TRAIN_MA_CHANGED today; the parameter exists so a future multi-step sequence (e.g. a real emergency-reaction handler) can reuse this same explicit-trigger mechanism instead of growing a new one. |
Definition at line 143 of file ab_gp_train.c.
| 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 ) |
One-shot pull equivalent of the push notification above - the SAME snapshot-building logic (real impl: ab_gp_train.c's own build_train_context(), shared with notify_train_context()), for a caller that just needs train_id's current state right now rather than reacting to a change. Replaces the individual ab_gp_train_session_get_*()/ab_gp_train_get_has_ma() getters GA used to call one field at a time (later session, on direct request - "it will be enough if GA can getTrainContext /
getRouteContext; setters stay separate since they require
validation"). Mutation still goes through the individual setters below - this is READ-ONLY, deliberately.
Definition at line 149 of file ab_gp_train.c.
|
static |
Definition at line 178 of file ab_gp_train.c.
|
static |
Definition at line 204 of file ab_gp_train.c.
|
static |
Encodes env into its RBC_ENVELOPE_WIRE_SIZE-byte MAXIMUM wire slot - see rbc_wire_types.h's own doc for the field layout this mirrors exactly. env->nid_message/l_message are calculated here from env->kind, not caller-supplied.
Definition at line 230 of file ab_gp_train.c.
|
static |
Decodes an RBC_ENVELOPE_WIRE_SIZE-byte wire slot - see rbc_wire_types.h's own doc.
in's own kind byte (REQ-RBC-001 revised/REQ-RBC-002) - a mismatch is rejected outright, never decoded with only some fields trusted. A kind this file does not otherwise recognize falls to train_wire_content_size_for_kind()'s own default content size (TRAIN_WIRE_CONTENT_SIZE_BASE) here, so it is only accepted at this layer if l_message happens to match that - the real, final rejection for an unrecognized-but-l_message-matching kind is the caller's own switch (ab_gp_train_apply_envelope()), whose default: case already logs and drops it. Definition at line 277 of file ab_gp_train.c.
|
static |
exclude_train_id, 0 = exclude none) already carries nid_engine - the same physical train can never occupy two slots at once (ab_gp_train_add()/_set_nid_engine()'s own doc). Definition at line 358 of file ab_gp_train.c.
| 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, has_ma=false, and an empty route_ids[]/route_count=0.
| train_id | 1..RTE_EXAMPLE_MAX_TRAINS. |
nid_engine is already connected in a DIFFERENT slot (the same physical train can never occupy two slots at once). Definition at line 374 of file ab_gp_train.c.
| 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.
Definition at line 406 of file ab_gp_train.c.
| 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.
| train_id | 1..RTE_EXAMPLE_MAX_TRAINS. |
Definition at line 428 of file ab_gp_train.c.
| 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.
| out_train_id | Receives the 1-based train_id if found. Left unmodified otherwise. |
Definition at line 441 of file ab_gp_train.c.
| bool ab_gp_train_is_connected | ( | const ab_gp_db_t * | db, |
| uint8_t | train_id ) |
Definition at line 459 of file ab_gp_train.c.
| bool ab_gp_train_get_nid_engine | ( | const ab_gp_db_t * | db, |
| uint8_t | train_id, | ||
| uint8_t * | out_nid_engine ) |
Definition at line 468 of file ab_gp_train.c.
| bool ab_gp_train_get_route_count | ( | const ab_gp_db_t * | db, |
| uint8_t | train_id, | ||
| uint8_t * | out_route_count ) |
Definition at line 478 of file ab_gp_train.c.
| bool ab_gp_train_set_nid_engine | ( | ab_gp_db_t * | db, |
| uint8_t | train_id, | ||
| uint8_t | nid_engine ) |
nid_engine is already connected in a different slot; otherwise true with the field updated. Definition at line 488 of file ab_gp_train.c.
| bool ab_gp_train_set_has_ma | ( | ab_gp_db_t * | db, |
| uint8_t | train_id, | ||
| bool | has_ma ) |
Definition at line 502 of file ab_gp_train.c.
| bool ab_gp_train_get_last_position | ( | const ab_gp_db_t * | db, |
| uint8_t | train_id, | ||
| uint32_t * | out_nid_lrbg ) |
Definition at line 522 of file ab_gp_train.c.
| 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 cyclic route-connect sweep reads (ab_gp_logic.h).
Definition at line 532 of file ab_gp_train.c.
| 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-nid_engine stand-in caveat as that function's own doc. Idempotent (safe to call again for an already-connected train_id - just returns false, changes nothing, same as ab_gp_train_add() itself).
Definition at line 542 of file ab_gp_train.c.
| 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 this is the first data seen for it (tolerates M136 arriving before/without a P0, same lenient posture com's own ctx->sessions[] handling takes), then records nid_lrbg via ab_gp_train_set_last_position() if it is nonzero (0 = no real balise reported this cycle, ab_gp_db.h's own sentinel - left unchanged rather than overwritten with "none").
Definition at line 547 of file ab_gp_train.c.
| 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_M15) directly into out. msg_type is RTE_EXAMPLE_MSG_M24 or _M15 (common_config.h) - the caller's own decision, not recomputed here.
| out | Destination, exactly RBC_ENVELOPE_WIRE_SIZE bytes. Must not be NULL. |
Definition at line 560 of file ab_gp_train.c.
| 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) directly into out (same contract as ab_gp_train_build_position_answer() above).
Definition at line 574 of file ab_gp_train.c.
|
static |
RBC_MSG_P0 handler: connect a new session, or no-op (logged at DEBUG) if already in use.
Definition at line 588 of file ab_gp_train.c.
|
static |
RBC_MSG_M136 handler: record position, ack with M24. Sets have_channel_data.
Definition at line 625 of file ab_gp_train.c.
|
static |
RBC_MSG_M146 handler: ack the MA if the sequence number matches.
Definition at line 695 of file ab_gp_train.c.
|
static |
RBC_MSG_TRAIN_DISCONNECT handler: release every held route, then remove the train.
Definition at line 707 of file ab_gp_train.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 Train relay channel (P0/M136/M146 - see site_config.h's own rte_example_relay_kind_t doc) - wire-decodes it (this module's own train_wire_decode(), ab_gp_train.c; the old shared rbc_wire_decode() is retired, see this file's own module doc), applies it to sessions (com's own cross-compare/state-transfer table) and to db, and computes the M24/M15 decision (including the D_LRBG fault-injection scenario) for an M136. com/'s ab_gp_channel.c contains no train-specific logic of its own after this - not even train_id bounds-checking or wire decode, both of which this function does itself (same posture every other entry point in this file already takes).
| sessions | com's own ab_gp_train_session_t table (RTE_EXAMPLE_MAX_TRAINS entries) - mutated in place. |
| db | AB's own Train/Route database - mutated in place via this file's own ab_gp_train_handle_connect()/ _handle_position_report(). |
| channel_index | Which Train[index] relay channel this envelope arrived on (0-based) - purely a defensive diagnostic cross-check against the decoded env.train_id (logged, not fatal, on a mismatch): routing itself is already fully structural (this IS the Train channel, by construction of the caller's own per-instance queue drain), so a mismatch here means a misconfigured sim/wrong port, not a misrouted envelope. |
| env_bytes | Raw wire bytes, exactly RBC_ENVELOPE_WIRE_SIZE - not yet decoded. |
| cycle | This AB cycle's own number (logging only). |
| is_role_a | Whether this channel is role A - only the M136 D_LRBG fault-injection scenario needs this. |
| site | This channel's own site (logging only). |
| role_tag | This channel's own "A/WEST" etc. tag (logging only). |
| cyc_msg_type_due | Per-train scratch array (RTE_EXAMPLE_MAX_TRAINS entries) - set for this envelope's own train_id if it was an M136 (the computed M24/M15 answer); left unmodified otherwise. |
| cyc_position_reply_due | Per-train scratch array, same size - set true alongside cyc_msg_type_due for an M136; left unmodified otherwise. |
Definition at line 749 of file ab_gp_train.c.
| 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's own "Outbound envelope
building" doc above for the two-layer split this sits on top of. Does not send anything and does not mutate sessions - com/'s ab_gp_channel_forward_to_c_if_needed() owns actually sending each built entry (ab_gp_channel_send_envelope_to_c()) and owns clearing session->ma_pending_send once both this function and AB/GA/ctc/ab_ga_ctc.h's own ab_ga_ctc_build_outputs() have each had their own chance to read it this cycle (the flag is genuinely shared between the two - see ab_gp_channel_forward_to_c_if_needed()'s own doc for why the coordinator, not either domain, clears it).
| sessions | com's own ab_gp_train_session_t table (RTE_EXAMPLE_MAX_TRAINS entries) - read-only. |
| cyc_msg_type_due | This cycle's own per-train scratch array (ab_gp_channel_read_channels()'s own output) - RTE_EXAMPLE_MSG_M24/_M15 per train with cyc_position_reply_due true. |
| cyc_position_reply_due | This cycle's own per-train scratch array - true if that train had a fresh M136 this cycle. |
| out | Destination array, AB_GP_TRAIN_MAX_PENDING_OUTPUTS entries. Must not be NULL. |
out (0..AB_GP_TRAIN_MAX_PENDING_OUTPUTS). Definition at line 809 of file ab_gp_train.c.
| bool ab_gp_train_session_add_granted_length | ( | ab_gp_train_session_t | sessions[], |
| uint8_t | train_id, | ||
| uint32_t | delta ) |
Adds delta to this session's own granted_length - exposed as an accumulating setter (not a plain set) since that is the only way il/'s own ROUTE_ADD handling ever changes this field.
train_id is out of range; otherwise true. Definition at line 848 of file ab_gp_train.c.
| bool ab_gp_train_session_set_granted_length | ( | ab_gp_train_session_t | sessions[], |
| uint8_t | train_id, | ||
| uint32_t | granted_length ) |
Sets this session's own granted_length directly.
train_id is out of range; otherwise true. Definition at line 858 of file ab_gp_train.c.
| bool ab_gp_train_session_increment_ma_seq | ( | ab_gp_train_session_t | sessions[], |
| uint8_t | train_id ) |
Increments this session's own ma_seq by 1 - exposed as an accumulating setter, same rationale as ab_gp_train_session_add_granted_length() above.
train_id is out of range; otherwise true. Definition at line 870 of file ab_gp_train.c.
| bool ab_gp_train_session_set_ma_pending_send | ( | ab_gp_train_session_t | sessions[], |
| uint8_t | train_id, | ||
| bool | pending ) |
train_id is out of range; otherwise true with the field updated. Definition at line 882 of file ab_gp_train.c.
| bool ab_gp_train_session_set_ma_acked | ( | ab_gp_train_session_t | sessions[], |
| uint8_t | train_id, | ||
| bool | acked ) |
train_id is out of range; otherwise true with the field updated. Definition at line 892 of file ab_gp_train.c.
| bool ab_gp_train_session_set_ctc_connected_sent | ( | ab_gp_train_session_t | sessions[], |
| uint8_t | train_id, | ||
| bool | sent ) |
train_id is out of range; otherwise true with the field updated. Definition at line 905 of file ab_gp_train.c.
| bool ab_gp_train_session_set_ctc_ma_granted_sent | ( | ab_gp_train_session_t | sessions[], |
| uint8_t | train_id, | ||
| bool | sent ) |
train_id is out of range; otherwise true with the field updated. Definition at line 917 of file ab_gp_train.c.
| bool ab_gp_train_session_set_ctc_ma_notify_pending | ( | ab_gp_train_session_t | sessions[], |
| uint8_t | train_id, | ||
| bool | pending ) |
train_id is out of range; otherwise true with the field updated - see ab_gp_train_session_t's own doc on why this is a SEPARATE flag from ma_pending_send. Definition at line 934 of file ab_gp_train.c.
|
static |
This module's own registered payload-collector encoder (see ab_gp_train_init()) - packs every RTE_EXAMPLE_MAX_TRAINS ab_gp_train_session_t into its own slice of the combined A<->B payload, RTE_EXAMPLE_TRAIN_SESSION_WIRE_SIZE bytes per session; the loop and field layout are entirely this module's own concern - AB/GP/com/ab_gp_channel_payload.c never sees a ab_gp_train_session_t. context is unused (always NULL, see ab_gp_train_init()).
Definition at line 951 of file ab_gp_train.c.
|
static |
This module's own registered payload-collector decoder (see ab_gp_train_init()) - see train_sessions_collector_encode()'s own doc. ma_pending_send is deliberately left false (not on the wire) - see ab_gp_train_session_t's own doc. On a malformed/short slot (should never happen - each slot is always exactly RTE_EXAMPLE_TRAIN_SESSION_WIRE_SIZE bytes here), that session's fields are left at their all-zero/false state, same fail-safe posture ab_gp_channel_payload_decode_ab_sample()'s own overall contract takes.
Definition at line 983 of file ab_gp_train.c.
| 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/ab_gp_channel_payload.h's own ab_gp_channel_payload_register_collector()) - this module is ab_gp_train_session_t's own real owner, so it is the one that provides the whole-array wire packing/unpacking ab_gp_channel_payload_encode_collector()/_decode_collector() (and, via those, ab_gp_channel_payload_encode_ab_sample()/ _decode_ab_sample()) call for its own slice - the same registration pattern already used between GA and GP, applied here between two GP submodules instead. Setup-phase only, call once from ab_gp_channel_train_codec_setup() (AB/GP/com/ab_gp_channel.c), before any cycle that might touch the peer link can run.
Definition at line 1025 of file ab_gp_train.c.
| uint32_t ab_gp_train_payload_collector_id | ( | void | ) |
Definition at line 1032 of file ab_gp_train.c.
|
static |
Definition at line 37 of file ab_gp_train.c.
|
static |
Definition at line 1023 of file ab_gp_train.c.