Skip to content

Commit

Permalink
[Telink] Fix TC-OPCREDS-3.6 and prevent writing to NVS during factory…
Browse files Browse the repository at this point in the history
… 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>
  • Loading branch information
4 people authored and pull[bot] committed Oct 26, 2023
1 parent 1c69e75 commit 1069940
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
56 changes: 55 additions & 1 deletion examples/platform/telink/common/src/AppTaskCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -118,7 +123,47 @@ class AppFabricTableDelegate : public FabricTable::Delegate
{
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();
}
}
};
Expand Down Expand Up @@ -240,6 +285,15 @@ CHIP_ERROR AppTaskCommon::InitCommonParts(void)
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.
Expand Down
5 changes: 5 additions & 0 deletions src/platform/telink/ThreadStackManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,10 @@ CHIP_ERROR ThreadStackManagerImpl::_StartThreadScan(NetworkCommissioning::Thread
return CHIP_NO_ERROR;
}

void ThreadStackManagerImpl::Finalize(void)
{
otInstanceFinalize(openthread_get_default_instance());
}

} // namespace DeviceLayer
} // namespace chip
1 change: 1 addition & 0 deletions src/platform/telink/ThreadStackManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class ThreadStackManagerImpl final : public ThreadStackManager,
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.
Expand Down

0 comments on commit 1069940

Please sign in to comment.