Skip to content

Commit 3922041

Browse files
Damian-Nordicpull[bot]
authored andcommitted
[events] Refactor startup and shutdown event management (#15909)
* [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
1 parent 45bcb8d commit 3922041

9 files changed

+95
-66
lines changed

src/app/clusters/basic/basic.cpp

+10-6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <app-common/zap-generated/cluster-objects.h>
2323
#include <app/DataModelRevision.h>
2424
#include <app/EventLogging.h>
25+
#include <app/InteractionModelEngine.h>
2526
#include <app/util/attribute-storage.h>
2627
#include <platform/CHIPDeviceLayer.h>
2728
#include <platform/ConfigurationManager.h>
@@ -329,10 +330,10 @@ CHIP_ERROR BasicAttrAccess::WriteLocation(AttributeValueDecoder & aDecoder)
329330

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

337338
for (auto endpoint : EnabledEndpointsWithServerCluster(Basic::Id))
338339
{
@@ -343,15 +344,15 @@ class PlatformMgrDelegate : public DeviceLayer::PlatformManagerDelegate
343344
CHIP_ERROR err = LogEvent(event, endpoint, eventNumber);
344345
if (CHIP_NO_ERROR != err)
345346
{
346-
ChipLogError(Zcl, "PlatformMgrDelegate: Failed to record StartUp event: %" CHIP_ERROR_FORMAT, err.Format());
347+
ChipLogError(Zcl, "Failed to emit StartUp event: %" CHIP_ERROR_FORMAT, err.Format());
347348
}
348349
}
349350
}
350351

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

356357
for (auto endpoint : EnabledEndpointsWithServerCluster(Basic::Id))
357358
{
@@ -362,9 +363,12 @@ class PlatformMgrDelegate : public DeviceLayer::PlatformManagerDelegate
362363
CHIP_ERROR err = LogEvent(event, endpoint, eventNumber);
363364
if (CHIP_NO_ERROR != err)
364365
{
365-
ChipLogError(Zcl, "PlatformMgrDelegate: Failed to record ShutDown event: %" CHIP_ERROR_FORMAT, err.Format());
366+
ChipLogError(Zcl, "Failed to emit ShutDown event: %" CHIP_ERROR_FORMAT, err.Format());
366367
}
367368
}
369+
370+
// Flush the events to increase chances that they get sent before the shutdown
371+
InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleUrgentEventDeliverySync();
368372
}
369373
};
370374

src/app/server/Server.cpp

+12-27
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
#include <system/TLVPacketBufferBackingStore.h>
4646
#include <transport/SessionManager.h>
4747

48+
using namespace chip::DeviceLayer;
49+
4850
using chip::kMinValidFabricIndex;
4951
using chip::RendezvousInformationFlag;
5052
using chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr;
@@ -75,16 +77,6 @@ void StopEventLoop(intptr_t arg)
7577
}
7678
}
7779

78-
void DispatchShutDownEvent(intptr_t arg)
79-
{
80-
// The ShutDown event SHOULD be emitted on a best-effort basis by a Node prior to any orderly shutdown sequence.
81-
chip::DeviceLayer::PlatformManagerDelegate * platformManagerDelegate = chip::DeviceLayer::PlatformMgr().GetDelegate();
82-
if (platformManagerDelegate != nullptr)
83-
{
84-
platformManagerDelegate->OnShutDown();
85-
}
86-
}
87-
8880
} // namespace
8981

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

