Matter SDK Coverage Report
Current view: top level - include/platform - PlatformManager.h (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 48.5 % 33 16
Test Date: 2025-01-17 19:00:11 Functions: 54.5 % 11 6

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

Generated by: LCOV version 2.0-1