Skip to content

Commit

Permalink
WIP: Fix crash on factory reset
Browse files Browse the repository at this point in the history
  • Loading branch information
andriy-bilynskyy committed Nov 6, 2023
1 parent 26a58be commit 3010587
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 39 deletions.
67 changes: 36 additions & 31 deletions examples/platform/telink/common/src/AppTaskCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,37 +156,38 @@ class AppFabricTableDelegate : public FabricTable::Delegate
{
void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex)
{
if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0)
{
ChipLogProgress(DeviceLayer, "Performing erasing of settings partition");

// Do FactoryReset in case of failed commissioning to allow new pairing via BLE
if (sIsCommissioningFailed)
{
chip::Server::GetInstance().ScheduleFactoryReset();
}
// TC-OPCREDS-3.6 (device doesn't need to reboot automatically after the last fabric is removed) can't use FactoryReset
else
{
void * storage = nullptr;
int status = settings_storage_get(&storage);

if (!status)
{
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);
}
}
}
printk("AppFabricTableDelegate\n");
// if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0)
// {
// ChipLogProgress(DeviceLayer, "Performing erasing of settings partition");

// // Do FactoryReset in case of failed commissioning to allow new pairing via BLE
// if (sIsCommissioningFailed)
// {
// chip::Server::GetInstance().ScheduleFactoryReset();
// }
// // TC-OPCREDS-3.6 (device doesn't need to reboot automatically after the last fabric is removed) can't use FactoryReset
// else
// {
// void * storage = nullptr;
// int status = settings_storage_get(&storage);

// if (!status)
// {
// 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);
// }
// }
// }
}
};

Expand Down Expand Up @@ -566,12 +567,14 @@ void AppTaskCommon::StartBleAdvHandler(AppEvent * aEvent)

void AppTaskCommon::FactoryResetButtonEventHandler(void)
{
printk("AppTaskCommon::FactoryResetButtonEventHandler\n");
AppEvent event;

event.Type = AppEvent::kEventType_Button;
event.ButtonEvent.Action = kButtonPushEvent;
event.Handler = FactoryResetHandler;
GetAppTask().PostEvent(&event);
printk("AppTaskCommon::FactoryResetButtonEventHandler event posted\n");
}

void AppTaskCommon::FactoryResetHandler(AppEvent * aEvent)
Expand All @@ -589,7 +592,9 @@ void AppTaskCommon::FactoryResetHandler(AppEvent * aEvent)
k_timer_stop(&sFactoryResetTimer);
sFactoryResetCntr = 0;

printk("AppTaskCommon::FactoryResetHandler ScheduleFactoryReset\n");
chip::Server::GetInstance().ScheduleFactoryReset();
printk("AppTaskCommon::FactoryResetHandler ScheduleFactoryReset done\n");
}
}

Expand Down
33 changes: 29 additions & 4 deletions src/app/EventManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,8 +725,20 @@ CHIP_ERROR EventManagement::FabricRemoved(FabricIndex aFabricIndex)
TLVReader reader;
CircularEventBufferWrapper bufWrapper;

ReturnErrorOnFailure(GetEventReader(reader, PriorityLevel::Critical, &bufWrapper));
CHIP_ERROR err = TLV::Utilities::Iterate(reader, FabricRemovedCB, &aFabricIndex, recurse);
printk("EventManagement::FabricRemoved+\n");

CHIP_ERROR err = GetEventReader(reader, PriorityLevel::Critical, &bufWrapper);

printk("EventManagement::FabricRemoved ~\n");;

if (err != CHIP_NO_ERROR)
{
printk("EventManagement::FabricRemoved error\n");;
return err;
}

