diff --git a/src/platform/Darwin/DnssdContexts.cpp b/src/platform/Darwin/DnssdContexts.cpp index 228e1fedc02a61..96ae760c3475a8 100644 --- a/src/platform/Darwin/DnssdContexts.cpp +++ b/src/platform/Darwin/DnssdContexts.cpp @@ -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 && 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) @@ -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(), err); + if (nullptr == callback) + { + // Nothing to do. + } + else + { + callback(context, nullptr, Span(), err); + } if (needDelete) { @@ -508,7 +527,20 @@ void ResolveContext::DispatchSuccess() } ChipLogProgress(Discovery, "Mdns: Resolve success on interface %" PRIu32, interface.first); - callback(context, &interface.second.service, Span(ips.data(), ips.size()), CHIP_NO_ERROR); + + auto & service = interface.second.service; + auto addresses = Span(ips.data(), ips.size()); + if (nullptr == callback) + { + auto delegate = static_cast(context); + DiscoveredNodeData nodeData; + service.ToDiscoveredNodeData(addresses, nodeData); + delegate->OnNodeDiscovered(nodeData); + } + else + { + callback(context, &service, addresses, CHIP_NO_ERROR); + } break; } diff --git a/src/platform/Darwin/DnssdImpl.cpp b/src/platform/Darwin/DnssdImpl.cpp index 5840d71e8920d1..d5cf5d554e7db7 100644 --- a/src/platform/Darwin/DnssdImpl.cpp +++ b/src/platform/Darwin/DnssdImpl.cpp @@ -111,6 +111,21 @@ class ScopedTXTRecord char mRecordBuffer[kDnssdTextMaxSize]; }; +std::shared_ptr 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(0); +} + } // namespace namespace chip { @@ -252,32 +267,12 @@ 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 counterHolder; - if (auto existingCtx = MdnsContexts::GetInstance().GetExistingResolveForInstanceName(name)) - { - counterHolder = existingCtx->consumerCounter; - } - else - { - counterHolder = std::make_shared(0); - } - - auto sdCtx = chip::Platform::New(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)); @@ -285,7 +280,7 @@ static CHIP_ERROR Resolve(void * context, DnssdResolveCallback callback, uint32_ 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))++; @@ -293,6 +288,27 @@ static CHIP_ERROR Resolve(void * context, DnssdResolveCallback callback, uint32_ 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(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(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) @@ -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); diff --git a/src/platform/Darwin/DnssdImpl.h b/src/platform/Darwin/DnssdImpl.h index c662b8587e11ea..1dd6319222599e 100644 --- a/src/platform/Darwin/DnssdImpl.h +++ b/src/platform/Darwin/DnssdImpl.h @@ -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 && consumerCounterToUse); + ResolveContext(CommissioningResolveDelegate * delegate, chip::Inet::IPAddressType cbAddressType, + const char * instanceNameToResolve, std::shared_ptr && consumerCounterToUse); virtual ~ResolveContext(); void DispatchFailure(const char * errorStr, CHIP_ERROR err) override;