Skip to content

Commit c6ad5b1

Browse files
authored
Report mdns results from all interfaces instead of the highest priori… (#35597)
* [chip-tool] Add discover find-commissionable-by-instance-name command * Report mdns results from all interfaces instead of the highest priority interface * Update DnssdContexts.cpp
1 parent 2ed3f65 commit c6ad5b1

File tree

6 files changed

+83
-66
lines changed

6 files changed

+83
-66
lines changed

examples/chip-tool/commands/discover/Commands.h

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ void registerCommandsDiscover(Commands & commands, CredentialIssuerCommands * cr
8484
make_unique<DiscoverCommissionableByCommissioningModeCommand>(credsIssuerConfig),
8585
make_unique<DiscoverCommissionableByVendorIdCommand>(credsIssuerConfig),
8686
make_unique<DiscoverCommissionableByDeviceTypeCommand>(credsIssuerConfig),
87+
make_unique<DiscoverCommissionableByInstanceNameCommand>(credsIssuerConfig),
8788
make_unique<DiscoverCommissionersCommand>(credsIssuerConfig),
8889
};
8990

examples/chip-tool/commands/discover/DiscoverCommissionablesCommand.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,11 @@ CHIP_ERROR DiscoverCommissionableByDeviceTypeCommand::RunCommand()
122122
chip::Dnssd::DiscoveryFilter filter(chip::Dnssd::DiscoveryFilterType::kDeviceType, mDeviceType);
123123
return mCommissioner->DiscoverCommissionableNodes(filter);
124124
}
125+
126+
CHIP_ERROR DiscoverCommissionableByInstanceNameCommand::RunCommand()
127+
{
128+
mCommissioner = &CurrentCommissioner();
129+
mCommissioner->RegisterDeviceDiscoveryDelegate(this);
130+
chip::Dnssd::DiscoveryFilter filter(chip::Dnssd::DiscoveryFilterType::kInstanceName, mInstanceName);
131+
return mCommissioner->DiscoverCommissionableNodes(filter);
132+
}

examples/chip-tool/commands/discover/DiscoverCommissionablesCommand.h

+16
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,19 @@ class DiscoverCommissionableByDeviceTypeCommand : public DiscoverCommissionables
159159
// TODO: possibly 32-bit - see spec issue #3226
160160
uint16_t mDeviceType;
161161
};
162+
163+
class DiscoverCommissionableByInstanceNameCommand : public DiscoverCommissionablesCommandBase
164+
{
165+
public:
166+
DiscoverCommissionableByInstanceNameCommand(CredentialIssuerCommands * credsIssuerConfig) :
167+
DiscoverCommissionablesCommandBase("find-commissionable-by-instance-name", credsIssuerConfig)
168+
{
169+
AddArgument("value", &mInstanceName);
170+
}
171+
172+
/////////// CHIPCommand Interface /////////
173+
CHIP_ERROR RunCommand() override;
174+
175+
private:
176+
char * mInstanceName;
177+
};

