|
RTE RBC 2oo2 Reference Application 0.1.0 build 0006685
SIL 4 2oo2 Dual-Site Fault-Tolerant ERTMS Radio Block Centre Reference Architecture
|
A/B's own simplified Train/Route database - fixed-size arrays describing the domain objects logic/ (planned) will reason about when granting/extending a Movement Authority. More...
#include <stdbool.h>#include <stdint.h>#include "rte/utils/status/rte_status.h"#include "../../common/common_config.h"Go to the source code of this file.
Data Structures | |
| struct | ab_gp_db_route_t |
| One track section A/B's simplified layout knows about. More... | |
| struct | ab_gp_db_train_t |
| One train A/B's simplified database knows about. More... | |
| struct | ab_gp_db_t |
| struct | ab_gp_route_context_t |
Macros | |
| #define | AB_GP_DB_ROUTE_IL_STATUS_T_DEFINED |
| IL's own last-reported status for a route (planned - today's ILRBCSim only ever sends ROUTE_ADD, so LOCKED is the only value reachable in practice yet; the rest exist so logic/ has somewhere to put a richer IL status later without another struct-shape change). An enum, not a struct - GA sees this type in full (a closed set of named integers carries no layout to hide), unlike ab_gp_db_t below. | |
| #define | AB_GP_DB_T_DEFINED |
| A/B's whole simplified Train/Route database - fixed-size tables, one instance per channel (owned by whatever context logic/ ends up threading this through, same "caller-owned
storage, no hidden state" convention as ab_gp_channel_context_t - see ab_gp_channel_types.h). Tagged struct ab_gp_db_s (not an anonymous struct) specifically so it can be forward-declared elsewhere - see this file's own header doc. | |
Enumerations | |
| enum | ab_gp_db_route_il_status_t { AB_GP_DB_ROUTE_IL_STATUS_UNKNOWN = 0 , AB_GP_DB_ROUTE_IL_STATUS_FREE , AB_GP_DB_ROUTE_IL_STATUS_RESERVED , AB_GP_DB_ROUTE_IL_STATUS_LOCKED } |
Functions | |
Mechanical route<->train connect/disconnect (the "repository" | |
layer) Genuinely mechanical bookkeeping only - no business judgment (does this route exist, is it valid, should it be granted at all - that stays il/'s own concern, AB/GA/il/ab_ga_il.h's own ab_ga_il_route_verify()/_route_add()). This is the ONE place that mutates ab_gp_db_route_t.used_in_ma/train_id and ab_gp_db_train_t.route_ids[]/route_count together - moved here (this session's own GA/GP split) from what used to be il/'s own ab_ga_il_route_assign_train()/_unassign_train() bodies, which reached directly into these fields with no setter existing at all; il/'s own functions of the same name are now thin wrappers over these. Callers: AB/GP/ma_logic/ab_gp_logic.c's own ab_gp_logic_connect_route_for_train() (GP, after its own registered GA validator has approved), and il/'s own wrappers (unchanged real ROUTE_ADD wire path, AB/GA/il/ab_ga_il.c's ab_ga_il_apply_envelope()). | |
| bool | ab_gp_db_route_connect_train (ab_gp_db_t *db, uint16_t route_id, uint8_t train_id) |
Connects route_id to train_id: appends the route to that train's own route_ids[] and marks the route used_in_ma. | |
| bool | ab_gp_db_route_disconnect_train (ab_gp_db_t *db, uint16_t route_id) |
| Reverses ab_gp_db_route_connect_train(): clears the route's own used_in_ma/train_id and removes it from its owning train's route_ids[] (compacting the remaining entries down). | |
Route table getters/setters (the encapsulation boundary for GA) | |
Every field of ab_gp_db_route_t that AB/GA/il/ab_ga_il.c used to touch directly (before this session's own GA/GP opacity pass) now has its own accessor here - il/'s own route_add()/_remove()/_set_status() are thin wrappers over these, exactly like the connect/disconnect pair above. All take/return plain values, never a pointer into the table itself (no ab_gp_db_route_t * ever crosses into GA), so GA can only ever read a SNAPSHOT of a field or request a new value be written - never alias or hold a live reference into db->routes[]. | |
| bool | ab_gp_db_route_exists (const ab_gp_db_t *db, uint16_t route_id) |
| bool | ab_gp_db_route_add (ab_gp_db_t *db, uint16_t route_id, uint16_t start_signal, uint16_t end_signal) |
Adds a new route to db->routes[]. New entry starts fully idle: occupied=false, il_status=AB_GP_DB_ROUTE_IL_STATUS_UNKNOWN, used_in_ma=false, train_id=0. Purely mechanical - does NOT verify route_id/ site layout (that stays il/'s own business, ab_ga_il_route_verify(), called before this). | |
| bool | ab_gp_db_route_remove (ab_gp_db_t *db, uint16_t route_id) |
| Removes a tracked route from db->routes[], freeing its slot. | |
| bool | ab_gp_db_route_set_status (ab_gp_db_t *db, uint16_t route_id, ab_gp_db_route_il_status_t status) |
| bool | ab_gp_db_route_set_type (ab_gp_db_t *db, uint16_t route_id, uint32_t route_type) |
| bool | ab_gp_db_route_set_fsm_state (ab_gp_db_t *db, uint16_t route_id, uint32_t fsm_state) |
| Get/set the per-route FSM state (ab_ga_route_state_t, raw uint32_t - GA owns the value space, GP just stores it). | |
| uint32_t | ab_gp_db_route_get_fsm_state (const ab_gp_db_t *db, uint16_t route_id) |
| uint8_t | ab_gp_db_route_get_count (const ab_gp_db_t *db) |
| Returns total number of active routes currently in the GP database. | |
| bool | ab_gp_db_route_get_by_index (const ab_gp_db_t *db, uint8_t index, uint16_t *out_route_id, uint16_t *out_start_signal, uint16_t *out_end_signal, uint8_t *out_train_id, bool *out_used_in_ma) |
| Retrieves route snapshot by table index for GA/GP route list synchronization. | |
| bool | ab_gp_db_train_is_connected (const ab_gp_db_t *db, uint8_t train_id) |
| Checks if a train has an active connection session in the DB. | |
| bool | ab_gp_db_train_get_routes (const ab_gp_db_t *db, uint8_t train_id, uint16_t out_routes[RTE_EXAMPLE_MAX_ROUTES_PER_TRAIN], uint8_t *out_count) |
| Retrieves routes currently allocated to a train. | |
Database Wire Serialization & Deserialization (State Transfer) | |
| rte_status_t | ab_gp_db_encode (const ab_gp_db_t *db, uint8_t *out_bytes, uint32_t out_capacity, uint32_t *out_written) |
| Encodes the full route and train database into a deterministic wire format. | |
| rte_status_t | ab_gp_db_decode (ab_gp_db_t *db, const uint8_t *in_bytes, uint32_t in_size) |
| Decodes the full route and train database from a deterministic wire format. | |
GA notification - db/'s own single GP->GA route hook | |
db/ is the module that actually mutates db->routes[], so db/ is the module that notifies about it (same "whichever GP module performs a mutation is the one that fires the matching notify" rule AB/GP/train/ab_gp_train.h's own notify hook follows too). ONE subscription (ab_gp_db_register_route_context_notify() below) covers every route change (added/status-changed/connected/disconnected - see ab_gp_route_update_type_t's own doc) - collapsed from four separate registrations on direct instruction (the GP<->GA interface had grown too complicated: one callback typedef, one subscriber list, and one registration call site per event, most with zero real GA subscribers). Fan-out, fail-open (zero subscribers is fine - unlike AB/GP/ma_logic/ab_gp_logic.h's own route-connect VALIDATOR, this is observational, not a gate - that one stays its own, separate registration, since it needs a synchronous bool return to approve/veto a connection, which a fire-and-forget notify can't do). Setup-phase only (rte_lifecycle_check_setup_allowed()), same contract as every other registration function in this codebase - GA's own single dispatch module (safeAPIRBC2oo2GA/src/AB/main/ab_ga_dispatch.c) is the ONLY registrant, called once from its own _init(), itself called once from ab_gp_channel_ga_setup() (AB/GP/com/ab_gp_channel.c) - GP has no knowledge that il/ctc/logic exist as separate GA modules. | |
| #define | AB_GP_ROUTE_UPDATE_TYPE_T_DEFINED |
| What kind of change a single ab_gp_route_context_notify_fn call is reporting - see that typedef's own doc. Collapses what used to be four separate notify types (added/status/connected/ disconnected) into one subscription, on direct request - see this file's own module doc for the full rationale. | |
| #define | AB_GP_ROUTE_CONTEXT_T_DEFINED |
| A flat, fully-visible (NOT opaque, unlike ab_gp_db_t itself) snapshot of one route's current state - what ab_gp_route_context_notify_fn hands its subscriber. A copy, not a live pointer into db->routes[] - GA reads real struct fields directly (no getter calls needed), while still never touching GP's actual internal storage. | |
| #define | AB_GP_DB_ROUTE_NOTIFY_FN_DEFINED |
| #define | AB_GP_DB_MAX_ROUTE_CONTEXT_SUBSCRIBERS 4U |
| enum | ab_gp_route_update_type_t { AB_ROUTE_ADDED , AB_ROUTE_STATUS_CHANGED , AB_ROUTE_CONNECTED , AB_ROUTE_DISCONNECTED } |
| typedef void(*) | ab_gp_route_context_notify_fn(const void *context, const ab_gp_route_context_t *ctx, ab_gp_route_update_type_t update_type) |
| rte_status_t | ab_gp_db_register_route_context_notify (ab_gp_route_context_notify_fn fn, const void *context) |
| bool | ab_gp_db_get_route_context (const ab_gp_db_t *db, uint16_t route_id, ab_gp_route_context_t *out_ctx) |
One-shot pull equivalent of the push notification above - the SAME snapshot-building logic (real impl: ab_gp_db.c's own build_route_context(), shared with notify_route_context()), for a caller that just needs route_id's current state right now rather than reacting to a change. Replaces the individual ab_gp_db_route_get_status()/_get_used_in_ma()/_get_type() getters GA used to call one field at a time (later session, on direct request). Mutation still goes through the individual setters - this is READ-ONLY, deliberately. | |
A/B's own simplified Train/Route database - fixed-size arrays describing the domain objects logic/ (planned) will reason about when granting/extending a Movement Authority.
Deliberately separate from com/'s own ab_gp_train_session_t (ab_gp_channel_types.h): that struct is transport/cross-compare/ negotiation session bookkeeping (in_use, granted_length, ma_seq, the wire-encoded fields ab_gp_channel_negotiate.c carries across a STANDBY->ONLINE promotion) - this module is the track-layout domain model above it (which train has which route, what a route's own signals/occupancy/IL status are). com/ does not know this struct exists; a later pass wires the two together (logic/ reads both).
Fixed-size arrays only (RTE_EXAMPLE_MAX_TRAINS/_MAX_ROUTES/ _MAX_ROUTES_PER_TRAIN, common_config.h) - never a dynamic list, same convention as every other table in this project (CLAUDE.md: no malloc/free/realloc).
GA/GP encapsulation (this session's own addition): ab_gp_db_t is declared here with a real tag (struct ab_gp_db_s) specifically so AB/GP/ga_interface/ga_interface.h can forward-declare it as an INCOMPLETE type - GA (AB/GA/il/, AB/GA/ctc/) never includes this header and never sees ab_gp_db_route_t's/ab_gp_db_train_t's own field layout; it only ever holds/passes an ab_gp_db_t * and reads/writes through the getter/setter functions below, re-declared verbatim in ga_interface.h. This is enforced by the C type system, not just convention: GA's own translation units cannot compile a db->field expression at all, since they never see this struct's body.
Definition in file ab_gp_db.h.
| #define AB_GP_DB_ROUTE_IL_STATUS_T_DEFINED |
IL's own last-reported status for a route (planned - today's ILRBCSim only ever sends ROUTE_ADD, so LOCKED is the only value reachable in practice yet; the rest exist so logic/ has somewhere to put a richer IL status later without another struct-shape change). An enum, not a struct - GA sees this type in full (a closed set of named integers carries no layout to hide), unlike ab_gp_db_t below.
Definition at line 52 of file ab_gp_db.h.
| #define AB_GP_DB_T_DEFINED |
A/B's whole simplified Train/Route database - fixed-size tables, one instance per channel (owned by whatever context logic/ ends up threading this through, same "caller-owned storage, no hidden state" convention as ab_gp_channel_context_t - see ab_gp_channel_types.h). Tagged struct ab_gp_db_s (not an anonymous struct) specifically so it can be forward-declared elsewhere - see this file's own header doc.
Definition at line 131 of file ab_gp_db.h.
| #define AB_GP_ROUTE_UPDATE_TYPE_T_DEFINED |
What kind of change a single ab_gp_route_context_notify_fn call is reporting - see that typedef's own doc. Collapses what used to be four separate notify types (added/status/connected/ disconnected) into one subscription, on direct request - see this file's own module doc for the full rationale.
Definition at line 308 of file ab_gp_db.h.
| #define AB_GP_ROUTE_CONTEXT_T_DEFINED |
A flat, fully-visible (NOT opaque, unlike ab_gp_db_t itself) snapshot of one route's current state - what ab_gp_route_context_notify_fn hands its subscriber. A copy, not a live pointer into db->routes[] - GA reads real struct fields directly (no getter calls needed), while still never touching GP's actual internal storage.
Definition at line 329 of file ab_gp_db.h.
| #define AB_GP_DB_ROUTE_NOTIFY_FN_DEFINED |
Definition at line 345 of file ab_gp_db.h.
| #define AB_GP_DB_MAX_ROUTE_CONTEXT_SUBSCRIBERS 4U |
One subscriber (GA's own dispatch module) with headroom to spare.
Definition at line 358 of file ab_gp_db.h.
| typedef void(*) ab_gp_route_context_notify_fn(const void *context, const ab_gp_route_context_t *ctx, ab_gp_route_update_type_t update_type) |
Fired once per real route change (see ab_gp_route_update_type_t) with a snapshot of that route's CURRENT state - one subscription replaces what used to be four (added/status/connected/disconnected). GA's own dispatch module (safeAPIRBC2oo2GA/src/AB/main/ab_ga_dispatch.c) is the ONLY registrant; it fans out internally to whichever of GA's own modules (il/ctc) care about which update_type - GP has no knowledge that those are separate GA modules.
Definition at line 353 of file ab_gp_db.h.
Definition at line 53 of file ab_gp_db.h.
| Enumerator | |
|---|---|
| AB_ROUTE_ADDED | ab_gp_db_route_add() just added this route. |
| AB_ROUTE_STATUS_CHANGED | ab_gp_db_route_set_status() just changed il_status. |
| AB_ROUTE_CONNECTED | ab_gp_db_route_connect_train() just connected this route to ctx->train_id. |
| AB_ROUTE_DISCONNECTED | ab_gp_db_route_disconnect_train() just disconnected this route - ctx->train_id is the train it WAS connected to (captured before the disconnect cleared it), same identity a subscriber would have seen in the matching earlier AB_ROUTE_CONNECTED. |
Definition at line 309 of file ab_gp_db.h.
| bool ab_gp_db_route_connect_train | ( | ab_gp_db_t * | db, |
| uint16_t | route_id, | ||
| uint8_t | train_id ) |
Connects route_id to train_id: appends the route to that train's own route_ids[] and marks the route used_in_ma.
| db | AB's own Train/Route database. Must not be NULL. |
| route_id | Must already be tracked (db->routes[], e.g. via ab_gp_db_route_add() - this function does not add it). |
| train_id | 1..RTE_EXAMPLE_MAX_TRAINS. |
route_id is not tracked, train_id is out of range, the route is already used_in_ma (disconnect first, never silently reassigned), it is already in that same train's route_ids[], or that train's route_ids[] (RTE_EXAMPLE_MAX_ROUTES_PER_TRAIN) is full. true once connected. Definition at line 150 of file ab_gp_db.c.
| bool ab_gp_db_route_disconnect_train | ( | ab_gp_db_t * | db, |
| uint16_t | route_id ) |
Reverses ab_gp_db_route_connect_train(): clears the route's own used_in_ma/train_id and removes it from its owning train's route_ids[] (compacting the remaining entries down).
route_id is not tracked, or it is not currently used_in_ma (nothing to disconnect). Definition at line 197 of file ab_gp_db.c.
| bool ab_gp_db_route_exists | ( | const ab_gp_db_t * | db, |
| uint16_t | route_id ) |
route_id is already tracked in db->routes[]. Definition at line 253 of file ab_gp_db.c.
| bool ab_gp_db_route_add | ( | ab_gp_db_t * | db, |
| uint16_t | route_id, | ||
| uint16_t | start_signal, | ||
| uint16_t | end_signal ) |
Adds a new route to db->routes[]. New entry starts fully idle: occupied=false, il_status=AB_GP_DB_ROUTE_IL_STATUS_UNKNOWN, used_in_ma=false, train_id=0. Purely mechanical - does NOT verify route_id/ site layout (that stays il/'s own business, ab_ga_il_route_verify(), called before this). start_signal/ anyend_signal against
route_id is already tracked (call ab_gp_db_route_remove() first to replace it), or db->routes[] (RTE_EXAMPLE_MAX_ROUTES) is full. Definition at line 258 of file ab_gp_db.c.
| bool ab_gp_db_route_remove | ( | ab_gp_db_t * | db, |
| uint16_t | route_id ) |
Removes a tracked route from db->routes[], freeing its slot.
route_id is not tracked, or it is still used_in_ma (ab_gp_db_route_disconnect_train() first - a route actively backing a train's Movement Authority is never silently dropped). Definition at line 291 of file ab_gp_db.c.
| bool ab_gp_db_route_set_status | ( | ab_gp_db_t * | db, |
| uint16_t | route_id, | ||
| ab_gp_db_route_il_status_t | status ) |
route_id is not tracked; otherwise true with the field updated. Does not touch occupied (a separate, non-IL-sourced concept - see ab_gp_db_route_t's own doc). Definition at line 310 of file ab_gp_db.c.
| bool ab_gp_db_route_set_type | ( | ab_gp_db_t * | db, |
| uint16_t | route_id, | ||
| uint32_t | route_type ) |
route_id is not tracked; otherwise true with the field updated (rbc_route_type_t value, raw uint32_t) - IL's latest report always wins, no notify (route_type is not observed by anything yet - unlike il_status, which already has GA subscribers). Definition at line 335 of file ab_gp_db.c.
| bool ab_gp_db_route_set_fsm_state | ( | ab_gp_db_t * | db, |
| uint16_t | route_id, | ||
| uint32_t | fsm_state ) |
Get/set the per-route FSM state (ab_ga_route_state_t, raw uint32_t - GA owns the value space, GP just stores it).
route_id is not tracked, else true. get: the stored value, or AB_GA_ROUTE_STATE_NO_ROUTE (0) for an unknown route. Definition at line 347 of file ab_gp_db.c.
| uint32_t ab_gp_db_route_get_fsm_state | ( | const ab_gp_db_t * | db, |
| uint16_t | route_id ) |
Definition at line 359 of file ab_gp_db.c.
| uint8_t ab_gp_db_route_get_count | ( | const ab_gp_db_t * | db | ) |
Returns total number of active routes currently in the GP database.
Definition at line 375 of file ab_gp_db.c.
| bool ab_gp_db_route_get_by_index | ( | const ab_gp_db_t * | db, |
| uint8_t | index, | ||
| uint16_t * | out_route_id, | ||
| uint16_t * | out_start_signal, | ||
| uint16_t * | out_end_signal, | ||
| uint8_t * | out_train_id, | ||
| bool * | out_used_in_ma ) |
Retrieves route snapshot by table index for GA/GP route list synchronization.
Definition at line 395 of file ab_gp_db.c.
| bool ab_gp_db_train_is_connected | ( | const ab_gp_db_t * | db, |
| uint8_t | train_id ) |
Checks if a train has an active connection session in the DB.
Definition at line 435 of file ab_gp_db.c.
| bool ab_gp_db_train_get_routes | ( | const ab_gp_db_t * | db, |
| uint8_t | train_id, | ||
| uint16_t | out_routes[RTE_EXAMPLE_MAX_ROUTES_PER_TRAIN], | ||
| uint8_t * | out_count ) |
Retrieves routes currently allocated to a train.
Definition at line 444 of file ab_gp_db.c.
| rte_status_t ab_gp_db_register_route_context_notify | ( | ab_gp_route_context_notify_fn | fn, |
| const void * | context ) |
fn is NULL; RTE_STATUS_INVALID_STATE if the setup phase is already locked; RTE_STATUS_RESOURCE_EXHAUSTED if AB_GP_DB_MAX_ROUTE_CONTEXT_SUBSCRIBERS are already registered. Definition at line 25 of file ab_gp_db.c.
| bool ab_gp_db_get_route_context | ( | const ab_gp_db_t * | db, |
| uint16_t | route_id, | ||
| ab_gp_route_context_t * | out_ctx ) |
One-shot pull equivalent of the push notification above - the SAME snapshot-building logic (real impl: ab_gp_db.c's own build_route_context(), shared with notify_route_context()), for a caller that just needs route_id's current state right now rather than reacting to a change. Replaces the individual ab_gp_db_route_get_status()/_get_used_in_ma()/_get_type() getters GA used to call one field at a time (later session, on direct request). Mutation still goes through the individual setters - this is READ-ONLY, deliberately.
route_id is not tracked; otherwise true with *out_ctx fully populated. Definition at line 323 of file ab_gp_db.c.
| rte_status_t ab_gp_db_encode | ( | const ab_gp_db_t * | db, |
| uint8_t * | out_bytes, | ||
| uint32_t | out_capacity, | ||
| uint32_t * | out_written ) |
Encodes the full route and train database into a deterministic wire format.
| db | Database to encode. |
| out_bytes | Destination buffer. |
| out_capacity | Size of destination buffer (must be at least RTE_EXAMPLE_DB_WIRE_SIZE). |
| out_written | Bytes written. |
Definition at line 474 of file ab_gp_db.c.
| rte_status_t ab_gp_db_decode | ( | ab_gp_db_t * | db, |
| const uint8_t * | in_bytes, | ||
| uint32_t | in_size ) |
Decodes the full route and train database from a deterministic wire format.
| db | Destination database to populate. |
| in_bytes | Buffer containing wire format. |
| in_size | Size of buffer (must be at least RTE_EXAMPLE_DB_WIRE_SIZE). |
Definition at line 557 of file ab_gp_db.c.