Matter SDK Coverage Report
Current view: top level - app/server - Server.h (source / functions) Coverage Total Hit
Test: SHA:f1767a8b0a3778fdf31b1d979afbdf544892fd94 Lines: 42.4 % 139 59
Test Date: 2026-06-03 07:35:21 Functions: 67.7 % 31 21

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020 Project CHIP Authors
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : 
      18              : #pragma once
      19              : 
      20              : #include <app/AppConfig.h>
      21              : #include <app/icd/server/ICDServerConfig.h>
      22              : 
      23              : #include <access/AccessControl.h>
      24              : #include <access/GroupAuxiliaryAccessControlDelegate.h>
      25              : #include <access/examples/ExampleAccessControlDelegate.h>
      26              : #include <access/examples/GroupAuxiliaryAccessControlDelegateImpl.h>
      27              : #include <app/CASEClientPool.h>
      28              : #include <app/CASESessionManager.h>
      29              : #include <app/DefaultSafeAttributePersistenceProvider.h>
      30              : #include <app/FailSafeContext.h>
      31              : #include <app/OperationalSessionSetupPool.h>
      32              : #include <app/SimpleSubscriptionResumptionStorage.h>
      33              : #include <app/TestEventTriggerDelegate.h>
      34              : #include <app/server/AclStorage.h>
      35              : #include <app/server/AppDelegate.h>
      36              : #include <app/server/CommissioningWindowManager.h>
      37              : #include <app/server/DefaultAclStorage.h>
      38              : #include <credentials/CertificateValidityPolicy.h>
      39              : #include <credentials/FabricTable.h>
      40              : #include <credentials/GroupDataProvider.h>
      41              : #include <credentials/GroupDataProviderImpl.h>
      42              : #include <credentials/OperationalCertificateStore.h>
      43              : #include <credentials/PersistentStorageOpCertStore.h>
      44              : #include <crypto/DefaultSessionKeystore.h>
      45              : #include <crypto/OperationalKeystore.h>
      46              : #include <crypto/PersistentStorageOperationalKeystore.h>
      47              : #include <inet/InetConfig.h>
      48              : #include <lib/core/CHIPConfig.h>
      49              : #include <lib/support/AutoRelease.h>
      50              : #include <lib/support/SafeInt.h>
      51              : #include <messaging/ExchangeMgr.h>
      52              : #include <platform/DefaultTimerDelegate.h>
      53              : #include <platform/DeviceInstanceInfoProvider.h>
      54              : #include <platform/KeyValueStoreManager.h>
      55              : #include <platform/KvsPersistentStorageDelegate.h>
      56              : #include <protocols/secure_channel/CASEServer.h>
      57              : #include <protocols/secure_channel/MessageCounterManager.h>
      58              : #include <protocols/secure_channel/PASESession.h>
      59              : #include <protocols/secure_channel/RendezvousParameters.h>
      60              : #include <protocols/secure_channel/UnsolicitedStatusHandler.h>
      61              : #if CHIP_CONFIG_ENABLE_SESSION_RESUMPTION
      62              : #include <protocols/secure_channel/SimpleSessionResumptionStorage.h>
      63              : #endif
      64              : #include <protocols/user_directed_commissioning/UserDirectedCommissioning.h>
      65              : #include <system/SystemClock.h>
      66              : #include <transport/SessionManager.h>
      67              : #include <transport/TransportMgr.h>
      68              : #include <transport/TransportMgrBase.h>
      69              : #if CONFIG_NETWORK_LAYER_BLE
      70              : #include <transport/raw/BLE.h>
      71              : #endif
      72              : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
      73              : #include <transport/raw/WiFiPAF.h>
      74              : #endif
      75              : #include <app/reporting/ReportSchedulerImpl.h>
      76              : #include <transport/raw/UDP.h>
      77              : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
      78              : #include <transport/raw/NFC.h>
      79              : #endif
      80              : 
      81              : #if CHIP_CONFIG_ENABLE_ICD_SERVER
      82              : #include <app/icd/server/ICDManager.h> // nogncheck
      83              : 
      84              : #if CHIP_CONFIG_ENABLE_ICD_CIP
      85              : #include <app/icd/server/DefaultICDCheckInBackOffStrategy.h> // nogncheck
      86              : #include <app/icd/server/ICDCheckInBackOffStrategy.h>        // nogncheck
      87              : #endif                                                       // CHIP_CONFIG_ENABLE_ICD_CIP
      88              : #endif                                                       // CHIP_CONFIG_ENABLE_ICD_SERVER
      89              : 
      90              : #if CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
      91              : #include <app/server/JointFabricAdministrator.h> //nogncheck
      92              : #include <app/server/JointFabricDatastore.h>     //nogncheck
      93              : #endif                                           // CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
      94              : 
      95              : namespace chip {
      96              : 
      97              : inline constexpr size_t kMaxBlePendingPackets = 1;
      98              : 
      99              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
     100              : inline constexpr size_t kMaxTcpActiveConnectionCount = CHIP_CONFIG_MAX_ACTIVE_TCP_CONNECTIONS;
     101              : 
     102              : inline constexpr size_t kMaxTcpPendingPackets = CHIP_CONFIG_MAX_TCP_PENDING_PACKETS;
     103              : #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
     104              : 
     105              : //
     106              : // NOTE: Please do not alter the order of template specialization here as the logic
     107              : //       in the Server impl depends on this.
     108              : //
     109              : using ServerTransportMgr = chip::TransportMgr<chip::Transport::UDP
     110              : #if INET_CONFIG_ENABLE_IPV4
     111              :                                               ,
     112              :                                               chip::Transport::UDP
     113              : #endif
     114              : #if CONFIG_NETWORK_LAYER_BLE
     115              :                                               ,
     116              :                                               chip::Transport::BLE<kMaxBlePendingPackets>
     117              : #endif
     118              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
     119              :                                               ,
     120              :                                               chip::Transport::TCP<kMaxTcpActiveConnectionCount, kMaxTcpPendingPackets>
     121              : #if INET_CONFIG_ENABLE_IPV4
     122              :                                               ,
     123              :                                               chip::Transport::TCP<kMaxTcpActiveConnectionCount, kMaxTcpPendingPackets>
     124              : #endif
     125              : #endif
     126              : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
     127              :                                               ,
     128              :                                               chip::Transport::WiFiPAFBase
     129              : #endif
     130              : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
     131              :                                               ,
     132              :                                               chip::Transport::NFC
     133              : #endif
     134              :                                               >;
     135              : 
     136              : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
     137              : using UdcTransportMgr = TransportMgr<Transport::UDP /* IPv6 */
     138              : #if INET_CONFIG_ENABLE_IPV4
     139              :                                      ,
     140              :                                      Transport::UDP /* IPv4 */
     141              : #endif
     142              :                                      >;
     143              : #endif
     144              : 
     145              : struct ServerInitParams
     146              : {
     147            1 :     ServerInitParams() = default;
     148              : 
     149              :     // Not copyable
     150              :     ServerInitParams(const ServerInitParams &)             = delete;
     151              :     ServerInitParams & operator=(const ServerInitParams &) = delete;
     152              : 
     153              :     // Application delegate to handle some commissioning lifecycle events
     154              :     AppDelegate * appDelegate = nullptr;
     155              :     // device discovery timeout
     156            1 :     System::Clock::Seconds32 discoveryTimeout = System::Clock::Seconds32(CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS);
     157              :     // Port to use for Matter commissioning/operational traffic
     158              :     uint16_t operationalServicePort = CHIP_PORT;
     159              :     // Port to use for UDC if supported
     160              :     uint16_t userDirectedCommissioningPort = CHIP_UDC_PORT;
     161              :     // Interface on which to run daemon
     162              :     Inet::InterfaceId interfaceId = Inet::InterfaceId::Null();
     163              : 
     164              : #if CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     165              :     // Number of sequential port retries if binding fails with "address in use"
     166              :     // When > 0, if binding to operationalServicePort (or userDirectedCommissioningPort) fails,
     167              :     // the system will automatically try portRetryCount additional sequential ports.
     168              :     // For example: if operationalServicePort=5540 and portRetryCount=10, it will try
     169              :     // ports 5540, 5541, 5542, ... up to 5550 until one succeeds.
     170              :     // When set to 0 (default), no retry is attempted - implements single port behavior.
     171              :     uint16_t portRetryCount = CHIP_DEVICE_CONFIG_PORT_RETRY_COUNT;
     172              : #endif // CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     173              : 
     174              :     // Persistent storage delegate: MUST be injected. Used to maintain storage by much common code.
     175              :     // Must be initialized before being provided.
     176              :     PersistentStorageDelegate * persistentStorageDelegate = nullptr;
     177              :     // Session resumption storage: Optional. Support session resumption when provided.
     178              :     // Must be initialized before being provided.
     179              :     SessionResumptionStorage * sessionResumptionStorage = nullptr;
     180              :     // Session resumption storage: Optional. Support session resumption when provided.
     181              :     // Must be initialized before being provided.
     182              :     app::SubscriptionResumptionStorage * subscriptionResumptionStorage = nullptr;
     183              :     // Certificate validity policy: Optional. If none is injected, CHIPCert
     184              :     // enforces a default policy.
     185              :     Credentials::CertificateValidityPolicy * certificateValidityPolicy = nullptr;
     186              :     // Group data provider: MUST be injected. Used to maintain critical keys such as the Identity
     187              :     // Protection Key (IPK) for CASE. Must be initialized before being provided.
     188              :     Credentials::GroupDataProvider * groupDataProvider = nullptr;
     189              :     // Session keystore: MUST be injected. Used to derive and manage lifecycle of symmetric keys.
     190              :     Crypto::SessionKeystore * sessionKeystore = nullptr;
     191              :     // Access control delegate: MUST be injected. Used to look up access control rules. Must be
     192              :     // initialized before being provided.
     193              :     Access::AccessControl::Delegate * accessDelegate = nullptr;
     194              :     // Access control auxiliary delegate: Optional. Used to look up auxiliary access control rules.
     195              :     // May be either pre-initialized (Initialize already called) or default-constructed:
     196              :     // Server::Init will call Initialize with its own FabricTable on a not-yet-initialized
     197              :     // delegate before registering it. Applications may substitute their own subclass of
     198              :     // Access::GroupAuxiliaryAccessControlDelegate rather than reusing the default Impl.
     199              :     Access::GroupAuxiliaryAccessControlDelegate * groupAuxiliaryAccessControlDelegate = nullptr;
     200              :     // ACL storage: MUST be injected. Used to store ACL entries in persistent storage. Must NOT
     201              :     // be initialized before being provided.
     202              :     app::AclStorage * aclStorage = nullptr;
     203              : 
     204              : #if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
     205              :     // Access Restriction implementation: MUST be injected if MNGD feature enabled. Used to enforce
     206              :     // access restrictions that are managed by the device.
     207              :     Access::AccessRestrictionProvider * accessRestrictionProvider = nullptr;
     208              : #endif
     209              : 
     210              :     // Network native params can be injected depending on the
     211              :     // selected Endpoint implementation
     212              :     void * endpointNativeParams = nullptr;
     213              :     // Optional. Support test event triggers when provided. Must be initialized before being
     214              :     // provided.
     215              :     TestEventTriggerDelegate * testEventTriggerDelegate = nullptr;
     216              :     // Operational keystore with access to the operational keys: MUST be injected.
     217              :     Crypto::OperationalKeystore * operationalKeystore = nullptr;
     218              :     // Operational certificate store with access to the operational certs in persisted storage:
     219              :     // must not be null at timne of Server::Init().
     220              :     Credentials::OperationalCertificateStore * opCertStore = nullptr;
     221              :     // Required, if not provided, the Server::Init() WILL fail.
     222              :     app::reporting::ReportScheduler * reportScheduler = nullptr;
     223              : #if CHIP_CONFIG_ENABLE_ICD_CIP
     224              :     // Optional. Support for the ICD Check-In BackOff strategy. Must be initialized before being provided.
     225              :     // If the ICD Check-In protocol use-case is supported and no strategy is provided, server will use the default strategy.
     226              :     app::ICDCheckInBackOffStrategy * icdCheckInBackOffStrategy = nullptr;
     227              : #endif // CHIP_CONFIG_ENABLE_ICD_CIP
     228              : 
     229              :     // MUST NOT be null during initialization: every application must define the
     230              :     // data model it wants to use. Backwards-compatibility can use `CodegenDataModelProviderInstance`
     231              :     // for ember/zap-generated models.
     232              :     chip::app::DataModel::Provider * dataModelProvider = nullptr;
     233              : 
     234              :     bool advertiseCommissionableIfNoFabrics = CHIP_DEVICE_CONFIG_ENABLE_PAIRING_AUTOSTART;
     235              : };
     236              : 
     237              : /**
     238              :  * Transitional version of ServerInitParams to assist SDK integrators in
     239              :  * transitioning to injecting product/platform-owned resources. This version
     240              :  * of `ServerInitParams` owns and initializes (via the `InitializeStaticResourcesBeforeServerInit()`
     241              :  * method) the persistent storage delegate, the group data provider, and the access control delegate.
     242              :  * This is to reduce the amount of copied boilerplate in all the example initializations
     243              :  * (e.g. AppTask.cpp, main.cpp).
     244              :  *
     245              :  * This version SHOULD BE USED ONLY FOR THE IN-TREE EXAMPLES.
     246              :  *
     247              :  * IMPORTANT: Instances of this class MUST outlive the Server because Server::Init()
     248              :  *            stores pointers to resources owned by this class.
     249              :  *
     250              :  * ACTION ITEMS FOR TRANSITION from a example in-tree to a product:
     251              :  *
     252              :  * While this could be used indefinitely, it does not exemplify orderly management of
     253              :  * application-injected resources. It is recommended for actual products to instead:
     254              :  *   - Use the basic ServerInitParams in the application
     255              :  *   - Have the application own an instance of the resources being injected in its own
     256              :  *     state (e.g. an implementation of PersistentStorageDelegate and GroupDataProvider
     257              :  *     interfaces).
     258              :  *   - Initialize the injected resources prior to calling Server::Init()
     259              :  *   - De-initialize the injected resources after calling Server::Shutdown()
     260              :  *
     261              :  * WARNING: DO NOT replicate the pattern shown here of having a subclass of ServerInitParams
     262              :  *          own the resources outside of examples. This was done to reduce the amount of change
     263              :  *          to existing examples while still supporting non-example versions of the
     264              :  *          resources to be injected.
     265              :  */
     266              : struct CommonCaseDeviceServerInitParams : public ServerInitParams
     267              : {
     268            1 :     CommonCaseDeviceServerInitParams() = default;
     269              : 
     270              :     // Not copyable
     271              :     CommonCaseDeviceServerInitParams(const CommonCaseDeviceServerInitParams &)             = delete;
     272              :     CommonCaseDeviceServerInitParams & operator=(const CommonCaseDeviceServerInitParams &) = delete;
     273              : 
     274              :     /**
     275              :      * Call this before Server::Init() to initialize the internally-owned resources.
     276              :      * Server::Init() will fail if this is not done, since several params required to
     277              :      * be non-null will be null without calling this method. ** See the transition method
     278              :      * in the outer comment of this class **.
     279              :      *
     280              :      * @return CHIP_NO_ERROR on success or a CHIP_ERROR value from APIs called to initialize
     281              :      *         resources on failure.
     282              :      */
     283            1 :     CHIP_ERROR InitializeStaticResourcesBeforeServerInit()
     284              :     {
     285              :         // KVS-based persistent storage delegate injection
     286            1 :         if (persistentStorageDelegate == nullptr)
     287              :         {
     288              :             chip::DeviceLayer::PersistedStorage::KeyValueStoreManager & kvsManager =
     289            1 :                 DeviceLayer::PersistedStorage::KeyValueStoreMgr();
     290            1 :             ReturnErrorOnFailure(mKvsPersistentStorageDelegate.Init(&kvsManager));
     291            1 :             this->persistentStorageDelegate = &mKvsPersistentStorageDelegate;
     292              :         }
     293              : 
     294              :         // PersistentStorageDelegate "software-based" operational key access injection
     295            1 :         if (this->operationalKeystore == nullptr)
     296              :         {
     297              :             // WARNING: PersistentStorageOperationalKeystore::Finish() is never called. It's fine for
     298              :             //          for examples and for now.
     299            1 :             ReturnErrorOnFailure(mPersistentStorageOperationalKeystore.Init(this->persistentStorageDelegate));
     300            1 :             this->operationalKeystore = &mPersistentStorageOperationalKeystore;
     301              :         }
     302              : 
     303              :         // OpCertStore can be injected but default to persistent storage default
     304              :         // for simplicity of the examples.
     305            1 :         if (this->opCertStore == nullptr)
     306              :         {
     307              :             // WARNING: PersistentStorageOpCertStore::Finish() is never called. It's fine for
     308              :             //          for examples and for now, since all storage is immediate for that impl.
     309            1 :             ReturnErrorOnFailure(mPersistentStorageOpCertStore.Init(this->persistentStorageDelegate));
     310            1 :             this->opCertStore = &mPersistentStorageOpCertStore;
     311              :         }
     312              : 
     313              :         // Injection of report scheduler WILL lead to two schedulers being allocated. As recommended above, this should only be used
     314              :         // for IN-TREE examples. If a default scheduler is desired, the basic ServerInitParams should be used by the application and
     315              :         // CommonCaseDeviceServerInitParams should not be allocated.
     316            1 :         if (this->reportScheduler == nullptr)
     317              :         {
     318            0 :             this->reportScheduler = &mReportScheduler;
     319              :         }
     320              : 
     321              :         // Session Keystore injection
     322            1 :         if (this->sessionKeystore == nullptr)
     323              :         {
     324            1 :             this->sessionKeystore = &mSessionKeystore;
     325              :         }
     326              : 
     327              :         // Group Data provider injection
     328            1 :         if (this->groupDataProvider == nullptr)
     329              :         {
     330            1 :             mGroupDataProvider.SetStorageDelegate(this->persistentStorageDelegate);
     331            1 :             mGroupDataProvider.SetSessionKeystore(this->sessionKeystore);
     332            1 :             ReturnErrorOnFailure(mGroupDataProvider.Init());
     333            1 :             this->groupDataProvider = &mGroupDataProvider;
     334              :         }
     335              : 
     336              : #if CHIP_CONFIG_ENABLE_SESSION_RESUMPTION
     337            1 :         if (this->sessionResumptionStorage == nullptr)
     338              :         {
     339            1 :             ChipLogProgress(AppServer, "Initializing session resumption storage...");
     340            1 :             ReturnErrorOnFailure(mSessionResumptionStorage.Init(this->persistentStorageDelegate));
     341            1 :             this->sessionResumptionStorage = &mSessionResumptionStorage;
     342              :         }
     343              : #endif
     344              : 
     345              :         // Inject access control delegate
     346            1 :         if (this->accessDelegate == nullptr)
     347              :         {
     348            1 :             this->accessDelegate = Access::Examples::GetAccessControlDelegate();
     349              :         }
     350              : 
     351            1 :         if (this->aclStorage == nullptr)
     352              :         {
     353              :             // Inject ACL storage. (Don't initialize it.)
     354            1 :             this->aclStorage = &mAclStorage;
     355              :         }
     356              : 
     357              : #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
     358            1 :         if (this->subscriptionResumptionStorage == nullptr)
     359              :         {
     360            1 :             ChipLogProgress(AppServer, "Initializing subscription resumption storage...");
     361            1 :             ReturnErrorOnFailure(mSubscriptionResumptionStorage.Init(this->persistentStorageDelegate));
     362            1 :             this->subscriptionResumptionStorage = &mSubscriptionResumptionStorage;
     363              :         }
     364              : #endif
     365              : 
     366              : #if CHIP_CONFIG_ENABLE_ICD_CIP
     367              :         if (this->icdCheckInBackOffStrategy == nullptr)
     368              :         {
     369              :             this->icdCheckInBackOffStrategy = &mICDCheckInBackOffStrategy;
     370              :         }
     371              : #endif
     372              : 
     373              : #if CHIP_CONFIG_ENABLE_GROUPCAST
     374              :         if (this->groupAuxiliaryAccessControlDelegate == nullptr)
     375              :         {
     376              :             // The delegate is left uninitialized here on purpose: Server::Init will call
     377              :             // Initialize on it with the Server-owned FabricTable, which is not reachable
     378              :             // from this scope.
     379              :             this->groupAuxiliaryAccessControlDelegate = &mGroupAuxiliaryAccessControlDelegate;
     380              :         }
     381              : #endif // CHIP_CONFIG_ENABLE_GROUPCAST
     382              : 
     383            1 :         return CHIP_NO_ERROR;
     384              :     }
     385              : 
     386              : private:
     387              :     // Owned resources - these are instance members (not static) so each
     388              :     // CommonCaseDeviceServerInitParams instance owns its own copy.
     389              :     // They must outlive Server::Init() because that method stores pointers to them.
     390              :     KvsPersistentStorageDelegate mKvsPersistentStorageDelegate;
     391              :     PersistentStorageOperationalKeystore mPersistentStorageOperationalKeystore;
     392              :     Credentials::PersistentStorageOpCertStore mPersistentStorageOpCertStore;
     393              :     Credentials::GroupDataProviderImpl mGroupDataProvider;
     394              :     app::DefaultTimerDelegate mTimerDelegate;
     395              :     app::reporting::ReportSchedulerImpl mReportScheduler{ &mTimerDelegate };
     396              : 
     397              : #if CHIP_CONFIG_ENABLE_SESSION_RESUMPTION
     398              :     SimpleSessionResumptionStorage mSessionResumptionStorage;
     399              : #endif
     400              : 
     401              : #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
     402              :     app::SimpleSubscriptionResumptionStorage mSubscriptionResumptionStorage;
     403              : #endif
     404              : 
     405              :     app::DefaultAclStorage mAclStorage;
     406              :     Crypto::DefaultSessionKeystore mSessionKeystore;
     407              : 
     408              : #if CHIP_CONFIG_ENABLE_ICD_CIP
     409              :     app::DefaultICDCheckInBackOffStrategy mICDCheckInBackOffStrategy;
     410              : #endif
     411              : 
     412              : #if CHIP_CONFIG_ENABLE_GROUPCAST
     413              :     // Default delegate used when the application does not provide its own. Concrete Impl,
     414              :     // exposed through the abstract base via groupAuxiliaryAccessControlDelegate above.
     415              :     Access::Examples::GroupAuxiliaryAccessControlDelegateImpl mGroupAuxiliaryAccessControlDelegate;
     416              : #endif
     417              : };
     418              : 
     419              : /**
     420              :  * The `Server` singleton class is an aggregate for all the resources needed to run a
     421              :  * Node that is both Commissionable and mainly used as an end-node with server clusters.
     422              :  * In other words, it aggregates the state needed for the type of Node used for most
     423              :  * products that are not mainly controller/administrator role.
     424              :  *
     425              :  * This sington class expects `ServerInitParams` initialization parameters but does not
     426              :  * own the resources injected from `ServerInitParams`. Any object pointers/references
     427              :  * passed in ServerInitParams must be pre-initialized externally, and shutdown/finalized
     428              :  * after `Server::Shutdown()` is called.
     429              :  *
     430              :  * TODO: Separate lifecycle ownership for some more capabilities that should not belong to
     431              :  *       common logic, such as `GenerateShutDownEvent`.
     432              :  *
     433              :  * TODO: Replace all uses of GetInstance() to "reach in" to this state from all cluster
     434              :  *       server common logic that deal with global node state with either a common NodeState
     435              :  *       compatible with OperationalDeviceProxy/DeviceProxy, or with injection at common
     436              :  *       SDK logic init.
     437              :  */
     438              : class Server
     439              : {
     440              : public:
     441              :     CHIP_ERROR Init(const ServerInitParams & initParams);
     442              : 
     443              : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
     444              :     CHIP_ERROR
     445              :     SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress commissioner,
     446              :                                          Protocols::UserDirectedCommissioning::IdentificationDeclaration & id);
     447              : 
     448              :     Protocols::UserDirectedCommissioning::UserDirectedCommissioningClient * GetUserDirectedCommissioningClient()
     449              :     {
     450              :         return gUDCClient;
     451              :     }
     452              : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
     453              : 
     454              :     /**
     455              :      * @brief Call this function to rejoin existing groups found in the GroupDataProvider
     456              :      */
     457              :     void RejoinExistingMulticastGroups();
     458              : 
     459         1265 :     FabricTable & GetFabricTable() { return mFabrics; }
     460              : 
     461              :     Access::AccessControl & GetAccessControl() { return mAccessControl; }
     462              : 
     463         1239 :     CASESessionManager * GetCASESessionManager() { return &mCASESessionManager; }
     464              : 
     465           26 :     Messaging::ExchangeManager & GetExchangeManager() { return mExchangeMgr; }
     466              : 
     467           12 :     SessionManager & GetSecureSessionManager() { return mSessions; }
     468              : 
     469            0 :     SessionResumptionStorage * GetSessionResumptionStorage() { return mSessionResumptionStorage; }
     470              : 
     471            0 :     app::SubscriptionResumptionStorage * GetSubscriptionResumptionStorage() { return mSubscriptionResumptionStorage; }
     472              : 
     473            0 :     TransportMgrBase & GetTransportManager() { return mTransports; }
     474              : 
     475            2 :     Credentials::GroupDataProvider * GetGroupDataProvider() { return mGroupsProvider; }
     476              : 
     477              :     Crypto::SessionKeystore * GetSessionKeystore() const { return mSessionKeystore; }
     478              : 
     479              : #if CONFIG_NETWORK_LAYER_BLE
     480           10 :     Ble::BleLayer * GetBleLayerObject() { return mBleLayer; }
     481              : #endif
     482              : 
     483           27 :     CommissioningWindowManager & GetCommissioningWindowManager() { return mCommissioningWindowManager; }
     484              : 
     485            1 :     PersistentStorageDelegate & GetPersistentStorage() { return *mDeviceStorage; }
     486              : 
     487           33 :     app::FailSafeContext & GetFailSafeContext() { return mFailSafeContext; }
     488              : 
     489              :     TestEventTriggerDelegate * GetTestEventTriggerDelegate() { return mTestEventTriggerDelegate; }
     490              : 
     491              :     Crypto::OperationalKeystore * GetOperationalKeystore() { return mOperationalKeystore; }
     492              : 
     493              :     Credentials::OperationalCertificateStore * GetOpCertStore() { return mOpCertStore; }
     494              : 
     495              :     app::DefaultSafeAttributePersistenceProvider & GetDefaultAttributePersister() { return mAttributePersister; }
     496              : 
     497              :     app::reporting::ReportScheduler * GetReportScheduler() { return mReportScheduler; }
     498              : 
     499              : #if CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
     500              :     app::JointFabricDatastore & GetJointFabricDatastore() { return mJointFabricDatastore; }
     501            7 :     app::JointFabricAdministrator & GetJointFabricAdministrator() { return mJointFabricAdministrator; }
     502              : #endif // CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
     503              : 
     504              : #if CHIP_CONFIG_ENABLE_ICD_SERVER
     505              :     app::ICDManager & GetICDManager() { return mICDManager; }
     506              : 
     507              : #if CHIP_CONFIG_ENABLE_ICD_CIP
     508              :     /**
     509              :      * @brief Function to determine if a Check-In message would be sent at Boot up
     510              :      *
     511              :      * @param aFabricIndex client fabric index
     512              :      * @param subjectID client subject ID
     513              :      * @return true Check-In message would be sent on boot up.
     514              :      * @return false Device has a persisted subscription with the client. See CHIP_CONFIG_PERSIST_SUBSCRIPTIONS.
     515              :      */
     516              :     bool ShouldCheckInMsgsBeSentAtBootFunction(FabricIndex aFabricIndex, NodeId subjectID);
     517              : #endif // CHIP_CONFIG_ENABLE_ICD_CIP
     518              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
     519              : 
     520              :     /**
     521              :      * This function causes the ShutDown event to be generated async on the
     522              :      * Matter event loop.  Should be called before stopping the event loop.
     523              :      */
     524              :     void GenerateShutDownEvent();
     525              : 
     526              :     void Shutdown();
     527              : 
     528              :     void ScheduleFactoryReset();
     529              : 
     530              :     System::Clock::Microseconds64 TimeSinceInit() const
     531              :     {
     532              :         return System::SystemClock().GetMonotonicMicroseconds64() - mInitTimestamp;
     533              :     }
     534              : 
     535         2575 :     static Server & GetInstance() { return sServer; }
     536              : 
     537              : private:
     538          142 :     Server() {}
     539              : 
     540              :     static Server sServer;
     541              : 
     542              :     void InitFailSafe();
     543              :     void OnPlatformEvent(const DeviceLayer::ChipDeviceEvent & event);
     544              :     void CheckServerReadyEvent();
     545              : 
     546              :     void PostFactoryResetEvent();
     547              : 
     548              :     static void OnPlatformEventWrapper(const DeviceLayer::ChipDeviceEvent * event, intptr_t);
     549              : 
     550              : #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
     551              :     /**
     552              :      * @brief Called at Server::Init time to resume persisted subscriptions if the feature flag is enabled
     553              :      */
     554              :     void ResumeSubscriptions();
     555              : #endif
     556              : 
     557              :     class GroupDataProviderListener final : public Credentials::GroupDataProvider::GroupListener
     558              :     {
     559              :     public:
     560          142 :         GroupDataProviderListener() {}
     561              : 
     562            1 :         CHIP_ERROR Init(Server * server)
     563              :         {
     564            1 :             VerifyOrReturnError(server != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     565              : 
     566            1 :             mServer = server;
     567            1 :             return CHIP_NO_ERROR;
     568              :         };
     569              : 
     570            0 :         void OnGroupAdded(chip::FabricIndex fabric_index, const Credentials::GroupDataProvider::GroupInfo & new_group) override
     571              :         {
     572            0 :             const FabricInfo * fabric = mServer->GetFabricTable().FindFabricWithIndex(fabric_index);
     573            0 :             if (fabric == nullptr)
     574              :             {
     575            0 :                 ChipLogError(AppServer, "Group added to nonexistent fabric?");
     576            0 :                 return;
     577              :             }
     578              : 
     579            0 :             const Transport::PeerAddress & address = new_group.UsePerGroupAddress()
     580            0 :                 ? Transport::PeerAddress::BuildMatterPerGroupMulticastAddress(fabric->GetFabricId(), new_group.group_id)
     581            0 :                 : Transport::PeerAddress::BuildMatterIanaMulticastAddress();
     582              : 
     583            0 :             if (CHIP_NO_ERROR != mServer->GetTransportManager().MulticastGroupJoinLeave(address, true))
     584              :             {
     585            0 :                 ChipLogError(AppServer, "Unable to listen to group");
     586              :             }
     587              :         };
     588              : 
     589            0 :         void OnGroupRemoved(chip::FabricIndex fabric_index, const Credentials::GroupDataProvider::GroupInfo & old_group) override
     590              :         {
     591            0 :             if (old_group.UsePerGroupAddress())
     592              :             {
     593              :                 // Per group address no longer in use, unsubscribe
     594            0 :                 const FabricInfo * fabric = mServer->GetFabricTable().FindFabricWithIndex(fabric_index);
     595            0 :                 if (fabric == nullptr)
     596              :                 {
     597            0 :                     ChipLogError(AppServer, "Group removed from nonexistent fabric?");
     598            0 :                     return;
     599              :                 }
     600              :                 const Transport::PeerAddress & address =
     601            0 :                     Transport::PeerAddress::BuildMatterPerGroupMulticastAddress(fabric->GetFabricId(), old_group.group_id);
     602            0 :                 VerifyOrReturn(CHIP_NO_ERROR == mServer->GetTransportManager().MulticastGroupJoinLeave(address, false));
     603              :             }
     604              :             else
     605              :             {
     606              :                 // Check if the address is still in use
     607            0 :                 Credentials::GroupDataProvider * provider = mServer->GetGroupDataProvider();
     608            0 :                 bool in_use                               = false;
     609            0 :                 if (nullptr != provider)
     610              :                 {
     611              :                     // Check all groups from all fabrics
     612            0 :                     Credentials::GroupDataProvider::GroupInfo group;
     613            0 :                     for (const FabricInfo & fabric : mServer->GetFabricTable())
     614              :                     {
     615            0 :                         chip::AutoRelease iter(provider->IterateGroupInfo(fabric.GetFabricIndex()));
     616            0 :                         while (!iter.IsNull() && iter->Next(group) && !in_use)
     617              :                         {
     618            0 :                             in_use = !group.UsePerGroupAddress();
     619              :                         }
     620            0 :                         if (in_use)
     621            0 :                             break;
     622            0 :                     }
     623              :                 }
     624            0 :                 if (!in_use)
     625              :                 {
     626              :                     // Groupcast address no longer in use, unsubscribe
     627            0 :                     const Transport::PeerAddress & address = Transport::PeerAddress::BuildMatterIanaMulticastAddress();
     628            0 :                     VerifyOrReturn(CHIP_NO_ERROR == mServer->GetTransportManager().MulticastGroupJoinLeave(address, false));
     629              :                 }
     630              :             }
     631              :         };
     632              : 
     633              :     private:
     634              :         Server * mServer;
     635              :     };
     636              : 
     637              :     class ServerFabricDelegate final : public chip::FabricTable::Delegate
     638              :     {
     639              :     public:
     640          142 :         ServerFabricDelegate() {}
     641              : 
     642            1 :         CHIP_ERROR Init(Server * server)
     643              :         {
     644            1 :             VerifyOrReturnError(server != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     645              : 
     646            1 :             mServer = server;
     647            1 :             return CHIP_NO_ERROR;
     648              :         }
     649              : 
     650            0 :         void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) override
     651              :         {
     652              :             (void) fabricTable;
     653            0 :             ClearCASEResumptionStateOnFabricChange(fabricIndex);
     654            0 :             ClearSubscriptionResumptionStateOnFabricChange(fabricIndex);
     655              : 
     656            0 :             Credentials::GroupDataProvider * groupDataProvider = mServer->GetGroupDataProvider();
     657            0 :             if (groupDataProvider != nullptr)
     658              :             {
     659            0 :                 CHIP_ERROR err = groupDataProvider->RemoveFabric(fabricIndex);
     660            0 :                 if (err != CHIP_NO_ERROR)
     661              :                 {
     662            0 :                     ChipLogError(AppServer,
     663              :                                  "Warning, failed to delete GroupDataProvider state for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
     664              :                                  static_cast<unsigned>(fabricIndex), err.Format());
     665              :                 }
     666              :             }
     667              : 
     668              :             // Remove access control entries in reverse order (it could be any order, but reverse order
     669              :             // will cause less churn in persistent storage).
     670            0 :             CHIP_ERROR aclErr = Access::GetAccessControl().DeleteAllEntriesForFabric(fabricIndex);
     671            0 :             if (aclErr != CHIP_NO_ERROR)
     672              :             {
     673            0 :                 ChipLogError(AppServer, "Warning, failed to delete access control state for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
     674              :                              static_cast<unsigned>(fabricIndex), aclErr.Format());
     675              :             }
     676              : 
     677              :             //  Remove ACL extension entry for the given fabricIndex.
     678            0 :             auto & storage = mServer->GetPersistentStorage();
     679            0 :             aclErr = storage.SyncDeleteKeyValue(DefaultStorageKeyAllocator::AccessControlExtensionEntry(fabricIndex).KeyName());
     680              : 
     681            0 :             if (aclErr != CHIP_NO_ERROR && aclErr != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
     682              :             {
     683            0 :                 ChipLogError(AppServer, "Warning, failed to delete ACL extension entry for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
     684              :                              static_cast<unsigned>(fabricIndex), aclErr.Format());
     685              :             }
     686              : 
     687            0 :             mServer->GetCommissioningWindowManager().OnFabricRemoved(fabricIndex);
     688            0 :         }
     689              : 
     690            0 :         void OnFabricUpdated(const FabricTable & fabricTable, chip::FabricIndex fabricIndex) override
     691              :         {
     692              :             (void) fabricTable;
     693            0 :             ClearCASEResumptionStateOnFabricChange(fabricIndex);
     694            0 :         }
     695              : 
     696              :     private:
     697            0 :         void ClearCASEResumptionStateOnFabricChange(chip::FabricIndex fabricIndex)
     698              :         {
     699            0 :             auto * sessionResumptionStorage = mServer->GetSessionResumptionStorage();
     700            0 :             VerifyOrReturn(sessionResumptionStorage != nullptr);
     701            0 :             CHIP_ERROR err = sessionResumptionStorage->DeleteAll(fabricIndex);
     702            0 :             if (err != CHIP_NO_ERROR)
     703              :             {
     704            0 :                 ChipLogError(AppServer,
     705              :                              "Warning, failed to delete session resumption state for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
     706              :                              static_cast<unsigned>(fabricIndex), err.Format());
     707              :             }
     708              :         }
     709              : 
     710            0 :         void ClearSubscriptionResumptionStateOnFabricChange(chip::FabricIndex fabricIndex)
     711              :         {
     712            0 :             auto * subscriptionResumptionStorage = mServer->GetSubscriptionResumptionStorage();
     713            0 :             VerifyOrReturn(subscriptionResumptionStorage != nullptr);
     714            0 :             CHIP_ERROR err = subscriptionResumptionStorage->DeleteAll(fabricIndex);
     715            0 :             if (err != CHIP_NO_ERROR)
     716              :             {
     717            0 :                 ChipLogError(AppServer,
     718              :                              "Warning, failed to delete subscription resumption state for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
     719              :                              static_cast<unsigned>(fabricIndex), err.Format());
     720              :             }
     721              :         }
     722              : 
     723              :         Server * mServer = nullptr;
     724              :     };
     725              : 
     726              :     /**
     727              :      * Since root certificates for Matter nodes cannot be updated in a reasonable
     728              :      * way, it doesn't make sense to enforce expiration time on root certificates.
     729              :      * This policy allows through root certificates, even if they're expired, and
     730              :      * otherwise delegates to the provided policy, or to the default policy if no
     731              :      * policy is provided.
     732              :      */
     733              :     class IgnoreRootExpirationValidityPolicy : public Credentials::CertificateValidityPolicy
     734              :     {
     735              :     public:
     736          142 :         IgnoreRootExpirationValidityPolicy() {}
     737              : 
     738            1 :         void Init(Credentials::CertificateValidityPolicy * providedPolicy) { mProvidedPolicy = providedPolicy; }
     739              : 
     740            0 :         CHIP_ERROR ApplyCertificateValidityPolicy(const Credentials::ChipCertificateData * cert, uint8_t depth,
     741              :                                                   Credentials::CertificateValidityResult result) override
     742              :         {
     743            0 :             switch (result)
     744              :             {
     745            0 :             case Credentials::CertificateValidityResult::kExpired:
     746              :             case Credentials::CertificateValidityResult::kExpiredAtLastKnownGoodTime:
     747              :             case Credentials::CertificateValidityResult::kTimeUnknown: {
     748              :                 Credentials::CertType certType;
     749            0 :                 ReturnErrorOnFailure(cert->mSubjectDN.GetCertType(certType));
     750            0 :                 if (certType == Credentials::CertType::kRoot)
     751              :                 {
     752            0 :                     return CHIP_NO_ERROR;
     753              :                 }
     754              : 
     755            0 :                 break;
     756              :             }
     757            0 :             default:
     758            0 :                 break;
     759              :             }
     760              : 
     761            0 :             if (mProvidedPolicy)
     762              :             {
     763            0 :                 return mProvidedPolicy->ApplyCertificateValidityPolicy(cert, depth, result);
     764              :             }
     765              : 
     766            0 :             return Credentials::CertificateValidityPolicy::ApplyDefaultPolicy(cert, depth, result);
     767              :         }
     768              : 
     769              :     private:
     770              :         Credentials::CertificateValidityPolicy * mProvidedPolicy = nullptr;
     771              :     };
     772              : 
     773              : #if CONFIG_NETWORK_LAYER_BLE
     774              :     Ble::BleLayer * mBleLayer = nullptr;
     775              : #endif
     776              : 
     777              :     // By default, use a certificate validation policy compatible with non-wall-clock-time-synced
     778              :     // embedded systems.
     779              :     static Credentials::IgnoreCertificateValidityPeriodPolicy sDefaultCertValidityPolicy;
     780              : 
     781              :     ServerTransportMgr mTransports;
     782              :     SessionManager mSessions;
     783              :     CASEServer mCASEServer;
     784              : 
     785              :     CASESessionManager mCASESessionManager;
     786              :     CASEClientPool<CHIP_CONFIG_DEVICE_MAX_ACTIVE_CASE_CLIENTS> mCASEClientPool;
     787              :     OperationalSessionSetupPool<CHIP_CONFIG_DEVICE_MAX_ACTIVE_DEVICES> mSessionSetupPool;
     788              : 
     789              :     Protocols::SecureChannel::UnsolicitedStatusHandler mUnsolicitedStatusHandler;
     790              :     Messaging::ExchangeManager mExchangeMgr;
     791              :     FabricTable mFabrics;
     792              :     secure_channel::MessageCounterManager mMessageCounterManager;
     793              : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
     794              :     Protocols::UserDirectedCommissioning::UserDirectedCommissioningClient * gUDCClient = nullptr;
     795              :     // mUdcTransportMgr is for insecure communication (ex. user directed commissioning)
     796              :     // specifically, the commissioner declaration message (sent by commissioner to commissionee)
     797              :     UdcTransportMgr * mUdcTransportMgr = nullptr;
     798              :     uint16_t mCdcListenPort            = CHIP_UDC_COMMISSIONEE_PORT;
     799              : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
     800              :     CommissioningWindowManager mCommissioningWindowManager;
     801              : 
     802              :     IgnoreRootExpirationValidityPolicy mCertificateValidityPolicy;
     803              : 
     804              :     PersistentStorageDelegate * mDeviceStorage;
     805              :     SessionResumptionStorage * mSessionResumptionStorage;
     806              :     app::SubscriptionResumptionStorage * mSubscriptionResumptionStorage;
     807              :     Credentials::GroupDataProvider * mGroupsProvider;
     808              :     Crypto::SessionKeystore * mSessionKeystore;
     809              :     app::DefaultSafeAttributePersistenceProvider mAttributePersister;
     810              :     GroupDataProviderListener mListener;
     811              :     ServerFabricDelegate mFabricDelegate;
     812              :     app::reporting::ReportScheduler * mReportScheduler;
     813              : 
     814              :     Access::AccessControl mAccessControl;
     815              :     app::AclStorage * mAclStorage;
     816              : 
     817              : #if CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
     818              :     app::JointFabricDatastore mJointFabricDatastore;
     819              :     app::JointFabricAdministrator mJointFabricAdministrator;
     820              : #endif // CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
     821              : 
     822              :     TestEventTriggerDelegate * mTestEventTriggerDelegate;
     823              :     Crypto::OperationalKeystore * mOperationalKeystore;
     824              :     Credentials::OperationalCertificateStore * mOpCertStore;
     825              :     app::FailSafeContext mFailSafeContext;
     826              : 
     827              :     bool mIsDnssdReady = false;
     828              :     uint16_t mOperationalServicePort;
     829              :     uint16_t mUserDirectedCommissioningPort;
     830              :     Inet::InterfaceId mInterfaceId;
     831              : 
     832              :     System::Clock::Microseconds64 mInitTimestamp;
     833              : #if CHIP_CONFIG_ENABLE_ICD_SERVER
     834              :     app::ICDManager mICDManager;
     835              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
     836              : };
     837              : 
     838              : } // namespace chip
        

Generated by: LCOV version 2.0-1