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