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 :
46 : namespace chip {
47 : namespace Controller {
48 :
49 : class DeviceCommissioner;
50 :
51 : class SetUpCodePairerParameters : public RendezvousParameters
52 : {
53 : public:
54 : SetUpCodePairerParameters() = default;
55 : SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, size_t index);
56 : #if CONFIG_NETWORK_LAYER_BLE
57 : SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, bool connected = true);
58 : #endif // CONFIG_NETWORK_LAYER_BLE
59 : char mHostName[Dnssd::kHostNameMaxLength + 1] = {};
60 : Inet::InterfaceId mInterfaceId;
61 : };
62 :
63 : enum class SetupCodePairerBehaviour : uint8_t
64 : {
65 : kCommission,
66 : kPaseOnly,
67 : };
68 :
69 : enum class DiscoveryType : uint8_t
70 : {
71 : kDiscoveryNetworkOnly,
72 : kDiscoveryNetworkOnlyWithoutPASEAutoRetry,
73 : kAll,
74 : };
75 :
76 : class DLL_EXPORT SetUpCodePairer : public DevicePairingDelegate
77 : {
78 : public:
79 0 : SetUpCodePairer(DeviceCommissioner * commissioner) : mCommissioner(commissioner) {}
80 : ~SetUpCodePairer();
81 :
82 : CHIP_ERROR PairDevice(chip::NodeId remoteId, const char * setUpCode,
83 : SetupCodePairerBehaviour connectionType = SetupCodePairerBehaviour::kCommission,
84 : DiscoveryType discoveryType = DiscoveryType::kAll,
85 : Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);
86 :
87 : // Called by the DeviceCommissioner to notify that we have discovered a new device.
88 : void NotifyCommissionableDeviceDiscovered(const chip::Dnssd::DiscoveredNodeData & nodeData);
89 :
90 0 : void SetSystemLayer(System::Layer * systemLayer) { mSystemLayer = systemLayer; };
91 :
92 : #if CONFIG_NETWORK_LAYER_BLE
93 0 : void SetBleLayer(Ble::BleLayer * bleLayer) { mBleLayer = bleLayer; };
94 : #endif // CONFIG_NETWORK_LAYER_BLE
95 :
96 : // Stop ongoing discovery / pairing of the specified node, or of
97 : // whichever node we're pairing if kUndefinedNodeId is passed.
98 : bool StopPairing(NodeId remoteId = kUndefinedNodeId);
99 :
100 : private:
101 : // DevicePairingDelegate implementation.
102 : void OnStatusUpdate(DevicePairingDelegate::Status status) override;
103 : void OnPairingComplete(CHIP_ERROR error) override;
104 : void OnPairingDeleted(CHIP_ERROR error) override;
105 : void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error) override;
106 :
107 : CHIP_ERROR Connect(SetupPayload & paload);
108 : CHIP_ERROR StartDiscoverOverBle(SetupPayload & payload);
109 : CHIP_ERROR StopConnectOverBle();
110 : CHIP_ERROR StartDiscoverOverIP(SetupPayload & payload);
111 : CHIP_ERROR StopConnectOverIP();
112 : CHIP_ERROR StartDiscoverOverSoftAP(SetupPayload & payload);
113 : CHIP_ERROR StopConnectOverSoftAP();
114 : CHIP_ERROR StartDiscoverOverWiFiPAF(SetupPayload & payload);
115 : CHIP_ERROR StopConnectOverWiFiPAF();
116 :
117 : // Returns whether we have kicked off a new connection attempt.
118 : bool ConnectToDiscoveredDevice();
119 :
120 : // Reset our mWaitingForDiscovery/mDiscoveredParameters state to indicate no
121 : // pending work.
122 : void ResetDiscoveryState();
123 :
124 : // Get ready to start PASE establishment via mCommissioner. Sets up
125 : // whatever state is needed for that.
126 : void ExpectPASEEstablishment();
127 :
128 : // PASE establishment by mCommissioner has completed: we either have a PASE
129 : // session now or we failed to set one up, but we are done waiting on
130 : // mCommissioner.
131 : void PASEEstablishmentComplete();
132 :
133 : // Called when PASE establishment fails.
134 : //
135 : // May start a new PASE establishment.
136 : //
137 : // Will return whether we might in fact have more rendezvous parameters to
138 : // try (e.g. because we started a new PASE establishment or are waiting on
139 : // more device discovery).
140 : //
141 : // The commissioner can use the return value to decide whether pairing has
142 : // actually failed or not.
143 : bool TryNextRendezvousParameters();
144 :
145 : // True if we are still waiting on discovery to possibly produce new
146 : // RendezvousParameters in the future.
147 : bool DiscoveryInProgress() const;
148 :
149 : // Not an enum class because we use this for indexing into arrays.
150 : enum TransportTypes
151 : {
152 : kBLETransport = 0,
153 : kIPTransport,
154 : kSoftAPTransport,
155 : kWiFiPAFTransport,
156 : kTransportTypeCount,
157 : };
158 :
159 : void NotifyCommissionableDeviceDiscovered(const chip::Dnssd::CommonResolutionData & resolutionData);
160 :
161 : static void OnDeviceDiscoveredTimeoutCallback(System::Layer * layer, void * context);
162 :
163 : #if CONFIG_NETWORK_LAYER_BLE
164 : Ble::BleLayer * mBleLayer = nullptr;
165 : void OnDiscoveredDeviceOverBle(BLE_CONNECTION_OBJECT connObj);
166 : void OnBLEDiscoveryError(CHIP_ERROR err);
167 : /////////// BLEConnectionDelegate Callbacks /////////
168 : static void OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj);
169 : static void OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err);
170 : #endif // CONFIG_NETWORK_LAYER_BLE
171 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
172 : void OnDiscoveredDeviceOverWifiPAF();
173 : void OnWifiPAFDiscoveryError(CHIP_ERROR err);
174 : static void OnWiFiPAFSubscribeComplete(void * appState);
175 : static void OnWiFiPAFSubscribeError(void * appState, CHIP_ERROR err);
176 : #endif
177 :
178 : bool NodeMatchesCurrentFilter(const Dnssd::DiscoveredNodeData & nodeData) const;
179 : static bool IdIsPresent(uint16_t vendorOrProductID);
180 :
181 : Dnssd::DiscoveryFilter mCurrentFilter;
182 : // The vendor id and product id from the SetupPayload. They may be 0, which
183 : // indicates "not available" (e.g. because the SetupPayload came from a
184 : // short manual code). In that case we should not filter on those values.
185 : static constexpr uint16_t kNotAvailable = 0;
186 : uint16_t mPayloadVendorID = kNotAvailable;
187 : uint16_t mPayloadProductID = kNotAvailable;
188 :
189 : DeviceCommissioner * mCommissioner = nullptr;
190 : System::Layer * mSystemLayer = nullptr;
191 : chip::NodeId mRemoteId = kUndefinedNodeId;
192 : uint32_t mSetUpPINCode = 0;
193 : SetupCodePairerBehaviour mConnectionType = SetupCodePairerBehaviour::kCommission;
194 : DiscoveryType mDiscoveryType = DiscoveryType::kAll;
195 :
196 : // While we are trying to pair, we intercept the DevicePairingDelegate
197 : // notifications from mCommissioner. We want to make sure we send them on
198 : // to the original pairing delegate, if any.
199 : DevicePairingDelegate * mPairingDelegate = nullptr;
200 :
201 : // Boolean will be set to true if we currently have an async discovery
202 : // process happening via the relevant transport.
203 : bool mWaitingForDiscovery[kTransportTypeCount] = { false };
204 :
205 : // Double ended-queue of things we have discovered but not tried connecting to yet. The
206 : // general discovery/pairing process will terminate once this queue is empty
207 : // and all the booleans in mWaitingForDiscovery are false.
208 : std::deque<SetUpCodePairerParameters> mDiscoveredParameters;
209 :
210 : // Current thing we are trying to connect to over UDP. If a PASE connection fails with
211 : // a CHIP_ERROR_TIMEOUT, the discovered parameters will be used to ask the
212 : // mdns daemon to invalidate the
213 : Optional<SetUpCodePairerParameters> mCurrentPASEParameters;
214 :
215 : // mWaitingForPASE is true if we have called either
216 : // EstablishPASEConnection or PairDevice on mCommissioner and are now just
217 : // waiting to see whether that works.
218 : bool mWaitingForPASE = false;
219 :
220 : // mLastPASEError is the error from the last OnPairingComplete call we got.
221 : CHIP_ERROR mLastPASEError = CHIP_NO_ERROR;
222 : };
223 :
224 : } // namespace Controller
225 : } // namespace chip
|