Skip to content

Commit

Permalink
[darwin] Add ChipDnssdResolve that accepts a delegate implementation …
Browse files Browse the repository at this point in the history
…on darwin
  • Loading branch information
vivien-apple committed May 9, 2023
1 parent 0f3dc8f commit fcb025a
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 25 deletions.
36 changes: 34 additions & 2 deletions src/platform/Darwin/DnssdContexts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,18 @@ ResolveContext::ResolveContext(void * cbContext, DnssdResolveCallback cb, chip::
consumerCounter = std::move(consumerCounterToUse);
}

ResolveContext::ResolveContext(CommissioningResolveDelegate * delegate, chip::Inet::IPAddressType cbAddressType,
const char * instanceNameToResolve, std::shared_ptr<uint32_t> && consumerCounterToUse) :
browseThatCausedResolve(nullptr)
{
type = ContextType::Resolve;
context = delegate;
callback = nullptr;
protocol = GetProtocol(cbAddressType);
instanceName = instanceNameToResolve;
consumerCounter = std::move(consumerCounterToUse);
}

ResolveContext::~ResolveContext() {}

void ResolveContext::DispatchFailure(const char * errorStr, CHIP_ERROR err)
Expand All @@ -483,7 +495,14 @@ void ResolveContext::DispatchFailure(const char * errorStr, CHIP_ERROR err)
// ChipDnssdResolveNoLongerNeeded don't find us and try to also remove us.
bool needDelete = MdnsContexts::GetInstance().RemoveWithoutDeleting(this);

callback(context, nullptr, Span<Inet::IPAddress>(), err);
if (nullptr == callback)
{
// Nothing to do.
}
else
{
callback(context, nullptr, Span<Inet::IPAddress>(), err);
}

if (needDelete)
{
Expand All @@ -508,7 +527,20 @@ void ResolveContext::DispatchSuccess()
}

ChipLogProgress(Discovery, "Mdns: Resolve success on interface %" PRIu32, interface.first);
callback(context, &interface.second.service, Span<Inet::IPAddress>(ips.data(), ips.size()), CHIP_NO_ERROR);

auto & service = interface.second.service;
auto addresses = Span<Inet::IPAddress>(ips.data(), ips.size());
if (nullptr == callback)
{
auto delegate = static_cast<CommissioningResolveDelegate *>(context);
DiscoveredNodeData nodeData;
service.ToDiscoveredNodeData(addresses, nodeData);
delegate->OnNodeDiscovered(nodeData);
}
else
{
callback(context, &service, addresses, CHIP_NO_ERROR);
}
break;
}

Expand Down
72 changes: 49 additions & 23 deletions src/platform/Darwin/DnssdImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,21 @@ class ScopedTXTRecord
char mRecordBuffer[kDnssdTextMaxSize];
};

std::shared_ptr<uint32_t> GetCounterHolder(const char * name)
{
// This is a little silly, in that resolves for the same name, type, etc get
// coalesced by the underlying mDNSResponder anyway. But we need to keep
// track of our context/callback/etc, (even though in practice it's always
// exactly the same) and the interface id (which might actually be different
// for different Resolve calls). So for now just keep using a
// ResolveContext to track all that.
if (auto existingCtx = MdnsContexts::GetInstance().GetExistingResolveForInstanceName(name))
{
return existingCtx->consumerCounter;
}
return std::make_shared<uint32_t>(0);
}

} // namespace

namespace chip {
Expand Down Expand Up @@ -252,47 +267,48 @@ static void OnResolve(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t inter
}
}

