Skip to content

Commit

Permalink
Add an API to stop a DNS-SD browse operation. (#22823)
Browse files Browse the repository at this point in the history
* Add an API to stop a DNS-SD browse operation.

Most backends don't implement this yet. Darwin does, and no longer
stops Browse operations itself.

Fixes #19194

May provide a way toward fixing
#13275

* Address review comments.

* Address more review comments.
  • Loading branch information
bzbarsky-apple authored and pull[bot] committed Jun 21, 2023
1 parent a5942de commit 1002331
Show file tree
Hide file tree
Showing 29 changed files with 256 additions and 22 deletions.
3 changes: 2 additions & 1 deletion examples/chip-tool/commands/pairing/PairingCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,8 @@ void PairingCommand::OnDiscoveredDevice(const chip::Dnssd::DiscoveredNodeData &
nodeData.resolutionData.ipAddress[0].ToString(buf);
ChipLogProgress(chipTool, "Discovered Device: %s:%u", buf, port);

// Stop Mdns discovery. Is it the right method ?
// Stop Mdns discovery.
CurrentCommissioner().StopCommissionableDiscovery();
CurrentCommissioner().RegisterDeviceDiscoveryDelegate(nullptr);

Inet::InterfaceId interfaceId =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ CHIP_ERROR DiscoveryCommands::SetupDiscoveryCommands()

CHIP_ERROR DiscoveryCommands::TearDownDiscoveryCommands()
{
mDNSResolver.StopDiscovery();
mDNSResolver.SetOperationalDelegate(nullptr);
mDNSResolver.SetCommissioningDelegate(nullptr);
return CHIP_NO_ERROR;
Expand Down
5 changes: 5 additions & 0 deletions src/controller/CHIPDeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1431,6 +1431,11 @@ CHIP_ERROR DeviceCommissioner::DiscoverCommissionableNodes(Dnssd::DiscoveryFilte
return mDNSResolver.DiscoverCommissionableNodes(filter);
}

CHIP_ERROR DeviceCommissioner::StopCommissionableDiscovery()
{
return mDNSResolver.StopDiscovery();
}

const Dnssd::DiscoveredNodeData * DeviceCommissioner::GetDiscoveredDevice(int idx)
{
return GetDiscoveredNode(idx);
Expand Down
6 changes: 6 additions & 0 deletions src/controller/CHIPDeviceController.h
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,12 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController,
*/
CHIP_ERROR DiscoverCommissionableNodes(Dnssd::DiscoveryFilter filter);

/**
* Stop commissionable discovery triggered by a previous
* DiscoverCommissionableNodes call.
*/
CHIP_ERROR StopCommissionableDiscovery();

/**
* @brief
* Returns information about discovered devices.
Expand Down
2 changes: 2 additions & 0 deletions src/controller/SetUpCodePairer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ CHIP_ERROR SetUpCodePairer::StopConnectOverIP()

mWaitingForDiscovery[kIPTransport] = false;
currentFilter.type = Dnssd::DiscoveryFilterType::kNone;

mCommissioner->StopCommissionableDiscovery();
return CHIP_NO_ERROR;
}

Expand Down
1 change: 1 addition & 0 deletions src/controller/tests/TestCommissionableNodeController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class MockResolver : public Resolver
{
return CHIP_ERROR_NOT_IMPLEMENTED;
}
CHIP_ERROR StopDiscovery() override { return CHIP_ERROR_NOT_IMPLEMENTED; }

CHIP_ERROR InitStatus = CHIP_NO_ERROR;
CHIP_ERROR ResolveNodeIdStatus = CHIP_NO_ERROR;
Expand Down
13 changes: 13 additions & 0 deletions src/lib/dnssd/ActiveResolveAttempts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,19 @@ void ActiveResolveAttempts::CompleteIpResolution(SerializedQNameIterator targetH
}
}

CHIP_ERROR ActiveResolveAttempts::CompleteAllBrowses()
{
for (auto & item : mRetryQueue)
{
if (item.attempt.IsBrowse())
{
item.attempt.Clear();
}
}

return CHIP_NO_ERROR;
}

void ActiveResolveAttempts::MarkPending(const chip::PeerId & peerId)
{
MarkPending(ScheduledAttempt(peerId, /* firstSend */ true));
Expand Down
4 changes: 4 additions & 0 deletions src/lib/dnssd/ActiveResolveAttempts.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ class ActiveResolveAttempts
void Complete(const chip::Dnssd::DiscoveredNodeData & data);
void CompleteIpResolution(SerializedQNameIterator targetHostName);

/// Mark all browse-type scheduled attemptes as a success, removing them
/// from the internal list.
CHIP_ERROR CompleteAllBrowses();

/// Mark that a resolution is pending, adding it to the internal list
///
/// Once this complete, this peer id will be returned immediately
Expand Down
53 changes: 49 additions & 4 deletions src/lib/dnssd/Discovery_ImplPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,14 @@ static void HandleNodeBrowse(void * context, DnssdService * services, size_t ser

if (error != CHIP_NO_ERROR)
{
// We don't have access to the ResolverProxy here to clear out its
// mDiscoveryContext. The underlying implementation of
// ChipDnssdStopBrowse needs to handle a possibly-stale reference
// safely, so this won't lead to crashes, but it can lead to
// mis-behavior if a stale mDiscoveryContext happens to match a newer
// browse operation.
//
// TODO: Have a way to clear that state here.
proxy->Release();
return;
}
Expand All @@ -174,6 +182,14 @@ static void HandleNodeBrowse(void * context, DnssdService * services, size_t ser

if (finalBrowse)
{
// We don't have access to the ResolverProxy here to clear out its
// mDiscoveryContext. The underlying implementation of
// ChipDnssdStopBrowse needs to handle a possibly-stale reference
// safely, so this won't lead to crashes, but it can lead to
// mis-behavior if a stale mDiscoveryContext happens to match a newer
// browse operation.
//
// TODO: Have a way to clear that state here.
proxy->Release();
}
}
Expand Down Expand Up @@ -616,6 +632,12 @@ CHIP_ERROR DiscoveryImplPlatform::DiscoverCommissioners(DiscoveryFilter filter)
return mResolverProxy.DiscoverCommissioners(filter);
}

CHIP_ERROR DiscoveryImplPlatform::StopDiscovery()
{
ReturnErrorOnFailure(InitImpl());
return mResolverProxy.StopDiscovery();
}

DiscoveryImplPlatform & DiscoveryImplPlatform::GetInstance()
{
return sManager;
Expand Down Expand Up @@ -656,6 +678,8 @@ ResolverProxy::~ResolverProxy()

CHIP_ERROR ResolverProxy::DiscoverCommissionableNodes(DiscoveryFilter filter)
{
StopDiscovery();

VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE);
mDelegate->Retain();

Expand All @@ -674,12 +698,17 @@ CHIP_ERROR ResolverProxy::DiscoverCommissionableNodes(DiscoveryFilter filter)
char serviceName[kMaxCommissionableServiceNameSize];
ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kCommissionableNode));

return ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny,
Inet::InterfaceId::Null(), HandleNodeBrowse, mDelegate);
intptr_t browseIdentifier;
ReturnErrorOnFailure(ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny,
Inet::InterfaceId::Null(), HandleNodeBrowse, mDelegate, &browseIdentifier));
mDiscoveryContext.Emplace(browseIdentifier);
return CHIP_NO_ERROR;
}

