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