Matter SDK Coverage Report
Current view: top level - app/server - Server.cpp (source / functions) Coverage Total Hit
Test: SHA:3f9cd168e84cd831b7699126f5296f5c5498690f Lines: 81.3 % 235 191
Test Date: 2026-04-27 19:52:19 Functions: 71.4 % 14 10

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2021 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              : #include <app/server/Server.h>
      19              : 
      20              : #include <access/ProviderDeviceTypeResolver.h>
      21              : #include <access/examples/ExampleAccessControlDelegate.h>
      22              : 
      23              : #include <app/AppConfig.h>
      24              : #include <app/EventManagement.h>
      25              : #include <app/InteractionModelEngine.h>
      26              : #include <app/SafeAttributePersistenceProvider.h>
      27              : #include <app/data-model-provider/Provider.h>
      28              : #include <app/server/Dnssd.h>
      29              : #include <app/server/EchoHandler.h>
      30              : #include <platform/DefaultTimerDelegate.h>
      31              : 
      32              : #if CONFIG_NETWORK_LAYER_BLE
      33              : #include <ble/Ble.h>
      34              : #endif
      35              : #include <inet/IPAddress.h>
      36              : #include <inet/InetError.h>
      37              : #include <lib/core/CHIPPersistentStorageDelegate.h>
      38              : #include <lib/dnssd/Advertiser.h>
      39              : #include <lib/dnssd/ServiceNaming.h>
      40              : #include <lib/support/CodeUtils.h>
      41              : #include <lib/support/DefaultStorageKeyAllocator.h>
      42              : #include <lib/support/PersistedCounter.h>
      43              : #include <lib/support/TestGroupData.h>
      44              : #include <lib/support/logging/CHIPLogging.h>
      45              : #include <messaging/ExchangeMgr.h>
      46              : #include <platform/CHIPDeviceLayer.h>
      47              : #include <platform/DeviceControlServer.h>
      48              : #include <platform/DeviceInfoProvider.h>
      49              : #include <platform/KeyValueStoreManager.h>
      50              : #include <platform/LockTracker.h>
      51              : #include <protocols/secure_channel/CASEServer.h>
      52              : #include <protocols/secure_channel/MessageCounterManager.h>
      53              : #if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID)
      54              : #include <setup_payload/AdditionalDataPayloadGenerator.h>
      55              : #endif
      56              : #include <setup_payload/SetupPayload.h>
      57              : #include <sys/param.h>
      58              : #include <system/SystemPacketBuffer.h>
      59              : #include <system/TLVPacketBufferBackingStore.h>
      60              : #include <transport/SessionManager.h>
      61              : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
      62              : #include <transport/raw/NFC.h>
      63              : #endif
      64              : 
      65              : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
      66              : #include <transport/raw/WiFiPAF.h>
      67              : #endif
      68              : 
      69              : #if defined(CHIP_SUPPORT_ENABLE_STORAGE_API_AUDIT) || defined(CHIP_SUPPORT_ENABLE_STORAGE_LOAD_TEST_AUDIT)
      70              : #include <lib/support/PersistentStorageAudit.h>
      71              : #endif // defined(CHIP_SUPPORT_ENABLE_STORAGE_API_AUDIT) || defined(CHIP_SUPPORT_ENABLE_STORAGE_LOAD_TEST_AUDIT)
      72              : 
      73              : using namespace chip::DeviceLayer;
      74              : 
      75              : using chip::kMinValidFabricIndex;
      76              : using chip::RendezvousInformationFlag;
      77              : using chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr;
      78              : using chip::Inet::IPAddressType;
      79              : #if CONFIG_NETWORK_LAYER_BLE
      80              : using chip::Transport::BleListenParameters;
      81              : #endif
      82              : using chip::Transport::PeerAddress;
      83              : using chip::Transport::UdpListenParameters;
      84              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
      85              : using chip::Transport::TcpListenParameters;
      86              : #endif
      87              : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
      88              : using chip::Transport::NfcListenParameters;
      89              : #endif
      90              : 
      91              : namespace {
      92              : 
      93            0 : chip::Access::DynamicProviderDeviceTypeResolver sDeviceTypeResolver([] {
      94            0 :     return chip::app::InteractionModelEngine::GetInstance()->GetDataModelProvider();
      95              : });
      96              : 
      97              : } // namespace
      98              : 
      99              : namespace chip {
     100              : 
     101              : #if CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     102              : 
     103              : namespace {
     104              : 
     105              : /**
     106              :  * Helper function to check if an error is an "address already in use" error
     107              :  *
     108              :  * @param err The error to check
     109              :  * @return true if the error indicates the address/port is already in use
     110              :  */
     111              : bool IsAddressInUseError(CHIP_ERROR err)
     112              : {
     113              :     // CHIP_ERROR_POSIX(EADDRINUSE) - Address already in use
     114              :     // The error code 0x02000062 corresponds to this
     115              :     return (err == CHIP_ERROR_POSIX(EADDRINUSE));
     116              : }
     117              : 
     118              : /**
     119              :  * Helper function to safely increment a port number with overflow protection
     120              :  *
     121              :  * @param basePort The base port number
     122              :  * @param increment The amount to increment
     123              :  * @param[out] outPort The resulting port number
     124              :  * @return true if the increment was successful, false if overflow would occur
     125              :  */
     126              : bool SafePortIncrement(uint16_t basePort, uint16_t increment, uint16_t & outPort)
     127              : {
     128              :     // Check for overflow: if basePort + increment > UINT16_MAX
     129              :     if (increment > (UINT16_MAX - basePort))
     130              :     {
     131              :         return false;
     132              :     }
     133              :     outPort = static_cast<uint16_t>(basePort + increment);
     134              :     return true;
     135              : }
     136              : 
     137              : /**
     138              :  * Helper function to initialize a transport with automatic port selection and retry logic
     139              :  *
     140              :  * This function attempts to initialize a transport on a specific port, and if the port is already
     141              :  * in use, it will retry with incrementing port numbers up to the specified retry count.
     142              :  *
     143              :  * @param basePort The initial port to try
     144              :  * @param maxRetries Maximum number of retry attempts
     145              :  * @param componentName Name of the component being initialized (for logging)
     146              :  * @param initFunction Function to call to initialize the transport with a given port
     147              :  *                     Returns CHIP_ERROR indicating success or failure
     148              :  * @param closeFunction Function to call to close/cleanup the transport on retry
     149              :  * @param[out] outBoundPort The actual port that was successfully bound
     150              :  * @return CHIP_ERROR indicating success or failure of the initialization
     151              :  */
     152              : CHIP_ERROR InitTransportWithPortRetry(uint16_t basePort, uint16_t maxRetries, const char * componentName,
     153              :                                       std::function<CHIP_ERROR(uint16_t)> initFunction, std::function<void()> closeFunction,
     154              :                                       uint16_t & outBoundPort)
     155              : {
     156              :     uint16_t portToTry     = basePort;
     157              :     uint16_t attemptNumber = 0;
     158              :     CHIP_ERROR err         = CHIP_NO_ERROR;
     159              : 
     160              :     for (;;)
     161              :     {
     162              :         // Try next sequential port if retrying
     163              :         if (attemptNumber > 0)
     164              :         {
     165              :             if (!SafePortIncrement(basePort, attemptNumber, portToTry))
     166              :             {
     167              :                 ChipLogError(AppServer, "%s: Port increment would overflow (base: %u, increment: %u)", componentName, basePort,
     168              :                              attemptNumber);
     169              :                 return CHIP_ERROR_INVALID_ARGUMENT;
     170              :             }
     171              : 
     172              :             ChipLogProgress(AppServer, "Retrying %s initialization with port %u (attempt %u/%u)", componentName, portToTry,
     173              :                             attemptNumber + 1, maxRetries + 1);
     174              :         }
     175              : 
     176              :         // Attempt to initialize transport with the selected port
     177              :         err = initFunction(portToTry);
     178              : 
     179              :         // Check if initialization succeeded
     180              :         if (err == CHIP_NO_ERROR)
     181              :         {
     182              :             // Success! Update the output port to the actually bound port
     183              :             outBoundPort = portToTry;
     184              :             if (attemptNumber > 0)
     185              :             {
     186              :                 ChipLogProgress(AppServer, "Successfully bound %s to port %u after %u attempt(s)", componentName, outBoundPort,
     187              :                                 attemptNumber + 1);
     188              :             }
     189              :             break;
     190              :         }
     191              : 
     192              :         // Check if we should retry
     193              :         if (IsAddressInUseError(err) && attemptNumber < maxRetries)
     194              :         {
     195              :             closeFunction();
     196              :             ChipLogProgress(AppServer, "%s port %u already in use (error: %" CHIP_ERROR_FORMAT "), will retry with different port",
     197              :                             componentName, portToTry, err.Format());
     198              :             attemptNumber++;
     199              :             continue;
     200              :         }
     201              : 
     202              :         // No retry possible or different error - break out
     203              :         if (IsAddressInUseError(err))
     204              :         {
     205              :             ChipLogError(AppServer,
     206              :                          "Failed to bind %s to port %u: Address already in use. "
     207              :                          "Consider setting portRetryCount > 0 to enable automatic port selection.",
     208              :                          componentName, portToTry);
     209              :         }
     210              :         break;
     211              :     }
     212              : 
     213              :     return err;
     214              : }
     215              : 
     216              : } // anonymous namespace
     217              : #endif // CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     218              : 
     219              : Server Server::sServer;
     220              : 
     221              : #if CHIP_CONFIG_ENABLE_SERVER_IM_EVENT
     222              : #define CHIP_NUM_EVENT_LOGGING_BUFFERS 3
     223              : static uint8_t sInfoEventBuffer[CHIP_DEVICE_CONFIG_EVENT_LOGGING_INFO_BUFFER_SIZE];
     224              : static uint8_t sDebugEventBuffer[CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE];
     225              : static uint8_t sCritEventBuffer[CHIP_DEVICE_CONFIG_EVENT_LOGGING_CRIT_BUFFER_SIZE];
     226              : static PersistedCounter<EventNumber> sGlobalEventIdCounter;
     227              : static app::CircularEventBuffer sLoggingBuffer[CHIP_NUM_EVENT_LOGGING_BUFFERS];
     228              : #endif // CHIP_CONFIG_ENABLE_SERVER_IM_EVENT
     229              : 
     230            1 : CHIP_ERROR Server::Init(const ServerInitParams & initParams)
     231              : {
     232            1 :     ChipLogProgress(AppServer, "Server initializing...");
     233            1 :     assertChipStackLockedByCurrentThread();
     234              : 
     235            1 :     mInitTimestamp = System::SystemClock().GetMonotonicMicroseconds64();
     236              : 
     237            1 :     CASESessionManagerConfig caseSessionManagerConfig;
     238            1 :     DeviceLayer::DeviceInfoProvider * deviceInfoprovider = nullptr;
     239              : 
     240            1 :     mOperationalServicePort        = initParams.operationalServicePort;
     241            1 :     mUserDirectedCommissioningPort = initParams.userDirectedCommissioningPort;
     242            1 :     mInterfaceId                   = initParams.interfaceId;
     243              : 
     244              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
     245            1 :     auto tcpListenParams = TcpListenParameters(DeviceLayer::TCPEndPointManager())
     246            1 :                                .SetAddressType(IPAddressType::kIPv6)
     247            1 :                                .SetListenPort(mOperationalServicePort);
     248              : #endif
     249              : 
     250            1 :     CHIP_ERROR err = CHIP_NO_ERROR;
     251              : 
     252            1 :     VerifyOrExit(initParams.persistentStorageDelegate != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
     253            1 :     VerifyOrExit(initParams.accessDelegate != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
     254            1 :     VerifyOrExit(initParams.aclStorage != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
     255            1 :     VerifyOrExit(initParams.groupDataProvider != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
     256            1 :     VerifyOrExit(initParams.sessionKeystore != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
     257            1 :     VerifyOrExit(initParams.operationalKeystore != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
     258            1 :     VerifyOrExit(initParams.opCertStore != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
     259            1 :     VerifyOrExit(initParams.reportScheduler != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
     260              : 
     261              :     // Extra log since this is an incremental requirement and existing applications may not be aware
     262            1 :     if (initParams.dataModelProvider == nullptr)
     263              :     {
     264            0 :         ChipLogError(AppServer, "Application Server requires a `initParams.dataModelProvider` value.");
     265            0 :         ChipLogError(AppServer, "For backwards compatibility, you likely can use `CodegenDataModelProviderInstance(...)`");
     266              :     }
     267              : 
     268            1 :     VerifyOrExit(initParams.dataModelProvider != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
     269              : 
     270              :     // TODO(16969): Remove Platform::MemoryInit() call from Server class, it belongs to outer code
     271            1 :     TEMPORARY_RETURN_IGNORED Platform::MemoryInit();
     272              : 
     273              :     // Initialize PersistentStorageDelegate-based storage
     274            1 :     mDeviceStorage                 = initParams.persistentStorageDelegate;
     275            1 :     mSessionResumptionStorage      = initParams.sessionResumptionStorage;
     276            1 :     mSubscriptionResumptionStorage = initParams.subscriptionResumptionStorage;
     277            1 :     mOperationalKeystore           = initParams.operationalKeystore;
     278            1 :     mOpCertStore                   = initParams.opCertStore;
     279            1 :     mSessionKeystore               = initParams.sessionKeystore;
     280              : 
     281            1 :     if (initParams.certificateValidityPolicy)
     282              :     {
     283            0 :         mCertificateValidityPolicy.Init(initParams.certificateValidityPolicy);
     284              :     }
     285              :     else
     286              :     {
     287            1 :         mCertificateValidityPolicy.Init(&sDefaultCertValidityPolicy);
     288              :     }
     289              : 
     290              : #if defined(CHIP_SUPPORT_ENABLE_STORAGE_API_AUDIT)
     291              :     VerifyOrDie(audit::ExecutePersistentStorageApiAudit(*mDeviceStorage));
     292              : #endif
     293              : 
     294              : #if defined(CHIP_SUPPORT_ENABLE_STORAGE_LOAD_TEST_AUDIT)
     295              :     VerifyOrDie(audit::ExecutePersistentStorageLoadTestAudit(*mDeviceStorage));
     296              : #endif
     297              : 
     298              :     // Set up attribute persistence before we try to bring up the data model
     299              :     // handler.
     300            1 :     SuccessOrExit(err = mAttributePersister.Init(mDeviceStorage));
     301            1 :     SetSafeAttributePersistenceProvider(&mAttributePersister);
     302              : 
     303              :     {
     304            1 :         FabricTable::InitParams fabricTableInitParams;
     305            1 :         fabricTableInitParams.storage             = mDeviceStorage;
     306            1 :         fabricTableInitParams.operationalKeystore = mOperationalKeystore;
     307            1 :         fabricTableInitParams.opCertStore         = mOpCertStore;
     308              : 
     309            1 :         err = mFabrics.Init(fabricTableInitParams);
     310            1 :         SuccessOrExit(err);
     311              :     }
     312              : 
     313            1 :     SuccessOrExit(err = mAccessControl.Init(initParams.accessDelegate, sDeviceTypeResolver));
     314            1 :     if (initParams.groupAuxiliaryAccessControlDelegate != nullptr)
     315              :     {
     316            0 :         SuccessOrExit(mAccessControl.RegisterGroupAuxiliaryDelegate(initParams.groupAuxiliaryAccessControlDelegate));
     317              :     }
     318            1 :     Access::SetAccessControl(mAccessControl);
     319              : 
     320              : #if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
     321              :     if (initParams.accessRestrictionProvider != nullptr)
     322              :     {
     323              :         mAccessControl.SetAccessRestrictionProvider(initParams.accessRestrictionProvider);
     324              :     }
     325              : #endif
     326              : 
     327            1 :     mAclStorage = initParams.aclStorage;
     328            1 :     SuccessOrExit(err = mAclStorage->Init(*mDeviceStorage, mFabrics.begin(), mFabrics.end()));
     329              : 
     330            1 :     mGroupsProvider = initParams.groupDataProvider;
     331            1 :     SetGroupDataProvider(mGroupsProvider);
     332              : 
     333            1 :     mReportScheduler = initParams.reportScheduler;
     334              : 
     335            1 :     mTestEventTriggerDelegate = initParams.testEventTriggerDelegate;
     336            1 :     if (mTestEventTriggerDelegate == nullptr)
     337              :     {
     338            0 :         ChipLogProgress(AppServer, "WARNING: mTestEventTriggerDelegate is null");
     339              :     }
     340              : 
     341            1 :     deviceInfoprovider = DeviceLayer::GetDeviceInfoProvider();
     342            1 :     if (deviceInfoprovider)
     343              :     {
     344            0 :         deviceInfoprovider->SetStorageDelegate(mDeviceStorage);
     345              :     }
     346              : 
     347              :     // Init transport before operations with secure session mgr.
     348              :     //
     349              :     // The logic below expects that the IPv6 transport is at index 0. Keep that logic in sync with
     350              :     // this code.
     351              :     //
     352              : #if CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     353              :     // Use helper function for automatic port selection with retry logic and overflow protection
     354              :     err = InitTransportWithPortRetry(
     355              :         mOperationalServicePort, initParams.portRetryCount, "transport",
     356              :         [&](uint16_t port) -> CHIP_ERROR {
     357              :     // Update TCP listen params if enabled
     358              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
     359              :             tcpListenParams.SetListenPort(port);
     360              : #endif
     361              : 
     362              :             // Attempt to initialize transports with the selected port
     363              :             return mTransports.Init(
     364              :                 UdpListenParameters(DeviceLayer::UDPEndPointManager())
     365              :                     .SetAddressType(IPAddressType::kIPv6)
     366              :                     .SetListenPort(port)
     367              :                     .SetNativeParams(initParams.endpointNativeParams)
     368              : #if INET_CONFIG_ENABLE_IPV4
     369              :                     ,
     370              :                 // The logic below expects that the IPv4 transport, if enabled, is at
     371              :                 // index 1. Keep that logic in sync with this code.
     372              :                 UdpListenParameters(DeviceLayer::UDPEndPointManager()).SetAddressType(IPAddressType::kIPv4).SetListenPort(port)
     373              : #endif
     374              : #if CONFIG_NETWORK_LAYER_BLE
     375              :                     ,
     376              :                 BleListenParameters(DeviceLayer::ConnectivityMgr().GetBleLayer())
     377              : #endif
     378              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
     379              :                     ,
     380              :                 tcpListenParams
     381              : #if INET_CONFIG_ENABLE_IPV4
     382              :                 ,
     383              :                 TcpListenParameters(DeviceLayer::TCPEndPointManager()).SetAddressType(IPAddressType::kIPv4).SetListenPort(port)
     384              : #endif
     385              : #endif
     386              : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
     387              :                     ,
     388              :                 Transport::WiFiPAFListenParameters(
     389              :                     static_cast<Transport::WiFiPAFBase *>(DeviceLayer::ConnectivityMgr().GetWiFiPAF()->mWiFiPAFTransport))
     390              : #endif
     391              : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
     392              :                     ,
     393              :                 NfcListenParameters(nullptr)
     394              : #endif
     395              :             );
     396              :         },
     397              :         [&]() {
     398              :             // Close transports from the failed attempt before retrying
     399              :             // BLE transport now handles re-initialization gracefully as a no-op
     400              :             mTransports.Close();
     401              :         },
     402              :         mOperationalServicePort);
     403              : #else // CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     404              :     // Initialize transports without port retry
     405              : 
     406              :     // Update TCP listen params if enabled
     407              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
     408            1 :     tcpListenParams.SetListenPort(mOperationalServicePort);
     409              : #endif
     410              : 
     411            2 :     err = mTransports.Init(UdpListenParameters(DeviceLayer::UDPEndPointManager())
     412            1 :                                .SetAddressType(IPAddressType::kIPv6)
     413            1 :                                .SetListenPort(mOperationalServicePort)
     414            1 :                                .SetNativeParams(initParams.endpointNativeParams)
     415              : #if INET_CONFIG_ENABLE_IPV4
     416              :                                ,
     417              :                            // The logic below expects that the IPv4 transport, if enabled, is at
     418              :                            // index 1. Keep that logic in sync with this code.
     419            1 :                            UdpListenParameters(DeviceLayer::UDPEndPointManager())
     420            1 :                                .SetAddressType(IPAddressType::kIPv4)
     421            1 :                                .SetListenPort(mOperationalServicePort)
     422              : #endif
     423              : #if CONFIG_NETWORK_LAYER_BLE
     424              :                                ,
     425            1 :                            BleListenParameters(DeviceLayer::ConnectivityMgr().GetBleLayer())
     426              : #endif
     427              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
     428              :                                ,
     429              :                            tcpListenParams
     430              : #if INET_CONFIG_ENABLE_IPV4
     431              :                            ,
     432            1 :                            TcpListenParameters(DeviceLayer::TCPEndPointManager())
     433            1 :                                .SetAddressType(IPAddressType::kIPv4)
     434            1 :                                .SetListenPort(mOperationalServicePort)
     435              : #endif
     436              : #endif
     437              : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
     438              :                                ,
     439            1 :                            Transport::WiFiPAFListenParameters(static_cast<Transport::WiFiPAFBase *>(
     440            1 :                                DeviceLayer::ConnectivityMgr().GetWiFiPAF()->mWiFiPAFTransport))
     441              : #endif
     442              : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
     443              :                                ,
     444              :                            NfcListenParameters(nullptr)
     445              : #endif
     446              :     );
     447              : #endif // CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     448              : 
     449            1 :     SuccessOrExit(err);
     450            1 :     err = mListener.Init(this);
     451            1 :     SuccessOrExit(err);
     452            1 :     mGroupsProvider->SetListener(&mListener);
     453              : 
     454              : #if CONFIG_NETWORK_LAYER_BLE
     455            1 :     mBleLayer = DeviceLayer::ConnectivityMgr().GetBleLayer();
     456              : #endif
     457            1 :     SuccessOrExit(err);
     458              : 
     459            1 :     err = mSessions.Init(&DeviceLayer::SystemLayer(), &mTransports, &mMessageCounterManager, mDeviceStorage, &GetFabricTable(),
     460            1 :                          *mSessionKeystore);
     461            1 :     SuccessOrExit(err);
     462              : 
     463            1 :     err = mFabricDelegate.Init(this);
     464            1 :     SuccessOrExit(err);
     465            1 :     TEMPORARY_RETURN_IGNORED mFabrics.AddFabricDelegate(&mFabricDelegate);
     466              : 
     467            1 :     err = mExchangeMgr.Init(&mSessions);
     468            1 :     SuccessOrExit(err);
     469            1 :     err = mMessageCounterManager.Init(&mExchangeMgr);
     470            1 :     SuccessOrExit(err);
     471              : 
     472            1 :     err = mUnsolicitedStatusHandler.Init(&mExchangeMgr);
     473            1 :     SuccessOrExit(err);
     474              : 
     475            1 :     SuccessOrExit(err = mCommissioningWindowManager.Init(this));
     476            1 :     mCommissioningWindowManager.SetAppDelegate(initParams.appDelegate);
     477              : 
     478            1 :     app::DnssdServer::Instance().SetFabricTable(&mFabrics);
     479            1 :     app::DnssdServer::Instance().SetCommissioningModeProvider(&mCommissioningWindowManager);
     480              : 
     481            1 :     TEMPORARY_RETURN_IGNORED Dnssd::Resolver::Instance().Init(DeviceLayer::UDPEndPointManager());
     482              : 
     483              : #if CHIP_CONFIG_ENABLE_SERVER_IM_EVENT
     484              :     // Initialize event logging subsystem
     485            1 :     err = sGlobalEventIdCounter.Init(mDeviceStorage, DefaultStorageKeyAllocator::IMEventNumber(),
     486              :                                      CHIP_DEVICE_CONFIG_EVENT_ID_COUNTER_EPOCH);
     487            1 :     SuccessOrExit(err);
     488              : 
     489              :     {
     490            1 :         app::LogStorageResources logStorageResources[] = {
     491              :             { &sDebugEventBuffer[0], sizeof(sDebugEventBuffer), app::PriorityLevel::Debug },
     492              :             { &sInfoEventBuffer[0], sizeof(sInfoEventBuffer), app::PriorityLevel::Info },
     493              :             { &sCritEventBuffer[0], sizeof(sCritEventBuffer), app::PriorityLevel::Critical }
     494              :         };
     495              : 
     496            2 :         err = app::EventManagement::GetInstance().Init(&mExchangeMgr, CHIP_NUM_EVENT_LOGGING_BUFFERS, &sLoggingBuffer[0],
     497              :                                                        &logStorageResources[0], &sGlobalEventIdCounter,
     498            1 :                                                        std::chrono::duration_cast<System::Clock::Milliseconds64>(mInitTimestamp),
     499            1 :                                                        &app::InteractionModelEngine::GetInstance()->GetReportingEngine());
     500              : 
     501            1 :         SuccessOrExit(err);
     502              :     }
     503              : #endif // CHIP_CONFIG_ENABLE_SERVER_IM_EVENT
     504              : 
     505              :     // SetDataModelProvider() initializes and starts the provider, which in turn
     506              :     // triggers the initialization of cluster implementations. This callsite is
     507              :     // critical because it ensures that cluster-level initialization occurs only
     508              :     // after all necessary low-level dependencies have been set up.
     509              :     //
     510              :     // Ordering guarantees:
     511              :     // 1) Provider initialization (under SetDataModelProvider) must happen after
     512              :     //    SetSafeAttributePersistenceProvider to ensure the provider can leverage
     513              :     //    the safe persistence provider for attribute persistence logic.
     514              :     // 2) It must occur after all low-level components that cluster implementations
     515              :     //    might depend on have been initialized, as they rely on these components
     516              :     //    during their own initialization.
     517              :     //
     518              :     // This remains the single point of entry to ensure that all cluster-level
     519              :     // initialization is performed in the correct order.
     520            1 :     app::InteractionModelEngine::GetInstance()->SetDataModelProvider(initParams.dataModelProvider);
     521              : 
     522              : #if defined(CHIP_APP_USE_ECHO)
     523              :     err = InitEchoHandler(&mExchangeMgr);
     524              :     SuccessOrExit(err);
     525              : #endif
     526              : 
     527            1 :     app::DnssdServer::Instance().SetSecuredIPv6Port(mTransports.GetTransport().GetImplAtIndex<0>().GetBoundPort());
     528              : #if INET_CONFIG_ENABLE_IPV4
     529            1 :     app::DnssdServer::Instance().SetSecuredIPv4Port(mTransports.GetTransport().GetImplAtIndex<1>().GetBoundPort());
     530              : #endif // INET_CONFIG_ENABLE_IPV4
     531              : 
     532            1 :     app::DnssdServer::Instance().SetUnsecuredPort(mUserDirectedCommissioningPort);
     533            1 :     app::DnssdServer::Instance().SetInterfaceId(mInterfaceId);
     534              : 
     535              : #if CHIP_CONFIG_ENABLE_ICD_SERVER
     536              :     // We set the ICDManager reference betfore calling the ICDManager init due to the init ordering limitations.
     537              :     // DnssdServer will use the default value initially and will update advertisement once ICDManager
     538              :     // init is called.
     539              :     app::DnssdServer::Instance().SetICDManager(&mICDManager);
     540              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
     541              : 
     542              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
     543              :     // Enable the TCP Server based on the TCPListenParameters setting.
     544            1 :     app::DnssdServer::Instance().SetTCPServerEnabled(tcpListenParams.IsServerListenEnabled());
     545              : #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
     546              : 
     547            1 :     if (GetFabricTable().FabricCount() != 0)
     548              :     {
     549              : #if CONFIG_NETWORK_LAYER_BLE
     550              :         // The device is already commissioned, proactively disable BLE advertisement.
     551            0 :         ChipLogProgress(AppServer, "Fabric already commissioned. Disabling BLE advertisement");
     552            0 :         TEMPORARY_RETURN_IGNORED DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(false);
     553              : #endif
     554              :     }
     555            1 :     else if (initParams.advertiseCommissionableIfNoFabrics)
     556              :     {
     557            1 :         SuccessOrExit(err = mCommissioningWindowManager.OpenBasicCommissioningWindow(initParams.discoveryTimeout));
     558              :     }
     559              : 
     560              :     // TODO @bzbarsky-apple @cecille Move to examples
     561              :     // ESP32 examples have a custom logic for enabling DNS-SD
     562              : #if !CHIP_DEVICE_LAYER_TARGET_ESP32 && (!CHIP_DEVICE_LAYER_TARGET_AMEBA || !CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE)
     563              :     // StartServer only enables commissioning mode if device has not been commissioned
     564            1 :     app::DnssdServer::Instance().StartServer();
     565              : #endif
     566              : 
     567              :     caseSessionManagerConfig = {
     568              :         .sessionInitParams =  {
     569            1 :             .sessionManager    = &mSessions,
     570            1 :             .sessionResumptionStorage = mSessionResumptionStorage,
     571              :             .certificateValidityPolicy = &mCertificateValidityPolicy,
     572            1 :             .exchangeMgr       = &mExchangeMgr,
     573            1 :             .fabricTable       = &mFabrics,
     574            1 :             .groupDataProvider = mGroupsProvider,
     575              :             // Don't provide an MRP local config, so each CASE initiation will use
     576              :             // the then-current value.
     577              :             .mrpLocalConfig = NullOptional,
     578              :         },
     579              :         .clientPool            = &mCASEClientPool,
     580              :         .sessionSetupPool      = &mSessionSetupPool,
     581            1 :     };
     582              : 
     583            1 :     err = mCASESessionManager.Init(&DeviceLayer::SystemLayer(), caseSessionManagerConfig);
     584            1 :     SuccessOrExit(err);
     585              : 
     586            1 :     err = mCASEServer.ListenForSessionEstablishment(&mExchangeMgr, &mSessions, &mFabrics, mSessionResumptionStorage,
     587              :                                                     &mCertificateValidityPolicy, mGroupsProvider);
     588            1 :     SuccessOrExit(err);
     589              : 
     590            1 :     err = app::InteractionModelEngine::GetInstance()->Init(&mExchangeMgr, &GetFabricTable(), mReportScheduler, &mCASESessionManager,
     591              :                                                            mSubscriptionResumptionStorage);
     592            1 :     SuccessOrExit(err);
     593              : 
     594              : #if CHIP_CONFIG_ENABLE_ICD_SERVER
     595              :     app::InteractionModelEngine::GetInstance()->SetICDManager(&mICDManager);
     596              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
     597              : 
     598              :     // ICD Init needs to be after data model init and InteractionModel Init
     599              : #if CHIP_CONFIG_ENABLE_ICD_SERVER
     600              : 
     601              :     // Register the ICDStateObservers.
     602              :     // Call register before init so that observers are notified of any state change during the init.
     603              :     // All observers are released at mICDManager.Shutdown(). They can be released individually with ReleaseObserver
     604              :     mICDManager.RegisterObserver(mReportScheduler);
     605              :     mICDManager.RegisterObserver(&app::DnssdServer::Instance());
     606              : 
     607              : #if CHIP_CONFIG_ENABLE_ICD_CIP
     608              :     mICDManager.SetPersistentStorageDelegate(mDeviceStorage)
     609              :         .SetFabricTable(&GetFabricTable())
     610              :         .SetSymmetricKeyStore(mSessionKeystore)
     611              :         .SetExchangeManager(&mExchangeMgr)
     612              :         .SetSubscriptionsInfoProvider(app::InteractionModelEngine::GetInstance())
     613              :         .SetICDCheckInBackOffStrategy(initParams.icdCheckInBackOffStrategy);
     614              : 
     615              : #endif // CHIP_CONFIG_ENABLE_ICD_CIP
     616              :     mICDManager.Init();
     617              : 
     618              :     // Register Test Event Trigger Handler
     619              :     if (mTestEventTriggerDelegate != nullptr)
     620              :     {
     621              :         TEMPORARY_RETURN_IGNORED mTestEventTriggerDelegate->AddHandler(&mICDManager);
     622              :     }
     623              : 
     624              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
     625              : 
     626              :     // This code is necessary to restart listening to existing groups after a reboot
     627              :     // Each manufacturer needs to validate that they can rejoin groups by placing this code at the appropriate location for them
     628              :     //
     629              :     // Thread LWIP devices using dedicated Inet endpoint implementations are excluded because they call this function from:
     630              :     // src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp
     631              : #if !CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
     632            1 :     RejoinExistingMulticastGroups();
     633              : #endif // !CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
     634              : 
     635              :     // Handle deferred clean-up of a previously armed fail-safe that occurred during FabricTable commit.
     636              :     // This is done at the very end since at the earlier time above when FabricTable::Init() is called,
     637              :     // the delegates could not have been registered, and the other systems were not initialized. By now,
     638              :     // everything is initialized, so we can do a deferred clean-up.
     639              :     {
     640            1 :         FabricIndex fabricIndexDeletedOnInit = GetFabricTable().GetDeletedFabricFromCommitMarker();
     641            1 :         if (fabricIndexDeletedOnInit != kUndefinedFabricIndex)
     642              :         {
     643            0 :             ChipLogError(AppServer, "FabricIndex 0x%x deleted due to restart while fail-safed. Processing a clean-up!",
     644              :                          static_cast<unsigned>(fabricIndexDeletedOnInit));
     645              : 
     646              :             // Always pretend it was an add, since being in the middle of an update currently breaks
     647              :             // the validity of the fabric table. This is expected to be extremely infrequent, so
     648              :             // this "harsher" than usual clean-up is more likely to get us in a valid state for whatever
     649              :             // remains.
     650            0 :             const bool addNocCalled    = true;
     651            0 :             const bool updateNocCalled = false;
     652            0 :             GetFailSafeContext().ScheduleFailSafeCleanup(fabricIndexDeletedOnInit, addNocCalled, updateNocCalled);
     653              : 
     654              :             // Schedule clearing of the commit marker to only occur after we have processed all fail-safe clean-up.
     655              :             // Because Matter runs a single event loop for all scheduled work, it will occur after the above has
     656              :             // taken place. If a reset occurs before we have cleaned everything up, the next boot will still
     657              :             // see the commit marker.
     658            0 :             TEMPORARY_RETURN_IGNORED PlatformMgr().ScheduleWork(
     659            0 :                 [](intptr_t arg) {
     660            0 :                     Server * server = reinterpret_cast<Server *>(arg);
     661            0 :                     VerifyOrReturn(server != nullptr);
     662              : 
     663            0 :                     server->GetFabricTable().ClearCommitMarker();
     664            0 :                     ChipLogProgress(AppServer, "Cleared FabricTable pending commit marker");
     665              :                 },
     666              :                 reinterpret_cast<intptr_t>(this));
     667              :         }
     668              :     }
     669              : 
     670              : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT // support UDC port for commissioner declaration msgs
     671              : #if CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     672              :     // Use helper function for UDC transport initialization with automatic port selection and overflow protection
     673              :     mUdcTransportMgr = Platform::New<UdcTransportMgr>();
     674              :     err              = InitTransportWithPortRetry(
     675              :         mCdcListenPort, initParams.portRetryCount, "UDC transport",
     676              :         [&](uint16_t port) -> CHIP_ERROR {
     677              :             // Attempt to initialize UDC transport with the selected port
     678              :             return mUdcTransportMgr->Init(Transport::UdpListenParameters(DeviceLayer::UDPEndPointManager())
     679              :                                                            .SetAddressType(Inet::IPAddressType::kIPv6)
     680              :                                                            .SetListenPort(port)
     681              :                                                            .SetNativeParams(initParams.endpointNativeParams)
     682              : #if INET_CONFIG_ENABLE_IPV4
     683              :                                               ,
     684              :                                           Transport::UdpListenParameters(DeviceLayer::UDPEndPointManager())
     685              :                                               .SetAddressType(Inet::IPAddressType::kIPv4)
     686              :                                               .SetListenPort(port)
     687              : #endif // INET_CONFIG_ENABLE_IPV4
     688              :             );
     689              :         },
     690              :         [&]() { mUdcTransportMgr->Close(); }, mCdcListenPort);
     691              : #else // CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     692              :     // Initialize UDC transport without port retry
     693              :     mUdcTransportMgr = Platform::New<UdcTransportMgr>();
     694              :     err              = mUdcTransportMgr->Init(Transport::UdpListenParameters(DeviceLayer::UDPEndPointManager())
     695              :                                                   .SetAddressType(Inet::IPAddressType::kIPv6)
     696              :                                                   .SetListenPort(mCdcListenPort)
     697              :                                                   .SetNativeParams(initParams.endpointNativeParams)
     698              : #if INET_CONFIG_ENABLE_IPV4
     699              :                                                   ,
     700              :                                               Transport::UdpListenParameters(DeviceLayer::UDPEndPointManager())
     701              :                                                   .SetAddressType(Inet::IPAddressType::kIPv4)
     702              :                                                   .SetListenPort(mCdcListenPort)
     703              : #endif // INET_CONFIG_ENABLE_IPV4
     704              :                  );
     705              : #endif // CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     706              :     SuccessOrExit(err);
     707              : 
     708              :     gUDCClient = Platform::New<Protocols::UserDirectedCommissioning::UserDirectedCommissioningClient>();
     709              :     mUdcTransportMgr->SetSessionManager(gUDCClient);
     710              : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
     711              : 
     712            1 :     TEMPORARY_RETURN_IGNORED PlatformMgr().AddEventHandler(OnPlatformEventWrapper, reinterpret_cast<intptr_t>(this));
     713            1 :     PlatformMgr().HandleServerStarted();
     714              : 
     715            1 :     mIsDnssdReady = Dnssd::Resolver::Instance().IsInitialized();
     716            1 :     CheckServerReadyEvent();
     717              : 
     718            1 : exit:
     719            2 :     if (err != CHIP_NO_ERROR)
     720              :     {
     721            0 :         ChipLogError(AppServer, "ERROR setting up transport: %" CHIP_ERROR_FORMAT, err.Format());
     722              :     }
     723              :     else
     724              :     {
     725              :         // NOTE: this log is scraped by the test harness.
     726            1 :         ChipLogProgress(AppServer, "Server Listening...");
     727              :     }
     728            1 :     return err;
     729              : }
     730              : 
     731            8 : void Server::OnPlatformEvent(const DeviceLayer::ChipDeviceEvent & event)
     732              : {
     733            8 :     switch (event.Type)
     734              :     {
     735            1 :     case DeviceEventType::kDnssdInitialized:
     736              :         // Platform DNS-SD implementation uses kPlatformDnssdInitialized event to signal that it's ready.
     737            1 :         if (!mIsDnssdReady)
     738              :         {
     739            0 :             mIsDnssdReady = true;
     740            0 :             CheckServerReadyEvent();
     741              :         }
     742            1 :         break;
     743            1 :     case DeviceEventType::kServerReady:
     744              : #if CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP
     745              :         // Only Trigger Check-In messages if we are not in the middle of a commissioning.
     746              :         // This check is only necessary for the first commissioiner since the kServerReady event
     747              :         // is triggered once we join the network.
     748              :         // We trigger Check-In messages before resuming subscriptions to avoid doing both.
     749              :         if (!mFailSafeContext.IsFailSafeArmed())
     750              :         {
     751              :             std::function<app::ICDManager::ShouldCheckInMsgsBeSentFunction> sendCheckInMessagesOnBootUp =
     752              :                 std::bind(&Server::ShouldCheckInMsgsBeSentAtBootFunction, this, std::placeholders::_1, std::placeholders::_2);
     753              :             mICDManager.TriggerCheckInMessages(sendCheckInMessagesOnBootUp);
     754              :         }
     755              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP
     756              : #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
     757            1 :         ResumeSubscriptions();
     758              : #endif // CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
     759            1 :         break;
     760              : #if CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
     761              :     case DeviceEventType::kThreadConnectivityChange:
     762              :         if (event.ThreadConnectivityChange.Result == kConnectivity_Established)
     763              :         {
     764              :             // Refresh Multicast listening
     765              :             ChipLogDetail(DeviceLayer, "Thread Attached updating Multicast address");
     766              :             RejoinExistingMulticastGroups();
     767              :         }
     768              :         break;
     769              : #endif // CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
     770            6 :     default:
     771            6 :         break;
     772              :     }
     773            8 : }
     774              : 
     775            1 : void Server::CheckServerReadyEvent()
     776              : {
     777              :     // Check if all asynchronously initialized server components (currently, only DNS-SD)
     778              :     // are ready, and emit the 'server ready' event if so.
     779            1 :     if (mIsDnssdReady)
     780              :     {
     781            1 :         ChipLogProgress(AppServer, "Server initialization complete");
     782              : 
     783            1 :         ChipDeviceEvent event = { .Type = DeviceEventType::kServerReady };
     784            1 :         PlatformMgr().PostEventOrDie(&event);
     785              :     }
     786            1 : }
     787              : 
     788            8 : void Server::OnPlatformEventWrapper(const DeviceLayer::ChipDeviceEvent * event, intptr_t server)
     789              : {
     790            8 :     reinterpret_cast<Server *>(server)->OnPlatformEvent(*event);
     791            8 : }
     792              : 
     793            1 : void Server::RejoinExistingMulticastGroups()
     794              : {
     795            1 :     ChipLogProgress(AppServer, "Joining Multicast groups");
     796            1 :     CHIP_ERROR err = CHIP_NO_ERROR;
     797              : 
     798            1 :     bool groupcast_joined = false;
     799            1 :     for (const FabricInfo & fabric : mFabrics)
     800              :     {
     801            0 :         Credentials::GroupDataProvider::GroupInfo groupInfo;
     802              : 
     803            0 :         auto * iterator = mGroupsProvider->IterateGroupInfo(fabric.GetFabricIndex());
     804            0 :         if (iterator)
     805              :         {
     806              :             // GroupDataProvider was able to allocate rescources for an iterator
     807            0 :             while (iterator->Next(groupInfo))
     808              :             {
     809            0 :                 bool use_iana_addr = !groupInfo.UsePerGroupAddress();
     810            0 :                 if (use_iana_addr && groupcast_joined)
     811              :                 {
     812              :                     // Already joined groupcast address
     813            0 :                     continue;
     814              :                 }
     815              : 
     816              :                 const Transport::PeerAddress & address = use_iana_addr
     817              :                     ? Transport::PeerAddress::Groupcast()
     818            0 :                     : Transport::PeerAddress::Multicast(fabric.GetFabricId(), groupInfo.group_id);
     819              : 
     820            0 :                 err = mTransports.MulticastGroupJoinLeave(address, true);
     821            0 :                 if (err != CHIP_NO_ERROR)
     822              :                 {
     823            0 :                     ChipLogError(AppServer, "Error when trying to join Group %u of fabric index %u : %" CHIP_ERROR_FORMAT,
     824              :                                  groupInfo.group_id, fabric.GetFabricIndex(), err.Format());
     825              : 
     826              :                     // We assume the failure is caused by a network issue or a lack of rescources; neither of which will be solved
     827              :                     // before the next join. Exit the loop to save rescources.
     828            0 :                     iterator->Release();
     829            0 :                     return;
     830              :                 }
     831            0 :                 if (use_iana_addr)
     832            0 :                     groupcast_joined = true;
     833              :             }
     834              : 
     835            0 :             iterator->Release();
     836              :         }
     837              :     }
     838              : }
     839              : 
     840              : #if CHIP_CONFIG_ENABLE_ICD_CIP
     841              : bool Server::ShouldCheckInMsgsBeSentAtBootFunction(FabricIndex aFabricIndex, NodeId subjectID)
     842              : {
     843              : #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
     844              :     // If at least one registration has a persisted entry, do not send Check-In message.
     845              :     // The resumption of the persisted subscription will serve the same function a check-in would have served.
     846              :     return !app::InteractionModelEngine::GetInstance()->SubjectHasPersistedSubscription(aFabricIndex, subjectID);
     847              : #else
     848              :     return true;
     849              : #endif // CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
     850              : }
     851              : #endif // CHIP_CONFIG_ENABLE_ICD_CIP
     852              : 
     853            0 : void Server::GenerateShutDownEvent()
     854              : {
     855            0 :     TEMPORARY_RETURN_IGNORED PlatformMgr().ScheduleWork([](intptr_t) { PlatformMgr().HandleServerShuttingDown(); });
     856            0 : }
     857              : 
     858            1 : void Server::PostFactoryResetEvent()
     859              : {
     860            1 :     DeviceLayer::ChipDeviceEvent event{ .Type = DeviceLayer::DeviceEventType::kFactoryReset };
     861              : 
     862            1 :     CHIP_ERROR error = DeviceLayer::PlatformMgr().PostEvent(&event);
     863            2 :     if (error != CHIP_NO_ERROR)
     864              :     {
     865            0 :         ChipLogError(AppServer, "Posting kFactoryReset event failed with %" CHIP_ERROR_FORMAT, error.Format());
     866              :     }
     867            1 : }
     868              : 
     869            1 : void Server::ScheduleFactoryReset()
     870              : {
     871            1 :     PostFactoryResetEvent();
     872              : 
     873            1 :     TEMPORARY_RETURN_IGNORED PlatformMgr().ScheduleWork([](intptr_t) {
     874              :         // Delete all fabrics and emit Leave event.
     875            1 :         GetInstance().GetFabricTable().DeleteAllFabrics();
     876            1 :         PlatformMgr().HandleServerShuttingDown();
     877            1 :         ConfigurationMgr().InitiateFactoryReset();
     878            1 :     });
     879            1 : }
     880              : 
     881            1 : void Server::Shutdown()
     882              : {
     883            1 :     assertChipStackLockedByCurrentThread();
     884            1 :     PlatformMgr().RemoveEventHandler(OnPlatformEventWrapper, 0);
     885            1 :     mCASEServer.Shutdown();
     886            1 :     mCASESessionManager.Shutdown();
     887              : #if CHIP_CONFIG_ENABLE_ICD_SERVER
     888              :     app::DnssdServer::Instance().SetICDManager(nullptr);
     889              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
     890            1 :     app::DnssdServer::Instance().SetCommissioningModeProvider(nullptr);
     891            1 :     Dnssd::ServiceAdvertiser::Instance().Shutdown();
     892              : 
     893              : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
     894              :     if (mUdcTransportMgr != nullptr)
     895              :     {
     896              :         Platform::Delete(mUdcTransportMgr);
     897              :         mUdcTransportMgr = nullptr;
     898              :     }
     899              :     if (gUDCClient != nullptr)
     900              :     {
     901              :         Platform::Delete(gUDCClient);
     902              :         gUDCClient = nullptr;
     903              :     }
     904              : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
     905              : 
     906            1 :     Dnssd::Resolver::Instance().Shutdown();
     907            1 :     app::InteractionModelEngine::GetInstance()->Shutdown();
     908              : #if CHIP_CONFIG_ENABLE_ICD_SERVER
     909              :     app::InteractionModelEngine::GetInstance()->SetICDManager(nullptr);
     910              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
     911              :     // Shut down any remaining sessions (and hence exchanges) before we do any
     912              :     // futher teardown.  CASE handshakes have been shut down already via
     913              :     // shutting down mCASESessionManager and mCASEServer above; shutting
     914              :     // down mCommissioningWindowManager will shut down any PASE handshakes we
     915              :     // have going on.
     916            1 :     mSessions.ExpireAllSecureSessions();
     917            1 :     mCommissioningWindowManager.Shutdown();
     918            1 :     mMessageCounterManager.Shutdown();
     919            1 :     mExchangeMgr.Shutdown();
     920            1 :     mSessions.Shutdown();
     921            1 :     mTransports.Close();
     922            1 :     mAccessControl.Finish();
     923            1 :     Access::ResetAccessControlToDefault();
     924            1 :     Credentials::SetGroupDataProvider(nullptr);
     925              : #if CHIP_CONFIG_ENABLE_ICD_SERVER
     926              :     // Remove Test Event Trigger Handler
     927              :     if (mTestEventTriggerDelegate != nullptr)
     928              :     {
     929              :         mTestEventTriggerDelegate->RemoveHandler(&mICDManager);
     930              :     }
     931              :     mICDManager.Shutdown();
     932              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
     933              : 
     934              :     // TODO(16969): Remove chip::Platform::MemoryInit() call from Server class, it belongs to outer code
     935            1 :     chip::Platform::MemoryShutdown();
     936            1 : }
     937              : 
     938              : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
     939              : // NOTE: UDC client is located in Server.cpp because it really only makes sense
     940              : // to send UDC from a Matter device. The UDC message payload needs to include the device's
     941              : // randomly generated service name.
     942              : CHIP_ERROR Server::SendUserDirectedCommissioningRequest(Transport::PeerAddress commissioner,
     943              :                                                         Protocols::UserDirectedCommissioning::IdentificationDeclaration & id)
     944              : {
     945              :     ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest()");
     946              : 
     947              :     CHIP_ERROR err;
     948              : 
     949              :     // only populate fields left blank by the client
     950              :     if (strlen(id.GetInstanceName()) == 0)
     951              :     {
     952              :         ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Instance Name not known");
     953              :         char nameBuffer[Dnssd::Commission::kInstanceNameMaxLength + 1];
     954              :         err = app::DnssdServer::Instance().GetCommissionableInstanceName(nameBuffer, sizeof(nameBuffer));
     955              :         if (err != CHIP_NO_ERROR)
     956              :         {
     957              :             ChipLogError(
     958              :                 AppServer,
     959              :                 "Server::SendUserDirectedCommissioningRequest() Failed to get mdns instance name error: %" CHIP_ERROR_FORMAT,
     960              :                 err.Format());
     961              :             return err;
     962              :         }
     963              :         id.SetInstanceName(nameBuffer);
     964              :         ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Instance Name set to %s", nameBuffer);
     965              :     }
     966              : 
     967              :     if (id.GetVendorId() == 0)
     968              :     {
     969              :         uint16_t vendorId = 0;
     970              :         if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(vendorId) != CHIP_NO_ERROR)
     971              :         {
     972              :             ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Vendor ID not known");
     973              :         }
     974              :         else
     975              :         {
     976              :             id.SetVendorId(vendorId);
     977              :         }
     978              :     }
     979              : 
     980              :     if (id.GetProductId() == 0)
     981              :     {
     982              :         uint16_t productId = 0;
     983              :         if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetProductId(productId) != CHIP_NO_ERROR)
     984              :         {
     985              :             ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Product ID not known");
     986              :         }
     987              :         else
     988              :         {
     989              :             id.SetProductId(productId);
     990              :         }
     991              :     }
     992              : 
     993              :     if (strlen(id.GetDeviceName()) == 0)
     994              :     {
     995              :         char deviceName[Dnssd::kKeyDeviceNameMaxLength + 1] = {};
     996              :         if (!DeviceLayer::ConfigurationMgr().IsCommissionableDeviceNameEnabled() ||
     997              :             DeviceLayer::ConfigurationMgr().GetCommissionableDeviceName(deviceName, sizeof(deviceName)) != CHIP_NO_ERROR)
     998              :         {
     999              :             ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Device Name not known");
    1000              :         }
    1001              :         else
    1002              :         {
    1003              :             id.SetDeviceName(deviceName);
    1004              :         }
    1005              :     }
    1006              : 
    1007              : #if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID)
    1008              :     if (id.GetRotatingIdLength() == 0)
    1009              :     {
    1010              :         AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
    1011              :         uint8_t rotatingDeviceIdUniqueId[DeviceLayer::ConfigurationManager::kRotatingDeviceIDUniqueIDLength];
    1012              :         MutableByteSpan rotatingDeviceIdUniqueIdSpan(rotatingDeviceIdUniqueId);
    1013              : 
    1014              :         ReturnErrorOnFailure(
    1015              :             DeviceLayer::GetDeviceInstanceInfoProvider()->GetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueIdSpan));
    1016              :         ReturnErrorOnFailure(
    1017              :             DeviceLayer::ConfigurationMgr().GetLifetimeCounter(additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter));
    1018              :         additionalDataPayloadParams.rotatingDeviceIdUniqueId = rotatingDeviceIdUniqueIdSpan;
    1019              : 
    1020              :         uint8_t rotatingDeviceIdInternalBuffer[RotatingDeviceId::kMaxLength];
    1021              :         MutableByteSpan rotatingDeviceIdBufferTemp(rotatingDeviceIdInternalBuffer);
    1022              :         ReturnErrorOnFailure(AdditionalDataPayloadGenerator().generateRotatingDeviceIdAsBinary(additionalDataPayloadParams,
    1023              :                                                                                                rotatingDeviceIdBufferTemp));
    1024              : 
    1025              :         id.SetRotatingId(rotatingDeviceIdInternalBuffer, RotatingDeviceId::kMaxLength);
    1026              :     }
    1027              : #endif
    1028              : 
    1029              :     if (id.GetCdPort() == 0)
    1030              :     {
    1031              :         id.SetCdPort(mCdcListenPort);
    1032              :     }
    1033              : 
    1034              :     err = gUDCClient->SendUDCMessage(&mTransports, id, commissioner);
    1035              : 
    1036              :     if (err == CHIP_NO_ERROR)
    1037              :     {
    1038              :         ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Send UDC request success");
    1039              :     }
    1040              :     else
    1041              :     {
    1042              :         ChipLogError(AppServer, "Server::SendUserDirectedCommissioningRequest() Send UDC request failed, err: %" CHIP_ERROR_FORMAT,
    1043              :                      err.Format());
    1044              :     }
    1045              :     return err;
    1046              : }
    1047              : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
    1048              : 
    1049              : #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
    1050            1 : void Server::ResumeSubscriptions()
    1051              : {
    1052            1 :     CHIP_ERROR err = app::InteractionModelEngine::GetInstance()->ResumeSubscriptions();
    1053            2 :     if (err != CHIP_NO_ERROR)
    1054              :     {
    1055            0 :         ChipLogError(AppServer, "Error when trying to resume subscriptions : %" CHIP_ERROR_FORMAT, err.Format());
    1056              :     }
    1057            1 : }
    1058              : #endif
    1059              : 
    1060              : Credentials::IgnoreCertificateValidityPeriodPolicy Server::sDefaultCertValidityPolicy;
    1061              : 
    1062              : } // namespace chip
        

Generated by: LCOV version 2.0-1