SafeAPI RBC 2oo2 Generic Application
IL/CTC route and train logic for the safeAPIRBC2oo2 reference RBC
Loading...
Searching...
No Matches
ab_ga_ctc.c File Reference

Builds outbound CTC_CONNECTED/CTC_MA_GRANTED/CTC_MA_EXTENDED envelopes, AND the CTC-domain wire codec (ctc_wire_encode() below) - see ab_ga_ctc.h. More...

#include "ab_ga_ctc.h"
#include "safeapi/utils/buffer/sapi_buffer.h"
#include "safeapi/oal/memory/sapi_mem_util.h"
#include "common_config.h"
#include "ga_interface.h"
#include "ab_siteGA.h"
Include dependency graph for ab_ga_ctc.c:

Go to the source code of this file.

Macros

#define CTC_WIRE_HEADER_SIZE   12U
#define CTC_WIRE_CONTENT_SIZE_BASE   24U

Functions

static void ctc_wire_encode (uint8_t out[RBC_ENVELOPE_WIRE_SIZE], const rbc_envelope_t *env)
static void compute_train_info_signals (const uint16_t route_ids[SAFEAPI_EXAMPLE_MAX_ROUTES_PER_TRAIN], uint8_t route_count, uint32_t d_lrbg, uint16_t *out_front_signal, uint32_t *out_dist_to_front, uint16_t *out_target_signal)
void ab_ga_ctc_build_connected (uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t train_id, uint32_t d_lrbg)
 Builds and wire-encodes the outbound CTC_CONNECTED indication for train_id (kind=RBC_MSG_CTC_CONNECTED) directly into out - sent once, the first time a train's session becomes known (GP's own ctc_connected_sent latch, read/written via ga_interface.h). Wire-encoding is this module's own (ctc_wire_encode(), ab_ga_ctc.c, file-static) - the old shared rbc_wire_encode() is retired.
