[Telink] Fix TC-OPCREDS-3.6 and prevent writing to NVS during factory reset (#26784)
* [Telink] Added storage reset in case of fabric count == 0
Signed-off-by: Misha Tkachenko <misha.tkachenko@telink-semi.com>
* [Telink] Disable openthread before reset to prevent writing to NVS
Signed-off-by: Misha Tkachenko <misha.tkachenko@telink-semi.com>
* [Telink] remove commented code
* Restyled by clang-format
* [Telink]: Added a clear explanation for preventing NVS writing on shutdown
Signed-off-by: Misha Tkachenko <misha.tkachenko@telink-semi.com>
* [Telink]: Updated OpenThread finalization function
Signed-off-by: Misha Tkachenko <misha.tkachenko@telink-semi.com>
* Restyled by whitespace
---------
Signed-off-by: Misha Tkachenko <misha.tkachenko@telink-semi.com>
Co-authored-by: Misha Tkachenko <misha.tkachenko@telink-semi.com>
Co-authored-by: Restyled.io <commits@restyled.io>
Co-authored-by: Misha Tkachenko <36621698+mishadesh@users.noreply.github.com>
diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp
index 4297d3a..ec45f92 100644
--- a/examples/platform/telink/common/src/AppTaskCommon.cpp
+++ b/examples/platform/telink/common/src/AppTaskCommon.cpp
@@ -38,6 +38,11 @@
#include <app/InteractionModelEngine.h>
#endif
+#ifdef CONFIG_CHIP_FACTORY_RESET_ERASE_NVS
+#include <zephyr/fs/nvs.h>
+#include <zephyr/settings/settings.h>
+#endif
+
using namespace chip::app;
LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL);
@@ -118,7 +123,47 @@
{
if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0)
{
- chip::Server::GetInstance().ScheduleFactoryReset();
+ ChipLogProgress(DeviceLayer, "Performing erasing of settings partition");
+
+#ifdef CONFIG_CHIP_FACTORY_RESET_ERASE_NVS
+ void * storage = nullptr;
+ int status = settings_storage_get(&storage);
+
+ if (status == 0)
+ {
+ status = nvs_clear(static_cast<nvs_fs *>(storage));
+ }
+
+ if (!status)
+ {
+ status = nvs_mount(static_cast<nvs_fs *>(storage));
+ }
+
+ if (status)
+ {
+ ChipLogError(DeviceLayer, "Storage clearance failed: %d", status);
+ }
+#else
+ const CHIP_ERROR err = PersistedStorage::KeyValueStoreMgrImpl().DoFactoryReset();
+
+ if (err != CHIP_NO_ERROR)
+ {
+ ChipLogError(DeviceLayer, "Factory reset failed: %" CHIP_ERROR_FORMAT, err.Format());
+ }
+
+ ConnectivityMgr().ErasePersistentInfo();
+#endif
+ }
+ }
+};
+
+class PlatformMgrDelegate : public DeviceLayer::PlatformManagerDelegate
+{
+ void OnShutDown() override
+ {
+ if (ThreadStackManagerImpl().IsThreadEnabled())
+ {
+ ThreadStackManagerImpl().Finalize();
}
}
};
@@ -240,6 +285,15 @@
chip::app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(&GetICDUtil());
#endif
+ // We need to disable OpenThread to prevent writing to the NVS storage when factory reset occurs
+ // The OpenThread thread is running during factory reset. The nvs_clear function is called during
+ // factory reset, which makes the NVS storage innaccessible, but the OpenThread knows nothing
+ // about this and tries to store the parameters to NVS. Because of this the OpenThread need to be
+ // shut down before NVS. This delegate fixes the issue "Failed to store setting , ret -13",
+ // which means that the NVS is already disabled.
+ // For this the OnShutdown function is used
+ PlatformMgr().SetDelegate(new PlatformMgrDelegate);
+
// Add CHIP event handler and start CHIP thread.
// Note that all the initialization code should happen prior to this point to avoid data races
// between the main and the CHIP threads.
diff --git a/src/platform/telink/ThreadStackManagerImpl.cpp b/src/platform/telink/ThreadStackManagerImpl.cpp
index d6657c4..e66735b 100644
--- a/src/platform/telink/ThreadStackManagerImpl.cpp
+++ b/src/platform/telink/ThreadStackManagerImpl.cpp
@@ -136,5 +136,10 @@
return CHIP_NO_ERROR;
}
+void ThreadStackManagerImpl::Finalize(void)
+{
+ otInstanceFinalize(openthread_get_default_instance());
+}
+
} // namespace DeviceLayer
} // namespace chip
diff --git a/src/platform/telink/ThreadStackManagerImpl.h b/src/platform/telink/ThreadStackManagerImpl.h
index 870ea17..5083823 100644
--- a/src/platform/telink/ThreadStackManagerImpl.h
+++ b/src/platform/telink/ThreadStackManagerImpl.h
@@ -64,6 +64,7 @@
CHIP_ERROR _InitThreadStack();
void SetRadioBlocked(bool state) { mRadioBlocked = state; }
bool IsReadyToAttach(void) const { return mReadyToAttach; }
+ void Finalize(void);
protected:
// ===== Methods that implement the ThreadStackManager abstract interface.