265+
PlatformMgr().HandleServerStarted();
266+
273267
exit:
274268
if (err != CHIP_NO_ERROR)
275269
{
@@ -317,27 +311,18 @@ void Server::RejoinExistingMulticastGroups()
317311

318312
void Server::DispatchShutDownAndStopEventLoop()
319313
{
320-
chip::DeviceLayer::PlatformMgr().ScheduleWork(DispatchShutDownEvent);
321-
chip::DeviceLayer::PlatformMgr().ScheduleWork(StopEventLoop);
314+
PlatformMgr().ScheduleWork([](intptr_t) { PlatformMgr().HandleServerShuttingDown(); });
315+
PlatformMgr().ScheduleWork(StopEventLoop);
322316
}
323317

324318
void Server::ScheduleFactoryReset()
325319
{
326-
chip::DeviceLayer::PlatformMgr().ScheduleWork(FactoryReset);
327-
}
328-
329-
void Server::FactoryReset(intptr_t arg)
330-
{
331-
// Delete all fabrics and emit Leave event.
332-
GetInstance().GetFabricTable().DeleteAllFabrics();
333-
334-
// Emit Shutdown event, as shutdown will come after factory reset.
335-
DispatchShutDownEvent(0);
336-
337-
// Flush all dispatched events.
338-
chip::app::InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleUrgentEventDeliverySync();
339-
340-
chip::DeviceLayer::ConfigurationMgr().InitiateFactoryReset();
320+
PlatformMgr().ScheduleWork([](intptr_t) {
321+
// Delete all fabrics and emit Leave event.
322+
GetInstance().GetFabricTable().DeleteAllFabrics();
323+
PlatformMgr().HandleServerShuttingDown();
324+
ConfigurationMgr().InitiateFactoryReset();
325+
});
341326
}
342327

343328
void Server::Shutdown()

src/app/server/Server.h

-2
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,6 @@ class Server
104104

105105
void ScheduleFactoryReset();
106106

107-
static void FactoryReset(intptr_t arg);
108-
109107
static Server & GetInstance() { return sServer; }
110108

111109
private:

src/include/platform/PlatformManager.h

+22
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,18 @@ class PlatformManager
117117
void SetDelegate(PlatformManagerDelegate * delegate) { mDelegate = delegate; }
118118
PlatformManagerDelegate * GetDelegate() const { return mDelegate; }
119119

120+
/**
121+
* Should be called after initializing all layers of the Matter stack to
122+
* run all needed post-startup actions.
123+
*/
124+
void HandleServerStarted();
125+
126+
/**
127+
* Should be called before shutting down the Matter stack or restarting the
128+
* application to run all needed pre-shutdown actions.
129+
*/
130+
void HandleServerShuttingDown();
131+
120132
/**
121133
* ScheduleWork can be called after InitChipStack has been called. Calls
122134
* that happen before either StartEventLoopTask or RunEventLoop will queue
@@ -342,6 +354,16 @@ inline void PlatformManager::RemoveEventHandler(EventHandlerFunct handler, intpt
342354
static_cast<ImplClass *>(this)->_RemoveEventHandler(handler, arg);
343355
}
344356

357+
inline void PlatformManager::HandleServerStarted()
358+
{
359+
static_cast<ImplClass *>(this)->_HandleServerStarted();
360+
}
361+
362+
inline void PlatformManager::HandleServerShuttingDown()
363+
{
364+
static_cast<ImplClass *>(this)->_HandleServerShuttingDown();
365+
}
366+
345367
inline void PlatformManager::ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg)
346368
{
347369
static_cast<ImplClass *>(this)->_ScheduleWork(workFunct, arg);

src/include/platform/internal/GenericPlatformManagerImpl.cpp

+34-28
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,6 @@ CHIP_ERROR GenericPlatformManagerImpl<ImplClass>::_InitChipStack()
121121

122122
SuccessOrExit(err);
123123

124-
// TODO Initialize the Software Update Manager object.
125-
126-
_ScheduleWork(HandleDeviceRebooted, 0);
127-
128124
exit:
129125
return err;
130126
}
@@ -195,6 +191,40 @@ void GenericPlatformManagerImpl<ImplClass>::_RemoveEventHandler(PlatformManager:
195191
}
196192
}
197193

194+
template <class ImplClass>
195+
void GenericPlatformManagerImpl<ImplClass>::_HandleServerStarted()
196+
{
197+
PlatformManagerDelegate * platformManagerDelegate = PlatformMgr().GetDelegate();
198+
GeneralDiagnosticsDelegate * generalDiagnosticsDelegate = GetDiagnosticDataProvider().GetGeneralDiagnosticsDelegate();
199+
200+
if (platformManagerDelegate != nullptr)
201+
{
202+
uint32_t softwareVersion;
203+
204+
if (ConfigurationMgr().GetSoftwareVersion(softwareVersion) == CHIP_NO_ERROR)
205+
platformManagerDelegate->OnStartUp(softwareVersion);
206+
}
207+
208+
if (generalDiagnosticsDelegate != nullptr)
209+
{
210+
uint8_t bootReason;
211+
212+
if (GetDiagnosticDataProvider().GetBootReason(bootReason) == CHIP_NO_ERROR)
213+
generalDiagnosticsDelegate->OnDeviceRebooted(static_cast<BootReasonType>(bootReason));
214+
}
215+
}
216+
217+
template <class ImplClass>
218+
void GenericPlatformManagerImpl<ImplClass>::_HandleServerShuttingDown()
219+
{
220+
PlatformManagerDelegate * platformManagerDelegate = PlatformMgr().GetDelegate();
221+
222+
if (platformManagerDelegate != nullptr)
223+
{
224+
platformManagerDelegate->OnShutDown();
225+
}
226+
}
227+
198228
template <class ImplClass>
199229
void GenericPlatformManagerImpl<ImplClass>::_ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg)
200230
{
@@ -290,30 +320,6 @@ void GenericPlatformManagerImpl<ImplClass>::HandleMessageLayerActivityChanged(bo
290320
}
291321
}
292322

293-
template <class ImplClass>
294-
void GenericPlatformManagerImpl<ImplClass>::HandleDeviceRebooted(intptr_t arg)
295-
{
296-
PlatformManagerDelegate * platformManagerDelegate = PlatformMgr().GetDelegate();
297-
GeneralDiagnosticsDelegate * generalDiagnosticsDelegate = GetDiagnosticDataProvider().GetGeneralDiagnosticsDelegate();
298-
299-
if (generalDiagnosticsDelegate != nullptr)
300-
{
301-
uint8_t bootReason;
302-
303-
if (GetDiagnosticDataProvider().GetBootReason(bootReason) == CHIP_NO_ERROR)
304-
generalDiagnosticsDelegate->OnDeviceRebooted(static_cast<BootReasonType>(bootReason));
305-
}
306-
307-
// The StartUp event SHALL be emitted by a Node after completing a boot or reboot process
308-
if (platformManagerDelegate != nullptr)
309-
{
310-
uint32_t softwareVersion;
311-
312-
if (ConfigurationMgr().GetSoftwareVersion(softwareVersion) == CHIP_NO_ERROR)
313-
platformManagerDelegate->OnStartUp(softwareVersion);
314-
}
315-
}
316-
317323
// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
318324
template class GenericPlatformManagerImpl<PlatformManagerImpl>;
319325

src/include/platform/internal/GenericPlatformManagerImpl.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ class GenericPlatformManagerImpl
5555
CHIP_ERROR _Shutdown();
5656
CHIP_ERROR _AddEventHandler(PlatformManager::EventHandlerFunct handler, intptr_t arg);
5757
void _RemoveEventHandler(PlatformManager::EventHandlerFunct handler, intptr_t arg);
58+
void _HandleServerStarted();
59+
void _HandleServerShuttingDown();
5860
void _ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg);
5961
void _DispatchEvent(const ChipDeviceEvent * event);
6062

@@ -78,7 +80,6 @@ class GenericPlatformManagerImpl
7880
private:
7981
bool mMsgLayerWasActive;
8082

81-
static void HandleDeviceRebooted(intptr_t arg);
8283
ImplClass * Impl() { return static_cast<ImplClass *>(this); }
8384
};
8485

src/platform/fake/PlatformManagerImpl.h

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ class PlatformManagerImpl final : public PlatformManager
4949

5050
CHIP_ERROR _AddEventHandler(EventHandlerFunct handler, intptr_t arg = 0) { return CHIP_ERROR_NOT_IMPLEMENTED; }
5151
void _RemoveEventHandler(EventHandlerFunct handler, intptr_t arg = 0) {}
52+
void _HandleServerStarted() {}
53+
void _HandleServerShuttingDown() {}
5254
void _ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg = 0) {}
5355

5456
void _RunEventLoop()

src/platform/nrfconnect/CHIPDevicePlatformConfig.h

+6
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@
6767
#define CHIP_DEVICE_CONFIG_OTA_REQUESTOR_REBOOT_DELAY_MS 1000
6868
#endif // CHIP_DEVICE_CONFIG_OTA_REQUESTOR_REBOOT_DELAY_MS
6969

70+
#ifndef CHIP_DEVICE_CONFIG_SERVER_SHUTDOWN_ACTIONS_SLEEP_MS
71+
/// Time to sleep after running server shutdown actions to let lower layers complete the actions.
72+
/// This may include transmitting packets created by the actions.
73+
#define CHIP_DEVICE_CONFIG_SERVER_SHUTDOWN_ACTIONS_SLEEP_MS 10
74+
#endif // CHIP_DEVICE_CONFIG_SERVER_SHUTDOWN_ACTIONS_SLEEP_MS
75+
7076
// ========== Platform-specific Configuration Overrides =========
7177

7278
#ifndef CHIP_DEVICE_CONFIG_CHIP_TASK_PRIORITY

src/platform/nrfconnect/OTAImageProcessorImpl.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,14 @@ CHIP_ERROR OTAImageProcessorImpl::Apply()
6161
ReturnErrorOnFailure(System::MapErrorZephyr(dfu_target_done(true)));
6262

6363
#ifdef CONFIG_CHIP_OTA_REQUESTOR_REBOOT_ON_APPLY
64-
return DeviceLayer::SystemLayer().StartTimer(
64+
return SystemLayer().StartTimer(
6565
System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_OTA_REQUESTOR_REBOOT_DELAY_MS),
66-
[](System::Layer *, void * /* context */) { sys_reboot(SYS_REBOOT_WARM); }, nullptr /* context */);
66+
[](System::Layer *, void * /* context */) {
67+
PlatformMgr().HandleServerShuttingDown();
68+
k_msleep(CHIP_DEVICE_CONFIG_SERVER_SHUTDOWN_ACTIONS_SLEEP_MS);
69+
sys_reboot(SYS_REBOOT_WARM);
70+
},
71+
nullptr /* context */);
6772
#else
6873
return CHIP_NO_ERROR;
6974
#endif

0 commit comments

Comments
 (0)