Skip to content

Commit

Permalink
[Linux] Fix getting ActiveDatasetTlvs in ThreadStackManager (#15400)
Browse files Browse the repository at this point in the history
  • Loading branch information
erjiaqing authored and pull[bot] committed Jan 23, 2024
1 parent 1424da3 commit d66e635
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,9 @@ async def test_thread(self, endpointId):
raise AssertionError(
f"LastNetworkID, LastConnectErrorValue and LastNetworkingStatus should not be Null")

# TODO: Linux Thread driver cannot get infomation of current connected networks.
'''
logger.info(f"Check network list")
res = await self._devCtrl.ReadAttribute(nodeid=self._nodeid, attributes=[(endpointId, Clusters.NetworkCommissioning.Attributes.Networks)], returnClusterObject=True)
networkList = res[endpointId][Clusters.NetworkCommissioning].networks
networkList = res[0][endpointId][Clusters.NetworkCommissioning].networks
logger.info(f"Got network list: {networkList}")
if len(networkList) != 1:
raise AssertionError(
Expand All @@ -294,7 +292,6 @@ async def test_thread(self, endpointId):
if not networkList[0].connected:
raise AssertionError(
f"Unexpected result: network is not marked as connected")
'''

async def run(self):
try:
Expand Down
61 changes: 52 additions & 9 deletions src/platform/Linux/ThreadStackManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,18 +238,45 @@ CHIP_ERROR ThreadStackManagerImpl::_GetThreadProvision(ByteSpan & netInfo)
VerifyOrReturnError(mProxy, CHIP_ERROR_INCORRECT_STATE);

{
// TODO: The following code does not works actually, since otbr-posix does not emit signals for properties changes. Which is
// required for gdbus to caching properties.
std::unique_ptr<GVariant, GVariantDeleter> value(
openthread_io_openthread_border_router_dup_active_dataset_tlvs(mProxy.get()));
std::unique_ptr<GError, GErrorDeleter> err;

std::unique_ptr<GVariant, GVariantDeleter> response(
g_dbus_proxy_call_sync(G_DBUS_PROXY(mProxy.get()), "org.freedesktop.DBus.Properties.Get",
g_variant_new("(ss)", "io.openthread.BorderRouter", "ActiveDatasetTlvs"), G_DBUS_CALL_FLAGS_NONE,
-1, nullptr, &MakeUniquePointerReceiver(err).Get()));

if (err)
{
ChipLogError(DeviceLayer, "openthread: failed to read ActiveDatasetTlvs property: %s", err->message);
return CHIP_ERROR_INTERNAL;
}

// Note: The actual value is wrapped by a GVariant container, wrapped in another GVariant with tuple type.

if (response == nullptr)
{
netInfo = ByteSpan();
return CHIP_ERROR_KEY_NOT_FOUND;
}

std::unique_ptr<GVariant, GVariantDeleter> tupleContent(g_variant_get_child_value(response.get(), 0));

if (tupleContent == nullptr)
{
netInfo = ByteSpan();
return CHIP_ERROR_KEY_NOT_FOUND;
}

std::unique_ptr<GVariant, GVariantDeleter> value(g_variant_get_variant(tupleContent.get()));

if (value == nullptr)
{
netInfo = ByteSpan();
return CHIP_ERROR_KEY_NOT_FOUND;
}
GBytes * bytes = g_variant_get_data_as_bytes(value.get());

gsize size;
const uint8_t * data = reinterpret_cast<const uint8_t *>(g_bytes_get_data(bytes, &size));
const uint8_t * data = reinterpret_cast<const uint8_t *>(g_variant_get_fixed_array(value.get(), &size, sizeof(guchar)));
ReturnErrorOnFailure(mDataset.Init(ByteSpan(data, size)));
}

Expand All @@ -270,13 +297,29 @@ void ThreadStackManagerImpl::_ErasePersistentInfo()

bool ThreadStackManagerImpl::_IsThreadEnabled()
{
if (!mProxy)
VerifyOrReturnError(mProxy, false);

std::unique_ptr<GError, GErrorDeleter> err;

std::unique_ptr<GVariant, GVariantDeleter> value(
g_dbus_proxy_call_sync(G_DBUS_PROXY(mProxy.get()), "org.freedesktop.DBus.Properties.Get",
g_variant_new("(ss)", "io.openthread.BorderRouter", "DeviceRole"), G_DBUS_CALL_FLAGS_NONE, -1,
nullptr, &MakeUniquePointerReceiver(err).Get()));

if (err)
{
ChipLogError(DeviceLayer, "openthread: failed to read DeviceRole property: %s", err->message);
return false;
}

std::unique_ptr<gchar, GFree> role(openthread_io_openthread_border_router_dup_device_role(mProxy.get()));
return (strcmp(role.get(), kOpenthreadDeviceRoleDisabled) != 0);
if (value == nullptr)
{
return false;
}

const gchar * role = g_variant_get_string(value.get(), nullptr);

return (strcmp(role, kOpenthreadDeviceRoleDisabled) != 0);
}

bool ThreadStackManagerImpl::_IsThreadAttached()
Expand Down

0 comments on commit d66e635

Please sign in to comment.