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 : Server Server::sServer;
102 :
103 : #if CHIP_CONFIG_ENABLE_SERVER_IM_EVENT
104 : #define CHIP_NUM_EVENT_LOGGING_BUFFERS 3
105 : static uint8_t sInfoEventBuffer[CHIP_DEVICE_CONFIG_EVENT_LOGGING_INFO_BUFFER_SIZE];
106 : static uint8_t sDebugEventBuffer[CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE];
107 : static uint8_t sCritEventBuffer[CHIP_DEVICE_CONFIG_EVENT_LOGGING_CRIT_BUFFER_SIZE];
108 : static PersistedCounter<EventNumber> sGlobalEventIdCounter;
109 : static app::CircularEventBuffer sLoggingBuffer[CHIP_NUM_EVENT_LOGGING_BUFFERS];
110 : #endif // CHIP_CONFIG_ENABLE_SERVER_IM_EVENT
111 :
112 1 : CHIP_ERROR Server::Init(const ServerInitParams & initParams)
113 : {
114 1 : ChipLogProgress(AppServer, "Server initializing...");
115 1 : assertChipStackLockedByCurrentThread();
116 :
117 1 : mInitTimestamp = System::SystemClock().GetMonotonicMicroseconds64();
118 :
119 1 : CASESessionManagerConfig caseSessionManagerConfig;
120 1 : DeviceLayer::DeviceInfoProvider * deviceInfoprovider = nullptr;
121 :
122 1 : mOperationalServicePort = initParams.operationalServicePort;
123 1 : mUserDirectedCommissioningPort = initParams.userDirectedCommissioningPort;
124 1 : mInterfaceId = initParams.interfaceId;
125 :
126 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
127 1 : auto tcpListenParams = TcpListenParameters(DeviceLayer::TCPEndPointManager())
128 1 : .SetAddressType(IPAddressType::kIPv6)
129 1 : .SetListenPort(mOperationalServicePort);
130 : #endif
131 :
132 1 : CHIP_ERROR err = CHIP_NO_ERROR;
133 :
134 1 : VerifyOrExit(initParams.persistentStorageDelegate != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
135 1 : VerifyOrExit(initParams.accessDelegate != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
136 1 : VerifyOrExit(initParams.aclStorage != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
137 1 : VerifyOrExit(initParams.groupDataProvider != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
138 1 : VerifyOrExit(initParams.sessionKeystore != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
139 1 : VerifyOrExit(initParams.operationalKeystore != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
140 1 : VerifyOrExit(initParams.opCertStore != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
141 1 : VerifyOrExit(initParams.reportScheduler != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
142 :
143 : // Extra log since this is an incremental requirement and existing applications may not be aware
144 1 : if (initParams.dataModelProvider == nullptr)
145 : {
146 0 : ChipLogError(AppServer, "Application Server requires a `initParams.dataModelProvider` value.");
147 0 : ChipLogError(AppServer, "For backwards compatibility, you likely can use `CodegenDataModelProviderInstance(...)`");
148 : }
149 :
150 1 : VerifyOrExit(initParams.dataModelProvider != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
151 :
152 : // TODO(16969): Remove Platform::MemoryInit() call from Server class, it belongs to outer code
153 1 : TEMPORARY_RETURN_IGNORED Platform::MemoryInit();
154 :
155 : // Initialize PersistentStorageDelegate-based storage
156 1 : mDeviceStorage = initParams.persistentStorageDelegate;
157 1 : mSessionResumptionStorage = initParams.sessionResumptionStorage;
158 1 : mSubscriptionResumptionStorage = initParams.subscriptionResumptionStorage;
159 1 : mOperationalKeystore = initParams.operationalKeystore;
160 1 : mOpCertStore = initParams.opCertStore;
161 1 : mSessionKeystore = initParams.sessionKeystore;
162 :
163 1 : if (initParams.certificateValidityPolicy)
164 : {
165 0 : mCertificateValidityPolicy.Init(initParams.certificateValidityPolicy);
166 : }
167 : else
168 : {
169 1 : mCertificateValidityPolicy.Init(&sDefaultCertValidityPolicy);
170 : }
171 :
172 : #if defined(CHIP_SUPPORT_ENABLE_STORAGE_API_AUDIT)
173 : VerifyOrDie(audit::ExecutePersistentStorageApiAudit(*mDeviceStorage));
174 : #endif
175 :
176 : #if defined(CHIP_SUPPORT_ENABLE_STORAGE_LOAD_TEST_AUDIT)
177 : VerifyOrDie(audit::ExecutePersistentStorageLoadTestAudit(*mDeviceStorage));
178 : #endif
179 :
180 : // Set up attribute persistence before we try to bring up the data model
181 : // handler.
182 1 : SuccessOrExit(err = mAttributePersister.Init(mDeviceStorage));
183 1 : SetSafeAttributePersistenceProvider(&mAttributePersister);
184 :
185 : {
186 1 : FabricTable::InitParams fabricTableInitParams;
187 1 : fabricTableInitParams.storage = mDeviceStorage;
188 1 : fabricTableInitParams.operationalKeystore = mOperationalKeystore;
189 1 : fabricTableInitParams.opCertStore = mOpCertStore;
190 :
191 1 : err = mFabrics.Init(fabricTableInitParams);
192 1 : SuccessOrExit(err);
193 : }
194 :
195 1 : SuccessOrExit(err = mAccessControl.Init(initParams.accessDelegate, sDeviceTypeResolver));
196 1 : Access::SetAccessControl(mAccessControl);
197 :
198 : #if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
199 : if (initParams.accessRestrictionProvider != nullptr)
200 : {
201 : mAccessControl.SetAccessRestrictionProvider(initParams.accessRestrictionProvider);
202 : }
203 : #endif
204 :
205 1 : mAclStorage = initParams.aclStorage;
206 1 : SuccessOrExit(err = mAclStorage->Init(*mDeviceStorage, mFabrics.begin(), mFabrics.end()));
207 :
208 1 : mGroupsProvider = initParams.groupDataProvider;
209 1 : SetGroupDataProvider(mGroupsProvider);
210 :
211 1 : mReportScheduler = initParams.reportScheduler;
212 :
213 1 : mTestEventTriggerDelegate = initParams.testEventTriggerDelegate;
214 1 : if (mTestEventTriggerDelegate == nullptr)
215 : {
216 0 : ChipLogProgress(AppServer, "WARNING: mTestEventTriggerDelegate is null");
217 : }
218 :
219 1 : deviceInfoprovider = DeviceLayer::GetDeviceInfoProvider();
220 1 : if (deviceInfoprovider)
221 : {
222 0 : deviceInfoprovider->SetStorageDelegate(mDeviceStorage);
223 : }
224 :
225 : // Init transport before operations with secure session mgr.
226 : //
227 : // The logic below expects that the IPv6 transport is at index 0. Keep that logic in sync with
228 : // this code.
229 2 : err = mTransports.Init(UdpListenParameters(DeviceLayer::UDPEndPointManager())
230 1 : .SetAddressType(IPAddressType::kIPv6)
231 1 : .SetListenPort(mOperationalServicePort)
232 1 : .SetNativeParams(initParams.endpointNativeParams)
233 : #if INET_CONFIG_ENABLE_IPV4
234 : ,
235 : // The logic below expects that the IPv4 transport, if enabled, is at
236 : // index 1. Keep that logic in sync with this code.
237 1 : UdpListenParameters(DeviceLayer::UDPEndPointManager())
238 1 : .SetAddressType(IPAddressType::kIPv4)
239 1 : .SetListenPort(mOperationalServicePort)
240 : #endif
241 : #if CONFIG_NETWORK_LAYER_BLE
242 : ,
243 1 : BleListenParameters(DeviceLayer::ConnectivityMgr().GetBleLayer())
244 : #endif
245 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
246 : ,
247 : tcpListenParams
248 : #if INET_CONFIG_ENABLE_IPV4
249 : ,
250 1 : TcpListenParameters(DeviceLayer::TCPEndPointManager())
251 1 : .SetAddressType(IPAddressType::kIPv4)
252 1 : .SetListenPort(mOperationalServicePort)
253 : #endif
254 : #endif
255 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
256 : ,
257 1 : Transport::WiFiPAFListenParameters(static_cast<Transport::WiFiPAFBase *>(
258 1 : DeviceLayer::ConnectivityMgr().GetWiFiPAF()->mWiFiPAFTransport))
259 : #endif
260 : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
261 : ,
262 : NfcListenParameters(nullptr)
263 : #endif
264 : );
265 :
266 1 : SuccessOrExit(err);
267 1 : err = mListener.Init(this);
268 1 : SuccessOrExit(err);
269 1 : mGroupsProvider->SetListener(&mListener);
270 :
271 : #if CONFIG_NETWORK_LAYER_BLE
272 1 : mBleLayer = DeviceLayer::ConnectivityMgr().GetBleLayer();
273 : #endif
274 1 : SuccessOrExit(err);
275 :
276 1 : err = mSessions.Init(&DeviceLayer::SystemLayer(), &mTransports, &mMessageCounterManager, mDeviceStorage, &GetFabricTable(),
277 1 : *mSessionKeystore);
278 1 : SuccessOrExit(err);
279 :
280 1 : err = mFabricDelegate.Init(this);
281 1 : SuccessOrExit(err);
282 1 : TEMPORARY_RETURN_IGNORED mFabrics.AddFabricDelegate(&mFabricDelegate);
283 :
284 1 : err = mExchangeMgr.Init(&mSessions);
285 1 : SuccessOrExit(err);
286 1 : err = mMessageCounterManager.Init(&mExchangeMgr);
287 1 : SuccessOrExit(err);
288 :
289 1 : err = mUnsolicitedStatusHandler.Init(&mExchangeMgr);
290 1 : SuccessOrExit(err);
291 :
292 1 : SuccessOrExit(err = mCommissioningWindowManager.Init(this));
293 1 : mCommissioningWindowManager.SetAppDelegate(initParams.appDelegate);
294 :
295 1 : app::DnssdServer::Instance().SetFabricTable(&mFabrics);
296 1 : app::DnssdServer::Instance().SetCommissioningModeProvider(&mCommissioningWindowManager);
297 :
298 1 : TEMPORARY_RETURN_IGNORED Dnssd::Resolver::Instance().Init(DeviceLayer::UDPEndPointManager());
299 :
300 : #if CHIP_CONFIG_ENABLE_SERVER_IM_EVENT
301 : // Initialize event logging subsystem
302 1 : err = sGlobalEventIdCounter.Init(mDeviceStorage, DefaultStorageKeyAllocator::IMEventNumber(),
303 : CHIP_DEVICE_CONFIG_EVENT_ID_COUNTER_EPOCH);
304 1 : SuccessOrExit(err);
305 :
306 : {
307 1 : app::LogStorageResources logStorageResources[] = {
308 : { &sDebugEventBuffer[0], sizeof(sDebugEventBuffer), app::PriorityLevel::Debug },
309 : { &sInfoEventBuffer[0], sizeof(sInfoEventBuffer), app::PriorityLevel::Info },
310 : { &sCritEventBuffer[0], sizeof(sCritEventBuffer), app::PriorityLevel::Critical }
311 : };
312 :
313 3 : err = app::EventManagement::GetInstance().Init(&mExchangeMgr, CHIP_NUM_EVENT_LOGGING_BUFFERS, &sLoggingBuffer[0],
314 : &logStorageResources[0], &sGlobalEventIdCounter,
315 1 : std::chrono::duration_cast<System::Clock::Milliseconds64>(mInitTimestamp),
316 1 : &app::InteractionModelEngine::GetInstance()->GetReportingEngine());
317 :
318 1 : SuccessOrExit(err);
319 : }
320 : #endif // CHIP_CONFIG_ENABLE_SERVER_IM_EVENT
321 :
322 : // SetDataModelProvider() initializes and starts the provider, which in turn
323 : // triggers the initialization of cluster implementations. This callsite is
324 : // critical because it ensures that cluster-level initialization occurs only
325 : // after all necessary low-level dependencies have been set up.
326 : //
327 : // Ordering guarantees:
328 : // 1) Provider initialization (under SetDataModelProvider) must happen after
329 : // SetSafeAttributePersistenceProvider to ensure the provider can leverage
330 : // the safe persistence provider for attribute persistence logic.
331 : // 2) It must occur after all low-level components that cluster implementations
332 : // might depend on have been initialized, as they rely on these components
333 : // during their own initialization.
334 : //
335 : // This remains the single point of entry to ensure that all cluster-level
336 : // initialization is performed in the correct order.
337 1 : app::InteractionModelEngine::GetInstance()->SetDataModelProvider(initParams.dataModelProvider);
338 :
339 : #if defined(CHIP_APP_USE_ECHO)
340 : err = InitEchoHandler(&mExchangeMgr);
341 : SuccessOrExit(err);
342 : #endif
343 :
344 1 : app::DnssdServer::Instance().SetSecuredIPv6Port(mTransports.GetTransport().GetImplAtIndex<0>().GetBoundPort());
345 : #if INET_CONFIG_ENABLE_IPV4
346 1 : app::DnssdServer::Instance().SetSecuredIPv4Port(mTransports.GetTransport().GetImplAtIndex<1>().GetBoundPort());
347 : #endif // INET_CONFIG_ENABLE_IPV4
348 :
349 1 : app::DnssdServer::Instance().SetUnsecuredPort(mUserDirectedCommissioningPort);
350 1 : app::DnssdServer::Instance().SetInterfaceId(mInterfaceId);
351 :
352 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
353 : // We set the ICDManager reference betfore calling the ICDManager init due to the init ordering limitations.
354 : // DnssdServer will use the default value initially and will update advertisement once ICDManager
355 : // init is called.
356 : app::DnssdServer::Instance().SetICDManager(&mICDManager);
357 : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
358 :
359 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
360 : // Enable the TCP Server based on the TCPListenParameters setting.
361 1 : app::DnssdServer::Instance().SetTCPServerEnabled(tcpListenParams.IsServerListenEnabled());
362 : #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
363 :
364 1 : if (GetFabricTable().FabricCount() != 0)
365 : {
366 : #if CONFIG_NETWORK_LAYER_BLE
367 : // The device is already commissioned, proactively disable BLE advertisement.
368 0 : ChipLogProgress(AppServer, "Fabric already commissioned. Disabling BLE advertisement");
369 0 : TEMPORARY_RETURN_IGNORED DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(false);
370 : #endif
371 : }
372 1 : else if (initParams.advertiseCommissionableIfNoFabrics)
373 : {
374 1 : SuccessOrExit(err = mCommissioningWindowManager.OpenBasicCommissioningWindow(initParams.discoveryTimeout));
375 : }
376 :
377 : // TODO @bzbarsky-apple @cecille Move to examples
378 : // ESP32 examples have a custom logic for enabling DNS-SD
379 : #if !CHIP_DEVICE_LAYER_TARGET_ESP32 && (!CHIP_DEVICE_LAYER_TARGET_AMEBA || !CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE)
380 : // StartServer only enables commissioning mode if device has not been commissioned
381 1 : app::DnssdServer::Instance().StartServer();
382 : #endif
383 :
384 : caseSessionManagerConfig = {
385 : .sessionInitParams = {
386 1 : .sessionManager = &mSessions,
387 1 : .sessionResumptionStorage = mSessionResumptionStorage,
388 : .certificateValidityPolicy = &mCertificateValidityPolicy,
389 1 : .exchangeMgr = &mExchangeMgr,
390 1 : .fabricTable = &mFabrics,
391 1 : .groupDataProvider = mGroupsProvider,
392 : // Don't provide an MRP local config, so each CASE initiation will use
393 : // the then-current value.
394 : .mrpLocalConfig = NullOptional,
395 : },
396 : .clientPool = &mCASEClientPool,
397 : .sessionSetupPool = &mSessionSetupPool,
398 1 : };
399 :
400 1 : err = mCASESessionManager.Init(&DeviceLayer::SystemLayer(), caseSessionManagerConfig);
401 1 : SuccessOrExit(err);
402 :
403 1 : err = mCASEServer.ListenForSessionEstablishment(&mExchangeMgr, &mSessions, &mFabrics, mSessionResumptionStorage,
404 : &mCertificateValidityPolicy, mGroupsProvider);
405 1 : SuccessOrExit(err);
406 :
407 1 : err = app::InteractionModelEngine::GetInstance()->Init(&mExchangeMgr, &GetFabricTable(), mReportScheduler, &mCASESessionManager,
408 : mSubscriptionResumptionStorage);
409 1 : SuccessOrExit(err);
410 :
411 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
412 : app::InteractionModelEngine::GetInstance()->SetICDManager(&mICDManager);
413 : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
414 :
415 : // ICD Init needs to be after data model init and InteractionModel Init
416 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
417 :
418 : // Register the ICDStateObservers.
419 : // Call register before init so that observers are notified of any state change during the init.
420 : // All observers are released at mICDManager.Shutdown(). They can be released individually with ReleaseObserver
421 : mICDManager.RegisterObserver(mReportScheduler);
422 : mICDManager.RegisterObserver(&app::DnssdServer::Instance());
423 :
424 : #if CHIP_CONFIG_ENABLE_ICD_CIP
425 : mICDManager.SetPersistentStorageDelegate(mDeviceStorage)
426 : .SetFabricTable(&GetFabricTable())
427 : .SetSymmetricKeyStore(mSessionKeystore)
428 : .SetExchangeManager(&mExchangeMgr)
429 : .SetSubscriptionsInfoProvider(app::InteractionModelEngine::GetInstance())
430 : .SetICDCheckInBackOffStrategy(initParams.icdCheckInBackOffStrategy);
431 :
432 : #endif // CHIP_CONFIG_ENABLE_ICD_CIP
433 : mICDManager.Init();
434 :
435 : // Register Test Event Trigger Handler
436 : if (mTestEventTriggerDelegate != nullptr)
437 : {
438 : TEMPORARY_RETURN_IGNORED mTestEventTriggerDelegate->AddHandler(&mICDManager);
439 : }
440 :
441 : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
442 :
443 : // This code is necessary to restart listening to existing groups after a reboot
444 : // Each manufacturer needs to validate that they can rejoin groups by placing this code at the appropriate location for them
445 : //
446 : // Thread LWIP devices using dedicated Inet endpoint implementations are excluded because they call this function from:
447 : // src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp
448 : #if !CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
449 1 : RejoinExistingMulticastGroups();
450 : #endif // !CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
451 :
452 : // Handle deferred clean-up of a previously armed fail-safe that occurred during FabricTable commit.
453 : // This is done at the very end since at the earlier time above when FabricTable::Init() is called,
454 : // the delegates could not have been registered, and the other systems were not initialized. By now,
455 : // everything is initialized, so we can do a deferred clean-up.
456 : {
457 1 : FabricIndex fabricIndexDeletedOnInit = GetFabricTable().GetDeletedFabricFromCommitMarker();
458 1 : if (fabricIndexDeletedOnInit != kUndefinedFabricIndex)
459 : {
460 0 : ChipLogError(AppServer, "FabricIndex 0x%x deleted due to restart while fail-safed. Processing a clean-up!",
461 : static_cast<unsigned>(fabricIndexDeletedOnInit));
462 :
463 : // Always pretend it was an add, since being in the middle of an update currently breaks
464 : // the validity of the fabric table. This is expected to be extremely infrequent, so
465 : // this "harsher" than usual clean-up is more likely to get us in a valid state for whatever
466 : // remains.
467 0 : const bool addNocCalled = true;
468 0 : const bool updateNocCalled = false;
469 0 : GetFailSafeContext().ScheduleFailSafeCleanup(fabricIndexDeletedOnInit, addNocCalled, updateNocCalled);
470 :
471 : // Schedule clearing of the commit marker to only occur after we have processed all fail-safe clean-up.
472 : // Because Matter runs a single event loop for all scheduled work, it will occur after the above has
473 : // taken place. If a reset occurs before we have cleaned everything up, the next boot will still
474 : // see the commit marker.
475 0 : TEMPORARY_RETURN_IGNORED PlatformMgr().ScheduleWork(
476 0 : [](intptr_t arg) {
477 0 : Server * server = reinterpret_cast<Server *>(arg);
478 0 : VerifyOrReturn(server != nullptr);
479 :
480 0 : server->GetFabricTable().ClearCommitMarker();
481 0 : ChipLogProgress(AppServer, "Cleared FabricTable pending commit marker");
482 : },
483 : reinterpret_cast<intptr_t>(this));
484 : }
485 : }
486 :
487 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT // support UDC port for commissioner declaration msgs
488 : mUdcTransportMgr = Platform::New<UdcTransportMgr>();
489 : ReturnErrorOnFailure(mUdcTransportMgr->Init(Transport::UdpListenParameters(DeviceLayer::UDPEndPointManager())
490 : .SetAddressType(Inet::IPAddressType::kIPv6)
491 : .SetListenPort(static_cast<uint16_t>(mCdcListenPort))
492 : #if INET_CONFIG_ENABLE_IPV4
493 : ,
494 : Transport::UdpListenParameters(DeviceLayer::UDPEndPointManager())
495 : .SetAddressType(Inet::IPAddressType::kIPv4)
496 : .SetListenPort(static_cast<uint16_t>(mCdcListenPort))
497 : #endif // INET_CONFIG_ENABLE_IPV4
498 : ));
499 :
500 : gUDCClient = Platform::New<Protocols::UserDirectedCommissioning::UserDirectedCommissioningClient>();
501 : mUdcTransportMgr->SetSessionManager(gUDCClient);
502 : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
503 :
504 1 : TEMPORARY_RETURN_IGNORED PlatformMgr().AddEventHandler(OnPlatformEventWrapper, reinterpret_cast<intptr_t>(this));
505 1 : PlatformMgr().HandleServerStarted();
506 :
507 1 : mIsDnssdReady = Dnssd::Resolver::Instance().IsInitialized();
508 1 : CheckServerReadyEvent();
509 :
510 1 : exit:
511 2 : if (err != CHIP_NO_ERROR)
512 : {
513 0 : ChipLogError(AppServer, "ERROR setting up transport: %" CHIP_ERROR_FORMAT, err.Format());
514 : }
515 : else
516 : {
517 : // NOTE: this log is scraped by the test harness.
518 1 : ChipLogProgress(AppServer, "Server Listening...");
519 : }
520 1 : return err;
521 : }
522 :
523 8 : void Server::OnPlatformEvent(const DeviceLayer::ChipDeviceEvent & event)
524 : {
525 8 : switch (event.Type)
526 : {
527 1 : case DeviceEventType::kDnssdInitialized:
528 : // Platform DNS-SD implementation uses kPlatformDnssdInitialized event to signal that it's ready.
529 1 : if (!mIsDnssdReady)
530 : {
531 0 : mIsDnssdReady = true;
532 0 : CheckServerReadyEvent();
533 : }
534 1 : break;
535 1 : case DeviceEventType::kServerReady:
536 : #if CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP
537 : // Only Trigger Check-In messages if we are not in the middle of a commissioning.
538 : // This check is only necessary for the first commissioiner since the kServerReady event
539 : // is triggered once we join the network.
540 : // We trigger Check-In messages before resuming subscriptions to avoid doing both.
541 : if (!mFailSafeContext.IsFailSafeArmed())
542 : {
543 : std::function<app::ICDManager::ShouldCheckInMsgsBeSentFunction> sendCheckInMessagesOnBootUp =
544 : std::bind(&Server::ShouldCheckInMsgsBeSentAtBootFunction, this, std::placeholders::_1, std::placeholders::_2);
545 : mICDManager.TriggerCheckInMessages(sendCheckInMessagesOnBootUp);
546 : }
547 : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP
548 : #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
549 1 : ResumeSubscriptions();
550 : #endif // CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
551 1 : break;
552 : #if CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
553 : case DeviceEventType::kThreadConnectivityChange:
554 : if (event.ThreadConnectivityChange.Result == kConnectivity_Established)
555 : {
556 : // Refresh Multicast listening
557 : ChipLogDetail(DeviceLayer, "Thread Attached updating Multicast address");
558 : RejoinExistingMulticastGroups();
559 : }
560 : break;
561 : #endif // CHIP_SYSTEM_CONFIG_USE_OPENTHREAD_ENDPOINT
562 6 : default:
563 6 : break;
564 : }
565 8 : }
566 :
567 1 : void Server::CheckServerReadyEvent()
568 : {
569 : // Check if all asynchronously initialized server components (currently, only DNS-SD)
570 : // are ready, and emit the 'server ready' event if so.
571 1 : if (mIsDnssdReady)
572 : {
573 1 : ChipLogProgress(AppServer, "Server initialization complete");
574 :
575 1 : ChipDeviceEvent event = { .Type = DeviceEventType::kServerReady };
576 1 : PlatformMgr().PostEventOrDie(&event);
577 : }
578 1 : }
579 :
580 8 : void Server::OnPlatformEventWrapper(const DeviceLayer::ChipDeviceEvent * event, intptr_t server)
581 : {
582 8 : reinterpret_cast<Server *>(server)->OnPlatformEvent(*event);
583 8 : }
584 :
585 1 : void Server::RejoinExistingMulticastGroups()
586 : {
587 1 : ChipLogProgress(AppServer, "Joining Multicast groups");
588 1 : CHIP_ERROR err = CHIP_NO_ERROR;
589 1 : for (const FabricInfo & fabric : mFabrics)
590 : {
591 0 : Credentials::GroupDataProvider::GroupInfo groupInfo;
592 :
593 0 : auto * iterator = mGroupsProvider->IterateGroupInfo(fabric.GetFabricIndex());
594 0 : if (iterator)
595 : {
596 : // GroupDataProvider was able to allocate rescources for an iterator
597 0 : while (iterator->Next(groupInfo))
598 : {
599 0 : err = mTransports.MulticastGroupJoinLeave(
600 0 : Transport::PeerAddress::Multicast(fabric.GetFabricId(), groupInfo.group_id), true);
601 0 : if (err != CHIP_NO_ERROR)
602 : {
603 0 : ChipLogError(AppServer, "Error when trying to join Group %u of fabric index %u : %" CHIP_ERROR_FORMAT,
604 : groupInfo.group_id, fabric.GetFabricIndex(), err.Format());
605 :
606 : // We assume the failure is caused by a network issue or a lack of rescources; neither of which will be solved
607 : // before the next join. Exit the loop to save rescources.
608 0 : iterator->Release();
609 0 : return;
610 : }
611 : }
612 :
613 0 : iterator->Release();
614 : }
615 : }
616 : }
617 :
618 : #if CHIP_CONFIG_ENABLE_ICD_CIP
619 : bool Server::ShouldCheckInMsgsBeSentAtBootFunction(FabricIndex aFabricIndex, NodeId subjectID)
620 : {
621 : #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
622 : // If at least one registration has a persisted entry, do not send Check-In message.
623 : // The resumption of the persisted subscription will serve the same function a check-in would have served.
624 : return !app::InteractionModelEngine::GetInstance()->SubjectHasPersistedSubscription(aFabricIndex, subjectID);
625 : #else
626 : return true;
627 : #endif // CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
628 : }
629 : #endif // CHIP_CONFIG_ENABLE_ICD_CIP
630 :
631 0 : void Server::GenerateShutDownEvent()
632 : {
633 0 : TEMPORARY_RETURN_IGNORED PlatformMgr().ScheduleWork([](intptr_t) { PlatformMgr().HandleServerShuttingDown(); });
634 0 : }
635 :
636 1 : void Server::PostFactoryResetEvent()
637 : {
638 1 : DeviceLayer::ChipDeviceEvent event{ .Type = DeviceLayer::DeviceEventType::kFactoryReset };
639 :
640 1 : CHIP_ERROR error = DeviceLayer::PlatformMgr().PostEvent(&event);
641 2 : if (error != CHIP_NO_ERROR)
642 : {
643 0 : ChipLogError(AppServer, "Posting kFactoryReset event failed with %" CHIP_ERROR_FORMAT, error.Format());
644 : }
645 1 : }
646 :
647 1 : void Server::ScheduleFactoryReset()
648 : {
649 1 : PostFactoryResetEvent();
650 :
651 1 : TEMPORARY_RETURN_IGNORED PlatformMgr().ScheduleWork([](intptr_t) {
652 : // Delete all fabrics and emit Leave event.
653 1 : GetInstance().GetFabricTable().DeleteAllFabrics();
654 1 : PlatformMgr().HandleServerShuttingDown();
655 1 : ConfigurationMgr().InitiateFactoryReset();
656 1 : });
657 1 : }
658 :
659 1 : void Server::Shutdown()
660 : {
661 1 : assertChipStackLockedByCurrentThread();
662 1 : PlatformMgr().RemoveEventHandler(OnPlatformEventWrapper, 0);
663 1 : mCASEServer.Shutdown();
664 1 : mCASESessionManager.Shutdown();
665 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
666 : app::DnssdServer::Instance().SetICDManager(nullptr);
667 : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
668 1 : app::DnssdServer::Instance().SetCommissioningModeProvider(nullptr);
669 1 : Dnssd::ServiceAdvertiser::Instance().Shutdown();
670 :
671 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
672 : if (mUdcTransportMgr != nullptr)
673 : {
674 : Platform::Delete(mUdcTransportMgr);
675 : mUdcTransportMgr = nullptr;
676 : }
677 : if (gUDCClient != nullptr)
678 : {
679 : Platform::Delete(gUDCClient);
680 : gUDCClient = nullptr;
681 : }
682 : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
683 :
684 1 : Dnssd::Resolver::Instance().Shutdown();
685 1 : app::InteractionModelEngine::GetInstance()->Shutdown();
686 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
687 : app::InteractionModelEngine::GetInstance()->SetICDManager(nullptr);
688 : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
689 : // Shut down any remaining sessions (and hence exchanges) before we do any
690 : // futher teardown. CASE handshakes have been shut down already via
691 : // shutting down mCASESessionManager and mCASEServer above; shutting
692 : // down mCommissioningWindowManager will shut down any PASE handshakes we
693 : // have going on.
694 1 : mSessions.ExpireAllSecureSessions();
695 1 : mCommissioningWindowManager.Shutdown();
696 1 : mMessageCounterManager.Shutdown();
697 1 : mExchangeMgr.Shutdown();
698 1 : mSessions.Shutdown();
699 1 : mTransports.Close();
700 1 : mAccessControl.Finish();
701 1 : Access::ResetAccessControlToDefault();
702 1 : Credentials::SetGroupDataProvider(nullptr);
703 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
704 : // Remove Test Event Trigger Handler
705 : if (mTestEventTriggerDelegate != nullptr)
706 : {
707 : mTestEventTriggerDelegate->RemoveHandler(&mICDManager);
708 : }
709 : mICDManager.Shutdown();
710 : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
711 :
712 : // TODO(16969): Remove chip::Platform::MemoryInit() call from Server class, it belongs to outer code
713 1 : chip::Platform::MemoryShutdown();
714 1 : }
715 :
716 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
717 : // NOTE: UDC client is located in Server.cpp because it really only makes sense
718 : // to send UDC from a Matter device. The UDC message payload needs to include the device's
719 : // randomly generated service name.
720 : CHIP_ERROR Server::SendUserDirectedCommissioningRequest(Transport::PeerAddress commissioner,
721 : Protocols::UserDirectedCommissioning::IdentificationDeclaration & id)
722 : {
723 : ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest()");
724 :
725 : CHIP_ERROR err;
726 :
727 : // only populate fields left blank by the client
728 : if (strlen(id.GetInstanceName()) == 0)
729 : {
730 : ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Instance Name not known");
731 : char nameBuffer[Dnssd::Commission::kInstanceNameMaxLength + 1];
732 : err = app::DnssdServer::Instance().GetCommissionableInstanceName(nameBuffer, sizeof(nameBuffer));
733 : if (err != CHIP_NO_ERROR)
734 : {
735 : ChipLogError(
736 : AppServer,
737 : "Server::SendUserDirectedCommissioningRequest() Failed to get mdns instance name error: %" CHIP_ERROR_FORMAT,
738 : err.Format());
739 : return err;
740 : }
741 : id.SetInstanceName(nameBuffer);
742 : ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Instance Name set to %s", nameBuffer);
743 : }
744 :
745 : if (id.GetVendorId() == 0)
746 : {
747 : uint16_t vendorId = 0;
748 : if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(vendorId) != CHIP_NO_ERROR)
749 : {
750 : ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Vendor ID not known");
751 : }
752 : else
753 : {
754 : id.SetVendorId(vendorId);
755 : }
756 : }
757 :
758 : if (id.GetProductId() == 0)
759 : {
760 : uint16_t productId = 0;
761 : if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetProductId(productId) != CHIP_NO_ERROR)
762 : {
763 : ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Product ID not known");
764 : }
765 : else
766 : {
767 : id.SetProductId(productId);
768 : }
769 : }
770 :
771 : if (strlen(id.GetDeviceName()) == 0)
772 : {
773 : char deviceName[Dnssd::kKeyDeviceNameMaxLength + 1] = {};
774 : if (!DeviceLayer::ConfigurationMgr().IsCommissionableDeviceNameEnabled() ||
775 : DeviceLayer::ConfigurationMgr().GetCommissionableDeviceName(deviceName, sizeof(deviceName)) != CHIP_NO_ERROR)
776 : {
777 : ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Device Name not known");
778 : }
779 : else
780 : {
781 : id.SetDeviceName(deviceName);
782 : }
783 : }
784 :
785 : #if CHIP_ENABLE_ROTATING_DEVICE_ID && defined(CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID)
786 : if (id.GetRotatingIdLength() == 0)
787 : {
788 : AdditionalDataPayloadGeneratorParams additionalDataPayloadParams;
789 : uint8_t rotatingDeviceIdUniqueId[DeviceLayer::ConfigurationManager::kRotatingDeviceIDUniqueIDLength];
790 : MutableByteSpan rotatingDeviceIdUniqueIdSpan(rotatingDeviceIdUniqueId);
791 :
792 : ReturnErrorOnFailure(
793 : DeviceLayer::GetDeviceInstanceInfoProvider()->GetRotatingDeviceIdUniqueId(rotatingDeviceIdUniqueIdSpan));
794 : ReturnErrorOnFailure(
795 : DeviceLayer::ConfigurationMgr().GetLifetimeCounter(additionalDataPayloadParams.rotatingDeviceIdLifetimeCounter));
796 : additionalDataPayloadParams.rotatingDeviceIdUniqueId = rotatingDeviceIdUniqueIdSpan;
797 :
798 : uint8_t rotatingDeviceIdInternalBuffer[RotatingDeviceId::kMaxLength];
799 : MutableByteSpan rotatingDeviceIdBufferTemp(rotatingDeviceIdInternalBuffer);
800 : ReturnErrorOnFailure(AdditionalDataPayloadGenerator().generateRotatingDeviceIdAsBinary(additionalDataPayloadParams,
801 : rotatingDeviceIdBufferTemp));
802 :
803 : id.SetRotatingId(rotatingDeviceIdInternalBuffer, RotatingDeviceId::kMaxLength);
804 : }
805 : #endif
806 :
807 : if (id.GetCdPort() == 0)
808 : {
809 : id.SetCdPort(mCdcListenPort);
810 : }
811 :
812 : err = gUDCClient->SendUDCMessage(&mTransports, id, commissioner);
813 :
814 : if (err == CHIP_NO_ERROR)
815 : {
816 : ChipLogDetail(AppServer, "Server::SendUserDirectedCommissioningRequest() Send UDC request success");
817 : }
818 : else
819 : {
820 : ChipLogError(AppServer, "Server::SendUserDirectedCommissioningRequest() Send UDC request failed, err: %" CHIP_ERROR_FORMAT,
821 : err.Format());
822 : }
823 : return err;
824 : }
825 : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
826 :
827 : #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
828 1 : void Server::ResumeSubscriptions()
829 : {
830 1 : CHIP_ERROR err = app::InteractionModelEngine::GetInstance()->ResumeSubscriptions();
831 2 : if (err != CHIP_NO_ERROR)
832 : {
833 0 : ChipLogError(AppServer, "Error when trying to resume subscriptions : %" CHIP_ERROR_FORMAT, err.Format());
834 : }
835 1 : }
836 : #endif
837 :
838 : Credentials::IgnoreCertificateValidityPeriodPolicy Server::sDefaultCertValidityPolicy;
839 :
840 : } // namespace chip
|