Skip to content

Commit

Permalink
OpenThread: added Thread interface enabled support (project-chip#33860)
Browse files Browse the repository at this point in the history
* OpenThread: added Thread interface enabled support

* Added Thread autostart configuration and check for Thread interface

* Update comments for RevertConfiguration

* Fix CI

* Fix CI
  • Loading branch information
DejinChen authored Jun 27, 2024
1 parent b274320 commit 720c834
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/include/platform/CHIPDeviceConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,15 @@ static_assert(CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_MIN <= CHIP_DEVICE
#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT 0
#endif

/**
* CHIP_DEVICE_CONFIG_ENABLE_THREAD_AUTOSTART
*
* Enable starting provisioned Thread network automatically after device power-up.
*/
#ifndef CHIP_DEVICE_CONFIG_ENABLE_THREAD_AUTOSTART
#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_AUTOSTART 1
#endif

// -------------------- Network Telemetry Configuration --------------------

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ CHIP_ERROR GenericThreadDriver::Init(Internal::BaseDriver::NetworkStatusChangeCa
// must be restored on the boot. If there's no backup, the below function is a no-op.
RevertConfiguration();

CheckInterfaceEnabled();

return CHIP_NO_ERROR;
}

Expand Down Expand Up @@ -95,6 +97,16 @@ CHIP_ERROR GenericThreadDriver::RevertConfiguration()
// since the fail-safe was armed, so return with no error.
ReturnErrorCodeIf(error == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR);

if (!GetEnabled())
{
// When reverting configuration, set InterfaceEnabled to default value (true).
// From the spec:
// If InterfaceEnabled is written to false on the same interface as that which is used to write the value, the Administrator
// could await the recovery of network configuration to prior safe values, before being able to communicate with the
// node again.
ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Delete(kInterfaceEnabled));
}

ChipLogProgress(NetworkProvisioning, "Reverting Thread operational dataset");

if (error == CHIP_NO_ERROR)
Expand Down Expand Up @@ -166,6 +178,12 @@ void GenericThreadDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * c
{
NetworkCommissioning::Status status = MatchesNetworkId(mStagingNetwork, networkId);

if (!GetEnabled())
{
// Set InterfaceEnabled to default value (true).
ReturnOnFailure(PersistedStorage::KeyValueStoreMgr().Delete(kInterfaceEnabled));
}

if (status == Status::kSuccess && BackupConfiguration() != CHIP_NO_ERROR)
{
status = Status::kUnknownError;
Expand All @@ -183,6 +201,30 @@ void GenericThreadDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * c
}
}

CHIP_ERROR GenericThreadDriver::SetEnabled(bool enabled)
{
if (enabled == GetEnabled())
{
return CHIP_NO_ERROR;
}

ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kInterfaceEnabled, &enabled, sizeof(enabled)));

if ((!enabled && ThreadStackMgrImpl().IsThreadEnabled()) || (enabled && ThreadStackMgrImpl().IsThreadProvisioned()))
{
ReturnErrorOnFailure(ThreadStackMgrImpl().SetThreadEnabled(enabled));
}
return CHIP_NO_ERROR;
}

bool GenericThreadDriver::GetEnabled()
{
bool value;
// InterfaceEnabled default value is true.
VerifyOrReturnValue(PersistedStorage::KeyValueStoreMgr().Get(kInterfaceEnabled, &value, sizeof(value)) == CHIP_NO_ERROR, true);
return value;
}

void GenericThreadDriver::ScanNetworks(ThreadDriver::ScanCallback * callback)
{
if (DeviceLayer::ThreadStackMgrImpl().StartThreadScan(callback) != CHIP_NO_ERROR)
Expand Down Expand Up @@ -223,6 +265,18 @@ CHIP_ERROR GenericThreadDriver::BackupConfiguration()
return KeyValueStoreMgr().Put(DefaultStorageKeyAllocator::FailSafeNetworkConfig().KeyName(), dataset.data(), dataset.size());
}

void GenericThreadDriver::CheckInterfaceEnabled()
{
#if !CHIP_DEVICE_CONFIG_ENABLE_THREAD_AUTOSTART
// If the Thread interface is enabled and stack has been provisioned, but is not currently enabled, enable it now.
if (GetEnabled() && ThreadStackMgrImpl().IsThreadProvisioned() && !ThreadStackMgrImpl().IsThreadEnabled())
{
ReturnOnFailure(ThreadStackMgrImpl().SetThreadEnabled(true));
ChipLogProgress(DeviceLayer, "OpenThread ifconfig up and thread start");
}
#endif
}

size_t GenericThreadDriver::ThreadNetworkIterator::Count()
{
return driver->mStagingNetwork.IsCommissioned() ? 1 : 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ class GenericThreadDriver final : public ThreadDriver
// BaseDriver
NetworkIterator * GetNetworks() override { return new ThreadNetworkIterator(this); }
CHIP_ERROR Init(Internal::BaseDriver::NetworkStatusChangeCallback * statusChangeCallback) override;
CHIP_ERROR SetEnabled(bool enabled) override;
bool GetEnabled() override;
void Shutdown() override;

// WirelessDriver
Expand All @@ -114,11 +116,13 @@ class GenericThreadDriver final : public ThreadDriver
void ScanNetworks(ThreadDriver::ScanCallback * callback) override;

private:
static constexpr const char * kInterfaceEnabled = "g/gtd/en";
uint8_t scanNetworkTimeoutSeconds;
uint8_t connectNetworkTimeout;
static void OnThreadStateChangeHandler(const ChipDeviceEvent * event, intptr_t arg);
Status MatchesNetworkId(const Thread::OperationalDataset & dataset, const ByteSpan & networkId) const;
CHIP_ERROR BackupConfiguration();
void CheckInterfaceEnabled();

ThreadNetworkIterator mThreadIterator = ThreadNetworkIterator(this);
Thread::OperationalDataset mStagingNetwork = {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,7 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::DoInit(otInstanc
memset(&mSrpClient, 0, sizeof(mSrpClient));
#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT

#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_AUTOSTART
// If the Thread stack has been provisioned, but is not currently enabled, enable it now.
if (otThreadGetDeviceRole(mOTInst) == OT_DEVICE_ROLE_DISABLED && otDatasetIsCommissioned(otInst))
{
Expand All @@ -1143,6 +1144,7 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread<ImplClass>::DoInit(otInstanc

ChipLogProgress(DeviceLayer, "OpenThread ifconfig up and thread start");
}
#endif

initNetworkCommissioningThreadDriver();

Expand Down

0 comments on commit 720c834

Please sign in to comment.