diff --git a/src/controller/SetUpCodePairer.cpp b/src/controller/SetUpCodePairer.cpp index c3b41a7aab1c0f..bf56023793a857 100644 --- a/src/controller/SetUpCodePairer.cpp +++ b/src/controller/SetUpCodePairer.cpp @@ -138,9 +138,26 @@ CHIP_ERROR SetUpCodePairer::StartDiscoverOverIP(SetupPayload & payload) : Dnssd::DiscoveryFilterType::kLongDiscriminator; currentFilter.code = payload.isShortDiscriminator ? static_cast((payload.discriminator >> 8) & 0x0F) : payload.discriminator; + + // We're going to ensure that anything we discover matches currentFilter + // before we use it, which will do our discriminator checks for us. + // + // We are using an mdns continuous query for some PTR record to discover + // devices. If the PTR record we use is for one of the discriminator-based + // subtypes (based on currentFilter), then we can run into a problem where + // we discover a (possibly stale) advertisement for a non-commissionable + // (CM=0) node and ignore it, and then when it becomes commissionable we + // don't notice because that just updates the TXT record to CM=1 and does + // not touch the PTR record we are querying for. + // + // So instead we query the PTR record for the "_CM" subtype, which will get + // added when a node enters commissioning mode. + Dnssd::DiscoveryFilter filter; + filter.type = Dnssd::DiscoveryFilterType::kCommissioningMode; + // Handle possibly-sync callbacks. mWaitingForDiscovery[kIPTransport] = true; - CHIP_ERROR err = mCommissioner->DiscoverCommissionableNodes(currentFilter); + CHIP_ERROR err = mCommissioner->DiscoverCommissionableNodes(filter); if (err != CHIP_NO_ERROR) { mWaitingForDiscovery[kIPTransport] = false;