RTE RBC 2oo2 Reference Application 0.1.0 build 0006685
SIL 4 2oo2 Dual-Site Fault-Tolerant ERTMS Radio Block Centre Reference Architecture
Loading...
Searching...
No Matches
ab_gp_saf_train.h File Reference

Train link safe communication (Subset-037 SaF) terminated inside A and B - REQ-SC-001, REQ-SC-003/004 (root docs/architecture/SAFE_COMM_INTEGRATION.dox, plan step 3). More...

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "safecomm/saf/saf.h"
#include "../../common/common_config.h"
Include dependency graph for ab_gp_saf_train.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ab_gp_saf_train_slot_t
 Per-train-slot state. More...
struct  ab_gp_saf_train_t
 One channel's train-link SaF termination. More...
struct  ab_gp_saf_result_t
 Output of ab_gp_saf_train_on_frame() / _on_peer_rb(). More...

Macros

#define AB_GP_SAF_ENVELOPE_HEADER   4U
 Envelope prefix: kind, train_id, 2-byte frame length.
#define AB_GP_SAF_FRAME_MAX   ((size_t)RBC_TRAIN_ENVELOPE_WIRE_SIZE - (size_t)AB_GP_SAF_ENVELOPE_HEADER)
 Largest SaF frame one Train relay envelope carries.
#define AB_GP_SAF_PDU_MAX   (AB_GP_SAF_FRAME_MAX - (size_t)SAFECOMM_SAF_DATA_OVERHEAD)
 Largest application PDU (ERTMS codec bytes) one protected frame carries.
#define AB_GP_SAF_PEER_RB_SIZE   (1U + SAFECOMM_MAC_RAND_LEN + SAFECOMM_MAC_RAND_LEN)
 PEER_MSG_KIND_SAF_RB payload: train_id(1) + RA(8) + RB(8).
#define AB_GP_SAF_KEYS_MAX   16U
 Capacity of the KMAC table (one entry per train ETCS identity).

Enumerations

enum  ab_gp_saf_action_t {
  AB_GP_SAF_ACTION_NONE = 0 , AB_GP_SAF_ACTION_REPLY , AB_GP_SAF_ACTION_APP , AB_GP_SAF_ACTION_REJECTED ,
  AB_GP_SAF_ACTION_DISCONNECTED
}
 What the caller must do with a processed frame. More...

Functions

void ab_gp_saf_keys_clear (void)
 Empties the KMAC table (process-global, shared by every slot).
bool ab_gp_saf_keys_install (uint32_t peer_etcs_id, const uint8_t kmac[SAFECOMM_MAC_KEY_LEN])
 Installs (or replaces) the KMAC for one train ETCS identity.
bool ab_gp_saf_keys_load_file (const char *path, uint32_t *out_count)
 Loads KMACs from a text file: one "<etcs_id> <48 hex chars>" per line (decimal or 0x identity), '#' comments and blank lines ignored - the same format the train simulator reads. A provisioning path for test environments and tools; in service the KM114 client installs keys (REQ-SC-005: no key compiled in).
void ab_gp_saf_train_init (ab_gp_saf_train_t *s, bool enabled, bool is_role_a, uint32_t rbc_etcs_id)
 Resets s. enabled false makes every other call a no-op / rejection.
void ab_gp_saf_train_on_frame (ab_gp_saf_train_t *s, uint8_t train_id, const uint8_t *frame, size_t frame_len, uint32_t now_ms, ab_gp_saf_result_t *out)
 Processes one SaF frame received from train slot train_id (1..RTE_EXAMPLE_MAX_TRAINS).
void ab_gp_saf_train_on_peer_rb (ab_gp_saf_train_t *s, const uint8_t *payload, size_t size, uint32_t now_ms, ab_gp_saf_result_t *out)
 B only: processes A's PEER_MSG_KIND_SAF_RB payload; answers the parked AU1 when its RA matches.
bool ab_gp_saf_train_wrap (ab_gp_saf_train_t *s, uint8_t train_id, const uint8_t *pdu, size_t pdu_len, uint8_t *out_frame, size_t out_cap, size_t *out_len)
 Protects one outbound application PDU for train slot train_id (only in DATA).
uint32_t ab_gp_saf_train_supervise (ab_gp_saf_train_t *s, uint32_t now_ms)
 Idle-link supervision of every connection in DATA (REQ-SC-004).
bool ab_gp_saf_train_is_connected (const ab_gp_saf_train_t *s, uint8_t train_id)
 True if train slot train_id has a connection in DATA.
bool ab_gp_saf_envelope_encode (uint8_t train_id, const uint8_t *frame, size_t frame_len, uint8_t out[RBC_TRAIN_ENVELOPE_WIRE_SIZE])
 Builds an RBC_MSG_SAF_ENVELOPE relay frame (RBC_TRAIN_ENVELOPE_WIRE_SIZE bytes).
