Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Linux] Fix getting ActiveDatasetTlvs in ThreadStackManager #15400

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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