err = TLV::Utilities::Iterate(reader, FabricRemovedCB, &aFabricIndex, recurse);
printk("EventManagement::FabricRemoved-\n");
if (err == CHIP_END_OF_TLV)
{
err = CHIP_NO_ERROR;
Expand All @@ -740,9 +752,15 @@ CHIP_ERROR EventManagement::GetEventReader(TLVReader & aReader, PriorityLevel aP
VerifyOrReturnError(buffer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
apBufWrapper->mpCurrent = buffer;

printk("EventManagement::GetEventReader+\n");

CircularEventReader reader;
reader.Init(apBufWrapper);
printk("EventManagement::GetEventReader A\n");
aReader.Init(reader);
printk("EventManagement::GetEventReader B\n");

printk("EventManagement::GetEventReader-\n");

return CHIP_NO_ERROR;
}
Expand Down Expand Up @@ -877,19 +895,26 @@ CHIP_ERROR CircularEventBuffer::OnInit(TLV::TLVWriter & writer, uint8_t *& bufSt
void CircularEventReader::Init(CircularEventBufferWrapper * apBufWrapper)
{
CircularEventBuffer * prev;

if (apBufWrapper->mpCurrent == nullptr)
printk("CircularEventReader::Init +\n");
if (apBufWrapper->mpCurrent == nullptr) {
printk("CircularEventReader::Init ret\n");
return;
}

printk("CircularEventReader::Init A %p %u\n", apBufWrapper, apBufWrapper->mpCurrent->DataLength());
TLVReader::Init(*apBufWrapper, apBufWrapper->mpCurrent->DataLength());
printk("CircularEventReader::Init B\n");
mMaxLen = apBufWrapper->mpCurrent->DataLength();
printk("CircularEventReader::Init C\n");
for (prev = apBufWrapper->mpCurrent->GetPreviousCircularEventBuffer(); prev != nullptr;
prev = prev->GetPreviousCircularEventBuffer())
{
printk("CircularEventReader::Init ***\n");
CircularEventBufferWrapper bufWrapper;
bufWrapper.mpCurrent = prev;
mMaxLen += prev->DataLength();
}
printk("CircularEventReader::Init +\n");
}

CHIP_ERROR CircularEventBufferWrapper::GetNextBuffer(TLVReader & aReader, const uint8_t *& aBufStart, uint32_t & aBufLen)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,15 +354,18 @@ class OpCredsFabricTableDelegate : public chip::FabricTable::Delegate
// Gets called when a fabric is deleted
void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) override
{
ChipLogProgress(Zcl, "OpCreds: Fabric index 0x%x was removed", static_cast<unsigned>(fabricIndex));

ChipLogProgress(Zcl, "OpCreds: Fabric index 0x%x was removed!!!", static_cast<unsigned>(fabricIndex));

printk("OnFabricRemoved 0\n");
// We need to withdraw the advertisement for the now-removed fabric, so need
// to restart advertising altogether.
app::DnssdServer::Instance().StartServer();

printk("OnFabricRemoved A\n");
EventManagement::GetInstance().FabricRemoved(fabricIndex);

printk("OnFabricRemoved B\n");
NotifyFabricTableChanged();
printk("OnFabricRemoved C\n");
}

// Gets called when a fabric is added/updated, but not necessarily committed to storage
Expand Down
5 changes: 5 additions & 0 deletions src/app/server/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,11 +467,16 @@ void Server::GenerateShutDownEvent()

void Server::ScheduleFactoryReset()
{
printk("Server::ScheduleFactoryReset()\n");
PlatformMgr().ScheduleWork([](intptr_t) {
// Delete all fabrics and emit Leave event.
printk("Server::ScheduleFactoryReset() - A\n");
GetInstance().GetFabricTable().DeleteAllFabrics();
printk("Server::ScheduleFactoryReset() - B\n");
PlatformMgr().HandleServerShuttingDown();
printk("Server::ScheduleFactoryReset() - C\n");
ConfigurationMgr().InitiateFactoryReset();
printk("Server::ScheduleFactoryReset() - D\n");
});
}

Expand Down
16 changes: 15 additions & 1 deletion src/credentials/FabricTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -919,9 +919,11 @@ FabricTable::AddOrUpdateInner(FabricIndex fabricIndex, bool isAddition, Crypto::

CHIP_ERROR FabricTable::Delete(FabricIndex fabricIndex)
{
printk("FabricTable::Delete\n");
VerifyOrReturnError(mStorage != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(IsValidFabricIndex(fabricIndex), CHIP_ERROR_INVALID_ARGUMENT);

printk("FabricTable::Delete delegate +\n");
{
FabricTable::Delegate * delegate = mDelegateListRoot;
while (delegate)
Expand All @@ -933,6 +935,7 @@ CHIP_ERROR FabricTable::Delete(FabricIndex fabricIndex)
delegate = nextDelegate;
}
}
printk("FabricTable::Delete delegate -\n");

FabricInfo * fabricInfo = GetMutableFabricByIndex(fabricIndex);
if (fabricInfo == &mPendingFabric)
Expand Down Expand Up @@ -1005,6 +1008,8 @@ CHIP_ERROR FabricTable::Delete(FabricIndex fabricIndex)
ChipLogProgress(FabricProvisioning, "Fabric (0x%x) deleted.", static_cast<unsigned>(fabricIndex));
}

printk("FabricTable::Delete mDelegateListRoot +\n");

if (mDelegateListRoot != nullptr)
{
FabricTable::Delegate * delegate = mDelegateListRoot;
Expand All @@ -1013,29 +1018,38 @@ CHIP_ERROR FabricTable::Delete(FabricIndex fabricIndex)
// It is possible that delegate will remove itself from the list in OnFabricRemoved,
// so we grab the next delegate in the list now.
FabricTable::Delegate * nextDelegate = delegate->next;
printk("FabricTable::Delete mDelegateListRoot ** +\n");
delegate->OnFabricRemoved(*this, fabricIndex);
printk("FabricTable::Delete mDelegateListRoot ** -\n");
delegate = nextDelegate;
}
}

printk("FabricTable::Delete mDelegateListRoot -\n");

// Only return error after trying really hard to remove everything we could
ReturnErrorOnFailure(metadataErr);
ReturnErrorOnFailure(opKeyErr);
ReturnErrorOnFailure(opCertsErr);

printk("FabricTable::Delete finish\n");

return CHIP_NO_ERROR;
}

void FabricTable::DeleteAllFabrics()
{
static_assert(kMaxValidFabricIndex <= UINT8_MAX, "Cannot create more fabrics than UINT8_MAX");

printk("FabricTable::DeleteAllFabrics\n");
RevertPendingFabricData();

printk("FabricTable::DeleteAllFabrics +\n");
for (auto & fabric : *this)
{
printk("FabricTable::DeleteAllFabrics ***\n");
Delete(fabric.GetFabricIndex());
}
printk("FabricTable::DeleteAllFabrics -\n");
}

CHIP_ERROR FabricTable::Init(const FabricTable::InitParams & initParams)
Expand Down
1 change: 1 addition & 0 deletions src/include/platform/PlatformManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ inline void PlatformManager::HandleServerShuttingDown()

inline CHIP_ERROR PlatformManager::ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg)
{
printk("PlatformManager::ScheduleWork\n");
return static_cast<ImplClass *>(this)->_ScheduleWork(workFunct, arg);
}

Expand Down
1 change: 1 addition & 0 deletions src/platform/Zephyr/ConfigurationManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ CHIP_ERROR ConfigurationManagerImpl::StoreTotalOperationalHours(uint32_t totalOp

void ConfigurationManagerImpl::InitiateFactoryReset()
{
printk("ConfigurationManagerImpl::InitiateFactoryReset\n");
PlatformMgr().ScheduleWork(DoFactoryReset);
}

Expand Down

0 comments on commit 3010587

Please sign in to comment.