Matter SDK Coverage Report
Current view: top level - app/server - Server.cpp (source / functions) Coverage Total Hit
Test: SHA:e021a368d10ac6f3f201c101585146211fdcdaa2 Lines: 83.3 % 227 189
Test Date: 2026-02-13 08:13:38 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 :     Access::SetAccessControl(mAccessControl);
     315              : 
     316              : #if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
     317              :     if (initParams.accessRestrictionProvider != nullptr)
     318              :     {
     319              :         mAccessControl.SetAccessRestrictionProvider(initParams.accessRestrictionProvider);
     320              :     }
     321              : #endif
     322              : 
     323            1 :     mAclStorage = initParams.aclStorage;
     324            1 :     SuccessOrExit(err = mAclStorage->Init(*mDeviceStorage, mFabrics.begin(), mFabrics.end()));
     325              : 
     326            1 :     mGroupsProvider = initParams.groupDataProvider;
     327            1 :     SetGroupDataProvider(mGroupsProvider);
     328              : 
     329            1 :     mReportScheduler = initParams.reportScheduler;
     330              : 
     331            1 :     mTestEventTriggerDelegate = initParams.testEventTriggerDelegate;
     332            1 :     if (mTestEventTriggerDelegate == nullptr)
     333              :     {
     334            0 :         ChipLogProgress(AppServer, "WARNING: mTestEventTriggerDelegate is null");
     335              :     }
     336              : 
     337            1 :     deviceInfoprovider = DeviceLayer::GetDeviceInfoProvider();
     338            1 :     if (deviceInfoprovider)
     339              :     {
     340            0 :         deviceInfoprovider->SetStorageDelegate(mDeviceStorage);
     341              :     }
     342              : 
     343              :     // Init transport before operations with secure session mgr.
     344              :     //
     345              :     // The logic below expects that the IPv6 transport is at index 0. Keep that logic in sync with
     346              :     // this code.
     347              :     //
     348              : #if CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     349              :     // Use helper function for automatic port selection with retry logic and overflow protection
     350              :     err = InitTransportWithPortRetry(
     351              :         mOperationalServicePort, initParams.portRetryCount, "transport",
     352              :         [&](uint16_t port) -> CHIP_ERROR {
     353              :     // Update TCP listen params if enabled
     354              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
     355              :             tcpListenParams.SetListenPort(port);
     356              : #endif
     357              : 
     358              :             // Attempt to initialize transports with the selected port
     359              :             return mTransports.Init(
     360              :                 UdpListenParameters(DeviceLayer::UDPEndPointManager())
     361              :                     .SetAddressType(IPAddressType::kIPv6)
     362              :                     .SetListenPort(port)
     363              :                     .SetNativeParams(initParams.endpointNativeParams)
     364              : #if INET_CONFIG_ENABLE_IPV4
     365              :                     ,
     366              :                 // The logic below expects that the IPv4 transport, if enabled, is at
     367              :                 // index 1. Keep that logic in sync with this code.
     368              :                 UdpListenParameters(DeviceLayer::UDPEndPointManager()).SetAddressType(IPAddressType::kIPv4).SetListenPort(port)
     369              : #endif
     370              : #if CONFIG_NETWORK_LAYER_BLE
     371              :                     ,
     372              :                 BleListenParameters(DeviceLayer::ConnectivityMgr().GetBleLayer())
     373              : #endif
     374              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
     375              :                     ,
     376              :                 tcpListenParams
     377              : #if INET_CONFIG_ENABLE_IPV4
     378              :                 ,
     379              :                 TcpListenParameters(DeviceLayer::TCPEndPointManager()).SetAddressType(IPAddressType::kIPv4).SetListenPort(port)
     380              : #endif
     381              : #endif
     382              : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
     383              :                     ,
     384              :                 Transport::WiFiPAFListenParameters(
     385              :                     static_cast<Transport::WiFiPAFBase *>(DeviceLayer::ConnectivityMgr().GetWiFiPAF()->mWiFiPAFTransport))
     386              : #endif
     387              : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
     388              :                     ,
     389              :                 NfcListenParameters(nullptr)
     390              : #endif
     391              :             );
     392              :         },
     393              :         [&]() {
     394              :             // Close transports from the failed attempt before retrying
     395              :             // BLE transport now handles re-initialization gracefully as a no-op
     396              :             mTransports.Close();
     397              :         },
     398              :         mOperationalServicePort);
     399              : #else // CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     400              :     // Initialize transports without port retry
     401              : 
     402              :     // Update TCP listen params if enabled
     403              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
     404            1 :     tcpListenParams.SetListenPort(mOperationalServicePort);
     405              : #endif
     406              : 
     407            2 :     err = mTransports.Init(UdpListenParameters(DeviceLayer::UDPEndPointManager())
     408            1 :                                .SetAddressType(IPAddressType::kIPv6)
     409            1 :                                .SetListenPort(mOperationalServicePort)
     410            1 :                                .SetNativeParams(initParams.endpointNativeParams)
     411              : #if INET_CONFIG_ENABLE_IPV4
     412              :                                ,
     413              :                            // The logic below expects that the IPv4 transport, if enabled, is at
     414              :                            // index 1. Keep that logic in sync with this code.
     415            1 :                            UdpListenParameters(DeviceLayer::UDPEndPointManager())
     416            1 :                                .SetAddressType(IPAddressType::kIPv4)
     417            1 :                                .SetListenPort(mOperationalServicePort)
     418              : #endif
     419              : #if CONFIG_NETWORK_LAYER_BLE
     420              :                                ,
     421            1 :                            BleListenParameters(DeviceLayer::ConnectivityMgr().GetBleLayer())
     422              : #endif
     423              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
     424              :                                ,
     425              :                            tcpListenParams
     426              : #if INET_CONFIG_ENABLE_IPV4
     427              :                            ,
     428            1 :                            TcpListenParameters(DeviceLayer::TCPEndPointManager())
     429            1 :                                .SetAddressType(IPAddressType::kIPv4)
     430            1 :                                .SetListenPort(mOperationalServicePort)
     431              : #endif
     432              : #endif
     433              : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
     434              :                                ,
     435            1 :                            Transport::WiFiPAFListenParameters(static_cast<Transport::WiFiPAFBase *>(
     436            1 :                                DeviceLayer::ConnectivityMgr().GetWiFiPAF()->mWiFiPAFTransport))
     437              : #endif
     438              : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
     439              :                                ,
     440              :                            NfcListenParameters(nullptr)
     441              : #endif
     442              :     );
     443              : #endif // CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     444              : 
     445            1 :     SuccessOrExit(err);
     446            1 :     err = mListener.Init(this);
     447            1 :     SuccessOrExit(err);
     448            1 :     mGroupsProvider->SetListener(&mListener);
     449              : 
     450              : #if CONFIG_NETWORK_LAYER_BLE
     451            1 :     mBleLayer = DeviceLayer::ConnectivityMgr().GetBleLayer();
     452              : #endif
     453            1 :     SuccessOrExit(err);
     454              : 
     455            1 :     err = mSessions.Init(&DeviceLayer::SystemLayer(), &mTransports, &mMessageCounterManager, mDeviceStorage, &GetFabricTable(),
     456            1 :                          *mSessionKeystore);
     457            1 :     SuccessOrExit(err);
     458              : 
     459            1 :     err = mFabricDelegate.Init(this);
     460            1 :     SuccessOrExit(err);
     461            1 :     TEMPORARY_RETURN_IGNORED mFabrics.AddFabricDelegate(&mFabricDelegate);
     462              : 
     463            1 :     err = mExchangeMgr.Init(&mSessions);
     464            1 :     SuccessOrExit(err);
     465            1 :     err = mMessageCounterManager.Init(&mExchangeMgr);
     466            1 :     SuccessOrExit(err);
     467              : 
     468            1 :     err = mUnsolicitedStatusHandler.Init(&mExchangeMgr);
     469            1 :     SuccessOrExit(err);
     470              : 
     471            1 :     SuccessOrExit(err = mCommissioningWindowManager.Init(this));
     472            1 :     mCommissioningWindowManager.SetAppDelegate(initParams.appDelegate);
     473              : 
     474            1 :     app::DnssdServer::Instance().SetFabricTable(&mFabrics);
     475            1 :     app::DnssdServer::Instance().SetCommissioningModeProvider(&mCommissioningWindowManager);
     476              : 
     477            1 :     TEMPORARY_RETURN_IGNORED Dnssd::Resolver::Instance().Init(DeviceLayer::UDPEndPointManager());
     478              : 
     479              : #if CHIP_CONFIG_ENABLE_SERVER_IM_EVENT
     480              :     // Initialize event logging subsystem
     481            1 :     err = sGlobalEventIdCounter.Init(mDeviceStorage, DefaultStorageKeyAllocator::IMEventNumber(),
     482              :                                      CHIP_DEVICE_CONFIG_EVENT_ID_COUNTER_EPOCH);
     483            1 :     SuccessOrExit(err);
     484              : 
     485              :     {
     486            1 :         app::LogStorageResources logStorageResources[] = {
     487              :             { &sDebugEventBuffer[0], sizeof(sDebugEventBuffer), app::PriorityLevel::Debug },
     488              :             { &sInfoEventBuffer[0], sizeof(sInfoEventBuffer), app::PriorityLevel::Info },
     489              :             { &sCritEventBuffer[0], sizeof(sCritEventBuffer), app::PriorityLevel::Critical }
     490              :         };
     491              : 
     492            3 :         err = app::EventManagement::GetInstance().Init(&mExchangeMgr, CHIP_NUM_EVENT_LOGGING_BUFFERS, &sLoggingBuffer[0],
     493              :                                                        &logStorageResources[0], &sGlobalEventIdCounter,
     494            1 :                                                        std::chrono::duration_cast<System::Clock::Milliseconds64>(mInitTimestamp),
     495            1 :                                                        &app::InteractionModelEngine::GetInstance()->GetReportingEngine());
     496              : 
     497            1 :         SuccessOrExit(err);
     498              :     }
     499              : #endif // CHIP_CONFIG_ENABLE_SERVER_IM_EVENT
     500              : 
     501              :     // SetDataModelProvider() initializes and starts the provider, which in turn
     502              :     // triggers the initialization of cluster implementations. This callsite is
     503              :     // critical because it ensures that cluster-level initialization occurs only
     504              :     // after all necessary low-level dependencies have been set up.
     505              :     //
     506              :     // Ordering guarantees:
     507              :     // 1) Provider initialization (under SetDataModelProvider) must happen after
     508              :     //    SetSafeAttributePersistenceProvider to ensure the provider can leverage
     509              :     //    the safe persistence provider for attribute persistence logic.
     510              :     // 2) It must occur after all low-level components that cluster implementations
     511              :     //    might depend on have been initialized, as they rely on these components
     512              :     //    during their own initialization.
     513              :     //
     514              :     // This remains the single point of entry to ensure that all cluster-level
     515              :     // initialization is performed in the correct order.
     516            1 :     app::InteractionModelEngine::GetInstance()->SetDataModelProvider(initParams.dataModelProvider);
     517              : 
     518              : #if defined(CHIP_APP_USE_ECHO)
     519              :     err = InitEchoHandler(&mExchangeMgr);
     520              :     SuccessOrExit(err);
     521              : #endif
     522              : 
     523            1 :     app::DnssdServer::Instance().SetSecuredIPv6Port(mTransports.GetTransport().GetImplAtIndex<0>().GetBoundPort());
     524              : #if INET_CONFIG_ENABLE_IPV4
     525            1 :     app::DnssdServer::Instance().SetSecuredIPv4Port(mTransports.GetTransport().GetImplAtIndex<1>().GetBoundPort());
     526              : #endif // INET_CONFIG_ENABLE_IPV4
     527              : 
     528            1 :     app::DnssdServer::Instance().SetUnsecuredPort(mUserDirectedCommissioningPort);
     529            1 :     app::DnssdServer::Instance().SetInterfaceId(mInterfaceId);
     530              : 
     531              : #if CHIP_CONFIG_ENABLE_ICD_SERVER
     532              :     // We set the ICDManager reference betfore calling the ICDManager init due to the init ordering limitations.
     533              :     // DnssdServer will use the default value initially and will update advertisement once ICDManager
     534              :     // init is called.
     535              :     app::DnssdServer::Instance().SetICDManager(&mICDManager);
     536              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
     537              : 
     538              : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
     539              :     // Enable the TCP Server based on the TCPListenParameters setting.
     540            1 :     app::DnssdServer::Instance().SetTCPServerEnabled(tcpListenParams.IsServerListenEnabled());
     541              : #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
     542              : 
     543            1 :     if (GetFabricTable().FabricCount() != 0)
     544              :     {
     545              : #if CONFIG_NETWORK_LAYER_BLE
     546              :         // The device is already commissioned, proactively disable BLE advertisement.
     547            0 :         ChipLogProgress(AppServer, "Fabric already commissioned. Disabling BLE advertisement");
     548            0 :         TEMPORARY_RETURN_IGNORED DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(false);
     549              : #endif
     550              :     }
     551            1 :     else if (initParams.advertiseCommissionableIfNoFabrics)
     552              :     {
     553            1 :         SuccessOrExit(err = mCommissioningWindowManager.OpenBasicCommissioningWindow(initParams.discoveryTimeout));
     554              :     }
     555              : 
     556              :     // TODO @bzbarsky-apple @cecille Move to examples
     557              :     // ESP32 examples have a custom logic for enabling DNS-SD
     558              : #if !CHIP_DEVICE_LAYER_TARGET_ESP32 && (!CHIP_DEVICE_LAYER_TARGET_AMEBA || !CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE)
     559              :     // StartServer only enables commissioning mode if device has not been commissioned
     560            1 :     app::DnssdServer::Instance().StartServer();
     561              : #endif
     562              : 
     563              :     caseSessionManagerConfig = {
     564              :         .sessionInitParams =  {
     565            1 :             .sessionManager    = &mSessions,
     566            1 :             .sessionResumptionStorage = mSessionResumptionStorage,
     567              :             .certificateValidityPolicy = &mCertificateValidityPolicy,
     568            1 :             .exchangeMgr       = &mExchangeMgr,
     569            1 :             .fabricTable       = &mFabrics,
     570            1 :             .groupDataProvider = mGroupsProvider,
     571              :             // Don't provide an MRP local config, so each CASE initiation will use
     572              :             // the then-current value.
     573              :             .mrpLocalConfig = NullOptional,
     574              :         },
     575              :         .clientPool            = &mCASEClientPool,
     576              :         .sessionSetupPool      = &mSessionSetupPool,
     577            1 :     };
     578              : 
     579            1 :     err = mCASESessionManager.Init(&DeviceLayer::SystemLayer(), caseSessionManagerConfig);
     580            1 :     SuccessOrExit(err);
     581              : 
     582            1 :     err = mCASEServer.ListenForSessionEstablishment(&mExchangeMgr, &mSessions, &mFabrics, mSessionResumptionStorage,
     583              :                                                     &mCertificateValidityPolicy, mGroupsProvider);
     584            1 :     SuccessOrExit(err);
     585              : 
     586            1 :     err = app::InteractionModelEngine::GetInstance()->Init(&mExchangeMgr, &GetFabricTable(), mReportScheduler, &mCASESessionManager,
     587              :                                                            mSubscriptionResumptionStorage);
     588            1 :     SuccessOrExit(err);
     589              : 
     590              : #if CHIP_CONFIG_ENABLE_ICD_SERVER
     591              :     app::InteractionModelEngine::GetInstance()->SetICDManager(&mICDManager);
     592              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
     593              : 
     594              :     // ICD Init needs to be after data model init and InteractionModel Init
     595              : #if CHIP_CONFIG_ENABLE_ICD_SERVER
     596              : 
     597              :     // Register the ICDStateObservers.
     598              :     // Call register before init so that observers are notified of any state change during the init.
     599              :     // All observers are released at mICDManager.Shutdown(). They can be released individually with ReleaseObserver
     600              :     mICDManager.RegisterObserver(mReportScheduler);
     601              :     mICDManager.RegisterObserver(&app::DnssdServer::Instance());
     602              : 
     603              : #if CHIP_CONFIG_ENABLE_ICD_CIP
     604              :     mICDManager.SetPersistentStorageDelegate(mDeviceStorage)
     605              :         .SetFabricTable(&GetFabricTable())
     606              :         .SetSymmetricKeyStore(mSessionKeystore)
     607              :         .SetExchangeManager(&mExchangeMgr)
     608              :         .SetSubscriptionsInfoProvider(app::InteractionModelEngine::GetInstance())
     609              :         .SetICDCheckInBackOffStrategy(initParams.icdCheckInBackOffStrategy);
     610              : 
     611              : #endif // CHIP_CONFIG_ENABLE_ICD_CIP
     612              :     mICDManager.Init();
     613              : 
     614              :     // Register Test Event Trigger Handler
     615              :     if (mTestEventTriggerDelegate != nullptr)
     616              :     {
     617              :         TEMPORARY_RETURN_IGNORED mTestEventTriggerDelegate->AddHandler(&mICDManager);
     618              :     }
     619              : 
     620              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
     621              : 
     622              :     // This code is necessary to restart listening to existing groups after a reboot
     623              :     // Each manufacturer needs to validate that they can rejoin groups by placing this code at the appropriate location for them
     624              :     //
     625              :     // Thread LWIP devices using dedicated Inet endpoint implementations are excluded because they call this function from:
     626              :     // src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp
     627              : #if !CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
     628            1 :     RejoinExistingMulticastGroups();
     629              : #endif // !CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
     630              : 
     631              :     // Handle deferred clean-up of a previously armed fail-safe that occurred during FabricTable commit.
     632              :     // This is done at the very end since at the earlier time above when FabricTable::Init() is called,
     633              :     // the delegates could not have been registered, and the other systems were not initialized. By now,
     634              :     // everything is initialized, so we can do a deferred clean-up.
     635              :     {
     636            1 :         FabricIndex fabricIndexDeletedOnInit = GetFabricTable().GetDeletedFabricFromCommitMarker();
     637            1 :         if (fabricIndexDeletedOnInit != kUndefinedFabricIndex)
     638              :         {
     639            0 :             ChipLogError(AppServer, "FabricIndex 0x%x deleted due to restart while fail-safed. Processing a clean-up!",
     640              :                          static_cast<unsigned>(fabricIndexDeletedOnInit));
     641              : 
     642              :             // Always pretend it was an add, since being in the middle of an update currently breaks
     643              :             // the validity of the fabric table. This is expected to be extremely infrequent, so
     644              :             // this "harsher" than usual clean-up is more likely to get us in a valid state for whatever
     645              :             // remains.
     646            0 :             const bool addNocCalled    = true;
     647            0 :             const bool updateNocCalled = false;
     648            0 :             GetFailSafeContext().ScheduleFailSafeCleanup(fabricIndexDeletedOnInit, addNocCalled, updateNocCalled);
     649              : 
     650              :             // Schedule clearing of the commit marker to only occur after we have processed all fail-safe clean-up.
     651              :             // Because Matter runs a single event loop for all scheduled work, it will occur after the above has
     652              :             // taken place. If a reset occurs before we have cleaned everything up, the next boot will still
     653              :             // see the commit marker.
     654            0 :             TEMPORARY_RETURN_IGNORED PlatformMgr().ScheduleWork(
     655            0 :                 [](intptr_t arg) {
     656            0 :                     Server * server = reinterpret_cast<Server *>(arg);
     657            0 :                     VerifyOrReturn(server != nullptr);
     658              : 
     659            0 :                     server->GetFabricTable().ClearCommitMarker();
     660            0 :                     ChipLogProgress(AppServer, "Cleared FabricTable pending commit marker");
     661              :                 },
     662              :                 reinterpret_cast<intptr_t>(this));
     663              :         }
     664              :     }
     665              : 
     666              : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT // support UDC port for commissioner declaration msgs
     667              : #if CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     668              :     // Use helper function for UDC transport initialization with automatic port selection and overflow protection
     669              :     mUdcTransportMgr = Platform::New<UdcTransportMgr>();
     670              :     err              = InitTransportWithPortRetry(
     671              :         mCdcListenPort, initParams.portRetryCount, "UDC transport",
     672              :         [&](uint16_t port) -> CHIP_ERROR {
     673              :             // Attempt to initialize UDC transport with the selected port
     674              :             return mUdcTransportMgr->Init(Transport::UdpListenParameters(DeviceLayer::UDPEndPointManager())
     675              :                                                            .SetAddressType(Inet::IPAddressType::kIPv6)
     676              :                                                            .SetListenPort(port)
     677              :                                                            .SetNativeParams(initParams.endpointNativeParams)
     678              : #if INET_CONFIG_ENABLE_IPV4
     679              :                                               ,
     680              :                                           Transport::UdpListenParameters(DeviceLayer::UDPEndPointManager())
     681              :                                               .SetAddressType(Inet::IPAddressType::kIPv4)
     682              :                                               .SetListenPort(port)
     683              : #endif // INET_CONFIG_ENABLE_IPV4
     684              :             );
     685              :         },
     686              :         [&]() { mUdcTransportMgr->Close(); }, mCdcListenPort);
     687              : #else // CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     688              :     // Initialize UDC transport without port retry
     689              :     mUdcTransportMgr = Platform::New<UdcTransportMgr>();
     690              :     err              = mUdcTransportMgr->Init(Transport::UdpListenParameters(DeviceLayer::UDPEndPointManager())
     691              :                                                   .SetAddressType(Inet::IPAddressType::kIPv6)
     692              :                                                   .SetListenPort(mCdcListenPort)
     693              :                                                   .SetNativeParams(initParams.endpointNativeParams)
     694              : #if INET_CONFIG_ENABLE_IPV4
     695              :                                                   ,
     696              :                                               Transport::UdpListenParameters(DeviceLayer::UDPEndPointManager())
     697              :                                                   .SetAddressType(Inet::IPAddressType::kIPv4)
     698              :                                                   .SetListenPort(mCdcListenPort)
     699              : #endif // INET_CONFIG_ENABLE_IPV4
     700              :                  );
     701              : #endif // CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
     702              :     SuccessOrExit(err);
     703              : 
     704              :     gUDCClient = Platform::New<Protocols::UserDirectedCommissioning::UserDirectedCommissioningClient>();
     705              :     mUdcTransportMgr->SetSessionManager(gUDCClient);
     706              : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
     707              : 
     708            1 :     TEMPORARY_RETURN_IGNORED PlatformMgr().AddEventHandler(OnPlatformEventWrapper, reinterpret_cast<intptr_t>(this));
     709            1 :     PlatformMgr().HandleServerStarted();
     710              : 
     711            1 :     mIsDnssdReady = Dnssd::Resolver::Instance().IsInitialized();
     712            1 :     CheckServerReadyEvent();
     713              : 
     714            1 : exit:
     715            2 :     if (err != CHIP_NO_ERROR)
     716              :     {
     717            0 :         ChipLogError(AppServer, "ERROR setting up transport: %" CHIP_ERROR_FORMAT, err.Format());
     718              :     }
     719              :     else
     720              :     {
     721              :         // NOTE: this log is scraped by the test harness.
     722            1 :         ChipLogProgress(AppServer, "Server Listening...");
     723              :     }
     724            1 :     return err;
     725              : }
     726              : 
     727            8 : void Server::OnPlatformEvent(const DeviceLayer::ChipDeviceEvent & event)
     728              : {
     729            8 :     switch (event.Type)
     730              :     {
     731            1 :     case DeviceEventType::kDnssdInitialized:
     732              :         // Platform DNS-SD implementation uses kPlatformDnssdInitialized event to signal that it's ready.
     733            1 :         if (!mIsDnssdReady)
     734              :         {
     735            0 :             mIsDnssdReady = true;
     736            0 :             CheckServerReadyEvent();
     737              :         }
     738            1 :         break;
     739            1 :     case DeviceEventType::kServerReady:
     740              : #if CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP
     741              :         // Only Trigger Check-In messages if we are not in the middle of a commissioning.
     742              :         // This check is only necessary for the first commissioiner since the kServerReady event
     743              :         // is triggered once we join the network.
     744              :         // We trigger Check-In messages before resuming subscriptions to avoid doing both.
     745              :         if (!mFailSafeContext.IsFailSafeArmed())
     746              :         {
     747              :             std::function<app::ICDManager::ShouldCheckInMsgsBeSentFunction> sendCheckInMessagesOnBootUp =
     748              :                 std::bind(&Server::ShouldCheckInMsgsBeSentAtBootFunction, this, std::placeholders::_1, std::placeholders::_2);
     749              :             mICDManager.TriggerCheckInMessages(sendCheckInMessagesOnBootUp);
     750              :         }
     751              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP
     752              : #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
     753            1 :         ResumeSubscriptions();
     754              : #endif // CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
     755            1 :         break;
     756              : #if CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
     757              :     case DeviceEventType::kThreadConnectivityChange:
     758              :         if (event.ThreadConnectivityChange.Result == kConnectivity_Established)
     759              :         {
     760              :             // Refresh Multicast listening
     761              :             ChipLogDetail(DeviceLayer, "Thread Attached updating Multicast address");
     762              :             RejoinExistingMulticastGroups();
     763              :         }
     764              :         break;
     765              : #endif // CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
     766            6 :     default:
     767            6 :         break;
     768              :     }
     769            8 : }
     770              : 
     771            1 : void Server::CheckServerReadyEvent()
     772              : {
     773              :     // Check if all asynchronously initialized server components (currently, only DNS-SD)
     774              :     // are ready, and emit the 'server ready' event if so.
     775            1 :     if (mIsDnssdReady)
     776              :     {
     777            1 :         ChipLogProgress(AppServer, "Server initialization complete");
     778              : 
     779            1 :         ChipDeviceEvent event = { .Type = DeviceEventType::kServerReady };
     780            1 :         PlatformMgr().PostEventOrDie(&event);
     781              :     }
     782            1 : }
     783              : 
     784            8 : void Server::OnPlatformEventWrapper(const DeviceLayer::ChipDeviceEvent * event, intptr_t server)
     785              : {
     786            8 :     reinterpret_cast<Server *>(server)->OnPlatformEvent(*event);
     787            8 : }
     788              : 
     789            1 : void Server::RejoinExistingMulticastGroups()
     790              : {
     791            1 :     ChipLogProgress(AppServer, "Joining Multicast groups");
     792            1 :     CHIP_ERROR err = CHIP_NO_ERROR;
     793            1 :     for (const FabricInfo & fabric : mFabrics)
     794              :     {
     795            0 :         Credentials::GroupDataProvider::GroupInfo groupInfo;
     796              : 
     797            0 :         auto * iterator = mGroupsProvider->IterateGroupInfo(fabric.GetFabricIndex());
     798            0 :         if (iterator)
     799              :         {
     800              :             // GroupDataProvider was able to allocate rescources for an iterator
     801            0 :             while (iterator->Next(groupInfo))
     802              :             {
     803            0 :                 err = mTransports.MulticastGroupJoinLeave(
     804            0 :                     Transport::PeerAddress::Multicast(fabric.GetFabricId(), groupInfo.group_id), true);
     805            0 :                 if (err != CHIP_NO_ERROR)
     806              :                 {
     807            0 :                     ChipLogError(AppServer, "Error when trying to join Group %u of fabric index %u : %" CHIP_ERROR_FORMAT,
     808              :                                  groupInfo.group_id, fabric.GetFabricIndex(), err.Format());
     809              : 
     810              :                     // We assume the failure is caused by a network issue or a lack of rescources; neither of which will be solved
     811              :                     // before the next join. Exit the loop to save rescources.
     812            0 :                     iterator->Release();
     813            0 :                     return;
     814              :                 }
     815              :             }
     816              : 
     817            0 :             iterator->Release();
     818              :         }
     819              :     }
     820              : }
     821              : 
     822              : #if CHIP_CONFIG_ENABLE_ICD_CIP
     823              : bool Server::ShouldCheckInMsgsBeSentAtBootFunction(FabricIndex aFabricIndex, NodeId subjectID)
     824              : {
     825              : #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
     826              :     // If at least one registration has a persisted entry, do not send Check-In message.
     827              :     // The resumption of the persisted subscription will serve the same function a check-in would have served.
     828              :     return !app::InteractionModelEngine::GetInstance()->SubjectHasPersistedSubscription(aFabricIndex, subjectID);
     829              : #else
     830              :     return true;
     831              : #endif // CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
     832              : }
     833              : #endif // CHIP_CONFIG_ENABLE_ICD_CIP
     834              : 
     835            0 : void Server::GenerateShutDownEvent()
     836              : {
     837            0 :     TEMPORARY_RETURN_IGNORED PlatformMgr().ScheduleWork([](intptr_t) { PlatformMgr().HandleServerShuttingDown(); });
     838            0 : }
     839              : 
     840            1 : void Server::PostFactoryResetEvent()
     841              : {
     842            1 :     DeviceLayer::ChipDeviceEvent event{ .Type = DeviceLayer::DeviceEventType::kFactoryReset };
     843              : 
     844            1 :     CHIP_ERROR error = DeviceLayer::PlatformMgr().PostEvent(&event);
     845            2 :     if (error != CHIP_NO_ERROR)
     846              :     {
     847            0 :         ChipLogError(AppServer, "Posting kFactoryReset event failed with %" CHIP_ERROR_FORMAT, error.Format());
     848              :     }
     849            1 : }
     850              : 
     851            1 : void Server::ScheduleFactoryReset()
     852              : {
     853            1 :     PostFactoryResetEvent();
     854              : 
     855            1 :     TEMPORARY_RETURN_IGNORED PlatformMgr().ScheduleWork([](intptr_t) {
     856              :         // Delete all fabrics and emit Leave event.
     857            1 :         GetInstance().GetFabricTable().DeleteAllFabrics();
     858            1 :         PlatformMgr().HandleServerShuttingDown();
     859            1 :         ConfigurationMgr().InitiateFactoryReset();
     860            1 :     });
     861            1 : }
     862              : 
     863            1 : void Server::Shutdown()
     864              : {
     865            1 :     assertChipStackLockedByCurrentThread();
     866            1 :     PlatformMgr().RemoveEventHandler(OnPlatformEventWrapper, 0);
     867            1 :     mCASEServer.Shutdown();
     868            1 :     mCASESessionManager.Shutdown();
     869              : #if CHIP_CONFIG_ENABLE_ICD_SERVER
     870              :     app::DnssdServer::Instance().SetICDManager(nullptr);
     871              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
     872            1 :     app::DnssdServer::Instance().SetCommissioningModeProvider(nullptr);
     873            1 :     Dnssd::ServiceAdvertiser::Instance().Shutdown();
     874              : 
     875              : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
     876              :     if (mUdcTransportMgr != nullptr)
     877              :     {
     878              :         Platform::Delete(mUdcTransportMgr);
     879              :         mUdcTransportMgr = nullptr;
     880              :     }
     881              :     if (gUDCClient != nullptr)
     882              :     {
     883              :         Platform::Delete(gUDCClient);
     884              :         gUDCClient = nullptr;
     885              :     }
     886              : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
     887              : 
     888            1 :     Dnssd::Resolver::Instance().Shutdown();
     889            1 :     app::InteractionModelEngine::GetInstance()->Shutdown();
     890              : #if CHIP_CONFIG_ENABLE_ICD_SERVER
     891              :     app::InteractionModelEngine::GetInstance()->SetICDManager(nullptr);
     892              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
     893              :     // Shut down any remaining sessions (and hence exchanges) before we do any
     894              :     // futher teardown.  CASE handshakes have been shut down already via
     895              :     // shutting down mCASESessionManager and mCASEServer above; shutting
     896              :     // down mCommissioningWindowManager will shut down any PASE handshakes we
     897              :     // have going on.
     898            1 :     mSessions.ExpireAllSecureSessions();
     899            1 :     mCommissioningWindowManager.Shutdown();
     900            1 :     mMessageCounterManager.Shutdown();
     901            1 :     mExchangeMgr.Shutdown();
     902            1 :     mSessions.Shutdown();
     903            1 :     mTransports.Close();
     904            1 :     mAccessControl.Finish();
     905            1 :     Access::ResetAccessControlToDefault();
     906            1 :     Credentials::SetGroupDataProvider(nullptr);
     907              : #if CHIP_CONFIG_ENABLE_ICD_SERVER
     908              :     // Remove Test Event Trigger Handler
     909              :     if (mTestEventTriggerDelegate != nullptr)
     910              :     {
     911              :         mTestEventTriggerDelegate->RemoveHandler(&mICDManager);
     912              :     }
     913              :     mICDManager.Shutdown();
     914              : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
     915              : 
     916              :     // TODO(16969): Remove chip::Platform::MemoryInit() call from Server class, it belongs to outer code
     917            1 :     chip::Platform::MemoryShutdown();
     918            1 : }
     919              : 
     920              : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
     921              : // NOTE: UDC client is located in Server.cpp because it really only makes sense
     922              : // to send UDC from a Matter device. The UDC message payload needs to include the device's
     923              : // randomly generated service name.
     924              : CHIP_ERROR Server::SendUserDirectedCommissioningRequest(Transport::PeerAddress commissioner,
     925              :                                                         Protocols::UserDirectedCommissioning::IdentificationDeclaration & id)
     926              : {
     927              :     ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest()");
     928              : 
     929              :     CHIP_ERROR err;
     930              : 
     931              :     // only populate fields left blank by the client
     932              :     if (strlen(id.GetInstanceName()) == 0)
     933              :     {
     934              :         ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Instance Name not known");
     935              :         char nameBuffer[Dnssd::Commission::kInstanceNameMaxLength + 1];
     936              :         err = app::DnssdServer::Instance().GetCommissionableInstanceName(nameBuffer, sizeof(nameBuffer));
     937              :         if (err != CHIP_NO_ERROR)
     938              :         {
     939              :             ChipLogError(
     940              :                 AppServer,
     941              :                 "Server::SendUserDirectedCommissioningRequest() Failed to get mdns instance name error: %" CHIP_ERROR_FORMAT,
     942              :                 err.Format());
     943              :             return err;
     944              :         }
     945              :         id.SetInstanceName(nameBuffer);
     946              :         ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Instance Name set to %s", nameBuffer);
     947              :     }
     948              : 
     949              :     if (id.GetVendorId() == 0)
     950              :     {
     951              :         uint16_t vendorId = 0;
     952              :         if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(vendorId) != CHIP_NO_ERROR)
     953              :         {
     954              :             ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Vendor ID not known");
     955              :         }
     956              :         else
     957              :         {
     958              :             id.SetVendorId(vendorId);
     959              :         }
     960              :     }
     961              : 
     962              :     if (id.GetProductId() == 0)
     963              :     {
     964              :         uint16_t productId = 0;
     965              :         if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetProductId(productId) != CHIP_NO_ERROR)
     966              :         {
     967              :             ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Product ID not known");
     968              :         }
     969              :         else
     970              :         {
     971              :             id.SetProductId(productId);
     972              :         }
     973              :     }
     974              : 
     975              :     if (strlen(id.GetDeviceName()) == 0)
     976              :     {
     977              :         char deviceName[Dnssd::kKeyDeviceNameMaxLength + 1] = {};
     978              :         if (!DeviceLayer::ConfigurationMgr().IsCommissionableDeviceNameEnabled() ||
     979              :             DeviceLayer::ConfigurationMgr().GetCommissionableDeviceName(deviceName, sizeof(deviceName)) != CHIP_NO_ERROR)
     980              :         {
     981              :             ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Device Name not known");
     982              :         }
     983              :         else
     984              :         {
     985              :             id.SetDeviceName(deviceName);
     986              :         }
     987              :     }
     988              : 
     989              : #if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID)
     990              :     if (id.GetRotatingIdLength() == 0)
     991              :     {
     992              :         AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
     993              :         uint8_t rotatingDeviceIdUniqueId[DeviceLayer::ConfigurationManager::kRotatingDeviceIDUniqueIDLength];
     994              :         MutableByteSpan rotatingDeviceIdUniqueIdSpan(rotatingDeviceIdUniqueId);
     995              : 
     996              :         ReturnErrorOnFailure(
     997              :             DeviceLayer::GetDeviceInstanceInfoProvider()->GetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueIdSpan));
     998              :         ReturnErrorOnFailure(
     999              :             DeviceLayer::ConfigurationMgr().GetLifetimeCounter(additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter));
    1000              :         additionalDataPayloadParams.rotatingDeviceIdUniqueId = rotatingDeviceIdUniqueIdSpan;
    1001              : 
    1002              :         uint8_t rotatingDeviceIdInternalBuffer[RotatingDeviceId::kMaxLength];
    1003              :         MutableByteSpan rotatingDeviceIdBufferTemp(rotatingDeviceIdInternalBuffer);
    1004              :         ReturnErrorOnFailure(AdditionalDataPayloadGenerator().generateRotatingDeviceIdAsBinary(additionalDataPayloadParams,
    1005              :                                                                                                rotatingDeviceIdBufferTemp));
    1006              : 
    1007              :         id.SetRotatingId(rotatingDeviceIdInternalBuffer, RotatingDeviceId::kMaxLength);
    1008              :     }
    1009              : #endif
    1010              : 
    1011              :     if (id.GetCdPort() == 0)
    1012              :     {
    1013              :         id.SetCdPort(mCdcListenPort);
    1014              :     }
    1015              : 
    1016              :     err = gUDCClient->SendUDCMessage(&mTransports, id, commissioner);
    1017              : 
    1018              :     if (err == CHIP_NO_ERROR)
    1019              :     {
    1020              :         ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Send UDC request success");
    1021              :     }
    1022              :     else
    1023              :     {
    1024              :         ChipLogError(AppServer, "Server::SendUserDirectedCommissioningRequest() Send UDC request failed, err: %" CHIP_ERROR_FORMAT,
    1025              :                      err.Format());
    1026              :     }
    1027              :     return err;
    1028              : }
    1029              : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
    1030              : 
    1031              : #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
    1032            1 : void Server::ResumeSubscriptions()
    1033              : {
    1034            1 :     CHIP_ERROR err = app::InteractionModelEngine::GetInstance()->ResumeSubscriptions();
    1035            2 :     if (err != CHIP_NO_ERROR)
    1036              :     {
    1037            0 :         ChipLogError(AppServer, "Error when trying to resume subscriptions : %" CHIP_ERROR_FORMAT, err.Format());
    1038              :     }
    1039            1 : }
    1040              : #endif
    1041              : 
    1042              : Credentials::IgnoreCertificateValidityPeriodPolicy Server::sDefaultCertValidityPolicy;
    1043              : 
    1044              : } // namespace chip
        

Generated by: LCOV version 2.0-1