|
RTE RBC 2oo2 Reference Application 0.1.0 build 0006685
SIL 4 2oo2 Dual-Site Fault-Tolerant ERTMS Radio Block Centre Reference Architecture
|
The RBC Train/IL/CTC scenario's shared wire envelope (ADR-029) - one fixed-size struct/frame reused for every message kind exchanged between C and the Train/IL/CTC sims, AND between C and A/B (the same envelope end-to-end - see monitor_c.c's own header). Pure types, no I/O - encode/decode is owned per-domain by AB/train/ab_gp_train.c, AB/GA/il/ab_ga_il.c, and AB/GA/ctc/ab_ga_ctc.c (each a file-static codec over the kinds its own relay channel carries; no single shared codec file). More...
#include <stdbool.h>#include <stdint.h>#include "rte/oal/memory/rte_mem_util.h"#include "common_config.h"Go to the source code of this file.
Data Structures | |
| struct | rbc_envelope_t |
| One decoded envelope - see this file's own module doc for where the wire<->struct conversion now lives (per-domain, not one shared codec). More... | |
| struct | rbc_envelope_queue_t |
Macros | |
| #define | RBC_ENVELOPE_QUEUE_CAPACITY 16U |
| Fixed-capacity single-producer/single-consumer envelope queue - REQ-RBC-003. Unlike the M136/ANSWER single-slot "latest value
only matters" primitives this replaces (answer_slot_t/rx_slot_t, still used elsewhere for genuinely refresh-every-cycle values), a link now carrying P0/M136/ROUTE_ADD/M24_M15/M3/M146/CTC_* interleaved from up to RTE_EXAMPLE_MAX_TRAINS independent trains can legitimately have MORE THAN ONE distinct event arrive within a single C report cycle (e.g. two trains' M136 the same cycle, or an M3 grant landing the same cycle as a CTC indication) - overwriting one with the other would silently drop a real, distinct message, not just a stale duplicate. This queue is drained fully every cycle (rbc_envelope_queue_pop() in a loop until empty), not read-latest-only. | |
Enumerations | |
| enum | rbc_msg_kind_t { RBC_MSG_P0 = 0 , RBC_MSG_M136 = 1 , RBC_MSG_M24_M15 = 2 , RBC_MSG_ROUTE_ADD = 3 , RBC_MSG_M3 = 4 , RBC_MSG_M146 = 5 , RBC_MSG_CTC_CONNECTED = 6 , RBC_MSG_CTC_MA_GRANTED = 7 , RBC_MSG_CTC_MA_EXTENDED = 8 , RBC_MSG_RELAY_KEEPALIVE = 9 , RBC_MSG_ROUTE_RELEASE = 10 , RBC_MSG_TRAIN_POSITION_IN_ROUTE = 11 , RBC_MSG_CTC_ALARM = 12 , RBC_MSG_TSR_ADD = 13 , RBC_MSG_TSR_REMOVE = 14 , RBC_MSG_TEXT_MESSAGE = 15 , RBC_MSG_TEXT_MESSAGE_ACK = 16 , RBC_MSG_HANDOVER_ORDER = 17 , RBC_MSG_SET_LOG_LEVEL = 18 , RBC_MSG_SIM_STATUS = 19 , RBC_MSG_TRAIN_DISCONNECT = 20 , RBC_MSG_ERTMS_ENVELOPE = 22 , RBC_MSG_ROUTE_STATUS_REPORT = 23 , RBC_MSG_CTC_TRAIN_INFO = 24 , RBC_MSG_IL_ROUTE_CMD = 25 , RBC_MSG_IL_STATUS = 26 , RBC_MSG_IL_ROUTE_INDICATION = 27 , RBC_MSG_SAF_ENVELOPE = 28 } |
| Which of this envelope's fields are meaningful, and which direction it travels - see this file's own header. More... | |
| enum | rbc_il_route_type_t { RBC_IL_ROUTE_TYPE_NO_ROUTE = 0 , RBC_IL_ROUTE_TYPE_LOCKED = 1 } |
| RBC_MSG_IL_ROUTE_CMD.route_type - is IL indicating a route here at all, and is it locked. Distinct from rbc_route_type_t (the older FS/OS/SH supervision-mode field): supervision mode now lives in rbc_il_route_status_t below. More... | |
| enum | rbc_il_route_status_t { RBC_IL_ROUTE_STATUS_NO_STATUS = 0 , RBC_IL_ROUTE_STATUS_FS = 1 , RBC_IL_ROUTE_STATUS_OS = 2 , RBC_IL_ROUTE_STATUS_SH = 3 , RBC_IL_ROUTE_STATUS_USED = 4 , RBC_IL_ROUTE_STATUS_DEGRADED = 5 } |
| RBC_MSG_IL_ROUTE_CMD.route_status - the supervision mode / lifecycle status IL reports for the route. More... | |
| enum | rbc_il_degraded_status_t { RBC_IL_DEGRADED_STATUS_NO_STATUS = 0 , RBC_IL_DEGRADED_STATUS_LOW = 1 , RBC_IL_DEGRADED_STATUS_MEDIUM = 2 , RBC_IL_DEGRADED_STATUS_HIGH = 3 } |
| RBC_MSG_IL_ROUTE_CMD.degraded_status - severity, meaningful only when route_status == RBC_IL_ROUTE_STATUS_DEGRADED. More... | |
| enum | rbc_il_status_t { RBC_IL_STATUS_DOWN = 0 , RBC_IL_STATUS_RESTARTING = 1 , RBC_IL_STATUS_UP = 2 } |
| RBC_MSG_IL_STATUS.il_status - IL process health. More... | |
| enum | rbc_il_emergency_type_t { RBC_IL_EMERGENCY_TYPE_NONE = -1 , RBC_IL_EMERGENCY_TYPE_SAM = 0 , RBC_IL_EMERGENCY_TYPE_CEM = 1 , RBC_IL_EMERGENCY_TYPE_UEM = 2 } |
| RBC_MSG_IL_ROUTE_INDICATION.emergency_type - carried as a SIGNED int8 on the wire, -1 = no emergency. More... | |
| enum | rbc_alarm_severity_t { RBC_ALARM_SEVERITY_INFO = 0 , RBC_ALARM_SEVERITY_WARNING = 1 , RBC_ALARM_SEVERITY_ERROR = 2 } |
| Severity of an RBC_MSG_CTC_ALARM envelope (msg_type field on the wire) - deliberately a small, closed vocabulary mirroring safeAPIFreamwork's own rte_log_level_t (DEBUG omitted: an alarm forwarded all the way to a human dispatcher is by definition not a verbose debug trace). More... | |
| enum | rbc_route_type_t { RBC_ROUTE_TYPE_FS = 0 , RBC_ROUTE_TYPE_OS = 1 , RBC_ROUTE_TYPE_SH = 2 } |
| ROUTE_ADD's own route_type field - the supervision mode IL is granting this route under (real ETCS concept, Subset-026). Stored on the wire (and in ab_gp_db_route_t) as a plain uint32_t, same convention as msg_type/RTE_EXAMPLE_MSG_M24 - not dispatched on directly by any decode switch, so a raw uint32_t carries it end to end rather than this enum type itself appearing in any struct field. More... | |
| enum | rbc_route_status_t { RBC_ROUTE_STATUS_NO_TRAIN = 0 , RBC_ROUTE_STATUS_TRAIN_IN_ROUTE = 1 } |
| TRAIN_POSITION_IN_ROUTE's own route_status field - see that kind's own doc (rbc_msg_kind_t). Same raw-uint32_t-on-the-wire convention as rbc_route_type_t above. More... | |
Functions | |
| static void | rbc_envelope_write_keepalive (uint8_t out[RBC_ENVELOPE_WIRE_SIZE]) |
Fills out with a keepalive frame (RBC_MSG_RELAY_KEEPALIVE in byte 0, every other byte zero) - see that kind's own doc above. Domain-blind by design (unlike every real envelope, this one carries no per-kind fields), so it lives here rather than in any one domain's own codec (ab_gp_train.c/ab_ga_il.c/ab_ga_ctc.c). | |
| static bool | rbc_envelope_is_keepalive (const uint8_t in[RBC_ENVELOPE_WIRE_SIZE]) |
true if in is a keepalive frame - see rbc_envelope_write_keepalive()'s own doc. Callers on the receiving end of a relay link whose real traffic is one-directional check this BEFORE a real domain decode or forwarding to an external sim, both of which would otherwise mishandle it. | |
| static void | rbc_envelope_write_set_log_level (uint8_t out[RBC_ENVELOPE_WIRE_SIZE], uint8_t level) |
Fills out with a set-log-level control frame: RBC_MSG_SET_LOG_LEVEL in byte 0, level in byte 1, every other byte zero - see that kind's own doc. Domain-blind (carries no per-kind fields), so it lives here, not in any one domain's codec. | |
| static bool | rbc_envelope_is_set_log_level (const uint8_t in[RBC_ENVELOPE_WIRE_SIZE], uint8_t *out_level) |
true if in is a set-log-level control frame; *out_level (if non-NULL) then receives the requested level byte. Checked BEFORE a real domain decode or a forward to a sim, same as rbc_envelope_is_keepalive(). | |
| static void | rbc_envelope_write_sim_status (uint8_t out[RBC_ENVELOPE_WIRE_SIZE], const char *payload) |
Fills out with an ADR-038 sim-status frame: RBC_MSG_SIM_STATUS in byte 0, the ASCII payload length in byte 1, that many payload chars from byte 2 (rest zero, NUL not stored). A payload longer than RBC_ENVELOPE_WIRE_SIZE-2 is truncated. Domain-blind (the owning gateway republishes it to the C status broker, never typed-decodes it), so it lives here beside the keepalive / set-log-level helpers. AB never emits or receives this kind. | |
| static bool | rbc_envelope_is_sim_status (const uint8_t in[RBC_ENVELOPE_WIRE_SIZE], char *out_payload, uint16_t out_size) |
true if in is a sim-status frame; when it is and out_payload is non-NULL, copies the ASCII payload there NUL-terminated, truncated to out_size. Checked BEFORE a real domain decode or a forward to AB, same as rbc_envelope_is_keepalive(). | |
| static void | rbc_envelope_queue_init (rbc_envelope_queue_t *queue) |
| static bool | rbc_envelope_queue_push (rbc_envelope_queue_t *queue, const uint8_t bytes[RBC_ENVELOPE_WIRE_SIZE]) |
| static bool | rbc_envelope_queue_pop (rbc_envelope_queue_t *queue, uint8_t out_bytes[RBC_ENVELOPE_WIRE_SIZE]) |
The RBC Train/IL/CTC scenario's shared wire envelope (ADR-029) - one fixed-size struct/frame reused for every message kind exchanged between C and the Train/IL/CTC sims, AND between C and A/B (the same envelope end-to-end - see monitor_c.c's own header). Pure types, no I/O - encode/decode is owned per-domain by AB/train/ab_gp_train.c, AB/GA/il/ab_ga_il.c, and AB/GA/ctc/ab_ga_ctc.c (each a file-static codec over the kinds its own relay channel carries; no single shared codec file).
Per this project's MISRA fixed-size-everything convention (no dynamically-sized encoding anywhere else in this codebase either), this is ONE struct reused for P0/M136/M24-M15/ROUTE_ADD/M3/M146 and the three CTC indication kinds, rather than N distinct wire structs - fields not meaningful for a given kind are left at 0.
REQ-RBC-001 (revised, safeAPIFreamwork/docs/requirements/SRS.md): a real Subset-026-style header (nid_message/l_message/t_train) plus per-kind-variable content length, gated by l_message - see common_config.h's own RBC_ENVELOPE_WIRE_SIZE comment for the exact layout and AB/train/ab_gp_train.c's own train_wire_encode()/_decode() header for the encode/decode logic (duplicated, not shared, across that file/AB/GA/il/ab_ga_il.c/AB/GA/ctc/ab_ga_ctc.c - see its own doc for why). Implemented as a fixed-size MAXIMUM slot (RBC_ENVELOPE_WIRE_SIZE bytes, unused tail zero-padded) with a genuinely-calculated, genuinely-varying l_message inside it - not variable-size UDP datagrams (that would touch 20+ already-tested rte_netlink_send()/_recv() call sites for no safety benefit this pass actually needs). RBC_MSG_M146 uses the 4-byte t_train_ack extension (l_message=40); RBC_MSG_M136 uses the whole original slot (l_message=80, offsets 0-79); ROUTE_ADD/ROUTE_RELEASE/ TRAIN_POSITION_IN_ROUTE (route identity/type/status - offsets 80-95, appended after M136's own block) use the whole current slot (l_message=RBC_ENVELOPE_WIRE_SIZE=96) - every other kind's content is still the original 6-field/24-byte layout (l_message=36), unchanged. Widening which kinds use which content length further, or genuinely varying the transmitted datagram size, is separately-scoped follow-on work.
Definition in file rbc_wire_types.h.
| #define RBC_ENVELOPE_QUEUE_CAPACITY 16U |
Fixed-capacity single-producer/single-consumer envelope queue - REQ-RBC-003. Unlike the M136/ANSWER single-slot "latest value only matters" primitives this replaces (answer_slot_t/rx_slot_t, still used elsewhere for genuinely refresh-every-cycle values), a link now carrying P0/M136/ROUTE_ADD/M24_M15/M3/M146/CTC_* interleaved from up to RTE_EXAMPLE_MAX_TRAINS independent trains can legitimately have MORE THAN ONE distinct event arrive within a single C report cycle (e.g. two trains' M136 the same cycle, or an M3 grant landing the same cycle as a CTC indication) - overwriting one with the other would silently drop a real, distinct message, not just a stale duplicate. This queue is drained fully every cycle (rbc_envelope_queue_pop() in a loop until empty), not read-latest-only.
Single-producer/single-consumer by construction (same convention as every other cross-task primitive in this codebase - see rx_slot_t's own doc): the owning rx task is the ONLY writer of write_index/entries[]; the main cycle thread is the ONLY writer of read_index. This is a demo-grade, not formally-verified synchronization technique (a real SIL-rated implementation would use a qualified RTOS queue primitive), relying on a naturally-aligned uint32_t read/write being atomic enough on this project's target platforms (x86_64/arm64 Linux) - same caveat already documented on rx_slot_t/answer_slot_t.
Bounded: a producer that finds the queue full (RBC_ENVELOPE_QUEUE_CAPACITY unread entries already pending) drops the new message and returns false so the caller can log it - REQ-RBC-004 (no silent, unbounded growth; no dynamic allocation, CLAUDE.md). Sized generously relative to this scenario's actual message rates (P0 once per connection, M136 roughly once per train cycle, ROUTE_ADD/M146 occasional) so this should not be reached in ordinary operation - reaching it is itself a diagnostic signal that a producer is outrunning the consumer, not something this "first simple pass" tries to handle more gracefully than dropping.
ADR-029: raised 8 -> 16 after real 11-container Docker testing found this single queue - shared by ALL RTE_EXAMPLE_MAX_TRAINS trains' AND ILs' P0/M136/ROUTE_ADD/M146 traffic, multiplexed over the one C<->A (and C<->B) link - genuinely filling and staying full across several consecutive drain cycles under transient host scheduling pressure (both this project's own C-to-A/B link occasionally stalling for a cycle or two, matching the same reconnect jitter RTE_EXAMPLE_LINK_STALE_TIMEOUT_COUNT's own doc already describes, AND real Docker CPU contention on the test host), not just a hypothetical burst - a commanded ROUTE_ADD landing in that exact window is silently and permanently lost (this queue has no retry/dedup - see relay_inbound_to_ab()'s own doc, monitor_c.c, for why a naive resend is not a safe fix). Doubling the capacity is a cheap (28 bytes/entry), purely defensive widening of the existing margin, not a redesign - reaching even 16 under ordinary 2-train traffic remains a genuine diagnostic signal, not an expected steady-state condition.
Definition at line 610 of file rbc_wire_types.h.
| enum rbc_msg_kind_t |
Which of this envelope's fields are meaningful, and which direction it travels - see this file's own header.
| Enumerator | |
|---|---|
| RBC_MSG_P0 | Train -> C -> AB: handshake, establishes train_id. |
| RBC_MSG_M136 | Train -> C -> AB: cyclic position report (train_id, cycle, d_lrbg). |
| RBC_MSG_M24_M15 | AB -> C -> Train: position-report ack (train_id, cycle, msg_type - RTE_EXAMPLE_MSG_M24 or _M15, common_config.h). |
| RBC_MSG_ROUTE_ADD | IL -> C -> AB: grant one more route (train_id, route_len). |
| RBC_MSG_M3 | AB -> C -> Train: Movement Authority grant/extend (train_id, ma_seq, ma_length). |
| RBC_MSG_M146 | Train -> C -> AB: MA ack (train_id, ma_seq echoed back). |
| RBC_MSG_CTC_CONNECTED | AB -> C -> CTC: train connected + position (train_id, d_lrbg). |
| RBC_MSG_CTC_MA_GRANTED | AB -> C -> CTC: train has an MA (train_id, ma_seq, ma_length). |
| RBC_MSG_CTC_MA_EXTENDED | AB -> C -> CTC: MA length updated (train_id, ma_seq, ma_length). |
| RBC_MSG_RELAY_KEEPALIVE | Not a Subset-026 message and not domain data - a pure wire-level liveness frame for a per-{peer,kind,instance} relay link (ADR-029) whose real application traffic is legitimately one-directional and event-driven (IL: C->AB only; CTC: AB->C only) rather than steady/cyclic (unlike Train's M136-driven cadence). Found live: with nothing real to send, such a link's own idle direction goes quiet for RTE_EXAMPLE_LINK_STALE_TIMEOUT_COUNT
|
| RBC_MSG_ROUTE_RELEASE | IL -> C -> AB: release a previously-granted route by its own identity (start_signal, end_signal) - see ab_ga_il.c's own handle_route_release(). Appended after RBC_MSG_RELAY_KEEPALIVE deliberately, not inserted earlier in this list, so no existing kind value is ever renumbered. |
| RBC_MSG_TRAIN_POSITION_IN_ROUTE | AB -> C -> IL: reports whether a route currently has a train authorized through it (route_status: RBC_ROUTE_STATUS_NO_TRAIN or _TRAIN_IN_ROUTE), identified the same way (start_signal, end_signal). Fired from ab_gp_db_route_connect_train()/ _disconnect_train() via the route-connected/-disconnected notify hooks (ab_gp_db.h) - see ab_ga_il_build_outputs()'s own doc. |
| RBC_MSG_CTC_ALARM | AB -> C -> CTC: a severity-leveled operational alarm/event (not train/route domain data) - raised by AB's own fault-reaction code (safeAPIRBC2oo2GP/src/application/AB/GP/com/ab_gp_channel.c's ab_gp_channel_raise_ctc_alarm(), called from the safestate handler and from ab_gp_channel_crosscompare.c's react_to_fault()) so a human dispatcher watching CTC learns something is wrong, not just a local log line nobody outside this process sees. Built by safeAPIRBC2oo2GA's ab_ga_ctc_build_alarm() (rbc_alarm_severity_t in msg_type, a numeric reason/fault code in ma_seq - both fields already zeroed/unused for every other CTC_* kind, see ab_ga_ctc.c's own ctc_wire_encode() comments - not a new field). Appended after RBC_MSG_TRAIN_POSITION_IN_ROUTE, same never-renumber-an-existing-kind precedent as every earlier addition to this enum. |
| RBC_MSG_TSR_ADD | CTC/IL -> C -> AB: Grant / apply a Temporary Speed Restriction (Subset-026 Packet 65) (nid_tsr in msg_type, v_tsr_kmh in route_len, d_tsr_start_m in start_signal, d_tsr_end_m in end_signal). |
| RBC_MSG_TSR_REMOVE | CTC/IL -> C -> AB: Revoke a Temporary Speed Restriction (Subset-026 Packet 66) (nid_tsr in msg_type). |
| RBC_MSG_TEXT_MESSAGE | CTC/AB -> C -> Train: Text message / driver advisory (Subset-026 Packet 72) (text_id in msg_type, q_textconfirm in ma_seq, display_distance in start_signal). |
| RBC_MSG_TEXT_MESSAGE_ACK | Train -> C -> AB/CTC: Driver text confirmation acknowledgment (text_id in msg_type, timestamp in t_train_ack). |
| RBC_MSG_HANDOVER_ORDER | AB -> C -> Train: RBC Transition Order / Handover Order (Subset-026 Packet 131) (nid_rbc in msg_type, nid_radio in start_signal, d_rbctr in d_lrbg). |
| RBC_MSG_SET_LOG_LEVEL | C -> AB (and applied locally by C): set this process's rte_log severity threshold. Diagnostic control frame, not domain data (rte_log is non-safety, ADR-001 section 4) - same category as RBC_MSG_RELAY_KEEPALIVE. The rte_log_level_t value rides in byte 1 (train_id's wire slot, unused here); every other byte is zero. Broadcast over the IL relay link by C's gateway_c_logctl.c so one command re-levels A, B and C together. Value 18 chosen to sit past this enum's current max in BOTH rbc_wire_types.h copies (the C-side copy stops at 12 + this; keep the two in sync for wire meaning). |
| RBC_MSG_SIM_STATUS | ADR-038: Sim -> C (own sim link), NOT forwarded to AB (AB never sees this kind). Carries an ASCII key=value status payload (byte 1 = length, bytes 2.. = the chars); the owning C gateway republishes it verbatim to the C-side status broker as an rbc_util_frame_t PUBLISH. Domain-blind, never typed-decoded - same category as RBC_MSG_RELAY_KEEPALIVE. Appended, never renumbering; kept at 19 in BOTH rbc_wire_types.h copies. |
| RBC_MSG_TRAIN_DISCONNECT | Train -> C -> AB: explicit disconnect - the train sim is formally leaving (as opposed to a radio-silence/reconnect-forever socket drop, which sends nothing on the wire at all). No extra fields (train_id is enough, same as RBC_MSG_P0's own "just the header" shape) - ab_gp_train.c's own ab_gp_train_apply_envelope() releases every route this train currently holds (ab_gp_db_route_disconnect_train() per entry from ab_gp_db_train_get_routes()) before calling the already-existing (previously unused) ab_gp_train_remove(), which itself refuses to remove a train still holding routes - see that function's own doc. Keep numerically synced with the C-side rbc_wire_types.h copy, same as RBC_MSG_SET_LOG_LEVEL above. |
| RBC_MSG_ERTMS_ENVELOPE | Train <-> C -> AB: opaque wrapper carrying a real Subset-026 message, TLV-encoded by rbc_train_codec_encode_track_to_train()/ _decode_train_to_track() (ab_gp_ertms_train_message_codec.c) - NOT this file's own flat rbc_envelope_t shape. Wire layout: byte 0 = this kind, byte 1 = train_id (same 2-byte prefix every other kind on this channel uses, so session-slot routing needs no nid_engine lookup), bytes 2.. = the codec's own frame verbatim (its own nid_message/l_message header first, then whichever packets l_message says are present) - see ab_gp_proc_dispatch.c, the glue between this kind and the ertms_procedures/ engine. Rides the Train relay channel's now-widened RBC_TRAIN_ENVELOPE_WIRE_SIZE slot (common_config.h) instead of RBC_ENVELOPE_WIRE_SIZE - every other kind on this channel (P0/M136/M24_M15/M3/M146/ TRAIN_DISCONNECT) is untouched and keeps working exactly as before, this is a purely additive kind for the real-message flow layered on top of an already P0-connected session slot. Appended, never renumbering; keep numerically synced with the C-side copy. Deliberately 22, NOT 21: TrainRBCSim's own message_catalog.json (not touched by this fix - see that project's own history) defines a "TRAIN_CONNECT" flat message with kind=21, added independently after this constant already claimed 21 - a real, found-live collision (a plain P0/TRAIN_CONNECT handshake byte[0]=21 was being routed into the ERTMS TLV decoder and rejected as malformed, breaking every pre-existing flat-scheme test's own connect step). SimCore's rbc_messages.py mirrors this same value as its own _ertmsWrapperKind default - keep both in sync if this ever moves again. |
| RBC_MSG_ROUTE_STATUS_REPORT | IL -> C -> AB: Phase D periodic route-status broadcast (2s cadence) - IL's own locally-tracked lock state for one route (start_signal/end_signal identity, route_status: RBC_ROUTE_STATUS_NO_TRAIN/_TRAIN_IN_ROUTE reused as free/locked - see rbc_route_status_t's own doc). Deliberately reuses RBC_MSG_TRAIN_POSITION_IN_ROUTE's own field triple - same wire shape, opposite direction. Liveness-first cut (ab_ga_il.c's own decode case logs receipt only, no cross-check against AB's own held-route state yet - see that function's own doc for the rationale). Appended, never renumbering. |
| RBC_MSG_CTC_TRAIN_INFO | AB -> C -> CTC: periodic, on-change-only train telemetry for the web_runner "Train" object (CTC is meant to be the sole real observation point for train position/MA, not a mix of Train-sim wire traffic and IL events - see safeAPIRBC2oo2TestEnv's own web_runner design). Built by safeAPIRBC2oo2GA's ab_ga_ctc_build_train_info() (ab_ga_ctc.c) - deliberately reuses every existing generic field slot below rather than widening this struct, same "reuse, don't grow" convention RBC_MSG_CTC_ALARM already set for msg_type/ma_seq/t_train: d_lrbg - train's current reported position (same meaning as CTC_CONNECTED's own d_lrbg). msg_type - MA status: 0 = NONE, 1 = GRANTED. route_len - MA target signal (the end_signal of the last route in this train's currently-held route chain) - this field is otherwise always 0 for every CTC_* kind (see ab_ga_ctc.c's own ctc_wire_encode() comment), so it is free to repurpose here. t_train - front signal (the end_signal of the earliest held route whose cumulative length the train has not yet reached) - otherwise CTC_ALARM's own timestamp field, 0 for every other kind. cycle - distance to that front signal, meters - otherwise CTC_ALARM's own cycle field, 0 for every other kind. ma_seq - this train's real MA sequence number, same meaning as CTC_MA_GRANTED/_EXTENDED's own ma_seq (lets a dispatcher correlate this indication with those). ma_length - MA offset relative to the target signal, METERS, SIGNED (d_lrbg - granted_length; negative while approaching, 0 at the limit) stored as its raw two's-complement bit pattern in this uint32_t slot
|
| RBC_MSG_IL_ROUTE_CMD | IL -> C -> AB: the full IL route command (ADR: dedicated IL wire messages, not the shared 96-byte rbc_envelope_t). Carries route identity (route_id/start_signal/end_signal, int32, -1 = unset), route_type (rbc_il_route_type_t), route_status (rbc_il_route_status_t), degraded_status (rbc_il_degraded_status_t), release_route_request and first_route_in_path (0/1). Payload struct + byte layout: safeAPIRBC2oo2GA/src/AB/il/ab_ga_il_wire.h (with its byte-identical Python mirror in ILRBCSim). Still shipped in the fixed 96-byte relay slot, just with its own small meaningful prefix - the slot is NOT grown and rbc_envelope_t is untouched. |
| RBC_MSG_IL_STATUS | IL -> C -> AB: IL health (rbc_il_status_t - DOWN/RESTARTING/UP). Same dedicated-message rationale as RBC_MSG_IL_ROUTE_CMD. |
| RBC_MSG_IL_ROUTE_INDICATION | AB -> C -> IL: per-route indication the RBC pushes back to IL - route identity, train_in_route, train_has_ma_in_route, allocated_train_nid_engine (int32, -1 = none), emergency_in_route, emergency_type (rbc_il_emergency_type_t, -1 = none). Supersedes the RBC_MSG_TRAIN_POSITION_IN_ROUTE indication for the new field set; that kind stays for the existing liveness-first flow. |
| RBC_MSG_SAF_ENVELOPE | Train <-> C -> AB: one Subset-037 SaF frame (AU1/AU2/AU3/AR/Sa-DATA/Sa-DISCONNECT) when the train link is protected (RTE_SAFECOMM_TRAIN_RBC_ID set - root docs/architecture/SAFE_COMM_INTEGRATION.dox plan step 3). Wire layout: byte 0 = this kind, byte 1 = train_id, bytes 2..3 = frame length (big-endian), then the frame, zero-padded to RBC_TRAIN_ENVELOPE_WIRE_SIZE. A Sa-DATA frame's user data is exactly what an RBC_MSG_ERTMS_ENVELOPE carries from byte 2 on. Verified and unwrapped in A/B only (ab_gp_saf_train.c); the gateway relays it untouched. Appended, never renumbering. |
Definition at line 53 of file rbc_wire_types.h.
| enum rbc_il_route_type_t |
RBC_MSG_IL_ROUTE_CMD.route_type - is IL indicating a route here at all, and is it locked. Distinct from rbc_route_type_t (the older FS/OS/SH supervision-mode field): supervision mode now lives in rbc_il_route_status_t below.
| Enumerator | |
|---|---|
| RBC_IL_ROUTE_TYPE_NO_ROUTE | No route indicated / cleared (default). |
| RBC_IL_ROUTE_TYPE_LOCKED | IL has locked this route (points set, flank protection). |
Definition at line 285 of file rbc_wire_types.h.
RBC_MSG_IL_ROUTE_CMD.route_status - the supervision mode / lifecycle status IL reports for the route.
Definition at line 293 of file rbc_wire_types.h.
RBC_MSG_IL_ROUTE_CMD.degraded_status - severity, meaningful only when route_status == RBC_IL_ROUTE_STATUS_DEGRADED.
| Enumerator | |
|---|---|
| RBC_IL_DEGRADED_STATUS_NO_STATUS | Not degraded (default). |
| RBC_IL_DEGRADED_STATUS_LOW | |
| RBC_IL_DEGRADED_STATUS_MEDIUM | |
| RBC_IL_DEGRADED_STATUS_HIGH | |
Definition at line 305 of file rbc_wire_types.h.
| enum rbc_il_status_t |
RBC_MSG_IL_STATUS.il_status - IL process health.
| Enumerator | |
|---|---|
| RBC_IL_STATUS_DOWN | IL not reachable / not operational (default). |
| RBC_IL_STATUS_RESTARTING | IL restarting - route state not yet trustworthy. |
| RBC_IL_STATUS_UP | IL operational. |
Definition at line 314 of file rbc_wire_types.h.
RBC_MSG_IL_ROUTE_INDICATION.emergency_type - carried as a SIGNED int8 on the wire, -1 = no emergency.
Definition at line 323 of file rbc_wire_types.h.
| enum rbc_alarm_severity_t |
Severity of an RBC_MSG_CTC_ALARM envelope (msg_type field on the wire) - deliberately a small, closed vocabulary mirroring safeAPIFreamwork's own rte_log_level_t (DEBUG omitted: an alarm forwarded all the way to a human dispatcher is by definition not a verbose debug trace).
Definition at line 336 of file rbc_wire_types.h.
| enum rbc_route_type_t |
ROUTE_ADD's own route_type field - the supervision mode IL is granting this route under (real ETCS concept, Subset-026). Stored on the wire (and in ab_gp_db_route_t) as a plain uint32_t, same convention as msg_type/RTE_EXAMPLE_MSG_M24 - not dispatched on directly by any decode switch, so a raw uint32_t carries it end to end rather than this enum type itself appearing in any struct field.
| Enumerator | |
|---|---|
| RBC_ROUTE_TYPE_FS | Full Supervision. |
| RBC_ROUTE_TYPE_OS | On Sight. |
| RBC_ROUTE_TYPE_SH | Shunting. |
Definition at line 350 of file rbc_wire_types.h.
| enum rbc_route_status_t |
TRAIN_POSITION_IN_ROUTE's own route_status field - see that kind's own doc (rbc_msg_kind_t). Same raw-uint32_t-on-the-wire convention as rbc_route_type_t above.
| Enumerator | |
|---|---|
| RBC_ROUTE_STATUS_NO_TRAIN | No train currently authorized through this route. |
| RBC_ROUTE_STATUS_TRAIN_IN_ROUTE | A train currently is. |
Definition at line 360 of file rbc_wire_types.h.
|
inlinestatic |
Fills out with a keepalive frame (RBC_MSG_RELAY_KEEPALIVE in byte 0, every other byte zero) - see that kind's own doc above. Domain-blind by design (unlike every real envelope, this one carries no per-kind fields), so it lives here rather than in any one domain's own codec (ab_gp_train.c/ab_ga_il.c/ab_ga_ctc.c).
Definition at line 457 of file rbc_wire_types.h.
|
inlinestatic |
true if in is a keepalive frame - see rbc_envelope_write_keepalive()'s own doc. Callers on the receiving end of a relay link whose real traffic is one-directional check this BEFORE a real domain decode or forwarding to an external sim, both of which would otherwise mishandle it.
Definition at line 469 of file rbc_wire_types.h.
|
inlinestatic |
Fills out with a set-log-level control frame: RBC_MSG_SET_LOG_LEVEL in byte 0, level in byte 1, every other byte zero - see that kind's own doc. Domain-blind (carries no per-kind fields), so it lives here, not in any one domain's codec.
Definition at line 479 of file rbc_wire_types.h.
|
inlinestatic |
true if in is a set-log-level control frame; *out_level (if non-NULL) then receives the requested level byte. Checked BEFORE a real domain decode or a forward to a sim, same as rbc_envelope_is_keepalive().
Definition at line 490 of file rbc_wire_types.h.
|
inlinestatic |
Fills out with an ADR-038 sim-status frame: RBC_MSG_SIM_STATUS in byte 0, the ASCII payload length in byte 1, that many payload chars from byte 2 (rest zero, NUL not stored). A payload longer than RBC_ENVELOPE_WIRE_SIZE-2 is truncated. Domain-blind (the owning gateway republishes it to the C status broker, never typed-decodes it), so it lives here beside the keepalive / set-log-level helpers. AB never emits or receives this kind.
Definition at line 508 of file rbc_wire_types.h.
|
inlinestatic |
true if in is a sim-status frame; when it is and out_payload is non-NULL, copies the ASCII payload there NUL-terminated, truncated to out_size. Checked BEFORE a real domain decode or a forward to AB, same as rbc_envelope_is_keepalive().
Definition at line 529 of file rbc_wire_types.h.
|
inlinestatic |
Definition at line 619 of file rbc_wire_types.h.
|
inlinestatic |
Definition at line 628 of file rbc_wire_types.h.
|
inlinestatic |
Definition at line 647 of file rbc_wire_types.h.