librescoot-ums (ums-service)¶
Description¶
Manages USB gadget mode switching on the MDB between network (g_ether) and USB Mass Storage (g_mass_storage) modes. In UMS mode, exposes a 1 GB FAT32 virtual drive at /data/usb.drive to the host PC. On switching back to normal mode, processes files placed on the drive: syncs settings and WireGuard configs, installs Mender updates and RPMs, runs scripts, and transfers maps to the DBC.
Command-Line Options¶
REDIS_ADDR=localhost:6379 Redis server address (environment variable)
REDIS_PASSWORD= Redis password (environment variable)
UMS_MAP_TIMEOUT=10m Per-file timeout for map transfers (environment variable)
UMS_RPM_TIMEOUT=5m Per-file timeout for RPM transfers (environment variable)
UMS_SCRIPT_TIMEOUT=2m Per-file timeout for script transfers (environment variable)
UMS_MENDER_TIMEOUT=15m Per-file timeout for Mender update transfers (environment variable)
Redis Operations¶
Hash: usb¶
Fields read/written:
mode- Current USB mode (normal,ums,ums-by-dbc)
Fields written:
status- Service status (idle,preparing,active,processing,awaiting-reboot)awaiting-rebootis set while a UMS-initiated update install runs and the service waits for the post-install reboot (see UMS exit flow). It transitions back toidleonce the reboot is triggered, the wait fails/times out, or a new UMS session cancels the pending reboot.step- Current processing step (settings,wireguard,radio-gaga,uplink-service,onboot,updates,maps, or empty). The RPM and script stages run without settingstep.progress- Upload progress percentage (0–100) during file transfersdetail- Human-readable transfer sub-step (e.g.map.mbtiles (120/380 MB))
Subscribed channel: usb
mode- Triggers mode switch when published
List: usb:log¶
Processing events are pushed here in real-time during UMS exit processing. Capped at 100 entries. Also written to ums_log.txt on the drive at the end of processing.
LED feedback¶
Uses blinker channels 3, 4, 6, 7 via scooter:led:fade to indicate UMS state:
| State | LEDs |
|---|---|
| UMS active (host connected) | All 4 blinker channels on |
ums-by-dbc: first disconnect, waiting for PC |
Front blinkers (3, 4) only |
| Normal / off | All 4 off |
USB Modes¶
# Switch to USB Mass Storage mode
redis-cli HSET usb mode ums
redis-cli PUBLISH usb mode
# UMS mode with DBC-specific double-disconnect behavior
redis-cli HSET usb mode ums-by-dbc
redis-cli PUBLISH usb mode
# Return to normal (g_ether) mode
redis-cli HSET usb mode normal
redis-cli PUBLISH usb mode
Mode behavior:
- ums — returns to normal after first USB disconnect
- ums-by-dbc — stays in UMS after first disconnect, switches to normal after second disconnect (for DBC updates, which may disconnect and reconnect mid-process)
- normal — standard g_ether USB network mode
Brake exit¶
The service subscribes to the input-events channel and acts on exactly one
event, brake:left:hold (vehicle-service emits it after a 3 s hold). Other
namespaced gestures such as brake:right:press and seatbox:tap are ignored,
so a stray input cannot interrupt a transfer.
What the hold does depends on where the service is:
- While preparing (
statusispreparing): the entry is abandoned beforeSwitchModeruns. The drive is already unmounted and the gadget was never touched, sog_etherstays loaded and the DBC's link survives.usb.modeis reconciled back tonormalandstatusreturns toidle. Librescoot 1.2 and later. - Once UMS is active:
doSwitchToNormalruns, which is the same path as a USB eject: the full exit processing below happens, including any queued update install and reboot. It is not a bail-out.
The cancel flag is recorded before taking the service mutex, because
switchToUMS holds that mutex for the whole preparing phase; setting the flag
first lets the in-flight entry observe it and abandon itself.
scootui-qt mirrors this on the UMS overlay, labelling the left-brake hold
Cancel while status is preparing and Exit otherwise.
Virtual Drive¶
1 GB FAT32 image at /data/usb.drive:
/
├── settings.toml # copied from /data/settings.toml if present
├── wireguard/ # WireGuard VPN configs
│ └── *.conf
├── radio-gaga/
│ └── config.yaml # copied from /data/radio-gaga/config.yaml
├── uplink-service/
│ └── config.yaml # copied from /data/uplink-service/config.yaml
├── onboot.sh # copied from the on-boot script if present
├── system-update/ # place .mender or .delta update files here
│ ├── librescoot-mdb-*.mender
│ └── librescoot-dbc-*.mender
├── maps/ # place map files here
│ ├── *.mbtiles
│ └── *tiles.tar or valhalla_tiles_*.tar
├── rpms/
│ ├── mdb/ # RPMs to install on MDB
│ └── dbc/ # RPMs to transfer and install on DBC
├── scripts/
│ ├── mdb.sh # shell script to run on MDB
│ └── dbc.sh # shell script to transfer and run on DBC
├── log-bundles/ # pre-populated: bundles previously captured with lsc
├── diagnostics/ # pre-populated on UMS entry (read-only for user)
│ ├── mdb/
│ └── dbc/ # only if DBC was reachable at UMS entry
└── ums_log.txt # written on exit, survives the post-processing wipe
File Processing¶
On UMS entry¶
- Copies
/data/settings.tomlto drive root (if present) - Copies
/data/wireguard/*.conftowireguard/ - Copies
/data/radio-gaga/config.yamltoradio-gaga/and/data/uplink-service/config.yamltouplink-service/ - Copies the on-boot script to
onboot.sh - Creates
system-update/,maps/,rpms/mdb/,rpms/dbc/,scripts/andlog-bundles/directories - Copies existing log bundles from
/data/log-bundlestolog-bundles/ - Collects diagnostics to
diagnostics/mdb/(journal, dmesg, system info) anddiagnostics/dbc/if DBC is reachable
The config files above are round-trips: whatever comes back on exit is read into place, and an untouched file is a no-op.
On UMS exit (returning to normal mode)¶
- Settings - copies
settings.tomlback to/data/, restarts settings-service if changed - WireGuard - syncs
*.conffiles to/data/wireguard/, removes local configs absent from drive, restarts settings-service if changed - radio-gaga - copies
radio-gaga/config.yamlback to/data/radio-gaga/, restartsradio-gaga.serviceif changed - uplink-service - copies
uplink-service/config.yamlback to/data/uplink-service/, restartslibrescoot-uplink.serviceif changed - onboot - copies
onboot.shback into place - Updates - MDB
.mender/.deltafiles installed locally viascooter:update:mdb; DBC.mender/.deltafiles transferred to DBC and queued viascooter:update:dbc - Maps - transfers
.mbtilesto/data/maps/map.mbtileson DBC; transfers Valhalla tile archives to/data/valhalla/tiles.taron DBC - RPMs - installs
rpms/mdb/*.rpmlocally viarpm -Uvh --force; transfers and installsrpms/dbc/*.rpmon DBC - Scripts - runs
scripts/mdb.shlocally; transfersscripts/dbc.shto DBC and runs it remotely - Writes
ums_log.txtto drive root, then cleans the drive (preservingums_log.txt)
Each step is independent: a failure is logged to usb:log and the remaining
steps still run.
Post-update reboot: if the exit processing queued an MDB or DBC update install, the service sets status to awaiting-reboot and a background watcher performs the install pushes, waits for completion (10 min timeout), then triggers a reboot. The reboot is gated on the vehicle state being in an allowed set (stand-by, parked, shutting-down); if the state is anything else, the reboot is skipped. MDB updates reboot the MDB via scooter:power; DBC-only updates power-cycle the dashboard via scooter:hardware. The watcher is cancellable: re-entering UMS cancels a pending reboot. When no update is queued, status goes straight back to idle with no reboot.
Hardware¶
- Network mode:
g_etherkernel module - UMS mode:
g_mass_storagekernel module - Requires root for
modprobe/rmmodoperations - DBC file transfers: HTTP PUT to port 8080 on
192.168.7.2(primary); SCP fallback. MDB serves staging files over HTTP at192.168.7.1:31337.
File Locations¶
| Path | Purpose |
|---|---|
/data/usb.drive |
Virtual USB drive image |
/data/settings.toml |
Device settings |
/data/wireguard/ |
WireGuard VPN configs |
/data/ota/ |
OTA update staging |
/data/dbc/ |
DBC file staging |