CTC (Centralized Traffic Control) sim (ADR-029) - a real, dual-homed
TCP client. A single instance oversees both sites (unlike train/il, which
run one pair per train slot) - dual-homed to both sites' CTC port the
same way train_sim.py/il_sim.py are (see dual_link.py's own header),
receive-only: this scenario never has CTC send anything back to the RBC,
it only observes the one-way status pushes (train connected/MA granted/
MA extended) and logs them, tagged by train_id.
Configuration: one JSON file (common/sim_config.py, SIM_CONFIG_PATH env
var, default /app/config.json) - rbcWest/rbcEast and controlServer only
(no trainIndex - CTC is not per-train). See config/ctc.json, right next
to this script. Message vocabulary comes from message_catalog.json, also
right next to this script.
Commands (controlServer.port, config file - see common/control_server.py):
PING Replies "PONG\\n" - liveness check.
Structured JSON commands (tests/robot/design/DESIGN.md,
SIM_INTERFACES.md - same port, see common/control_server.py's own doc).
No sendMessage - CTC never transmits in this scenario:
getMessage {"cmd":"getMessage","nidEngine":N,"message":"CTC_MA_GRANTED"}
Returns the most recently received indication of that
kind concerning train nidEngine, or an ERR if none has
arrived yet.
| _decode_ma_offset |
( |
| raw_offset | ) |
|
|
protected |
ma_length rides the wire as a SIGNED value's raw two's-complement uint32 bit pattern
(CTC_TRAIN_INFO's own message_catalog.json comment) - converts it back to a real signed
Python int. Pure extraction (2026-09-24, for unit-testability - this used to be inline in
main()'s own receive loop, matching the "pure extraction, no logic changed" precedent
RBC_GP's own C code already uses for the same reason, e.g. rte_voter.c's
voter_group_matching_responses()).
Definition at line 58 of file ctc_sim.py.