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 : * Declaration of SetUp Code Pairer, a class that parses a given
22 : * setup code and uses the extracted informations to discover and
23 : * filter commissionables nodes, before initiating the pairing process.
24 : *
25 : */
26 :
27 : #pragma once
28 :
29 : #include <controller/DevicePairingDelegate.h>
30 : #include <lib/core/CHIPError.h>
31 : #include <lib/core/NodeId.h>
32 : #include <lib/support/DLLUtil.h>
33 : #include <platform/CHIPDeviceConfig.h>
34 : #include <protocols/secure_channel/RendezvousParameters.h>
35 : #include <setup_payload/ManualSetupPayloadParser.h>
36 : #include <setup_payload/QRCodeSetupPayloadParser.h>
37 :
38 : #if CONFIG_NETWORK_LAYER_BLE
39 : #include <ble/Ble.h>
40 : #endif // CONFIG_NETWORK_BLE
41 :
42 : #include <controller/DeviceDiscoveryDelegate.h>
43 :
44 : #include <deque>
45 : #include <optional>
46 : #include <vector>
47 :
48 : namespace chip {
49 : namespace Controller {
50 :
51 : class DeviceCommissioner;
52 :
53 : /**
54 : * A class that represents a discovered device. This includes both the inputs to discovery (via the
55 : * RendezvousParameters super-class), and the outputs from discovery (the PeerAddress in
56 : * RendezvousParameters but also some of our members like mHostName, mInterfaceId,
57 : * mLongDiscriminator).
58 : */
59 : class SetUpCodePairerParameters : public RendezvousParameters
60 : {
61 : public:
62 0 : SetUpCodePairerParameters() = default;
63 : SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, std::optional<uint16_t> longDiscriminator, size_t index);
64 : #if CONFIG_NETWORK_LAYER_BLE
65 : SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, std::optional<uint16_t> longDiscriminator, bool connected = true);
66 : #endif // CONFIG_NETWORK_LAYER_BLE
67 : char mHostName[Dnssd::kHostNameMaxLength + 1] = {};
68 : Inet::InterfaceId mInterfaceId;
69 :
70 : // The long discriminator of the device that was actually discovered, if this is known. This
71 : // differs from the mSetupDiscriminator member of RendezvousParameters in that the latter may be
72 : // a short discriminator from a numeric setup code (which may match multiple devices), while
73 : // this member, if set, is always a long discriminator that was actually advertised by the
74 : // device represented by our PeerAddress.
75 : std::optional<uint16_t> mLongDiscriminator = std::nullopt;
76 : };
77 :
78 : enum class SetupCodePairerBehaviour : uint8_t
79 : {
80 : kCommission,
81 : kPaseOnly,
82 : };
83 :
84 : enum class DiscoveryType : uint8_t
85 : {
86 : kDiscoveryNetworkOnly,
87 : kDiscoveryNetworkOnlyWithoutPASEAutoRetry,
88 : kAll,
89 : };
90 :
91 : class DLL_EXPORT SetUpCodePairer : public DevicePairingDelegate
92 : {
93 : public:
94 0 : SetUpCodePairer(DeviceCommissioner * commissioner) : mCommissioner(commissioner) {}
95 0 : virtual ~SetUpCodePairer() {}
96 :
97 : CHIP_ERROR PairDevice(chip::NodeId remoteId, const char * setUpCode,
98 : SetupCodePairerBehaviour connectionType = SetupCodePairerBehaviour::kCommission,
99 : DiscoveryType discoveryType = DiscoveryType::kAll,
100 : Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);
101 :
102 : // Called by the DeviceCommissioner to notify that we have discovered a new device.
103 : void NotifyCommissionableDeviceDiscovered(const chip::Dnssd::DiscoveredNodeData & nodeData);
104 :
105 0 : void SetSystemLayer(System::Layer * systemLayer) { mSystemLayer = systemLayer; };
106 :
107 : #if CONFIG_NETWORK_LAYER_BLE
108 0 : void SetBleLayer(Ble::BleLayer * bleLayer) { mBleLayer = bleLayer; };
109 : #endif // CONFIG_NETWORK_LAYER_BLE
110 :
111 : // Stop ongoing discovery / pairing of the specified node, or of
112 : // whichever node we're pairing if kUndefinedNodeId is passed.
113 : bool StopPairing(NodeId remoteId = kUndefinedNodeId);
114 :
115 : private:
116 : // DevicePairingDelegate implementation.
117 : void OnStatusUpdate(DevicePairingDelegate::Status status) override;
118 : void OnPairingComplete(CHIP_ERROR error) override;
119 : void OnPairingDeleted(CHIP_ERROR error) override;
120 : void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error) override;
121 :
122 : CHIP_ERROR Connect();
123 : CHIP_ERROR StartDiscoveryOverBLE();
124 : CHIP_ERROR StopDiscoveryOverBLE();
125 : CHIP_ERROR StartDiscoveryOverDNSSD();
126 : CHIP_ERROR StopDiscoveryOverDNSSD();
127 : CHIP_ERROR StartDiscoveryOverWiFiPAF();
128 : CHIP_ERROR StopDiscoveryOverWiFiPAF();
129 :
130 : // Returns whether we have kicked off a new connection attempt.
131 : bool ConnectToDiscoveredDevice();
132 :
133 : // Stop attempts to discover more things to connect to, but keep trying to
134 : // connect to the ones we have already discovered.
135 : void StopAllDiscoveryAttempts();
136 :
137 : // Reset our mWaitingForDiscovery/mDiscoveredParameters state to indicate no
138 : // pending work.
139 : void ResetDiscoveryState();
140 :
141 : // Get ready to start PASE establishment via mCommissioner. Sets up
142 : // whatever state is needed for that.
143 : void ExpectPASEEstablishment();
144 :
145 : // PASE establishment by mCommissioner has completed: we either have a PASE
146 : // session now or we failed to set one up, but we are done waiting on
147 : // mCommissioner.
148 : void PASEEstablishmentComplete();
149 :
150 : // Called when PASE establishment fails.
151 : //
152 : // May start a new PASE establishment.
153 : //
154 : // Will return whether we might in fact have more rendezvous parameters to
155 : // try (e.g. because we started a new PASE establishment or are waiting on
156 : // more device discovery).
157 : //
158 : // The commissioner can use the return value to decide whether pairing has
159 : // actually failed or not.
160 : bool TryNextRendezvousParameters();
161 :
162 : // True if we are still waiting on discovery to possibly produce new
163 : // RendezvousParameters in the future.
164 : bool DiscoveryInProgress() const;
165 :
166 : // Not an enum class because we use this for indexing into arrays.
167 : enum TransportTypes
168 : {
169 : kBLETransport = 0,
170 : kIPTransport,
171 : kWiFiPAFTransport,
172 : kTransportTypeCount,
173 : };
174 :
175 : void NotifyCommissionableDeviceDiscovered(const chip::Dnssd::CommonResolutionData & resolutionData,
176 : std::optional<uint16_t> matchedLongDiscriminator);
177 :
178 : static void OnDeviceDiscoveredTimeoutCallback(System::Layer * layer, void * context);
179 :
180 : #if CONFIG_NETWORK_LAYER_BLE
181 : Ble::BleLayer * mBleLayer = nullptr;
182 : void OnDiscoveredDeviceOverBle(BLE_CONNECTION_OBJECT connObj, std::optional<uint16_t> matchedLongDiscriminator);
183 : void OnBLEDiscoveryError(CHIP_ERROR err);
184 : /////////// BLEConnectionDelegate Callbacks /////////
185 : static void OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj);
186 : static void OnDiscoveredDeviceWithDiscriminatorOverBleSuccess(void * appState, uint16_t matchedLongDiscriminator,
187 : BLE_CONNECTION_OBJECT connObj);
188 : static void OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err);
189 : #endif // CONFIG_NETWORK_LAYER_BLE
190 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
191 : void OnDiscoveredDeviceOverWifiPAF();
192 : void OnWifiPAFDiscoveryError(CHIP_ERROR err);
193 : static void OnWiFiPAFSubscribeComplete(void * appState);
194 : static void OnWiFiPAFSubscribeError(void * appState, CHIP_ERROR err);
195 : #endif
196 :
197 : bool NodeMatchesCurrentFilter(const Dnssd::DiscoveredNodeData & nodeData) const;
198 : static bool IdIsPresent(uint16_t vendorOrProductID);
199 :
200 : bool ShouldDiscoverUsing(RendezvousInformationFlag commissioningChannel) const;
201 :
202 : // kNotAvailable represents unavailable vendor/product ID values in setup payloads.
203 : static constexpr uint16_t kNotAvailable = 0;
204 :
205 : DeviceCommissioner * mCommissioner = nullptr;
206 : System::Layer * mSystemLayer = nullptr;
207 : chip::NodeId mRemoteId = kUndefinedNodeId;
208 : SetupCodePairerBehaviour mConnectionType = SetupCodePairerBehaviour::kCommission;
209 : DiscoveryType mDiscoveryType = DiscoveryType::kAll;
210 : std::vector<SetupPayload> mSetupPayloads;
211 :
212 : // While we are trying to pair, we intercept the DevicePairingDelegate
213 : // notifications from mCommissioner. We want to make sure we send them on
214 : // to the original pairing delegate, if any.
215 : DevicePairingDelegate * mPairingDelegate = nullptr;
216 :
217 : // Boolean will be set to true if we currently have an async discovery
218 : // process happening via the relevant transport.
219 : bool mWaitingForDiscovery[kTransportTypeCount] = { false };
220 :
221 : // Double ended-queue of things we have discovered but not tried connecting to yet. The
222 : // general discovery/pairing process will terminate once this queue is empty
223 : // and all the booleans in mWaitingForDiscovery are false.
224 : std::deque<SetUpCodePairerParameters> mDiscoveredParameters;
225 :
226 : // Current thing we are trying to connect to over UDP. If a PASE connection fails with
227 : // a CHIP_ERROR_TIMEOUT, the discovered parameters will be used to ask the
228 : // mdns daemon to invalidate the
229 : Optional<SetUpCodePairerParameters> mCurrentPASEParameters;
230 :
231 : // mWaitingForPASE is true if we have called either
232 : // EstablishPASEConnection or PairDevice on mCommissioner and are now just
233 : // waiting to see whether that works.
234 : bool mWaitingForPASE = false;
235 :
236 : // mLastPASEError is the error from the last OnPairingComplete call we got.
237 : CHIP_ERROR mLastPASEError = CHIP_NO_ERROR;
238 : };
239 :
240 : } // namespace Controller
241 : } // namespace chip
|