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/BleLayer.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 0 : virtual ~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 : 115 : // Returns whether we have kicked off a new connection attempt. 116 : bool ConnectToDiscoveredDevice(); 117 : 118 : // Reset our mWaitingForDiscovery/mDiscoveredParameters state to indicate no 119 : // pending work. 120 : void ResetDiscoveryState(); 121 : 122 : // Get ready to start PASE establishment via mCommissioner. Sets up 123 : // whatever state is needed for that. 124 : void ExpectPASEEstablishment(); 125 : 126 : // PASE establishment by mCommissioner has completed: we either have a PASE 127 : // session now or we failed to set one up, but we are done waiting on 128 : // mCommissioner. 129 : void PASEEstablishmentComplete(); 130 : 131 : // Called when PASE establishment fails. 132 : // 133 : // May start a new PASE establishment. 134 : // 135 : // Will return whether we might in fact have more rendezvous parameters to 136 : // try (e.g. because we started a new PASE establishment or are waiting on 137 : // more device discovery). 138 : // 139 : // The commissioner can use the return value to decide whether pairing has 140 : // actually failed or not. 141 : bool TryNextRendezvousParameters(); 142 : 143 : // True if we are still waiting on discovery to possibly produce new 144 : // RendezvousParameters in the future. 145 : bool DiscoveryInProgress() const; 146 : 147 : // Not an enum class because we use this for indexing into arrays. 148 : enum TransportTypes 149 : { 150 : kBLETransport = 0, 151 : kIPTransport, 152 : kSoftAPTransport, 153 : kTransportTypeCount, 154 : }; 155 : 156 : void NotifyCommissionableDeviceDiscovered(const chip::Dnssd::CommonResolutionData & resolutionData); 157 : 158 : static void OnDeviceDiscoveredTimeoutCallback(System::Layer * layer, void * context); 159 : 160 : #if CONFIG_NETWORK_LAYER_BLE 161 : Ble::BleLayer * mBleLayer = nullptr; 162 : void OnDiscoveredDeviceOverBle(BLE_CONNECTION_OBJECT connObj); 163 : void OnBLEDiscoveryError(CHIP_ERROR err); 164 : /////////// BLEConnectionDelegate Callbacks ///////// 165 : static void OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj); 166 : static void OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err); 167 : #endif // CONFIG_NETWORK_LAYER_BLE 168 : 169 : bool NodeMatchesCurrentFilter(const Dnssd::DiscoveredNodeData & nodeData) const; 170 : static bool IdIsPresent(uint16_t vendorOrProductID); 171 : 172 : Dnssd::DiscoveryFilter mCurrentFilter; 173 : // The vendor id and product id from the SetupPayload. They may be 0, which 174 : // indicates "not available" (e.g. because the SetupPayload came from a 175 : // short manual code). In that case we should not filter on those values. 176 : static constexpr uint16_t kNotAvailable = 0; 177 : uint16_t mPayloadVendorID = kNotAvailable; 178 : uint16_t mPayloadProductID = kNotAvailable; 179 : 180 : DeviceCommissioner * mCommissioner = nullptr; 181 : System::Layer * mSystemLayer = nullptr; 182 : chip::NodeId mRemoteId = kUndefinedNodeId; 183 : uint32_t mSetUpPINCode = 0; 184 : SetupCodePairerBehaviour mConnectionType = SetupCodePairerBehaviour::kCommission; 185 : DiscoveryType mDiscoveryType = DiscoveryType::kAll; 186 : 187 : // While we are trying to pair, we intercept the DevicePairingDelegate 188 : // notifications from mCommissioner. We want to make sure we send them on 189 : // to the original pairing delegate, if any. 190 : DevicePairingDelegate * mPairingDelegate = nullptr; 191 : 192 : // Boolean will be set to true if we currently have an async discovery 193 : // process happening via the relevant transport. 194 : bool mWaitingForDiscovery[kTransportTypeCount] = { false }; 195 : 196 : // Double ended-queue of things we have discovered but not tried connecting to yet. The 197 : // general discovery/pairing process will terminate once this queue is empty 198 : // and all the booleans in mWaitingForDiscovery are false. 199 : std::deque<SetUpCodePairerParameters> mDiscoveredParameters; 200 : 201 : // Current thing we are trying to connect to over UDP. If a PASE connection fails with 202 : // a CHIP_ERROR_TIMEOUT, the discovered parameters will be used to ask the 203 : // mdns daemon to invalidate the 204 : Optional<SetUpCodePairerParameters> mCurrentPASEParameters; 205 : 206 : // mWaitingForPASE is true if we have called either 207 : // EstablishPASEConnection or PairDevice on mCommissioner and are now just 208 : // waiting to see whether that works. 209 : bool mWaitingForPASE = false; 210 : 211 : // mLastPASEError is the error from the last OnPairingComplete call we got. 212 : CHIP_ERROR mLastPASEError = CHIP_NO_ERROR; 213 : }; 214 : 215 : } // namespace Controller 216 : } // namespace chip