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