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