Skip to content

Commit

Permalink
[events] Added generating events on factory reset (#15413)
Browse files Browse the repository at this point in the history
* [events] Added generating events on factory reset

Zephyr platform doesn't support generating
all mandatory events from Basic and General
Diagnostics clusters.

Generic changes:
* Added generating BootReason event
* Added Server::FactoryReset method to dispatch
necessary events and flush pending events before
factory reset
* Added dispatching shutdown event on factory
reset
* Added DeleteAllFabrics in FactoryReset to emit
Leave event.
* Added flushing events on factory reset
* Added for all examples to call Server FactoryReset
instead of platform InitiateFactoryReset

Zephyr platform changes:
* Fixed bug in persisted storage read
implementation that returned wrong error code
and it resulted in PersistedCounter initialization
failure.
* Added calling Shutdown after factory reset

* Addressed review comments
  • Loading branch information
kkasperczyk-no authored Feb 23, 2022
1 parent 9f09e52 commit 843643c
Show file tree
Hide file tree
Showing 38 changed files with 122 additions and 71 deletions.
2 changes: 1 addition & 1 deletion examples/all-clusters-app/esp32/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ class SetupListModel : public TouchesMatterStackModel
}
else if (i == 1)
{
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}
else if (i == 2)
{
Expand Down
2 changes: 1 addition & 1 deletion examples/light-switch-app/efr32/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
{
// Actually trigger Factory Reset
sAppTask.mFunction = kFunction_NoneSelected;
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/lighting-app/efr32/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
{
// Actually trigger Factory Reset
sAppTask.mFunction = kFunction_NoneSelected;
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/lighting-app/mbed/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
// Actually trigger Factory Reset
ChipLogProgress(NotSpecified, "Factory Reset initiated");
sAppTask.mFunction = kFunction_NoneSelected;
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down
3 changes: 2 additions & 1 deletion examples/lighting-app/nrfconnect/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,8 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
{
// Actually trigger Factory Reset
sAppTask.mFunction = kFunction_NoneSelected;
ConfigurationMgr().InitiateFactoryReset();

chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
K32W_LOG("Device will factory reset...");

// Actually trigger Factory Reset
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}

void AppTask::ResetActionEventHandler(AppEvent * aEvent)
Expand Down
2 changes: 1 addition & 1 deletion examples/lighting-app/p6/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
{
// Actually trigger Factory Reset
sAppTask.mFunction = Function::kNoneSelected;
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/lighting-app/qpg/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
{
// Actually trigger Factory Reset
sAppTask.mFunction = kFunction_NoneSelected;
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/lighting-app/telink/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ void AppTask::FactoryResetButtonEventHandler(void)
void AppTask::FactoryResetHandler(AppEvent * aEvent)
{
LOG_INF("Factory Reset triggered.");
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}

void AppTask::StartThreadButtonEventHandler(void)
Expand Down
2 changes: 1 addition & 1 deletion examples/lock-app/efr32/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
{
// Actually trigger Factory Reset
sAppTask.mFunction = kFunction_NoneSelected;
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/lock-app/esp32/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
{
// Actually trigger Factory Reset
sAppTask.mFunction = kFunction_NoneSelected;
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/lock-app/mbed/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
// Actually trigger Factory Reset
ChipLogProgress(NotSpecified, "Factory Reset initiated");
sAppTask.mFunction = kFunction_NoneSelected;
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down
3 changes: 2 additions & 1 deletion examples/lock-app/nrfconnect/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,8 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
{
// Actually trigger Factory Reset
sAppTask.mFunction = kFunction_NoneSelected;
ConfigurationMgr().InitiateFactoryReset();

chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ void AppTask::FunctionTimerEventHandler(void * aGenericEvent)
K32W_LOG("Device will factory reset...");

// Actually trigger Factory Reset
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}

void AppTask::ResetActionEventHandler(void * aGenericEvent)
Expand Down
2 changes: 1 addition & 1 deletion examples/lock-app/p6/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * event)
{
// Actually trigger Factory Reset
sAppTask.mFunction = Function::kNoneSelected;
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/lock-app/qpg/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
{
// Actually trigger Factory Reset
sAppTask.mFunction = kFunction_NoneSelected;
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/ota-requestor-app/efr32/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
{
// Actually trigger Factory Reset
sAppTask.mFunction = kFunction_NoneSelected;
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/ota-requestor-app/mbed/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
sAppTask.CancelTimer(kFunction_Button_1);
sAppTask.mFunction[kFunction_Button_1] = kFunction_NoneSelected;

ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}
break;
case kFunction_Button_2:
Expand Down
14 changes: 7 additions & 7 deletions examples/platform/linux/AppMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,26 +99,26 @@ void OnSignalHandler(int signum)
// The BootReason attribute SHALL indicate the reason for the Node’s most recent boot, the real usecase
// for this attribute is embedded system. In Linux simulation, we use different signals to tell the current
// running process to terminate with different reasons.
DiagnosticDataProvider::BootReasonType bootReason = DiagnosticDataProvider::BootReasonType::Unspecified;
BootReasonType bootReason = BootReasonType::Unspecified;
switch (signum)
{
case SIGVTALRM:
bootReason = DiagnosticDataProvider::BootReasonType::PowerOnReboot;
bootReason = BootReasonType::PowerOnReboot;
break;
case SIGALRM:
bootReason = DiagnosticDataProvider::BootReasonType::BrownOutReset;
bootReason = BootReasonType::BrownOutReset;
break;
case SIGILL:
bootReason = DiagnosticDataProvider::BootReasonType::SoftwareWatchdogReset;
bootReason = BootReasonType::SoftwareWatchdogReset;
break;
case SIGTRAP:
bootReason = DiagnosticDataProvider::BootReasonType::HardwareWatchdogReset;
bootReason = BootReasonType::HardwareWatchdogReset;
break;
case SIGIO:
bootReason = DiagnosticDataProvider::BootReasonType::SoftwareUpdateCompleted;
bootReason = BootReasonType::SoftwareUpdateCompleted;
break;
case SIGINT:
bootReason = DiagnosticDataProvider::BootReasonType::SoftwareReset;
bootReason = BootReasonType::SoftwareReset;
break;
default:
IgnoreUnusedVariable(bootReason);
Expand Down
2 changes: 1 addition & 1 deletion examples/pump-app/cc13x2x7_26x2x7/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ void AppTask::DispatchEvent(AppEvent * aEvent)
}
else if (AppEvent::kAppEventButtonType_LongPressed == aEvent->ButtonEvent.Type)
{
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}
break;

Expand Down
3 changes: 2 additions & 1 deletion examples/pump-app/nrfconnect/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,8 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
{
// Actually trigger Factory Reset
sAppTask.mFunction = kFunction_NoneSelected;
ConfigurationMgr().InitiateFactoryReset();

chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ void AppTask::DispatchEvent(AppEvent * aEvent)
}
else if (AppEvent::kAppEventButtonType_LongPressed == aEvent->ButtonEvent.Type)
{
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}
break;

Expand Down
3 changes: 2 additions & 1 deletion examples/pump-controller-app/nrfconnect/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
{
// Actually trigger Factory Reset
sAppTask.mFunction = kFunction_NoneSelected;
ConfigurationMgr().InitiateFactoryReset();

chip::Server::GetInstance().ScheduleFactoryReset();
}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/shell/nxp/k32w/k32w0/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
K32W_LOG("Device will factory reset...");

// Actually trigger Factory Reset
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
}

void AppTask::ResetActionEventHandler(AppEvent * aEvent)
Expand Down
2 changes: 1 addition & 1 deletion examples/window-app/common/src/WindowApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ void WindowApp::DispatchEvent(const WindowApp::Event & event)
break;

case EventId::Reset:
ConfigurationMgr().InitiateFactoryReset();
chip::Server::GetInstance().ScheduleFactoryReset();
break;

case EventId::UpPressed:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ using chip::DeviceLayer::ConnectivityMgr;
using chip::DeviceLayer::DiagnosticDataProvider;
using chip::DeviceLayer::GetDiagnosticDataProvider;

static_assert(sizeof(DiagnosticDataProvider::BootReasonType) == sizeof(EmberAfBootReasonType),
static_assert(sizeof(chip::DeviceLayer::BootReasonType) == sizeof(EmberAfBootReasonType),
"BootReasonType size doesn't match EmberAfBootReasonType size");
static_assert(static_cast<uint8_t>(DiagnosticDataProvider::BootReasonType::Unspecified) == EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED &&
static_cast<uint8_t>(DiagnosticDataProvider::BootReasonType::SoftwareReset) ==
static_assert(static_cast<uint8_t>(chip::DeviceLayer::BootReasonType::Unspecified) == EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED &&
static_cast<uint8_t>(chip::DeviceLayer::BootReasonType::SoftwareReset) ==
EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_RESET,
"BootReasonType and EmberAfBootReasonType values does not match.");

Expand Down Expand Up @@ -195,11 +195,22 @@ class GeneralDiagnosticsDelegate : public DeviceLayer::ConnectivityManagerDelega
}

// Gets called when the device has been rebooted.
void OnDeviceRebooted() override
void OnDeviceRebooted(chip::DeviceLayer::BootReasonType bootReason) override
{
ChipLogProgress(Zcl, "GeneralDiagnosticsDelegate: OnDeviceRebooted");

ReportAttributeOnAllEndpoints(GeneralDiagnostics::Attributes::BootReasons::Id);

// GeneralDiagnostics cluster should exist only for endpoint 0.

Events::BootReason::Type event{ static_cast<EmberAfBootReasonType>(bootReason) };
EventNumber eventNumber;

CHIP_ERROR err = LogEvent(event, 0, eventNumber, EventOptions::Type::kUrgent);
if (CHIP_NO_ERROR != err)
{
ChipLogError(Zcl, "GeneralDiagnosticsDelegate: Failed to record BootReason event: %" CHIP_ERROR_FORMAT, err.Format());
}
}

// Get called when the Node detects a hardware fault has been raised.
Expand Down
3 changes: 2 additions & 1 deletion src/app/reporting/Engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ class Engine

uint32_t GetNumReportsInFlight() { return mNumReportsInFlight; }

void ScheduleUrgentEventDeliverySync();

private:
friend class TestReportingEngine;
/**
Expand Down Expand Up @@ -165,7 +167,6 @@ class Engine
CHIP_ERROR ScheduleUrgentEventDelivery(ConcreteEventPath & aPath);
CHIP_ERROR ScheduleBufferPressureEventDelivery(uint32_t aBytesWritten);
void GetMinEventLogPosition(uint32_t & aMinLogPosition);
void ScheduleUrgentEventDeliverySync();

/**
* If the provided path is a superset of our of our existing paths, update that existing path to match the
Expand Down
19 changes: 19 additions & 0 deletions src/app/server/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,25 @@ void Server::DispatchShutDownAndStopEventLoop()
chip::DeviceLayer::PlatformMgr().ScheduleWork(StopEventLoop);
}

void Server::ScheduleFactoryReset()
{
chip::DeviceLayer::PlatformMgr().ScheduleWork(FactoryReset);
}

void Server::FactoryReset(intptr_t arg)
{
// Delete all fabrics and emit Leave event.
GetInstance().GetFabricTable().DeleteAllFabrics();

// Emit Shutdown event, as shutdown will come after factory reset.
DispatchShutDownEvent(0);

// Flush all dispatched events.
chip::app::InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleUrgentEventDeliverySync();

chip::DeviceLayer::ConfigurationMgr().InitiateFactoryReset();
}

void Server::Shutdown()
{
chip::Dnssd::ServiceAdvertiser::Instance().Shutdown();
Expand Down
4 changes: 4 additions & 0 deletions src/app/server/Server.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ class Server

void Shutdown();

void ScheduleFactoryReset();

static void FactoryReset(intptr_t arg);

static Server & GetInstance() { return sServer; }

private:
Expand Down
24 changes: 12 additions & 12 deletions src/include/platform/DiagnosticDataProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ constexpr size_t kMaxIPv6AddrSize = 16;
constexpr size_t kMaxIPv4AddrCount = 4;
constexpr size_t kMaxIPv6AddrCount = 8;

enum BootReasonType : uint8_t
{
Unspecified = 0,
PowerOnReboot = 1,
BrownOutReset = 2,
SoftwareWatchdogReset = 3,
HardwareWatchdogReset = 4,
SoftwareUpdateCompleted = 5,
SoftwareReset = 6,
};

struct ThreadMetrics : public app::Clusters::SoftwareDiagnostics::Structs::ThreadMetrics::Type
{
char NameBuf[kMaxThreadNameLength + 1];
Expand Down Expand Up @@ -70,7 +81,7 @@ class GeneralDiagnosticsDelegate
* @brief
* Called after the current device is rebooted.
*/
virtual void OnDeviceRebooted() {}
virtual void OnDeviceRebooted(BootReasonType bootReason) {}

/**
* @brief
Expand Down Expand Up @@ -142,17 +153,6 @@ class WiFiDiagnosticsDelegate
class DiagnosticDataProvider
{
public:
enum BootReasonType : uint8_t
{
Unspecified = 0,
PowerOnReboot = 1,
BrownOutReset = 2,
SoftwareWatchdogReset = 3,
HardwareWatchdogReset = 4,
SoftwareUpdateCompleted = 5,
SoftwareReset = 6,
};

void SetGeneralDiagnosticsDelegate(GeneralDiagnosticsDelegate * delegate) { mGeneralDiagnosticsDelegate = delegate; }
GeneralDiagnosticsDelegate * GetGeneralDiagnosticsDelegate() const { return mGeneralDiagnosticsDelegate; }

Expand Down
Loading

0 comments on commit 843643c

Please sign in to comment.