Skip to content

build(docker): Add remote radio support in docker#201

Open
Lakshmi97-velampati wants to merge 14 commits into
mainfrom
mvelam850/dev/threadRadionInDockerCompose
Open

build(docker): Add remote radio support in docker#201
Lakshmi97-velampati wants to merge 14 commits into
mainfrom
mvelam850/dev/threadRadionInDockerCompose

Conversation

@Lakshmi97-velampati
Copy link
Copy Markdown
Contributor

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

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>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-radio Docker image + entrypoint that brings up D-Bus, Avahi, cpcd, then otbr-agent over CPC (spinel+cpc://).
  • Add a Compose overlay to run otbr-radio with host networking/privileges and share /var/run/dbus with barton.
  • Extend tooling/docs: dockerw -T flag, .env variables (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.

Comment thread docker/otbr-radio-entrypoint.sh Outdated
Comment thread docker/otbr-radio-entrypoint.sh Outdated
Comment thread docker/setupDockerEnv.sh Outdated
Comment thread dockerw Outdated
Copy link
Copy Markdown
Contributor

@kfundecmcsa kfundecmcsa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a couple open questions, but requesting changes for the title. This effort should fall into the build commit type, not feat

Comment thread docs/THREAD_BORDER_ROUTER_SUPPORT.md Outdated
Comment thread docs/THREAD_BORDER_ROUTER_SUPPORT.md Outdated
@Lakshmi97-velampati Lakshmi97-velampati changed the title feat(docker): Add thread radio support in docker build(docker): Add thread radio support in docker Apr 13, 2026
@Lakshmi97-velampati
Copy link
Copy Markdown
Contributor Author

I have a couple open questions, but requesting changes for the title. This effort should fall into the build commit type, not feat

Updated

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment thread docker/Dockerfile.otbr-radio
Comment thread docker/compose.otbr-radio.yaml Outdated
Comment thread docker/compose.otbr-radio.yaml Outdated
Comment thread docker/compose.otbr-radio.yaml Outdated
Comment thread docker/otbr-radio-entrypoint.sh Outdated
Comment thread docker/otbr-radio-entrypoint.sh Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

Comment thread docker/otbr-radio-entrypoint.sh Outdated
Comment thread docker/compose.otbr-radio.yaml Outdated
Comment thread docker/compose.otbr-radio.yaml Outdated
Comment thread docker/compose.otbr-radio.yaml Outdated
Comment thread .devcontainer/devcontainer.json
@Lakshmi97-velampati Lakshmi97-velampati marked this pull request as draft April 17, 2026 02:10
@tleacmcsa
Copy link
Copy Markdown
Contributor

Be sure to take this PR out of draft when you are ready for re-review.

@Lakshmi97-velampati Lakshmi97-velampati marked this pull request as ready for review April 17, 2026 16:03
Copilot AI review requested due to automatic review settings April 17, 2026 16:03
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Comment thread docs/THREAD_BORDER_ROUTER_SUPPORT.md Outdated
Comment thread docker/compose.otbr-radio.yaml Outdated
Comment thread dockerw Outdated
Comment thread dockerw Outdated
@Lakshmi97-velampati
Copy link
Copy Markdown
Contributor Author

@cleithner-comcast and @kfundecmcsa : you have comments that are still open. Please review the responses/changes and mark them resolved if satisfied. @Lakshmi97-velampati same for you, but for copilot's comments. Please let me know if its ready for me to try out.

@tleacmcsa yes, you can try this.

@cleithner-comcast
Copy link
Copy Markdown
Contributor

Marked comments resolved

Copilot AI review requested due to automatic review settings April 27, 2026 15:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Comment thread dockerw
Comment thread docker/otbr-radio-entrypoint.sh
Comment thread docs/THREAD_BORDER_ROUTER_SUPPORT.md Outdated
Comment thread dockerw
Copy link
Copy Markdown
Contributor

@tleacmcsa tleacmcsa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Comment thread docker/compose.otbr-radio.yaml Outdated
volumes:
- dbus-socket:/var/run/otbr-dbus
environment:
- DBUS_SYSTEM_BUS_ADDRESS=${DBUS_SYSTEM_BUS_ADDRESS:-unix:path=/var/run/dbus/system_bus_socket}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why isnt this the otbr-dbus?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure will try it.

@Lakshmi97-velampati Lakshmi97-velampati marked this pull request as draft April 29, 2026 14:01
Comment thread docker/Dockerfile.otbr-radio Outdated
@Lakshmi97-velampati
Copy link
Copy Markdown
Contributor Author

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?

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.

@tleacmcsa tleacmcsa changed the title build(docker): Add thread radio support in docker build(docker): Add remote radio support in docker May 11, 2026
@Lakshmi97-velampati Lakshmi97-velampati marked this pull request as ready for review May 19, 2026 06:12
Copilot AI review requested due to automatic review settings May 19, 2026 06:12
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 4 comments.

# 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]().
Comment on lines +227 to +230
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 &
Lakshmi97-velampati and others added 2 commits May 19, 2026 11:05
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
Copilot AI review requested due to automatic review settings May 20, 2026 19:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 6 comments.

# 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}
Comment on lines +86 to +104
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
Comment thread docker/otbr-agent.conf
Comment on lines +4 to +13
<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="*"/>
Comment on lines +278 to +279
# 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)
Comment on lines +41 to +45
# 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.
Comment on lines +308 to +314
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);
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.

7 participants