ILRBCSim
ADR-029 Interlocking simulator — grants/extends Movement Authority against the RBC wire protocol
Toggle main menu visibility
Loading...
Searching...
No Matches
il_wire.py
Go to the documentation of this file.
1
"""Byte-identical Python mirror of safeAPIRBC2oo2GA/src/AB/il/ab_ga_il_wire.h -
2
the dedicated IL <-> RBC messages (wire kinds 25/26/27).
3
4
These do NOT use SimCore's generic flat 96-byte envelope codec
5
(rbc_wire.py / MessageCatalog); each has its own small packed layout,
6
still shipped inside the fixed 96-byte relay slot (rest zero). Keep this
7
in exact lockstep with ab_ga_il_wire.h - there is no shared schema, same
8
"by-hand port" precedent as SimCore/rbc_wire.py for the flat scheme and
9
TrainRBCSim/rbc_ertms_wire.py for the ERTMS scheme.
10
11
All multi-byte fields little-endian. See ab_ga_il_wire.h for the
12
authoritative byte-offset table.
13
"""
14
15
import
struct
16
17
from
simcore.rbc_wire
import
ENVELOPE_SIZE
18
19
# ---- wire kinds (rbc_wire_types.h) ---------------------------------------
20
KIND_IL_ROUTE_CMD = 25
21
KIND_IL_STATUS = 26
22
KIND_IL_ROUTE_INDICATION = 27
23
24
# ---- enum values (rbc_wire_types.h, rbc_il_* enums) --------------------
25
ROUTE_TYPE_NO_ROUTE = 0
26
ROUTE_TYPE_LOCKED = 1
27
28
ROUTE_STATUS_NO_STATUS = 0
29
ROUTE_STATUS_FS = 1
30
ROUTE_STATUS_OS = 2
31
ROUTE_STATUS_SH = 3
32
ROUTE_STATUS_USED = 4
33
ROUTE_STATUS_DEGRADED = 5
34
35
DEGRADED_STATUS_NO_STATUS = 0
36
DEGRADED_STATUS_LOW = 1
37
DEGRADED_STATUS_MEDIUM = 2
38
DEGRADED_STATUS_HIGH = 3
39
40
IL_STATUS_DOWN = 0
41
IL_STATUS_RESTARTING = 1
42
IL_STATUS_UP = 2
43
44
EMERGENCY_TYPE_NONE = -1
45
EMERGENCY_TYPE_SAM = 0
46
EMERGENCY_TYPE_CEM = 1
47
EMERGENCY_TYPE_UEM = 2
48
49
_NAME_BY_KIND = {
50
KIND_IL_ROUTE_CMD:
"IL_ROUTE_CMD"
,
51
KIND_IL_STATUS:
"IL_STATUS"
,
52
KIND_IL_ROUTE_INDICATION:
"IL_ROUTE_INDICATION"
,
53
}
54
55
56
def
_slot
(payload):
57
"""Zero-pads @payload out to the full 96-byte relay slot."""
58
if
len(payload) > ENVELOPE_SIZE:
59
raise
ValueError(
"IL message payload exceeds the relay slot"
)
60
return
payload + b
"\x00"
* (ENVELOPE_SIZE - len(payload))
61
62
63
def
encode_route_cmd
(route_type=ROUTE_TYPE_NO_ROUTE, route_status=ROUTE_STATUS_NO_STATUS,
64
degraded_status=DEGRADED_STATUS_NO_STATUS, release_route_request=0,
65
first_route_in_path=0, route_id=-1, start_signal=-1, end_signal=-1):
66
"""RBC_MSG_IL_ROUTE_CMD (IL -> RBC). Fields default to the SPEC
67
defaults ("first value is default value"). route_id/start_signal/
68
end_signal are int32, -1 = unset."""
69
body = struct.pack(
70
"<BBBBBBBB iii"
,
71
KIND_IL_ROUTE_CMD,
72
0,
# reserved
73
route_type & 0xFF,
74
route_status & 0xFF,
75
degraded_status & 0xFF,
76
1
if
release_route_request
else
0,
77
1
if
first_route_in_path
else
0,
78
0,
# reserved
79
int(route_id), int(start_signal), int(end_signal),
80
)
81
return
_slot
(body)
82
83
84
def
encode_il_status
(il_status=IL_STATUS_DOWN):
85
"""RBC_MSG_IL_STATUS (IL -> RBC)."""
86
body = struct.pack(
"<BBH"
, KIND_IL_STATUS, il_status & 0xFF, 0)
87
return
_slot
(body)
88
89
90
def
decode_route_indication
(frame):
91
"""RBC_MSG_IL_ROUTE_INDICATION (RBC -> IL) -> flat dict, or None if
92
@frame is not this kind / too short. emergency_type is a SIGNED byte
93
(-1 = none). route_fsm_state is ab_ga_route_state_t (0..6:
94
NO_ROUTE/LOCKED/FS/OS/SH/USED/DEGRADED)."""
95
if
len(frame) < 24
or
frame[0] != KIND_IL_ROUTE_INDICATION:
96
return
None
97
(_kind, _rsv1, train_in_route, train_has_ma_in_route, emergency_in_route,
98
emergency_type_i8, route_fsm_state, route_fsm_is_stub) = struct.unpack_from(
"<BBBBBbBB"
, frame, 0)
99
route_id, start_signal, end_signal, allocated_train_nid_engine = struct.unpack_from(
"<iiii"
, frame, 8)
100
return
{
101
"route_id"
: route_id,
102
"start_signal"
: start_signal,
103
"end_signal"
: end_signal,
104
"allocated_train_nid_engine"
: allocated_train_nid_engine,
105
"train_in_route"
: int(bool(train_in_route)),
106
"train_has_ma_in_route"
: int(bool(train_has_ma_in_route)),
107
"emergency_in_route"
: int(bool(emergency_in_route)),
108
"emergency_type"
: emergency_type_i8,
109
"route_fsm_state"
: route_fsm_state,
110
"route_fsm_is_stub"
: int(bool(route_fsm_is_stub)),
111
}
112
113
114
ROUTE_FSM_STATE_NAMES = [
"NO_ROUTE"
,
"LOCKED"
,
"FS"
,
"OS"
,
"SH"
,
"USED"
,
"DEGRADED"
]
115
116
117
def
route_fsm_state_name
(v):
118
return
ROUTE_FSM_STATE_NAMES[v]
if
0 <= v < len(ROUTE_FSM_STATE_NAMES)
else
"#%d"
% v
119
120
121
def
kind_name
(kind_byte):
122
return
_NAME_BY_KIND.get(kind_byte)
il.il_wire.kind_name
kind_name(kind_byte)
Definition
il_wire.py:121
il.il_wire.route_fsm_state_name
route_fsm_state_name(v)
Definition
il_wire.py:117
il.il_wire.encode_route_cmd
encode_route_cmd(route_type=ROUTE_TYPE_NO_ROUTE, route_status=ROUTE_STATUS_NO_STATUS, degraded_status=DEGRADED_STATUS_NO_STATUS, release_route_request=0, first_route_in_path=0, route_id=-1, start_signal=-1, end_signal=-1)
Definition
il_wire.py:65
il.il_wire.encode_il_status
encode_il_status(il_status=IL_STATUS_DOWN)
Definition
il_wire.py:84
il.il_wire._slot
_slot(payload)
Definition
il_wire.py:56
il.il_wire.decode_route_indication
decode_route_indication(frame)
Definition
il_wire.py:90
src
il
il_wire.py
Generated by
1.18.0