src/lib/dnssd/Discovery_ImplPlatform.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static void HandleNodeResolve(void * context, DnssdService * result, const Span<
4343
{
4444
DiscoveryContext * discoveryContext = static_cast<DiscoveryContext *>(context);
4545

46-
if (error != CHIP_NO_ERROR)
46+
if (error != CHIP_NO_ERROR && error != CHIP_ERROR_IN_PROGRESS)
4747
{
4848
discoveryContext->Release();
4949
return;
@@ -55,7 +55,13 @@ static void HandleNodeResolve(void * context, DnssdService * result, const Span<
5555

5656
nodeData.Get<CommissionNodeData>().LogDetail();
5757
discoveryContext->OnNodeDiscovered(nodeData);
58-
discoveryContext->Release();
58+
59+
// CHIP_ERROR_IN_PROGRESS indicates that more results are coming, so don't release
60+
// the context yet.
61+
if (error == CHIP_NO_ERROR)
62+
{
63+
discoveryContext->Release();
64+
}
5965
}
6066

6167
static void HandleNodeOperationalBrowse(void * context, DnssdService * result, CHIP_ERROR error)

src/platform/Darwin/DnssdContexts.cpp

+44-54
Original file line numberDiff line numberDiff line change
@@ -564,88 +564,78 @@ void ResolveContext::DispatchSuccess()
564564
};
565565
#endif // TARGET_OS_TV
566566

567-
for (auto interfaceIndex : priorityInterfaceIndices)
567+
std::vector<InterfaceKey> interfacesOrder;
568+
for (auto priorityInterfaceIndex : priorityInterfaceIndices)
568569
{
569-
if (interfaceIndex == 0)
570+
if (priorityInterfaceIndex == 0)
570571
{
571572
// Not actually an interface we have, since if_nametoindex
572573
// returned 0.
573574
continue;
574575
}
575576

576-
if (TryReportingResultsForInterfaceIndex(static_cast<uint32_t>(interfaceIndex)))
577+
for (auto & interface : interfaces)
577578
{
578-
return;
579+
if (interface.second.HasAddresses() && priorityInterfaceIndex == interface.first.interfaceId)
580+
{
581+
interfacesOrder.push_back(interface.first);
582+
}
579583
}
580584
}
581585

582586
for (auto & interface : interfaces)
583587
{
584-
if (TryReportingResultsForInterfaceIndex(interface.first.interfaceId, interface.first.hostname,
585-
interface.first.isSRPResult))
588+
// Skip interfaces that have already been prioritized to avoid duplicate results
589+
auto interfaceKey = std::find(std::begin(interfacesOrder), std::end(interfacesOrder), interface.first);
590+
if (interfaceKey != std::end(interfacesOrder))
586591
{
587-
return;
592+
continue;
588593
}
589-
}
590594

591-
ChipLogError(Discovery, "Successfully finalizing resolve for %s without finding any actual IP addresses.",
592-
instanceName.c_str());
593-
}
594-
595-
bool ResolveContext::TryReportingResultsForInterfaceIndex(uint32_t interfaceIndex, const std::string & hostname, bool isSRPResult)
596-
{
597-
InterfaceKey interfaceKey = { interfaceIndex, hostname, isSRPResult };
598-
auto & interface = interfaces[interfaceKey];
599-
auto & ips = interface.addresses;
595+
// Some interface may not have any ips, just ignore them.
596+
if (!interface.second.HasAddresses())
597+
{
598+
continue;
599+
}
600600

601-
// Some interface may not have any ips, just ignore them.
602-
if (ips.size() == 0)
603-
{
604-
return false;
601+
interfacesOrder.push_back(interface.first);
605602
}
606603

607-
ChipLogProgress(Discovery, "Mdns: Resolve success on interface %" PRIu32, interfaceIndex);
608-
609-
auto & service = interface.service;
610-
auto addresses = Span<Inet::IPAddress>(ips.data(), ips.size());
611-
if (nullptr == callback)
604+
for (auto & interfaceKey : interfacesOrder)
612605
{
613-
auto delegate = static_cast<DiscoverNodeDelegate *>(context);
614-
DiscoveredNodeData nodeData;
606+
auto & interfaceInfo = interfaces[interfaceKey];
607+
auto & service = interfaceInfo.service;
608+
auto & ips = interfaceInfo.addresses;
609+
auto addresses = Span<Inet::IPAddress>(ips.data(), ips.size());
615610

616-
// Check whether mType (service name) exactly matches with operational service name
617-
if (strcmp(service.mType, kOperationalServiceName) == 0)
611+
ChipLogProgress(Discovery, "Mdns: Resolve success on interface %" PRIu32, interfaceKey.interfaceId);
612+
613+
if (nullptr == callback)
618614
{
619-
service.ToDiscoveredOperationalNodeBrowseData(nodeData);
615+
auto delegate = static_cast<DiscoverNodeDelegate *>(context);
616+
DiscoveredNodeData nodeData;
617+
618+
// Check whether mType (service name) exactly matches with operational service name
619+
if (strcmp(service.mType, kOperationalServiceName) == 0)
620+
{
621+
service.ToDiscoveredOperationalNodeBrowseData(nodeData);
622+
}
623+
else
624+
{
625+
service.ToDiscoveredCommissionNodeData(addresses, nodeData);
626+
}
627+
delegate->OnNodeDiscovered(nodeData);
620628
}
621629
else
622630
{
623-
service.ToDiscoveredCommissionNodeData(addresses, nodeData);
631+
CHIP_ERROR error = &interfaceKey == &interfacesOrder.back() ? CHIP_NO_ERROR : CHIP_ERROR_IN_PROGRESS;
632+
callback(context, &service, addresses, error);
624633
}
625-
delegate->OnNodeDiscovered(nodeData);
626634
}
627-
else
628-
{
629-
callback(context, &service, addresses, CHIP_NO_ERROR);
630-
}
631-
632-
return true;
633-
}
634635

635-
bool ResolveContext::TryReportingResultsForInterfaceIndex(uint32_t interfaceIndex)
636-
{
637-
for (auto & interface : interfaces)
638-
{
639-
if (interface.first.interfaceId == interfaceIndex)
640-
{
641-
if (TryReportingResultsForInterfaceIndex(interface.first.interfaceId, interface.first.hostname,
642-
interface.first.isSRPResult))
643-
{
644-
return true;
645-
}
646-
}
647-
}
648-
return false;
636+
VerifyOrDo(interfacesOrder.size(),
637+
ChipLogError(Discovery, "Successfully finalizing resolve for %s without finding any actual IP addresses.",
638+
instanceName.c_str()));
649639
}
650640

651641
void ResolveContext::SRPTimerExpiredCallback(chip::System::Layer * systemLayer, void * callbackContext)

src/platform/Darwin/DnssdImpl.h

+6-10
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ struct InterfaceInfo
233233
std::vector<Inet::IPAddress> addresses;
234234
std::string fullyQualifiedDomainName;
235235
bool isDNSLookUpRequested = false;
236+
bool HasAddresses() const { return addresses.size() != 0; };
236237
};
237238

238239
struct InterfaceKey
@@ -247,6 +248,11 @@ struct InterfaceKey
247248
(this->isSRPResult < other.isSRPResult));
248249
}
249250

251+
inline bool operator==(const InterfaceKey & other) const
252+
{
253+
return this->interfaceId == other.interfaceId && this->hostname == other.hostname && this->isSRPResult == other.isSRPResult;
254+
}
255+
250256
uint32_t interfaceId;
251257
std::string hostname;
252258
bool isSRPResult = false;
@@ -310,16 +316,6 @@ struct ResolveContext : public GenericContext
310316
*
311317
*/
312318
void CancelSRPTimerIfRunning();
313-
314-
private:
315-
/**
316-
* Try reporting the results we got on the provided interface index.
317-
* Returns true if information was reported, false if not (e.g. if there
318-
* were no IP addresses, etc).
319-
*/
320-
bool TryReportingResultsForInterfaceIndex(uint32_t interfaceIndex, const std::string & hostname, bool isSRPResult);
321-
322-
bool TryReportingResultsForInterfaceIndex(uint32_t interfaceIndex);
323319
};
324320

325321
} // namespace Dnssd

0 commit comments

Comments
 (0)