Matter SDK Coverage Report
Current view: top level - include/platform - PlatformManager.h (source / functions) Coverage Total Hit
Test: SHA:09f6fdf93a7e847a42518c076e487f336877a722 Lines: 57.6 % 33 19
Test Date: 2025-06-07 07:10:33 Functions: 63.6 % 11 7

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020 Project CHIP Authors
       4              :  *    Copyright (c) 2018 Nest Labs, Inc.
       5              :  *
       6              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       7              :  *    you may not use this file except in compliance with the License.
       8              :  *    You may obtain a copy of the License at
       9              :  *
      10              :  *        http://www.apache.org/licenses/LICENSE-2.0
      11              :  *
      12              :  *    Unless required by applicable law or agreed to in writing, software
      13              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      14              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15              :  *    See the License for the specific language governing permissions and
      16              :  *    limitations under the License.
      17              :  */
      18              : 
      19              : /**
      20              :  *    @file
      21              :  *          Defines the public interface for the Device Layer PlatformManager object.
      22              :  */
      23              : 
      24              : #pragma once
      25              : 
      26              : #include <platform/AttributeList.h>
      27              : #include <platform/CHIPDeviceConfig.h>
      28              : #include <platform/CHIPDeviceEvent.h>
      29              : #include <system/PlatformEventSupport.h>
      30              : #include <system/SystemLayer.h>
      31              : 
      32              : namespace chip {
      33              : 
      34              : namespace Dnssd {
      35              : class DiscoveryImplPlatform;
      36              : }
      37              : 
      38              : namespace DeviceLayer {
      39              : 
      40              : static constexpr size_t kMaxCalendarTypes = 12;
      41              : 
      42              : class PlatformManagerImpl;
      43              : class ConnectivityManagerImpl;
      44              : class ConfigurationManagerImpl;
      45              : class DeviceControlServer;
      46              : class TraitManager;
      47              : class ThreadStackManagerImpl;
      48              : 
      49              : namespace Internal {
      50              : class NFCCommissioningManagerImpl;
      51              : class BLEManagerImpl;
      52              : template <class>
      53              : class GenericConfigurationManagerImpl;
      54              : template <class>
      55              : class GenericPlatformManagerImpl;
      56              : template <class>
      57              : class GenericPlatformManagerImpl_CMSISOS;
      58              : template <class>
      59              : class GenericPlatformManagerImpl_FreeRTOS;
      60              : template <class>
      61              : class GenericPlatformManagerImpl_POSIX;
      62              : template <class>
      63              : class GenericPlatformManagerImpl_Zephyr;
      64              : template <class>
      65              : class GenericConnectivityManagerImpl_Thread;
      66              : template <class>
      67              : class GenericThreadStackManagerImpl_OpenThread;
      68              : template <class>
      69              : class GenericThreadStackManagerImpl_OpenThread_LwIP;
      70              : } // namespace Internal
      71              : 
      72              : /**
      73              :  * Defines the delegate class of Platform Manager to notify platform updates.
      74              :  */
      75              : class PlatformManagerDelegate
      76              : {
      77              : public:
      78              :     virtual ~PlatformManagerDelegate() {}
      79              : 
      80              :     /**
      81              :      * @brief
      82              :      *   Called by the current Node after completing a boot or reboot process.
      83              :      */
      84              :     virtual void OnStartUp(uint32_t softwareVersion) {}
      85              : 
      86              :     /**
      87              :      * @brief
      88              :      *   Called by the current Node prior to any orderly shutdown sequence on a
      89              :      *   best-effort basis.
      90              :      */
      91              :     virtual void OnShutDown() {}
      92              : };
      93              : 
      94              : /**
      95              :  * Provides features for initializing and interacting with the chip network
      96              :  * stack on a chip-enabled device.
      97              :  */
      98              : class PlatformManager
      99              : {
     100              :     using ImplClass = ::chip::DeviceLayer::PlatformManagerImpl;
     101              : 
     102              : public:
     103              :     // ===== Members that define the public interface of the PlatformManager
     104              : 
     105              :     typedef void (*EventHandlerFunct)(const ChipDeviceEvent * event, intptr_t arg);
     106              : 
     107              :     /**
     108              :      * InitChipStack() initializes the PlatformManager.  After calling that, a
     109              :      * consumer is allowed to call either StartEventLoopTask or RunEventLoop to
     110              :      * process pending work.  Calling both is not allowed: it must be one or the
     111              :      * other.
     112              :      */
     113              :     CHIP_ERROR InitChipStack();
     114              : 
     115              :     CHIP_ERROR AddEventHandler(EventHandlerFunct handler, intptr_t arg = 0);
     116              :     void RemoveEventHandler(EventHandlerFunct handler, intptr_t arg = 0);
     117              :     void SetDelegate(PlatformManagerDelegate * delegate) { mDelegate = delegate; }
     118              :     PlatformManagerDelegate * GetDelegate() const { return mDelegate; }
     119              : 
     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              : 
     132              :     /**
     133              :      * ScheduleWork can be called after InitChipStack has been called.  Calls
     134              :      * that happen before either StartEventLoopTask or RunEventLoop will queue
     135              :      * the work up but that work will NOT run until one of those functions is
     136              :      * called.
     137              :      *
     138              :      * ScheduleWork can be called safely on any thread without locking the
     139              :      * stack.  When called from a thread that is not doing the stack work item
     140              :      * processing, the callback function may be called (on the work item
     141              :      * processing thread) before ScheduleWork returns.
     142              :      */
     143              :     CHIP_ERROR ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg = 0);
     144              : 
     145              :     /**
     146              :      * Process work items until StopEventLoopTask is called.  RunEventLoop will
     147              :      * not return until work item processing is stopped.  Once it returns it
     148              :      * guarantees that no more work items will be processed unless there's
     149              :      * another call to RunEventLoop.
     150              :      *
     151              :      * Consumers that call RunEventLoop must not call StartEventLoopTask.
     152              :      *
     153              :      * Consumers that call RunEventLoop must ensure that RunEventLoop returns
     154              :      * before calling Shutdown.
     155              :      */
     156              :     void RunEventLoop();
     157              : 
     158              :     /**
     159              :      * Process work items until StopEventLoopTask is called.
     160              :      *
     161              :      * StartEventLoopTask processes items asynchronously.  It can return before
     162              :      * any items are processed, or after some items have been processed, or
     163              :      * while an item is being processed, or even after StopEventLoopTask() has
     164              :      * been called (e.g. if ScheduleWork() was called before StartEventLoopTask
     165              :      * was called, with a work item that calls StopEventLoopTask).
     166              :      *
     167              :      * Consumers that call StartEventLoopTask must not call RunEventLoop.
     168              :      *
     169              :      * Consumers that call StartEventLoopTask must ensure that they call
     170              :      * StopEventLoopTask before calling Shutdown.
     171              :      */
     172              :     CHIP_ERROR StartEventLoopTask();
     173              : 
     174              :     /**
     175              :      * Stop processing of work items by the event loop.
     176              :      *
     177              :      * If called from outside work item processing, StopEventLoopTask guarantees
     178              :      * that any currently-executing work item completes execution and no more
     179              :      * work items will run after StopEventLoopTask returns.  This is generally
     180              :      * how StopEventLoopTask is used in conjunction with StartEventLoopTask.
     181              :      *
     182              :      * If called from inside work item processing, StopEventLoopTask makes no
     183              :      * guarantees about exactly when work item processing will stop.  What it
     184              :      * does guarantee is that if it is used this way in conjunction with
     185              :      * RunEventLoop then all work item processing will stop before RunEventLoop
     186              :      * returns.
     187              :      */
     188              :     CHIP_ERROR StopEventLoopTask();
     189              : 
     190              :     void LockChipStack();
     191              :     bool TryLockChipStack();
     192              :     void UnlockChipStack();
     193              :     void Shutdown();
     194              : 
     195              : #if CHIP_STACK_LOCK_TRACKING_ENABLED
     196              :     bool IsChipStackLockedByCurrentThread() const;
     197              : #endif
     198              : 
     199              :     /*
     200              :      * PostEvent can be called safely on any thread without locking the stack.
     201              :      * When called from a thread that is not doing the stack work item
     202              :      * processing, the event might get dispatched (on the work item processing
     203              :      * thread) before PostEvent returns.
     204              :      */
     205              :     [[nodiscard]] CHIP_ERROR PostEvent(const ChipDeviceEvent * event);
     206              :     void PostEventOrDie(const ChipDeviceEvent * event);
     207              : 
     208              :     /**
     209              :      * Generally this function has the same semantics as ScheduleWork
     210              :      * except it applies to background processing.
     211              :      *
     212              :      * Delegates to PostBackgroundEvent (which will delegate to PostEvent if
     213              :      * CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING is not true).
     214              :      */
     215              :     CHIP_ERROR ScheduleBackgroundWork(AsyncWorkFunct workFunct, intptr_t arg = 0);
     216              : 
     217              :     /**
     218              :      * Generally this function has the same semantics as PostEvent
     219              :      * except it applies to background processing.
     220              :      *
     221              :      * If CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING is not true, will delegate
     222              :      * to PostEvent.
     223              :      *
     224              :      * Only accepts events of type kCallWorkFunct or kNoOp.
     225              :      *
     226              :      * Returns CHIP_ERROR_INVALID_ARGUMENT if the event type is not acceptable.
     227              :      * Returns CHIP_ERROR_NO_MEMORY if resources are exhausted.
     228              :      */
     229              :     CHIP_ERROR PostBackgroundEvent(const ChipDeviceEvent * event);
     230              : 
     231              :     /**
     232              :      * Generally this function has the same semantics as RunEventLoop
     233              :      * except it applies to background processing.
     234              :      */
     235              :     void RunBackgroundEventLoop();
     236              : 
     237              :     /**
     238              :      * Generally this function has the same semantics as StartEventLoopTask
     239              :      * except it applies to background processing.
     240              :      */
     241              :     CHIP_ERROR StartBackgroundEventLoopTask();
     242              : 
     243              :     /**
     244              :      * Generally this function has the same semantics as StopEventLoopTask
     245              :      * except it applies to background processing.
     246              :      */
     247              :     CHIP_ERROR StopBackgroundEventLoopTask();
     248              : 
     249              : private:
     250              :     bool mInitialized                   = false;
     251              :     PlatformManagerDelegate * mDelegate = nullptr;
     252              : 
     253              :     // ===== Members for internal use by the following friends.
     254              : 
     255              :     friend class PlatformManagerImpl;
     256              :     friend class ConnectivityManagerImpl;
     257              :     friend class ConfigurationManagerImpl;
     258              :     friend class DeviceControlServer;
     259              :     friend class Dnssd::DiscoveryImplPlatform;
     260              :     friend class FailSafeContext;
     261              :     friend class TraitManager;
     262              :     friend class ThreadStackManagerImpl;
     263              :     friend class Internal::NFCCommissioningManagerImpl;
     264              :     friend class Internal::BLEManagerImpl;
     265              :     template <class>
     266              :     friend class Internal::GenericPlatformManagerImpl;
     267              :     template <class>
     268              :     friend class Internal::GenericPlatformManagerImpl_CMSISOS;
     269              :     template <class>
     270              :     friend class Internal::GenericPlatformManagerImpl_FreeRTOS;
     271              :     template <class>
     272              :     friend class Internal::GenericPlatformManagerImpl_POSIX;
     273              :     template <class>
     274              :     friend class Internal::GenericPlatformManagerImpl_Zephyr;
     275              :     template <class>
     276              :     friend class Internal::GenericConnectivityManagerImpl_Thread;
     277              :     template <class>
     278              :     friend class Internal::GenericThreadStackManagerImpl_OpenThread;
     279              :     template <class>
     280              :     friend class Internal::GenericThreadStackManagerImpl_OpenThread_LwIP;
     281              :     template <class>
     282              :     friend class Internal::GenericConfigurationManagerImpl;
     283              :     friend class System::PlatformEventing;
     284              : 
     285              :     void DispatchEvent(const ChipDeviceEvent * event);
     286              :     CHIP_ERROR StartChipTimer(System::Clock::Timeout duration);
     287              : 
     288              : protected:
     289              :     // Construction/destruction limited to subclasses.
     290              :     PlatformManager()  = default;
     291              :     ~PlatformManager() = default;
     292              : 
     293              :     // No copy, move or assignment.
     294              :     PlatformManager(const PlatformManager &)             = delete;
     295              :     PlatformManager(const PlatformManager &&)            = delete;
     296              :     PlatformManager & operator=(const PlatformManager &) = delete;
     297              : };
     298              : 
     299              : /**
     300              :  * Returns the public interface of the PlatformManager singleton object.
     301              :  *
     302              :  * chip applications should use this to access features of the PlatformManager object
     303              :  * that are common to all platforms.
     304              :  */
     305              : extern PlatformManager & PlatformMgr();
     306              : 
     307              : /**
     308              :  * Returns the platform-specific implementation of the PlatformManager singleton object.
     309              :  *
     310              :  * chip applications can use this to gain access to features of the PlatformManager
     311              :  * that are specific to the selected platform.
     312              :  */
     313              : extern PlatformManagerImpl & PlatformMgrImpl();
     314              : 
     315              : /**
     316              :  * @brief
     317              :  * RAII locking for PlatformManager to simplify management of
     318              :  * LockChipStack()/UnlockChipStack calls.
     319              :  */
     320              : class StackLock
     321              : {
     322              : public:
     323              :     StackLock() { PlatformMgr().LockChipStack(); }
     324              : 
     325              :     ~StackLock() { PlatformMgr().UnlockChipStack(); }
     326              : };
     327              : 
     328              : /**
     329              :  * @brief
     330              :  * RAII unlocking for PlatformManager to simplify management of
     331              :  * LockChipStack()/UnlockChipStack calls.
     332              :  */
     333              : class StackUnlock
     334              : {
     335              : public:
     336              :     StackUnlock() { PlatformMgr().UnlockChipStack(); }
     337              :     ~StackUnlock() { PlatformMgr().LockChipStack(); }
     338              : };
     339              : 
     340              : } // namespace DeviceLayer
     341              : } // namespace chip
     342              : 
     343              : /* Include a header file containing the implementation of the ConfigurationManager
     344              :  * object for the selected platform.
     345              :  */
     346              : #ifdef EXTERNAL_PLATFORMMANAGERIMPL_HEADER
     347              : #include EXTERNAL_PLATFORMMANAGERIMPL_HEADER
     348              : #elif defined(CHIP_DEVICE_LAYER_TARGET)
     349              : #define PLATFORMMANAGERIMPL_HEADER <platform/CHIP_DEVICE_LAYER_TARGET/PlatformManagerImpl.h>
     350              : #include PLATFORMMANAGERIMPL_HEADER
     351              : #endif // defined(CHIP_DEVICE_LAYER_TARGET)
     352              : 
     353              : namespace chip {
     354              : namespace DeviceLayer {
     355              : 
     356              : #if CHIP_STACK_LOCK_TRACKING_ENABLED
     357              : inline bool PlatformManager::IsChipStackLockedByCurrentThread() const
     358              : {
     359              :     return static_cast<const ImplClass *>(this)->_IsChipStackLockedByCurrentThread();
     360              : }
     361              : #endif
     362              : 
     363            0 : inline CHIP_ERROR PlatformManager::InitChipStack()
     364              : {
     365              :     // NOTE: this is NOT thread safe and cannot be as the chip stack lock is prepared by
     366              :     // InitChipStack itself on many platforms.
     367              :     //
     368              :     // In the future, this could be moved into specific platform code (where it can
     369              :     // be made thread safe). In general however, init twice
     370              :     // is likely a logic error and we may want to avoid that path anyway. Likely to
     371              :     // be done once code stabilizes a bit more.
     372            0 :     if (mInitialized)
     373              :     {
     374            0 :         return CHIP_NO_ERROR;
     375              :     }
     376              : 
     377            0 :     CHIP_ERROR err = static_cast<ImplClass *>(this)->_InitChipStack();
     378            0 :     mInitialized   = (err == CHIP_NO_ERROR);
     379            0 :     return err;
     380              : }
     381              : 
     382           13 : inline CHIP_ERROR PlatformManager::AddEventHandler(EventHandlerFunct handler, intptr_t arg)
     383              : {
     384           13 :     return static_cast<ImplClass *>(this)->_AddEventHandler(handler, arg);
     385              : }
     386              : 
     387            6 : inline void PlatformManager::RemoveEventHandler(EventHandlerFunct handler, intptr_t arg)
     388              : {
     389            6 :     static_cast<ImplClass *>(this)->_RemoveEventHandler(handler, arg);
     390            6 : }
     391              : 
     392            1 : inline void PlatformManager::HandleServerStarted()
     393              : {
     394            1 :     static_cast<ImplClass *>(this)->_HandleServerStarted();
     395            1 : }
     396              : 
     397            1 : inline void PlatformManager::HandleServerShuttingDown()
     398              : {
     399            1 :     static_cast<ImplClass *>(this)->_HandleServerShuttingDown();
     400            1 : }
     401              : 
     402            0 : inline CHIP_ERROR PlatformManager::ScheduleWork(AsyncWorkFunct workFunct, intptr_t arg)
     403              : {
     404            0 :     return static_cast<ImplClass *>(this)->_ScheduleWork(workFunct, arg);
     405              : }
     406              : 
     407              : inline void PlatformManager::RunEventLoop()
     408              : {
     409              :     static_cast<ImplClass *>(this)->_RunEventLoop();
     410              : }
     411              : 
     412              : /**
     413              :  * @brief
     414              :  *  Starts the stack on its own task with an associated event queue
     415              :  *  to dispatch and handle events posted to that task.
     416              :  *
     417              :  *  This is thread-safe.
     418              :  *  This is *NOT SAFE* to call from within the CHIP event loop since it can grab the stack lock.
     419              :  */
     420            0 : inline CHIP_ERROR PlatformManager::StartEventLoopTask()
     421              : {
     422            0 :     return static_cast<ImplClass *>(this)->_StartEventLoopTask();
     423              : }
     424              : 
     425              : /**
     426              :  * @brief
     427              :  *  This will trigger the event loop to exit and block till it has exited the loop.
     428              :  *  This prevents the processing of any further events in the queue.
     429              :  *
     430              :  *  Additionally, this stops the CHIP task if the following criteria are met:
     431              :  *      1. One was created earlier through a call to StartEventLoopTask
     432              :  *      2. This call isn't being made from that task.
     433              :  *
     434              :  *  This is safe to call from any task.
     435              :  *  This is safe to call from within the CHIP event loop.
     436              :  *
     437              :  */
     438              : inline CHIP_ERROR PlatformManager::StopEventLoopTask()
     439              : {
     440              :     return static_cast<ImplClass *>(this)->_StopEventLoopTask();
     441              : }
     442              : 
     443              : /**
     444              :  * @brief
     445              :  *   Shuts down and cleans up the main objects in the CHIP stack.
     446              :  *   This DOES NOT stop the chip thread or event queue from running.
     447              :  *
     448              :  */
     449            0 : inline void PlatformManager::Shutdown()
     450              : {
     451            0 :     static_cast<ImplClass *>(this)->_Shutdown();
     452            0 :     mInitialized = false;
     453            0 : }
     454              : 
     455              : inline void PlatformManager::LockChipStack()
     456              : {
     457              :     static_cast<ImplClass *>(this)->_LockChipStack();
     458              : }
     459              : 
     460              : inline bool PlatformManager::TryLockChipStack()
     461              : {
     462              :     return static_cast<ImplClass *>(this)->_TryLockChipStack();
     463              : }
     464              : 
     465              : inline void PlatformManager::UnlockChipStack()
     466              : {
     467              :     static_cast<ImplClass *>(this)->_UnlockChipStack();
     468              : }
     469              : 
     470          121 : inline CHIP_ERROR PlatformManager::PostEvent(const ChipDeviceEvent * event)
     471              : {
     472          121 :     return static_cast<ImplClass *>(this)->_PostEvent(event);
     473              : }
     474              : 
     475            3 : inline void PlatformManager::PostEventOrDie(const ChipDeviceEvent * event)
     476              : {
     477            3 :     CHIP_ERROR status = static_cast<ImplClass *>(this)->_PostEvent(event);
     478            3 :     VerifyOrDieWithMsg(status == CHIP_NO_ERROR, DeviceLayer, "Failed to post event %d: %" CHIP_ERROR_FORMAT,
     479              :                        static_cast<int>(event->Type), status.Format());
     480            3 : }
     481              : 
     482            8 : inline CHIP_ERROR PlatformManager::ScheduleBackgroundWork(AsyncWorkFunct workFunct, intptr_t arg)
     483              : {
     484            8 :     return static_cast<ImplClass *>(this)->_ScheduleBackgroundWork(workFunct, arg);
     485              : }
     486              : 
     487              : inline CHIP_ERROR PlatformManager::PostBackgroundEvent(const ChipDeviceEvent * event)
     488              : {
     489              :     return static_cast<ImplClass *>(this)->_PostBackgroundEvent(event);
     490              : }
     491              : 
     492              : inline void PlatformManager::RunBackgroundEventLoop()
     493              : {
     494              :     static_cast<ImplClass *>(this)->_RunBackgroundEventLoop();
     495              : }
     496              : 
     497              : inline CHIP_ERROR PlatformManager::StartBackgroundEventLoopTask()
     498              : {
     499              :     return static_cast<ImplClass *>(this)->_StartBackgroundEventLoopTask();
     500              : }
     501              : 
     502              : inline CHIP_ERROR PlatformManager::StopBackgroundEventLoopTask()
     503              : {
     504              :     return static_cast<ImplClass *>(this)->_StopBackgroundEventLoopTask();
     505              : }
     506              : 
     507              : inline void PlatformManager::DispatchEvent(const ChipDeviceEvent * event)
     508              : {
     509              :     static_cast<ImplClass *>(this)->_DispatchEvent(event);
     510              : }
     511              : 
     512              : inline CHIP_ERROR PlatformManager::StartChipTimer(System::Clock::Timeout duration)
     513              : {
     514              :     return static_cast<ImplClass *>(this)->_StartChipTimer(duration);
     515              : }
     516              : 
     517              : } // namespace DeviceLayer
     518              : } // namespace chip
        

Generated by: LCOV version 2.0-1