CHIP_ERROR ResolverProxy::DiscoverCommissioners(DiscoveryFilter filter)
{
StopDiscovery();

VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE);
mDelegate->Retain();

Expand All @@ -698,8 +727,24 @@ CHIP_ERROR ResolverProxy::DiscoverCommissioners(DiscoveryFilter filter)
char serviceName[kMaxCommissionerServiceNameSize];
ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kCommissionerNode));

return ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny,
Inet::InterfaceId::Null(), HandleNodeBrowse, mDelegate);
intptr_t browseIdentifier;
ReturnErrorOnFailure(ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny,
Inet::InterfaceId::Null(), HandleNodeBrowse, mDelegate, &browseIdentifier));
mDiscoveryContext.Emplace(browseIdentifier);
return CHIP_NO_ERROR;
}

CHIP_ERROR ResolverProxy::StopDiscovery()
{
if (!mDiscoveryContext.HasValue())
{
// No discovery going on.
return CHIP_NO_ERROR;
}

CHIP_ERROR err = ChipDnssdStopBrowse(mDiscoveryContext.Value());
mDiscoveryContext.ClearValue();
return err;
}

} // namespace Dnssd
Expand Down
1 change: 1 addition & 0 deletions src/lib/dnssd/Discovery_ImplPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class DiscoveryImplPlatform : public ServiceAdvertiser, public Resolver
CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type) override;
CHIP_ERROR DiscoverCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter()) override;
CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter = DiscoveryFilter()) override;
CHIP_ERROR StopDiscovery() override;

static DiscoveryImplPlatform & GetInstance();

Expand Down
8 changes: 8 additions & 0 deletions src/lib/dnssd/Resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,14 @@ class Resolver
*/
virtual CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter = DiscoveryFilter()) = 0;

/**
* Stop discovery (of commissionable or commissioner nodes).
*
* Some back ends may not support stopping discovery, so consumers should
* not assume they will stop getting callbacks after calling this.
*/
virtual CHIP_ERROR StopDiscovery() = 0;

/**
* Provides the system-wide implementation of the service resolver
*/
Expand Down
5 changes: 5 additions & 0 deletions src/lib/dnssd/ResolverProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,16 @@ class ResolverProxy : public Resolver
CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type) override;
CHIP_ERROR DiscoverCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter()) override;
CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter = DiscoveryFilter()) override;
CHIP_ERROR StopDiscovery() override;

private:
ResolverDelegateProxy * mDelegate = nullptr;
OperationalResolveDelegate * mPreInitOperationalDelegate = nullptr;
CommissioningResolveDelegate * mPreInitCommissioningDelegate = nullptr;

