66eab916bc
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
125 lines
5.4 KiB
Markdown
125 lines
5.4 KiB
Markdown
---
|
||
type: reference
|
||
---
|
||
# ADB in the car
|
||
|
||
**In one line: ADB over TCP on the tablet's USB-Ethernet link to the Orin, reached
|
||
from halogen through one SSH port-forward via the Orin.** TCP mode is armed once
|
||
over a USB cable to halogen, and again after every tablet reboot.
|
||
|
||
## Why USB debugging is unavailable in the car
|
||
|
||
A USB link has exactly one host and one device. The tablet's single USB-C port can
|
||
be either, decided by the USB-C CC resistors at plug-in:
|
||
|
||
| Plugged into | Tablet role | USB debugging |
|
||
|---|---|---|
|
||
| halogen | device | yes: ADB is a USB function the tablet offers as a device |
|
||
| the Orin (via the PD hub) | **host** | no: a host offers no USB functions |
|
||
|
||
A data hub does not help: it adds more devices under the same host. The PD hub in
|
||
the car only passes power through, so the tablet charges while it is the host.
|
||
|
||
## What the link is
|
||
|
||
The Orin runs Jetson's USB device mode (`l4t-usb-device-mode`) and presents itself
|
||
as a USB network adapter, with a DHCP server on it. The tablet's kernel binds it as
|
||
**NCM** and Android brings it up as an ordinary **Ethernet** network:
|
||
|
||
```
|
||
tablet 192.168.55.100 ⇄ USB NCM ⇄ Orin 192.168.55.1
|
||
```
|
||
|
||
The app reaches `svc-gw` over this network. It requests the network explicitly and
|
||
binds to it, because a network without internet never becomes Android's default
|
||
while WiFi or LTE is up. `adbd` is a system daemon and needs none of that: once
|
||
it listens on TCP, it listens on every interface, this one included.
|
||
|
||
## The path from halogen
|
||
|
||
halogen is not on `192.168.55.0/24`; the Orin is. halogen reaches the Orin over
|
||
the LAN or the tailnet (the Orin has an LTE uplink), so one SSH local forward
|
||
bridges the gap:
|
||
|
||
```
|
||
adb (halogen) → localhost:15555 ═SSH═▶ Orin → 192.168.55.100:5555 → adbd (tablet)
|
||
```
|
||
|
||
Authorisation is unchanged: the tablet still checks ADB's RSA key, and halogen's
|
||
key was accepted at the USB pairing. The tablet's port is reachable only from the
|
||
NCM link (and from WiFi, while TCP mode is on and WiFi is up).
|
||
|
||
## Steps
|
||
|
||
**1. Arm, at the desk** (USB cable to halogen; once per tablet boot):
|
||
|
||
```bash
|
||
adb -s 1f1530c87d84 tcpip 5555
|
||
```
|
||
|
||
**2. In the car** (tablet on the Orin, app link up):
|
||
|
||
```bash
|
||
ssh -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=10 \
|
||
-L 15555:192.168.55.100:5555 mikkeli-orin-nano &
|
||
adb connect localhost:15555
|
||
adb devices # → localhost:15555 device
|
||
flutter run -d localhost:15555 --dart-define=YUKART_GW=ws://192.168.55.1:7700/
|
||
```
|
||
|
||
The default gateway address already is `ws://192.168.55.1:7700/`; the define only
|
||
matters if a desk build was installed last.
|
||
|
||
**3. Disarm** (optional): `adb usb` returns ADB to USB only. A reboot does the same.
|
||
|
||
Local port 15555, not 5555: halogen's adb server scans localhost 5555–5585 for
|
||
emulators, and a tunnel there shows up a second time as `emulator-5554`.
|
||
|
||
## When it does not work
|
||
|
||
| Symptom | Check |
|
||
|---|---|
|
||
| `connect` refused or times out | From the Orin: `nc -zv 192.168.55.100 5555`. Refused means TCP mode is off: the tablet rebooted; re-arm over USB |
|
||
| No route to `192.168.55.100` from the Orin | The USB link is down: cable, PD hub, or the tablet asleep (see the initial plan, "The USB link, as measured") |
|
||
| `unauthorized` | Accept the prompt on the tablet; the halogen key was revoked or never accepted |
|
||
| `bind: Address already in use` on 15555 | An old tunnel is still running: `pkill -f 15555:192.168.55.100` |
|
||
|
||
## Alternatives
|
||
|
||
- **adb on the Orin itself.** `adb connect 192.168.55.100:5555` there, no tunnel.
|
||
Needs `adb` installed on the Orin, and `flutter run` stays on halogen anyway.
|
||
- **Wireless debugging** (Android 11+, pairing codes) survives better, but it only
|
||
runs over WiFi, so it does not use this link.
|
||
|
||
## Status (2026-10-11)
|
||
|
||
Tested with the tablet on the Orin, charging through the PD hub:
|
||
|
||
- **Works:** `adb tcpip 5555` on HyperOS, the SSH forward, `adb connect`, `shell`,
|
||
`input`, `screencap`. The app retargeted to `ws://192.168.55.1:7700/` showed
|
||
*USB link up, bound*, the Orin's gateway with no mock banner, and a mark reached
|
||
the recorder (answered *no session*, correctly, with no CAN traffic).
|
||
- **Bulk transfer does not.** The NCM link loses packets under load: ping loss
|
||
rose from 0% at 5 packets/s to as much as 32% at 20 packets/s, mostly small
|
||
packets, with no error counted on the Orin's side. TCP backs off (RTO ~10 s),
|
||
and throughput collapses to **~54 kB/s**. A 20 MB push took 6 minutes. The
|
||
165 MB debug APK install failed, and so will `flutter run`'s first install.
|
||
The app's own traffic (small, 5 Hz) is unaffected so far.
|
||
|
||
**Follow-up the same day: the hub is not the cause.** A replug later, the link
|
||
tested clean through the PD hub with and without the charger, and on a plain
|
||
cable: 0% loss up to 500 packets/s, 0 retransmits. The lossy state did not come
|
||
back. Details: [link test report](impl/reports/LINK-TEST-2026-10-11.md).
|
||
|
||
**adb push stays slow on a healthy link: ~0.14 MB/s**, with the Orin
|
||
retransmitting ~220 segments per 20 MB, while the app's own TCP over the same
|
||
link runs at 2–6 MB/s with none. Specific to the adbd connection; unexplained.
|
||
|
||
So: install at the desk over USB, and use the car path for `logcat`, `shell`,
|
||
screenshots and `am start`.
|
||
|
||
A test trap: commands started from `adb shell` on the tablet use Android's
|
||
default network (WiFi), not the USB link. `nc 192.168.55.1 …` from there gets
|
||
no route. Only sockets bound to the Ethernet network, as the app's are, take the
|
||
link.
|