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

Generated by: LCOV version 2.0-1