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