// While discovery (commissionable or commissioner) is ongoing,
// mDiscoveryContext may have a value to allow StopDiscovery to work.
Optional<intptr_t> mDiscoveryContext;
};

} // namespace Dnssd
Expand Down
11 changes: 11 additions & 0 deletions src/lib/dnssd/Resolver_ImplMinimalMdns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ class MinMdnsResolver : public Resolver, public MdnsPacketDelegate
CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type) override;
CHIP_ERROR DiscoverCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter()) override;
CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter = DiscoveryFilter()) override;
CHIP_ERROR StopDiscovery() override;

private:
OperationalResolveDelegate * mOperationalDelegate = nullptr;
Expand Down Expand Up @@ -633,6 +634,11 @@ CHIP_ERROR MinMdnsResolver::DiscoverCommissioners(DiscoveryFilter filter)
return BrowseNodes(DiscoveryType::kCommissionerNode, filter);
}

CHIP_ERROR MinMdnsResolver::StopDiscovery()
{
return mActiveResolves.CompleteAllBrowses();
}

CHIP_ERROR MinMdnsResolver::BrowseNodes(DiscoveryType type, DiscoveryFilter filter)
{
mActiveResolves.MarkPending(filter, type);
Expand Down Expand Up @@ -712,5 +718,10 @@ CHIP_ERROR ResolverProxy::DiscoverCommissioners(DiscoveryFilter filter)
return chip::Dnssd::Resolver::Instance().DiscoverCommissioners(filter);
}

CHIP_ERROR ResolverProxy::StopDiscovery()
{
return CHIP_ERROR_NOT_IMPLEMENTED;
}

} // namespace Dnssd
} // namespace chip
6 changes: 6 additions & 0 deletions src/lib/dnssd/Resolver_ImplNone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class NoneResolver : public Resolver
return CHIP_ERROR_NOT_IMPLEMENTED;
}
CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter = DiscoveryFilter()) override { return CHIP_ERROR_NOT_IMPLEMENTED; }
CHIP_ERROR StopDiscovery() override { return CHIP_ERROR_NOT_IMPLEMENTED; }
};

NoneResolver gResolver;
Expand Down Expand Up @@ -73,5 +74,10 @@ CHIP_ERROR ResolverProxy::DiscoverCommissioners(DiscoveryFilter filter)
return CHIP_ERROR_NOT_IMPLEMENTED;
}

CHIP_ERROR ResolverProxy::StopDiscovery()
{
return CHIP_ERROR_NOT_IMPLEMENTED;
}

} // namespace Dnssd
} // namespace chip
19 changes: 18 additions & 1 deletion src/lib/dnssd/platform/Dnssd.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,14 +203,31 @@ CHIP_ERROR ChipDnssdFinalizeServiceUpdate();
* @param[in] interface The interface to send queries.
* @param[in] callback The callback for found services.
* @param[in] context The user context.
* @param[out] browseIdentifier an identifier for this browse operation. This
* can be used to call ChipDnssdStopBrowse. Only
* set on success. This value remains valid until
* the browse callback is called with an error or
* is called with finalBrowse set to true.
*
* @retval CHIP_NO_ERROR The browse succeeds.
* @retval CHIP_ERROR_INVALID_ARGUMENT The type or callback is nullptr.
* @retval Error code The browse fails.
*
*/
CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType,
chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context);
chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context,
intptr_t * browseIdentifier);

/**
* Stop an ongoing browse, if supported by this backend. If successful, this
* will trigger a final callback, with either an error status or finalBrowse set
* to true, to the DnssdBrowseCallback that was passed to the ChipDnssdBrowse
* call that handed back this browseIdentifier.
*
* @param browseIdentifier an identifier for a browse operation that came from
* ChipDnssdBrowse.
*/
CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier);

/**
* This function resolves the services published by mDNS
Expand Down
8 changes: 7 additions & 1 deletion src/platform/Ameba/DnssdImpl.cpp
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,13 @@ CHIP_ERROR ChipDnssdStopPublish()
}

CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType,
chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context);
chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context,
intptr_t * browseIdentifier);
{
return CHIP_ERROR_NOT_IMPLEMENTED;
}

CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier)
{
return CHIP_ERROR_NOT_IMPLEMENTED;
}
Expand Down
6 changes: 6 additions & 0 deletions src/platform/Darwin/DnssdContexts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,12 @@ void BrowseContext::DispatchSuccess()
MdnsContexts::GetInstance().Remove(this);
}

void BrowseContext::DispatchPartialSuccess()
{
callback(context, services.data(), services.size(), false, CHIP_NO_ERROR);
services.clear();
}

ResolveContext::ResolveContext(void * cbContext, DnssdResolveCallback cb, chip::Inet::IPAddressType cbAddressType)
{
type = ContextType::Resolve;
Expand Down
Loading

0 comments on commit 1002331

Please sign in to comment.