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

Generated by: LCOV version 2.0-1