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