Skip to content

Commit

Permalink
[events] Refactor startup and shutdown event management (#15909)
Browse files Browse the repository at this point in the history
* [events] Refactor startup and shutdown event management

Add PlatformMgr().HandleServerStarted() to handle post-init
actions, such as emitting StartUp and BootReason events and
call it explicitly inside Server::Init not to rely on any
specific Matter stack initialization mechanism.

Add PlatformMgr().HandleServerShuttingDown() to handle
pre-shutdown actions, such as emitting Shutdown event. Use
the method in the existing factory reset sequence, and in
nRF Connect OTA image processor (other platforms should
probably be updated, too).

* Fix fake platform
  • Loading branch information
Damian-Nordic authored and pull[bot] committed Mar 23, 2022
1 parent d2daa2b commit 4158147
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 66 deletions.
16 changes: 10 additions & 6 deletions src/app/clusters/basic/basic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <app-common/zap-generated/cluster-objects.h>
#include <app/DataModelRevision.h>
#include <app/EventLogging.h>
#include <app/InteractionModelEngine.h>
#include <app/util/attribute-storage.h>
#include <platform/CHIPDeviceLayer.h>
#include <platform/ConfigurationManager.h>
Expand Down Expand Up @@ -329,10 +330,10 @@ CHIP_ERROR BasicAttrAccess::WriteLocation(AttributeValueDecoder & aDecoder)

class PlatformMgrDelegate : public DeviceLayer::PlatformManagerDelegate
{
// Gets called by the current Node after completing a boot or reboot process
void OnStartUp(uint32_t softwareVersion) override
{
ChipLogProgress(Zcl, "PlatformMgrDelegate: OnStartUp");
// The StartUp event SHALL be emitted by a Node after completing a boot or reboot process
ChipLogDetail(Zcl, "Emitting StartUp event");

for (auto endpoint : EnabledEndpointsWithServerCluster(Basic::Id))
{
Expand All @@ -343,15 +344,15 @@ class PlatformMgrDelegate : public DeviceLayer::PlatformManagerDelegate
CHIP_ERROR err = LogEvent(event, endpoint, eventNumber);
if (CHIP_NO_ERROR != err)
{
ChipLogError(Zcl, "PlatformMgrDelegate: Failed to record StartUp event: %" CHIP_ERROR_FORMAT, err.Format());
ChipLogError(Zcl, "Failed to emit StartUp event: %" CHIP_ERROR_FORMAT, err.Format());
}
}
}

// Gets called by the current Node prior to any orderly shutdown sequence on a best-effort basis.
void OnShutDown() override
{
ChipLogProgress(Zcl, "PlatformMgrDelegate: OnShutDown");
// The ShutDown event SHOULD be emitted on a best-effort basis by a Node prior to any orderly shutdown sequence.
ChipLogDetail(Zcl, "Emitting ShutDown event");

for (auto endpoint : EnabledEndpointsWithServerCluster(Basic::Id))
{
Expand All @@ -362,9 +363,12 @@ class PlatformMgrDelegate : public DeviceLayer::PlatformManagerDelegate
CHIP_ERROR err = LogEvent(event, endpoint, eventNumber);
if (CHIP_NO_ERROR != err)
{
ChipLogError(Zcl, "PlatformMgrDelegate: Failed to record ShutDown event: %" CHIP_ERROR_FORMAT, err.Format());
ChipLogError(Zcl, "Failed to emit ShutDown event: %" CHIP_ERROR_FORMAT, err.Format());
}
}

// Flush the events to increase chances that they get sent before the shutdown
InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleUrgentEventDeliverySync();
}
};

Expand Down
39 changes: 12 additions & 27 deletions src/app/server/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
#include <system/TLVPacketBufferBackingStore.h>
#include <transport/SessionManager.h>

using namespace chip::DeviceLayer;

using chip::kMinValidFabricIndex;
using chip::RendezvousInformationFlag;
using chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr;
Expand Down Expand Up @@ -75,16 +77,6 @@ void StopEventLoop(intptr_t arg)
}
}

void DispatchShutDownEvent(intptr_t arg)
{
// The ShutDown event SHOULD be emitted on a best-effort basis by a Node prior to any orderly shutdown sequence.
chip::DeviceLayer::PlatformManagerDelegate * platformManagerDelegate = chip::DeviceLayer::PlatformMgr().GetDelegate();
if (platformManagerDelegate != nullptr)
{
platformManagerDelegate->OnShutDown();
}
}

} // namespace

