diff --git a/src/controller/SetUpCodePairer.cpp b/src/controller/SetUpCodePairer.cpp index 64b2459ce5faeb..1cde4883f44455 100644 --- a/src/controller/SetUpCodePairer.cpp +++ b/src/controller/SetUpCodePairer.cpp @@ -223,14 +223,14 @@ bool SetUpCodePairer::ConnectToDiscoveredDevice() // Remove it from the queue before we try to connect, in case the // connection attempt fails and calls right back into us to try the next // thing. - RendezvousParameters params(mDiscoveredParameters.front()); + mCurrentParameters = mDiscoveredParameters.front(); mDiscoveredParameters.pop(); - params.SetSetupPINCode(mSetUpPINCode); + mCurrentParameters.SetSetupPINCode(mSetUpPINCode); #if CHIP_PROGRESS_LOGGING char buf[Transport::PeerAddress::kMaxToStringSize]; - params.GetPeerAddress().ToString(buf); + mCurrentParameters.GetPeerAddress().ToString(buf); ChipLogProgress(Controller, "Attempting PASE connection to %s", buf); #endif // CHIP_PROGRESS_LOGGING @@ -240,11 +240,11 @@ bool SetUpCodePairer::ConnectToDiscoveredDevice() CHIP_ERROR err; if (mConnectionType == SetupCodePairerBehaviour::kCommission) { - err = mCommissioner->PairDevice(mRemoteId, params); + err = mCommissioner->PairDevice(mRemoteId, mCurrentParameters); } else { - err = mCommissioner->EstablishPASEConnection(mRemoteId, params); + err = mCommissioner->EstablishPASEConnection(mRemoteId, mCurrentParameters); } LogErrorOnFailure(err); @@ -267,9 +267,7 @@ void SetUpCodePairer::OnDiscoveredDeviceOverBle(BLE_CONNECTION_OBJECT connObj) mWaitingForDiscovery[kBLETransport] = false; - Transport::PeerAddress peerAddress = Transport::PeerAddress::BLE(); - mDiscoveredParameters.emplace(); - mDiscoveredParameters.back().SetPeerAddress(peerAddress).SetConnectionObject(connObj); + mDiscoveredParameters.emplace(connObj); ConnectToDiscoveredDevice(); } @@ -338,25 +336,7 @@ void SetUpCodePairer::NotifyCommissionableDeviceDiscovered(const Dnssd::Discover ChipLogProgress(Controller, "Discovered device to be commissioned over DNS-SD"); - Inet::InterfaceId interfaceId = - nodeData.resolutionData.ipAddress[0].IsIPv6LinkLocal() ? nodeData.resolutionData.interfaceId : Inet::InterfaceId::Null(); - Transport::PeerAddress peerAddress = - Transport::PeerAddress::UDP(nodeData.resolutionData.ipAddress[0], nodeData.resolutionData.port, interfaceId); - mDiscoveredParameters.emplace(); - mDiscoveredParameters.back().SetPeerAddress(peerAddress); - - if (nodeData.resolutionData.mrpRetryIntervalIdle.HasValue()) - { - auto interval = nodeData.resolutionData.mrpRetryIntervalIdle.Value(); - mDiscoveredParameters.back().SetIdleInterval(interval); - } - - if (nodeData.resolutionData.mrpRetryIntervalActive.HasValue()) - { - auto interval = nodeData.resolutionData.mrpRetryIntervalActive.Value(); - mDiscoveredParameters.back().SetActiveInterval(interval); - } - + mDiscoveredParameters.emplace(nodeData.resolutionData); ConnectToDiscoveredDevice(); } @@ -412,7 +392,8 @@ void SetUpCodePairer::ResetDiscoveryState() mDiscoveredParameters.pop(); } - mLastPASEError = CHIP_NO_ERROR; + mCurrentParameters = SetUpCodePairerParameters(); + mLastPASEError = CHIP_NO_ERROR; } void SetUpCodePairer::ExpectPASEEstablishment() @@ -474,7 +455,9 @@ void SetUpCodePairer::OnPairingComplete(CHIP_ERROR error) // ends up immediately calling back into the commissioner again when // notified. auto * pairingDelegate = mPairingDelegate; - PASEEstablishmentComplete(); + + auto params = mCurrentParameters; + mCurrentParameters = SetUpCodePairerParameters(); if (CHIP_NO_ERROR == error) { @@ -483,10 +466,17 @@ void SetUpCodePairer::OnPairingComplete(CHIP_ERROR error) ResetDiscoveryState(); if (pairingDelegate != nullptr) { + PASEEstablishmentComplete(); pairingDelegate->OnPairingComplete(error); } return; } + else if (CHIP_ERROR_TIMEOUT == error && mWaitingForPASE) + { + // It may happen that there is stale DNS entry. If so, ReconfirmRecord will flush the record from the daemon cache + // once it determines that it is invalid. It may not help for this particular resolve, but may help subsequent resolves. + params.ReconfirmRecord(); + } // We failed to establish PASE. Try the next thing we have discovered, if // any. @@ -499,6 +489,7 @@ void SetUpCodePairer::OnPairingComplete(CHIP_ERROR error) if (pairingDelegate != nullptr) { + PASEEstablishmentComplete(); pairingDelegate->OnPairingComplete(error); } } @@ -541,5 +532,43 @@ void SetUpCodePairer::OnDeviceDiscoveredTimeoutCallback(System::Layer * layer, v } } +SetUpCodePairerParameters::SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data) +{ + interfaceId = data.interfaceId; + Platform::CopyString(hostName, data.hostName); + + auto ip = data.ipAddress[0]; + SetPeerAddress(Transport::PeerAddress::UDP(ip, data.port, ip.IsIPv6LinkLocal() ? data.interfaceId : Inet::InterfaceId::Null())); + + if (data.mrpRetryIntervalIdle.HasValue()) + { + SetIdleInterval(data.mrpRetryIntervalIdle.Value()); + } + + if (data.mrpRetryIntervalActive.HasValue()) + { + SetActiveInterval(data.mrpRetryIntervalActive.Value()); + } +} + +#if CONFIG_NETWORK_LAYER_BLE +SetUpCodePairerParameters::SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj) +{ + Transport::PeerAddress peerAddress = Transport::PeerAddress::BLE(); + SetPeerAddress(peerAddress).SetConnectionObject(connObj); +} +#endif // CONFIG_NETWORK_LAYER_BLE + +void SetUpCodePairerParameters::ReconfirmRecord() const +{ + VerifyOrReturn(GetPeerAddress().GetTransportType() == Transport::Type::kUdp); + + auto err = Dnssd::Resolver::Instance().ReconfirmRecord(hostName, GetPeerAddress().GetIPAddress(), interfaceId); + if (CHIP_NO_ERROR != err && CHIP_ERROR_NOT_IMPLEMENTED != err) + { + ChipLogError(Controller, "Error when verifying the validity of an address: %" CHIP_ERROR_FORMAT, err.Format()); + } +} + } // namespace Controller } // namespace chip diff --git a/src/controller/SetUpCodePairer.h b/src/controller/SetUpCodePairer.h index ed1c6f0c2ad5ac..db3a9dcc4b9a32 100644 --- a/src/controller/SetUpCodePairer.h +++ b/src/controller/SetUpCodePairer.h @@ -48,6 +48,22 @@ namespace Controller { class DeviceCommissioner; +class SetUpCodePairerParameters : public RendezvousParameters +{ +public: + SetUpCodePairerParameters() = default; + SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data); +#if CONFIG_NETWORK_LAYER_BLE + SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj); +#endif // CONFIG_NETWORK_LAYER_BLE + + void ReconfirmRecord() const; + +private: + char hostName[Dnssd::kHostNameMaxLength + 1] = {}; + Inet::InterfaceId interfaceId; +}; + enum class SetupCodePairerBehaviour : uint8_t { kCommission, @@ -180,7 +196,8 @@ class DLL_EXPORT SetUpCodePairer : public DevicePairingDelegate // Queue of things we have discovered but not tried connecting to yet. The // general discovery/pairing process will terminate once this queue is empty // and all the booleans in mWaitingForDiscovery are false. - std::queue mDiscoveredParameters; + std::queue mDiscoveredParameters; + SetUpCodePairerParameters mCurrentParameters; // mWaitingForPASE is true if we have called either // EstablishPASEConnection or PairDevice on mCommissioner and are now just