Product: RBC_Test_Sim_Core, shared transport plumbing for the simulators (repository RBC_Test_Sim_Core, package simcore). Layer: verification, Python, not safety-rated. Stands in for an external system; it is not RBC code.
Shared transport-layer plumbing for the ADR-029 Train/IL/CTC RBC simulators (RBC_Test_Sim_Train, RBC_Test_Sim_IL, RBC_Test_Sim_CTC). Extracted from what used to be three separately-duplicated common/ copies inside those projects.
Deliberately scoped to transport-layer mechanics only — TCP/IP session handling, generic envelope byte-packing, generic command-port framing — with zero knowledge of which specific messages/commands any sim actually uses. Each sim's own code is its "application layer," built on top of RBC_Test_Sim_Core, never the other way round.
What's here
- rbc_wire.py — the rbc_envelope_t codec: a byte-verified Python mirror of RBC_GP/src/application/rbc_wire.c/.h's wire layout (byte offsets/types) only. It does not name or enumerate what any kind value means — that's each sim's own message_catalog.json's job. If the C codec's wire layout changes, this mirror needs a matching manual update — nothing enforces the two stay in sync automatically.
- dual_link.py — the dual-homed WEST+EAST TCP link: connects to both sites at once, so a site failover is invisible to the sim using it.
- rbc_messages.py — generic catalog-driven encode/decode. A sim's own message_catalog.json is the sole authority on its message names/kind numbers/fields; RBC_Test_Sim_Core only sanity-checks a declared kind is a plausible wire byte (0–255).
- control_server.py — a real TCP/IP control port (ControlServer) each sim wires up with its own dedicated command table (constructor handlers/json_handlers args). RBC_Test_Sim_Core itself defines no commands — Train's, IL's, and CTC's tables all differ.
- sim_config.py — JSON config-file loader (SIM_CONFIG_PATH, default /app/config.json).
- saf.py — Python mirror of the safe-communication SaF layer (3DES CBC-MAC, KSMAC, AU1-3/DATA/DISCONNECT, sequence window, supervision), byte-identical to Platform_Protocol_SafeComm and tested against C-generated vectors (tests/test_saf.py). Besides the blocking connect(), a frame-driven initiator (initiator_start() / initiator_on_frame() / accept_frame()) for a sim that cannot block.
- saf_train_link.py — SafTrainLink: wraps a train sim's link (DualHomedLink or SafeCommLink) and carries its ERTMS envelopes (kind 22) as SaF Sa-DATA inside RBC_MSG_SAF_ENVELOPE (kind 28), handshaking per train on first use; the Python end of RBC_GP's train-link SaF termination. train_sim enables it with RTE_SAFECOMM_TRAIN_RBC_ID + RTE_SAFECOMM_TRAIN_KEYS_FILE (tests/test_saf_train_link.py).
- status_report.py, safecomm.py — status-reporting and (future) safe-comms transport helpers shared across the sims.
Using it
Each sim project declares dependencies = ["simcore"] in its own pyproject.toml and resolves this package from dist/ (pip install --find-links ./dist simcore) or via Conan (requires = "simcore/0.1.0") — see the workspace dist/ convention in docs/architecture/OVERVIEW.dox, section 6.
Building
python -m build --outdir dist
Interfaces exposed to other products
| Interface | Form | Used by |
| simcore.rbc_wire | Python module: rbc_envelope_t encode and decode (byte offsets and types only) | The three simulators; hand-mirror of RBC_GP's C codec, update both together |
| simcore.rbc_messages | Generic catalog-driven encode and decode | Simulators (each supplies its own message_catalog.json) |
| simcore.dual_link | Dual-homed WEST and EAST TCP link | Simulators |
| simcore.control_server | ControlServer: TCP control port with a caller-supplied command table | Simulators, driven by RBC_Test_Env |
| simcore.sim_config | JSON config loader (SIM_CONFIG_PATH) | Simulators |
| Wheel | dist/simcore-*.whl, Conan simcore/0.1.0 | Simulator builds and Dockerfiles |