diff --git a/src/app/CASESessionManager.cpp b/src/app/CASESessionManager.cpp index 559ae13fde2979..199d25effb654e 100644 --- a/src/app/CASESessionManager.cpp +++ b/src/app/CASESessionManager.cpp @@ -53,7 +53,7 @@ CHIP_ERROR CASESessionManager::FindOrEstablishSession(NodeId nodeId, Callback::C session->OnNodeIdResolved(resolutionData); } - CHIP_ERROR err = session->Connect(onConnection, onFailure); + CHIP_ERROR err = session->Connect(onConnection, onFailure, mConfig.dnsResolver); if (err != CHIP_NO_ERROR) { ReleaseSession(session); @@ -69,8 +69,8 @@ void CASESessionManager::ReleaseSession(NodeId nodeId) CHIP_ERROR CASESessionManager::ResolveDeviceAddress(NodeId nodeId) { - return Dnssd::Resolver::Instance().ResolveNodeId(GetFabricInfo()->GetPeerIdForNode(nodeId), Inet::IPAddressType::kAny, - Dnssd::Resolver::CacheBypass::On); + return mConfig.dnsResolver->ResolveNodeId(GetFabricInfo()->GetPeerIdForNode(nodeId), Inet::IPAddressType::kAny, + Dnssd::Resolver::CacheBypass::On); } void CASESessionManager::OnNodeIdResolved(const Dnssd::ResolvedNodeData & nodeData) diff --git a/src/app/CASESessionManager.h b/src/app/CASESessionManager.h index f2a5b381592a0c..757d2b48708758 100644 --- a/src/app/CASESessionManager.h +++ b/src/app/CASESessionManager.h @@ -27,7 +27,7 @@ #include #include -#include +#include namespace chip { @@ -36,6 +36,7 @@ struct CASESessionManagerConfig DeviceProxyInitParams sessionInitParams; Dnssd::DnssdCache * dnsCache = nullptr; OperationalDeviceProxyPoolDelegate * devicePool = nullptr; + Dnssd::ResolverProxy * dnsResolver = nullptr; }; /** diff --git a/src/app/OperationalDeviceProxy.cpp b/src/app/OperationalDeviceProxy.cpp index 46ebccb0681be4..8f2859ad3bc51f 100644 --- a/src/app/OperationalDeviceProxy.cpp +++ b/src/app/OperationalDeviceProxy.cpp @@ -43,7 +43,8 @@ using namespace chip::Callback; namespace chip { CHIP_ERROR OperationalDeviceProxy::Connect(Callback::Callback * onConnection, - Callback::Callback * onFailure) + Callback::Callback * onFailure, + Dnssd::ResolverProxy * resolver) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -54,7 +55,8 @@ CHIP_ERROR OperationalDeviceProxy::Connect(Callback::Callback break; case State::NeedsAddress: - err = Dnssd::Resolver::Instance().ResolveNodeId(mPeerId, chip::Inet::IPAddressType::kAny); + VerifyOrReturnError(resolver != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + err = resolver->ResolveNodeId(mPeerId, chip::Inet::IPAddressType::kAny); EnqueueConnectionCallbacks(onConnection, onFailure); break; diff --git a/src/app/OperationalDeviceProxy.h b/src/app/OperationalDeviceProxy.h index b67384b873e3f1..7ee309fbfeb6aa 100644 --- a/src/app/OperationalDeviceProxy.h +++ b/src/app/OperationalDeviceProxy.h @@ -43,7 +43,7 @@ #include #include -#include +#include namespace chip { @@ -109,9 +109,11 @@ class DLL_EXPORT OperationalDeviceProxy : public DeviceProxy, SessionReleaseDele * session setup fails, `onFailure` will be called. * * If the session already exists, `onConnection` will be called immediately. + * If the resolver is null and the device state is State::NeedsAddress, CHIP_ERROR_INVALID_ARGUMENT will be + * returned. */ CHIP_ERROR Connect(Callback::Callback * onConnection, - Callback::Callback * onFailure); + Callback::Callback * onFailure, Dnssd::ResolverProxy * resolver); bool IsConnected() const { return mState == State::SecureConnected; } diff --git a/src/app/clusters/ota-requestor/OTARequestor.cpp b/src/app/clusters/ota-requestor/OTARequestor.cpp index 703dfa7334f670..61d0bbd5fed0e5 100644 --- a/src/app/clusters/ota-requestor/OTARequestor.cpp +++ b/src/app/clusters/ota-requestor/OTARequestor.cpp @@ -235,6 +235,7 @@ CHIP_ERROR OTARequestor::SetupCASESessionManager(FabricIndex fabricIndex) .sessionInitParams = initParams, .dnsCache = nullptr, .devicePool = mServer->GetDevicePool(), + .dnsResolver = nullptr, }; mCASESessionManager = Platform::New(sessionManagerConfig); diff --git a/src/controller/AbstractDnssdDiscoveryController.cpp b/src/controller/AbstractDnssdDiscoveryController.cpp index 8d34292df1bb02..924ca6183086c0 100644 --- a/src/controller/AbstractDnssdDiscoveryController.cpp +++ b/src/controller/AbstractDnssdDiscoveryController.cpp @@ -19,10 +19,6 @@ // module header, comes first #include -#if CONFIG_DEVICE_LAYER -#include -#endif - #include #include @@ -66,11 +62,6 @@ void AbstractDnssdDiscoveryController::OnNodeDiscoveryComplete(const chip::Dnssd CHIP_ERROR AbstractDnssdDiscoveryController::SetUpNodeDiscovery() { -#if CONFIG_DEVICE_LAYER - ReturnErrorOnFailure(mResolver->Init(&DeviceLayer::InetLayer())); -#endif - mResolver->SetResolverDelegate(this); - auto discoveredNodes = GetDiscoveredNodes(); for (auto & discoveredNode : discoveredNodes) { diff --git a/src/controller/AbstractDnssdDiscoveryController.h b/src/controller/AbstractDnssdDiscoveryController.h index aae783c5bb79b9..df5845711d4fbd 100644 --- a/src/controller/AbstractDnssdDiscoveryController.h +++ b/src/controller/AbstractDnssdDiscoveryController.h @@ -19,7 +19,7 @@ #pragma once #include -#include +#include #include #include @@ -39,11 +39,7 @@ namespace Controller { class DLL_EXPORT AbstractDnssdDiscoveryController : public Dnssd::ResolverDelegate { public: - AbstractDnssdDiscoveryController(chip::Dnssd::Resolver * resolver = &chip::Dnssd::Resolver::Instance()) - { - mResolver = resolver; - } - + AbstractDnssdDiscoveryController() {} virtual ~AbstractDnssdDiscoveryController() {} void OnNodeDiscoveryComplete(const chip::Dnssd::DiscoveredNodeData & nodeData) override; @@ -52,9 +48,9 @@ class DLL_EXPORT AbstractDnssdDiscoveryController : public Dnssd::ResolverDelega using DiscoveredNodeList = FixedSpan; CHIP_ERROR SetUpNodeDiscovery(); const Dnssd::DiscoveredNodeData * GetDiscoveredNode(int idx); - virtual DiscoveredNodeList GetDiscoveredNodes() = 0; - chip::Dnssd::Resolver * mResolver; + virtual DiscoveredNodeList GetDiscoveredNodes() = 0; DeviceDiscoveryDelegate * mDeviceDiscoveryDelegate = nullptr; + Dnssd::ResolverProxy mDNSResolver; }; } // namespace Controller diff --git a/src/controller/CHIPCommissionableNodeController.cpp b/src/controller/CHIPCommissionableNodeController.cpp index 34d892db70f31c..d127e2abee050e 100644 --- a/src/controller/CHIPCommissionableNodeController.cpp +++ b/src/controller/CHIPCommissionableNodeController.cpp @@ -19,6 +19,10 @@ // module header, comes first #include +#if CONFIG_DEVICE_LAYER +#include +#endif + #include namespace chip { @@ -27,7 +31,22 @@ namespace Controller { CHIP_ERROR CommissionableNodeController::DiscoverCommissioners(Dnssd::DiscoveryFilter discoveryFilter) { ReturnErrorOnFailure(SetUpNodeDiscovery()); - return mResolver->FindCommissioners(discoveryFilter); + + if (mResolver == nullptr) + { +#if CONFIG_DEVICE_LAYER + ReturnErrorOnFailure(mDNSResolver.Init(&DeviceLayer::InetLayer())); +#endif + mDNSResolver.SetResolverDelegate(this); + return mDNSResolver.FindCommissioners(discoveryFilter); + } + else + { +#if CONFIG_DEVICE_LAYER + ReturnErrorOnFailure(mResolver->Init(&DeviceLayer::InetLayer())); +#endif + return mResolver->FindCommissioners(discoveryFilter); + } } const Dnssd::DiscoveredNodeData * CommissionableNodeController::GetDiscoveredCommissioner(int idx) diff --git a/src/controller/CHIPCommissionableNodeController.h b/src/controller/CHIPCommissionableNodeController.h index 8bafe788e8ef9e..af57d1d6abe223 100644 --- a/src/controller/CHIPCommissionableNodeController.h +++ b/src/controller/CHIPCommissionableNodeController.h @@ -19,7 +19,6 @@ #pragma once #include -#include #include #include @@ -37,8 +36,7 @@ namespace Controller { class DLL_EXPORT CommissionableNodeController : public AbstractDnssdDiscoveryController { public: - CommissionableNodeController(chip::Dnssd::Resolver * resolver = &chip::Dnssd::Resolver::Instance()) : - AbstractDnssdDiscoveryController(resolver){}; + CommissionableNodeController(chip::Dnssd::Resolver * resolver = nullptr) : mResolver(resolver) {} virtual ~CommissionableNodeController() {} CHIP_ERROR DiscoverCommissioners(Dnssd::DiscoveryFilter discoveryFilter = Dnssd::DiscoveryFilter()); @@ -66,6 +64,7 @@ class DLL_EXPORT CommissionableNodeController : public AbstractDnssdDiscoveryCon DiscoveredNodeList GetDiscoveredNodes() override { return DiscoveredNodeList(mDiscoveredCommissioners); } private: + Dnssd::Resolver * mResolver = nullptr; Dnssd::DiscoveredNodeData mDiscoveredCommissioners[CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES]; }; diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 27e748ee29cc39..1840ea11dd06c9 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -45,7 +45,6 @@ #include #include -#include #include #include #include @@ -132,14 +131,12 @@ CHIP_ERROR DeviceController::Init(ControllerInitParams params) VerifyOrReturnError(params.systemState->TransportMgr() != nullptr, CHIP_ERROR_INVALID_ARGUMENT); #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD - Dnssd::Resolver::Instance().Init(params.systemState->InetLayer()); - Dnssd::Resolver::Instance().SetResolverDelegate(this); + ReturnErrorOnFailure(mDNSResolver.Init(params.systemState->InetLayer())); + mDNSResolver.SetResolverDelegate(this); RegisterDeviceAddressUpdateDelegate(params.deviceAddressUpdateDelegate); RegisterDeviceDiscoveryDelegate(params.deviceDiscoveryDelegate); #endif // CHIP_DEVICE_CONFIG_ENABLE_DNSSD - InitDataModelHandler(params.systemState->ExchangeMgr()); - VerifyOrReturnError(params.operationalCredentialsDelegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT); mOperationalCredentialsDelegate = params.operationalCredentialsDelegate; @@ -160,6 +157,11 @@ CHIP_ERROR DeviceController::Init(ControllerInitParams params) .sessionInitParams = deviceInitParams, .dnsCache = &mDNSCache, .devicePool = &mDevicePool, +#if CHIP_DEVICE_CONFIG_ENABLE_DNSSD + .dnsResolver = &mDNSResolver, +#else + .dnsResolver = nullptr, +#endif }; mCASESessionManager = chip::Platform::New(sessionManagerConfig); @@ -227,10 +229,6 @@ CHIP_ERROR DeviceController::Shutdown() mState = State::NotInitialized; -#if CHIP_DEVICE_CONFIG_ENABLE_DNSSD - Dnssd::Resolver::Instance().Shutdown(); -#endif // CHIP_DEVICE_CONFIG_ENABLE_DNSSD - mStorageDelegate = nullptr; mSystemState->Fabrics()->ReleaseFabricIndex(mFabricIndex); @@ -238,7 +236,7 @@ CHIP_ERROR DeviceController::Shutdown() mSystemState = nullptr; #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD - Dnssd::Resolver::Instance().SetResolverDelegate(nullptr); + mDNSResolver.Shutdown(); mDeviceAddressUpdateDelegate = nullptr; mDeviceDiscoveryDelegate = nullptr; #endif // CHIP_DEVICE_CONFIG_ENABLE_DNSSD @@ -1571,7 +1569,7 @@ void DeviceCommissioner::OnSessionEstablishmentTimeoutCallback(System::Layer * a CHIP_ERROR DeviceCommissioner::DiscoverCommissionableNodes(Dnssd::DiscoveryFilter filter) { ReturnErrorOnFailure(SetUpNodeDiscovery()); - return chip::Dnssd::Resolver::Instance().FindCommissionableNodes(filter); + return mDNSResolver.FindCommissionableNodes(filter); } const Dnssd::DiscoveredNodeData * DeviceCommissioner::GetDiscoveredDevice(int idx) @@ -1837,7 +1835,7 @@ void DeviceCommissioner::AdvanceCommissioningStage(CHIP_ERROR err) #if CONFIG_DEVICE_LAYER status = DeviceLayer::ConfigurationMgr().GetCountryCode(countryCodeStr, kMaxCountryCodeSize, actualCountryCodeSize); #else - status = CHIP_ERROR_NOT_IMPLEMENTED; + status = CHIP_ERROR_NOT_IMPLEMENTED; #endif if (status != CHIP_NO_ERROR) { @@ -1894,7 +1892,7 @@ void DeviceCommissioner::AdvanceCommissioningStage(CHIP_ERROR err) RendezvousCleanup(CHIP_NO_ERROR); #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD ChipLogProgress(Controller, "Finding node on operational network"); - Dnssd::Resolver::Instance().ResolveNodeId(peerId, Inet::IPAddressType::kAny); + mDNSResolver.ResolveNodeId(peerId, Inet::IPAddressType::kAny); #endif } break; diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index c810c6a18df075..c23c93d7da99bd 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -72,6 +72,7 @@ #include #include #include +#include #endif namespace chip { diff --git a/src/controller/CHIPDeviceControllerFactory.cpp b/src/controller/CHIPDeviceControllerFactory.cpp index 95bb7f69a1de97..929c52e877035b 100644 --- a/src/controller/CHIPDeviceControllerFactory.cpp +++ b/src/controller/CHIPDeviceControllerFactory.cpp @@ -24,6 +24,7 @@ #include +#include #include #if CONFIG_DEVICE_LAYER @@ -140,9 +141,15 @@ CHIP_ERROR DeviceControllerFactory::InitSystemState(FactoryInitParams params) ReturnErrorOnFailure(stateParams.exchangeMgr->Init(stateParams.sessionMgr)); ReturnErrorOnFailure(stateParams.messageCounterManager->Init(stateParams.exchangeMgr)); + InitDataModelHandler(stateParams.exchangeMgr); + stateParams.imDelegate = params.imDelegate; ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->Init(stateParams.exchangeMgr, stateParams.imDelegate)); +#if CHIP_DEVICE_CONFIG_ENABLE_DNSSD + ReturnErrorOnFailure(Dnssd::Resolver::Instance().Init(stateParams.inetLayer)); +#endif // CHIP_DEVICE_CONFIG_ENABLE_DNSSD + // store the system state mSystemState = chip::Platform::New(stateParams); ChipLogDetail(Controller, "System State Initialized..."); @@ -220,6 +227,10 @@ CHIP_ERROR DeviceControllerSystemState::Shutdown() ChipLogDetail(Controller, "Shutting down the System State, this will teardown the CHIP Stack"); +#if CHIP_DEVICE_CONFIG_ENABLE_DNSSD + Dnssd::Resolver::Instance().Shutdown(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_DNSSD + // Shut down the interaction model app::InteractionModelEngine::GetInstance()->Shutdown(); diff --git a/src/controller/tests/TestCommissionableNodeController.cpp b/src/controller/tests/TestCommissionableNodeController.cpp index c1101eca7ebb97..07500b493d1cd9 100644 --- a/src/controller/tests/TestCommissionableNodeController.cpp +++ b/src/controller/tests/TestCommissionableNodeController.cpp @@ -180,9 +180,26 @@ const nlTest sTests[] = } // namespace +int TestCommissionableNodeController_Setup(void * inContext) +{ + if (CHIP_NO_ERROR != chip::Platform::MemoryInit()) + { + return FAILURE; + } + + return SUCCESS; +} + +int TestCommissionableNodeController_Teardown(void * inContext) +{ + chip::Platform::MemoryShutdown(); + return SUCCESS; +} + int TestCommissionableNodeController() { - nlTestSuite theSuite = { "CommissionableNodeController", &sTests[0], NULL, NULL }; + nlTestSuite theSuite = { "CommissionableNodeController", &sTests[0], TestCommissionableNodeController_Setup, + TestCommissionableNodeController_Teardown }; nlTestRunner(&theSuite, nullptr); return nlTestRunnerStats(&theSuite); } diff --git a/src/lib/dnssd/Discovery_ImplPlatform.cpp b/src/lib/dnssd/Discovery_ImplPlatform.cpp index 0f564488f1d126..38701b0b6c0445 100644 --- a/src/lib/dnssd/Discovery_ImplPlatform.cpp +++ b/src/lib/dnssd/Discovery_ImplPlatform.cpp @@ -36,11 +36,119 @@ namespace chip { namespace Dnssd { -DiscoveryImplPlatform DiscoveryImplPlatform::sManager; +namespace { + #if CHIP_CONFIG_MDNS_CACHE_SIZE > 0 -DnssdCache DiscoveryImplPlatform::sDnssdCache; +static DnssdCache sDnssdCache; #endif +static void HandleNodeResolve(void * context, DnssdService * result, CHIP_ERROR error) +{ + ResolverDelegateProxy * proxy = static_cast(context); + + if (CHIP_NO_ERROR != error) + { + proxy->Release(); + return; + } + + DiscoveredNodeData nodeData; + Platform::CopyString(nodeData.hostName, result->mHostName); + Platform::CopyString(nodeData.instanceName, result->mName); + + if (result->mAddress.HasValue() && nodeData.numIPs < DiscoveredNodeData::kMaxIPAddresses) + { + nodeData.ipAddress[nodeData.numIPs] = result->mAddress.Value(); + nodeData.interfaceId[nodeData.numIPs] = result->mInterface; + nodeData.numIPs++; + } + + nodeData.port = result->mPort; + + for (size_t i = 0; i < result->mTextEntrySize; ++i) + { + ByteSpan key(reinterpret_cast(result->mTextEntries[i].mKey), strlen(result->mTextEntries[i].mKey)); + ByteSpan val(result->mTextEntries[i].mData, result->mTextEntries[i].mDataSize); + FillNodeDataFromTxt(key, val, nodeData); + } + + proxy->OnNodeDiscoveryComplete(nodeData); + proxy->Release(); +} + +static void HandleNodeIdResolve(void * context, DnssdService * result, CHIP_ERROR error) +{ + ResolverDelegateProxy * proxy = static_cast(context); + if (CHIP_NO_ERROR != error) + { + proxy->OnNodeIdResolutionFailed(PeerId(), error); + proxy->Release(); + } + + if (result == nullptr) + { + proxy->OnNodeIdResolutionFailed(PeerId(), CHIP_ERROR_UNKNOWN_RESOURCE_ID); + proxy->Release(); + } + + PeerId peerId; + error = ExtractIdFromInstanceName(result->mName, &peerId); + if (CHIP_NO_ERROR != error) + { + proxy->OnNodeIdResolutionFailed(PeerId(), error); + proxy->Release(); + } + + ResolvedNodeData nodeData; + Platform::CopyString(nodeData.mHostName, result->mHostName); + nodeData.mInterfaceId = result->mInterface; + nodeData.mAddress[0] = result->mAddress.ValueOr({}); + nodeData.mPort = result->mPort; + nodeData.mNumIPs = 1; + nodeData.mPeerId = peerId; + // TODO: Use seconds? + const System::Clock::Timestamp currentTime = System::SystemClock().GetMonotonicTimestamp(); + + nodeData.mExpiryTime = currentTime + System::Clock::Seconds16(result->mTtlSeconds); + + for (size_t i = 0; i < result->mTextEntrySize; ++i) + { + ByteSpan key(reinterpret_cast(result->mTextEntries[i].mKey), strlen(result->mTextEntries[i].mKey)); + ByteSpan val(result->mTextEntries[i].mData, result->mTextEntries[i].mDataSize); + FillNodeDataFromTxt(key, val, nodeData); + } + + nodeData.LogNodeIdResolved(); +#if CHIP_CONFIG_MDNS_CACHE_SIZE > 0 + LogErrorOnFailure(sDnssdCache.Insert(nodeData)); +#endif + proxy->OnNodeIdResolved(nodeData); + proxy->Release(); +} + +static void HandleNodeBrowse(void * context, DnssdService * services, size_t servicesSize, CHIP_ERROR error) +{ + ResolverDelegateProxy * proxy = static_cast(context); + proxy->Release(); + + for (size_t i = 0; i < servicesSize; ++i) + { + proxy->Retain(); + // For some platforms browsed services are already resolved, so verify if resolve is really needed or call resolve callback + if (!services[i].mAddress.HasValue()) + { + ChipDnssdResolve(&services[i], services[i].mInterface, HandleNodeResolve, context); + } + else + { + HandleNodeResolve(context, &services[i], error); + } + } +} +} // namespace + +DiscoveryImplPlatform DiscoveryImplPlatform::sManager; + DiscoveryImplPlatform::DiscoveryImplPlatform() = default; CHIP_ERROR DiscoveryImplPlatform::InitImpl() @@ -460,6 +568,40 @@ CHIP_ERROR DiscoveryImplPlatform::ResolveNodeId(const PeerId & peerId, Inet::IPA Resolver::CacheBypass dnssdCacheBypass) { ReturnErrorOnFailure(InitImpl()); + return mResolverProxy.ResolveNodeId(peerId, type, dnssdCacheBypass); +} + +CHIP_ERROR DiscoveryImplPlatform::FindCommissionableNodes(DiscoveryFilter filter) +{ + ReturnErrorOnFailure(InitImpl()); + return mResolverProxy.FindCommissionableNodes(filter); +} + +CHIP_ERROR DiscoveryImplPlatform::FindCommissioners(DiscoveryFilter filter) +{ + ReturnErrorOnFailure(InitImpl()); + return mResolverProxy.FindCommissioners(filter); +} + +DiscoveryImplPlatform & DiscoveryImplPlatform::GetInstance() +{ + return sManager; +} + +ServiceAdvertiser & chip::Dnssd::ServiceAdvertiser::Instance() +{ + return DiscoveryImplPlatform::GetInstance(); +} + +Resolver & chip::Dnssd::Resolver::Instance() +{ + return DiscoveryImplPlatform::GetInstance(); +} + +CHIP_ERROR ResolverProxy::ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type, Resolver::CacheBypass dnssdCacheBypass) +{ + VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE); + mDelegate->Retain(); #if CHIP_CONFIG_MDNS_CACHE_SIZE > 0 if (dnssdCacheBypass == Resolver::CacheBypass::Off) @@ -468,7 +610,8 @@ CHIP_ERROR DiscoveryImplPlatform::ResolveNodeId(const PeerId & peerId, Inet::IPA ResolvedNodeData nodeData; if (sDnssdCache.Lookup(peerId, nodeData) == CHIP_NO_ERROR) { - mResolverDelegate->OnNodeIdResolved(nodeData); + mDelegate->OnNodeIdResolved(nodeData); + mDelegate->Release(); return CHIP_NO_ERROR; } } @@ -480,150 +623,31 @@ CHIP_ERROR DiscoveryImplPlatform::ResolveNodeId(const PeerId & peerId, Inet::IPA strncpy(service.mType, kOperationalServiceName, sizeof(service.mType)); service.mProtocol = DnssdServiceProtocol::kDnssdProtocolTcp; service.mAddressType = type; - return ChipDnssdResolve(&service, Inet::InterfaceId::Null(), HandleNodeIdResolve, this); -} - -void DiscoveryImplPlatform::HandleNodeBrowse(void * context, DnssdService * services, size_t servicesSize, CHIP_ERROR error) -{ - for (size_t i = 0; i < servicesSize; ++i) - { - // For some platforms browsed services are already resolved, so verify if resolve is really needed or call resolve callback - if (!services[i].mAddress.HasValue()) - { - ChipDnssdResolve(&services[i], services[i].mInterface, HandleNodeResolve, context); - } - else - { - HandleNodeResolve(context, &services[i], error); - } - } + return ChipDnssdResolve(&service, Inet::InterfaceId::Null(), HandleNodeIdResolve, mDelegate); } -void DiscoveryImplPlatform::HandleNodeResolve(void * context, DnssdService * result, CHIP_ERROR error) +CHIP_ERROR ResolverProxy::FindCommissionableNodes(DiscoveryFilter filter) { - if (error != CHIP_NO_ERROR) - { - return; - } - DiscoveryImplPlatform * mgr = static_cast(context); - DiscoveredNodeData data; - Platform::CopyString(data.hostName, result->mHostName); - Platform::CopyString(data.instanceName, result->mName); - - if (result->mAddress.HasValue() && data.numIPs < DiscoveredNodeData::kMaxIPAddresses) - { - data.ipAddress[data.numIPs] = result->mAddress.Value(); - data.interfaceId[data.numIPs] = result->mInterface; - data.numIPs++; - } - - data.port = result->mPort; + VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE); + mDelegate->Retain(); - for (size_t i = 0; i < result->mTextEntrySize; ++i) - { - ByteSpan key(reinterpret_cast(result->mTextEntries[i].mKey), strlen(result->mTextEntries[i].mKey)); - ByteSpan val(result->mTextEntries[i].mData, result->mTextEntries[i].mDataSize); - FillNodeDataFromTxt(key, val, data); - } - mgr->mResolverDelegate->OnNodeDiscoveryComplete(data); -} - -CHIP_ERROR DiscoveryImplPlatform::FindCommissionableNodes(DiscoveryFilter filter) -{ - ReturnErrorOnFailure(InitImpl()); char serviceName[kMaxCommissionableServiceNameSize]; ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kCommissionableNode)); return ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny, - Inet::InterfaceId::Null(), HandleNodeBrowse, this); + Inet::InterfaceId::Null(), HandleNodeBrowse, mDelegate); } -CHIP_ERROR DiscoveryImplPlatform::FindCommissioners(DiscoveryFilter filter) +CHIP_ERROR ResolverProxy::FindCommissioners(DiscoveryFilter filter) { - ReturnErrorOnFailure(InitImpl()); + VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE); + mDelegate->Retain(); + char serviceName[kMaxCommissionerServiceNameSize]; ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kCommissionerNode)); return ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny, - Inet::InterfaceId::Null(), HandleNodeBrowse, this); -} - -void DiscoveryImplPlatform::HandleNodeIdResolve(void * context, DnssdService * result, CHIP_ERROR error) -{ - DiscoveryImplPlatform * mgr = static_cast(context); - - if (mgr->mResolverDelegate == nullptr) - { - return; - } - - if (error != CHIP_NO_ERROR) - { - ChipLogError(Discovery, "Node ID resolved failed with %s", chip::ErrorStr(error)); - mgr->mResolverDelegate->OnNodeIdResolutionFailed(PeerId(), error); - return; - } - - if (result == nullptr) - { - ChipLogError(Discovery, "Node ID resolve not found"); - mgr->mResolverDelegate->OnNodeIdResolutionFailed(PeerId(), CHIP_ERROR_UNKNOWN_RESOURCE_ID); - return; - } - - ResolvedNodeData nodeData; - - error = ExtractIdFromInstanceName(result->mName, &nodeData.mPeerId); - if (error != CHIP_NO_ERROR) - { - ChipLogError(Discovery, "Node ID resolved failed with %s", chip::ErrorStr(error)); - mgr->mResolverDelegate->OnNodeIdResolutionFailed(PeerId(), error); - return; - } - - // TODO: Expand the results to include all the addresses. - Platform::CopyString(nodeData.mHostName, result->mHostName); - nodeData.mInterfaceId = result->mInterface; - nodeData.mAddress[0] = result->mAddress.ValueOr({}); - nodeData.mPort = result->mPort; - nodeData.mNumIPs = 1; - // TODO: Use seconds? - const System::Clock::Timestamp currentTime = System::SystemClock().GetMonotonicTimestamp(); - - nodeData.mExpiryTime = currentTime + System::Clock::Seconds16(result->mTtlSeconds); - - for (size_t i = 0; i < result->mTextEntrySize; ++i) - { - ByteSpan key(reinterpret_cast(result->mTextEntries[i].mKey), strlen(result->mTextEntries[i].mKey)); - ByteSpan val(result->mTextEntries[i].mData, result->mTextEntries[i].mDataSize); - FillNodeDataFromTxt(key, val, nodeData); - } - - nodeData.LogNodeIdResolved(); -#if CHIP_CONFIG_MDNS_CACHE_SIZE > 0 - error = mgr->sDnssdCache.Insert(nodeData); - - if (CHIP_NO_ERROR != error) - { - ChipLogError(Discovery, "DnssdCache insert failed with %s", chip::ErrorStr(error)); - } -#endif - mgr->mResolverDelegate->OnNodeIdResolved(nodeData); -} - -DiscoveryImplPlatform & DiscoveryImplPlatform::GetInstance() -{ - return sManager; -} - -ServiceAdvertiser & chip::Dnssd::ServiceAdvertiser::Instance() -{ - return DiscoveryImplPlatform::GetInstance(); -} - -Resolver & chip::Dnssd::Resolver::Instance() -{ - return DiscoveryImplPlatform::GetInstance(); + Inet::InterfaceId::Null(), HandleNodeBrowse, mDelegate); } } // namespace Dnssd diff --git a/src/lib/dnssd/Discovery_ImplPlatform.h b/src/lib/dnssd/Discovery_ImplPlatform.h index 5ac1753493d6ca..c297ed3df04ec9 100644 --- a/src/lib/dnssd/Discovery_ImplPlatform.h +++ b/src/lib/dnssd/Discovery_ImplPlatform.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -48,7 +49,7 @@ class DiscoveryImplPlatform : public ServiceAdvertiser, public Resolver CHIP_ERROR GetCommissionableInstanceName(char * instanceName, size_t maxLength) override; // Members that implement Resolver interface. - void SetResolverDelegate(ResolverDelegate * delegate) override { mResolverDelegate = delegate; } + void SetResolverDelegate(ResolverDelegate * delegate) override { mResolverProxy.SetResolverDelegate(delegate); } CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type, Resolver::CacheBypass dnssdCacheBypass) override; CHIP_ERROR FindCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter()) override; CHIP_ERROR FindCommissioners(DiscoveryFilter filter = DiscoveryFilter()) override; @@ -65,11 +66,8 @@ class DiscoveryImplPlatform : public ServiceAdvertiser, public Resolver CHIP_ERROR PublishUnprovisionedDevice(chip::Inet::IPAddressType addressType, chip::Inet::InterfaceId interface); CHIP_ERROR PublishProvisionedDevice(chip::Inet::IPAddressType addressType, chip::Inet::InterfaceId interface); - static void HandleNodeIdResolve(void * context, DnssdService * result, CHIP_ERROR error); static void HandleDnssdInit(void * context, CHIP_ERROR initError); static void HandleDnssdError(void * context, CHIP_ERROR initError); - static void HandleNodeBrowse(void * context, DnssdService * services, size_t servicesSize, CHIP_ERROR error); - static void HandleNodeResolve(void * context, DnssdService * result, CHIP_ERROR error); static CHIP_ERROR GenerateRotatingDeviceId(char rotatingDeviceIdHexBuffer[], size_t & rotatingDeviceIdHexBufferSize); #ifdef DETAIL_LOGGING static void PrintEntries(const DnssdService * service); @@ -83,13 +81,11 @@ class DiscoveryImplPlatform : public ServiceAdvertiser, public Resolver bool mIsCommissionerPublishing = false; uint8_t mCommissionableInstanceName[sizeof(uint64_t)]; - bool mDnssdInitialized = false; - ResolverDelegate * mResolverDelegate = nullptr; + bool mDnssdInitialized = false; + + ResolverProxy mResolverProxy; static DiscoveryImplPlatform sManager; -#if CHIP_CONFIG_MDNS_CACHE_SIZE > 0 - static DnssdCache sDnssdCache; -#endif }; } // namespace Dnssd diff --git a/src/lib/dnssd/ResolverProxy.h b/src/lib/dnssd/ResolverProxy.h new file mode 100644 index 00000000000000..88ac1d407a1784 --- /dev/null +++ b/src/lib/dnssd/ResolverProxy.h @@ -0,0 +1,98 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace chip { +namespace Dnssd { + +class ResolverDelegateProxy : public ReferenceCounted, public ResolverDelegate +{ +public: + void SetDelegate(ResolverDelegate * delegate) { mDelegate = delegate; } + + /// ResolverDelegate interface + void OnNodeIdResolved(const ResolvedNodeData & nodeData) override + { + if (mDelegate != nullptr) + { + mDelegate->OnNodeIdResolved(nodeData); + } + } + + void OnNodeIdResolutionFailed(const PeerId & peerId, CHIP_ERROR error) override + { + if (mDelegate != nullptr) + { + mDelegate->OnNodeIdResolutionFailed(peerId, error); + } + } + + void OnNodeDiscoveryComplete(const DiscoveredNodeData & nodeData) override + { + if (mDelegate != nullptr) + { + mDelegate->OnNodeDiscoveryComplete(nodeData); + } + } + +private: + ResolverDelegate * mDelegate = nullptr; +}; + +class ResolverProxy : public Resolver +{ +public: + ResolverProxy() {} + + // Resolver interface. + CHIP_ERROR Init(Inet::InetLayer * inetLayer = nullptr) override + { + ReturnErrorOnFailure(chip::Dnssd::Resolver::Instance().Init(inetLayer)); + VerifyOrReturnError(mDelegate == nullptr, CHIP_ERROR_INCORRECT_STATE); + mDelegate = chip::Platform::New(); + return CHIP_NO_ERROR; + } + + void SetResolverDelegate(ResolverDelegate * delegate) override + { + VerifyOrReturn(mDelegate != nullptr); + mDelegate->SetDelegate(delegate); + } + + void Shutdown() override + { + VerifyOrReturn(mDelegate != nullptr); + mDelegate->SetDelegate(nullptr); + mDelegate->Release(); + mDelegate = nullptr; + } + + CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type, + Resolver::CacheBypass dnssdCacheBypass = CacheBypass::Off) override; + CHIP_ERROR FindCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter()) override; + CHIP_ERROR FindCommissioners(DiscoveryFilter filter = DiscoveryFilter()) override; + +private: + ResolverDelegateProxy * mDelegate = nullptr; +}; + +} // namespace Dnssd +} // namespace chip diff --git a/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp b/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp index 5252d51994fb4d..fa081b30beaf38 100644 --- a/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp +++ b/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -598,5 +599,30 @@ Resolver & chip::Dnssd::Resolver::Instance() return gResolver; } +// Minimal implementation does not support associating a context to a request (while platforms implementations do). So keep +// updating the delegate that ends up beeing used by the server by calling 'SetResolverDelegate'. +// This effectively allow minimal to have multiple controllers issuing requests as long the requests are serialized, but +// it won't work well if requests are issued in parallel. +CHIP_ERROR ResolverProxy::ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type, Resolver::CacheBypass dnssdCacheBypass) +{ + VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE); + chip::Dnssd::Resolver::Instance().SetResolverDelegate(mDelegate); + return chip::Dnssd::Resolver::Instance().ResolveNodeId(peerId, type, dnssdCacheBypass); +} + +CHIP_ERROR ResolverProxy::FindCommissionableNodes(DiscoveryFilter filter) +{ + VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE); + chip::Dnssd::Resolver::Instance().SetResolverDelegate(mDelegate); + return chip::Dnssd::Resolver::Instance().FindCommissionableNodes(filter); +} + +CHIP_ERROR ResolverProxy::FindCommissioners(DiscoveryFilter filter) +{ + VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE); + chip::Dnssd::Resolver::Instance().SetResolverDelegate(mDelegate); + return chip::Dnssd::Resolver::Instance().FindCommissioners(filter); +} + } // namespace Dnssd } // namespace chip diff --git a/src/lib/shell/commands/Ota.cpp b/src/lib/shell/commands/Ota.cpp index 7581c32e572795..20c398a51a8ed6 100644 --- a/src/lib/shell/commands/Ota.cpp +++ b/src/lib/shell/commands/Ota.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -299,7 +300,7 @@ void ConnectDeviceAsync(intptr_t) VerifyOrReturn(deviceProxy != nullptr); deviceProxy->UpdateDeviceData(sOtaContext.providerAddress, deviceProxy->GetMRPConfig()); - deviceProxy->Connect(&successCallback, &failureCallback); + deviceProxy->Connect(&successCallback, &failureCallback, nullptr); } template