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