-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Expand file tree
/
Copy pathSetUpCodePairer.h
More file actions
280 lines (229 loc) · 11.1 KB
/
SetUpCodePairer.h
File metadata and controls
280 lines (229 loc) · 11.1 KB
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
/*
*
* 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
* Declaration of SetUp Code Pairer, a class that parses a given
* setup code and uses the extracted informations to discover and
* filter commissionables nodes, before initiating the pairing process.
*
*/
#pragma once
#include <controller/DevicePairingDelegate.h>
#include <lib/core/CHIPError.h>
#include <lib/core/NodeId.h>
#include <lib/support/DLLUtil.h>
#include <platform/CHIPDeviceConfig.h>
#include <protocols/secure_channel/RendezvousParameters.h>
#include <setup_payload/ManualSetupPayloadParser.h>
#include <setup_payload/QRCodeSetupPayloadParser.h>
#if CONFIG_NETWORK_LAYER_BLE
#include <ble/Ble.h>
#endif // CONFIG_NETWORK_BLE
#if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
#include <nfc/NFC.h>
#endif // CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
#include <controller/DeviceDiscoveryDelegate.h>
#include <deque>
#include <optional>
#include <vector>
namespace chip {
namespace Testing {
class SetUpCodePairerTestAccess;
} // namespace Testing
namespace Controller {
class DeviceCommissioner;
/**
* A class that represents a discovered device. This includes both the inputs to discovery (via the
* RendezvousParameters super-class), and the outputs from discovery (the PeerAddress in
* RendezvousParameters but also some of our members like mHostName, mInterfaceId,
* mLongDiscriminator).
*/
class SetUpCodePairerParameters : public RendezvousParameters
{
public:
SetUpCodePairerParameters() = default;
SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, std::optional<uint16_t> longDiscriminator, size_t index);
#if CONFIG_NETWORK_LAYER_BLE
SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, std::optional<uint16_t> longDiscriminator, bool connected = true);
#endif // CONFIG_NETWORK_LAYER_BLE
char mHostName[Dnssd::kHostNameMaxLength + 1] = {};
Inet::InterfaceId mInterfaceId;
// The long discriminator of the device that was actually discovered, if this is known. This
// differs from the mSetupDiscriminator member of RendezvousParameters in that the latter may be
// a short discriminator from a numeric setup code (which may match multiple devices), while
// this member, if set, is always a long discriminator that was actually advertised by the
// device represented by our PeerAddress.
std::optional<uint16_t> mLongDiscriminator = std::nullopt;
};
enum class SetupCodePairerBehaviour : uint8_t
{
kCommission,
kPaseOnly,
};
enum class DiscoveryType : uint8_t
{
kDiscoveryNetworkOnly,
kDiscoveryNetworkOnlyWithoutPASEAutoRetry,
kAll,
};
class DLL_EXPORT SetUpCodePairer : public DevicePairingDelegate
#if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
,
public Nfc::NFCReaderTransportDelegate
#endif
{
friend class chip::Testing::SetUpCodePairerTestAccess;
public:
SetUpCodePairer(DeviceCommissioner * commissioner) : mCommissioner(commissioner) {}
virtual ~SetUpCodePairer() {}
CHIP_ERROR PairDevice(chip::NodeId remoteId, const char * setUpCode,
SetupCodePairerBehaviour connectionType = SetupCodePairerBehaviour::kCommission,
DiscoveryType discoveryType = DiscoveryType::kAll,
Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);
// Called by the DeviceCommissioner to notify that we have discovered a new device.
void NotifyCommissionableDeviceDiscovered(const chip::Dnssd::DiscoveredNodeData & nodeData);
void SetSystemLayer(System::Layer * systemLayer) { mSystemLayer = systemLayer; };
#if CONFIG_NETWORK_LAYER_BLE
void SetBleLayer(Ble::BleLayer * bleLayer) { mBleLayer = bleLayer; };
#endif // CONFIG_NETWORK_LAYER_BLE
// Stop ongoing discovery / pairing of the specified node, or of
// whichever node we're pairing if kUndefinedNodeId is passed.
bool StopPairing(NodeId remoteId = kUndefinedNodeId);
private:
// DevicePairingDelegate implementation.
void OnStatusUpdate(DevicePairingDelegate::Status status) override;
void OnPairingComplete(CHIP_ERROR error, const std::optional<RendezvousParameters> & rendezvousParameters,
const std::optional<SetupPayload> & setupPayload) override;
void OnPairingDeleted(CHIP_ERROR error) override;
void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error) override;
#if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
// Nfc::NFCReaderTransportDelegate implementation
void OnTagDiscovered(const chip::Nfc::NFCTag::Identifier & identifer) override;
void OnTagDiscoveryFailed(CHIP_ERROR error) override;
#endif
CHIP_ERROR Connect();
CHIP_ERROR StartDiscoveryOverBLE();
CHIP_ERROR StopDiscoveryOverBLE();
CHIP_ERROR StartDiscoveryOverDNSSD();
CHIP_ERROR StopDiscoveryOverDNSSD();
CHIP_ERROR StartDiscoveryOverWiFiPAF();
CHIP_ERROR StopDiscoveryOverWiFiPAF();
CHIP_ERROR StartDiscoveryOverNFC();
CHIP_ERROR StopDiscoveryOverNFC();
// Returns whether we have kicked off a new connection attempt.
bool ConnectToDiscoveredDevice();
// Stop attempts to discover more things to connect to, but keep trying to
// connect to the ones we have already discovered.
void StopAllDiscoveryAttempts();
// Reset our mWaitingForDiscovery/mDiscoveredParameters state to indicate no
// pending work.
void ResetDiscoveryState();
// Get ready to start PASE establishment via mCommissioner. Sets up
// whatever state is needed for that.
void ExpectPASEEstablishment();
// PASE establishment by mCommissioner has completed: we either have a PASE
// session now or we failed to set one up, but we are done waiting on
// mCommissioner.
void PASEEstablishmentComplete();
// Called when PASE establishment fails.
//
// May start a new PASE establishment.
//
// Will return whether we might in fact have more rendezvous parameters to
// try (e.g. because we started a new PASE establishment or are waiting on
// more device discovery).
//
// The commissioner can use the return value to decide whether pairing has
// actually failed or not.
bool TryNextRendezvousParameters();
// True if we are still waiting on discovery to possibly produce new
// RendezvousParameters in the future.
bool DiscoveryInProgress() const;
// If there is nothing left to try (no PASE in progress, no queued discovered
// parameters, no discovery in progress), notify the commissioner that pairing
// has failed. err is used as the failure error only if no PASE attempt has
// produced an error yet.
void StopPairingIfTransportsExhausted(CHIP_ERROR err);
// Not an enum class because we use this for indexing into arrays.
enum TransportTypes
{
kBLETransport = 0,
kIPTransport,
kWiFiPAFTransport,
#if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
kNFCTransport,
#endif
kTransportTypeCount,
};
void NotifyCommissionableDeviceDiscovered(const chip::Dnssd::CommonResolutionData & resolutionData,
std::optional<uint16_t> matchedLongDiscriminator);
static void OnDeviceDiscoveredTimeoutCallback(System::Layer * layer, void * context);
#if CONFIG_NETWORK_LAYER_BLE
Ble::BleLayer * mBleLayer = nullptr;
void OnDiscoveredDeviceOverBle(BLE_CONNECTION_OBJECT connObj, std::optional<uint16_t> matchedLongDiscriminator);
void OnBLEDiscoveryError(CHIP_ERROR err);
/////////// BLEConnectionDelegate Callbacks /////////
static void OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj);
static void OnDiscoveredDeviceWithDiscriminatorOverBleSuccess(void * appState, uint16_t matchedLongDiscriminator,
BLE_CONNECTION_OBJECT connObj);
static void OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err);
#endif // CONFIG_NETWORK_LAYER_BLE
#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
void OnDiscoveredDeviceOverWifiPAF();
void OnWifiPAFDiscoveryError(CHIP_ERROR err);
static void OnWiFiPAFSubscribeComplete(void * appState);
static void OnWiFiPAFSubscribeError(void * appState, CHIP_ERROR err);
#endif
bool NodeMatchesCurrentFilter(const Dnssd::DiscoveredNodeData & nodeData) const;
static bool IdIsPresent(uint16_t vendorOrProductID);
bool ShouldDiscoverUsing(RendezvousInformationFlag commissioningChannel) const;
// kNotAvailable represents unavailable vendor/product ID values in setup payloads.
static constexpr uint16_t kNotAvailable = 0;
DeviceCommissioner * mCommissioner = nullptr;
System::Layer * mSystemLayer = nullptr;
chip::NodeId mRemoteId = kUndefinedNodeId;
SetupCodePairerBehaviour mConnectionType = SetupCodePairerBehaviour::kCommission;
DiscoveryType mDiscoveryType = DiscoveryType::kAll;
std::vector<SetupPayload> mSetupPayloads;
// The payload we are using for our current PASE connection attempt. Only
// set while we are attempting PASE.
std::optional<SetupPayload> mCurrentPASEPayload;
// While we are trying to pair, we intercept the DevicePairingDelegate
// notifications from mCommissioner. We want to make sure we send them on
// to the original pairing delegate, if any.
DevicePairingDelegate * mPairingDelegate = nullptr;
// Boolean will be set to true if we currently have an async discovery
// process happening via the relevant transport.
bool mWaitingForDiscovery[kTransportTypeCount] = { false };
// Double ended-queue of things we have discovered but not tried connecting to yet. The
// general discovery/pairing process will terminate once this queue is empty
// and all the booleans in mWaitingForDiscovery are false.
std::deque<SetUpCodePairerParameters> mDiscoveredParameters;
// Current thing we are trying to connect to over UDP. If a PASE connection fails with
// a CHIP_ERROR_TIMEOUT, the discovered parameters will be used to ask the
// mdns daemon to invalidate its caches.
Optional<SetUpCodePairerParameters> mCurrentPASEParameters;
// mWaitingForPASE is true if we have called either
// EstablishPASEConnection or PairDevice on mCommissioner and are now just
// waiting to see whether that works.
bool mWaitingForPASE = false;
// mLastPASEError is the error from the last OnPairingComplete call we got.
CHIP_ERROR mLastPASEError = CHIP_NO_ERROR;
};
} // namespace Controller
} // namespace chip