build(docker): Add remote radio support in docker#201
build(docker): Add remote radio support in docker#201Lakshmi97-velampati wants to merge 14 commits into
Conversation
Add an optional otbr-radio Docker container that connects a Silicon Labs BRD2703 xG24 Explorer Kit to the Barton devcontainer via D-Bus, enabling Thread integration testing with real hardware. - Dockerfile.otbr-radio: builds image with cpcd and otbr-agent compiled for CPC transport; uses the URL spinel+cpc://cpcd_0?iid=1&iid-list=0 to handle both unicast and broadcast Spinel frames - compose.otbr-radio.yaml: compose overlay that shares a D-Bus socket volume with the barton service and maps RADIO_DEVICE at the same path on both the host and container sides - otbr-radio-entrypoint.sh: writes a fresh cpcd config on every start (uart_device_file, uart_hardflow: true), waits for "Daemon startup was successful" before launching otbr-agent, and auto-detects BACKBONE_IF from the host default route at runtime - setupDockerEnv.sh: auto-detects the backbone interface via ip route and writes it to docker/.env; Refs: BARTON-359 Signed-off-by: mvelam850 <munilakshmi_velampati@comcast.com>
There was a problem hiding this comment.
Pull request overview
Adds an optional “real USB radio” Thread Border Router path for Barton’s Docker-based dev environment by introducing an otbr-radio sidecar container (cpcd + otbr-agent) that shares a D-Bus socket volume with the main barton container, enabling Thread integration testing against real BRD2703 hardware.
Changes:
- Add an
otbr-radioDocker image + entrypoint that brings up D-Bus, Avahi, cpcd, then otbr-agent over CPC (spinel+cpc://). - Add a Compose overlay to run
otbr-radiowith host networking/privileges and share/var/run/dbuswithbarton. - Extend tooling/docs:
dockerw -Tflag,.envvariables (RADIO_DEVICE,BACKBONE_IF), and setup instructions.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/THREAD_BORDER_ROUTER_SUPPORT.md | Adds end-to-end documentation for simulated vs real-radio Thread setup, including USB-IP guidance. |
| dockerw | Adds -T flag to include the OTBR radio compose overlay and start the otbr-radio service. |
| docker/setupDockerEnv.sh | Writes optional RADIO_DEVICE and BACKBONE_IF into docker/.env, with backbone IF auto-detection. |
| docker/README.md | Documents the new compose overlay and the -T flag. |
| docker/otbr-radio-entrypoint.sh | New entrypoint that orchestrates D-Bus, Avahi, cpcd, and otbr-agent startup for CPC-based RCP. |
| docker/Dockerfile.otbr-radio | New build for cpcd + otbr-agent (Silabs GSDK transport/CPC) and D-Bus policy. |
| docker/compose.otbr-radio.yaml | New compose overlay that runs otbr-radio privileged with host networking and shares D-Bus socket volume with barton. |
kfundecmcsa
left a comment
There was a problem hiding this comment.
I have a couple open questions, but requesting changes for the title. This effort should fall into the build commit type, not feat
Updated |
|
Be sure to take this PR out of draft when you are ready for re-review. |
@tleacmcsa yes, you can try this. |
|
Marked comments resolved |
tleacmcsa
left a comment
There was a problem hiding this comment.
This generally worked with the exception that I had to change the DBUS_SYSTEM_BUS_ADDRESS value set in compose.otbr-radio.yaml to point to the otbr-dbus path.
Thread subsystem worked, but I could not commission a Matter+Thread device since there is no bluez/Bluetooth support. We need to add bluez in the same container as otbr-agent since they both can use the same radio for Thread and bluetooth. Its fine with me if the bluetooth/bluez part comes in a follow-up PR though.
To confirm, were you able to commission a Matter+Thread device in this configuration? How did you decide it was successful, the Thread subsystem showing ready?
| volumes: | ||
| - dbus-socket:/var/run/otbr-dbus | ||
| environment: | ||
| - DBUS_SYSTEM_BUS_ADDRESS=${DBUS_SYSTEM_BUS_ADDRESS:-unix:path=/var/run/dbus/system_bus_socket} |
There was a problem hiding this comment.
Why isnt this the otbr-dbus?
There was a problem hiding this comment.
unix:path=/var/run/dbus/system_bus_socket fallback is the safe default for the no-hardware case, and dockerw -T (or the devcontainer environment when hardware is configured) overrides it to the private bus.
There was a problem hiding this comment.
FYI, i am only testing the devcontainer method (as I expect most users of this would since we almost always work in the IDE). I did not see how to get this working without hacking on this yaml file to change it to the otbr-dbus. Please try that out and be sure to test with devcontainer.
There was a problem hiding this comment.
Sure will try it.
2e68240
Thanks for testing this and for adding the BLE support. Apologies, I haven’t validated the commissioning flow yet. My checks were limited to confirming that the otbr-agent is running in the new container. I’ll verify the commissioning flow now with the BLE changes you’ve added and confirm the results. |
| # AF_BLUETOOTH (e.g. bluetoothctl) can run via nsenter. | ||
| - /proc/1/ns/net:/run/host-netns:ro | ||
| environment: | ||
| - DBUS_SYSTEM_BUS_ADDRESS=${DBUS_SYSTEM_BUS_ADDRESS:-unix:path=/var/run/otbr-dbus/system_bus_socket} |
| 2. If using Matter, configure and build your Matter SDK as described in [MATTER_SUPPORT.md](). | ||
| 3. If using Zigbee, see [ZIGBEE_SUPPORT.md](). | ||
| 4. If using OpenThread's Border Router, see [THREAD_BORDER_ROUTER_SUPPORT.md](). | ||
| 4. If using OpenThread's Border Router, see [REMOTE_RADIO_FOR_DEVELOPMENT.md](). |
| if echo "${HCI_DEVICES}" | grep -q "hci${BLE_ADAPTER_ID}"; then | ||
| pass "hci${BLE_ADAPTER_ID} is present in host network namespace" | ||
|
|
||
| HCI_STATUS=$(echo "${HCI_DEVICES}" | grep -A2 "hci${BLE_ADAPTER_ID}:" || true) |
| echo "[otbr-radio] Starting cpcd (instance: cpcd_0, device: ${RADIO_DEVICE})..." | ||
| CPCD_LOG="/tmp/cpcd.log" | ||
| : > "${CPCD_LOG}" | ||
| cpcd --conf "${CPCD_CONF}" > >(tee "${CPCD_LOG}") 2>&1 & |
hcitool uses the legacy HCI socket interface which permanently conflicts with bluetoothd's MGMT socket. Starting an LE scan via hcitool and killing it leaves the kernel MGMT layer stuck, causing all subsequent StartDiscovery calls to fail with InProgress. Changes: - Rewrite ble_verify_scan() to use hciconfig instead of hcitool lescan - Make ble_health_check() passive (read D-Bus properties only, no StartDiscovery/StopDiscovery) to avoid conflicts with Matter SDK scans - Remove hciconfig down and hcitool cmd HCI_Reset from init sequence; simplify to hciconfig up with down/up recovery cycle - Update usbip-validate.sh checks for revised BLE stack behavior
| # AF_BLUETOOTH (e.g. bluetoothctl) can run via nsenter. | ||
| - /proc/1/ns/net:/run/host-netns:ro | ||
| environment: | ||
| - DBUS_SYSTEM_BUS_ADDRESS=${DBUS_SYSTEM_BUS_ADDRESS:-unix:path=/var/run/otbr-dbus/system_bus_socket} |
| echo "[otbr-radio] Starting private D-Bus system bus at ${DBUS_SYSTEM_BUS_ADDRESS}..." | ||
| mkdir -p "${DBUS_DIR}" | ||
| if [ -S "${DBUS_SOCKET_PATH}" ]; then | ||
| echo "[otbr-radio] Removing stale D-Bus socket ${DBUS_SOCKET_PATH}..." | ||
| rm -f "${DBUS_SOCKET_PATH}" | ||
| fi | ||
| dbus-daemon --config-file=/etc/otbr-dbus.conf --fork --nopidfile | ||
| echo "[otbr-radio] Private D-Bus started." | ||
|
|
||
| ############################################################################### | ||
| # 2. Validate the USB radio device | ||
| ############################################################################### | ||
| if [ -z "${RADIO_DEVICE}" ]; then | ||
| echo "[otbr-radio] ERROR: RADIO_DEVICE is not set." >&2 | ||
| echo "[otbr-radio] Set it in docker/.env or export before starting:" >&2 | ||
| echo "[otbr-radio] export RADIO_DEVICE=/dev/ttyACM0" >&2 | ||
| echo "[otbr-radio] See docs/REMOTE_RADIO_FOR_DEVELOPMENT.md for setup instructions." >&2 | ||
| exit 1 | ||
| fi |
| <listen>unix:path=/var/run/otbr-dbus/system_bus_socket</listen> | ||
| <auth>ANONYMOUS</auth> | ||
| <allow_anonymous/> | ||
| <policy context="default"> | ||
| <allow own="io.openthread.BorderRouter.wpan0"/> | ||
| <allow send_destination="io.openthread.BorderRouter.wpan0"/> | ||
| <allow send_interface="*"/> | ||
| <allow user="*"/> | ||
| <allow own="*"/> | ||
| <allow send_type="*"/> | ||
| <allow receive_sender="*"/> | ||
| <allow send_destination="*"/> | ||
| <allow receive_type="*"/> | ||
| <allow receive_sender="*"/> |
| # Use timeout because bluetoothctl blocks if bluetoothd is not running. | ||
| BT_LIST=$(timeout 5 sudo nsenter --net="${HOST_NETNS}" bluetoothctl list 2>/dev/null || true) |
| # scripts/usbip-attach-local.sh user@remote-server | ||
| # scripts/usbip-attach-local.sh remote-server # uses current username | ||
| # | ||
| # Leave the terminal open while you work. Press Ctrl-C to close the tunnel. | ||
| # Run scripts/usbip-detach-local.sh to clean up. |
| char *endPtr = nullptr; | ||
| unsigned long val = strtoul(env, &endPtr, 10); | ||
|
|
||
| if (endPtr != env && *endPtr == '\0') | ||
| { | ||
| adapterId = static_cast<uint32_t>(val); | ||
| icInfo("Using BLE adapter hci%u from %s", adapterId, BLE_CONTROLLER_ADAPTER_ID_ENV); |
Add an optional otbr-radio Docker container that connects a Silicon Labs BRD2703 xG24 Explorer Kit to the Barton devcontainer via D-Bus, enabling Thread integration testing with real hardware.
Refs: BARTON-359