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