|
RTE RBC 2oo2 Reference Application 0.1.0 build 0006685
SIL 4 2oo2 Dual-Site Fault-Tolerant ERTMS Radio Block Centre Reference Architecture
|
Event-driven legal-transition table for ab_gp_ertms_session_state_t (Subset-026 Chapter 5's various procedure states) - GP's first per-entity state machine under state_machines/ (one folder per entity: session/ here, train_data/ next; ma/, shunting/, emergency_stop/, route/, tsr/, boundary/ as they get the same treatment). All of them are fed by ab_gp_dispatch() (../ab_gp_dispatch.h) - a synchronous static event dispatcher whose one const subscription table says which FSM(s) react to each ab_gp_event_t (../ab_gp_event.h). A procedure raises an event through ab_gp_dispatch(); it never names an FSM. More...
Go to the source code of this file.
Typedefs | |
| typedef ab_gp_event_t | ab_gp_session_event_t |
| The events this state machine reacts to are the leading (session-lifecycle) block of the shared ab_gp_event_t vocabulary. | |
Functions | |
| bool | ab_gp_session_fsm_can_handle (ab_gp_ertms_session_state_t from, ab_gp_session_event_t event, ab_gp_ertms_session_state_t *out_to) |
| Read-only lookup, no side effect: what event does from a given state produce, if anything. | |
| bool | ab_gp_session_fsm_handle_event (ab_gp_ertms_train_context_t *ctx, ab_gp_session_event_t event) |
| Applies event to ctx->session_state. | |
Event-driven legal-transition table for ab_gp_ertms_session_state_t (Subset-026 Chapter 5's various procedure states) - GP's first per-entity state machine under state_machines/ (one folder per entity: session/ here, train_data/ next; ma/, shunting/, emergency_stop/, route/, tsr/, boundary/ as they get the same treatment). All of them are fed by ab_gp_dispatch() (../ab_gp_dispatch.h) - a synchronous static event dispatcher whose one const subscription table says which FSM(s) react to each ab_gp_event_t (../ab_gp_event.h). A procedure raises an event through ab_gp_dispatch(); it never names an FSM.
Design, per direct request: a state machine is a table of (state, EVENT) -> next state, not (state, next-state-the-caller-already-picked) -> legal?. A caller (an ertms_procedures/ file) never chooses a target state itself - it fires a named event describing WHAT HAPPENED (a message arrived, GA changed a route's status, a timer expired), and this table alone decides whether that event does anything from the current state, and if so, what the resulting state is. That keeps "what can event E do from state S" answerable by reading ONE table (s_table[][] below) instead of tracing every procedure file to find every place that might request a given state - the actual concrete problem prompting this design: v1 of this file (ab_gp_ertms_fsm.h, since renamed/rewritten) let a caller pick ANY target and only checked legality, which still left "what triggers FS" spread across ab_gp_proc_ma.c's own call site rather than in this table.
Functions take the relevant context struct as a plain parameter - state machine as functions operating ON a context, not an object with methods - by design.
Emergency-stop entry (AB_GP_SESSION_EVENT_EMERGENCY_STOP_ISSUED) is legal from EVERY state (including a self-transition, re-issuing while already active) - the actual, load-bearing safety property of "an emergency stop command must never be rejectable by a bug or edge case in session-lifecycle bookkeeping" is preserved, just made explicit in the table instead of being an accident of "no guard existed" (v1's own finding). Termination (AB_GP_SESSION_EVENT_SESSION_TERMINATED, -> IDLE) is likewise legal from every state including IDLE itself (defensive re-termination must stay idempotent) for the same reason - a caller must always be able to tear a session down.
Revoking an emergency stop can restore one of three different states (FS/STANDBY/ESTABLISHED) depending on what the train had before it - ab_gp_proc_emergency_stop_revoke() already computes which case applies (ctx->ma.has_active_ma / ctx->train_data.valid), so it fires the matching one of three distinct events rather than this table peeking at those fields itself - the table stays domain-agnostic about everything except the state field itself, per this whole design's own point.
Definition in file ab_gp_session_fsm.h.
| typedef ab_gp_event_t ab_gp_session_event_t |
The events this state machine reacts to are the leading (session-lifecycle) block of the shared ab_gp_event_t vocabulary.
The enum moved to ab_gp_event.h (one shared vocabulary for every state_machines/ FSM) when GP's procedures were put behind the ab_gp_dispatch() synchronous static dispatcher - see that header's own doc. Events past AB_GP_SESSION_EVENT_COUNT belong to other procedures' FSMs; ab_gp_session_fsm_can_handle()'s own range check already rejects them here (returns "not handled"), so the session table stays exactly its original 9 x AB_GP_SESSION_EVENT_COUNT shape.
Definition at line 81 of file ab_gp_session_fsm.h.
| bool ab_gp_session_fsm_can_handle | ( | ab_gp_ertms_session_state_t | from, |
| ab_gp_session_event_t | event, | ||
| ab_gp_ertms_session_state_t * | out_to ) |
Read-only lookup, no side effect: what event does from a given state produce, if anything.
| [in] | from | Current state. |
| [in] | event | Event to evaluate. |
| [out] | out_to | Receives the resulting state on success. Left untouched on failure. May be NULL if the caller only wants the yes/no answer (e.g. a procedure checking whether to bother doing its own work before firing the event for real). |
Definition at line 211 of file ab_gp_session_fsm.c.
| bool ab_gp_session_fsm_handle_event | ( | ab_gp_ertms_train_context_t * | ctx, |
| ab_gp_session_event_t | event ) |
Applies event to ctx->session_state.
| [in,out] | ctx | Train context whose session_state is (maybe) updated. Must not be NULL. |
| [in] | event | Event to apply. |
Definition at line 314 of file ab_gp_session_fsm.c.