Appearance
muxen-portal — Overview
Some of the equipment on a boat is not wired to the Brain. It hangs off a small MUXEN gateway box elsewhere on board, and looking at that equipment used to mean going to the gateway with a laptop. muxen-portal removes that trip: for a few minutes it borrows the gateway, so the bus behind it appears on the Brain and can be worked on from there.
Borrowing is the right word. While a session runs the gateway stops doing its normal job, so whatever it drives goes quiet — the session names what will go offline before it starts, and the boat's screens can show "gateway under maintenance" rather than alarms. None of it is permanent: a session cannot damage a gateway, and switching the gateway off and on again always brings its normal firmware back. That is why it is a deliberate maintenance act rather than something left running.
The rest of this manual is for the installer or integrator doing the work.
muxen-portal mirrors the remote interface of an STM32 gateway as a local interface on the MUXEN Brain. A CAN bus, a serial port or a LIN bus that is physically wired to a gateway elsewhere on the boat becomes a portal0 SocketCAN interface or a /dev/tty-portal0 PTY on the Brain, and ordinary Linux tooling works on it: candump, cansend, picocom, stty, the MUXEN daemons, muxen-uds itself.
The problem it solves
Some buses on board are not wired to the Brain. They hang off an STM32 gateway product — MCUboot + Zephyr, in production, with its own board, DTS, bootloader and signing key. Diagnosing or commissioning a device behind such a gateway used to require physical access to the gateway.
| Gateway family | Remote interface | Local mirror on the Brain |
|---|---|---|
CAN-to-CAN (cancan) | a CAN bus (NMEA 2000, J1939, …) | SocketCAN portal0 |
CAN-to-SERIAL (can-serial_v2) | up to 4 UART channels (VE.Direct, Modbus RTU) | one PTY per channel, /dev/tty-portal0[-chN] |
CAN-to-LIN (can-lin, can-mdv_v2) | up to 3 LIN buses | one SocketCAN portal0chN per channel, sllin mapping |
CAN-to-EnOcean (can-enocean) | one UART to the on-board EnOcean transceiver | /dev/tty-portal0 |
Anything the Brain writes to the local mirror is transmitted on the remote interface; anything received remotely appears locally with its original content. Remote line settings — CAN bitrate, serial baudrate and framing, LIN baud, role and checksum rule — are driven from the Brain.
The full board reference is Supported gateways.
How a session works
- Identify —
muxen-portal open <deviceId|uid>asks muxen-uds for a UID scan and the target's HardwareId, picks the matching signed portal firmware from the muxen-uds firmware store, and records the product identity strings. Refusals — unknown board, offline target — are immediate. - Upload and swap — the image goes through the existing muxen-uds
firmwareupload, then a reset makes MCUboot swap to it in test mode. - Bootstrap — the freshly booted portal announces
READYon a parking ISO-TP pair; the daemon assigns the session instance (SET_INSTANCE), andHELLOreports the gateway's capabilities: channels, rates, FD support, termination control. - Bridge —
OPENconfigures the remote interface per channel; the portal batches remote traffic into tunnel records over ISO-TP on the MUXEN bus, and the daemon feeds the local mirror. - Liveness — the daemon PINGs every second and publishes per-port counters to MQTT and to
muxen-portal stats. - Close —
muxen-portal close, a keep-alive timeout or a power-cycle ends the session; the daemon verifies by scan that the product identity is back.
Sessions covers this in operational detail.
The safety property: unconfirmed firmware
The tunnel is implemented by a dedicated portal firmware for the gateway, and the whole safety model rests on one property of it:
- The Brain uploads the portal firmware through the muxen-uds firmware upload command.
- MCUboot swaps to it in test mode.
- The portal firmware never confirms the image. Any reset or power-cycle makes MCUboot revert to the original application firmware.
A gateway is therefore never permanently modified and cannot be bricked by a portal session. Worst case, power-cycle the gateway and the product firmware is back. The session is transient by construction: on top of the revert, the gateway self-reverts if the Brain stops pinging it (default ~30 s), so a dead Brain cannot leave a product out of service.
At every step of a session, a power-cycle of the gateway returns the product to its original firmware. There is no state in which the portal firmware persists across a reset.
What a session costs you
A portal session is a deliberate maintenance act, not a monitoring mode. While it runs:
- The gateway is not running its product firmware. It is not on the MUXEN bus under its product identity, and whatever it drives is not being driven.
muxen-portal openprints the product identities that will go offline, and theportal/sessionMQTT topic publishes them so alarm logic can show "gateway under maintenance" rather than raw data-loss alarms. - On a bus-extender gateway, the whole bridged segment goes offline and cannot be enumerated. That is inherent: the reason to open a portal onto a bus extender is to debug that segment remotely.
- On a Muxen-native RS-485 segment, the polling master disappears — it was the gateway firmware the session just replaced. A quiet line is the expected reading there.
- One session per Brain. The protocol addresses several gateways concurrently, but the daemon runs one session at a time: close one, open the next.
Transport
The tunnel runs over the MUXEN CAN bus using ISO-TP (ISO 15765-2), carrying batched records: encapsulated classic CAN frames for CAN gateways, timestamped byte chunks for serial gateways, and the same CAN record carrying LIN frames for LIN gateways. It claims the ACCESS = 3 ID band — the lowest arbitration priority in network 0 — so a portal session can never starve normal MUXEN traffic.
Where both ends are FD-capable, the session can negotiate raw CAN-FD framing for the data plane (~3× tunnel throughput) while control stays on ISO-TP. This needs an FD-capable Brain and gateway and a segment carrying no classic-only product, because a single CAN 2.0 node destroys every FD frame on a shared bus. It is off by default (allow-fd). See Tunnel protocol.
Security posture
There is no session authentication, deliberately:
- The MUXEN bus's UDS is unauthenticated: anyone with physical bus access can already reset devices, rewrite config and upload signed firmware. The portal adds no capability an attacker on the bus does not already have — it mirrors a segment to the Brain, and starting a session requires access to the Brain itself.
- The signature chain stays the barrier to code execution. MCUboot only boots images signed with the per-board RSA key, portal images included.
- The tunnel peer is fixed. Portal firmware only accepts control-plane messages addressed from
brainAddr(0x27F), and is transient by construction. - Distribution. Portal
.srecimages ship only inside themuxen-portalDebian package on the internal APT repository — not in themuxen-firmwareblob package or any customer-facing channel.
Access to the mirrors is deliberately wide open: PTY slaves are 0666 and portal0 is an ordinary SocketCAN interface. Shell access to the Brain already implies unauthenticated access to can0, so the mirrors grant nothing new.
Document map
| Document | Content |
|---|---|
| Getting started | install, prerequisites, a first session end to end |
| Sessions | open / run / close, failure modes, recovery |
| The mirrors | the CAN, serial and LIN mirrors and how to drive them |
| Monitoring a session | per-port statistics, wire timing, MQTT state |
| muxen-detect — remote port audit and identity extraction | muxen-detect — remote port audit and identity extraction |
| Supported gateways | supported boards, images and identifiers |
| Troubleshooting | symptom → cause → action |
| Reference — CLI, configuration, packaging | CLI, daemon configuration, MQTT schema, packaging |
| Tunnel protocol | tunnel wire protocol — for client implementers |
| Gateway firmware | gateway firmware architecture, backends, build |