bool ab_gp_saf_envelope_decode (const uint8_t env[RBC_TRAIN_ENVELOPE_WIRE_SIZE], uint8_t *out_train_id, const uint8_t **out_frame, size_t *out_len)
 Splits a received RBC_MSG_SAF_ENVELOPE relay frame.

Detailed Description

Train link safe communication (Subset-037 SaF) terminated inside A and B - REQ-SC-001, REQ-SC-003/004 (root docs/architecture/SAFE_COMM_INTEGRATION.dox, plan step 3).

Each vital channel keeps one SaF responder connection per train slot and verifies every frame itself; the role C gateway only relays bytes. Frames ride the Train relay in an RBC_MSG_SAF_ENVELOPE: byte 0 = RBC_MSG_SAF_ENVELOPE, byte 1 = train_id, bytes 2..3 = SaF frame length (big-endian), then the frame, zero-padded to RBC_TRAIN_ENVELOPE_WIRE_SIZE.

2oo2: the session key depends on the responder random RB, and the gateway forwards one of A's/B's identical replies and drops the duplicate, so both channels must use the same RB. Channel A draws it from the platform CSPRNG (rte_random_fill()) when AU1 arrives and sends {train_id, RA, RB} to B over the A/B peer link (PEER_MSG_KIND_SAF_RB); B holds AU1 until the RB for that RA arrives, in whichever order the two come.

Keys: the KMAC for a train is looked up by the ETCS identity in its AU1, from a table the KM114 client fills when it installs a key (every peer listed in the K-STRUCT) - REQ-SC-005, no key compiled in.

