diff --git a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp index fe5bd40a0afb42..14828e90f50823 100644 --- a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp +++ b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp @@ -51,8 +51,13 @@ CHIP_ERROR GenericThreadDriver::Init(Internal::BaseDriver::NetworkStatusChangeCa // If the network configuration backup exists, it means that the device has been rebooted with // the fail-safe armed. Since OpenThread persists all operational dataset changes, the backup - // must be restored on the boot. If there's no backup, the below function is a no-op. - RevertConfiguration(); + // must be restored. + if (BackupExists()) + { + // Set flag and postpone revert until OpenThread is initialized, + // as we need to clear SRP host and services before restoring the backup. + mRevertOnServerReady = true; + } CheckInterfaceEnabled(); @@ -61,11 +66,28 @@ CHIP_ERROR GenericThreadDriver::Init(Internal::BaseDriver::NetworkStatusChangeCa void GenericThreadDriver::OnThreadStateChangeHandler(const ChipDeviceEvent * event, intptr_t arg) { - if ((event->Type == DeviceEventType::kThreadStateChange) && - (event->ThreadStateChange.OpenThread.Flags & OT_CHANGED_THREAD_PANID)) + auto & driver = *reinterpret_cast(arg); + + switch (event->Type) { - // Update the mStagingNetwork when thread panid changed - ThreadStackMgrImpl().GetThreadProvision(reinterpret_cast(arg)->mStagingNetwork); + case DeviceEventType::kThreadStateChange: + if (event->ThreadStateChange.OpenThread.Flags & OT_CHANGED_THREAD_PANID) + { + // Update the mStagingNetwork when thread panid changed + ThreadStackMgrImpl().GetThreadProvision(driver.mStagingNetwork); + } + break; + + case DeviceEventType::kServerReady: + if (driver.mRevertOnServerReady) + { + driver.mRevertOnServerReady = false; + driver.RevertConfiguration(); + } + break; + + default: + break; } } @@ -97,6 +119,8 @@ CHIP_ERROR GenericThreadDriver::RevertConfiguration() // since the fail-safe was armed, so return with no error. VerifyOrReturnError(error != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR); + ThreadStackMgrImpl().ClearAllSrpHostAndServices(); + if (!GetEnabled()) { // When reverting configuration, set InterfaceEnabled to default value (true). @@ -272,10 +296,11 @@ Status GenericThreadDriver::MatchesNetworkId(const Thread::OperationalDataset & CHIP_ERROR GenericThreadDriver::BackupConfiguration() { - // If configuration is already backed up, return with no error - CHIP_ERROR err = KeyValueStoreMgr().Get(DefaultStorageKeyAllocator::FailSafeNetworkConfig().KeyName(), nullptr, 0); + // Abort pending revert + mRevertOnServerReady = false; - if (err == CHIP_NO_ERROR || err == CHIP_ERROR_BUFFER_TOO_SMALL) + // If configuration is already backed up, return with no error + if (BackupExists()) { return CHIP_NO_ERROR; } @@ -285,6 +310,18 @@ CHIP_ERROR GenericThreadDriver::BackupConfiguration() return KeyValueStoreMgr().Put(DefaultStorageKeyAllocator::FailSafeNetworkConfig().KeyName(), dataset.data(), dataset.size()); } +bool GenericThreadDriver::BackupExists() +{ + CHIP_ERROR err = KeyValueStoreMgr().Get(DefaultStorageKeyAllocator::FailSafeNetworkConfig().KeyName(), nullptr, 0); + + if (err == CHIP_NO_ERROR || err == CHIP_ERROR_BUFFER_TOO_SMALL) + { + return true; + } + + return false; +} + void GenericThreadDriver::CheckInterfaceEnabled() { #if !CHIP_DEVICE_CONFIG_ENABLE_THREAD_AUTOSTART diff --git a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.h b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.h index 3cdb8cff668034..cc9f4a335506ef 100644 --- a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.h +++ b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.h @@ -127,10 +127,12 @@ class GenericThreadDriver final : public ThreadDriver static void OnThreadStateChangeHandler(const ChipDeviceEvent * event, intptr_t arg); Status MatchesNetworkId(const Thread::OperationalDataset & dataset, const ByteSpan & networkId) const; CHIP_ERROR BackupConfiguration(); + bool BackupExists(); void CheckInterfaceEnabled(); ThreadNetworkIterator mThreadIterator = ThreadNetworkIterator(this); Thread::OperationalDataset mStagingNetwork = {}; + bool mRevertOnServerReady = false; }; } // namespace NetworkCommissioning