Matter SDK Coverage Report
Current view: top level - controller - SetUpCodePairer.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 0.0 % 304 0
Test Date: 2025-01-17 19:00:11 Functions: 0.0 % 35 0

            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              :  *      Implementation 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              : #include <controller/SetUpCodePairer.h>
      28              : 
      29              : #include <controller/CHIPDeviceController.h>
      30              : #include <lib/dnssd/Resolver.h>
      31              : #include <lib/support/CodeUtils.h>
      32              : #include <memory>
      33              : #include <system/SystemClock.h>
      34              : #include <tracing/metric_event.h>
      35              : 
      36              : constexpr uint32_t kDeviceDiscoveredTimeout = CHIP_CONFIG_SETUP_CODE_PAIRER_DISCOVERY_TIMEOUT_SECS * chip::kMillisecondsPerSecond;
      37              : 
      38              : using namespace chip::Tracing;
      39              : 
      40              : namespace chip {
      41              : namespace Controller {
      42              : 
      43              : namespace {
      44              : 
      45            0 : CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload)
      46              : {
      47            0 :     bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
      48            0 :     if (isQRCode)
      49              :     {
      50            0 :         ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload));
      51            0 :         VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
      52              :     }
      53              :     else
      54              :     {
      55            0 :         ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload));
      56            0 :         VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
      57              :     }
      58              : 
      59            0 :     return CHIP_NO_ERROR;
      60              : }
      61              : } // namespace
      62              : 
      63            0 : SetUpCodePairer::~SetUpCodePairer()
      64              : {
      65              : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
      66              :     DeviceLayer::ConnectivityMgr().WiFiPAFCancelConnect();
      67              : #endif
      68            0 : }
      69              : 
      70            0 : CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
      71              :                                        DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
      72              : {
      73            0 :     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
      74            0 :     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
      75              : 
      76            0 :     SetupPayload payload;
      77            0 :     ReturnErrorOnFailure(GetPayload(setUpCode, payload));
      78              : 
      79            0 :     if (resolutionData.HasValue())
      80              :     {
      81            0 :         VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, discoveryType != DiscoveryType::kAll,
      82              :                                       CHIP_ERROR_INVALID_ARGUMENT);
      83            0 :         if (mRemoteId == remoteId && mSetUpPINCode == payload.setUpPINCode && mConnectionType == commission &&
      84            0 :             mDiscoveryType == discoveryType)
      85              :         {
      86            0 :             NotifyCommissionableDeviceDiscovered(resolutionData.Value());
      87            0 :             return CHIP_NO_ERROR;
      88              :         }
      89              :     }
      90              : 
      91            0 :     mConnectionType = commission;
      92            0 :     mDiscoveryType  = discoveryType;
      93            0 :     mRemoteId       = remoteId;
      94            0 :     mSetUpPINCode   = payload.setUpPINCode;
      95              : 
      96            0 :     ResetDiscoveryState();
      97              : 
      98            0 :     if (resolutionData.HasValue())
      99              :     {
     100            0 :         NotifyCommissionableDeviceDiscovered(resolutionData.Value());
     101            0 :         return CHIP_NO_ERROR;
     102              :     }
     103              : 
     104            0 :     ReturnErrorOnFailureWithMetric(kMetricSetupCodePairerPairDevice, Connect(payload));
     105              :     auto errorCode =
     106            0 :         mSystemLayer->StartTimer(System::Clock::Milliseconds32(kDeviceDiscoveredTimeout), OnDeviceDiscoveredTimeoutCallback, this);
     107            0 :     if (CHIP_NO_ERROR == errorCode)
     108              :     {
     109              :         MATTER_LOG_METRIC_BEGIN(kMetricSetupCodePairerPairDevice);
     110              :     }
     111            0 :     return errorCode;
     112            0 : }
     113              : 
     114            0 : CHIP_ERROR SetUpCodePairer::Connect(SetupPayload & payload)
     115              : {
     116            0 :     CHIP_ERROR err = CHIP_NO_ERROR;
     117            0 :     bool isRunning = false;
     118              : 
     119            0 :     bool searchOverAll = !payload.rendezvousInformation.HasValue();
     120              : 
     121            0 :     if (mDiscoveryType == DiscoveryType::kAll)
     122              :     {
     123            0 :         if (searchOverAll || payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kBLE))
     124              :         {
     125            0 :             if (CHIP_NO_ERROR == (err = StartDiscoverOverBle(payload)))
     126              :             {
     127            0 :                 isRunning = true;
     128              :             }
     129            0 :             VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err || CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err, err);
     130              :         }
     131              : 
     132            0 :         if (searchOverAll || payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kSoftAP))
     133              :         {
     134            0 :             if (CHIP_NO_ERROR == (err = StartDiscoverOverSoftAP(payload)))
     135              :             {
     136            0 :                 isRunning = true;
     137              :             }
     138            0 :             VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err || CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err, err);
     139              :         }
     140            0 :         if (searchOverAll || payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kWiFiPAF))
     141              :         {
     142            0 :             ChipLogProgress(Controller, "WiFi-PAF: has RendezvousInformationFlag::kWiFiPAF");
     143            0 :             if (CHIP_NO_ERROR == (err = StartDiscoverOverWiFiPAF(payload)))
     144              :             {
     145            0 :                 isRunning = true;
     146              :             }
     147            0 :             VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err || CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err, err);
     148              :         }
     149              :     }
     150              : 
     151              :     // We always want to search on network because any node that has already been commissioned will use on-network regardless of the
     152              :     // QR code flag.
     153            0 :     if (CHIP_NO_ERROR == (err = StartDiscoverOverIP(payload)))
     154              :     {
     155            0 :         isRunning = true;
     156              :     }
     157            0 :     VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err, err);
     158              : 
     159            0 :     return isRunning ? CHIP_NO_ERROR : CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
     160              : }
     161              : 
     162            0 : CHIP_ERROR SetUpCodePairer::StartDiscoverOverBle(SetupPayload & payload)
     163              : {
     164              : #if CONFIG_NETWORK_LAYER_BLE
     165              : #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
     166              :     VerifyOrReturnError(mCommissioner != nullptr, CHIP_ERROR_INCORRECT_STATE);
     167              :     mCommissioner->ConnectBleTransportToSelf();
     168              : #endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
     169            0 :     VerifyOrReturnError(mBleLayer != nullptr, CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
     170              : 
     171            0 :     ChipLogProgress(Controller, "Starting commissioning discovery over BLE");
     172              : 
     173              :     // Handle possibly-sync callbacks.
     174            0 :     mWaitingForDiscovery[kBLETransport] = true;
     175            0 :     CHIP_ERROR err = mBleLayer->NewBleConnectionByDiscriminator(payload.discriminator, this, OnDiscoveredDeviceOverBleSuccess,
     176              :                                                                 OnDiscoveredDeviceOverBleError);
     177            0 :     if (err != CHIP_NO_ERROR)
     178              :     {
     179            0 :         mWaitingForDiscovery[kBLETransport] = false;
     180              :     }
     181            0 :     return err;
     182              : #else
     183              :     return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
     184              : #endif // CONFIG_NETWORK_LAYER_BLE
     185              : }
     186              : 
     187            0 : CHIP_ERROR SetUpCodePairer::StopConnectOverBle()
     188              : {
     189              :     // Make sure to not call CancelBleIncompleteConnection unless we are in fact
     190              :     // waiting on BLE discovery.  It will cancel connections that are in fact
     191              :     // completed. In particular, if we just established PASE over BLE calling
     192              :     // CancelBleIncompleteConnection here unconditionally would cancel the BLE
     193              :     // connection underlying the PASE session.  So make sure to only call
     194              :     // CancelBleIncompleteConnection if we're still waiting to hear back on the
     195              :     // BLE discovery bits.
     196            0 :     if (!mWaitingForDiscovery[kBLETransport])
     197              :     {
     198            0 :         return CHIP_NO_ERROR;
     199              :     }
     200              : 
     201            0 :     mWaitingForDiscovery[kBLETransport] = false;
     202              : #if CONFIG_NETWORK_LAYER_BLE
     203            0 :     VerifyOrReturnError(mBleLayer != nullptr, CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
     204            0 :     ChipLogDetail(Controller, "Stopping commissioning discovery over BLE");
     205            0 :     return mBleLayer->CancelBleIncompleteConnection();
     206              : #else
     207              :     return CHIP_NO_ERROR;
     208              : #endif // CONFIG_NETWORK_LAYER_BLE
     209              : }
     210              : 
     211            0 : CHIP_ERROR SetUpCodePairer::StartDiscoverOverIP(SetupPayload & payload)
     212              : {
     213            0 :     ChipLogProgress(Controller, "Starting commissioning discovery over DNS-SD");
     214              : 
     215            0 :     auto & discriminator = payload.discriminator;
     216            0 :     if (discriminator.IsShortDiscriminator())
     217              :     {
     218            0 :         mCurrentFilter.type = Dnssd::DiscoveryFilterType::kShortDiscriminator;
     219            0 :         mCurrentFilter.code = discriminator.GetShortValue();
     220              :     }
     221              :     else
     222              :     {
     223            0 :         mCurrentFilter.type = Dnssd::DiscoveryFilterType::kLongDiscriminator;
     224            0 :         mCurrentFilter.code = discriminator.GetLongValue();
     225              :     }
     226            0 :     mPayloadVendorID  = payload.vendorID;
     227            0 :     mPayloadProductID = payload.productID;
     228              : 
     229              :     // Handle possibly-sync callbacks.
     230            0 :     mWaitingForDiscovery[kIPTransport] = true;
     231            0 :     CHIP_ERROR err                     = mCommissioner->DiscoverCommissionableNodes(mCurrentFilter);
     232            0 :     if (err != CHIP_NO_ERROR)
     233              :     {
     234            0 :         mWaitingForDiscovery[kIPTransport] = false;
     235              :     }
     236            0 :     return err;
     237              : }
     238              : 
     239            0 : CHIP_ERROR SetUpCodePairer::StopConnectOverIP()
     240              : {
     241            0 :     ChipLogDetail(Controller, "Stopping commissioning discovery over DNS-SD");
     242              : 
     243            0 :     mWaitingForDiscovery[kIPTransport] = false;
     244            0 :     mCurrentFilter.type                = Dnssd::DiscoveryFilterType::kNone;
     245            0 :     mPayloadVendorID                   = kNotAvailable;
     246            0 :     mPayloadProductID                  = kNotAvailable;
     247              : 
     248            0 :     mCommissioner->StopCommissionableDiscovery();
     249            0 :     return CHIP_NO_ERROR;
     250              : }
     251              : 
     252            0 : CHIP_ERROR SetUpCodePairer::StartDiscoverOverSoftAP(SetupPayload & payload)
     253              : {
     254            0 :     return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
     255              : }
     256              : 
     257            0 : CHIP_ERROR SetUpCodePairer::StopConnectOverSoftAP()
     258              : {
     259            0 :     mWaitingForDiscovery[kSoftAPTransport] = false;
     260            0 :     return CHIP_NO_ERROR;
     261              : }
     262              : 
     263            0 : CHIP_ERROR SetUpCodePairer::StartDiscoverOverWiFiPAF(SetupPayload & payload)
     264              : {
     265              : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
     266              :     ChipLogProgress(Controller, "Starting commissioning discovery over WiFiPAF");
     267              :     VerifyOrReturnError(mCommissioner != nullptr, CHIP_ERROR_INCORRECT_STATE);
     268              :     mWaitingForDiscovery[kWiFiPAFTransport] = true;
     269              :     CHIP_ERROR err = DeviceLayer::ConnectivityMgr().WiFiPAFConnect(payload.discriminator, (void *) this, OnWiFiPAFSubscribeComplete,
     270              :                                                                    OnWiFiPAFSubscribeError);
     271              :     if (err != CHIP_NO_ERROR)
     272              :     {
     273              :         ChipLogError(Controller, "Commissioning discovery over WiFiPAF failed, err = %" CHIP_ERROR_FORMAT, err.Format());
     274              :         mWaitingForDiscovery[kWiFiPAFTransport] = false;
     275              :     }
     276              :     return err;
     277              : #else
     278            0 :     return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
     279              : #endif // CONFIG_NETWORK_LAYER_BLE
     280              : }
     281              : 
     282            0 : CHIP_ERROR SetUpCodePairer::StopConnectOverWiFiPAF()
     283              : {
     284            0 :     mWaitingForDiscovery[kWiFiPAFTransport] = false;
     285            0 :     return CHIP_NO_ERROR;
     286              : }
     287              : 
     288            0 : bool SetUpCodePairer::ConnectToDiscoveredDevice()
     289              : {
     290            0 :     if (mWaitingForPASE)
     291              :     {
     292              :         // Nothing to do.  Just wait until we either succeed or fail at that
     293              :         // PASE session establishment.
     294            0 :         return false;
     295              :     }
     296              : 
     297            0 :     while (!mDiscoveredParameters.empty())
     298              :     {
     299              :         // Grab the first element from the queue and try connecting to it.
     300              :         // Remove it from the queue before we try to connect, in case the
     301              :         // connection attempt fails and calls right back into us to try the next
     302              :         // thing.
     303            0 :         SetUpCodePairerParameters params(mDiscoveredParameters.front());
     304            0 :         mDiscoveredParameters.pop_front();
     305              : 
     306            0 :         params.SetSetupPINCode(mSetUpPINCode);
     307              : 
     308              : #if CHIP_PROGRESS_LOGGING
     309              :         char buf[Transport::PeerAddress::kMaxToStringSize];
     310            0 :         params.GetPeerAddress().ToString(buf);
     311            0 :         ChipLogProgress(Controller, "Attempting PASE connection to %s", buf);
     312              : #endif // CHIP_PROGRESS_LOGGING
     313              : 
     314              :         // Handle possibly-sync call backs from attempts to establish PASE.
     315            0 :         ExpectPASEEstablishment();
     316              : 
     317            0 :         if (params.GetPeerAddress().GetTransportType() == Transport::Type::kUdp)
     318              :         {
     319            0 :             mCurrentPASEParameters.SetValue(params);
     320              :         }
     321              : 
     322              :         CHIP_ERROR err;
     323            0 :         if (mConnectionType == SetupCodePairerBehaviour::kCommission)
     324              :         {
     325            0 :             err = mCommissioner->PairDevice(mRemoteId, params);
     326              :         }
     327              :         else
     328              :         {
     329            0 :             err = mCommissioner->EstablishPASEConnection(mRemoteId, params);
     330              :         }
     331              : 
     332            0 :         LogErrorOnFailure(err);
     333            0 :         if (err == CHIP_NO_ERROR)
     334              :         {
     335            0 :             return true;
     336              :         }
     337              : 
     338              :         // Failed to start establishing PASE.  Move on to the next item.
     339            0 :         PASEEstablishmentComplete();
     340            0 :     }
     341              : 
     342            0 :     return false;
     343              : }
     344              : 
     345              : #if CONFIG_NETWORK_LAYER_BLE
     346            0 : void SetUpCodePairer::OnDiscoveredDeviceOverBle(BLE_CONNECTION_OBJECT connObj)
     347              : {
     348            0 :     ChipLogProgress(Controller, "Discovered device to be commissioned over BLE");
     349              : 
     350            0 :     mWaitingForDiscovery[kBLETransport] = false;
     351              : 
     352              :     // In order to not wait for all the possible addresses discovered over mdns to
     353              :     // be tried before trying to connect over BLE, the discovered connection object is
     354              :     // inserted at the beginning of the list.
     355              :     //
     356              :     // It makes it the 'next' thing to try to connect to if there are already some
     357              :     // discovered parameters in the list.
     358            0 :     mDiscoveredParameters.emplace_front(connObj);
     359            0 :     ConnectToDiscoveredDevice();
     360            0 : }
     361              : 
     362            0 : void SetUpCodePairer::OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj)
     363              : {
     364            0 :     (static_cast<SetUpCodePairer *>(appState))->OnDiscoveredDeviceOverBle(connObj);
     365            0 : }
     366              : 
     367            0 : void SetUpCodePairer::OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err)
     368              : {
     369            0 :     static_cast<SetUpCodePairer *>(appState)->OnBLEDiscoveryError(err);
     370            0 : }
     371              : 
     372            0 : void SetUpCodePairer::OnBLEDiscoveryError(CHIP_ERROR err)
     373              : {
     374            0 :     ChipLogError(Controller, "Commissioning discovery over BLE failed: %" CHIP_ERROR_FORMAT, err.Format());
     375            0 :     mWaitingForDiscovery[kBLETransport] = false;
     376            0 :     LogErrorOnFailure(err);
     377            0 : }
     378              : #endif // CONFIG_NETWORK_LAYER_BLE
     379              : 
     380              : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
     381              : void SetUpCodePairer::OnDiscoveredDeviceOverWifiPAF()
     382              : {
     383              :     ChipLogProgress(Controller, "Discovered device to be commissioned over WiFiPAF, RemoteId: %lu", mRemoteId);
     384              : 
     385              :     mWaitingForDiscovery[kWiFiPAFTransport] = false;
     386              :     auto param                              = SetUpCodePairerParameters();
     387              :     param.SetPeerAddress(Transport::PeerAddress(Transport::Type::kWiFiPAF, mRemoteId));
     388              :     mDiscoveredParameters.emplace_back(param);
     389              :     ConnectToDiscoveredDevice();
     390              : }
     391              : 
     392              : void SetUpCodePairer::OnWifiPAFDiscoveryError(CHIP_ERROR err)
     393              : {
     394              :     ChipLogError(Controller, "Commissioning discovery over WiFiPAF failed: %" CHIP_ERROR_FORMAT, err.Format());
     395              :     mWaitingForDiscovery[kWiFiPAFTransport] = false;
     396              : }
     397              : 
     398              : void SetUpCodePairer::OnWiFiPAFSubscribeComplete(void * appState)
     399              : {
     400              :     auto self = (SetUpCodePairer *) appState;
     401              :     self->OnDiscoveredDeviceOverWifiPAF();
     402              : }
     403              : 
     404              : void SetUpCodePairer::OnWiFiPAFSubscribeError(void * appState, CHIP_ERROR err)
     405              : {
     406              :     auto self = (SetUpCodePairer *) appState;
     407              :     self->OnWifiPAFDiscoveryError(err);
     408              : }
     409              : #endif
     410              : 
     411            0 : bool SetUpCodePairer::IdIsPresent(uint16_t vendorOrProductID)
     412              : {
     413            0 :     return vendorOrProductID != kNotAvailable;
     414              : }
     415              : 
     416            0 : bool SetUpCodePairer::NodeMatchesCurrentFilter(const Dnssd::DiscoveredNodeData & discNodeData) const
     417              : {
     418            0 :     if (!discNodeData.Is<Dnssd::CommissionNodeData>())
     419              :     {
     420            0 :         return false;
     421              :     }
     422              : 
     423            0 :     const Dnssd::CommissionNodeData & nodeData = discNodeData.Get<Dnssd::CommissionNodeData>();
     424            0 :     if (nodeData.commissioningMode == 0)
     425              :     {
     426            0 :         ChipLogProgress(Controller, "Discovered device does not have an open commissioning window.");
     427            0 :         return false;
     428              :     }
     429              : 
     430              :     // The advertisement may not include a vendor id.
     431            0 :     if (IdIsPresent(mPayloadVendorID) && IdIsPresent(nodeData.vendorId) && mPayloadVendorID != nodeData.vendorId)
     432              :     {
     433            0 :         ChipLogProgress(Controller, "Discovered device does not match our vendor id.");
     434            0 :         return false;
     435              :     }
     436              : 
     437              :     // The advertisement may not include a product id.
     438            0 :     if (IdIsPresent(mPayloadProductID) && IdIsPresent(nodeData.productId) && mPayloadProductID != nodeData.productId)
     439              :     {
     440            0 :         ChipLogProgress(Controller, "Discovered device does not match our product id.");
     441            0 :         return false;
     442              :     }
     443              : 
     444            0 :     bool discriminatorMatches = false;
     445            0 :     switch (mCurrentFilter.type)
     446              :     {
     447            0 :     case Dnssd::DiscoveryFilterType::kShortDiscriminator:
     448            0 :         discriminatorMatches = (((nodeData.longDiscriminator >> 8) & 0x0F) == mCurrentFilter.code);
     449            0 :         break;
     450            0 :     case Dnssd::DiscoveryFilterType::kLongDiscriminator:
     451            0 :         discriminatorMatches = (nodeData.longDiscriminator == mCurrentFilter.code);
     452            0 :         break;
     453            0 :     case Dnssd::DiscoveryFilterType::kNone:
     454            0 :         ChipLogDetail(Controller, "Filter type none; all matches will fail");
     455            0 :         return false;
     456            0 :     default:
     457            0 :         ChipLogError(Controller, "Unknown filter type; all matches will fail");
     458            0 :         return false;
     459              :     }
     460            0 :     if (!discriminatorMatches)
     461              :     {
     462            0 :         ChipLogProgress(Controller, "Discovered device does not match our discriminator.");
     463              :     }
     464            0 :     return discriminatorMatches;
     465              : }
     466              : 
     467            0 : void SetUpCodePairer::NotifyCommissionableDeviceDiscovered(const Dnssd::DiscoveredNodeData & nodeData)
     468              : {
     469            0 :     if (!NodeMatchesCurrentFilter(nodeData))
     470              :     {
     471            0 :         return;
     472              :     }
     473              : 
     474            0 :     ChipLogProgress(Controller, "Discovered device to be commissioned over DNS-SD");
     475              : 
     476            0 :     NotifyCommissionableDeviceDiscovered(nodeData.Get<Dnssd::CommissionNodeData>());
     477              : }
     478              : 
     479            0 : void SetUpCodePairer::NotifyCommissionableDeviceDiscovered(const Dnssd::CommonResolutionData & resolutionData)
     480              : {
     481            0 :     if (mDiscoveryType == DiscoveryType::kDiscoveryNetworkOnlyWithoutPASEAutoRetry)
     482              :     {
     483              :         // If the discovery type does not want the PASE auto retry mechanism, we will just store
     484              :         // a single IP. So the discovery process is stopped as it won't be of any help anymore.
     485            0 :         StopConnectOverIP();
     486            0 :         mDiscoveredParameters.emplace_back(resolutionData, 0);
     487              :     }
     488              :     else
     489              :     {
     490            0 :         for (size_t i = 0; i < resolutionData.numIPs; i++)
     491              :         {
     492            0 :             mDiscoveredParameters.emplace_back(resolutionData, i);
     493              :         }
     494              :     }
     495              : 
     496            0 :     ConnectToDiscoveredDevice();
     497            0 : }
     498              : 
     499            0 : bool SetUpCodePairer::StopPairing(NodeId remoteId)
     500              : {
     501            0 :     VerifyOrReturnValue(mRemoteId != kUndefinedNodeId, false);
     502            0 :     VerifyOrReturnValue(remoteId == kUndefinedNodeId || remoteId == mRemoteId, false);
     503              : 
     504            0 :     if (mWaitingForPASE)
     505              :     {
     506            0 :         PASEEstablishmentComplete();
     507              :     }
     508              : 
     509            0 :     ResetDiscoveryState();
     510            0 :     mRemoteId = kUndefinedNodeId;
     511            0 :     return true;
     512              : }
     513              : 
     514            0 : bool SetUpCodePairer::TryNextRendezvousParameters()
     515              : {
     516            0 :     if (ConnectToDiscoveredDevice())
     517              :     {
     518            0 :         ChipLogProgress(Controller, "Trying connection to commissionee over different transport");
     519            0 :         return true;
     520              :     }
     521              : 
     522            0 :     if (DiscoveryInProgress())
     523              :     {
     524            0 :         ChipLogProgress(Controller, "Waiting to discover commissionees that match our filters");
     525            0 :         return true;
     526              :     }
     527              : 
     528            0 :     return false;
     529              : }
     530              : 
     531            0 : bool SetUpCodePairer::DiscoveryInProgress() const
     532              : {
     533            0 :     for (const auto & waiting : mWaitingForDiscovery)
     534              :     {
     535            0 :         if (waiting)
     536              :         {
     537            0 :             return true;
     538              :         }
     539              :     }
     540              : 
     541            0 :     return false;
     542              : }
     543              : 
     544            0 : void SetUpCodePairer::ResetDiscoveryState()
     545              : {
     546            0 :     StopConnectOverBle();
     547            0 :     StopConnectOverIP();
     548            0 :     StopConnectOverSoftAP();
     549            0 :     StopConnectOverWiFiPAF();
     550              : 
     551              :     // Just in case any of those failed to reset the waiting state properly.
     552            0 :     for (auto & waiting : mWaitingForDiscovery)
     553              :     {
     554            0 :         waiting = false;
     555              :     }
     556              : 
     557            0 :     mDiscoveredParameters.clear();
     558            0 :     mCurrentPASEParameters.ClearValue();
     559            0 :     mLastPASEError = CHIP_NO_ERROR;
     560              : 
     561            0 :     mSystemLayer->CancelTimer(OnDeviceDiscoveredTimeoutCallback, this);
     562            0 : }
     563              : 
     564            0 : void SetUpCodePairer::ExpectPASEEstablishment()
     565              : {
     566            0 :     VerifyOrDie(!mWaitingForPASE);
     567            0 :     mWaitingForPASE = true;
     568            0 :     auto * delegate = mCommissioner->GetPairingDelegate();
     569            0 :     VerifyOrDie(delegate != this);
     570            0 :     mPairingDelegate = delegate;
     571            0 :     mCommissioner->RegisterPairingDelegate(this);
     572            0 : }
     573              : 
     574            0 : void SetUpCodePairer::PASEEstablishmentComplete()
     575              : {
     576            0 :     VerifyOrDie(mWaitingForPASE);
     577            0 :     mWaitingForPASE = false;
     578            0 :     mCommissioner->RegisterPairingDelegate(mPairingDelegate);
     579            0 :     mPairingDelegate = nullptr;
     580            0 : }
     581              : 
     582            0 : void SetUpCodePairer::OnStatusUpdate(DevicePairingDelegate::Status status)
     583              : {
     584            0 :     if (status == DevicePairingDelegate::Status::SecurePairingFailed)
     585              :     {
     586              :         // If we're still waiting on discovery, don't propagate this failure
     587              :         // (which is due to PASE failure with something we discovered, but the
     588              :         // "something" may not have been the right thing) for now.  Wait until
     589              :         // discovery completes.  Then we will either succeed and notify
     590              :         // accordingly or time out and land in OnStatusUpdate again, but at that
     591              :         // point we will not be waiting on discovery anymore.
     592            0 :         if (!mDiscoveredParameters.empty())
     593              :         {
     594            0 :             ChipLogProgress(Controller, "Ignoring SecurePairingFailed status for now; we have more discovered devices to try");
     595            0 :             return;
     596              :         }
     597              : 
     598            0 :         if (DiscoveryInProgress())
     599              :         {
     600            0 :             ChipLogProgress(Controller,
     601              :                             "Ignoring SecurePairingFailed status for now; we are waiting to see if we discover more devices");
     602            0 :             return;
     603              :         }
     604              :     }
     605              : 
     606            0 :     if (mPairingDelegate)
     607              :     {
     608            0 :         mPairingDelegate->OnStatusUpdate(status);
     609              :     }
     610              : }
     611              : 
     612            0 : void SetUpCodePairer::OnPairingComplete(CHIP_ERROR error)
     613              : {
     614              :     // Save the pairing delegate so we can notify it.  We want to notify it
     615              :     // _after_ we restore the state on the commissioner, in case the delegate
     616              :     // ends up immediately calling back into the commissioner again when
     617              :     // notified.
     618            0 :     auto * pairingDelegate = mPairingDelegate;
     619            0 :     PASEEstablishmentComplete();
     620              : 
     621            0 :     if (CHIP_NO_ERROR == error)
     622              :     {
     623            0 :         ChipLogProgress(Controller, "PASE session established with commissionee. Stopping discovery.");
     624            0 :         ResetDiscoveryState();
     625            0 :         mRemoteId = kUndefinedNodeId;
     626              :         MATTER_LOG_METRIC_END(kMetricSetupCodePairerPairDevice, error);
     627            0 :         if (pairingDelegate != nullptr)
     628              :         {
     629            0 :             pairingDelegate->OnPairingComplete(error);
     630              :         }
     631            0 :         return;
     632              :     }
     633              : 
     634              :     // It may happen that there is a stale DNS entry. If so, ReconfirmRecord will flush
     635              :     // the record from the daemon cache once it determines that it is invalid.
     636              :     // It may not help for this particular resolve, but may help subsequent resolves.
     637            0 :     if (CHIP_ERROR_TIMEOUT == error && mCurrentPASEParameters.HasValue())
     638              :     {
     639            0 :         const auto & params = mCurrentPASEParameters.Value();
     640            0 :         const auto & peer   = params.GetPeerAddress();
     641            0 :         const auto & ip     = peer.GetIPAddress();
     642            0 :         auto err            = Dnssd::Resolver::Instance().ReconfirmRecord(params.mHostName, ip, params.mInterfaceId);
     643            0 :         if (CHIP_NO_ERROR != err && CHIP_ERROR_NOT_IMPLEMENTED != err)
     644              :         {
     645            0 :             ChipLogError(Controller, "Error when verifying the validity of an address: %" CHIP_ERROR_FORMAT, err.Format());
     646              :         }
     647              :     }
     648            0 :     mCurrentPASEParameters.ClearValue();
     649              : 
     650              :     // We failed to establish PASE.  Try the next thing we have discovered, if
     651              :     // any.
     652            0 :     if (TryNextRendezvousParameters())
     653              :     {
     654              :         // Keep waiting until that finishes.  Don't call OnPairingComplete yet.
     655            0 :         mLastPASEError = error;
     656            0 :         return;
     657              :     }
     658              : 
     659              :     MATTER_LOG_METRIC_END(kMetricSetupCodePairerPairDevice, error);
     660            0 :     if (pairingDelegate != nullptr)
     661              :     {
     662            0 :         pairingDelegate->OnPairingComplete(error);
     663              :     }
     664              : }
     665              : 
     666            0 : void SetUpCodePairer::OnPairingDeleted(CHIP_ERROR error)
     667              : {
     668            0 :     if (mPairingDelegate)
     669              :     {
     670            0 :         mPairingDelegate->OnPairingDeleted(error);
     671              :     }
     672            0 : }
     673              : 
     674            0 : void SetUpCodePairer::OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error)
     675              : {
     676              :     // Not really expecting this, but handle it anyway.
     677            0 :     if (mPairingDelegate)
     678              :     {
     679            0 :         mPairingDelegate->OnCommissioningComplete(deviceId, error);
     680              :     }
     681            0 : }
     682              : 
     683            0 : void SetUpCodePairer::OnDeviceDiscoveredTimeoutCallback(System::Layer * layer, void * context)
     684              : {
     685            0 :     ChipLogError(Controller, "Discovery timed out");
     686            0 :     auto * pairer = static_cast<SetUpCodePairer *>(context);
     687            0 :     LogErrorOnFailure(pairer->StopConnectOverBle());
     688            0 :     LogErrorOnFailure(pairer->StopConnectOverIP());
     689            0 :     LogErrorOnFailure(pairer->StopConnectOverSoftAP());
     690            0 :     if (!pairer->mWaitingForPASE && pairer->mDiscoveredParameters.empty())
     691              :     {
     692              :         // We're not waiting on any more PASE attempts, and we're not going to
     693              :         // discover anything at this point, so we should just notify our
     694              :         // listener.
     695            0 :         CHIP_ERROR err = pairer->mLastPASEError;
     696            0 :         if (err == CHIP_NO_ERROR)
     697              :         {
     698            0 :             err = CHIP_ERROR_TIMEOUT;
     699              :         }
     700              :         MATTER_LOG_METRIC_END(kMetricSetupCodePairerPairDevice, err);
     701            0 :         pairer->mCommissioner->OnSessionEstablishmentError(err);
     702              :     }
     703            0 : }
     704              : 
     705            0 : SetUpCodePairerParameters::SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, size_t index)
     706              : {
     707            0 :     mInterfaceId = data.interfaceId;
     708            0 :     Platform::CopyString(mHostName, data.hostName);
     709              : 
     710            0 :     auto & ip = data.ipAddress[index];
     711            0 :     SetPeerAddress(Transport::PeerAddress::UDP(ip, data.port, ip.IsIPv6LinkLocal() ? data.interfaceId : Inet::InterfaceId::Null()));
     712              : 
     713            0 :     if (data.mrpRetryIntervalIdle.has_value())
     714              :     {
     715            0 :         SetIdleInterval(*data.mrpRetryIntervalIdle);
     716              :     }
     717              : 
     718            0 :     if (data.mrpRetryIntervalActive.has_value())
     719              :     {
     720            0 :         SetActiveInterval(*data.mrpRetryIntervalActive);
     721              :     }
     722            0 : }
     723              : 
     724              : #if CONFIG_NETWORK_LAYER_BLE
     725            0 : SetUpCodePairerParameters::SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, bool connected)
     726              : {
     727            0 :     Transport::PeerAddress peerAddress = Transport::PeerAddress::BLE();
     728            0 :     SetPeerAddress(peerAddress);
     729            0 :     if (connected)
     730              :     {
     731            0 :         SetConnectionObject(connObj);
     732              :     }
     733              :     else
     734              :     {
     735            0 :         SetDiscoveredObject(connObj);
     736              :     }
     737            0 : }
     738              : #endif // CONFIG_NETWORK_LAYER_BLE
     739              : 
     740              : } // namespace Controller
     741              : } // namespace chip
        

Generated by: LCOV version 2.0-1