Document ADB in the car: TCP over the NCM link, one SSH hop via the Orin
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
This commit is contained in:
@@ -24,5 +24,6 @@ flutter test
|
|||||||
flutter run --dart-define=YUKART_GW=ws://<host>:7700/ # default: the car Orin, ws://192.168.55.1:7700/
|
flutter run --dart-define=YUKART_GW=ws://<host>:7700/ # default: the car Orin, ws://192.168.55.1:7700/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- For debugging the app in the car (ADB over the Orin link), refer to [ADB in the car](docs/ADB-IN-CAR.md);
|
||||||
- For implementation practice guidelines, refer to the [guidelines](docs/GUIDELINES.md);
|
- For implementation practice guidelines, refer to the [guidelines](docs/GUIDELINES.md);
|
||||||
- For implementation plans and history, refer to [them](docs/impl/);
|
- For implementation plans and history, refer to [them](docs/impl/);
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
---
|
||||||
|
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
|
||||||
|
|
||||||
|
The NCM link and the app over it are verified (2026-10-09). The ADB path above is
|
||||||
|
**untested in the car**; HyperOS may need its USB-debugging security options for
|
||||||
|
installs over TCP as it did over USB.
|
||||||
@@ -109,23 +109,12 @@ The app binds the process to the USB Ethernet network only when the gateway
|
|||||||
address is on `192.168.55.0/24`, so a desk build pointed at halogen over WiFi is
|
address is on `192.168.55.0/24`, so a desk build pointed at halogen over WiFi is
|
||||||
not routed into a dead USB link.
|
not routed into a dead USB link.
|
||||||
|
|
||||||
### ADB in the car, without a hub
|
### ADB in the car
|
||||||
|
|
||||||
The tablet's only USB port is the Orin link, and in it the tablet is the host —
|
USB debugging is unavailable there: on the Orin link the tablet is the USB host.
|
||||||
USB debugging is unavailable there. ADB over TCP is not, and it travels over the
|
ADB runs over TCP on the NCM link instead, reached from halogen through one SSH
|
||||||
same NCM link:
|
forward via the Orin. Mechanism, steps and troubleshooting:
|
||||||
|
[ADB in the car](../../ADB-IN-CAR.md).
|
||||||
```bash
|
|
||||||
adb tcpip 5555 # at the desk, over USB, once per tablet boot
|
|
||||||
# in the car, from halogen, through the Orin over the tailnet:
|
|
||||||
ssh -N -L 5555:192.168.55.100:5555 mikkeli-orin-nano &
|
|
||||||
adb connect localhost:5555
|
|
||||||
flutter run -d localhost:5555
|
|
||||||
```
|
|
||||||
|
|
||||||
The tablet keeps the RSA authorisation from the USB pairing. `adb usb` turns TCP
|
|
||||||
mode off again; a reboot does too. Android's *Wireless debugging* (pairing) is
|
|
||||||
WiFi-only and does not help here. Untested in the car so far.
|
|
||||||
|
|
||||||
### CI
|
### CI
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user