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 fabric table. For now the removal is just from the 97 : * in-memory table, not from storage, which means that after controller 98 : * shutdown the storage and the in-memory fabric table will be out of sync. 99 : * This is acceptable for implementations that don't actually store any of 100 : * the fabric table information, but if someone wants a true removal at some 101 : * point another option will need to be added here. 102 : */ 103 : bool removeFromFabricTableOnShutdown = true; 104 : 105 : Credentials::DeviceAttestationVerifier * deviceAttestationVerifier = nullptr; 106 : CommissioningDelegate * defaultCommissioner = nullptr; 107 : }; 108 : 109 : // TODO everything other than the fabric storage, group data provider, OperationalKeystore, 110 : // OperationalCertificateStore, SessionKeystore, and SessionResumptionStorage here should 111 : // be removed. We're blocked because of the need to support !CHIP_DEVICE_LAYER 112 : struct FactoryInitParams 113 : { 114 : System::Layer * systemLayer = nullptr; 115 : PersistentStorageDelegate * fabricIndependentStorage = nullptr; 116 : Credentials::CertificateValidityPolicy * certificateValidityPolicy = nullptr; 117 : Credentials::GroupDataProvider * groupDataProvider = nullptr; 118 : app::reporting::ReportScheduler::TimerDelegate * timerDelegate = nullptr; 119 : Crypto::SessionKeystore * sessionKeystore = nullptr; 120 : Inet::EndPointManager<Inet::TCPEndPoint> * tcpEndPointManager = nullptr; 121 : Inet::EndPointManager<Inet::UDPEndPoint> * udpEndPointManager = nullptr; 122 : FabricTable * fabricTable = nullptr; 123 : OperationalKeystore * operationalKeystore = nullptr; 124 : Credentials::OperationalCertificateStore * opCertStore = nullptr; 125 : SessionResumptionStorage * sessionResumptionStorage = nullptr; 126 : #if CONFIG_NETWORK_LAYER_BLE 127 : Ble::BleLayer * bleLayer = nullptr; 128 : #endif 129 : 130 : // 131 : // Controls enabling server cluster interactions on a controller. This in turn 132 : // causes the following to get enabled: 133 : // 134 : // - Advertisement of active controller operational identities. 135 : // 136 : bool enableServerInteractions = false; 137 : 138 : /* The port used for operational communication to listen for and send messages over UDP/TCP. 139 : * The default value of `0` will pick any available port. */ 140 : uint16_t listenPort = 0; 141 : }; 142 : 143 : class DeviceControllerFactory 144 : { 145 : public: 146 : static DeviceControllerFactory & GetInstance() 147 : { 148 : static DeviceControllerFactory instance; 149 : return instance; 150 : } 151 : 152 : CHIP_ERROR Init(FactoryInitParams params); 153 : 154 : // Shuts down matter and frees the system state. 155 : // 156 : // Must not be called while any controllers are alive. 157 : void Shutdown(); 158 : 159 : CHIP_ERROR SetupController(SetupParams params, DeviceController & controller); 160 : CHIP_ERROR SetupCommissioner(SetupParams params, DeviceCommissioner & commissioner); 161 : 162 : // ----- IO ----- 163 : /** 164 : * @brief 165 : * Start the event loop task within the CHIP stack 166 : * @return CHIP_ERROR The return status 167 : */ 168 : CHIP_ERROR ServiceEvents(); 169 : 170 : ~DeviceControllerFactory(); 171 : DeviceControllerFactory(DeviceControllerFactory const &) = delete; 172 : void operator=(DeviceControllerFactory const &) = delete; 173 : 174 : // 175 : // Some clients do not prefer a complete shutdown of the stack being initiated if 176 : // all device controllers have ceased to exist. To avoid that, this method has been 177 : // created to permit retention of the underlying system state. 178 : // 179 : // NB: The system state will still be freed in Shutdown() regardless of this call. 180 : void RetainSystemState(); 181 : 182 : // 183 : // To initiate shutdown of the stack upon termination of all resident controllers in the 184 : // system, invoke this method to decrement the refcount on the system state and consequently, 185 : // shut-down the stack. 186 : // 187 : // This should only be invoked if a matching call to RetainSystemState() was called prior. 188 : // 189 : void ReleaseSystemState(); 190 : 191 : // 192 : // Retrieve a read-only pointer to the system state object that contains pointers to key stack 193 : // singletons. If the pointer is null, it indicates that the DeviceControllerFactory has yet to 194 : // be initialized properly, or has already been shut-down. 195 : // 196 : // This pointer ceases to be valid after a call to Shutdown has been made, or if all active 197 : // DeviceController instances have gone to 0. Consequently, care has to be taken to correctly 198 : // sequence the shutting down of active controllers with any entity that interacts with objects 199 : // present in the system state object. If de-coupling is desired, RetainSystemState and 200 : // ReleaseSystemState can be used to avoid this. 201 : // 202 : const DeviceControllerSystemState * GetSystemState() const { return mSystemState; } 203 : 204 : class ControllerFabricDelegate final : public chip::FabricTable::Delegate 205 : { 206 : public: 207 0 : CHIP_ERROR Init(SessionResumptionStorage * sessionResumptionStorage, Credentials::GroupDataProvider * groupDataProvider) 208 : { 209 0 : VerifyOrReturnError(sessionResumptionStorage != nullptr, CHIP_ERROR_INVALID_ARGUMENT); 210 0 : VerifyOrReturnError(groupDataProvider != nullptr, CHIP_ERROR_INVALID_ARGUMENT); 211 : 212 0 : mSessionResumptionStorage = sessionResumptionStorage; 213 0 : mGroupDataProvider = groupDataProvider; 214 0 : return CHIP_NO_ERROR; 215 : }; 216 : 217 0 : void OnFabricRemoved(const chip::FabricTable & fabricTable, FabricIndex fabricIndex) override 218 : { 219 : (void) fabricTable; 220 0 : if (mGroupDataProvider != nullptr) 221 : { 222 0 : mGroupDataProvider->RemoveFabric(fabricIndex); 223 : } 224 0 : ClearCASEResumptionStateOnFabricChange(fabricIndex); 225 0 : }; 226 : 227 0 : void OnFabricUpdated(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex) override 228 : { 229 : (void) fabricTable; 230 0 : ClearCASEResumptionStateOnFabricChange(fabricIndex); 231 0 : } 232 : 233 : private: 234 0 : void ClearCASEResumptionStateOnFabricChange(chip::FabricIndex fabricIndex) 235 : { 236 0 : VerifyOrReturn(mSessionResumptionStorage != nullptr); 237 0 : CHIP_ERROR err = mSessionResumptionStorage->DeleteAll(fabricIndex); 238 0 : if (err != CHIP_NO_ERROR) 239 : { 240 0 : ChipLogError(Controller, 241 : "Warning, failed to delete session resumption state for fabric index 0x%x: %" CHIP_ERROR_FORMAT, 242 : static_cast<unsigned>(fabricIndex), err.Format()); 243 : } 244 : } 245 : 246 : Credentials::GroupDataProvider * mGroupDataProvider = nullptr; 247 : SessionResumptionStorage * mSessionResumptionStorage = nullptr; 248 : }; 249 : 250 : private: 251 : DeviceControllerFactory() {} 252 : void PopulateInitParams(ControllerInitParams & controllerParams, const SetupParams & params); 253 : CHIP_ERROR InitSystemState(FactoryInitParams params); 254 : CHIP_ERROR InitSystemState(); 255 : void ControllerInitialized(const DeviceController & controller); 256 : 257 : uint16_t mListenPort; 258 : DeviceControllerSystemState * mSystemState = nullptr; 259 : PersistentStorageDelegate * mFabricIndependentStorage = nullptr; 260 : Crypto::OperationalKeystore * mOperationalKeystore = nullptr; 261 : Credentials::OperationalCertificateStore * mOpCertStore = nullptr; 262 : Credentials::CertificateValidityPolicy * mCertificateValidityPolicy = nullptr; 263 : SessionResumptionStorage * mSessionResumptionStorage = nullptr; 264 : bool mEnableServerInteractions = false; 265 : }; 266 : 267 : } // namespace Controller 268 : } // namespace chip