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

[Telink] Fix TC-OPCREDS-3.6 and prevent writing to NVS during factory reset #26784

Merged
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
s07641069 marked this conversation as resolved.
Show resolved Hide resolved
// 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