blob: 2f686ac455160a1f7301270f16ff98bd3528d02b [file] [log] [blame]
Sagar Dhawan55ef62f2020-05-13 20:35:27 -07001/*
2 *
Evgeny Margolisc69b6f12022-02-07 09:34:01 -08003 * Copyright (c) 2020-2022 Project CHIP Authors
Sagar Dhawan55ef62f2020-05-13 20:35:27 -07004 * Copyright (c) 2013-2017 Nest Labs, Inc.
5 * All rights reserved.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20/**
21 * @file
22 * Declaration of CHIP Device Controller, a common class
23 * that implements connecting and messaging and will later
24 * be expanded to support discovery, pairing and
25 * provisioning of CHIP devices.
26 *
27 */
28
Andrei Litvin1873e8c2020-10-12 10:52:26 -040029#pragma once
Sagar Dhawan55ef62f2020-05-13 20:35:27 -070030
Jiacheng Guoaba3c812021-12-09 02:18:03 +080031#include <app/CASEClientPool.h>
Pankaj Gargeb84a9d2021-11-16 13:59:57 -080032#include <app/CASESessionManager.h>
Jerry Johns964adbc2022-04-14 16:42:04 -070033#include <app/ClusterStateCache.h>
Terence Hampsonb6859d72022-08-05 13:48:11 -040034#include <app/OperationalSessionSetup.h>
35#include <app/OperationalSessionSetupPool.h>
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +020036#include <controller/AbstractDnssdDiscoveryController.h>
C Freeman798d7d22021-12-10 12:06:36 -050037#include <controller/AutoCommissioner.h>
C Freeman8ee96e42022-01-21 11:43:45 -050038#include <controller/CHIPCluster.h>
Sagar Dhawanae69dd72021-09-29 15:13:09 -070039#include <controller/CHIPDeviceControllerSystemState.h>
Pankaj Garga04576d2021-11-08 15:04:13 -080040#include <controller/CommissioneeDeviceProxy.h>
C Freeman798d7d22021-12-10 12:06:36 -050041#include <controller/CommissioningDelegate.h>
Boris Zbarskyd170a252022-03-31 20:51:58 -040042#include <controller/DevicePairingDelegate.h>
Pankaj Garga4907732021-05-07 09:08:45 -070043#include <controller/OperationalCredentialsDelegate.h>
Vivien Nicolas02d89002021-10-04 12:30:52 +020044#include <controller/SetUpCodePairer.h>
Pankaj Garg4052bdc2021-11-17 11:38:59 -080045#include <credentials/FabricTable.h>
Anush Nadathurb06bd8c2022-04-06 17:29:16 -070046#include <credentials/attestation_verifier/DeviceAttestationDelegate.h>
Tennessee Carmel-Veilleux22fb6c32022-02-22 16:49:16 -050047#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
Kevin Coppock2f853722022-06-16 09:53:08 -050048#include <inet/InetInterface.h>
Damian Królik8d41ec12021-09-28 16:22:13 +020049#include <lib/core/CHIPConfig.h>
Zang MingJie53dd5832021-09-03 03:05:16 +080050#include <lib/core/CHIPCore.h>
51#include <lib/core/CHIPPersistentStorageDelegate.h>
Tennessee Carmel-Veilleuxe5e09f52022-06-24 16:57:34 -040052#include <lib/core/DataModelTypes.h>
Martin Turon82bfcd52023-01-09 13:30:38 -080053#include <lib/core/TLV.h>
Zang MingJie53dd5832021-09-03 03:05:16 +080054#include <lib/support/DLLUtil.h>
Pankaj Garga04576d2021-11-08 15:04:13 -080055#include <lib/support/Pool.h>
Vivien Nicolasf24e6f12022-01-29 08:31:44 +010056#include <lib/support/SafeInt.h>
Zang MingJie53dd5832021-09-03 03:05:16 +080057#include <lib/support/SerializableIntegerSet.h>
Boris Zbarskyf72e0b72021-05-14 14:47:40 -040058#include <lib/support/Span.h>
C Freemanaa719692021-12-03 11:45:30 -050059#include <lib/support/ThreadOperationalDataset.h>
Song Guoa77a6622021-01-29 13:13:02 +080060#include <messaging/ExchangeMgr.h>
Zang MingJiec64d9d12021-05-13 00:09:08 +080061#include <protocols/secure_channel/MessageCounterManager.h>
Pankaj Garg0f443b82021-05-04 14:21:10 -070062#include <protocols/secure_channel/RendezvousParameters.h>
chrisdecenzo250d5f72021-07-21 19:28:45 -070063#include <protocols/user_directed_commissioning/UserDirectedCommissioning.h>
Boris Zbarsky8afc1f52023-03-09 23:58:40 -050064#include <system/SystemClock.h>
Zang MingJieeca9bff2021-09-23 03:19:51 +080065#include <transport/SessionManager.h>
Song Guofba2fdc2020-11-21 04:08:24 +080066#include <transport/TransportMgr.h>
Andrei Litvin992775c2020-10-01 20:20:52 -040067#include <transport/raw/UDP.h>
Sagar Dhawan55ef62f2020-05-13 20:35:27 -070068
Vivien Nicolas65c39822021-04-30 00:39:25 +020069#if CONFIG_DEVICE_LAYER
70#include <platform/CHIPDeviceLayer.h>
71#endif
72
Song Guo87142e02021-04-21 09:00:00 +080073#if CONFIG_NETWORK_LAYER_BLE
74#include <ble/BleLayer.h>
75#endif
Vivien Nicolas02d89002021-10-04 12:30:52 +020076#include <controller/DeviceDiscoveryDelegate.h>
Vivien Nicolase047d272021-04-13 15:39:41 +020077
Sagar Dhawan55ef62f2020-05-13 20:35:27 -070078namespace chip {
Sagar Dhawan55ef62f2020-05-13 20:35:27 -070079
Pankaj Garg047424f2020-11-10 21:56:59 -080080namespace Controller {
Pankaj Garg09e25822020-10-22 09:14:12 -070081
chrisdecenzo250d5f72021-07-21 19:28:45 -070082using namespace chip::Protocols::UserDirectedCommissioning;
83
Damian Królik8d41ec12021-09-28 16:22:13 +020084constexpr uint16_t kNumMaxActiveDevices = CHIP_CONFIG_CONTROLLER_MAX_ACTIVE_DEVICES;
Sagar Dhawan55ef62f2020-05-13 20:35:27 -070085
C Freemane86bb352021-05-26 19:19:40 -040086// Raw functions for cluster callbacks
Vivien Nicolasf24e6f12022-01-29 08:31:44 +010087void OnBasicFailure(void * context, CHIP_ERROR err);
C Freemane86bb352021-05-26 19:19:40 -040088
Song Guo3cb69ff2021-04-01 20:58:25 +080089struct ControllerInitParams
90{
Andrei Litvinb7924632022-03-03 15:29:54 -050091 DeviceControllerSystemState * systemState = nullptr;
Andrei Litvinb7924632022-03-03 15:29:54 -050092 DeviceDiscoveryDelegate * deviceDiscoveryDelegate = nullptr;
Pankaj Gargaeebd192021-05-14 13:17:50 -070093 OperationalCredentialsDelegate * operationalCredentialsDelegate = nullptr;
Pankaj Garg7b000572021-08-13 20:14:29 -070094
95 /* The following keypair must correspond to the public key used for generating
96 controllerNOC. It's used by controller to establish CASE sessions with devices */
Tennessee Carmel-Veilleux8d758452022-01-26 23:27:11 -050097 Crypto::P256Keypair * operationalKeypair = nullptr;
Pankaj Garg7b000572021-08-13 20:14:29 -070098
Tennessee Carmel-Veilleux51cbb532022-05-16 20:37:21 -040099 /**
100 * Controls whether or not the operationalKeypair should be owned by the caller.
101 * By default, this is false, but if the keypair cannot be serialized, then
Boris Zbarsky78728ab2022-05-17 06:31:15 -0400102 * setting this to true will allow the caller to manage this keypair's lifecycle.
Tennessee Carmel-Veilleux51cbb532022-05-16 20:37:21 -0400103 */
104 bool hasExternallyOwnedOperationalKeypair = false;
105
Pankaj Garg7b000572021-08-13 20:14:29 -0700106 /* The following certificates must be in x509 DER format */
107 ByteSpan controllerNOC;
108 ByteSpan controllerICAC;
109 ByteSpan controllerRCAC;
110
Jerry Johns0eed15d2022-08-01 17:56:38 -0700111 /**
112 * Controls whether we permit multiple DeviceController instances to exist
113 * on the same logical fabric (identified by the tuple of the fabric's
114 * root public key + fabric id).
115 *
116 * Each controller instance will be associated with its own FabricIndex.
117 * This pivots the FabricTable to tracking identities instead of fabrics,
118 * represented by FabricInfo instances that can have colliding logical fabrics.
119 *
120 */
121 bool permitMultiControllerFabrics = false;
122
Jerry Johns75372d82022-03-01 06:32:40 -0800123 //
124 // Controls enabling server cluster interactions on a controller. This in turn
125 // causes the following to get enabled:
126 //
127 // - Advertisement of active controller operational identities.
128 //
129 bool enableServerInteractions = false;
130
Boris Zbarsky01bfdd02023-04-06 20:40:13 -0400131 /**
132 * Controls whether shutdown of the controller removes the corresponding
133 * entry from the fabric table. For now the removal is just from the
134 * in-memory table, not from storage, which means that after controller
135 * shutdown the storage and the in-memory fabric table will be out of sync.
136 * This is acceptable for implementations that don't actually store any of
137 * the fabric table information, but if someone wants a true removal at some
138 * point another option will need to be added here.
139 */
140 bool removeFromFabricTableOnShutdown = true;
141
Vivien Nicolas401c3932022-05-11 13:04:29 +0200142 chip::VendorId controllerVendorId;
Song Guo3cb69ff2021-04-01 20:58:25 +0800143};
144
Andrei Litvind4da2fa2021-04-28 11:25:25 -0400145struct CommissionerInitParams : public ControllerInitParams
146{
C Freeman8ffe4222022-02-02 14:21:16 -0500147 DevicePairingDelegate * pairingDelegate = nullptr;
148 CommissioningDelegate * defaultCommissioner = nullptr;
Tennessee Carmel-Veilleuxa777a802022-05-17 22:56:37 -0400149 // Device attestation verifier instance for the commissioning.
150 // If null, the globally set attestation verifier (e.g. from GetDeviceAttestationVerifier()
151 // singleton) will be used.
152 Credentials::DeviceAttestationVerifier * deviceAttestationVerifier = nullptr;
Andrei Litvind4da2fa2021-04-28 11:25:25 -0400153};
154
Pankaj Garg047424f2020-11-10 21:56:59 -0800155/**
156 * @brief
157 * Controller applications can use this class to communicate with already paired CHIP devices. The
158 * application is required to provide access to the persistent storage, where the paired device information
159 * is stored. This object of this class can be initialized with the data from the storage (List of devices,
160 * and device pairing information for individual devices). Alternatively, this class can retrieve the
161 * relevant information when the application tries to communicate with the device
162 */
Zang MingJie76997612022-05-30 23:59:55 +0800163class DLL_EXPORT DeviceController : public AbstractDnssdDiscoveryController
Pankaj Garga43ec922020-06-30 06:03:18 -0700164{
165public:
Pankaj Garg047424f2020-11-10 21:56:59 -0800166 DeviceController();
Andrei Litvind80d5932022-03-16 21:15:16 -0400167 ~DeviceController() override {}
Sagar Dhawan55ef62f2020-05-13 20:35:27 -0700168
Pankaj Garg7b000572021-08-13 20:14:29 -0700169 CHIP_ERROR Init(ControllerInitParams params);
Song Guo3cb69ff2021-04-01 20:58:25 +0800170
Jerry Johns6cf91db2021-06-14 11:53:53 -0700171 /**
172 * @brief
173 * Tears down the entirety of the stack, including destructing key objects in the system.
174 * This expects to be called with external thread synchronization, and will not internally
175 * grab the CHIP stack lock.
176 *
177 * This will also not stop the CHIP event queue / thread (if one exists). Consumers are expected to
Martin Turond24eff12021-12-17 06:21:23 -0800178 * ensure this happened before calling this method.
Jerry Johns6cf91db2021-06-14 11:53:53 -0700179 */
Michael Spang63870492022-06-28 08:41:08 -0400180 virtual void Shutdown();
Sagar Dhawan55ef62f2020-05-13 20:35:27 -0700181
Jerry Johnsc503a972022-04-15 15:22:58 -0700182 SessionManager * SessionMgr()
183 {
184 if (mSystemState)
185 {
186 return mSystemState->SessionMgr();
187 }
188
189 return nullptr;
190 }
191
Jerry Johnsd94cbdc2022-07-26 08:07:06 -0700192 CHIP_ERROR GetPeerAddressAndPort(NodeId peerId, Inet::IPAddress & addr, uint16_t & port);
Pankaj Gargfee3d262021-10-17 19:31:32 -0700193
Vivien Nicolase047d272021-04-13 15:39:41 +0200194 /**
Kevin Coppock2f853722022-06-16 09:53:08 -0500195 * @brief
196 * Looks up the PeerAddress for an established CASE session.
197 *
Jerry Johnsd94cbdc2022-07-26 08:07:06 -0700198 * @param[in] nodeId the NodeId of the target.
Kevin Coppock2f853722022-06-16 09:53:08 -0500199 * @param[out] addr the PeerAddress to be filled on success
200 *
201 * @return CHIP_ERROR CHIP_ERROR_NOT_CONNECTED if no CASE session exists for the device
202 */
203 CHIP_ERROR GetPeerAddress(NodeId nodeId, Transport::PeerAddress & addr);
204
Jerry Johnsd94cbdc2022-07-26 08:07:06 -0700205 ScopedNodeId GetPeerScopedId(NodeId nodeId) { return ScopedNodeId(nodeId, GetFabricIndex()); }
206
Kevin Coppock2f853722022-06-16 09:53:08 -0500207 /**
Boris Zbarsky11651522022-05-19 13:04:39 -0400208 * This function finds the device corresponding to deviceId, and establishes
209 * a CASE session with it.
210 *
211 * Once the CASE session is successfully established the `onConnectedDevice`
212 * callback is called. This can happen before GetConnectedDevice returns if
213 * there is an existing CASE session.
214 *
215 * If a CASE sessions fails to be established, the `onError` callback will
216 * be called. This can also happen before GetConnectedDevice returns.
217 *
218 * An error return from this function means that neither callback has been
219 * called yet, and neither callback will be called in the future.
Pankaj Gargda453462021-06-22 19:53:34 -0700220 */
Tennessee Carmel-Veilleuxe5e09f52022-06-24 16:57:34 -0400221 CHIP_ERROR GetConnectedDevice(NodeId peerNodeId, Callback::Callback<OnDeviceConnected> * onConnection,
Andrei Litvin5a288652022-03-11 16:23:36 -0500222 chip::Callback::Callback<OnDeviceConnectionFailure> * onFailure)
Pankaj Garga04576d2021-11-08 15:04:13 -0800223 {
Tennessee Carmel-Veilleuxe5e09f52022-06-24 16:57:34 -0400224 VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE);
Jerry Johnsd94cbdc2022-07-26 08:07:06 -0700225 mSystemState->CASESessionMgr()->FindOrEstablishSession(ScopedNodeId(peerNodeId, GetFabricIndex()), onConnection, onFailure);
Boris Zbarsky11651522022-05-19 13:04:39 -0400226 return CHIP_NO_ERROR;
Pankaj Garga04576d2021-11-08 15:04:13 -0800227 }
Pankaj Gargda453462021-06-22 19:53:34 -0700228
229 /**
Pankaj Garga04576d2021-11-08 15:04:13 -0800230 * @brief
231 * Compute a PASE verifier and passcode ID for the desired setup pincode.
232 *
233 * This can be used to open a commissioning window on the device for
234 * additional administrator commissioning.
235 *
236 * @param[in] iterations The number of iterations to use when generating the verifier
237 * @param[in] setupPincode The desired PIN code to use
238 * @param[in] salt The 16-byte salt for verifier computation
alexhqwang9279ab22022-02-18 03:20:52 -0800239 * @param[out] outVerifier The Spake2pVerifier to be populated on success
Pankaj Garga04576d2021-11-08 15:04:13 -0800240 *
241 * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error
242 */
Evgeny Margolis27277392022-03-09 19:29:14 -0800243 CHIP_ERROR ComputePASEVerifier(uint32_t iterations, uint32_t setupPincode, const ByteSpan & salt,
244 Spake2pVerifier & outVerifier);
Vivien Nicolas74bfa692021-04-08 18:19:33 +0200245
Vivien Nicolas02d89002021-10-04 12:30:52 +0200246 void RegisterDeviceDiscoveryDelegate(DeviceDiscoveryDelegate * delegate) { mDeviceDiscoveryDelegate = delegate; }
Jerry Johns6cf91db2021-06-14 11:53:53 -0700247
Sagar Dhawan57b104c2020-05-21 13:31:39 -0700248 /**
Pankaj Garg6efec202021-08-25 10:47:29 -0700249 * @brief Get the Compressed Fabric ID assigned to the device.
Yufeng Wangb728b742021-06-16 08:04:17 -0700250 */
Tennessee Carmel-Veilleuxe5e09f52022-06-24 16:57:34 -0400251 uint64_t GetCompressedFabricId() const
252 {
253 const auto * fabricInfo = GetFabricInfo();
254 return (fabricInfo != nullptr) ? static_cast<uint64_t>(fabricInfo->GetCompressedFabricId()) : kUndefinedCompressedFabricId;
255 }
256
257 /**
258 * @brief Get the Compressed Fabric Id as a big-endian 64 bit octet string.
259 *
260 * Output span is resized to 8 bytes on success if it was larger.
261 *
262 * @param outBytes span to contain the compressed fabric ID, must be at least 8 bytes long
263 * @return CHIP_ERROR_BUFFER_TOO_SMALL if `outBytes` is too small, CHIP_ERROR_INVALID_FABRIC_INDEX
264 * if the controller is somehow not associated with a fabric (internal error!) or
265 * CHIP_NO_ERROR on success.
266 */
267 CHIP_ERROR GetCompressedFabricIdBytes(MutableByteSpan & outBytes) const;
Pankaj Garg6efec202021-08-25 10:47:29 -0700268
269 /**
270 * @brief Get the raw Fabric ID assigned to the device.
271 */
Tennessee Carmel-Veilleuxe5e09f52022-06-24 16:57:34 -0400272 uint64_t GetFabricId() const
273 {
274 const auto * fabricInfo = GetFabricInfo();
275 return (fabricInfo != nullptr) ? static_cast<uint64_t>(fabricInfo->GetFabricId()) : kUndefinedFabricId;
276 }
Yufeng Wangb728b742021-06-16 08:04:17 -0700277
Michael Sandstedtd625d352022-01-25 22:31:41 -0600278 /**
279 * @brief Get the Node ID of this instance.
280 */
Tennessee Carmel-Veilleuxe5e09f52022-06-24 16:57:34 -0400281 NodeId GetNodeId() const
Jean-Francois Penvenae2a7e82022-03-02 17:33:06 -0500282 {
Tennessee Carmel-Veilleuxe5e09f52022-06-24 16:57:34 -0400283 const auto * fabricInfo = GetFabricInfo();
284 return (fabricInfo != nullptr) ? static_cast<uint64_t>(fabricInfo->GetNodeId()) : kUndefinedNodeId;
Jean-Francois Penvenae2a7e82022-03-02 17:33:06 -0500285 }
286
Tennessee Carmel-Veilleuxe5e09f52022-06-24 16:57:34 -0400287 /**
288 * @brief Get the root public key for the fabric
289 *
290 * @param outRootPublicKey reference to public key object that gets updated on success.
291 *
292 * @return CHIP_NO_ERROR on success, CHIP_ERROR_INCORRECT_STATE if fabric table is unset, or another internal error
293 * on storage access failure.
294 */
295 CHIP_ERROR GetRootPublicKey(Crypto::P256PublicKey & outRootPublicKey) const;
296
297 FabricIndex GetFabricIndex() const { return mFabricIndex; }
Ricardo Casallas0b10bc82022-03-07 11:43:47 -0500298
Tennessee Carmel-Veilleux8cbfd2f2022-06-13 18:59:23 -0400299 const FabricTable * GetFabricTable() const
300 {
301 if (mSystemState == nullptr)
302 {
303 return nullptr;
304 }
305 return mSystemState->Fabrics();
306 }
307
Jerry Johnsf68cd642022-01-28 16:39:08 -0800308 OperationalCredentialsDelegate * GetOperationalCredentialsDelegate() { return mOperationalCredentialsDelegate; }
309
Andrei Litvin5a288652022-03-11 16:23:36 -0500310 /**
Tennessee Carmel-Veilleux51cbb532022-05-16 20:37:21 -0400311 * @brief
312 * Reconfigures a new set of operational credentials to be used with this
313 * controller given ControllerInitParams state.
314 *
315 * WARNING: This is a low-level method that should only be called directly
316 * if you know exactly how this will interact with controller state,
317 * since there are several integrations that do this call for you.
318 * It can be used for fine-grained dependency injection of a controller's
319 * NOC and operational keypair.
320 */
321 CHIP_ERROR InitControllerNOCChain(const ControllerInitParams & params);
322
Pankaj Garg047424f2020-11-10 21:56:59 -0800323protected:
324 enum class State
325 {
326 NotInitialized,
327 Initialized
328 };
329
Tennessee Carmel-Veilleuxe5e09f52022-06-24 16:57:34 -0400330 // This is not public to avoid users of DeviceController relying on "innards" access to
331 // the raw fabric table. Everything needed should be available with getters on DeviceController.
332 const FabricInfo * GetFabricInfo() const
333 {
334 VerifyOrReturnError((mState == State::Initialized) && (mFabricIndex != kUndefinedFabricIndex), nullptr);
335 VerifyOrReturnError(GetFabricTable() != nullptr, nullptr);
336
337 return GetFabricTable()->FindFabricWithIndex(mFabricIndex);
338 }
339
Pankaj Garg047424f2020-11-10 21:56:59 -0800340 State mState;
341
Tennessee Carmel-Veilleuxe5e09f52022-06-24 16:57:34 -0400342 FabricIndex mFabricIndex = kUndefinedFabricIndex;
Pankaj Garg6efec202021-08-25 10:47:29 -0700343
Boris Zbarsky01bfdd02023-04-06 20:40:13 -0400344 bool mRemoveFromFabricTableOnShutdown = true;
345
cecille81850192021-05-11 21:43:14 -0400346 // TODO(cecille): Make this configuarable.
347 static constexpr int kMaxCommissionableNodes = 10;
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200348 Dnssd::DiscoveredNodeData mCommissionableNodes[kMaxCommissionableNodes];
Sagar Dhawanae69dd72021-09-29 15:13:09 -0700349 DeviceControllerSystemState * mSystemState = nullptr;
Pankaj Garg047424f2020-11-10 21:56:59 -0800350
Song Guo3cb69ff2021-04-01 20:58:25 +0800351 ControllerDeviceInitParams GetControllerDeviceInitParams();
Pankaj Garg047424f2020-11-10 21:56:59 -0800352
Pankaj Gargaeebd192021-05-14 13:17:50 -0700353 OperationalCredentialsDelegate * mOperationalCredentialsDelegate;
354
Vivien Nicolas401c3932022-05-11 13:04:29 +0200355 chip::VendorId mVendorId;
Pankaj Garg7b000572021-08-13 20:14:29 -0700356
Boris Zbarsky5081bbe2021-07-12 11:53:06 -0400357 DiscoveredNodeList GetDiscoveredNodes() override { return DiscoveredNodeList(mCommissionableNodes); }
Pankaj Garg047424f2020-11-10 21:56:59 -0800358};
359
Zang MingJie6109d142022-04-22 06:19:42 +0800360#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
361using UdcTransportMgr = TransportMgr<Transport::UDP /* IPv6 */
362#if INET_CONFIG_ENABLE_IPV4
363 ,
364 Transport::UDP /* IPv4 */
365#endif
366 >;
367#endif
368
Pankaj Garg047424f2020-11-10 21:56:59 -0800369/**
chrisdecenzo620ef8f2022-11-22 09:10:02 -0800370 * @brief Callback prototype for ExtendArmFailSafe command.
371 */
372typedef void (*OnExtendFailsafeSuccess)(
373 void * context, const app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
374typedef void (*OnExtendFailsafeFailure)(void * context, CHIP_ERROR error);
375
376/**
Pankaj Garg047424f2020-11-10 21:56:59 -0800377 * @brief
378 * The commissioner applications can use this class to pair new/unpaired CHIP devices. The application is
379 * required to provide write access to the persistent storage, where the paired device information
380 * will be stored.
381 */
chrisdecenzo250d5f72021-07-21 19:28:45 -0700382class DLL_EXPORT DeviceCommissioner : public DeviceController,
383#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
384 public Protocols::UserDirectedCommissioning::InstanceNameResolver,
chrisdecenzo250d5f72021-07-21 19:28:45 -0700385#endif
C Freeman1ee93662022-02-03 09:51:04 -0500386 public SessionEstablishmentDelegate,
Jerry Johns964adbc2022-04-14 16:42:04 -0700387 public app::ClusterStateCache::Callback
Pankaj Garg047424f2020-11-10 21:56:59 -0800388{
389public:
390 DeviceCommissioner();
Andrei Litvind80d5932022-03-16 21:15:16 -0400391 ~DeviceCommissioner() override {}
Pankaj Garg047424f2020-11-10 21:56:59 -0800392
chrisdecenzo250d5f72021-07-21 19:28:45 -0700393#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
394 /**
395 * Set port for User Directed Commissioning
396 */
397 CHIP_ERROR SetUdcListenPort(uint16_t listenPort);
398#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
399
Pankaj Garg047424f2020-11-10 21:56:59 -0800400 /**
Pankaj Garg0238a6c2021-05-10 07:33:19 -0700401 * Commissioner-specific initialization, includes parameters such as the pairing delegate.
Pankaj Garg047424f2020-11-10 21:56:59 -0800402 */
Pankaj Garg7b000572021-08-13 20:14:29 -0700403 CHIP_ERROR Init(CommissionerInitParams params);
Pankaj Garg047424f2020-11-10 21:56:59 -0800404
Jerry Johns6cf91db2021-06-14 11:53:53 -0700405 /**
406 * @brief
407 * Tears down the entirety of the stack, including destructing key objects in the system.
408 * This is not a thread-safe API, and should be called with external synchronization.
409 *
410 * Please see implementation for more details.
411 */
Michael Spang63870492022-06-28 08:41:08 -0400412 void Shutdown() override;
Pankaj Garg047424f2020-11-10 21:56:59 -0800413
414 // ----- Connection Management -----
415 /**
416 * @brief
Vivien Nicolas02d89002021-10-04 12:30:52 +0200417 * Pair a CHIP device with the provided code. The code can be either a QRCode
418 * or a Manual Setup Code.
419 * Use registered DevicePairingDelegate object to receive notifications on
420 * pairing status updates.
421 *
422 * Note: Pairing process requires that the caller has registered PersistentStorageDelegate
423 * in the Init() call.
424 *
425 * @param[in] remoteDeviceId The remote device Id.
426 * @param[in] setUpCode The setup code for connecting to the device
Vivien Nicolasa60fb5a2022-09-12 18:23:18 +0200427 * @param[in] discoveryType The network discovery type, defaults to DiscoveryType::kAll.
Vivien Nicolas9f93a412023-06-08 18:16:15 +0200428 * @param[in] resolutionData Optional resolution data previously discovered on the network for the target device.
Vivien Nicolas02d89002021-10-04 12:30:52 +0200429 */
Vivien Nicolas9f93a412023-06-08 18:16:15 +0200430 CHIP_ERROR PairDevice(NodeId remoteDeviceId, const char * setUpCode, DiscoveryType discoveryType = DiscoveryType::kAll,
431 Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);
Vivien Nicolasa60fb5a2022-09-12 18:23:18 +0200432 CHIP_ERROR PairDevice(NodeId remoteDeviceId, const char * setUpCode, const CommissioningParameters & CommissioningParameters,
Vivien Nicolas9f93a412023-06-08 18:16:15 +0200433 DiscoveryType discoveryType = DiscoveryType::kAll,
434 Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);
Vivien Nicolas02d89002021-10-04 12:30:52 +0200435
436 /**
437 * @brief
Pankaj Garg047424f2020-11-10 21:56:59 -0800438 * Pair a CHIP device with the provided Rendezvous connection parameters.
439 * Use registered DevicePairingDelegate object to receive notifications on
440 * pairing status updates.
441 *
442 * Note: Pairing process requires that the caller has registered PersistentStorageDelegate
443 * in the Init() call.
444 *
445 * @param[in] remoteDeviceId The remote device Id.
C Freemanaa719692021-12-03 11:45:30 -0500446 * @param[in] rendezvousParams The Rendezvous connection parameters
Pankaj Garg047424f2020-11-10 21:56:59 -0800447 */
C Freemanaa719692021-12-03 11:45:30 -0500448 CHIP_ERROR PairDevice(NodeId remoteDeviceId, RendezvousParameters & rendezvousParams);
Yufeng Wangc6f65842023-05-15 19:53:07 -0700449
Kevin Schoedelfcd97852021-12-07 17:16:40 -0500450 /**
451 * @overload
452 * @param[in] remoteDeviceId The remote device Id.
453 * @param[in] rendezvousParams The Rendezvous connection parameters
454 * @param[in] commissioningParams The commissioning parameters (uses default if not supplied)
455 */
C Freemanaa719692021-12-03 11:45:30 -0500456 CHIP_ERROR PairDevice(NodeId remoteDeviceId, RendezvousParameters & rendezvousParams,
457 CommissioningParameters & commissioningParams);
458
459 /**
460 * @brief
461 * Start establishing a PASE connection with a node for the purposes of commissioning.
462 * Commissioners that wish to use the auto-commissioning functions should use the
463 * supplied "PairDevice" functions above to automatically establish a connection then
464 * perform commissioning. This function is intended to be use by commissioners that
465 * are not using the supplied auto-commissioner.
466 *
467 * This function is non-blocking. PASE is established once the DevicePairingDelegate
468 * receives the OnPairingComplete call.
469 *
470 * PASE connections can only be established with nodes that have their commissioning
471 * window open. The PASE connection will fail if this window is not open and the
472 * OnPairingComplete will be called with an error.
473 *
474 * @param[in] remoteDeviceId The remote device Id.
Kevin Schoedelfcd97852021-12-07 17:16:40 -0500475 * @param[in] params The Rendezvous connection parameters
C Freemanaa719692021-12-03 11:45:30 -0500476 */
477 CHIP_ERROR EstablishPASEConnection(NodeId remoteDeviceId, RendezvousParameters & params);
478
479 /**
480 * @brief
C Freeman3382a5f2022-03-09 16:06:59 -0500481 * Start establishing a PASE connection with a node for the purposes of commissioning.
482 * Commissioners that wish to use the auto-commissioning functions should use the
483 * supplied "PairDevice" functions above to automatically establish a connection then
484 * perform commissioning. This function is intended to be used by commissioners that
485 * are not using the supplied auto-commissioner.
486 *
487 * This function is non-blocking. PASE is established once the DevicePairingDelegate
488 * receives the OnPairingComplete call.
489 *
490 * PASE connections can only be established with nodes that have their commissioning
491 * window open. The PASE connection will fail if this window is not open and in that case
492 * OnPairingComplete will be called with an error.
493 *
494 * @param[in] remoteDeviceId The remote device Id.
495 * @param[in] setUpCode The setup code for connecting to the device
Vivien Nicolasa60fb5a2022-09-12 18:23:18 +0200496 * @param[in] discoveryType The network discovery type, defaults to DiscoveryType::kAll.
Vivien Nicolas9f93a412023-06-08 18:16:15 +0200497 * @param[in] resolutionData Optional resolution data previously discovered on the network for the target device.
C Freeman3382a5f2022-03-09 16:06:59 -0500498 */
Vivien Nicolasa60fb5a2022-09-12 18:23:18 +0200499 CHIP_ERROR EstablishPASEConnection(NodeId remoteDeviceId, const char * setUpCode,
Vivien Nicolas9f93a412023-06-08 18:16:15 +0200500 DiscoveryType discoveryType = DiscoveryType::kAll,
501 Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);
C Freeman3382a5f2022-03-09 16:06:59 -0500502
503 /**
504 * @brief
C Freemanaa719692021-12-03 11:45:30 -0500505 * Start the auto-commissioning process on a node after establishing a PASE connection.
506 * This function is intended to be used in conjunction with the EstablishPASEConnection
507 * function. It can be called either before or after the DevicePairingDelegate receives
508 * the OnPairingComplete call. Commissioners that want to perform simple auto-commissioning
509 * should use the supplied "PairDevice" functions above, which will establish the PASE
510 * connection and commission automatically.
511 *
512 * @param[in] remoteDeviceId The remote device Id.
513 * @param[in] params The commissioning parameters
514 */
515 CHIP_ERROR Commission(NodeId remoteDeviceId, CommissioningParameters & params);
C Freeman3382a5f2022-03-09 16:06:59 -0500516 CHIP_ERROR Commission(NodeId remoteDeviceId);
Pankaj Garg047424f2020-11-10 21:56:59 -0800517
Anush Nadathurb06bd8c2022-04-06 17:29:16 -0700518 /**
519 * @brief
520 * This function instructs the commissioner to proceed to the next stage of commissioning after
Jeff Tung89f5c8a2022-09-06 18:30:08 -0700521 * attestation is reported to an installed attestation delegate.
Anush Nadathurb06bd8c2022-04-06 17:29:16 -0700522 *
523 * @param[in] device The device being commissioned.
524 * @param[in] attestationResult The attestation result to use instead of whatever the device
525 * attestation verifier came up with. May be a success or an error result.
526 */
527 CHIP_ERROR
Jeff Tung89f5c8a2022-09-06 18:30:08 -0700528 ContinueCommissioningAfterDeviceAttestation(DeviceProxy * device, Credentials::AttestationVerificationResult attestationResult);
Anush Nadathurb06bd8c2022-04-06 17:29:16 -0700529
Pankaj Garga04576d2021-11-08 15:04:13 -0800530 CHIP_ERROR GetDeviceBeingCommissioned(NodeId deviceId, CommissioneeDeviceProxy ** device);
531
Pankaj Garg047424f2020-11-10 21:56:59 -0800532 /**
533 * @brief
534 * This function stops a pairing process that's in progress. It does not delete the pairing of a previously
535 * paired device.
536 *
537 * @param[in] remoteDeviceId The remote device Id.
538 *
539 * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error
540 */
541 CHIP_ERROR StopPairing(NodeId remoteDeviceId);
542
543 /**
544 * @brief
545 * Remove pairing for a paired device. If the device is currently being paired, it'll stop the pairing process.
546 *
547 * @param[in] remoteDeviceId The remote device Id.
548 *
549 * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error
550 */
551 CHIP_ERROR UnpairDevice(NodeId remoteDeviceId);
Jiacheng Guoe4ac46a2020-11-11 00:04:34 +0800552
Pankaj Garg0f443b82021-05-04 14:21:10 -0700553 //////////// SessionEstablishmentDelegate Implementation ///////////////
554 void OnSessionEstablishmentError(CHIP_ERROR error) override;
Zang MingJie477862d2022-04-20 04:52:22 +0800555 void OnSessionEstablished(const SessionHandle & session) override;
Pankaj Garge1c1bb12020-07-02 08:55:46 -0700556
Pankaj Garg047424f2020-11-10 21:56:59 -0800557 void RendezvousCleanup(CHIP_ERROR status);
558
C Freeman798d7d22021-12-10 12:06:36 -0500559 void PerformCommissioningStep(DeviceProxy * device, CommissioningStage step, CommissioningParameters & params,
C Freeman8ee96e42022-01-21 11:43:45 -0500560 CommissioningDelegate * delegate, EndpointId endpoint, Optional<System::Clock::Timeout> timeout);
C Freeman798d7d22021-12-10 12:06:36 -0500561
C Freeman09a49212022-01-24 21:19:43 -0500562 /**
563 * @brief
564 * This function validates the Attestation Information sent by the device.
565 *
C Freemanb541dee2022-02-17 01:14:48 -0500566 * @param[in] info Structure contatining all the required information for validating the device attestation.
C Freeman09a49212022-01-24 21:19:43 -0500567 */
C Freemanb541dee2022-02-17 01:14:48 -0500568 CHIP_ERROR ValidateAttestationInfo(const Credentials::DeviceAttestationVerifier::AttestationInfo & info);
C Freeman09a49212022-01-24 21:19:43 -0500569
C Freeman9fc0d2e2022-01-28 10:52:04 -0500570 /**
571 * @brief
572 * Sends CommissioningStepComplete report to the commissioning delegate. Function will fill in current step.
573 * @params[in] err error from the current step
574 * @params[in] report report to send. Current step will be filled in automatically
575 */
C Freeman8d6805f2022-01-26 22:31:49 -0500576 void
577 CommissioningStageComplete(CHIP_ERROR err,
578 CommissioningDelegate::CommissioningReport report = CommissioningDelegate::CommissioningReport());
C Freemane86bb352021-05-26 19:19:40 -0400579
chrisdecenzoa604ce22022-08-15 20:44:23 -0700580 /**
581 * @brief
582 * This function is called by the DevicePairingDelegate to indicate that network credentials have been set
583 * on the CommissioningParameters of the CommissioningDelegate using CommissioningDelegate.SetCommissioningParameters().
584 * As a result, commissioning can advance to the next stage.
585 *
586 * The DevicePairingDelegate may call this method from the OnScanNetworksSuccess and OnScanNetworksFailure callbacks,
587 * or it may call this method after obtaining network credentials using asyncronous methods (prompting user, cloud API call,
588 * etc).
589 *
chrisdecenzo620ef8f2022-11-22 09:10:02 -0800590 * If an error happens in the subsequent network commissioning step (either NetworkConfig or ConnectNetwork commands)
591 * then the DevicePairingDelegate will receive the error in completionStatus.networkCommissioningStatus and the
592 * commissioning stage will return to kNeedsNetworkCreds so that the DevicePairingDelegate can re-attempt with new
593 * network information. The DevicePairingDelegate can exit the commissioning process by calling StopPairing.
594 *
chrisdecenzoa604ce22022-08-15 20:44:23 -0700595 * @return CHIP_ERROR The return status. Returns CHIP_ERROR_INCORRECT_STATE if not in the correct state (kNeedsNetworkCreds).
596 */
597 CHIP_ERROR NetworkCredentialsReady();
598
chrisdecenzo06457ae2022-08-16 17:06:29 -0700599 /**
600 * @brief
601 * This function returns the current CommissioningStage for this commissioner.
602 */
603 CommissioningStage GetCommissioningStage() { return mCommissioningStage; }
604
Song Guo87142e02021-04-21 09:00:00 +0800605#if CONFIG_NETWORK_LAYER_BLE
chrisdecenzo654104c2022-03-02 15:11:33 -0800606#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
607 /**
608 * @brief
609 * Prior to commissioning, the Controller should make sure the BleLayer transport
610 * is set to the Commissioner transport and not the Server transport.
611 */
612 void ConnectBleTransportToSelf();
613#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
614
Song Guo87142e02021-04-21 09:00:00 +0800615 /**
616 * @brief
617 * Once we have finished all commissioning work, the Controller should close the BLE
618 * connection to the device and establish CASE session / another PASE session to the device
619 * if needed.
Song Guo87142e02021-04-21 09:00:00 +0800620 */
Michael Spang63870492022-06-28 08:41:08 -0400621 void CloseBleConnection();
Song Guo87142e02021-04-21 09:00:00 +0800622#endif
cecille81850192021-05-11 21:43:14 -0400623 /**
624 * @brief
cecille81850192021-05-11 21:43:14 -0400625 * Discover all devices advertising as commissionable.
626 * Should be called on main loop thread.
C Freeman8a535282021-06-22 22:54:19 -0400627 * * @param[in] filter Browse filter - controller will look for only the specified subtype.
cecille81850192021-05-11 21:43:14 -0400628 * @return CHIP_ERROR The return status
629 */
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200630 CHIP_ERROR DiscoverCommissionableNodes(Dnssd::DiscoveryFilter filter);
cecille81850192021-05-11 21:43:14 -0400631
632 /**
Boris Zbarskybd83c1a2022-10-04 16:22:19 -0400633 * Stop commissionable discovery triggered by a previous
634 * DiscoverCommissionableNodes call.
635 */
636 CHIP_ERROR StopCommissionableDiscovery();
637
638 /**
cecille81850192021-05-11 21:43:14 -0400639 * @brief
640 * Returns information about discovered devices.
641 * Should be called on main loop thread.
Sharad Binjolaf78d60e2021-06-17 05:50:45 -0700642 * @return const DiscoveredNodeData* info about the selected device. May be nullptr if no information has been returned yet.
cecille81850192021-05-11 21:43:14 -0400643 */
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200644 const Dnssd::DiscoveredNodeData * GetDiscoveredDevice(int idx);
cecille81850192021-05-11 21:43:14 -0400645
646 /**
647 * @brief
648 * Returns the max number of commissionable nodes this commissioner can track mdns information for.
649 * @return int The max number of commissionable nodes supported
650 */
651 int GetMaxCommissionableNodesSupported() { return kMaxCommissionableNodes; }
652
chrisdecenzo250d5f72021-07-21 19:28:45 -0700653#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
654 /**
655 * @brief
656 * Called when a UDC message is received specifying the given instanceName
657 * This method indicates that UDC Server needs the Commissionable Node corresponding to
658 * the given instance name to be found. UDC Server will wait for OnCommissionableNodeFound.
659 *
660 * @param instanceName DNS-SD instance name for the client requesting commissioning
661 *
662 */
663 void FindCommissionableNode(char * instanceName) override;
664
665 /**
666 * @brief
C Freeman3a339bc2021-12-03 14:48:02 -0500667 * Return the UDC Server instance
668 *
669 */
670 UserDirectedCommissioningServer * GetUserDirectedCommissioningServer() { return mUdcServer; }
671#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
672
C Freeman3a339bc2021-12-03 14:48:02 -0500673 /**
674 * @brief
Kamil Kasperczykd9e02a02021-10-12 09:19:23 +0200675 * Overrides method from AbstractDnssdDiscoveryController
chrisdecenzo250d5f72021-07-21 19:28:45 -0700676 *
677 * @param nodeData DNS-SD node information
678 *
679 */
Andrei Litvinf2c450c2022-02-23 23:57:30 -0500680 void OnNodeDiscovered(const chip::Dnssd::DiscoveredNodeData & nodeData) override;
Song Guo87142e02021-04-21 09:00:00 +0800681
Jerry Johns6cf91db2021-06-14 11:53:53 -0700682 void RegisterPairingDelegate(DevicePairingDelegate * pairingDelegate) { mPairingDelegate = pairingDelegate; }
Boris Zbarskyd170a252022-03-31 20:51:58 -0400683 DevicePairingDelegate * GetPairingDelegate() const { return mPairingDelegate; }
Jerry Johns6cf91db2021-06-14 11:53:53 -0700684
Jerry Johns964adbc2022-04-14 16:42:04 -0700685 // ClusterStateCache::Callback impl
Boris Zbarsky6c86c942022-05-23 18:15:17 -0400686 void OnDone(app::ReadClient *) override;
C Freeman1ee93662022-02-03 09:51:04 -0500687
tehampson76001792022-06-27 19:58:47 -0400688 // Issue an NOC chain using the associated OperationalCredentialsDelegate. The NOC chain will
689 // be provided in X509 DER format.
tehampsonf3be2ee2022-06-23 13:10:52 -0400690 // NOTE: This is only valid assuming that `mOperationalCredentialsDelegate` is what is desired
691 // to issue the NOC chain.
692 CHIP_ERROR IssueNOCChain(const ByteSpan & NOCSRElements, NodeId nodeId,
693 chip::Callback::Callback<OnNOCChainGeneration> * callback);
694
chrisdecenzo488262f2022-08-15 19:53:18 -0700695 void SetDeviceAttestationVerifier(Credentials::DeviceAttestationVerifier * deviceAttestationVerifier)
696 {
697 mDeviceAttestationVerifier = deviceAttestationVerifier;
698 }
699
Sharad Binjola74ea2522022-08-19 19:21:47 -0700700 Optional<CommissioningParameters> GetCommissioningParameters()
701 {
702 return mDefaultCommissioner == nullptr ? NullOptional : MakeOptional(mDefaultCommissioner->GetCommissioningParameters());
703 }
704
Boris Zbarskye42b5332023-03-14 00:13:25 -0400705 // Reset the arm failsafe timer during commissioning. If this returns
706 // false, that means that the timer was already set for a longer time period
707 // than the new time we are trying to set. In this case, neither
708 // onSuccess nor onFailure will be called.
709 bool ExtendArmFailSafe(DeviceProxy * proxy, CommissioningStage step, uint16_t armFailSafeTimeout,
chrisdecenzo620ef8f2022-11-22 09:10:02 -0800710 Optional<System::Clock::Timeout> commandTimeout, OnExtendFailsafeSuccess onSuccess,
711 OnExtendFailsafeFailure onFailure);
712
Sagar Dhawan55ef62f2020-05-13 20:35:27 -0700713private:
Pankaj Garg047424f2020-11-10 21:56:59 -0800714 DevicePairingDelegate * mPairingDelegate;
Sagar Dhawan55ef62f2020-05-13 20:35:27 -0700715
C Freeman6e981ec2022-03-18 16:04:49 -0400716 DeviceProxy * mDeviceBeingCommissioned = nullptr;
717 CommissioneeDeviceProxy * mDeviceInPASEEstablishment = nullptr;
Sagar Dhawan55ef62f2020-05-13 20:35:27 -0700718
C Freemane86bb352021-05-26 19:19:40 -0400719 CommissioningStage mCommissioningStage = CommissioningStage::kSecurePairing;
C Freemanaa719692021-12-03 11:45:30 -0500720 bool mRunCommissioningAfterConnection = false;
C Freemane86bb352021-05-26 19:19:40 -0400721
Kevin Schoedel22f5d222022-02-02 14:35:20 -0500722 ObjectPool<CommissioneeDeviceProxy, kNumMaxActiveDevices> mCommissioneeDevicePool;
Pankaj Garga04576d2021-11-08 15:04:13 -0800723
chrisdecenzo250d5f72021-07-21 19:28:45 -0700724#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
725 UserDirectedCommissioningServer * mUdcServer = nullptr;
726 // mUdcTransportMgr is for insecure communication (ex. user directed commissioning)
Zang MingJie6109d142022-04-22 06:19:42 +0800727 UdcTransportMgr * mUdcTransportMgr = nullptr;
728 uint16_t mUdcListenPort = CHIP_UDC_PORT;
chrisdecenzo250d5f72021-07-21 19:28:45 -0700729#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
730
Vivien Nicolasdf18a8c2022-11-21 16:10:18 +0100731#if CONFIG_NETWORK_LAYER_BLE
732 static void OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj);
733 static void OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err);
734 RendezvousParameters mRendezvousParametersForDeviceDiscoveredOverBle;
735#endif
736
Pankaj Garg2f064a52021-03-17 06:47:58 -0700737 CHIP_ERROR LoadKeyId(PersistentStorageDelegate * delegate, uint16_t & out);
738
Marty Leisner0e529702021-09-27 10:55:08 -0400739 /* This function sends a Device Attestation Certificate chain request to the device.
740 The function does not hold a reference to the device object.
741 */
Boris Zbarskyb27420a2022-06-03 19:50:39 -0400742 CHIP_ERROR SendCertificateChainRequestCommand(DeviceProxy * device, Credentials::CertificateType certificateType,
743 Optional<System::Clock::Timeout> timeout);
Marty Leisner0e529702021-09-27 10:55:08 -0400744 /* This function sends an Attestation request to the device.
745 The function does not hold a reference to the device object.
746 */
Boris Zbarskyb27420a2022-06-03 19:50:39 -0400747 CHIP_ERROR SendAttestationRequestCommand(DeviceProxy * device, const ByteSpan & attestationNonce,
748 Optional<System::Clock::Timeout> timeout);
Boris Zbarsky570a1ce2022-02-04 11:38:38 -0500749 /* This function sends an CSR request to the device.
Martin Turond24eff12021-12-17 06:21:23 -0800750 The function does not hold a reference to the device object.
Pankaj Garg22365d82021-05-13 09:02:36 -0700751 */
Boris Zbarskyb27420a2022-06-03 19:50:39 -0400752 CHIP_ERROR SendOperationalCertificateSigningRequestCommand(DeviceProxy * device, const ByteSpan & csrNonce,
753 Optional<System::Clock::Timeout> timeout);
Pankaj Garg22365d82021-05-13 09:02:36 -0700754 /* This function sends the operational credentials to the device.
Martin Turond24eff12021-12-17 06:21:23 -0800755 The function does not hold a reference to the device object.
Pankaj Garg22365d82021-05-13 09:02:36 -0700756 */
C Freeman566cf882022-03-31 19:58:36 -0400757 CHIP_ERROR SendOperationalCertificate(DeviceProxy * device, const ByteSpan & nocCertBuf, const Optional<ByteSpan> & icaCertBuf,
Damian Królik9b636332023-01-15 05:42:02 +0100758 IdentityProtectionKeySpan ipk, NodeId adminSubject,
759 Optional<System::Clock::Timeout> timeout);
Pankaj Garg22365d82021-05-13 09:02:36 -0700760 /* This function sends the trusted root certificate to the device.
Martin Turond24eff12021-12-17 06:21:23 -0800761 The function does not hold a reference to the device object.
Pankaj Garg22365d82021-05-13 09:02:36 -0700762 */
Boris Zbarskyb27420a2022-06-03 19:50:39 -0400763 CHIP_ERROR SendTrustedRootCertificate(DeviceProxy * device, const ByteSpan & rcac, Optional<System::Clock::Timeout> timeout);
Pankaj Garg22365d82021-05-13 09:02:36 -0700764
765 /* This function is called by the commissioner code when the device completes
766 the operational credential provisioning process.
Martin Turond24eff12021-12-17 06:21:23 -0800767 The function does not hold a reference to the device object.
Pankaj Garg22365d82021-05-13 09:02:36 -0700768 */
C Freeman6e981ec2022-03-18 16:04:49 -0400769 CHIP_ERROR OnOperationalCredentialsProvisioningCompletion(DeviceProxy * device);
Pankaj Garg22365d82021-05-13 09:02:36 -0700770
771 /* Callback when the previously sent CSR request results in failure */
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100772 static void OnCSRFailureResponse(void * context, CHIP_ERROR error);
Pankaj Garg22365d82021-05-13 09:02:36 -0700773
Jeff Tung89f5c8a2022-09-06 18:30:08 -0700774 void ExtendArmFailSafeForDeviceAttestation(const Credentials::DeviceAttestationVerifier::AttestationInfo & info,
775 Credentials::AttestationVerificationResult result);
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100776 static void OnCertificateChainFailureResponse(void * context, CHIP_ERROR error);
777 static void OnCertificateChainResponse(
778 void * context, const app::Clusters::OperationalCredentials::Commands::CertificateChainResponse::DecodableType & response);
Marty Leisner0e529702021-09-27 10:55:08 -0400779
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100780 static void OnAttestationFailureResponse(void * context, CHIP_ERROR error);
781 static void
782 OnAttestationResponse(void * context,
783 const app::Clusters::OperationalCredentials::Commands::AttestationResponse::DecodableType & data);
Marty Leisner0e529702021-09-27 10:55:08 -0400784
Pankaj Garg22365d82021-05-13 09:02:36 -0700785 /**
786 * @brief
787 * This function is called by the IM layer when the commissioner receives the CSR from the device.
Boris Zbarsky570a1ce2022-02-04 11:38:38 -0500788 * (Reference: Specifications section 11.18.5.6. NOCSR Elements)
Pankaj Garg22365d82021-05-13 09:02:36 -0700789 *
Pankaj Garg84c369c2021-07-30 11:54:25 -0700790 * @param[in] context The context provided while registering the callback.
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100791 * @param[in] data The response struct containing the following fields:
792 * NOCSRElements: CSR elements as per specifications section 11.22.5.6. NOCSR Elements.
793 * AttestationSignature: Cryptographic signature generated for the fields in the response
794 * message.
Pankaj Garg22365d82021-05-13 09:02:36 -0700795 */
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100796 static void OnOperationalCertificateSigningRequest(
Boris Zbarsky570a1ce2022-02-04 11:38:38 -0500797 void * context, const app::Clusters::OperationalCredentials::Commands::CSRResponse::DecodableType & data);
Pankaj Garg22365d82021-05-13 09:02:36 -0700798
799 /* Callback when adding operational certs to device results in failure */
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100800 static void OnAddNOCFailureResponse(void * context, CHIP_ERROR errro);
Pankaj Garg22365d82021-05-13 09:02:36 -0700801 /* Callback when the device confirms that it has added the operational certificates */
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100802 static void
803 OnOperationalCertificateAddResponse(void * context,
804 const app::Clusters::OperationalCredentials::Commands::NOCResponse::DecodableType & data);
Pankaj Garg22365d82021-05-13 09:02:36 -0700805
806 /* Callback when the device confirms that it has added the root certificate */
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100807 static void OnRootCertSuccessResponse(void * context, const chip::app::DataModel::NullObjectType &);
Pankaj Garg22365d82021-05-13 09:02:36 -0700808 /* Callback called when adding root cert to device results in failure */
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100809 static void OnRootCertFailureResponse(void * context, CHIP_ERROR error);
Pankaj Garg22365d82021-05-13 09:02:36 -0700810
Marcos Bcae63192023-01-13 14:53:14 -0700811 static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
Jerry Johnsd94cbdc2022-07-26 08:07:06 -0700812 static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error);
Boris Zbarsky8afc1f52023-03-09 23:58:40 -0500813#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
814 static void OnDeviceConnectionRetryFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error,
815 System::Clock::Seconds16 retryTimeout);
816#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
Pankaj Gargda453462021-06-22 19:53:34 -0700817
Jeff Tung89f5c8a2022-09-06 18:30:08 -0700818 static void OnDeviceAttestationInformationVerification(void * context,
819 const Credentials::DeviceAttestationVerifier::AttestationInfo & info,
820 Credentials::AttestationVerificationResult result);
Vijay Selvarajb8c540a2022-01-05 11:58:12 -0500821
Pankaj Garg84c369c2021-07-30 11:54:25 -0700822 static void OnDeviceNOCChainGeneration(void * context, CHIP_ERROR status, const ByteSpan & noc, const ByteSpan & icac,
Damian Królik9b636332023-01-15 05:42:02 +0100823 const ByteSpan & rcac, Optional<IdentityProtectionKeySpan> ipk,
824 Optional<NodeId> adminSubject);
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100825 static void OnArmFailSafe(void * context,
826 const chip::app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
827 static void OnSetRegulatoryConfigResponse(
828 void * context,
829 const chip::app::Clusters::GeneralCommissioning::Commands::SetRegulatoryConfigResponse::DecodableType & data);
830 static void
chrisdecenzo16793422022-07-28 08:00:08 -0700831 OnScanNetworksResponse(void * context,
832 const app::Clusters::NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & data);
833 static void OnScanNetworksFailure(void * context, CHIP_ERROR err);
834 static void
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100835 OnNetworkConfigResponse(void * context,
chrisdecenzo16793422022-07-28 08:00:08 -0700836 const app::Clusters::NetworkCommissioning::Commands::NetworkConfigResponse::DecodableType & data);
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100837 static void OnConnectNetworkResponse(
838 void * context, const chip::app::Clusters::NetworkCommissioning::Commands::ConnectNetworkResponse::DecodableType & data);
839 static void OnCommissioningCompleteResponse(
840 void * context,
841 const chip::app::Clusters::GeneralCommissioning::Commands::CommissioningCompleteResponse::DecodableType & data);
C Freemanc3b18102022-04-04 16:17:09 -0400842 static void OnDisarmFailsafe(void * context,
843 const app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
844 static void OnDisarmFailsafeFailure(void * context, CHIP_ERROR error);
845 void DisarmDone();
Jeff Tung89f5c8a2022-09-06 18:30:08 -0700846 static void OnArmFailSafeExtendedForDeviceAttestation(
Anush Nadathurb06bd8c2022-04-06 17:29:16 -0700847 void * context, const chip::app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
Jeff Tung89f5c8a2022-09-06 18:30:08 -0700848 static void OnFailedToExtendedArmFailSafeDeviceAttestation(void * context, CHIP_ERROR error);
Pankaj Gargab5c6172021-06-28 11:03:11 -0700849
Pankaj Garg22365d82021-05-13 09:02:36 -0700850 /**
851 * @brief
852 * This function processes the CSR sent by the device.
Boris Zbarsky570a1ce2022-02-04 11:38:38 -0500853 * (Reference: Specifications section 11.18.5.6. NOCSR Elements)
Pankaj Garg22365d82021-05-13 09:02:36 -0700854 *
C Freeman09a49212022-01-24 21:19:43 -0500855 * @param[in] proxy device proxy
Pankaj Garg84c369c2021-07-30 11:54:25 -0700856 * @param[in] NOCSRElements CSR elements as per specifications section 11.22.5.6. NOCSR Elements.
857 * @param[in] AttestationSignature Cryptographic signature generated for all the above fields.
C Freeman09a49212022-01-24 21:19:43 -0500858 * @param[in] dac device attestation certificate
C Freemana208c3d2022-04-04 08:23:45 -0400859 * @param[in] pai Product Attestation Intermediate certificate
C Freeman09a49212022-01-24 21:19:43 -0500860 * @param[in] csrNonce certificate signing request nonce
Pankaj Garg22365d82021-05-13 09:02:36 -0700861 */
C Freemana208c3d2022-04-04 08:23:45 -0400862 CHIP_ERROR ProcessCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, const ByteSpan & AttestationSignature,
863 const ByteSpan & dac, const ByteSpan & pai, const ByteSpan & csrNonce);
864
865 /**
866 * @brief
867 * This function validates the CSR information from the device.
868 * (Reference: Specifications section 11.18.5.6. NOCSR Elements)
869 *
870 * @param[in] proxy device proxy
871 * @param[in] NOCSRElements CSR elements as per specifications section 11.22.5.6. NOCSR Elements.
872 * @param[in] AttestationSignature Cryptographic signature generated for all the above fields.
873 * @param[in] dac device attestation certificate
874 * @param[in] csrNonce certificate signing request nonce
875 */
876 CHIP_ERROR ValidateCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, const ByteSpan & AttestationSignature,
877 const ByteSpan & dac, const ByteSpan & csrNonce);
Pankaj Garga4907732021-05-07 09:08:45 -0700878
Marty Leisner0e529702021-09-27 10:55:08 -0400879 /**
880 * @brief
881 * This function processes the DAC or PAI certificate sent by the device.
882 */
883 CHIP_ERROR ProcessCertificateChain(const ByteSpan & certificate);
884
Marty Leisner0e529702021-09-27 10:55:08 -0400885 void HandleAttestationResult(CHIP_ERROR err);
886
Pankaj Garga04576d2021-11-08 15:04:13 -0800887 CommissioneeDeviceProxy * FindCommissioneeDevice(NodeId id);
C Freemanc3b18102022-04-04 16:17:09 -0400888 CommissioneeDeviceProxy * FindCommissioneeDevice(const Transport::PeerAddress & peerAddress);
Pankaj Garga04576d2021-11-08 15:04:13 -0800889 void ReleaseCommissioneeDevice(CommissioneeDeviceProxy * device);
890
Boris Zbarsky7fe4abc2023-01-20 15:43:30 -0500891 template <typename RequestObjectT>
Boris Zbarsky43a1e1a2022-01-29 04:13:17 -0500892 CHIP_ERROR SendCommand(DeviceProxy * device, const RequestObjectT & request,
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100893 CommandResponseSuccessCallback<typename RequestObjectT::ResponseType> successCb,
Boris Zbarskyb27420a2022-06-03 19:50:39 -0400894 CommandResponseFailureCallback failureCb, Optional<System::Clock::Timeout> timeout)
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100895 {
Boris Zbarsky7fe4abc2023-01-20 15:43:30 -0500896 return SendCommand(device, request, successCb, failureCb, 0, timeout);
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100897 }
898
Boris Zbarsky7fe4abc2023-01-20 15:43:30 -0500899 template <typename RequestObjectT>
Boris Zbarsky43a1e1a2022-01-29 04:13:17 -0500900 CHIP_ERROR SendCommand(DeviceProxy * device, const RequestObjectT & request,
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100901 CommandResponseSuccessCallback<typename RequestObjectT::ResponseType> successCb,
Boris Zbarsky43a1e1a2022-01-29 04:13:17 -0500902 CommandResponseFailureCallback failureCb, EndpointId endpoint, Optional<System::Clock::Timeout> timeout)
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100903 {
Boris Zbarsky7fe4abc2023-01-20 15:43:30 -0500904 ClusterBase cluster(*device->GetExchangeManager(), device->GetSecureSession().Value(), endpoint);
Boris Zbarsky43a1e1a2022-01-29 04:13:17 -0500905 cluster.SetCommandTimeout(timeout);
Vivien Nicolasf24e6f12022-01-29 08:31:44 +0100906
907 return cluster.InvokeCommand(request, this, successCb, failureCb);
908 }
C Freemane86bb352021-05-26 19:19:40 -0400909
Boris Zbarskycccce012023-01-18 11:27:01 -0500910 static CHIP_ERROR
911 ConvertFromOperationalCertStatus(chip::app::Clusters::OperationalCredentials::NodeOperationalCertStatusEnum err);
C Freemane86bb352021-05-26 19:19:40 -0400912
C Freemanc3b18102022-04-04 16:17:09 -0400913 // Sends commissioning complete callbacks to the delegate depending on the status. Sends
914 // OnCommissioningComplete and either OnCommissioningSuccess or OnCommissioningFailure depending on the given completion status.
915 void SendCommissioningCompleteCallbacks(NodeId nodeId, const CompletionStatus & completionStatus);
916
917 // Cleans up and resets failsafe as appropriate depending on the error and the failed stage.
918 // For success, sends completion report with the CommissioningDelegate and sends callbacks to the PairingDelegate
919 // For failures after AddNOC succeeds, sends completion report with the CommissioningDelegate and sends callbacks to the
920 // PairingDelegate. In this case, it does not disarm the failsafe or close the pase connection. For failures up through AddNOC,
921 // sends a command to immediately expire the failsafe, then sends completion report with the CommissioningDelegate and callbacks
922 // to the PairingDelegate upon arm failsafe command completion.
923 void CleanupCommissioning(DeviceProxy * proxy, NodeId nodeId, const CompletionStatus & completionStatus);
924
Boris Zbarskye42b5332023-03-14 00:13:25 -0400925 // Extend the fail-safe before trying to do network-enable (since after that
926 // point, for non-concurrent-commissioning devices, we may not have a way to
927 // extend it).
928 void ExtendFailsafeBeforeNetworkEnable(DeviceProxy * device, CommissioningParameters & params, CommissioningStage step);
929
C Freeman1ee93662022-02-03 09:51:04 -0500930 chip::Callback::Callback<OnDeviceConnected> mOnDeviceConnectedCallback;
931 chip::Callback::Callback<OnDeviceConnectionFailure> mOnDeviceConnectionFailureCallback;
Boris Zbarsky8afc1f52023-03-09 23:58:40 -0500932#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
933 chip::Callback::Callback<OnDeviceConnectionRetry> mOnDeviceConnectionRetryCallback;
934#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
Pankaj Gargda453462021-06-22 19:53:34 -0700935
Jeff Tung89f5c8a2022-09-06 18:30:08 -0700936 chip::Callback::Callback<Credentials::DeviceAttestationVerifier::OnAttestationInformationVerification>
937 mDeviceAttestationInformationVerificationCallback;
Vijay Selvarajb8c540a2022-01-05 11:58:12 -0500938
C Freeman1ee93662022-02-03 09:51:04 -0500939 chip::Callback::Callback<OnNOCChainGeneration> mDeviceNOCChainCallback;
Vivien Nicolas02d89002021-10-04 12:30:52 +0200940 SetUpCodePairer mSetUpCodePairer;
C Freeman798d7d22021-12-10 12:06:36 -0500941 AutoCommissioner mAutoCommissioner;
C Freeman8ffe4222022-02-02 14:21:16 -0500942 CommissioningDelegate * mDefaultCommissioner =
943 nullptr; // Commissioning delegate to call when PairDevice / Commission functions are used
944 CommissioningDelegate * mCommissioningDelegate =
945 nullptr; // Commissioning delegate that issued the PerformCommissioningStep command
C Freemanc3b18102022-04-04 16:17:09 -0400946 CompletionStatus commissioningCompletionStatus;
C Freeman1ee93662022-02-03 09:51:04 -0500947
Jerry Johns964adbc2022-04-14 16:42:04 -0700948 Platform::UniquePtr<app::ClusterStateCache> mAttributeCache;
C Freeman1ee93662022-02-03 09:51:04 -0500949 Platform::UniquePtr<app::ReadClient> mReadClient;
Anush Nadathurb06bd8c2022-04-06 17:29:16 -0700950 Credentials::AttestationVerificationResult mAttestationResult;
Jeff Tung89f5c8a2022-09-06 18:30:08 -0700951 Platform::UniquePtr<Credentials::DeviceAttestationVerifier::AttestationDeviceInfo> mAttestationDeviceInfo;
Tennessee Carmel-Veilleuxa777a802022-05-17 22:56:37 -0400952 Credentials::DeviceAttestationVerifier * mDeviceAttestationVerifier = nullptr;
Sagar Dhawan55ef62f2020-05-13 20:35:27 -0700953};
954
Pankaj Garg047424f2020-11-10 21:56:59 -0800955} // namespace Controller
Sagar Dhawan55ef62f2020-05-13 20:35:27 -0700956} // namespace chip