Repository navigation
RocNet Compatibility Matrix
Status: RocNet is now the protocol Hive-Rail speaks on the mesh. The mesh design is in RocNet on the Mesh. This page remains the reference for carrying RocNet from local RocNet transports (UDP, TCP, MQTT, serial) across the mesh. Its proposed
frame_hexJSON envelope is replaced by binary RocNet frames with a Zenoh attachment.
RocNet is the railway application protocol: its groups and actions describe locomotive, command-station, stationary-device, sensor, and related messages. UDP, TCP, MQTT, and serial are transports used by RocNet deployments. Hive-Rail adds Zenoh as another transport so RocNet messages can cross the distributed mesh; Zenoh does not replace or reinterpret the RocNet messages.
local RocNet equipment <-> existing RocNet transport <-> module adapter <-> Zenoh mesh
<-> module adapter <-> existing RocNet transport <-> local RocNet equipment
This is a compatibility target, not an implemented feature. Initial compatibility means preserving RocNet message semantics across the additional Zenoh transport, not translating RocNet into a new Hive-Rail railway protocol. It does not imply OpenLCB/LCC compatibility; translation between RocNet and another railway protocol requires a separate, explicit mapping.
| Transport | Role at a module | Hive-Rail relationship | Compatibility requirements |
|---|---|---|---|
| UDP | Existing local RocNet transport | Adapter receives/sends RocNet frames and carries them over Zenoh to the remote module adapter | Preserve frame boundaries, addressing, broadcast behavior, and request/reply behavior |
| TCP | Existing local RocNet transport | Same RocNet messages carried through the Zenoh mesh | Preserve stream framing, reconnect behavior, ordering, and request/reply behavior |
| MQTT | Existing local RocNet transport | Bridge the existing RocNet/MQTT endpoint to a Zenoh mesh peer | Preserve topic-to-address mapping, QoS, retain/session behavior, and avoid echo loops |
| Serial | Existing local RocNet transport | A local adapter reads/writes the serial framing and carries complete RocNet messages over Zenoh | Preserve framing, byte/ASCII encoding, timing, and reconnect behavior |
| Zenoh | Additional Hive-Rail mesh transport | Carries RocNet frames between module adapters and separately carries Hive-Rail distributed-coordination traffic | Keep sessions isolated; route to the intended module; preserve frame payloads and required delivery semantics |
The exact transport behavior can vary by RocNet implementation/version. Confirm framing, addressing, and delivery guarantees for each supported endpoint rather than assuming every transport has identical semantics.
The supplied RocNet protocol reference describes UDP 8-bit as the default and recommended method, using multicast address 224.0.0.1 and port 4321. It describes RocNet as peer-to-peer/masterless, with Rocrail acting as an ordinary network participant rather than a required master. It also defines these discovery-related behaviors:
- Recipient ID
0is broadcast: every unit evaluates the message. The reference says this can be used for queries to see which devices are available. - Stationary group action
identifycan report a node's class, manufacturer ID, version, I/O count, and sub-IP fields. - Reserved node ID
65535is the initial ID for a new node; the reference says the Rocrail server assigns a new ID. - Network ID
0means all networks.
This gives us a practical LAN discovery starting point, but it does not by itself provide the topology and binding model Hive-Rail wants. The reserved-ID note says a new node starts at 65535 and a Rocrail server assigns a new ID, even though RocNet otherwise describes a masterless network. We need to determine whether that assignment is optional Rocrail behavior or required for interoperable RocNet nodes. Hive-Rail must not silently become a required master; it could preserve existing RocNet IDs within each network and use a separate stable Hive-Rail node identity.
Hive-Rail node discovery is separate from RocNet's local discovery. The prototype uses Zenoh's native peer scouting at 224.0.0.224:7446; it does not bind to RocNet/RocRail's 224.0.0.1:4321. If a future local RocNet UDP adapter joins the Rocrail multicast group for interoperability, that remains a local transport adapter and must not be mistaken for Hive-Rail mesh discovery.
For the first single-subnet prototype, test multicast query and identify without changing IDs or sending control commands. Then establish how the discovered RocNet node IDs map to Hive-Rail module IDs and how those announcements are bridged to Zenoh. Multicast discovery is LAN-local; cross-subnet peers still need Zenoh discovery/bootstrap.
The group IDs and action names below come from the supplied RocNet protocol page and rocnet-const.h reference. This table describes intended routing, not a claim that every message has been validated or implemented.
| RocNet group | Examples in the reference | Local-to-mesh direction | Mesh-to-local direction | Initial compatibility plan |
|---|---|---|---|---|
0 Host |
ping, pong, shutdown | Node status and replies | Host requests to addressed RocNet nodes | Preserve request/reply and origin; define whether shutdown may cross a module boundary |
1 Command station |
track power, halt, velocity, function, POM, switch, output | State, replies, and local command results | Commands addressed to the local command station | Preserve addresses and action data; keep local power/safety policy authoritative |
2 Mobile |
setup, velocity, functions, query, RocMouse, acknowledgement | Throttle input, query responses, and acknowledgements | Remote throttle commands and queries | First-pass locomotive-control target; preserve loco address, speed, direction, functions, and response semantics |
3 Stationary |
port, port-pair and multi-port actions; query, report, identify, error, acknowledgement | Occupancy/device reports, identity, errors, and acknowledgements | Turnout, signal, and stationary-device requests | First-pass accessory target; retain port identity and distinguish request, event, and reply |
4 PT mobile |
Programming-track/mobile actions | Responses from the local programming path | Programming-track requests | Defer until exact group/action definitions and permissions are confirmed |
5 PT stationary |
Programming-track/stationary actions | Responses from local stationary programming | Programming requests to local equipment | Defer; never relay programming writes by default |
6 GP data |
General-purpose data | Preserve only when enabled for the peer | Deliver only when enabled for the local adapter | Opaque pass-through initially; do not assign undocumented semantics |
7 Clock |
set, sync | Local clock reports if defined | Clock synchronization to local nodes | Optional; validate time source and authority before forwarding |
8 Sensor |
report, sensor ID/RFID report, acknowledgement | Sensor occupancy, status, and identification reports | Acknowledgement or supported sensor configuration | First-pass feedback target; preserve sensor ID, state, port, and optional locomotive identifier |
9 Output |
on, off; output type/value/address | Output state feedback only if defined | Accessory/output actions to a local node | First-pass accessory target; allowlist supported output types and addresses |
10 Input |
Reference says the group is unused; use Sensor group | None until specified | None until specified | Do not invent messages; use group 8 sensor reports where applicable |
11 Sound |
play, set path/player | Local playback status only if defined | Sound commands for local equipment | Optional peripheral traffic; defer |
12 Display |
text | Display status only if defined | Text/display commands for local equipment | Optional peripheral traffic; defer |
| Unclear in group list | Programming action table includes read/write port configuration, macros, channels, options, and RocNet ID | Replies/events from configuration operations | Configuration and programming requests | Do not route until the group ID, addressing, authorization, and response behavior are verified |
- Local to mesh: a module adapter publishes a RocNet-originated message with the source node/interface and original RocNet addressing preserved.
- Mesh to local: the receiving adapter validates the destination, applies local policy, and delivers the message to the matching RocNet interface.
- RocNet to RocNet: preserve the RocNet message rather than translating it through an incomplete Hive-Rail semantic model.
- Cross-protocol: map only explicitly supported meanings. Mark mappings lossless, partial, or unsupported; never silently drop fields or reinterpret an unknown action.
Zenoh carries two distinct kinds of traffic:
- RocNet traffic: existing locomotive, accessory, sensor, and related RocNet messages. Carry their original semantics and addressing through the added transport.
- Hive-Rail coordination: node presence, topology/binding confirmation, district ownership, leases, seam arbitration, and fail-safe coordination across modules.
Do not invent RocNet group meanings or repurpose existing actions for Hive-Rail coordination. First check whether RocNet already defines a suitable message. If it does not, keep the distributed coordination extension separately namespaced and versioned, and document how mixed-version nodes behave. Cross-protocol translation to LCC/OpenLCB remains a separate adapter, not an implicit effect of using Zenoh.
The first implementation should carry the complete RocNet frame as an opaque payload, alongside mesh metadata:
| Mesh metadata | Purpose |
|---|---|
| Session | Prevent traffic from crossing between different layout sessions |
| Source node and local interface | Identify the ingress adapter and support loop prevention |
| Destination node/interface or broadcast scope | Route only to intended module equipment |
| RocNet frame | Preserve net ID, sender, recipient, group, action/type, length, and data |
| Message identity | Support duplicate detection and request/reply correlation where applicable |
Do not treat transport delivery as authorization to actuate equipment. Each node must enforce local policy, and programming/configuration writes should be denied unless explicitly enabled. Preserve request/reply relationships and order where the RocNet operation depends on them. Unknown messages must not be reinterpreted as known commands.
These are illustrative mappings, not an implemented envelope or final Zenoh key schema. The RocNet frame bytes remain unchanged; the Zenoh key and outer envelope provide the mesh session, routing, and loop-prevention context. frame_hex is used here for readability. An implementation may carry the same bytes as a binary payload.
The RocNet reference's “stop all locos” example is:
RocNet UDP frame: 00 00 00 00 01 02 02 03 00 00 00
RocNet ASCII HEX: @0000000001020203000000
The header has network ID 0, recipient 0 (broadcast), sender 1, group 2 (mobile), action 2 (velocity), and data length 3. The three data bytes are velocity, direction, and lights; the reference says direction and lights are unchanged when their change bits are clear.
An illustrative Zenoh publication could be:
Key: hive/fremo-42/rocnet/net/0/broadcast
Payload:
{
"schema": "hive-rail-rocnet-envelope/1",
"origin_node": "module-a",
"origin_interface": "rocnet-udp",
"hop_count": 1,
"frame_hex": "0000000001020203000000"
}
The receiving module adapter validates the session and hop metadata, then sends the unchanged RocNet frame onto its local RocNet transport. It marks the copy as mesh-originated locally so it is not broadcast back onto the mesh, preventing a loop.
The RocNet reference's example for locomotive address 291, velocity 48, forward direction, and lights off is:
RocNet UDP frame: 00 01 23 00 01 02 02 03 30 41 40
RocNet ASCII HEX: @0001230001020203304140
The recipient address is 0x0123 (291). A proposed mesh route could use a Hive-Rail mapping from the RocNet network/address to the node that currently owns that locomotive:
Key: hive/fremo-42/rocnet/net/0/recipient/291
Route: RocNet network 0, address 291 -> current district-owner node
Payload:
{
"schema": "hive-rail-rocnet-envelope/1",
"origin_node": "module-a",
"origin_interface": "rocnet-udp",
"destination_node": "module-b",
"hop_count": 1,
"frame_hex": "0001230001020203304140"
}
destination_node is mesh routing metadata, not a replacement for the RocNet recipient field. The receiving adapter delivers the original frame to the local RocNet endpoint. How Hive-Rail learns or changes the address-to-owner mapping is a separate distributed-ownership question.
Status after reading the official RocNet protocol page:
| # | Answer |
|---|---|
| 1 | UDP and the mesh use the 8-bit binary frame. ASCII hex starts with @, two characters per byte. 7-bit serial sets bit 7 of the net ID as start marker and adds an optional XOR checksum |
| 2 | Hive-Rail uses net ID 0 and a fixed RocNet ID per node from its profile (RocNet on the Mesh §3) |
| 3 | Programming is groups 4 (mobile) and 5 (stationary, including command stations). They stay local to a node |
| 4 | Still open per message type; acknowledgements use stationary action 10 |
| 5 | The page describes RocNet as a binary open source protocol. Hive-Rail implements it from the public page and does not copy Rocrail's C header file |
| 6 | Programming and host shutdown are not routed across the mesh by default |
- What exact byte stream is sent on the local RocNet link: ASCII hex or decoded bytes? What framing delimiter, length rule, and checksum apply?
- How are net ID, node IDs, source, destination, and broadcast address scoped across multiple RocNet networks? Must IDs be rewritten at a gateway?
- The reference lists programming actions but does not make their group assignment clear in the group table. Confirm it from the authoritative protocol/source before routing them.
- Which messages require acknowledgements, retries, ordering, or deduplication? Is a RocNet acknowledgement still valid across the Zenoh hop?
- Can the RocNet protocol page and constants be implemented for interoperability without restrictions? The supplied header states "All rights reserved"; do not copy implementation code until the applicable terms are confirmed.
- Which action groups are allowed across a module boundary by default? In particular, keep programming and shutdown operations opt-in.
- Verify framing, group/action assignments, address scope, and terms against authoritative RocNet documentation and implementation.
- Add a simulator adapter that sends and receives opaque RocNet frames between two Zenoh nodes; test broadcast, unicast, replies, duplicates, and disconnects.
- Add a local RocNet interface and verify the same frame paths with real RocNet equipment, without connecting it to track power.
- Add selected cross-protocol mappings only after choosing the second target protocol and documenting lossless/partial behavior.
RocNet support, OpenLCB/LCC support, and Zenoh are separate layers: RocNet and LCC are railway protocol targets; Zenoh carries traffic between Hive-Rail nodes.