Off unless RTE_SAFECOMM_TRAIN_RBC_ID (this RBC's ETCS identity) is set; while off nothing here is called and the train link carries plain RBC_MSG_ERTMS_ENVELOPE frames exactly as before.

Not covered yet (first increment): SaF state is not transferred to a standby site (a failover makes every train reconnect); the flat P0/M136 scheme is not protected; the Python train simulator does not speak SaF yet (plan step 2), so the scenario suites run with this off.

Definition in file ab_gp_saf_train.h.

Macro Definition Documentation

◆ AB_GP_SAF_ENVELOPE_HEADER

#define AB_GP_SAF_ENVELOPE_HEADER   4U

Envelope prefix: kind, train_id, 2-byte frame length.

Definition at line 41 of file ab_gp_saf_train.h.

◆ AB_GP_SAF_FRAME_MAX

#define AB_GP_SAF_FRAME_MAX   ((size_t)RBC_TRAIN_ENVELOPE_WIRE_SIZE - (size_t)AB_GP_SAF_ENVELOPE_HEADER)

Largest SaF frame one Train relay envelope carries.

Definition at line 43 of file ab_gp_saf_train.h.

◆ AB_GP_SAF_PDU_MAX

#define AB_GP_SAF_PDU_MAX   (AB_GP_SAF_FRAME_MAX - (size_t)SAFECOMM_SAF_DATA_OVERHEAD)

Largest application PDU (ERTMS codec bytes) one protected frame carries.

Definition at line 45 of file ab_gp_saf_train.h.

◆ AB_GP_SAF_PEER_RB_SIZE

#define AB_GP_SAF_PEER_RB_SIZE   (1U + SAFECOMM_MAC_RAND_LEN + SAFECOMM_MAC_RAND_LEN)

PEER_MSG_KIND_SAF_RB payload: train_id(1) + RA(8) + RB(8).

Definition at line 47 of file ab_gp_saf_train.h.

◆ AB_GP_SAF_KEYS_MAX

#define AB_GP_SAF_KEYS_MAX   16U

Capacity of the KMAC table (one entry per train ETCS identity).

Definition at line 49 of file ab_gp_saf_train.h.

Enumeration Type Documentation

◆ ab_gp_saf_action_t

What the caller must do with a processed frame.

Enumerator
AB_GP_SAF_ACTION_NONE 

Consumed; nothing to send or dispatch (e.g. B parked an AU1).

AB_GP_SAF_ACTION_REPLY 

Send result.frame to the train (AU2 or AR).

AB_GP_SAF_ACTION_APP 

Verified application PDU in result.app for the ERTMS dispatcher.

AB_GP_SAF_ACTION_REJECTED 

Dropped: result.status says why (log it; never yields application data).

AB_GP_SAF_ACTION_DISCONNECTED 

The train released the connection.

Definition at line 72 of file ab_gp_saf_train.h.

Function Documentation

◆ ab_gp_saf_keys_clear()

void ab_gp_saf_keys_clear ( void )

Empties the KMAC table (process-global, shared by every slot).

Definition at line 122 of file ab_gp_saf_train.c.

◆ ab_gp_saf_keys_install()

bool ab_gp_saf_keys_install ( uint32_t peer_etcs_id,
const uint8_t kmac[SAFECOMM_MAC_KEY_LEN] )

Installs (or replaces) the KMAC for one train ETCS identity.

Returns
false if the table is full or kmac is NULL.

Definition at line 127 of file ab_gp_saf_train.c.

◆ ab_gp_saf_keys_load_file()

bool ab_gp_saf_keys_load_file ( const char * path,
uint32_t * out_count )

Loads KMACs from a text file: one "<etcs_id> <48 hex chars>" per line (decimal or 0x identity), '#' comments and blank lines ignored - the same format the train simulator reads. A provisioning path for test environments and tools; in service the KM114 client installs keys (REQ-SC-005: no key compiled in).

Parameters
pathfile to read. Non-NULL.
out_countreceives the number of keys installed. Non-NULL.
Returns
false if the file cannot be opened, any line is malformed, or the table is full (keys read before the failing line stay installed; the caller treats false as a fatal configuration error).

Definition at line 211 of file ab_gp_saf_train.c.

◆ ab_gp_saf_train_init()

void ab_gp_saf_train_init ( ab_gp_saf_train_t * s,
bool enabled,
bool is_role_a,
uint32_t rbc_etcs_id )

Resets s. enabled false makes every other call a no-op / rejection.

Definition at line 258 of file ab_gp_saf_train.c.

◆ ab_gp_saf_train_on_frame()

void ab_gp_saf_train_on_frame ( ab_gp_saf_train_t * s,
uint8_t train_id,
const uint8_t * frame,
size_t frame_len,
uint32_t now_ms,
ab_gp_saf_result_t * out )

Processes one SaF frame received from train slot train_id (1..RTE_EXAMPLE_MAX_TRAINS).

Parameters
now_msmonotonic milliseconds (the channel's cycle clock) for the connect budget and supervision.

Definition at line 270 of file ab_gp_saf_train.c.

◆ ab_gp_saf_train_on_peer_rb()

void ab_gp_saf_train_on_peer_rb ( ab_gp_saf_train_t * s,
const uint8_t * payload,
size_t size,
uint32_t now_ms,
ab_gp_saf_result_t * out )

B only: processes A's PEER_MSG_KIND_SAF_RB payload; answers the parked AU1 when its RA matches.

Definition at line 377 of file ab_gp_saf_train.c.

◆ ab_gp_saf_train_wrap()

bool ab_gp_saf_train_wrap ( ab_gp_saf_train_t * s,
uint8_t train_id,
const uint8_t * pdu,
size_t pdu_len,
uint8_t * out_frame,
size_t out_cap,
size_t * out_len )

Protects one outbound application PDU for train slot train_id (only in DATA).

Returns
true with the frame in out_frame; false if there is no connection in DATA or the PDU does not fit - the caller must then not send the message unprotected.

Definition at line 414 of file ab_gp_saf_train.c.

◆ ab_gp_saf_train_supervise()

uint32_t ab_gp_saf_train_supervise ( ab_gp_saf_train_t * s,
uint32_t now_ms )

Idle-link supervision of every connection in DATA (REQ-SC-004).

Returns
bit (train_id - 1) set for each train whose link was declared lost by this call.

Definition at line 431 of file ab_gp_saf_train.c.

◆ ab_gp_saf_train_is_connected()

bool ab_gp_saf_train_is_connected ( const ab_gp_saf_train_t * s,
uint8_t train_id )

True if train slot train_id has a connection in DATA.

Definition at line 456 of file ab_gp_saf_train.c.

◆ ab_gp_saf_envelope_encode()

bool ab_gp_saf_envelope_encode ( uint8_t train_id,
const uint8_t * frame,
size_t frame_len,
uint8_t out[RBC_TRAIN_ENVELOPE_WIRE_SIZE] )

Builds an RBC_MSG_SAF_ENVELOPE relay frame (RBC_TRAIN_ENVELOPE_WIRE_SIZE bytes).

Returns
false if frame_len exceeds AB_GP_SAF_FRAME_MAX or an argument is invalid.

Definition at line 466 of file ab_gp_saf_train.c.

◆ ab_gp_saf_envelope_decode()

bool ab_gp_saf_envelope_decode ( const uint8_t env[RBC_TRAIN_ENVELOPE_WIRE_SIZE],
uint8_t * out_train_id,
const uint8_t ** out_frame,
size_t * out_len )

Splits a received RBC_MSG_SAF_ENVELOPE relay frame.

Returns
false if the kind, train slot or length is invalid.

Definition at line 482 of file ab_gp_saf_train.c.