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 : * DeviceControllerFactory is a singleton utility class that manages the
22 : * runtime DeviceControllerSystemState and provides APIs to setup DeviceControllers
23 : * and DeviceCommissioners.
24 : *
25 : * Together with the SystemState this class implicitly manages the lifecycle of the underlying
26 : * CHIP stack. It lazily initializes the CHIPStack when setting up Controllers if the SystemState
27 : * was previously shutdown.
28 : */
29 :
30 : #pragma once
31 :
32 : #include <controller/CHIPDeviceController.h>
33 : #include <controller/CHIPDeviceControllerSystemState.h>
34 : #include <credentials/GroupDataProvider.h>
35 : #include <credentials/OperationalCertificateStore.h>
36 : #include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
37 : #include <protocols/secure_channel/SessionResumptionStorage.h>
38 :
39 : namespace chip {
40 :
41 : namespace Controller {
42 :
43 : struct SetupParams
44 : {
45 : OperationalCredentialsDelegate * operationalCredentialsDelegate = nullptr;
46 :
47 : /* The following keypair must correspond to the public key used for generating
48 : controllerNOC. It's used by controller to establish CASE sessions with devices */
49 : Crypto::P256Keypair * operationalKeypair = nullptr;
50 :
51 : /**
52 : * Controls whether or not the operationalKeypair should be owned by the
53 : * caller. By default, this is false, but if the keypair cannot be
54 : * serialized, then setting this to true will allow the caller to manage
55 : * this keypair's lifecycle.
56 : */
57 : bool hasExternallyOwnedOperationalKeypair = false;
58 :
59 : /* The following certificates must be in x509 DER format */
60 : ByteSpan controllerNOC;
61 : ByteSpan controllerICAC;
62 : ByteSpan controllerRCAC;
63 :
64 : //
65 : // This must be set to a valid, operational VendorId value associated with
66 : // the controller/commissioner.
67 : //
68 : chip::VendorId controllerVendorId = VendorId::Unspecified;
69 :
70 : // The Device Pairing Delegated used to initialize a Commissioner
71 : DevicePairingDelegate * pairingDelegate = nullptr;
72 :
73 : /**
74 : * Controls whether we permit multiple DeviceController instances to exist
75 : * on the same logical fabric (identified by the tuple of the fabric's
76 : * root public key + fabric id).
77 : *
78 : * Each controller instance will be associated with its own FabricIndex.
79 : * This pivots the FabricTable to tracking identities instead of fabrics,
80 : * represented by FabricInfo instances that can have colliding logical fabrics.
81 : *
82 : */
83 : bool permitMultiControllerFabrics = false;
84 :
85 : //
86 : // Controls enabling server cluster interactions on a controller. This in turn
87 : // causes the following to get enabled:
88 : //
89 : // - CASEServer to listen for unsolicited Sigma1 messages.
90 : // - Advertisement of active controller operational identities.
91 : //
92 : bool enableServerInteractions = false;
93 :
94 : /**
95 : * Controls whether shutdown of the controller removes the corresponding
96 : * entry from the in-memory fabric table, but NOT from storage.
97 : *
98 : * Note that this means that after controller shutdown the storage and
99 : * in-memory versions of the fabric table will be out of sync.
100 : * For compatibility reasons this is the default behavior.
101 : *
102 : * @see deleteFromFabricTableOnShutdown
103 : */
104 : bool removeFromFabricTableOnShutdown = true;
105 :
106 : /**
107 : * Controls whether shutdown of the controller deletes the corresponding
108 : * entry from the fabric table (both in-memory and storage).
109 : *
110 : * If both `removeFromFabricTableOnShutdown` and this setting are true,
111 : * this setting will take precedence.
112 : *
113 : * @see removeFromFabricTableOnShutdown
114 : */
115 : bool deleteFromFabricTableOnShutdown = false;
116 :
117 : /**
118 : * Specifies whether to utilize the fabric table entry for the given FabricIndex
119 : * for initialization. If provided and neither the operational key pair nor the NOC
120 : * chain are provided, then attempt to locate a fabric corresponding to the given FabricIndex.
121 : */
122 : chip::Optional<FabricIndex> fabricIndex;
123 :
124 : Credentials::DeviceAttestationVerifier * deviceAttestationVerifier = nullptr;
125 : CommissioningDelegate * defaultCommissioner = nullptr;
126 : };
127 :
128 : // TODO everything other than the fabric storage, group data provider, OperationalKeystore,
129 : // OperationalCertificateStore, SessionKeystore, and SessionResumptionStorage here should
130 : // be removed. We're blocked because of the need to support !CHIP_DEVICE_LAYER
131 : struct FactoryInitParams
132 : {
133 : System::Layer * systemLayer = nullptr;
134 : PersistentStorageDelegate * fabricIndependentStorage = nullptr;
135 : Credentials::CertificateValidityPolicy * certificateValidityPolicy = nullptr;
136 : Credentials::GroupDataProvider * groupDataProvider = nullptr;
137 : app::reporting::ReportScheduler::TimerDelegate * timerDelegate = nullptr;
138 : Crypto::SessionKeystore * sessionKeystore = nullptr;
139 : Inet::EndPointManager<Inet::TCPEndPoint> * tcpEndPointManager = nullptr;
140 : Inet::EndPointManager<Inet::UDPEndPoint> * udpEndPointManager = nullptr;
141 : FabricTable * fabricTable = nullptr;
142 : Crypto::OperationalKeystore * operationalKeystore = nullptr;
143 : Credentials::OperationalCertificateStore * opCertStore = nullptr;
144 : SessionResumptionStorage * sessionResumptionStorage = nullptr;
145 : #if CONFIG_NETWORK_LAYER_BLE
146 : Ble::BleLayer * bleLayer = nullptr;
147 : #endif
148 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
149 : Transport::WiFiPAFLayer * wifipaf_layer = nullptr;
150 : #endif
151 :
152 : //
153 : // Controls enabling server cluster interactions on a controller. This in turn
154 : // causes the following to get enabled:
155 : //
156 : // - Advertisement of active controller operational identities.
157 : //
158 : bool enableServerInteractions = false;
159 :
160 : /* The port used for operational communication to listen for and send messages over UDP/TCP.
161 : * The default value of `0` will pick any available port. */
162 : uint16_t listenPort = 0;
163 :
164 : // MUST NOT be null during initialization: every application must define the
165 : // data model it wants to use. Backwards-compatibility can use `CodegenDataModelProviderInstance`
166 : // for ember/zap-generated models.
167 : chip::app::DataModel::Provider * dataModelProvider = nullptr;
168 : };
169 :
170 : class DeviceControllerFactory
171 : {
172 : public:
173 : static DeviceControllerFactory & GetInstance()
174 : {
175 : static DeviceControllerFactory instance;
176 : return instance;
177 : }
178 :
179 : CHIP_ERROR Init(FactoryInitParams params);
180 :
181 : // Shuts down matter and frees the system state.
182 : //
183 : // Must not be called while any controllers are alive, or while any calls
184 : // to RetainSystemState or EnsureAndRetainSystemState have not been balanced
185 : // by a call to ReleaseSystemState.
186 : void Shutdown();
187 :
188 : CHIP_ERROR SetupController(SetupParams params, DeviceController & controller);
189 : CHIP_ERROR SetupCommissioner(SetupParams params, DeviceCommissioner & commissioner);
190 :
191 : // ----- IO -----
192 : /**
193 : * @brief
194 : * Start the event loop task within the CHIP stack
195 : * @return CHIP_ERROR The return status
196 : */
197 : CHIP_ERROR ServiceEvents();
198 :
199 : ~DeviceControllerFactory();
200 : DeviceControllerFactory(DeviceControllerFactory const &) = delete;
201 : void operator=(DeviceControllerFactory const &) = delete;
202 :
203 : //
204 : // Some clients do not prefer a complete shutdown of the stack being initiated if
205 : // all device controllers have ceased to exist. To avoid that, this method has been
206 : // created to permit retention of the underlying system state.
207 : //
208 : // Calls to this method must be balanced by calling ReleaseSystemState before Shutdown.
209 : //
210 : void RetainSystemState();
211 :
212 : //
213 : // To initiate shutdown of the stack upon termination of all resident controllers in the
214 : // system, invoke this method to decrement the refcount on the system state and consequently,
215 : // shut-down the stack.
216 : //
217 : // This should only be invoked if a matching call to RetainSystemState() was called prior.
218 : //
219 : // Returns true if stack was shut down in response to this call, or false otherwise.
220 : //
221 : bool ReleaseSystemState();
222 :
223 : // Like RetainSystemState(), but will re-initialize the system state first if necessary.
224 : // Calls to this method must be balanced by calling ReleaseSystemState before Shutdown.
225 : CHIP_ERROR EnsureAndRetainSystemState();
226 :
227 : //
228 : // Retrieve a read-only pointer to the system state object that contains pointers to key stack
229 : // singletons. If the pointer is null, it indicates that the DeviceControllerFactory has yet to
230 : // be initialized properly, or has already been shut-down.
231 : //
232 : // This pointer ceases to be valid after a call to Shutdown has been made, or if all active
233 : // DeviceController instances have gone to 0. Consequently, care has to be taken to correctly
234 : // sequence the shutting down of active controllers with any entity that interacts with objects
235 : // present in the system state object. If de-coupling is desired, RetainSystemState and
236 : // ReleaseSystemState can be used to avoid this.
237 : //
238 : const DeviceControllerSystemState * GetSystemState() const { return mSystemState; }
239 :
240 : class ControllerFabricDelegate final : public chip::FabricTable::Delegate
241 : {
242 : public:
243 0 : CHIP_ERROR Init(SessionResumptionStorage * sessionResumptionStorage, Credentials::GroupDataProvider * groupDataProvider)
244 : {
245 0 : VerifyOrReturnError(sessionResumptionStorage != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
246 0 : VerifyOrReturnError(groupDataProvider != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
247 :
248 0 : mSessionResumptionStorage = sessionResumptionStorage;
249 0 : mGroupDataProvider = groupDataProvider;
250 0 : return CHIP_NO_ERROR;
251 : };
252 :
253 0 : void OnFabricRemoved(const chip::FabricTable & fabricTable, FabricIndex fabricIndex) override
254 : {
255 : (void) fabricTable;
256 0 : if (mGroupDataProvider != nullptr)
257 : {
258 0 : mGroupDataProvider->RemoveFabric(fabricIndex);
259 : }
260 0 : ClearCASEResumptionStateOnFabricChange(fabricIndex);
261 0 : };
262 :
263 0 : void OnFabricUpdated(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex) override
264 : {
265 : (void) fabricTable;
266 0 : ClearCASEResumptionStateOnFabricChange(fabricIndex);
267 0 : }
268 :
269 : private:
270 0 : void ClearCASEResumptionStateOnFabricChange(chip::FabricIndex fabricIndex)
271 : {
272 0 : VerifyOrReturn(mSessionResumptionStorage != nullptr);
273 0 : CHIP_ERROR err = mSessionResumptionStorage->DeleteAll(fabricIndex);
274 0 : if (err != CHIP_NO_ERROR)
275 : {
276 0 : ChipLogError(Controller,
277 : "Warning, failed to delete session resumption state for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
278 : static_cast<unsigned>(fabricIndex), err.Format());
279 : }
280 : }
281 :
282 : Credentials::GroupDataProvider * mGroupDataProvider = nullptr;
283 : SessionResumptionStorage * mSessionResumptionStorage = nullptr;
284 : };
285 :
286 : private:
287 : DeviceControllerFactory() {}
288 : void PopulateInitParams(ControllerInitParams & controllerParams, const SetupParams & params);
289 : CHIP_ERROR InitSystemState(FactoryInitParams params);
290 : CHIP_ERROR ReinitSystemStateIfNecessary();
291 : void ControllerInitialized(const DeviceController & controller);
292 :
293 : uint16_t mListenPort;
294 : DeviceControllerSystemState * mSystemState = nullptr;
295 : PersistentStorageDelegate * mFabricIndependentStorage = nullptr;
296 : Crypto::OperationalKeystore * mOperationalKeystore = nullptr;
297 : Credentials::OperationalCertificateStore * mOpCertStore = nullptr;
298 : Credentials::CertificateValidityPolicy * mCertificateValidityPolicy = nullptr;
299 : SessionResumptionStorage * mSessionResumptionStorage = nullptr;
300 : bool mEnableServerInteractions = false;
301 : };
302 :
303 : } // namespace Controller
304 : } // namespace chip
|