Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
49578ce
feat(docker): add thread radio support in docker
Lakshmi97-velampati Apr 8, 2026
492020d
build(docker) : address review findings by copilot
Lakshmi97-velampati Apr 13, 2026
3f3bd21
Merge branch 'main' into mvelam850/dev/threadRadionInDockerCompose
Lakshmi97-velampati Apr 15, 2026
7eba8d7
Merge branch 'main' into mvelam850/dev/threadRadionInDockerCompose
Lakshmi97-velampati Apr 17, 2026
8b8db5d
build(docker): fix restart policy, DBUS wiring, and docs accuracy
Copilot Apr 21, 2026
af4bc0a
Merge branch 'main' into mvelam850/dev/threadRadionInDockerCompose
cleithner-comcast Apr 27, 2026
cf0abce
Merge branch 'main' into mvelam850/dev/threadRadionInDockerCompose
Lakshmi97-velampati Apr 29, 2026
2e68240
added simultaneous bluetooth support on same silabs radio
tleacmcsa Apr 29, 2026
adf2734
pick the right ble adapter for matter sdk
tleacmcsa Apr 29, 2026
8db26b1
Merge branch 'main' into mvelam850/dev/threadRadionInDockerCompose
Lakshmi97-velampati May 3, 2026
0b3a612
helper scripts and doc updates
tleacmcsa May 7, 2026
c7131c8
Merge branch 'main' into mvelam850/dev/threadRadionInDockerCompose
Lakshmi97-velampati May 19, 2026
cde9e19
fix private D-Bus connectivity and bluetoothd host system bus registr…
Lakshmi97-velampati May 19, 2026
5fceaff
fix(docker): remove hcitool usage to prevent BLE MGMT socket poisoning
tleacmcsa May 20, 2026
03b88c1
feat(docker): add remote CPC support and fix BLE via CPC firmware bugs
tleacmcsa May 26, 2026
6daac8b
Merge branch 'main' into mvelam850/dev/threadRadionInDockerCompose
Lakshmi97-velampati May 27, 2026
f8f0f47
fix(matter,remote-radio): fix BLE/Thread commissioning and harden rem…
tleacmcsa May 27, 2026
117f379
feat(docker): replace USB-IP with remote serial tunnel for radio access
tleacmcsa May 28, 2026
e62307a
fix(docker): unify service monitoring, add HCI auto-healing, update e…
tleacmcsa Jun 1, 2026
2ae0f20
Merge branch 'main' into mvelam850/dev/threadRadionInDockerCompose
Lakshmi97-velampati Jun 2, 2026
28aeabe
fix(docker): stabilize CPC BLE/Thread radio sharing for Matter commis…
tleacmcsa Jun 2, 2026
aae12a8
fix(otbr-radio): increase cpcd retry timeout for high-latency serial …
Lakshmi97-velampati Jun 4, 2026
9eaf4a2
Merge branch 'main' into mvelam850/dev/threadRadionInDockerCompose
Lakshmi97-velampati Jun 4, 2026
d3ee1ae
Revert "fix(otbr-radio): increase cpcd retry timeout for high-latency…
tleacmcsa Jun 4, 2026
7083714
fix(otbr-radio): increase cpcd retry timeout for high-latency serial …
Lakshmi97-velampati Jun 5, 2026
48e8f2f
some updates for timing and retries
tleacmcsa Jun 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"initializeCommand": "docker/setupDockerEnv.sh",
"dockerComposeFile": [
"../docker/compose.yaml",
"../docker/compose.devcontainer.yaml"
"../docker/compose.devcontainer.yaml",
"../docker/compose.otbr-radio.yaml"
],
Comment thread
Lakshmi97-velampati marked this conversation as resolved.
"service": "barton",

Expand Down Expand Up @@ -51,7 +52,11 @@
// when loaded via GObject introspection in Python. Without this, VS Code's pytest
// discovery crashes because ASAN kills the process. This is harmless for non-ASAN
// processes — they simply ignore the option.
"ASAN_OPTIONS": "verify_asan_link_order=0"
"ASAN_OPTIONS": "verify_asan_link_order=0",

// Disable debuginfod URL lookups — GDB hangs trying to download symbols from
// the Ubuntu debuginfod server when this is set.
"DEBUGINFOD_URLS": ""
},

// specify the non-root user to use in the container
Expand Down Expand Up @@ -110,5 +115,10 @@
},

// script for further VSC customization after the container is created
"postCreateCommand": ".devcontainer/setup.sh"
"postCreateCommand": ".devcontainer/setup.sh",

// Set up IPv6 routes to Thread devices via the otbr-radio container.
// Runs on every container start (not just creation) so routes survive
// restarts. Harmless no-op when otbr-radio is not running.
"postStartCommand": "docker/setup-thread-routes.sh"
}
55 changes: 53 additions & 2 deletions core/src/subsystems/matter/Matter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include "system/SystemClock.h"
#include "zap-generated/gen_config.h"
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <vector>
#define LOG_TAG "Matter"
#define logFmt(fmt) "(%s): " fmt, __func__
Expand Down Expand Up @@ -99,7 +101,9 @@ extern "C" {
#define CONNECT_DEVICE_TIMEOUT_SECONDS 15
#define DISCOVER_ON_NETWORK_DEVICE_TIMEOUT_SECS 1

#define BLE_CONTROLLER_ADAPTER_ID 0
#define BLE_CONTROLLER_ADAPTER_ID_DEFAULT 0
#define BLE_CONTROLLER_ADAPTER_ID_ENV "BARTON_BLE_ADAPTER_ID"
#define BLE_CONTROLLER_ADAPTER_ID_FILE "/var/run/otbr-dbus/ble_adapter_id"
#define BLE_CONTROLLER_DEVICE_NAME BARTON_CONFIG_MATTER_BLE_CONTROLLER_DEVICE_NAME

#define LOCAL_NODE_ID_SYSTEM_PROPERTY_NAME "localMatterNodeId"
Expand Down Expand Up @@ -278,7 +282,7 @@ bool Matter::Init(uint64_t accountId, std::string &&attestationTrustStorePath)
}

chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName(BLE_CONTROLLER_DEVICE_NAME);
chip::DeviceLayer::Internal::BLEMgrImpl().ConfigureBle(BLE_CONTROLLER_ADAPTER_ID, true);
chip::DeviceLayer::Internal::BLEMgrImpl().ConfigureBle(ResolveBleAdapterId(), true);
chip::DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(false);

#if CHIP_ENABLE_OPENTHREAD
Expand All @@ -294,6 +298,53 @@ bool Matter::Init(uint64_t accountId, std::string &&attestationTrustStorePath)
return result;
}

uint32_t Matter::ResolveBleAdapterId()
{
uint32_t adapterId = BLE_CONTROLLER_ADAPTER_ID_DEFAULT;
const char *env = getenv(BLE_CONTROLLER_ADAPTER_ID_ENV);

if (env != nullptr)
{
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);
Comment on lines +308 to +314
}
else
{
icWarn("Invalid %s value '%s', using default hci%u", BLE_CONTROLLER_ADAPTER_ID_ENV, env, adapterId);
}

return adapterId;
}

FILE *f = fopen(BLE_CONTROLLER_ADAPTER_ID_FILE, "r");

if (f != nullptr)
{
char buf[16];

if (fgets(buf, sizeof(buf), f) != nullptr)
{
char *endPtr = nullptr;
unsigned long val = strtoul(buf, &endPtr, 10);

if (endPtr != buf)
{
adapterId = static_cast<uint32_t>(val);
icInfo("Using BLE adapter hci%u from %s", adapterId, BLE_CONTROLLER_ADAPTER_ID_FILE);
}
}

fclose(f);
}

return adapterId;
}

bool Matter::Start()
{
icDebug();
Expand Down
12 changes: 12 additions & 0 deletions core/src/subsystems/matter/Matter.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,18 @@ namespace barton
*/
bool SetAccessRestrictionList();

/**
* Determine which BlueZ HCI adapter index to use for BLE operations.
*
* Selection order:
* 1. BARTON_BLE_ADAPTER_ID environment variable (integer, e.g. "1" for hci1).
* 2. The adapter index file written at /var/run/otbr-dbus/ble_adapter_id.
* 3. Falls back to hci0.
*
* @return the HCI adapter index to pass to BLEMgrImpl::ConfigureBle()
*/
static uint32_t ResolveBleAdapterId();

bool OpenLocalCommissioningWindow(uint16_t discriminator,
uint16_t timeoutSecs,
SetupPayload &setupPayload);
Expand Down
45 changes: 40 additions & 5 deletions core/src/subsystems/thread/OpenThreadClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,10 @@ using namespace otbr::DBus;
namespace
{
// Note: I've seen approx 7 seconds on a standard Ubuntu desktop environment for a new network, about 18 seconds for
// creating and replacing an existing network. This should just "go away" if we implement a proper main loop.
constexpr int ATTACH_WAIT_SECONDS = 25;
// creating and replacing an existing network. CPC-based radio hardware (e.g., EFR32 via serial/SPI) can take 35+
// seconds due to shared radio scheduling and slower transport. After the Attach callback fires, the OTBR may still
// need 30-40 seconds to form the network (detached → leader) before the dataset TLVs become available.
constexpr int ATTACH_WAIT_SECONDS = 120;
} // namespace

namespace barton
Expand Down Expand Up @@ -142,10 +144,43 @@ namespace barton

if (threadApiAttachCallbackCalled && threadApiAttachError == ClientError::ERROR_NONE)
{
threadApiCallError = threadApiBus->GetActiveDatasetTlvs(retVal);
if (threadApiCallError != ClientError::ERROR_NONE)
// The Attach callback may fire before OTBR has finished applying the new dataset.
// Retry GetActiveDatasetTlvs while time remains, processing D-Bus messages in between
// so we receive the "Active dataset tlvs changed" signal.
int datasetRetryCount = 0;

while (true)
{
icError("Failed to get active dataset tlvs. Error = %d", (int) threadApiCallError);
threadApiCallError = threadApiBus->GetActiveDatasetTlvs(retVal);

if (threadApiCallError == ClientError::ERROR_NONE && !retVal.empty())
{
break;
}

auto next = steady_clock::now();
timer = timer - duration_cast<milliseconds>(next - current);
current = next;

if (timer.count() <= 0)
{
icError("Timed out waiting for active dataset tlvs after successful attach.");
break;
}

if (datasetRetryCount == 0 || datasetRetryCount % 10 == 0)
{
icDebug("Active dataset not yet available (error=%d), retrying (%" PRId64 "ms remaining)...",
(int) threadApiCallError, (int64_t) timer.count());
}

datasetRetryCount++;

// Dispatch D-Bus messages for up to 2 seconds before retrying
dbus_connection_read_write_dispatch(dbusConnection.get(), 2000);
next = steady_clock::now();
timer = timer - duration_cast<milliseconds>(next - current);
current = next;
}
}
else if (timer.count() <= 0)
Expand Down
3 changes: 2 additions & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,8 @@ RUN apt-get update && apt-get -y upgrade && DEBIAN_FRONTEND='noninteractive' apt
tcpdump \
lcov \
rsync \
bash-completion
bash-completion \
bluez

RUN pip3 install --upgrade --break-system-packages \
stack-pr
Expand Down
Loading
Loading