Skip to content

benchpod 0.6.0: USB network for firmware 3.9.0, usb-bridge service, compatibility - #27

Merged
wardviaene merged 36 commits into
mainfrom
usb-net
Oct 13, 2026
Merged

wardviaene merged 36 commits into
mainfrom
usb-net

Conversation

@wardviaene

@wardviaene wardviaene commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

One PR for the CLI side of firmware 3.9.0 (phase 2 from the closed #28 is folded in). It releases together with embeddedci-com/benchpod-firmware#47, embeddedci-com/embeddedci-python#34 and embeddedci-com/embeddedci-server#115.

--connection usb

  • Firmware 3.9.0+: every command uses the pod's USB network adapter. That covers status, la voltage, flash (DAP over TCP), the wiring lookup, install-blobs (and the blob steps of flash-self/set-wifi), and cloud ca/cloud proxy (the USB link may change those).
  • USB networking off (Wi-Fi configured) or down: the pod's Ethernet or Wi-Fi address from the console status, checked with a JSON ping. The CLI says which and why; the external LAN policy applies there. Otherwise there is a clear error naming clear-wifi.
  • Console only: lan-policy, sig-policy, identity, set-wifi/show-network/clear-wifi, dfu, bootsel (physical presence).
  • usb:<name> picks one of several pods; plain usb with several pods lists them.
  • discover: prefers the USB link address, and --save stores usb.
  • status: a USB line (addresses, a weak USB-C port warning) and a Power draw line (rails and the pod's own 0x41 draw).

usb-bridge

  • What it does: an HTTP CONNECT proxy on this computer's end of the USB link (pod only, port 443 only). It sets the pod's cloud proxy over the USB link and clears it on stop. It never opens the USB console, so the web wizard (WebSerial), terminals and other commands keep it.
  • --watch: waits for the pod by watching the local interfaces (no serial probing), and survives unplugging and reboots.
  • usb-bridge install | uninstall | status: a per-user service (launchd, systemd --user, a Windows scheduled task at logon).
  • Linux: a packaging/linux/70-benchpod.rules udev rule (ModemManager off the console) ships in the archives.

Firmware updates

flash-self --enter-dfu records the pod's USB serial number and finds the pod again under its new USB ID (0483:5740 → 1209:xxxx), waiting up to 150 s for Windows to install drivers and assign a new COM port.

Backward compatibility (decided per pod, from its console status, never from the CLI version)

  • This CLI + firmware before 3.9.0: everything as before over the console, including install-blobs, flash-self's blob step and cloud ca set. The 0483:5740 and 2E8A IDs are still detected.
  • Released CLI 0.5.x + firmware 3.9.0:
    • recovery and policy commands work;
    • la voltage over USB and every upload print the pod's "moved to the network API ... update the benchpod CLI to 0.6.0" line;
    • over a network address everything works.
  • The README has the full table, Windows 10 (supported, not tested) and WSL2 (not tested).

Tests

  • go test ./... passes. It covers USB resolution and its fallbacks, usb:<name>, discovery, the CONNECT proxy, the bridge never touching the console (idle, ready, foreground), the service definitions, both firmware generations (la voltage, power, the moved line, blob target choice) and USB serial-number re-find.
  • HW on baea06 (macOS): usb-bridge (foreground and launchd), flash-self 3.8.1 ↔ 3.9 over USB, and the LAN fallback with external LAN open/off.
  • The full release-gate e2e is pending (report in benchpod-firmware#47).

🤖 Generated with Claude Code

wardviaene and others added 9 commits October 12, 2026 20:40
… usb-reattach

Firmware 3.9.0 makes the pod's USB device also a network adapter with the
full network API on a fixed 10.237.x.y address. A command that needs the
network and gets a USB connection (usb or a device path) now reads that
address from the console's status, checks the pod answers there and uses it;
when it cannot (old firmware, Wi-Fi configured, adapter not up) the error
says why. The console stays for the commands it runs. The serial auto-detect
ranks the new VID 1209 (1209:0001) with 2E8A and 0483.

usb-bridge runs an HTTP CONNECT proxy on the computer's end of the USB link
(serving only the pod, tunnelling only to port 443), sets it as the pod's
cloud proxy and clears it on Ctrl-C. usb-reattach re-enumerates the pod on
USB (macOS ignores a new adapter under a locked screen). README updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A pod advertises itself on every interface, so a computer with the pod on
USB and on the LAN heard both and kept whichever came last. discover now
merges the addresses per pod and picks the USB link (10.237.0.0/16) when
there is one; --save then stores usb, which keeps working over the console
when Wi-Fi turns USB networking off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two pods on one computer each have their own USB link. The console probe
now reads each pod's identity: usb:<name> (baea06, benchpod-baea06) opens
that pod, and plain usb with several pods errors with their names instead
of taking whichever port came first. One pod's macOS cu/tty twins count once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
--watch waits for the pod, notices when this computer loses the USB link
address and picks the pod up again, keeping the pod's proxy if it already
points here. usb-bridge install runs it at login for this user (launchd
agent on macOS, systemd user unit on Linux, a scheduled task at logon on
Windows); uninstall removes it and clears the pod's proxy when it points at
this computer; status says whether it is installed and running.

HW (macOS, baea06 with Ethernet stopped): install -> cloud connected through
the agent in ~4 s; usb-reattach -> the agent waited and resumed, cloud
connected; uninstall -> agent gone, proxy cleared.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
packaging/linux/70-benchpod.rules sets ID_MM_DEVICE_IGNORE for 1209:0001
(firmware 3.9.0+) and 0483:5740 (older firmware); the release archives
ship it and the README says how to install it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es the network

status shows the pod's USB network address and warns when the USB-C port
powering the pod advertises only default USB power (500 mA). status over
usb now asks over the USB network adapter when it is up (the full summary)
and falls back to the console's text. networkTarget probes the console once
per run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… network

Phase 2 of USB networking, ahead of trimming the firmware console: with a
USB connection, the commands that work both ways use the pod's USB network
adapter when it is up and the console otherwise. la voltage, flash (the
DAP probe over TCP), the wiring profile lookup, and install-blobs (also the
blob steps of set-wifi and flash-self), which now sends blobs with
blob_status + ota_* through the USB network. Policies, the cloud CA/proxy,
Wi-Fi and identity stay on the console.

HW (macOS, baea06): la voltage --connection usb answers over 10.237.8.85;
install-blobs --only gw1 --force through the USB network: 102 KB in 2.3 s,
pod signature check ok.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wardviaene

Copy link
Copy Markdown
Member Author

Added since the first push (all HW-checked on macOS with baea06 unless noted):

  • discover prefers the USB address: it merges each pod's mDNS addresses across interfaces and picks the USB link (10.237.0.0/16). --save stores usb for such a pod.
  • usb:<name>: picks one of several pods on USB. Plain usb with several pods errors and lists them; one pod's cu/tty twins count once.
  • Background service: usb-bridge --watch plus usb-bridge install | uninstall | status (launchd, systemd --user, Windows scheduled task). On macOS, install connected the cloud through the agent in ~4 s with Ethernet stopped, the agent recovered from usb-reattach, and uninstall cleared the proxy. The Linux unit generation is unit-tested only; Windows is not HW-tested.
  • Linux udev rule: packaging/linux/70-benchpod.rules (ModemManager ignore for 1209:0001 and 0483:5740), shipped in the release archives. Not tried on a Linux box.
  • status: gains a USB line with a warning when the USB-C port offers only default power (500 mA). status --connection usb uses the USB network when it is up.

Phase 2 (la voltage, flash, blob installs over the USB network) is in #28.

wardviaene and others added 8 commits October 12, 2026 21:21
…monitor

benchpod status reads power_status: the current and voltage of each rail
that is on and, on boards with the pod's 0x41 monitor, the pod's own draw
and the total it takes from USB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the USB network unusable (Wi-Fi configured, adapter not up) the
console fallback met a firmware that moved la-voltage and power to the
JSON API, and la voltage said to update the firmware. Say what happened
and why the USB network did not work instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…SB network

A console that answers unknown command to la-voltage is either too old to
have it or 3.9.0+ (which moved it to the JSON API); only the latter
reports a USB network. Also gofmt flash.go.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… generations

Firmware 3.9.0 (benchpod-firmware#48) answers la-voltage, power and the
other commands it moved to the JSON API with a moved-to-the-network-API
line instead of unknown command. The console client reports it as
ErrMovedToNetwork, which la voltage and flash turn into the reason the USB
network was not usable. Tests: la-voltage and power against an older and a
3.9.0 console, the la voltage message for each, and install-blobs staying
on the console for firmware before 3.9.0 and for a pod with Wi-Fi set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… 10 note

The CLI decides per pod from what it reports, never from its own version.
Windows 10 (1903+) is supported but not tested, with the manual driver
pick (UsbNcm Host Device) as the fallback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wardviaene and others added 6 commits October 12, 2026 22:23
On firmware 3.9.0+ with Wi-Fi configured (USB networking off) or the
adapter not up, the trimmed console has no la-voltage or power, so a
command over usb had no way in. It now uses the pod's Ethernet or Wi-Fi
address from the console's status when that answers on :8080, says which
address and why, and notes that the external LAN policy applies there;
when it does not answer either, the error names both and clear-wifi.
Firmware before 3.9.0 keeps the console path. README table updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the external LAN policy off the pod accepts a TCP connection and resets
it, so the fallback now checks a JSON ping answers, not just a connect.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
la voltage asked again for the reason after opening the console, which then
failed to open the port a second time and reported no console found. Keep the
first answer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wardviaene

Copy link
Copy Markdown
Member Author

Added: LAN fallback for usb. On firmware 3.9.0+ whose USB networking is off (Wi-Fi configured) or down, a network command over usb uses the pod's Ethernet or Wi-Fi address from the console status when a JSON ping answers there, and prints which address and why (the external LAN policy applies there). A bare TCP connect is not enough: with the policy off the pod accepts and resets. When neither answers, the error names both and clear-wifi. Firmware before 3.9.0 keeps the console path. HW on baea06 with the #48 trimmed firmware and Wi-Fi set: la voltage --connection usb went to 192.168.1.220 with the note; with the external LAN off it gave the combined error. Wi-Fi was cleared again afterwards.

wardviaene and others added 3 commits October 12, 2026 22:34
The background service opened the pod's USB console every 10 s while the
pod was not ready, which can last (Wi-Fi configured, a locked Mac, no pod):
it fought the web app's setup wizard (WebSerial), terminals and other
commands for the port (exclusive on Windows), and with no pod plugged in
the auto-detect probed other serial devices, typing status into ST-Link
COM ports. --watch now watches the local interfaces for a pod's USB
network link (10.237.x.y/30; the pod is the other host), reads the pod's
proxy over that link (cloud_proxy is readable at the LAN tier), and opens
the console once only to set the proxy, and once to clear it on stop.
usb:<name> picks the link by the pod's identity over the API. Tests: no
console use while idle, none when the proxy is already ours or someone
else's, exactly one set and one clear otherwise.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From firmware 3.8.x to 3.9.0 the pod's USB ID changes (0483:5740 ->
1209:xxxx), so after the reboot it is a different USB device: the port may
be renamed, and Windows installs drivers and assigns a new COM port.
flash-self --enter-dfu records the console's USB serial number (the same on
every firmware) and waits up to 150 s for a pod console with that serial
number under any pod USB ID before installing the blobs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wardviaene and others added 3 commits October 12, 2026 22:43
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…re-find)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the console

Firmware 3.9.0 lets the USB network link change the company CA and the
cloud proxy (physical presence) and drops the console uploads. So over usb:
cloud ca and cloud proxy use the JSON API on the USB link (the console only
on older firmware or without the link); install-blobs and the blob steps of
flash-self and set-wifi go over the USB network, else the pod's Ethernet or
Wi-Fi address, with a clear error instead of the gone console upload; and
usb-bridge (foreground and --watch) and usb-bridge uninstall read, set and
clear the proxy over the USB link, so they never open the console. README:
the per-connection table, the compatibility table (older CLIs on 3.9.0 can
no longer upload), cloud ca set and usb-bridge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wardviaene wardviaene changed the title usb: network commands over the pod's USB network adapter; usb-bridge, usb-reattach benchpod 0.6.0: USB network for firmware 3.9.0, usb-bridge service, compatibility Oct 13, 2026
wardviaene and others added 7 commits October 12, 2026 23:22
Runs status, ping, LA, capture, network, policies, identity, cloud proxy/CA
set+clear, install-blobs gw1, SWD flash and usb-reattach against a real pod;
prints PASS/FAIL/SKIP per step and exits with the failure count. Over usb on
baea06 (3.9.0 candidate): 19 passed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Firmware 3.9.0 takes cloud_ca and cloud_proxy changes over the USB network
adapter as well as the console, so the refusal on Ethernet/Wi-Fi now reads
"<verb>: change it from the cloud or over USB". sig_policy and lan_policy keep
"... or the USB console". Host tools accept both texts (older firmware).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Under external LAN policy locked, firmware 3.9.0 still takes T2/T3 commands
over its USB network adapter, so the refusal on Ethernet/Wi-Fi now reads
"locked: <cmd> needs the cloud or USB". Host tools match the "locked:"
prefix; hwe2e accepts both texts (older firmware).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The proxy is set and cleared over the USB network link since 3e02477; the
help still described the older console step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On Linux the console (/dev/ttyACM0, root:dialout 0660) is closed to users
outside the dialout group, and 'usb' then failed with "no bench-pod console
found". Network commands over usb (and the CA/proxy USB-link path) now take
the pod's address from this computer's end of its USB network link, as
usb-bridge does, with no console; usb:<name> picks by identity. A pod console
refused for lack of permission now says so, with the dialout / udev fix. The
udev rule adds TAG+="uaccess" so the desktop user can open the console.
Found in the 3.9.0 Linux e2e run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…console

Like the network commands, 'lan-policy'/'sig-policy' (show) and install-blobs
now reach a 3.9.0 pod through this computer's end of its USB network link
without opening the console, so they work for a Linux user outside the
dialout group. Policy changes stay on the console. hw-e2e.sh gets
--flash-args for hosts without the cloud wiring profile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wardviaene
wardviaene merged commit 2a0a511 into main Oct 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant