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/OperationalSessionSetup.h>
28 : #include <app/TimerDelegates.h>
29 : #include <app/reporting/ReportSchedulerImpl.h>
30 : #include <app/util/DataModelHandler.h>
31 : #include <lib/core/ErrorStr.h>
32 : #include <messaging/ReliableMessageProtocolConfig.h>
33 :
34 : #if CONFIG_DEVICE_LAYER
35 : #include <platform/CHIPDeviceLayer.h>
36 : #include <platform/ConfigurationManager.h>
37 : #endif
38 :
39 : #include <app/server/Dnssd.h>
40 : #include <protocols/secure_channel/CASEServer.h>
41 : #include <protocols/secure_channel/SimpleSessionResumptionStorage.h>
42 :
43 : using namespace chip::Inet;
44 : using namespace chip::System;
45 : using namespace chip::Credentials;
46 :
47 : namespace chip {
48 : namespace Controller {
49 :
50 0 : CHIP_ERROR DeviceControllerFactory::Init(FactoryInitParams params)
51 : {
52 :
53 : // SystemState is only set the first time init is called, after that it is managed
54 : // internally. If SystemState is set then init has already completed.
55 0 : if (mSystemState != nullptr)
56 : {
57 0 : ChipLogError(Controller, "Device Controller Factory already initialized...");
58 0 : return CHIP_NO_ERROR;
59 : }
60 :
61 : // Save our initialization state that we can't recover later from a
62 : // created-but-shut-down system state.
63 0 : mListenPort = params.listenPort;
64 0 : mFabricIndependentStorage = params.fabricIndependentStorage;
65 0 : mOperationalKeystore = params.operationalKeystore;
66 0 : mOpCertStore = params.opCertStore;
67 0 : mCertificateValidityPolicy = params.certificateValidityPolicy;
68 0 : mSessionResumptionStorage = params.sessionResumptionStorage;
69 0 : mEnableServerInteractions = params.enableServerInteractions;
70 :
71 0 : CHIP_ERROR err = InitSystemState(params);
72 :
73 0 : return err;
74 : }
75 :
76 0 : CHIP_ERROR DeviceControllerFactory::InitSystemState()
77 : {
78 0 : FactoryInitParams params;
79 0 : if (mSystemState != nullptr)
80 : {
81 0 : params.systemLayer = mSystemState->SystemLayer();
82 0 : params.udpEndPointManager = mSystemState->UDPEndPointManager();
83 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
84 0 : params.tcpEndPointManager = mSystemState->TCPEndPointManager();
85 : #endif
86 : #if CONFIG_NETWORK_LAYER_BLE
87 0 : params.bleLayer = mSystemState->BleLayer();
88 : #endif
89 0 : params.listenPort = mListenPort;
90 0 : params.fabricIndependentStorage = mFabricIndependentStorage;
91 0 : params.enableServerInteractions = mEnableServerInteractions;
92 0 : params.groupDataProvider = mSystemState->GetGroupDataProvider();
93 0 : params.sessionKeystore = mSystemState->GetSessionKeystore();
94 0 : params.fabricTable = mSystemState->Fabrics();
95 0 : params.operationalKeystore = mOperationalKeystore;
96 0 : params.opCertStore = mOpCertStore;
97 0 : params.certificateValidityPolicy = mCertificateValidityPolicy;
98 0 : params.sessionResumptionStorage = mSessionResumptionStorage;
99 : }
100 :
101 0 : return InitSystemState(params);
102 : }
103 :
104 0 : CHIP_ERROR DeviceControllerFactory::InitSystemState(FactoryInitParams params)
105 : {
106 0 : if (mSystemState != nullptr && mSystemState->IsInitialized())
107 : {
108 0 : return CHIP_NO_ERROR;
109 : }
110 :
111 0 : if (mSystemState != nullptr)
112 : {
113 0 : Platform::Delete(mSystemState);
114 0 : mSystemState = nullptr;
115 : }
116 :
117 0 : DeviceControllerSystemStateParams stateParams;
118 : #if CONFIG_DEVICE_LAYER
119 0 : ReturnErrorOnFailure(DeviceLayer::PlatformMgr().InitChipStack());
120 :
121 0 : stateParams.systemLayer = &DeviceLayer::SystemLayer();
122 0 : stateParams.udpEndPointManager = DeviceLayer::UDPEndPointManager();
123 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
124 0 : stateParams.tcpEndPointManager = DeviceLayer::TCPEndPointManager();
125 : #endif
126 : #else
127 : stateParams.systemLayer = params.systemLayer;
128 : stateParams.tcpEndPointManager = params.tcpEndPointManager;
129 : stateParams.udpEndPointManager = params.udpEndPointManager;
130 : ChipLogError(Controller, "Warning: Device Controller Factory should be with a CHIP Device Layer...");
131 : #endif // CONFIG_DEVICE_LAYER
132 :
133 0 : VerifyOrReturnError(stateParams.systemLayer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
134 0 : VerifyOrReturnError(stateParams.udpEndPointManager != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
135 :
136 : // OperationalCertificateStore needs to be provided to init the fabric table if fabric table is
137 : // not provided wholesale.
138 0 : ReturnErrorCodeIf((params.fabricTable == nullptr) && (params.opCertStore == nullptr), CHIP_ERROR_INVALID_ARGUMENT);
139 0 : ReturnErrorCodeIf(params.sessionKeystore == nullptr, CHIP_ERROR_INVALID_ARGUMENT);
140 :
141 : #if CONFIG_NETWORK_LAYER_BLE
142 : #if CONFIG_DEVICE_LAYER
143 0 : stateParams.bleLayer = DeviceLayer::ConnectivityMgr().GetBleLayer();
144 : #else
145 : stateParams.bleLayer = params.bleLayer;
146 : #endif // CONFIG_DEVICE_LAYER
147 0 : VerifyOrReturnError(stateParams.bleLayer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
148 : #endif
149 :
150 0 : stateParams.transportMgr = chip::Platform::New<DeviceTransportMgr>();
151 :
152 : //
153 : // The logic below expects IPv6 to be at index 0 of this tuple. Please do not alter that.
154 : //
155 0 : ReturnErrorOnFailure(stateParams.transportMgr->Init(Transport::UdpListenParameters(stateParams.udpEndPointManager)
156 : .SetAddressType(Inet::IPAddressType::kIPv6)
157 : .SetListenPort(params.listenPort)
158 : #if INET_CONFIG_ENABLE_IPV4
159 : ,
160 : Transport::UdpListenParameters(stateParams.udpEndPointManager)
161 : .SetAddressType(Inet::IPAddressType::kIPv4)
162 : .SetListenPort(params.listenPort)
163 : #endif
164 : #if CONFIG_NETWORK_LAYER_BLE
165 : ,
166 : Transport::BleListenParameters(stateParams.bleLayer)
167 : #endif
168 : ));
169 :
170 : // TODO(#16231): All the new'ed state above/below in this method is never properly released or null-checked!
171 0 : stateParams.sessionMgr = chip::Platform::New<SessionManager>();
172 0 : stateParams.certificateValidityPolicy = params.certificateValidityPolicy;
173 0 : stateParams.unsolicitedStatusHandler = Platform::New<Protocols::SecureChannel::UnsolicitedStatusHandler>();
174 0 : stateParams.exchangeMgr = chip::Platform::New<Messaging::ExchangeManager>();
175 0 : stateParams.messageCounterManager = chip::Platform::New<secure_channel::MessageCounterManager>();
176 0 : stateParams.groupDataProvider = params.groupDataProvider;
177 0 : stateParams.timerDelegate = chip::Platform::New<chip::app::DefaultTimerDelegate>();
178 0 : stateParams.reportScheduler = chip::Platform::New<app::reporting::ReportSchedulerImpl>(stateParams.timerDelegate);
179 0 : stateParams.sessionKeystore = params.sessionKeystore;
180 0 : stateParams.bdxTransferServer = chip::Platform::New<bdx::BDXTransferServer>();
181 :
182 : // if no fabricTable was provided, create one and track it in stateParams for cleanup
183 0 : stateParams.fabricTable = params.fabricTable;
184 :
185 0 : FabricTable * tempFabricTable = nullptr;
186 0 : if (stateParams.fabricTable == nullptr)
187 : {
188 : // TODO(#16231): Previously (and still) the objects new-ed in this entire method seem expected to last forever...
189 0 : auto newFabricTable = Platform::MakeUnique<FabricTable>();
190 0 : ReturnErrorCodeIf(!newFabricTable, CHIP_ERROR_NO_MEMORY);
191 :
192 0 : FabricTable::InitParams fabricTableInitParams;
193 0 : fabricTableInitParams.storage = params.fabricIndependentStorage;
194 0 : fabricTableInitParams.operationalKeystore = params.operationalKeystore;
195 0 : fabricTableInitParams.opCertStore = params.opCertStore;
196 0 : ReturnErrorOnFailure(newFabricTable->Init(fabricTableInitParams));
197 0 : stateParams.fabricTable = newFabricTable.release();
198 0 : tempFabricTable = stateParams.fabricTable;
199 0 : }
200 :
201 : SessionResumptionStorage * sessionResumptionStorage;
202 0 : if (params.sessionResumptionStorage == nullptr)
203 : {
204 0 : auto ownedSessionResumptionStorage = chip::Platform::MakeUnique<SimpleSessionResumptionStorage>();
205 0 : ReturnErrorOnFailure(ownedSessionResumptionStorage->Init(params.fabricIndependentStorage));
206 0 : stateParams.ownedSessionResumptionStorage = std::move(ownedSessionResumptionStorage);
207 0 : stateParams.externalSessionResumptionStorage = nullptr;
208 0 : sessionResumptionStorage = stateParams.ownedSessionResumptionStorage.get();
209 0 : }
210 : else
211 : {
212 0 : stateParams.ownedSessionResumptionStorage = nullptr;
213 0 : stateParams.externalSessionResumptionStorage = params.sessionResumptionStorage;
214 0 : sessionResumptionStorage = stateParams.externalSessionResumptionStorage;
215 : }
216 :
217 0 : auto delegate = chip::Platform::MakeUnique<ControllerFabricDelegate>();
218 0 : ReturnErrorOnFailure(delegate->Init(sessionResumptionStorage, stateParams.groupDataProvider));
219 0 : stateParams.fabricTableDelegate = delegate.get();
220 0 : ReturnErrorOnFailure(stateParams.fabricTable->AddFabricDelegate(stateParams.fabricTableDelegate));
221 0 : delegate.release();
222 :
223 0 : ReturnErrorOnFailure(stateParams.sessionMgr->Init(stateParams.systemLayer, stateParams.transportMgr,
224 : stateParams.messageCounterManager, params.fabricIndependentStorage,
225 : stateParams.fabricTable, *stateParams.sessionKeystore));
226 0 : ReturnErrorOnFailure(stateParams.exchangeMgr->Init(stateParams.sessionMgr));
227 0 : ReturnErrorOnFailure(stateParams.messageCounterManager->Init(stateParams.exchangeMgr));
228 0 : ReturnErrorOnFailure(stateParams.unsolicitedStatusHandler->Init(stateParams.exchangeMgr));
229 0 : ReturnErrorOnFailure(stateParams.bdxTransferServer->Init(stateParams.systemLayer, stateParams.exchangeMgr));
230 :
231 0 : InitDataModelHandler();
232 :
233 0 : ReturnErrorOnFailure(Dnssd::Resolver::Instance().Init(stateParams.udpEndPointManager));
234 :
235 0 : if (params.enableServerInteractions)
236 : {
237 0 : stateParams.caseServer = chip::Platform::New<CASEServer>();
238 :
239 : // Enable listening for session establishment messages.
240 0 : ReturnErrorOnFailure(stateParams.caseServer->ListenForSessionEstablishment(
241 : stateParams.exchangeMgr, stateParams.sessionMgr, stateParams.fabricTable, sessionResumptionStorage,
242 : stateParams.certificateValidityPolicy, stateParams.groupDataProvider));
243 :
244 : //
245 : // We need to advertise the port that we're listening to for unsolicited messages over UDP. However, we have both a IPv4
246 : // and IPv6 endpoint to pick from. Given that the listen port passed in may be set to 0 (which then has the kernel select
247 : // a valid port at bind time), that will result in two possible ports being provided back from the resultant endpoint
248 : // initializations. Since IPv6 is POR for Matter, let's go ahead and pick that port.
249 : //
250 0 : app::DnssdServer::Instance().SetSecuredPort(stateParams.transportMgr->GetTransport().GetImplAtIndex<0>().GetBoundPort());
251 :
252 : //
253 : // TODO: This is a hack to workaround the fact that we have a bi-polar stack that has controller and server modalities that
254 : // are mutually exclusive in terms of initialization of key stack singletons. Consequently, DnssdServer accesses
255 : // Server::GetInstance().GetFabricTable() to access the fabric table, but we don't want to do that when we're initializing
256 : // the controller logic since the factory here has its own fabric table.
257 : //
258 : // Consequently, reach in set the fabric table pointer to point to the right version.
259 : //
260 0 : app::DnssdServer::Instance().SetFabricTable(stateParams.fabricTable);
261 : }
262 :
263 0 : stateParams.sessionSetupPool = Platform::New<DeviceControllerSystemStateParams::SessionSetupPool>();
264 0 : stateParams.caseClientPool = Platform::New<DeviceControllerSystemStateParams::CASEClientPool>();
265 :
266 : CASEClientInitParams sessionInitParams = {
267 0 : .sessionManager = stateParams.sessionMgr,
268 : .sessionResumptionStorage = sessionResumptionStorage,
269 0 : .certificateValidityPolicy = stateParams.certificateValidityPolicy,
270 0 : .exchangeMgr = stateParams.exchangeMgr,
271 0 : .fabricTable = stateParams.fabricTable,
272 0 : .groupDataProvider = stateParams.groupDataProvider,
273 : .mrpLocalConfig = GetLocalMRPConfig(),
274 0 : };
275 :
276 : CASESessionManagerConfig sessionManagerConfig = {
277 : .sessionInitParams = sessionInitParams,
278 0 : .clientPool = stateParams.caseClientPool,
279 0 : .sessionSetupPool = stateParams.sessionSetupPool,
280 0 : };
281 :
282 : // TODO: Need to be able to create a CASESessionManagerConfig here!
283 0 : stateParams.caseSessionManager = Platform::New<CASESessionManager>();
284 0 : ReturnErrorOnFailure(stateParams.caseSessionManager->Init(stateParams.systemLayer, sessionManagerConfig));
285 :
286 0 : ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->Init(
287 : stateParams.exchangeMgr, stateParams.fabricTable, stateParams.reportScheduler, stateParams.caseSessionManager));
288 :
289 : // store the system state
290 0 : mSystemState = chip::Platform::New<DeviceControllerSystemState>(std::move(stateParams));
291 0 : mSystemState->SetTempFabricTable(tempFabricTable, params.enableServerInteractions);
292 0 : ChipLogDetail(Controller, "System State Initialized...");
293 0 : return CHIP_NO_ERROR;
294 0 : }
295 :
296 0 : void DeviceControllerFactory::PopulateInitParams(ControllerInitParams & controllerParams, const SetupParams & params)
297 : {
298 0 : controllerParams.operationalCredentialsDelegate = params.operationalCredentialsDelegate;
299 0 : controllerParams.operationalKeypair = params.operationalKeypair;
300 0 : controllerParams.hasExternallyOwnedOperationalKeypair = params.hasExternallyOwnedOperationalKeypair;
301 0 : controllerParams.controllerNOC = params.controllerNOC;
302 0 : controllerParams.controllerICAC = params.controllerICAC;
303 0 : controllerParams.controllerRCAC = params.controllerRCAC;
304 0 : controllerParams.permitMultiControllerFabrics = params.permitMultiControllerFabrics;
305 0 : controllerParams.removeFromFabricTableOnShutdown = params.removeFromFabricTableOnShutdown;
306 :
307 0 : controllerParams.systemState = mSystemState;
308 0 : controllerParams.controllerVendorId = params.controllerVendorId;
309 :
310 0 : controllerParams.enableServerInteractions = params.enableServerInteractions;
311 0 : }
312 :
313 0 : void DeviceControllerFactory::ControllerInitialized(const DeviceController & controller)
314 : {
315 0 : if (mEnableServerInteractions && controller.GetFabricIndex() != kUndefinedFabricIndex)
316 : {
317 : // Restart DNS-SD advertising, because initialization of this controller could
318 : // have modified whether a particular fabric identity should be
319 : // advertised. Just calling AdvertiseOperational() is not good enough
320 : // here, since we might be removing advertising.
321 0 : app::DnssdServer::Instance().StartServer();
322 : }
323 0 : }
324 :
325 0 : CHIP_ERROR DeviceControllerFactory::SetupController(SetupParams params, DeviceController & controller)
326 : {
327 0 : VerifyOrReturnError(mSystemState != nullptr, CHIP_ERROR_INCORRECT_STATE);
328 0 : VerifyOrReturnError(params.controllerVendorId != VendorId::Unspecified, CHIP_ERROR_INVALID_ARGUMENT);
329 :
330 0 : ReturnErrorOnFailure(InitSystemState());
331 :
332 0 : ControllerInitParams controllerParams;
333 0 : PopulateInitParams(controllerParams, params);
334 :
335 0 : CHIP_ERROR err = controller.Init(controllerParams);
336 :
337 0 : if (err == CHIP_NO_ERROR)
338 : {
339 0 : ControllerInitialized(controller);
340 : }
341 :
342 0 : return err;
343 : }
344 :
345 0 : CHIP_ERROR DeviceControllerFactory::SetupCommissioner(SetupParams params, DeviceCommissioner & commissioner)
346 : {
347 0 : VerifyOrReturnError(mSystemState != nullptr, CHIP_ERROR_INCORRECT_STATE);
348 0 : VerifyOrReturnError(params.controllerVendorId != VendorId::Unspecified, CHIP_ERROR_INVALID_ARGUMENT);
349 :
350 0 : ReturnErrorOnFailure(InitSystemState());
351 :
352 0 : CommissionerInitParams commissionerParams;
353 :
354 : // PopulateInitParams works against ControllerInitParams base class of CommissionerInitParams only
355 0 : PopulateInitParams(commissionerParams, params);
356 :
357 : // Set commissioner-specific fields not in ControllerInitParams
358 0 : commissionerParams.pairingDelegate = params.pairingDelegate;
359 0 : commissionerParams.defaultCommissioner = params.defaultCommissioner;
360 0 : commissionerParams.deviceAttestationVerifier = params.deviceAttestationVerifier;
361 :
362 0 : CHIP_ERROR err = commissioner.Init(commissionerParams);
363 :
364 0 : if (err == CHIP_NO_ERROR)
365 : {
366 0 : ControllerInitialized(commissioner);
367 : }
368 :
369 0 : return err;
370 : }
371 :
372 0 : CHIP_ERROR DeviceControllerFactory::ServiceEvents()
373 : {
374 0 : VerifyOrReturnError(mSystemState != nullptr, CHIP_ERROR_INCORRECT_STATE);
375 :
376 : #if CONFIG_DEVICE_LAYER
377 0 : ReturnErrorOnFailure(DeviceLayer::PlatformMgr().StartEventLoopTask());
378 : #endif // CONFIG_DEVICE_LAYER
379 :
380 0 : return CHIP_NO_ERROR;
381 : }
382 :
383 0 : void DeviceControllerFactory::RetainSystemState()
384 : {
385 0 : (void) mSystemState->Retain();
386 0 : }
387 :
388 0 : void DeviceControllerFactory::ReleaseSystemState()
389 : {
390 0 : mSystemState->Release();
391 0 : }
392 :
393 0 : DeviceControllerFactory::~DeviceControllerFactory()
394 : {
395 0 : Shutdown();
396 0 : }
397 :
398 0 : void DeviceControllerFactory::Shutdown()
399 : {
400 0 : if (mSystemState != nullptr)
401 : {
402 0 : Platform::Delete(mSystemState);
403 0 : mSystemState = nullptr;
404 : }
405 0 : mFabricIndependentStorage = nullptr;
406 0 : mOperationalKeystore = nullptr;
407 0 : mOpCertStore = nullptr;
408 0 : mCertificateValidityPolicy = nullptr;
409 0 : mSessionResumptionStorage = nullptr;
410 0 : }
411 :
412 0 : void DeviceControllerSystemState::Shutdown()
413 : {
414 0 : VerifyOrDie(mRefCount == 0);
415 0 : if (mHaveShutDown)
416 : {
417 : // Nothing else to do here.
418 0 : return;
419 : }
420 0 : mHaveShutDown = true;
421 :
422 0 : ChipLogDetail(Controller, "Shutting down the System State, this will teardown the CHIP Stack");
423 :
424 0 : if (mTempFabricTable && mEnableServerInteractions)
425 : {
426 : // The DnssdServer is holding a reference to our temp fabric table,
427 : // which we are about to destroy. Stop it, so that it will stop trying
428 : // to use it.
429 0 : app::DnssdServer::Instance().StopServer();
430 : }
431 :
432 0 : if (mFabricTableDelegate != nullptr)
433 : {
434 0 : if (mFabrics != nullptr)
435 : {
436 0 : mFabrics->RemoveFabricDelegate(mFabricTableDelegate);
437 : }
438 :
439 0 : chip::Platform::Delete(mFabricTableDelegate);
440 0 : mFabricTableDelegate = nullptr;
441 : }
442 :
443 0 : if (mBDXTransferServer != nullptr)
444 : {
445 0 : mBDXTransferServer->Shutdown();
446 0 : chip::Platform::Delete(mBDXTransferServer);
447 0 : mBDXTransferServer = nullptr;
448 : }
449 :
450 0 : if (mCASEServer != nullptr)
451 : {
452 0 : mCASEServer->Shutdown();
453 0 : chip::Platform::Delete(mCASEServer);
454 0 : mCASEServer = nullptr;
455 : }
456 :
457 0 : if (mCASESessionManager != nullptr)
458 : {
459 0 : mCASESessionManager->Shutdown();
460 0 : Platform::Delete(mCASESessionManager);
461 0 : mCASESessionManager = nullptr;
462 : }
463 :
464 : // mCASEClientPool and mSessionSetupPool must be deallocated
465 : // after mCASESessionManager, which uses them.
466 :
467 0 : if (mSessionSetupPool != nullptr)
468 : {
469 0 : Platform::Delete(mSessionSetupPool);
470 0 : mSessionSetupPool = nullptr;
471 : }
472 :
473 0 : if (mCASEClientPool != nullptr)
474 : {
475 0 : Platform::Delete(mCASEClientPool);
476 0 : mCASEClientPool = nullptr;
477 : }
478 :
479 0 : Dnssd::Resolver::Instance().Shutdown();
480 :
481 : // Shut down the interaction model
482 0 : app::InteractionModelEngine::GetInstance()->Shutdown();
483 :
484 : // Shut down the TransportMgr. This holds Inet::UDPEndPoints so it must be shut down
485 : // before PlatformMgr().Shutdown() shuts down Inet.
486 0 : if (mTransportMgr != nullptr)
487 : {
488 0 : mTransportMgr->Close();
489 0 : chip::Platform::Delete(mTransportMgr);
490 0 : mTransportMgr = nullptr;
491 : }
492 :
493 0 : if (mExchangeMgr != nullptr)
494 : {
495 0 : mExchangeMgr->Shutdown();
496 : }
497 0 : if (mSessionMgr != nullptr)
498 : {
499 0 : mSessionMgr->Shutdown();
500 : }
501 :
502 0 : mSystemLayer = nullptr;
503 0 : mUDPEndPointManager = nullptr;
504 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
505 0 : mTCPEndPointManager = nullptr;
506 : #endif
507 : #if CONFIG_NETWORK_LAYER_BLE
508 0 : mBleLayer = nullptr;
509 : #endif // CONFIG_NETWORK_LAYER_BLE
510 :
511 0 : if (mMessageCounterManager != nullptr)
512 : {
513 0 : chip::Platform::Delete(mMessageCounterManager);
514 0 : mMessageCounterManager = nullptr;
515 : }
516 :
517 0 : if (mExchangeMgr != nullptr)
518 : {
519 0 : chip::Platform::Delete(mExchangeMgr);
520 0 : mExchangeMgr = nullptr;
521 : }
522 :
523 0 : if (mUnsolicitedStatusHandler != nullptr)
524 : {
525 0 : Platform::Delete(mUnsolicitedStatusHandler);
526 0 : mUnsolicitedStatusHandler = nullptr;
527 : }
528 :
529 0 : if (mSessionMgr != nullptr)
530 : {
531 0 : chip::Platform::Delete(mSessionMgr);
532 0 : mSessionMgr = nullptr;
533 : }
534 :
535 0 : if (mReportScheduler != nullptr)
536 : {
537 0 : chip::Platform::Delete(mReportScheduler);
538 0 : mReportScheduler = nullptr;
539 : }
540 :
541 0 : if (mTimerDelegate != nullptr)
542 : {
543 0 : chip::Platform::Delete(mTimerDelegate);
544 0 : mTimerDelegate = nullptr;
545 : }
546 :
547 0 : if (mTempFabricTable != nullptr)
548 : {
549 0 : mTempFabricTable->Shutdown();
550 0 : chip::Platform::Delete(mTempFabricTable);
551 0 : mTempFabricTable = nullptr;
552 : // if we created a temp fabric table, then mFabrics points to it.
553 : // if we did not create a temp fabric table, then keep the reference
554 : // so that SetupController/Commissioner can use it
555 0 : mFabrics = nullptr;
556 : }
557 :
558 : #if CONFIG_DEVICE_LAYER
559 : //
560 : // We can safely call PlatformMgr().Shutdown(), which like DeviceController::Shutdown(),
561 : // expects to be called with external thread synchronization and will not try to acquire the
562 : // stack lock.
563 : //
564 : // Actually stopping the event queue is a separable call that applications will have to sequence.
565 : // Consumers are expected to call PlaformMgr().StopEventLoopTask() before calling
566 : // DeviceController::Shutdown() in the CONFIG_DEVICE_LAYER configuration
567 : //
568 0 : DeviceLayer::PlatformMgr().Shutdown();
569 : #endif
570 : }
571 :
572 : } // namespace Controller
573 : } // namespace chip
|