void ab_ga_ctc_build_ma_granted (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 CTC_MA_GRANTED indication for train_id (kind=RBC_MSG_CTC_MA_GRANTED) directly into out - sent the first time a route is granted for this train (GP's own ctc_ma_granted_sent latch); every grant after that is ab_ga_ctc_build_ma_extended() instead. Same contract as ab_ga_ctc_build_connected() above.
void ab_ga_ctc_build_ma_extended (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 CTC_MA_EXTENDED indication for train_id (kind=RBC_MSG_CTC_MA_EXTENDED) directly into out - see ab_ga_ctc_build_ma_granted()'s own doc for the granted/extended split. Same contract as ab_ga_ctc_build_connected() above.
void ab_ga_ctc_build_train_info (uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t train_id, uint32_t d_lrbg, uint32_t ma_seq, uint32_t granted_length, bool ma_granted, uint16_t front_signal, uint32_t dist_to_front_signal, uint16_t target_signal, uint32_t nid_lrbg, uint32_t v_train, uint32_t m_mode)
 Builds and wire-encodes a severity-leveled operational alarm (kind=RBC_MSG_CTC_ALARM) directly into out - see that kind's own doc in rbc_wire_types.h. Unlike ab_ga_ctc_build_connected()/_ma_granted()/_ma_extended() above, this is not part of the per-cycle ab_ga_ctc_build_outputs() pipeline - see ga_interface.h/AB/GP/main/ab_gp_ga_hooks.h's own ab_gp_build_ctc_alarm() instead: raising an alarm moved to be GP's own API entirely (later session, on direct request) - it's GP's own decision to raise one, not something that needs a GA round trip, so this module no longer owns it.
uint8_t ab_ga_ctc_build_outputs (ab_gp_train_session_t *sessions, ab_gp_db_t *db, ab_gp_ctc_pending_output_t out[AB_GP_CTC_MAX_PENDING_OUTPUTS])
 Decides which trains need a CTC indication THIS cycle and builds all of them - see this file's own module doc above for the two-layer split this sits on top of. Mutates sessions in place (ctc_connected_sent/ctc_ma_granted_sent - GP's own sticky latches, written via ga_interface.h's own setters) but does NOT clear ma_pending_send - see AB/GP/train/ab_gp_train.h's ab_gp_train_build_outputs()'s own doc for why the coordinator (com/'s ab_gp_channel_forward_to_c_if_needed()), not either domain, clears that shared flag. Does not send anything itself - ab_gp_channel_forward_to_c_if_needed() owns actually sending each built entry (ab_gp_channel_send_envelope_to_c()).
void ab_ga_ctc_on_route_context_changed (const ab_gp_route_context_t *ctx, ab_gp_route_update_type_t update_type)
 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 here (the only kind CTC ever logged - see this file's own module doc). CTC has no route validator of its own - it never has veto authority over a route<->train connection, only observes the fact once made.
void ab_ga_ctc_on_train_context_changed (const ab_gp_train_context_t *ctx, ab_gp_train_update_type_t update_type)
 GA's dispatch module fans every train-context change here - stores the received snapshot and marks this train as needing a fresh CTC_TRAIN_INFO next cycle (drained by ab_ga_ctc_build_outputs() below). Replaces the old per-cycle poll+diff scan against GP's own session getters entirely - interface-simplification pass, see this file's own module doc.

Variables

static bool g_train_info_pending [SAFEAPI_EXAMPLE_MAX_TRAINS]
static ab_gp_train_context_t g_last_train_ctx [SAFEAPI_EXAMPLE_MAX_TRAINS]
static bool g_train_ctx_known [SAFEAPI_EXAMPLE_MAX_TRAINS]

Detailed Description

Builds outbound CTC_CONNECTED/CTC_MA_GRANTED/CTC_MA_EXTENDED envelopes, AND the CTC-domain wire codec (ctc_wire_encode() below) - see ab_ga_ctc.h.

Definition in file ab_ga_ctc.c.

Macro Definition Documentation

◆ CTC_WIRE_CONTENT_SIZE_BASE

#define CTC_WIRE_CONTENT_SIZE_BASE   24U

Definition at line 29 of file ab_ga_ctc.c.

◆ CTC_WIRE_HEADER_SIZE

#define CTC_WIRE_HEADER_SIZE   12U

Local makros CTC-domain wire codec - own copy of the fixed-offset RBC envelope layout (REQ-RBC-001 revised), same "duplicated per domain, must stay byte-for-byte identical to every other domain's own copy and to SimCore's Python mirror" posture as ab_gp_train.c's own copy (see that file's own doc for why). CTC is send-only (ab_ga_ctc.h's own doc), so unlike ab_gp_train.c this file needs no decode side. All three CTC kinds use the base content length (nid_message has no real Subset-026 counterpart for any of them).

Definition at line 28 of file ab_ga_ctc.c.

Function Documentation

◆ ab_ga_ctc_build_connected()

void ab_ga_ctc_build_connected ( uint8_t out[RBC_ENVELOPE_WIRE_SIZE],
uint8_t train_id,
uint32_t d_lrbg )

Builds and wire-encodes the outbound CTC_CONNECTED indication for train_id (kind=RBC_MSG_CTC_CONNECTED) directly into out - sent once, the first time a train's session becomes known (GP's own ctc_connected_sent latch, read/written via ga_interface.h). Wire-encoding is this module's own (ctc_wire_encode(), ab_ga_ctc.c, file-static) - the old shared rbc_wire_encode() is retired.

Global functions

Parameters
outDestination, exactly RBC_ENVELOPE_WIRE_SIZE bytes. Must not be NULL.

Definition at line 92 of file ab_ga_ctc.c.

◆ ab_ga_ctc_build_ma_extended()

void ab_ga_ctc_build_ma_extended ( 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 CTC_MA_EXTENDED indication for train_id (kind=RBC_MSG_CTC_MA_EXTENDED) directly into out - see ab_ga_ctc_build_ma_granted()'s own doc for the granted/extended split. Same contract as ab_ga_ctc_build_connected() above.

Definition at line 116 of file ab_ga_ctc.c.

◆ ab_ga_ctc_build_ma_granted()

void ab_ga_ctc_build_ma_granted ( 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 CTC_MA_GRANTED indication for train_id (kind=RBC_MSG_CTC_MA_GRANTED) directly into out - sent the first time a route is granted for this train (GP's own ctc_ma_granted_sent latch); every grant after that is ab_ga_ctc_build_ma_extended() instead. Same contract as ab_ga_ctc_build_connected() above.

Definition at line 103 of file ab_ga_ctc.c.

◆ ab_ga_ctc_build_outputs()

uint8_t ab_ga_ctc_build_outputs ( ab_gp_train_session_t * sessions,
ab_gp_db_t * db,
ab_gp_ctc_pending_output_t out[AB_GP_CTC_MAX_PENDING_OUTPUTS] )

Decides which trains need a CTC indication THIS cycle and builds all of them - see this file's own module doc above for the two-layer split this sits on top of. Mutates sessions in place (ctc_connected_sent/ctc_ma_granted_sent - GP's own sticky latches, written via ga_interface.h's own setters) but does NOT clear ma_pending_send - see AB/GP/train/ab_gp_train.h's ab_gp_train_build_outputs()'s own doc for why the coordinator (com/'s ab_gp_channel_forward_to_c_if_needed()), not either domain, clears that shared flag. Does not send anything itself - ab_gp_channel_forward_to_c_if_needed() owns actually sending each built entry (ab_gp_channel_send_envelope_to_c()).

The pending-output element type/capacity this module fills (ab_gp_ctc_pending_output_t/AB_GP_CTC_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).

Parameters
sessionsGP's own ab_gp_train_session_t table (opaque to this module) (SAFEAPI_EXAMPLE_MAX_TRAINS entries) - mutated in place via ga_interface.h's own setters.
dbGP's own route/train database (opaque to this module)
  • needed to compute CTC_TRAIN_INFO's front/target signal via ab_gp_db_train_get_routes() (ga_interface.h) and ab_siteGA.h's own static route table. Every other output built here needs no db access, hence this parameter being new rather than always present.
outDestination array, AB_GP_CTC_MAX_PENDING_OUTPUTS entries. Must not be NULL.
Returns
the number of entries actually filled in out (0..AB_GP_CTC_MAX_PENDING_OUTPUTS).

Definition at line 169 of file ab_ga_ctc.c.

◆ ab_ga_ctc_build_train_info()

void ab_ga_ctc_build_train_info ( uint8_t out[RBC_ENVELOPE_WIRE_SIZE],
uint8_t train_id,
uint32_t d_lrbg,
uint32_t ma_seq,
uint32_t granted_length,
bool ma_granted,
uint16_t front_signal,
uint32_t dist_to_front_signal,
uint16_t target_signal,
uint32_t nid_lrbg,
uint32_t v_train,
uint32_t m_mode )

Builds and wire-encodes a severity-leveled operational alarm (kind=RBC_MSG_CTC_ALARM) directly into out - see that kind's own doc in rbc_wire_types.h. Unlike ab_ga_ctc_build_connected()/_ma_granted()/_ma_extended() above, this is not part of the per-cycle ab_ga_ctc_build_outputs() pipeline - see ga_interface.h/AB/GP/main/ab_gp_ga_hooks.h's own ab_gp_build_ctc_alarm() instead: raising an alarm moved to be GP's own API entirely (later session, on direct request) - it's GP's own decision to raise one, not something that needs a GA round trip, so this module no longer owns it.

Builds and wire-encodes the outbound CTC_TRAIN_INFO indication for train_id (kind=RBC_MSG_CTC_TRAIN_INFO) directly into out - see that kind's own doc in rbc_wire_types.h for the generic-field-reuse layout. Pure encode, no computation and no gating - front_signal/dist_to_front_signal/ target_signal are caller-computed (ab_ga_ctc_build_outputs() below owns that, via its own file-static route-chain walk).

Parameters
d_lrbgTrain's current reported position.
ma_seqThis train's real MA sequence number.
granted_lengthCumulative MA length granted, meters - used only to derive the signed MA offset (d_lrbg - granted_length) stored in the wire's ma_length slot.
ma_grantedTrue if this train currently has any MA (ma_status wire field).
front_signalEarliest not-yet-reached held-route boundary's end_signal, 0 if none.
dist_to_front_signalDistance to that boundary, meters.
target_signalend_signal of the last held route (the far end of the current MA), 0 if none.
nid_lrbgThis train's own last relevant balise group id (d_lrbg is relative to this) - appended after ma_length, not a reused generic slot - see ctc_wire_encode()'s own doc for why.
v_trainLast reported train speed (M136's own v_train), appended the same way.
m_modeLast reported ETCS mode (M136's own m_mode), appended the same way.
outDestination, exactly RBC_ENVELOPE_WIRE_SIZE bytes. Must not be NULL.

Definition at line 132 of file ab_ga_ctc.c.

◆ ab_ga_ctc_on_route_context_changed()

void ab_ga_ctc_on_route_context_changed ( const ab_gp_route_context_t * ctx,
ab_gp_route_update_type_t update_type )

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 here (the only kind CTC ever logged - see this file's own module doc). CTC has no route validator of its own - it never has veto authority over a route<->train connection, only observes the fact once made.

Definition at line 264 of file ab_ga_ctc.c.

◆ ab_ga_ctc_on_train_context_changed()

void ab_ga_ctc_on_train_context_changed ( const ab_gp_train_context_t * ctx,
ab_gp_train_update_type_t update_type )

GA's dispatch module fans every train-context change here - stores the received snapshot and marks this train as needing a fresh CTC_TRAIN_INFO next cycle (drained by ab_ga_ctc_build_outputs() below). Replaces the old per-cycle poll+diff scan against GP's own session getters entirely - interface-simplification pass, see this file's own module doc.

Definition at line 278 of file ab_ga_ctc.c.

◆ compute_train_info_signals()

void compute_train_info_signals ( const uint16_t route_ids[SAFEAPI_EXAMPLE_MAX_ROUTES_PER_TRAIN],
uint8_t route_count,
uint32_t d_lrbg,
uint16_t * out_front_signal,
uint32_t * out_dist_to_front,
uint16_t * out_target_signal )
static

Walks the given held-route chain (ab_siteGA.h's own static prev_route_id/next_route_id links, not route_ids' own array order - see this function's own body for why) to find the front signal (earliest not-yet-reached route boundary) and the MA target signal (end of the last held route) - RBC_MSG_CTC_TRAIN_INFO's own route-boundary-only front-signal design, see that kind's own doc in rbc_wire_types.h. All three out-params are set to 0 if route_count is 0 (or the held-route data can't be resolved against the static table).

Parameters
route_ids/

param route_count This train's currently-held routes - the caller's own ab_gp_train_context_t snapshot (ctx->route_ids/ctx->route_count) now, not a fresh ab_gp_db_train_get_routes() query - that getter is gone from this facade (later session, on direct request) and this data was already sitting in the stored snapshot the caller reads from anyway.

Definition at line 343 of file ab_ga_ctc.c.

◆ ctc_wire_encode()

void ctc_wire_encode ( uint8_t out[RBC_ENVELOPE_WIRE_SIZE],
const rbc_envelope_t * env )
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 437 of file ab_ga_ctc.c.

Variable Documentation

◆ g_last_train_ctx

ab_gp_train_context_t g_last_train_ctx[SAFEAPI_EXAMPLE_MAX_TRAINS]
static

Definition at line 62 of file ab_ga_ctc.c.

◆ g_train_ctx_known

bool g_train_ctx_known[SAFEAPI_EXAMPLE_MAX_TRAINS]
static

True once at least one context has ever been received for this train - forces the first CTC_TRAIN_INFO send (there is no prior value to compare against yet) - see ab_ga_ctc_on_train_context_changed()'s own doc.

Definition at line 67 of file ab_ga_ctc.c.

◆ g_train_info_pending

bool g_train_info_pending[SAFEAPI_EXAMPLE_MAX_TRAINS]
static

Local types declarations Local variables declarations Global variables declarations Local function declarations GP's own registered route-connected subscriber (see ab_ga_ctc_init(), ga_interface.h's own ab_gp_db_register_route_connected_notify()) - GP's db/ calls this once a route<->train connection has actually been made. Log-only today - CTC has no wire kind for "route connected" distinct from CTC_MA_GRANTED/_MA_EXTENDED (rbc_msg_kind_t, rbc_wire_types.h), and this session's own design decision keeps GP's position-inferred connect a separate, additive notification that does NOT drive real MA-granting (AB/GA/il/ab_ga_il.c's own ab_ga_il_apply_envelope(), unaffected) - a real, working observability seam for future CTC-side reactions, not empty scaffolding. context is the role_tag passed to ab_ga_ctc_init(). Per-train "does GP's own push notification say we need to (re)send CTC_TRAIN_INFO this cycle" flag + the last-received context snapshot to build it from - GA-internal, module-private storage (not exposed via the interface). Set by ab_ga_ctc_on_train_context_changed() (called from GA's own dispatch module on every real train change), drained by ab_ga_ctc_build_outputs() below - replaces the old per-cycle poll+diff scan entirely (interface-simplification pass, see this file's own module doc).

Definition at line 61 of file ab_ga_ctc.c.