static CHIP_ERROR Resolve(void * context, DnssdResolveCallback callback, uint32_t interfaceId,
chip::Inet::IPAddressType addressType, const char * type, const char * name)
static CHIP_ERROR Resolve(ResolveContext * sdCtx, uint32_t interfaceId, chip::Inet::IPAddressType addressType, const char * type,
const char * name)
{
ChipLogProgress(Discovery, "Resolve type=%s name=%s interface=%" PRIu32, StringOrNullMarker(type), StringOrNullMarker(name),
interfaceId);

// This is a little silly, in that resolves for the same name, type, etc get
// coalesced by the underlying mDNSResponder anyway. But we need to keep
// track of our context/callback/etc, (even though in practice it's always
// exactly the same) and the interface id (which might actually be different
// for different Resolve calls). So for now just keep using a
// ResolveContext to track all that.
std::shared_ptr<uint32_t> counterHolder;
if (auto existingCtx = MdnsContexts::GetInstance().GetExistingResolveForInstanceName(name))
{
counterHolder = existingCtx->consumerCounter;
}
else
{
counterHolder = std::make_shared<uint32_t>(0);
}

auto sdCtx = chip::Platform::New<ResolveContext>(context, callback, addressType, name,
BrowseContext::sContextDispatchingSuccess, std::move(counterHolder));
VerifyOrReturnError(nullptr != sdCtx, CHIP_ERROR_NO_MEMORY);

auto err = DNSServiceCreateConnection(&sdCtx->serviceRef);
VerifyOrReturnError(kDNSServiceErr_NoError == err, sdCtx->Finalize(err));

auto sdRefCopy = sdCtx->serviceRef; // Mandatory copy because of kDNSServiceFlagsShareConnection
err = DNSServiceResolve(&sdRefCopy, kResolveFlags, interfaceId, name, type, kLocalDot, OnResolve, sdCtx);
VerifyOrReturnError(kDNSServiceErr_NoError == err, sdCtx->Finalize(err));

CHIP_ERROR retval = MdnsContexts::GetInstance().Add(sdCtx, sdCtx->serviceRef);
auto retval = MdnsContexts::GetInstance().Add(sdCtx, sdCtx->serviceRef);
if (retval == CHIP_NO_ERROR)
{
(*(sdCtx->consumerCounter))++;
}
return retval;
}

static CHIP_ERROR Resolve(void * context, DnssdResolveCallback callback, uint32_t interfaceId,
chip::Inet::IPAddressType addressType, const char * type, const char * name)
{
auto counterHolder = GetCounterHolder(name);
auto sdCtx = chip::Platform::New<ResolveContext>(context, callback, addressType, name,
BrowseContext::sContextDispatchingSuccess, std::move(counterHolder));
VerifyOrReturnError(nullptr != sdCtx, CHIP_ERROR_NO_MEMORY);

return Resolve(sdCtx, interfaceId, addressType, type, name);
}

static CHIP_ERROR Resolve(CommissioningResolveDelegate * delegate, uint32_t interfaceId, chip::Inet::IPAddressType addressType,
const char * type, const char * name)
{
auto counterHolder = GetCounterHolder(name);
auto sdCtx = chip::Platform::New<ResolveContext>(delegate, addressType, name, std::move(counterHolder));
VerifyOrReturnError(nullptr != sdCtx, CHIP_ERROR_NO_MEMORY);

return Resolve(sdCtx, interfaceId, addressType, type, name);
}

} // namespace

CHIP_ERROR ChipDnssdInit(DnssdAsyncReturnCallback successCallback, DnssdAsyncReturnCallback errorCallback, void * context)
Expand Down Expand Up @@ -431,6 +447,16 @@ CHIP_ERROR ChipDnssdResolve(DnssdService * service, chip::Inet::InterfaceId inte
return Resolve(context, callback, interfaceId, service->mAddressType, regtype.c_str(), service->mName);
}

CHIP_ERROR ChipDnssdResolve(DnssdService * service, chip::Inet::InterfaceId interface, CommissioningResolveDelegate * delegate)
{
VerifyOrReturnError(service != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(IsSupportedProtocol(service->mProtocol), CHIP_ERROR_INVALID_ARGUMENT);

auto regtype = GetFullType(service);
auto interfaceId = GetInterfaceId(interface);
return Resolve(delegate, interfaceId, service->mAddressType, regtype.c_str(), service->mName);
}

void ChipDnssdResolveNoLongerNeeded(const char * instanceName)
{
ChipLogProgress(Discovery, "No longer need resolve for %s", instanceName);
Expand Down
2 changes: 2 additions & 0 deletions src/platform/Darwin/DnssdImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ struct ResolveContext : public GenericContext
ResolveContext(void * cbContext, DnssdResolveCallback cb, chip::Inet::IPAddressType cbAddressType,
const char * instanceNameToResolve, BrowseContext * browseCausingResolve,
std::shared_ptr<uint32_t> && consumerCounterToUse);
ResolveContext(CommissioningResolveDelegate * delegate, chip::Inet::IPAddressType cbAddressType,
const char * instanceNameToResolve, std::shared_ptr<uint32_t> && consumerCounterToUse);
virtual ~ResolveContext();

void DispatchFailure(const char * errorStr, CHIP_ERROR err) override;
Expand Down

0 comments on commit fcb025a

Please sign in to comment.