OpenThread: Clear SRP host and services during RevertConfiguration (#38053)
* Postpone `RevertConfiguration` until Server is initialized.
* Clear SRP host and services before reverting dataset.
* Abort revert if creating new backup.
Signed-off-by: Adrian Gielniewski <adrian.gielniewski@nordicsemi.no>
diff --git a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp
index fe5bd40..14828e9 100644
--- a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp
+++ b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp
@@ -51,8 +51,13 @@
// 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 @@
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<GenericThreadDriver *>(arg);
+
+ switch (event->Type)
{
- // Update the mStagingNetwork when thread panid changed
- ThreadStackMgrImpl().GetThreadProvision(reinterpret_cast<GenericThreadDriver *>(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 @@
// 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 @@
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 @@
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 3cdb8cf..cc9f4a3 100644
--- a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.h
+++ b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.h
@@ -127,10 +127,12 @@
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