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
|