namespace chip {
Expand Down Expand Up @@ -270,6 +262,8 @@ CHIP_ERROR Server::Init(AppDelegate * delegate, uint16_t secureServicePort, uint
RejoinExistingMulticastGroups();
#endif // !CHIP_DEVICE_CONFIG_ENABLE_THREAD

PlatformMgr().HandleServerStarted();

exit:
if (err != CHIP_NO_ERROR)
{
Expand Down Expand Up @@ -317,27 +311,18 @@ void Server::RejoinExistingMulticastGroups()

void Server::DispatchShutDownAndStopEventLoop()
{
chip::DeviceLayer::PlatformMgr().ScheduleWork(DispatchShutDownEvent);
chip::DeviceLayer::PlatformMgr().ScheduleWork(StopEventLoop);
PlatformMgr().ScheduleWork([](intptr_t) { PlatformMgr().HandleServerShuttingDown(); });
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();
PlatformMgr().ScheduleWork([](intptr_t) {
// Delete all fabrics and emit Leave event.
GetInstance().GetFabricTable().DeleteAllFabrics();
PlatformMgr().HandleServerShuttingDown();
ConfigurationMgr().InitiateFactoryReset();
});
}

void Server::Shutdown()
Expand Down
2 changes: 0 additions & 2 deletions src/app/server/Server.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ class Server

void ScheduleFactoryReset();

static void FactoryReset(intptr_t arg);

static Server & GetInstance() { return sServer; }

private:
Expand Down
22 changes: 22 additions & 0 deletions src/include/platform/PlatformManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@ class PlatformManager
void SetDelegate(PlatformManagerDelegate * delegate) { mDelegate = delegate; }
PlatformManagerDelegate * GetDelegate() const { return mDelegate; }

/**
* Should be called after initializing all layers of the Matter stack to
* run all needed post-startup actions.
*/
void HandleServerStarted();

/**
* Should be called before shutting down the Matter stack or restarting the
* application to run all needed pre-shutdown actions.
*/
void HandleServerShuttingDown();

/**
* ScheduleWork can be called after InitChipStack has been called. Calls
* that happen before either StartEventLoopTask or RunEventLoop will queue
Expand Down Expand Up @@ -342,6 +354,16 @@ inline void PlatformManager::RemoveEventHandler(EventHandlerFunct handler, intpt
static_cast<ImplClass *>(this)->_RemoveEventHandler(handler, arg);
}

inline void PlatformManager::HandleServerStarted()
{
static_cast<ImplClass *>(this)->_HandleServerStarted();
}

inline void PlatformManager::HandleServerShuttingDown()
{
static_cast<ImplClass *>(this)->_HandleServerShuttingDown();
}

inline void PlatformManager::ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg)
{
static_cast<ImplClass *>(this)->_ScheduleWork(workFunct, arg);
Expand Down
62 changes: 34 additions & 28 deletions src/include/platform/internal/GenericPlatformManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,6 @@ CHIP_ERROR GenericPlatformManagerImpl<ImplClass>::_InitChipStack()

SuccessOrExit(err);

// TODO Initialize the Software Update Manager object.

_ScheduleWork(HandleDeviceRebooted, 0);

exit:
return err;
}
Expand Down Expand Up @@ -195,6 +191,40 @@ void GenericPlatformManagerImpl<ImplClass>::_RemoveEventHandler(PlatformManager:
}
}

template <class ImplClass>
void GenericPlatformManagerImpl<ImplClass>::_HandleServerStarted()
{
PlatformManagerDelegate * platformManagerDelegate = PlatformMgr().GetDelegate();
GeneralDiagnosticsDelegate * generalDiagnosticsDelegate = GetDiagnosticDataProvider().GetGeneralDiagnosticsDelegate();

if (platformManagerDelegate != nullptr)
{
uint32_t softwareVersion;

if (ConfigurationMgr().GetSoftwareVersion(softwareVersion) == CHIP_NO_ERROR)
platformManagerDelegate->OnStartUp(softwareVersion);
}

if (generalDiagnosticsDelegate != nullptr)
{
uint8_t bootReason;

if (GetDiagnosticDataProvider().GetBootReason(bootReason) == CHIP_NO_ERROR)
generalDiagnosticsDelegate->OnDeviceRebooted(static_cast<BootReasonType>(bootReason));
}
}

template <class ImplClass>
void GenericPlatformManagerImpl<ImplClass>::_HandleServerShuttingDown()
{
PlatformManagerDelegate * platformManagerDelegate = PlatformMgr().GetDelegate();

if (platformManagerDelegate != nullptr)
{
platformManagerDelegate->OnShutDown();
}
}

template <class ImplClass>
void GenericPlatformManagerImpl<ImplClass>::_ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg)
{
Expand Down Expand Up @@ -290,30 +320,6 @@ void GenericPlatformManagerImpl<ImplClass>::HandleMessageLayerActivityChanged(bo
}
}

template <class ImplClass>
void GenericPlatformManagerImpl<ImplClass>::HandleDeviceRebooted(intptr_t arg)
{
PlatformManagerDelegate * platformManagerDelegate = PlatformMgr().GetDelegate();
GeneralDiagnosticsDelegate * generalDiagnosticsDelegate = GetDiagnosticDataProvider().GetGeneralDiagnosticsDelegate();

if (generalDiagnosticsDelegate != nullptr)
{
uint8_t bootReason;

if (GetDiagnosticDataProvider().GetBootReason(bootReason) == CHIP_NO_ERROR)
generalDiagnosticsDelegate->OnDeviceRebooted(static_cast<BootReasonType>(bootReason));
}

// The StartUp event SHALL be emitted by a Node after completing a boot or reboot process
if (platformManagerDelegate != nullptr)
{
uint32_t softwareVersion;

if (ConfigurationMgr().GetSoftwareVersion(softwareVersion) == CHIP_NO_ERROR)
platformManagerDelegate->OnStartUp(softwareVersion);
}
}

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
template class GenericPlatformManagerImpl<PlatformManagerImpl>;

Expand Down
3 changes: 2 additions & 1 deletion src/include/platform/internal/GenericPlatformManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ class GenericPlatformManagerImpl
CHIP_ERROR _Shutdown();
CHIP_ERROR _AddEventHandler(PlatformManager::EventHandlerFunct handler, intptr_t arg);
void _RemoveEventHandler(PlatformManager::EventHandlerFunct handler, intptr_t arg);
void _HandleServerStarted();
void _HandleServerShuttingDown();
void _ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg);
void _DispatchEvent(const ChipDeviceEvent * event);

Expand All @@ -78,7 +80,6 @@ class GenericPlatformManagerImpl
private:
bool mMsgLayerWasActive;

static void HandleDeviceRebooted(intptr_t arg);
ImplClass * Impl() { return static_cast<ImplClass *>(this); }
};

Expand Down
2 changes: 2 additions & 0 deletions src/platform/fake/PlatformManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class PlatformManagerImpl final : public PlatformManager

CHIP_ERROR _AddEventHandler(EventHandlerFunct handler, intptr_t arg = 0) { return CHIP_ERROR_NOT_IMPLEMENTED; }
void _RemoveEventHandler(EventHandlerFunct handler, intptr_t arg = 0) {}
void _HandleServerStarted() {}
void _HandleServerShuttingDown() {}
void _ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg = 0) {}

void _RunEventLoop()
Expand Down
6 changes: 6 additions & 0 deletions src/platform/nrfconnect/CHIPDevicePlatformConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@
#define CHIP_DEVICE_CONFIG_OTA_REQUESTOR_REBOOT_DELAY_MS 1000
#endif // CHIP_DEVICE_CONFIG_OTA_REQUESTOR_REBOOT_DELAY_MS

#ifndef CHIP_DEVICE_CONFIG_SERVER_SHUTDOWN_ACTIONS_SLEEP_MS
/// Time to sleep after running server shutdown actions to let lower layers complete the actions.
/// This may include transmitting packets created by the actions.
#define CHIP_DEVICE_CONFIG_SERVER_SHUTDOWN_ACTIONS_SLEEP_MS 10
#endif // CHIP_DEVICE_CONFIG_SERVER_SHUTDOWN_ACTIONS_SLEEP_MS

// ========== Platform-specific Configuration Overrides =========

#ifndef CHIP_DEVICE_CONFIG_CHIP_TASK_PRIORITY
Expand Down
9 changes: 7 additions & 2 deletions src/platform/nrfconnect/OTAImageProcessorImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,14 @@ CHIP_ERROR OTAImageProcessorImpl::Apply()
ReturnErrorOnFailure(System::MapErrorZephyr(dfu_target_done(true)));

#ifdef CONFIG_CHIP_OTA_REQUESTOR_REBOOT_ON_APPLY
return DeviceLayer::SystemLayer().StartTimer(
return SystemLayer().StartTimer(
System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_OTA_REQUESTOR_REBOOT_DELAY_MS),
[](System::Layer *, void * /* context */) { sys_reboot(SYS_REBOOT_WARM); }, nullptr /* context */);
[](System::Layer *, void * /* context */) {
PlatformMgr().HandleServerShuttingDown();
k_msleep(CHIP_DEVICE_CONFIG_SERVER_SHUTDOWN_ACTIONS_SLEEP_MS);
sys_reboot(SYS_REBOOT_WARM);
},
nullptr /* context */);
#else
return CHIP_NO_ERROR;
#endif
Expand Down

0 comments on commit 4158147

Please sign in to comment.