diff --git a/silabs_examples/unify-matter-pc/linux/BUILD.gn b/silabs_examples/unify-matter-pc/linux/BUILD.gn index f1f8dc7390ba43..c5ed91f6aea2ba 100644 --- a/silabs_examples/unify-matter-pc/linux/BUILD.gn +++ b/silabs_examples/unify-matter-pc/linux/BUILD.gn @@ -45,8 +45,6 @@ config("unify-config") { if (is_debug_build) { defines += [ "DEBUG_BUILD" ] } - # flag to temporarily disable node discovery until the changes are available from CSA - defines += ["UMPC_DISABLE_DISCOVERY"] } config("coverage") { diff --git a/silabs_examples/unify-matter-pc/linux/src/components/mpc_nw_monitor/src/mpc_nw_monitor.cpp b/silabs_examples/unify-matter-pc/linux/src/components/mpc_nw_monitor/src/mpc_nw_monitor.cpp index 586445ae319c63..f093e7db5e21ff 100644 --- a/silabs_examples/unify-matter-pc/linux/src/components/mpc_nw_monitor/src/mpc_nw_monitor.cpp +++ b/silabs_examples/unify-matter-pc/linux/src/components/mpc_nw_monitor/src/mpc_nw_monitor.cpp @@ -83,7 +83,7 @@ static void generateUNID(string & unid) } #ifndef UMPC_DISABLE_DISCOVERY -class OperationalDiscover : public chip::Dnssd::OperationalBrowseDeleagete +class OperationalDiscover : public chip::Dnssd::OperationalBrowseDelegate { bool needs_update(attribute node) { @@ -255,11 +255,15 @@ static void mpc_start_node_discovery() { #ifndef UMPC_DISABLE_DISCOVERY static OperationalDiscover mDNSdiscover; + static chip::Dnssd::ResolverProxy * mResolver = nullptr; + // Start discovering nodes - if (chip::Dnssd::Resolver::Instance().IsInitialized()) + if (mResolver == nullptr) { - chip::Dnssd::Resolver::Instance().SetOperationalBrowseDelegate(&mDNSdiscover); - chip::Dnssd::Resolver::Instance().DiscoverOperational(); + mResolver = Platform::New(); + mResolver->Init(); + mResolver->SetOperationalBrowseDelegate(&mDNSdiscover); + mResolver->DiscoverOperational(); } #endif } diff --git a/src/controller/tests/TestCommissionableNodeController.cpp b/src/controller/tests/TestCommissionableNodeController.cpp index c2aafe500c293d..9bcff26639108f 100644 --- a/src/controller/tests/TestCommissionableNodeController.cpp +++ b/src/controller/tests/TestCommissionableNodeController.cpp @@ -16,6 +16,7 @@ * limitations under the License. */ +#include "lib/dnssd/Resolver.h" #include #include #include @@ -43,7 +44,10 @@ class MockResolver : public Resolver { return CHIP_ERROR_NOT_IMPLEMENTED; } + CHIP_ERROR StopDiscovery(DiscoveryContext &) override { return CHIP_ERROR_NOT_IMPLEMENTED; } + CHIP_ERROR DiscoverOperational(DiscoveryFilter filter, DiscoveryContext &) override { return CHIP_ERROR_NOT_IMPLEMENTED; } + CHIP_ERROR ReconfirmRecord(const char * hostname, Inet::IPAddress address, Inet::InterfaceId interfaceId) override { return CHIP_ERROR_NOT_IMPLEMENTED; diff --git a/src/lib/dnssd/Discovery_ImplPlatform.cpp b/src/lib/dnssd/Discovery_ImplPlatform.cpp index 55debe8eb85e8b..46692c3210d714 100644 --- a/src/lib/dnssd/Discovery_ImplPlatform.cpp +++ b/src/lib/dnssd/Discovery_ImplPlatform.cpp @@ -643,6 +643,31 @@ void DiscoveryImplPlatform::NodeIdResolutionNoLongerNeeded(const PeerId & peerId ChipDnssdResolveNoLongerNeeded(name); } +CHIP_ERROR DiscoveryImplPlatform::DiscoverOperational(DiscoveryFilter filter, DiscoveryContext & context) +{ + ReturnErrorOnFailure(InitImpl()); + StopDiscovery(context); + + char serviceName[kMaxCommissionerServiceNameSize]; + ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kOperational)); + + intptr_t browseIdentifier; + // Increase the reference count of the context to keep it alive until HandleNodeBrowse is called back. + CHIP_ERROR error = ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny, + Inet::InterfaceId::Null(), HandleNodeBrowse, context.Retain(), &browseIdentifier); + + if (error == CHIP_NO_ERROR) + { + context.SetBrowseIdentifier(browseIdentifier); + } + else + { + context.Release(); + } + + return CHIP_NO_ERROR; +} + CHIP_ERROR DiscoveryImplPlatform::DiscoverCommissionableNodes(DiscoveryFilter filter, DiscoveryContext & context) { ReturnErrorOnFailure(InitImpl()); diff --git a/src/lib/dnssd/Discovery_ImplPlatform.h b/src/lib/dnssd/Discovery_ImplPlatform.h index a3f79796ca535c..3d515942e3c490 100644 --- a/src/lib/dnssd/Discovery_ImplPlatform.h +++ b/src/lib/dnssd/Discovery_ImplPlatform.h @@ -51,11 +51,14 @@ class DiscoveryImplPlatform : public ServiceAdvertiser, public Resolver // Members that implement Resolver interface. void SetOperationalDelegate(OperationalResolveDelegate * delegate) override { mOperationalDelegate = delegate; } + CHIP_ERROR ResolveNodeId(const PeerId & peerId) override; void NodeIdResolutionNoLongerNeeded(const PeerId & peerId) override; CHIP_ERROR DiscoverCommissionableNodes(DiscoveryFilter filter, DiscoveryContext & context) override; CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter, DiscoveryContext & context) override; + CHIP_ERROR DiscoverOperational(DiscoveryFilter filter, DiscoveryContext & context) override; CHIP_ERROR StopDiscovery(DiscoveryContext & context) override; + CHIP_ERROR ReconfirmRecord(const char * hostname, Inet::IPAddress address, Inet::InterfaceId interfaceId) override; static DiscoveryImplPlatform & GetInstance(); diff --git a/src/lib/dnssd/Resolver.h b/src/lib/dnssd/Resolver.h index ae4e95f4341b85..374e139bcf7d59 100644 --- a/src/lib/dnssd/Resolver.h +++ b/src/lib/dnssd/Resolver.h @@ -352,6 +352,18 @@ class CommissioningResolveDelegate /// multicast discovery query virtual void OnNodeDiscovered(const DiscoveredNodeData & nodeData) = 0; }; +/// Callback for Browsing for nodes without resolving the DNS records +/// +class OperationalBrowseDelegate +{ +public: + virtual ~OperationalBrowseDelegate() = default; + /// Called within the CHIP event loop once a node is discovered. + /// + /// May be called multiple times as more nodes send their answer to a + /// multicast discovery query + virtual void OnOperationalNodeDiscovered(const OperationalNodeData & operationalData) = 0; +}; /** * Node discovery context class. @@ -385,8 +397,22 @@ class DiscoveryContext : public ReferenceCounted } } + void SetOperationalBrowseDelegate(OperationalBrowseDelegate * delegate) { mBrowseOperationalDelegate = delegate; } + + void OnOperationalNodeDiscovered(const OperationalNodeData & operationalData) + { + if (mBrowseOperationalDelegate != nullptr){ + mBrowseOperationalDelegate->OnOperationalNodeDiscovered(operationalData); + } + else + { + ChipLogError(Discovery, "Missing Browse delegate. Data discarded"); + } + } + private: CommissioningResolveDelegate * mCommissioningDelegate = nullptr; + OperationalBrowseDelegate * mBrowseOperationalDelegate = nullptr; Optional mBrowseIdentifier; }; @@ -486,7 +512,21 @@ class Resolver virtual CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter, DiscoveryContext & context) = 0; /** - * Stop discovery (of commissionable or commissioner nodes). + * @brief Start Browising for operational devices + * + * This will start periodical brwosing of operational devices. The when a new node is + * found the delegate set with SetOperationalBrowseDelegate is called. The mDNS queryies + * will continue unitil StopDiscovery is called. + * + * Note, this will locate all the Operational devices on the network. Typically an + * application would filter the found nodes by relevant fabrics. + * + * If needed a discovery filter may be specified to narrow the search. + */ + virtual CHIP_ERROR DiscoverOperational(DiscoveryFilter filter, DiscoveryContext & context) = 0; + + /** + * Stop discovery (of operational, 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. diff --git a/src/lib/dnssd/ResolverProxy.cpp b/src/lib/dnssd/ResolverProxy.cpp index 3e7446ebbbdc6b..2a40e4acb42506 100644 --- a/src/lib/dnssd/ResolverProxy.cpp +++ b/src/lib/dnssd/ResolverProxy.cpp @@ -26,7 +26,10 @@ CHIP_ERROR ResolverProxy::Init(Inet::EndPointManager * udpEnd { VerifyOrReturnError(mContext == nullptr, CHIP_ERROR_INCORRECT_STATE); - ReturnErrorOnFailure(mResolver.Init(udpEndPoint)); + if (!mResolver.IsInitialized()) + { + ReturnErrorOnFailure(mResolver.Init(udpEndPoint)); + } mContext = Platform::New(); VerifyOrReturnError(mContext != nullptr, CHIP_ERROR_NO_MEMORY); @@ -55,6 +58,13 @@ CHIP_ERROR ResolverProxy::DiscoverCommissioners(DiscoveryFilter filter) return mResolver.DiscoverCommissioners(filter, *mContext); } +CHIP_ERROR ResolverProxy::DiscoverOperational(DiscoveryFilter filter) +{ + VerifyOrReturnError(mContext != nullptr, CHIP_ERROR_INCORRECT_STATE); + + return mResolver.DiscoverOperational(filter, *mContext); +} + CHIP_ERROR ResolverProxy::StopDiscovery() { VerifyOrReturnError(mContext != nullptr, CHIP_ERROR_INCORRECT_STATE); diff --git a/src/lib/dnssd/ResolverProxy.h b/src/lib/dnssd/ResolverProxy.h index 09a50e89c1a209..a0f0b70cd8446f 100644 --- a/src/lib/dnssd/ResolverProxy.h +++ b/src/lib/dnssd/ResolverProxy.h @@ -52,8 +52,17 @@ class ResolverProxy } } + void SetOperationalBrowseDelegate(OperationalBrowseDelegate * delegate) + { + if (mContext != nullptr) + { + mContext->SetOperationalBrowseDelegate(delegate); + } + } + CHIP_ERROR DiscoverCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter()); CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter = DiscoveryFilter()); + CHIP_ERROR DiscoverOperational(DiscoveryFilter filter = DiscoveryFilter()); CHIP_ERROR StopDiscovery(); private: diff --git a/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp b/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp index 64461965367b13..22351a84b90bab 100644 --- a/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp +++ b/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp @@ -16,7 +16,9 @@ */ #include "Resolver.h" +#include "lib/dnssd/minimal_mdns/core/Constants.h" +#include #include #include @@ -283,10 +285,12 @@ class MinMdnsResolver : public Resolver, public MdnsPacketDelegate bool IsInitialized() override; void Shutdown() override; void SetOperationalDelegate(OperationalResolveDelegate * delegate) override { mOperationalDelegate = delegate; } + CHIP_ERROR ResolveNodeId(const PeerId & peerId) override; void NodeIdResolutionNoLongerNeeded(const PeerId & peerId) override; CHIP_ERROR DiscoverCommissionableNodes(DiscoveryFilter filter, DiscoveryContext & context) override; CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter, DiscoveryContext & context) override; + CHIP_ERROR DiscoverOperational(DiscoveryFilter filter, DiscoveryContext & context) override; CHIP_ERROR StopDiscovery(DiscoveryContext & context) override; CHIP_ERROR ReconfirmRecord(const char * hostname, Inet::IPAddress address, Inet::InterfaceId interfaceId) override; @@ -294,6 +298,7 @@ class MinMdnsResolver : public Resolver, public MdnsPacketDelegate OperationalResolveDelegate * mOperationalDelegate = nullptr; DiscoveryContext * mDiscoveryContext = nullptr; System::Layer * mSystemLayer = nullptr; + ActiveResolveAttempts mActiveResolves; PacketParser mPacketParser; @@ -440,7 +445,6 @@ void MinMdnsResolver::AdvancePendingResolverStates() { MATTER_TRACE_SCOPE("Active operational delegate call", "MinMdnsResolver"); ResolvedNodeData nodeData; - CHIP_ERROR err = resolver->Take(nodeData); if (err != CHIP_NO_ERROR) { @@ -448,6 +452,12 @@ void MinMdnsResolver::AdvancePendingResolverStates() } mActiveResolves.Complete(nodeData.operationalData.peerId); + + if (mDiscoveryContext != nullptr) + { + mDiscoveryContext->OnOperationalNodeDiscovered(nodeData.operationalData); + } + if (mOperationalDelegate != nullptr) { mOperationalDelegate->OnOperationalNodeResolved(nodeData); @@ -701,6 +711,15 @@ CHIP_ERROR MinMdnsResolver::DiscoverCommissioners(DiscoveryFilter filter, Discov return BrowseNodes(DiscoveryType::kCommissionerNode, filter); } + +CHIP_ERROR MinMdnsResolver::DiscoverOperational(DiscoveryFilter filter, DiscoveryContext & context) +{ + // minmdns currently supports only one discovery context at a time so override the previous context + SetDiscoveryContext(&context); + + return BrowseNodes(DiscoveryType::kOperational, filter); +} + CHIP_ERROR MinMdnsResolver::StopDiscovery(DiscoveryContext & context) { SetDiscoveryContext(nullptr); diff --git a/src/lib/dnssd/Resolver_ImplNone.cpp b/src/lib/dnssd/Resolver_ImplNone.cpp index 9a1f40f3008dff..d8990a1f44746c 100644 --- a/src/lib/dnssd/Resolver_ImplNone.cpp +++ b/src/lib/dnssd/Resolver_ImplNone.cpp @@ -44,11 +44,17 @@ class NoneResolver : public Resolver { return CHIP_ERROR_NOT_IMPLEMENTED; } + CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter, DiscoveryContext & context) override { return CHIP_ERROR_NOT_IMPLEMENTED; } + CHIP_ERROR DiscoverOperational(DiscoveryFilter filter, DiscoveryContext & context) override + { + return CHIP_ERROR_NOT_IMPLEMENTED; + } CHIP_ERROR StopDiscovery(DiscoveryContext & context) override { return CHIP_ERROR_NOT_IMPLEMENTED; } + CHIP_ERROR ReconfirmRecord(const char * hostname, Inet::IPAddress address, Inet::InterfaceId interfaceId) override { return CHIP_ERROR_NOT_IMPLEMENTED; diff --git a/src/lib/shell/commands/Dns.cpp b/src/lib/shell/commands/Dns.cpp index badd6681fceec3..d93f4cf16313c2 100644 --- a/src/lib/shell/commands/Dns.cpp +++ b/src/lib/shell/commands/Dns.cpp @@ -228,6 +228,21 @@ CHIP_ERROR BrowseCommissionerHandler(int argc, char ** argv) return sResolverProxy.DiscoverCommissioners(filter); } +CHIP_ERROR BrowseOpertionalHandler(int argc, char ** argv) +{ + Dnssd::DiscoveryFilter filter; + + if (!ParseSubType(argc, argv, filter)) + { + streamer_printf(streamer_get(), "Invalid argument\r\n"); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + streamer_printf(streamer_get(), "Browsing operational nodes...\r\n"); + + return sResolverProxy.DiscoverOperational(filter); +} + CHIP_ERROR BrowseHandler(int argc, char ** argv) { if (argc == 0) @@ -262,6 +277,9 @@ void RegisterDnsCommands() "Browse Matter commissionable nodes. Usage: dns browse commissionable [subtype]" }, { &BrowseCommissionerHandler, "commissioner", "Browse Matter commissioner nodes. Usage: dns browse commissioner [subtype]" }, + { &BrowseOpertionalHandler, "operational", + "Browse Matter all operationional nodes. Usage: dns browse operational [subtype]" }, + }; static const shell_command_t sDnsSubCommands[] = {