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