Add a ResolveProxy class to keep track of which controller is issuing… (#12481)
* Add a ResolveProxy class to keep track of which controller is issuing a dns request
* Use ReferenceCount<ResolverDelegateProxy> to make sure the stack is not trying to access a dangling pointer once a response is received
diff --git a/src/app/CASESessionManager.cpp b/src/app/CASESessionManager.cpp
index 559ae13..199d25e 100644
--- a/src/app/CASESessionManager.cpp
+++ b/src/app/CASESessionManager.cpp
@@ -53,7 +53,7 @@
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 @@
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 f2a5b38..757d2b4 100644
--- a/src/app/CASESessionManager.h
+++ b/src/app/CASESessionManager.h
@@ -27,7 +27,7 @@
#include <lib/support/Pool.h>
#include <transport/SessionDelegate.h>
-#include <lib/dnssd/Resolver.h>
+#include <lib/dnssd/ResolverProxy.h>
namespace chip {
@@ -36,6 +36,7 @@
DeviceProxyInitParams sessionInitParams;
Dnssd::DnssdCache<CHIP_CONFIG_MDNS_CACHE_SIZE> * dnsCache = nullptr;
OperationalDeviceProxyPoolDelegate * devicePool = nullptr;
+ Dnssd::ResolverProxy * dnsResolver = nullptr;
};
/**
diff --git a/src/app/OperationalDeviceProxy.cpp b/src/app/OperationalDeviceProxy.cpp
index 46ebccb..8f2859a 100644
--- a/src/app/OperationalDeviceProxy.cpp
+++ b/src/app/OperationalDeviceProxy.cpp
@@ -43,7 +43,8 @@
namespace chip {
CHIP_ERROR OperationalDeviceProxy::Connect(Callback::Callback<OnDeviceConnected> * onConnection,
- Callback::Callback<OnDeviceConnectionFailure> * onFailure)
+ Callback::Callback<OnDeviceConnectionFailure> * onFailure,
+ Dnssd::ResolverProxy * resolver)
{
CHIP_ERROR err = CHIP_NO_ERROR;
@@ -54,7 +55,8 @@
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 b67384b..7ee309f 100644
--- a/src/app/OperationalDeviceProxy.h
+++ b/src/app/OperationalDeviceProxy.h
@@ -43,7 +43,7 @@
#include <transport/raw/MessageHeader.h>
#include <transport/raw/UDP.h>
-#include <lib/dnssd/Resolver.h>
+#include <lib/dnssd/ResolverProxy.h>
namespace chip {
@@ -109,9 +109,11 @@
* 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<OnDeviceConnected> * onConnection,
- Callback::Callback<OnDeviceConnectionFailure> * onFailure);
+ Callback::Callback<OnDeviceConnectionFailure> * 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 703dfa7..61d0bbd 100644
--- a/src/app/clusters/ota-requestor/OTARequestor.cpp
+++ b/src/app/clusters/ota-requestor/OTARequestor.cpp
@@ -235,6 +235,7 @@
.sessionInitParams = initParams,
.dnsCache = nullptr,
.devicePool = mServer->GetDevicePool(),
+ .dnsResolver = nullptr,
};
mCASESessionManager = Platform::New<CASESessionManager>(sessionManagerConfig);
diff --git a/src/controller/AbstractDnssdDiscoveryController.cpp b/src/controller/AbstractDnssdDiscoveryController.cpp
index 8d34292..924ca61 100644
--- a/src/controller/AbstractDnssdDiscoveryController.cpp
+++ b/src/controller/AbstractDnssdDiscoveryController.cpp
@@ -19,10 +19,6 @@
// module header, comes first
#include <controller/AbstractDnssdDiscoveryController.h>
-#if CONFIG_DEVICE_LAYER
-#include <platform/CHIPDeviceLayer.h>
-#endif
-
#include <lib/core/CHIPEncoding.h>
#include <lib/support/logging/CHIPLogging.h>
@@ -66,11 +62,6 @@
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 aae783c..df58457 100644
--- a/src/controller/AbstractDnssdDiscoveryController.h
+++ b/src/controller/AbstractDnssdDiscoveryController.h
@@ -19,7 +19,7 @@
#pragma once
#include <controller/DeviceDiscoveryDelegate.h>
-#include <lib/dnssd/Resolver.h>
+#include <lib/dnssd/ResolverProxy.h>
#include <lib/support/Span.h>
#include <platform/CHIPDeviceConfig.h>
@@ -39,11 +39,7 @@
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 @@
using DiscoveredNodeList = FixedSpan<Dnssd::DiscoveredNodeData, CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES>;
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 34d892d..d127e2a 100644
--- a/src/controller/CHIPCommissionableNodeController.cpp
+++ b/src/controller/CHIPCommissionableNodeController.cpp
@@ -19,6 +19,10 @@
// module header, comes first
#include <controller/CHIPCommissionableNodeController.h>
+#if CONFIG_DEVICE_LAYER
+#include <platform/CHIPDeviceLayer.h>
+#endif
+
#include <lib/support/CodeUtils.h>
namespace chip {
@@ -27,7 +31,22 @@
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 8bafe78..af57d1d 100644
--- a/src/controller/CHIPCommissionableNodeController.h
+++ b/src/controller/CHIPCommissionableNodeController.h
@@ -19,7 +19,6 @@
#pragma once
#include <controller/AbstractDnssdDiscoveryController.h>
-#include <lib/dnssd/Resolver.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/CHIPDeviceConfig.h>
@@ -37,8 +36,7 @@
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 @@
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 27e748e..1840ea1 100644
--- a/src/controller/CHIPDeviceController.cpp
+++ b/src/controller/CHIPDeviceController.cpp
@@ -45,7 +45,6 @@
#include <app/InteractionModelEngine.h>
#include <app/OperationalDeviceProxy.h>
-#include <app/util/DataModelHandler.h>
#include <app/util/error-mapping.h>
#include <credentials/CHIPCert.h>
#include <credentials/DeviceAttestationCredsProvider.h>
@@ -132,14 +131,12 @@
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 @@
.sessionInitParams = deviceInitParams,
.dnsCache = &mDNSCache,
.devicePool = &mDevicePool,
+#if CHIP_DEVICE_CONFIG_ENABLE_DNSSD
+ .dnsResolver = &mDNSResolver,
+#else
+ .dnsResolver = nullptr,
+#endif
};
mCASESessionManager = chip::Platform::New<CASESessionManager>(sessionManagerConfig);
@@ -227,10 +229,6 @@
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 @@
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 @@
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 @@
#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 @@
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 c810c6a..c23c93d 100644
--- a/src/controller/CHIPDeviceController.h
+++ b/src/controller/CHIPDeviceController.h
@@ -72,6 +72,7 @@
#include <controller/DeviceAddressUpdateDelegate.h>
#include <controller/DeviceDiscoveryDelegate.h>
#include <lib/dnssd/Resolver.h>
+#include <lib/dnssd/ResolverProxy.h>
#endif
namespace chip {
diff --git a/src/controller/CHIPDeviceControllerFactory.cpp b/src/controller/CHIPDeviceControllerFactory.cpp
index 95bb7f6..929c52e 100644
--- a/src/controller/CHIPDeviceControllerFactory.cpp
+++ b/src/controller/CHIPDeviceControllerFactory.cpp
@@ -24,6 +24,7 @@
#include <controller/CHIPDeviceControllerFactory.h>
+#include <app/util/DataModelHandler.h>
#include <lib/support/ErrorStr.h>
#if CONFIG_DEVICE_LAYER
@@ -140,9 +141,15 @@
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<DeviceControllerSystemState>(stateParams);
ChipLogDetail(Controller, "System State Initialized...");
@@ -220,6 +227,10 @@
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 c1101ec..07500b4 100644
--- a/src/controller/tests/TestCommissionableNodeController.cpp
+++ b/src/controller/tests/TestCommissionableNodeController.cpp
@@ -180,9 +180,26 @@
} // 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 0f56448..38701b0 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<CHIP_CONFIG_MDNS_CACHE_SIZE> DiscoveryImplPlatform::sDnssdCache;
+static DnssdCache<CHIP_CONFIG_MDNS_CACHE_SIZE> sDnssdCache;
#endif
+static void HandleNodeResolve(void * context, DnssdService * result, CHIP_ERROR error)
+{
+ ResolverDelegateProxy * proxy = static_cast<ResolverDelegateProxy *>(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<const uint8_t *>(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<ResolverDelegateProxy *>(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<const uint8_t *>(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<ResolverDelegateProxy *>(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,155 +568,19 @@
Resolver::CacheBypass dnssdCacheBypass)
{
ReturnErrorOnFailure(InitImpl());
-
-#if CHIP_CONFIG_MDNS_CACHE_SIZE > 0
- if (dnssdCacheBypass == Resolver::CacheBypass::Off)
- {
- /* see if the entry is cached and use it.... */
- ResolvedNodeData nodeData;
- if (sDnssdCache.Lookup(peerId, nodeData) == CHIP_NO_ERROR)
- {
- mResolverDelegate->OnNodeIdResolved(nodeData);
- return CHIP_NO_ERROR;
- }
- }
-#endif
-
- DnssdService service;
-
- ReturnErrorOnFailure(MakeInstanceName(service.mName, sizeof(service.mName), peerId));
- 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);
- }
- }
-}
-
-void DiscoveryImplPlatform::HandleNodeResolve(void * context, DnssdService * result, CHIP_ERROR error)
-{
- if (error != CHIP_NO_ERROR)
- {
- return;
- }
- DiscoveryImplPlatform * mgr = static_cast<DiscoveryImplPlatform *>(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;
-
- for (size_t i = 0; i < result->mTextEntrySize; ++i)
- {
- ByteSpan key(reinterpret_cast<const uint8_t *>(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);
+ return mResolverProxy.ResolveNodeId(peerId, type, dnssdCacheBypass);
}
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);
+ return mResolverProxy.FindCommissionableNodes(filter);
}
CHIP_ERROR DiscoveryImplPlatform::FindCommissioners(DiscoveryFilter filter)
{
ReturnErrorOnFailure(InitImpl());
- 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<DiscoveryImplPlatform *>(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<const uint8_t *>(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);
+ return mResolverProxy.FindCommissioners(filter);
}
DiscoveryImplPlatform & DiscoveryImplPlatform::GetInstance()
@@ -626,5 +598,57 @@
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)
+ {
+ /* see if the entry is cached and use it.... */
+ ResolvedNodeData nodeData;
+ if (sDnssdCache.Lookup(peerId, nodeData) == CHIP_NO_ERROR)
+ {
+ mDelegate->OnNodeIdResolved(nodeData);
+ mDelegate->Release();
+ return CHIP_NO_ERROR;
+ }
+ }
+#endif
+
+ DnssdService service;
+
+ ReturnErrorOnFailure(MakeInstanceName(service.mName, sizeof(service.mName), peerId));
+ strncpy(service.mType, kOperationalServiceName, sizeof(service.mType));
+ service.mProtocol = DnssdServiceProtocol::kDnssdProtocolTcp;
+ service.mAddressType = type;
+ return ChipDnssdResolve(&service, Inet::InterfaceId::Null(), HandleNodeIdResolve, mDelegate);
+}
+
+CHIP_ERROR ResolverProxy::FindCommissionableNodes(DiscoveryFilter filter)
+{
+ VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE);
+ mDelegate->Retain();
+
+ char serviceName[kMaxCommissionableServiceNameSize];
+ ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kCommissionableNode));
+
+ return ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny,
+ Inet::InterfaceId::Null(), HandleNodeBrowse, mDelegate);
+}
+
+CHIP_ERROR ResolverProxy::FindCommissioners(DiscoveryFilter filter)
+{
+ 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, mDelegate);
+}
+
} // namespace Dnssd
} // namespace chip
diff --git a/src/lib/dnssd/Discovery_ImplPlatform.h b/src/lib/dnssd/Discovery_ImplPlatform.h
index 5ac1753..c297ed3 100644
--- a/src/lib/dnssd/Discovery_ImplPlatform.h
+++ b/src/lib/dnssd/Discovery_ImplPlatform.h
@@ -23,6 +23,7 @@
#include <lib/dnssd/Advertiser.h>
#include <lib/dnssd/DnssdCache.h>
#include <lib/dnssd/Resolver.h>
+#include <lib/dnssd/ResolverProxy.h>
#include <lib/dnssd/platform/Dnssd.h>
#include <platform/CHIPDeviceConfig.h>
@@ -48,7 +49,7 @@
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 @@
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 @@
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<CHIP_CONFIG_MDNS_CACHE_SIZE> sDnssdCache;
-#endif
};
} // namespace Dnssd
diff --git a/src/lib/dnssd/ResolverProxy.h b/src/lib/dnssd/ResolverProxy.h
new file mode 100644
index 0000000..88ac1d4
--- /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 <lib/core/ReferenceCounted.h>
+#include <lib/dnssd/Resolver.h>
+
+namespace chip {
+namespace Dnssd {
+
+class ResolverDelegateProxy : public ReferenceCounted<ResolverDelegateProxy>, 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<ResolverDelegateProxy>();
+ 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 5252d51..fa081b3 100644
--- a/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp
+++ b/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp
@@ -23,6 +23,7 @@
#include <inet/IPPacketInfo.h>
#include <lib/core/CHIPConfig.h>
#include <lib/dnssd/MinimalMdnsServer.h>
+#include <lib/dnssd/ResolverProxy.h>
#include <lib/dnssd/ServiceNaming.h>
#include <lib/dnssd/TxtFields.h>
#include <lib/dnssd/minimal_mdns/ActiveResolveAttempts.h>
@@ -598,5 +599,30 @@
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 7581c32..20c398a 100644
--- a/src/lib/shell/commands/Ota.cpp
+++ b/src/lib/shell/commands/Ota.cpp
@@ -22,6 +22,7 @@
#include <app/server/Server.h>
#include <lib/core/CHIPCallback.h>
#include <lib/core/Optional.h>
+#include <lib/dnssd/Resolver.h>
#include <lib/shell/Commands.h>
#include <lib/shell/Engine.h>
#include <lib/shell/commands/Help.h>
@@ -299,7 +300,7 @@
VerifyOrReturn(deviceProxy != nullptr);
deviceProxy->UpdateDeviceData(sOtaContext.providerAddress, deviceProxy->GetMRPConfig());
- deviceProxy->Connect(&successCallback, &failureCallback);
+ deviceProxy->Connect(&successCallback, &failureCallback, nullptr);
}
template <OnDeviceConnected OnConnected>