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

OpenThread: added Thread interface enabled support #33860

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
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
Loading