Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021 Project CHIP Authors
4 : * All rights reserved.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : /**
20 : * @file
21 : * Implementation of CHIP Device Controller Factory, a utility/manager class
22 : * that vends Controller objects
23 : */
24 :
25 : #include <controller/CHIPDeviceControllerFactory.h>
26 :
27 : #include <app/InteractionModelEngine.h>
28 : #include <app/OperationalSessionSetup.h>
29 : #include <app/TimerDelegates.h>
30 : #include <app/reporting/ReportSchedulerImpl.h>
31 : #include <app/util/DataModelHandler.h>
32 : #include <lib/core/ErrorStr.h>
33 : #include <messaging/ReliableMessageProtocolConfig.h>
34 :
35 : #if CONFIG_DEVICE_LAYER
36 : #include <platform/CHIPDeviceLayer.h>
37 : #include <platform/ConfigurationManager.h>
38 : #endif
39 :
40 : #include <app/server/Dnssd.h>
41 : #include <protocols/secure_channel/CASEServer.h>
42 : #include <protocols/secure_channel/SimpleSessionResumptionStorage.h>
43 :
44 : using namespace chip::Inet;
45 : using namespace chip::System;
46 : using namespace chip::Credentials;
47 :
48 : namespace chip {
49 : namespace Controller {
50 :
51 0 : CHIP_ERROR DeviceControllerFactory::Init(FactoryInitParams params)
52 : {
53 :
54 : // SystemState is only set the first time init is called, after that it is managed
55 : // internally. If SystemState is set then init has already completed.
56 0 : if (mSystemState != nullptr)
57 : {
58 0 : ChipLogError(Controller, "Device Controller Factory already initialized...");
59 0 : return CHIP_NO_ERROR;
60 : }
61 :
62 : // Save our initialization state that we can't recover later from a
63 : // created-but-shut-down system state.
64 0 : mListenPort = params.listenPort;
65 0 : mInterfaceId = params.interfaceId;
66 0 : mFabricIndependentStorage = params.fabricIndependentStorage;
67 0 : mOperationalKeystore = params.operationalKeystore;
68 0 : mOpCertStore = params.opCertStore;
69 0 : mCertificateValidityPolicy = params.certificateValidityPolicy;
70 0 : mSessionResumptionStorage = params.sessionResumptionStorage;
71 0 : mEnableServerInteractions = params.enableServerInteractions;
72 :
73 : // Initialize the system state. Note that it is left in a somewhat
74 : // special state where it is initialized, but has a ref count of 0.
75 0 : CHIP_ERROR err = InitSystemState(params);
76 :
77 0 : return err;
78 : }
79 :
80 0 : CHIP_ERROR DeviceControllerFactory::ReinitSystemStateIfNecessary()
81 : {
82 0 : VerifyOrReturnError(mSystemState != nullptr, CHIP_ERROR_INCORRECT_STATE);
83 0 : VerifyOrReturnError(mSystemState->IsShutDown(), CHIP_NO_ERROR);
84 :
85 0 : FactoryInitParams params;
86 0 : params.systemLayer = mSystemState->SystemLayer();
87 0 : params.udpEndPointManager = mSystemState->UDPEndPointManager();
88 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
89 0 : params.tcpEndPointManager = mSystemState->TCPEndPointManager();
90 : #endif
91 : #if CONFIG_NETWORK_LAYER_BLE
92 0 : params.bleLayer = mSystemState->BleLayer();
93 : #endif
94 0 : params.listenPort = mListenPort;
95 0 : params.interfaceId = mInterfaceId;
96 0 : params.fabricIndependentStorage = mFabricIndependentStorage;
97 0 : params.enableServerInteractions = mEnableServerInteractions;
98 0 : params.groupDataProvider = mSystemState->GetGroupDataProvider();
99 0 : params.sessionKeystore = mSystemState->GetSessionKeystore();
100 0 : params.fabricTable = mSystemState->Fabrics();
101 0 : params.operationalKeystore = mOperationalKeystore;
102 0 : params.opCertStore = mOpCertStore;
103 0 : params.certificateValidityPolicy = mCertificateValidityPolicy;
104 0 : params.sessionResumptionStorage = mSessionResumptionStorage;
105 :
106 : // re-initialization keeps any previously initialized values. The only place where
107 : // a provider exists is in the InteractionModelEngine, so just say "keep it as is".
108 0 : params.dataModelProvider = app::InteractionModelEngine::GetInstance()->GetDataModelProvider();
109 :
110 0 : return InitSystemState(params);
111 : }
112 :
113 0 : CHIP_ERROR DeviceControllerFactory::InitSystemState(FactoryInitParams params)
114 : {
115 0 : if (mSystemState != nullptr)
116 : {
117 0 : Platform::Delete(mSystemState);
118 0 : mSystemState = nullptr;
119 : }
120 :
121 0 : DeviceControllerSystemStateParams stateParams;
122 : #if CONFIG_DEVICE_LAYER
123 0 : ReturnErrorOnFailure(DeviceLayer::PlatformMgr().InitChipStack());
124 :
125 0 : stateParams.systemLayer = &DeviceLayer::SystemLayer();
126 0 : stateParams.udpEndPointManager = DeviceLayer::UDPEndPointManager();
127 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
128 0 : stateParams.tcpEndPointManager = DeviceLayer::TCPEndPointManager();
129 : #endif
130 : #else
131 : stateParams.systemLayer = params.systemLayer;
132 : stateParams.tcpEndPointManager = params.tcpEndPointManager;
133 : stateParams.udpEndPointManager = params.udpEndPointManager;
134 : ChipLogError(Controller, "Warning: Device Controller Factory should be with a CHIP Device Layer...");
135 : #endif // CONFIG_DEVICE_LAYER
136 :
137 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
138 0 : auto tcpListenParams = Transport::TcpListenParameters(stateParams.tcpEndPointManager)
139 0 : .SetAddressType(IPAddressType::kIPv6)
140 0 : .SetListenPort(params.listenPort)
141 0 : .SetServerListenEnabled(false); // Initialize as a TCP Client
142 : #endif
143 :
144 0 : if (params.dataModelProvider == nullptr)
145 : {
146 0 : ChipLogError(AppServer, "Device Controller Factory requires a `dataModelProvider` value.");
147 0 : ChipLogError(AppServer, "For backwards compatibility, you likely can use `CodegenDataModelProviderInstance(...)`");
148 : }
149 :
150 0 : VerifyOrReturnError(params.dataModelProvider != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
151 0 : VerifyOrReturnError(stateParams.systemLayer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
152 0 : VerifyOrReturnError(stateParams.udpEndPointManager != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
153 :
154 : // OperationalCertificateStore needs to be provided to init the fabric table if fabric table is
155 : // not provided wholesale.
156 0 : VerifyOrReturnError((params.fabricTable != nullptr) || (params.opCertStore != nullptr), CHIP_ERROR_INVALID_ARGUMENT);
157 0 : VerifyOrReturnError(params.sessionKeystore != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
158 :
159 : #if CONFIG_NETWORK_LAYER_BLE
160 : #if CONFIG_DEVICE_LAYER
161 0 : stateParams.bleLayer = DeviceLayer::ConnectivityMgr().GetBleLayer();
162 : #else
163 : stateParams.bleLayer = params.bleLayer;
164 : #endif // CONFIG_DEVICE_LAYER
165 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
166 0 : stateParams.wifipaf_layer = params.wifipaf_layer;
167 : #endif
168 0 : VerifyOrReturnError(stateParams.bleLayer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
169 : #endif
170 :
171 0 : stateParams.transportMgr = chip::Platform::New<DeviceTransportMgr>();
172 :
173 : //
174 : // The logic below expects IPv6 to be at index 0 of this tuple. Keep that logic in sync with
175 : // this code.
176 : //
177 0 : ReturnErrorOnFailure(stateParams.transportMgr->Init(Transport::UdpListenParameters(stateParams.udpEndPointManager)
178 : .SetAddressType(Inet::IPAddressType::kIPv6)
179 : .SetListenPort(params.listenPort)
180 : #if INET_CONFIG_ENABLE_IPV4
181 : ,
182 : //
183 : // The logic below expects IPv4 to be at index 1 of this tuple,
184 : // if it's enabled. Keep that logic in sync with this code.
185 : //
186 : Transport::UdpListenParameters(stateParams.udpEndPointManager)
187 : .SetAddressType(Inet::IPAddressType::kIPv4)
188 : .SetListenPort(params.listenPort)
189 : #endif
190 : #if CONFIG_NETWORK_LAYER_BLE
191 : ,
192 : Transport::BleListenParameters(stateParams.bleLayer)
193 : #endif
194 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
195 : ,
196 : tcpListenParams
197 : #if INET_CONFIG_ENABLE_IPV4
198 : ,
199 : Transport::TcpListenParameters(stateParams.tcpEndPointManager)
200 : .SetAddressType(Inet::IPAddressType::kIPv4)
201 : .SetListenPort(params.listenPort)
202 : .SetServerListenEnabled(false)
203 : #endif
204 : #endif
205 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
206 : ,
207 : Transport::WiFiPAFListenParameters()
208 : #endif
209 : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
210 : ,
211 : Transport::NfcListenParameters(nullptr)
212 : #endif
213 : ));
214 :
215 : // TODO(#16231): All the new'ed state above/below in this method is never properly released or null-checked!
216 0 : stateParams.sessionMgr = chip::Platform::New<SessionManager>();
217 0 : stateParams.certificateValidityPolicy = params.certificateValidityPolicy;
218 0 : stateParams.unsolicitedStatusHandler = Platform::New<Protocols::SecureChannel::UnsolicitedStatusHandler>();
219 0 : stateParams.exchangeMgr = chip::Platform::New<Messaging::ExchangeManager>();
220 0 : stateParams.messageCounterManager = chip::Platform::New<secure_channel::MessageCounterManager>();
221 0 : stateParams.groupDataProvider = params.groupDataProvider;
222 0 : stateParams.timerDelegate = chip::Platform::New<chip::app::DefaultTimerDelegate>();
223 0 : stateParams.reportScheduler = chip::Platform::New<app::reporting::ReportSchedulerImpl>(stateParams.timerDelegate);
224 0 : stateParams.sessionKeystore = params.sessionKeystore;
225 0 : stateParams.bdxTransferServer = chip::Platform::New<bdx::BDXTransferServer>();
226 :
227 : // if no fabricTable was provided, create one and track it in stateParams for cleanup
228 0 : stateParams.fabricTable = params.fabricTable;
229 :
230 0 : FabricTable * tempFabricTable = nullptr;
231 0 : if (stateParams.fabricTable == nullptr)
232 : {
233 : // TODO(#16231): Previously (and still) the objects new-ed in this entire method seem expected to last forever...
234 0 : auto newFabricTable = Platform::MakeUnique<FabricTable>();
235 0 : VerifyOrReturnError(newFabricTable, CHIP_ERROR_NO_MEMORY);
236 :
237 0 : FabricTable::InitParams fabricTableInitParams;
238 0 : fabricTableInitParams.storage = params.fabricIndependentStorage;
239 0 : fabricTableInitParams.operationalKeystore = params.operationalKeystore;
240 0 : fabricTableInitParams.opCertStore = params.opCertStore;
241 0 : ReturnErrorOnFailure(newFabricTable->Init(fabricTableInitParams));
242 0 : stateParams.fabricTable = newFabricTable.release();
243 0 : tempFabricTable = stateParams.fabricTable;
244 0 : }
245 :
246 : SessionResumptionStorage * sessionResumptionStorage;
247 0 : if (params.sessionResumptionStorage == nullptr)
248 : {
249 0 : auto ownedSessionResumptionStorage = chip::Platform::MakeUnique<SimpleSessionResumptionStorage>();
250 0 : ReturnErrorOnFailure(ownedSessionResumptionStorage->Init(params.fabricIndependentStorage));
251 0 : stateParams.ownedSessionResumptionStorage = std::move(ownedSessionResumptionStorage);
252 0 : stateParams.externalSessionResumptionStorage = nullptr;
253 0 : sessionResumptionStorage = stateParams.ownedSessionResumptionStorage.get();
254 0 : }
255 : else
256 : {
257 0 : stateParams.ownedSessionResumptionStorage = nullptr;
258 0 : stateParams.externalSessionResumptionStorage = params.sessionResumptionStorage;
259 0 : sessionResumptionStorage = stateParams.externalSessionResumptionStorage;
260 : }
261 :
262 0 : auto delegate = chip::Platform::MakeUnique<ControllerFabricDelegate>();
263 0 : ReturnErrorOnFailure(delegate->Init(sessionResumptionStorage, stateParams.groupDataProvider));
264 0 : stateParams.fabricTableDelegate = delegate.get();
265 0 : ReturnErrorOnFailure(stateParams.fabricTable->AddFabricDelegate(stateParams.fabricTableDelegate));
266 0 : delegate.release();
267 :
268 0 : ReturnErrorOnFailure(stateParams.sessionMgr->Init(stateParams.systemLayer, stateParams.transportMgr,
269 : stateParams.messageCounterManager, params.fabricIndependentStorage,
270 : stateParams.fabricTable, *stateParams.sessionKeystore));
271 0 : ReturnErrorOnFailure(stateParams.exchangeMgr->Init(stateParams.sessionMgr));
272 0 : ReturnErrorOnFailure(stateParams.messageCounterManager->Init(stateParams.exchangeMgr));
273 0 : ReturnErrorOnFailure(stateParams.unsolicitedStatusHandler->Init(stateParams.exchangeMgr));
274 0 : ReturnErrorOnFailure(stateParams.bdxTransferServer->Init(stateParams.systemLayer, stateParams.exchangeMgr));
275 :
276 0 : chip::app::InteractionModelEngine * interactionModelEngine = chip::app::InteractionModelEngine::GetInstance();
277 :
278 : // Initialize the data model now that everything cluster implementations might
279 : // depend on is initalized.
280 0 : interactionModelEngine->SetDataModelProvider(params.dataModelProvider);
281 :
282 0 : ReturnErrorOnFailure(Dnssd::Resolver::Instance().Init(stateParams.udpEndPointManager));
283 :
284 0 : if (params.enableServerInteractions)
285 : {
286 0 : stateParams.caseServer = chip::Platform::New<CASEServer>();
287 :
288 : // Enable listening for session establishment messages.
289 0 : ReturnErrorOnFailure(stateParams.caseServer->ListenForSessionEstablishment(
290 : stateParams.exchangeMgr, stateParams.sessionMgr, stateParams.fabricTable, sessionResumptionStorage,
291 : stateParams.certificateValidityPolicy, stateParams.groupDataProvider));
292 :
293 : // Our IPv6 transport is at index 0.
294 0 : app::DnssdServer::Instance().SetSecuredIPv6Port(
295 0 : stateParams.transportMgr->GetTransport().GetImplAtIndex<0>().GetBoundPort());
296 :
297 : #if INET_CONFIG_ENABLE_IPV4
298 : // If enabled, our IPv4 transport is at index 1.
299 0 : app::DnssdServer::Instance().SetSecuredIPv4Port(
300 0 : stateParams.transportMgr->GetTransport().GetImplAtIndex<1>().GetBoundPort());
301 : #endif // INET_CONFIG_ENABLE_IPV4
302 :
303 0 : if (params.interfaceId)
304 : {
305 0 : app::DnssdServer::Instance().SetInterfaceId(*params.interfaceId);
306 : }
307 :
308 : //
309 : // TODO: This is a hack to workaround the fact that we have a bi-polar stack that has controller and server modalities that
310 : // are mutually exclusive in terms of initialization of key stack singletons. Consequently, DnssdServer accesses
311 : // Server::GetInstance().GetFabricTable() to access the fabric table, but we don't want to do that when we're initializing
312 : // the controller logic since the factory here has its own fabric table.
313 : //
314 : // Consequently, reach in set the fabric table pointer to point to the right version.
315 : //
316 0 : app::DnssdServer::Instance().SetFabricTable(stateParams.fabricTable);
317 :
318 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
319 : // Disable the TCP Server based on the TCPListenParameters setting.
320 0 : app::DnssdServer::Instance().SetTCPServerEnabled(tcpListenParams.IsServerListenEnabled());
321 : #endif
322 : }
323 :
324 0 : stateParams.sessionSetupPool = Platform::New<DeviceControllerSystemStateParams::SessionSetupPool>();
325 0 : stateParams.caseClientPool = Platform::New<DeviceControllerSystemStateParams::CASEClientPool>();
326 :
327 : CASEClientInitParams sessionInitParams = {
328 0 : .sessionManager = stateParams.sessionMgr,
329 : .sessionResumptionStorage = sessionResumptionStorage,
330 0 : .certificateValidityPolicy = stateParams.certificateValidityPolicy,
331 0 : .exchangeMgr = stateParams.exchangeMgr,
332 0 : .fabricTable = stateParams.fabricTable,
333 0 : .groupDataProvider = stateParams.groupDataProvider,
334 : // Don't provide an MRP local config, so each CASE initiation will use
335 : // the then-current value.
336 : .mrpLocalConfig = NullOptional,
337 0 : };
338 :
339 : CASESessionManagerConfig sessionManagerConfig = {
340 : .sessionInitParams = sessionInitParams,
341 0 : .clientPool = stateParams.caseClientPool,
342 0 : .sessionSetupPool = stateParams.sessionSetupPool,
343 0 : };
344 :
345 : // TODO: Need to be able to create a CASESessionManagerConfig here!
346 0 : stateParams.caseSessionManager = Platform::New<CASESessionManager>();
347 0 : ReturnErrorOnFailure(stateParams.caseSessionManager->Init(stateParams.systemLayer, sessionManagerConfig));
348 :
349 0 : ReturnErrorOnFailure(interactionModelEngine->Init(stateParams.exchangeMgr, stateParams.fabricTable, stateParams.reportScheduler,
350 : stateParams.caseSessionManager));
351 :
352 : // store the system state
353 0 : mSystemState = chip::Platform::New<DeviceControllerSystemState>(std::move(stateParams));
354 0 : mSystemState->SetTempFabricTable(tempFabricTable, params.enableServerInteractions);
355 0 : ChipLogDetail(Controller, "System State Initialized...");
356 0 : return CHIP_NO_ERROR;
357 0 : }
358 :
359 0 : void DeviceControllerFactory::PopulateInitParams(ControllerInitParams & controllerParams, const SetupParams & params)
360 : {
361 0 : controllerParams.operationalCredentialsDelegate = params.operationalCredentialsDelegate;
362 0 : controllerParams.operationalKeypair = params.operationalKeypair;
363 0 : controllerParams.hasExternallyOwnedOperationalKeypair = params.hasExternallyOwnedOperationalKeypair;
364 0 : controllerParams.controllerNOC = params.controllerNOC;
365 0 : controllerParams.controllerICAC = params.controllerICAC;
366 0 : controllerParams.controllerRCAC = params.controllerRCAC;
367 0 : controllerParams.permitMultiControllerFabrics = params.permitMultiControllerFabrics;
368 0 : controllerParams.removeFromFabricTableOnShutdown = params.removeFromFabricTableOnShutdown;
369 0 : controllerParams.deleteFromFabricTableOnShutdown = params.deleteFromFabricTableOnShutdown;
370 :
371 0 : controllerParams.systemState = mSystemState;
372 0 : controllerParams.controllerVendorId = params.controllerVendorId;
373 :
374 0 : controllerParams.enableServerInteractions = params.enableServerInteractions;
375 0 : if (params.fabricIndex.HasValue())
376 : {
377 0 : controllerParams.fabricIndex.SetValue(params.fabricIndex.Value());
378 : }
379 0 : }
380 :
381 0 : void DeviceControllerFactory::ControllerInitialized(const DeviceController & controller)
382 : {
383 0 : if (mEnableServerInteractions && controller.GetFabricIndex() != kUndefinedFabricIndex)
384 : {
385 : // Restart DNS-SD advertising, because initialization of this controller could
386 : // have modified whether a particular fabric identity should be
387 : // advertised. Just calling AdvertiseOperational() is not good enough
388 : // here, since we might be removing advertising.
389 0 : app::DnssdServer::Instance().StartServer();
390 : }
391 0 : }
392 :
393 0 : CHIP_ERROR DeviceControllerFactory::SetupController(SetupParams params, DeviceController & controller)
394 : {
395 0 : VerifyOrReturnError(params.controllerVendorId != VendorId::Unspecified, CHIP_ERROR_INVALID_ARGUMENT);
396 0 : ReturnErrorOnFailure(ReinitSystemStateIfNecessary());
397 :
398 0 : ControllerInitParams controllerParams;
399 0 : PopulateInitParams(controllerParams, params);
400 :
401 0 : CHIP_ERROR err = controller.Init(controllerParams);
402 :
403 0 : if (err == CHIP_NO_ERROR)
404 : {
405 0 : ControllerInitialized(controller);
406 : }
407 :
408 0 : return err;
409 : }
410 :
411 0 : CHIP_ERROR DeviceControllerFactory::SetupCommissioner(SetupParams params, DeviceCommissioner & commissioner)
412 : {
413 0 : VerifyOrReturnError(params.controllerVendorId != VendorId::Unspecified, CHIP_ERROR_INVALID_ARGUMENT);
414 0 : ReturnErrorOnFailure(ReinitSystemStateIfNecessary());
415 :
416 0 : CommissionerInitParams commissionerParams;
417 :
418 : // PopulateInitParams works against ControllerInitParams base class of CommissionerInitParams only
419 0 : PopulateInitParams(commissionerParams, params);
420 :
421 : // Set commissioner-specific fields not in ControllerInitParams
422 0 : commissionerParams.pairingDelegate = params.pairingDelegate;
423 0 : commissionerParams.defaultCommissioner = params.defaultCommissioner;
424 0 : commissionerParams.deviceAttestationVerifier = params.deviceAttestationVerifier;
425 :
426 0 : CHIP_ERROR err = commissioner.Init(commissionerParams);
427 :
428 0 : if (err == CHIP_NO_ERROR)
429 : {
430 0 : ControllerInitialized(commissioner);
431 : }
432 :
433 0 : return err;
434 : }
435 :
436 0 : CHIP_ERROR DeviceControllerFactory::ServiceEvents()
437 : {
438 0 : VerifyOrReturnError(mSystemState != nullptr, CHIP_ERROR_INCORRECT_STATE);
439 :
440 : #if CONFIG_DEVICE_LAYER
441 0 : ReturnErrorOnFailure(DeviceLayer::PlatformMgr().StartEventLoopTask());
442 : #endif // CONFIG_DEVICE_LAYER
443 :
444 0 : return CHIP_NO_ERROR;
445 : }
446 :
447 0 : void DeviceControllerFactory::RetainSystemState()
448 : {
449 0 : (void) mSystemState->Retain();
450 0 : }
451 :
452 0 : bool DeviceControllerFactory::ReleaseSystemState()
453 : {
454 0 : return mSystemState->Release();
455 : }
456 :
457 0 : CHIP_ERROR DeviceControllerFactory::EnsureAndRetainSystemState()
458 : {
459 0 : ReturnErrorOnFailure(ReinitSystemStateIfNecessary());
460 0 : RetainSystemState();
461 0 : return CHIP_NO_ERROR;
462 : }
463 :
464 0 : DeviceControllerFactory::~DeviceControllerFactory()
465 : {
466 0 : Shutdown();
467 0 : }
468 :
469 0 : void DeviceControllerFactory::Shutdown()
470 : {
471 0 : if (mSystemState != nullptr)
472 : {
473 : // ~DeviceControllerSystemState will call Shutdown(),
474 : // which in turn ensures that the reference count is 0.
475 0 : Platform::Delete(mSystemState);
476 0 : mSystemState = nullptr;
477 : }
478 0 : mFabricIndependentStorage = nullptr;
479 0 : mOperationalKeystore = nullptr;
480 0 : mOpCertStore = nullptr;
481 0 : mCertificateValidityPolicy = nullptr;
482 0 : mSessionResumptionStorage = nullptr;
483 0 : }
484 :
485 0 : void DeviceControllerSystemState::Shutdown()
486 : {
487 0 : VerifyOrDie(mRefCount == 0);
488 0 : if (mHaveShutDown)
489 : {
490 : // Nothing else to do here.
491 0 : return;
492 : }
493 0 : mHaveShutDown = true;
494 :
495 0 : ChipLogDetail(Controller, "Shutting down the System State, this will teardown the CHIP Stack");
496 :
497 0 : if (mTempFabricTable && mEnableServerInteractions)
498 : {
499 : // The DnssdServer is holding a reference to our temp fabric table,
500 : // which we are about to destroy. Stop it, so that it will stop trying
501 : // to use it.
502 0 : app::DnssdServer::Instance().StopServer();
503 : }
504 :
505 0 : if (mFabricTableDelegate != nullptr)
506 : {
507 0 : if (mFabrics != nullptr)
508 : {
509 0 : mFabrics->RemoveFabricDelegate(mFabricTableDelegate);
510 : }
511 :
512 0 : chip::Platform::Delete(mFabricTableDelegate);
513 0 : mFabricTableDelegate = nullptr;
514 : }
515 :
516 0 : if (mBDXTransferServer != nullptr)
517 : {
518 0 : mBDXTransferServer->Shutdown();
519 0 : chip::Platform::Delete(mBDXTransferServer);
520 0 : mBDXTransferServer = nullptr;
521 : }
522 :
523 0 : if (mCASEServer != nullptr)
524 : {
525 0 : mCASEServer->Shutdown();
526 0 : chip::Platform::Delete(mCASEServer);
527 0 : mCASEServer = nullptr;
528 : }
529 :
530 0 : if (mCASESessionManager != nullptr)
531 : {
532 0 : mCASESessionManager->Shutdown();
533 0 : Platform::Delete(mCASESessionManager);
534 0 : mCASESessionManager = nullptr;
535 : }
536 :
537 : // The above took care of CASE handshakes, and shutting down all the
538 : // controllers should have taken care of the PASE handshakes. Clean up any
539 : // outstanding secure sessions (shouldn't really be any, since controllers
540 : // should have handled that, but just in case).
541 0 : if (mSessionMgr != nullptr)
542 : {
543 0 : mSessionMgr->ExpireAllSecureSessions();
544 : }
545 :
546 : // mCASEClientPool and mSessionSetupPool must be deallocated
547 : // after mCASESessionManager, which uses them.
548 :
549 0 : if (mSessionSetupPool != nullptr)
550 : {
551 0 : Platform::Delete(mSessionSetupPool);
552 0 : mSessionSetupPool = nullptr;
553 : }
554 :
555 0 : if (mCASEClientPool != nullptr)
556 : {
557 0 : Platform::Delete(mCASEClientPool);
558 0 : mCASEClientPool = nullptr;
559 : }
560 :
561 0 : Dnssd::Resolver::Instance().Shutdown();
562 :
563 : // Shut down the interaction model
564 0 : app::InteractionModelEngine::GetInstance()->Shutdown();
565 :
566 : // Shut down the TransportMgr. This holds Inet::UDPEndPoints so it must be shut down
567 : // before PlatformMgr().Shutdown() shuts down Inet.
568 0 : if (mTransportMgr != nullptr)
569 : {
570 0 : mTransportMgr->Close();
571 0 : chip::Platform::Delete(mTransportMgr);
572 0 : mTransportMgr = nullptr;
573 : }
574 :
575 0 : if (mExchangeMgr != nullptr)
576 : {
577 0 : mExchangeMgr->Shutdown();
578 : }
579 0 : if (mSessionMgr != nullptr)
580 : {
581 0 : mSessionMgr->Shutdown();
582 : }
583 :
584 0 : mSystemLayer = nullptr;
585 0 : mUDPEndPointManager = nullptr;
586 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
587 0 : mTCPEndPointManager = nullptr;
588 : #endif
589 : #if CONFIG_NETWORK_LAYER_BLE
590 0 : mBleLayer = nullptr;
591 : #endif // CONFIG_NETWORK_LAYER_BLE
592 :
593 0 : if (mMessageCounterManager != nullptr)
594 : {
595 0 : chip::Platform::Delete(mMessageCounterManager);
596 0 : mMessageCounterManager = nullptr;
597 : }
598 :
599 0 : if (mExchangeMgr != nullptr)
600 : {
601 0 : chip::Platform::Delete(mExchangeMgr);
602 0 : mExchangeMgr = nullptr;
603 : }
604 :
605 0 : if (mUnsolicitedStatusHandler != nullptr)
606 : {
607 0 : Platform::Delete(mUnsolicitedStatusHandler);
608 0 : mUnsolicitedStatusHandler = nullptr;
609 : }
610 :
611 0 : if (mSessionMgr != nullptr)
612 : {
613 0 : chip::Platform::Delete(mSessionMgr);
614 0 : mSessionMgr = nullptr;
615 : }
616 :
617 0 : if (mReportScheduler != nullptr)
618 : {
619 0 : chip::Platform::Delete(mReportScheduler);
620 0 : mReportScheduler = nullptr;
621 : }
622 :
623 0 : if (mTimerDelegate != nullptr)
624 : {
625 0 : chip::Platform::Delete(mTimerDelegate);
626 0 : mTimerDelegate = nullptr;
627 : }
628 :
629 0 : if (mTempFabricTable != nullptr)
630 : {
631 0 : mTempFabricTable->Shutdown();
632 0 : chip::Platform::Delete(mTempFabricTable);
633 0 : mTempFabricTable = nullptr;
634 : // if we created a temp fabric table, then mFabrics points to it.
635 : // if we did not create a temp fabric table, then keep the reference
636 : // so that SetupController/Commissioner can use it
637 0 : mFabrics = nullptr;
638 : }
639 :
640 : #if CONFIG_DEVICE_LAYER
641 : //
642 : // We can safely call PlatformMgr().Shutdown(), which like DeviceController::Shutdown(),
643 : // expects to be called with external thread synchronization and will not try to acquire the
644 : // stack lock.
645 : //
646 : // Actually stopping the event queue is a separable call that applications will have to sequence.
647 : // Consumers are expected to call PlaformMgr().StopEventLoopTask() before calling
648 : // DeviceController::Shutdown() in the CONFIG_DEVICE_LAYER configuration
649 : //
650 0 : DeviceLayer::PlatformMgr().Shutdown();
651 : #endif
652 : }
653 :
654 : } // namespace Controller
655 : } // namespace chip
|