Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dns-sd] Added Operational Discovery and made browse delegate common #32750

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions src/lib/dnssd/IncrementalResolve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ SerializedQNameIterator StoredServerName::Get() const
return SerializedQNameIterator(BytesRange(mNameBuffer, mNameBuffer + sizeof(mNameBuffer)), mNameBuffer);
}

CHIP_ERROR IncrementalResolver::InitializeParsing(mdns::Minimal::SerializedQNameIterator name, const mdns::Minimal::SrvRecord & srv)
CHIP_ERROR IncrementalResolver::InitializeParsing(mdns::Minimal::SerializedQNameIterator name, const uint64_t ttl,
const mdns::Minimal::SrvRecord & srv)
{
AutoInactiveResetter inactiveReset(*this);

Expand Down Expand Up @@ -183,6 +184,7 @@ CHIP_ERROR IncrementalResolver::InitializeParsing(mdns::Minimal::SerializedQName
{
return err;
}
mSpecificResolutionData.Get<OperationalNodeData>().hasZeroTTL = (ttl == 0);
}

LogFoundOperationalSrvRecord(mSpecificResolutionData.Get<OperationalNodeData>().peerId, mTargetHostName.Get());
Expand Down Expand Up @@ -304,7 +306,7 @@ CHIP_ERROR IncrementalResolver::OnTxtRecord(const ResourceData & data, BytesRang
}
}

if (IsActiveBrowseParse())
if (IsActiveCommissionParse())
{
TxtParser<CommissionNodeData> delegate(mSpecificResolutionData.Get<CommissionNodeData>());
if (!ParseTxtRecord(data.GetData(), &delegate))
Expand Down Expand Up @@ -343,14 +345,17 @@ CHIP_ERROR IncrementalResolver::OnIpAddress(Inet::InterfaceId interface, const I

CHIP_ERROR IncrementalResolver::Take(DiscoveredNodeData & outputData)
{
VerifyOrReturnError(IsActiveBrowseParse(), CHIP_ERROR_INCORRECT_STATE);
VerifyOrReturnError(IsActiveCommissionParse(), CHIP_ERROR_INCORRECT_STATE);

IPAddressSorter::Sort(mCommonResolutionData.ipAddress, mCommonResolutionData.numIPs, mCommonResolutionData.interfaceId);

outputData.Set<CommissionNodeData>();
CommissionNodeData & nodeData = outputData.Get<CommissionNodeData>();
nodeData = mSpecificResolutionData.Get<CommissionNodeData>();
CommonResolutionData & resolutionData = nodeData;
// Set the DiscoveredNodeData with CommissionNodeData info specific to commissionable/commisssioner
// node available in mSpecificResolutionData.
outputData.Set<CommissionNodeData>(mSpecificResolutionData.Get<CommissionNodeData>());

// IncrementalResolver stored CommonResolutionData separately in mCommonResolutionData hence copy the
// CommonResolutionData info from mCommonResolutionData, to CommissionNodeData within DiscoveredNodeData
CommonResolutionData & resolutionData = outputData.Get<CommissionNodeData>();
resolutionData = mCommonResolutionData;

ResetToInactive();
Expand Down
7 changes: 4 additions & 3 deletions src/lib/dnssd/IncrementalResolve.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class IncrementalResolver
/// method.
bool IsActive() const { return mSpecificResolutionData.Valid(); }

bool IsActiveBrowseParse() const { return mSpecificResolutionData.Is<CommissionNodeData>(); }
bool IsActiveCommissionParse() const { return mSpecificResolutionData.Is<CommissionNodeData>(); }
bool IsActiveOperationalParse() const { return mSpecificResolutionData.Is<OperationalNodeData>(); }

ServiceNameType GetCurrentType() const { return mServiceNameType; }
Expand All @@ -115,7 +115,8 @@ class IncrementalResolver
/// interested on, after which TXT and A/AAAA are looked for.
///
/// If this function returns with error, the object will be in an inactive state.
CHIP_ERROR InitializeParsing(mdns::Minimal::SerializedQNameIterator name, const mdns::Minimal::SrvRecord & srv);
CHIP_ERROR InitializeParsing(mdns::Minimal::SerializedQNameIterator name, const uint64_t ttl,
const mdns::Minimal::SrvRecord & srv);

/// Notify that a new record is being processed.
/// Will handle filtering and processing of data to determine if the entry is relevant for
Expand Down Expand Up @@ -150,7 +151,7 @@ class IncrementalResolver

/// Take the current value of the object and clear it once returned.
///
/// Object must be in `IsActiveBrowseParse()` for this to succeed.
/// Object must be in `IsActive()` for this to succeed.
/// Data will be returned (and cleared) even if not yet complete based
/// on `GetMissingRequiredInformation()`. This method takes as much data as
/// it was parsed so far.
Expand Down
7 changes: 7 additions & 0 deletions src/lib/dnssd/ResolverProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ CHIP_ERROR ResolverProxy::DiscoverCommissioners(DiscoveryFilter filter)
return mResolver.StartDiscovery(DiscoveryType::kCommissionerNode, filter, *mContext);
}

CHIP_ERROR ResolverProxy::DiscoverOperationalNodes(DiscoveryFilter filter)
{
VerifyOrReturnError(mContext != nullptr, CHIP_ERROR_INCORRECT_STATE);

return mResolver.StartDiscovery(DiscoveryType::kOperational, filter, *mContext);
}

CHIP_ERROR ResolverProxy::StopDiscovery()
{
VerifyOrReturnError(mContext != nullptr, CHIP_ERROR_INCORRECT_STATE);
Expand Down
1 change: 1 addition & 0 deletions src/lib/dnssd/ResolverProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class ResolverProxy

CHIP_ERROR DiscoverCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter());
CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter = DiscoveryFilter());
CHIP_ERROR DiscoverOperationalNodes(DiscoveryFilter filter = DiscoveryFilter());
CHIP_ERROR StopDiscovery();

private:
Expand Down
37 changes: 29 additions & 8 deletions src/lib/dnssd/Resolver_ImplMinimalMdns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ void PacketParser::ParseSRVResource(const ResourceData & data)
continue;
}

CHIP_ERROR err = resolver.InitializeParsing(data.GetName(), srv);
CHIP_ERROR err = resolver.InitializeParsing(data.GetName(), data.GetTtlSeconds(), srv);
if (err != CHIP_NO_ERROR)
{
// Receiving records that we do not need to parse is normal:
Expand Down Expand Up @@ -363,14 +363,15 @@ void MinMdnsResolver::AdvancePendingResolverStates()
{
if (!resolver->IsActive())
{
ChipLogError(Discovery, "resolver inactive, continue to next");
su-shanka marked this conversation as resolved.
Show resolved Hide resolved
continue;
}

IncrementalResolver::RequiredInformationFlags missing = resolver->GetMissingRequiredInformation();

if (missing.Has(IncrementalResolver::RequiredInformationBitFlags::kIpAddress))
{
if (resolver->IsActiveBrowseParse())
if (resolver->IsActiveCommissionParse())
{
// Browse wants IP addresses
ScheduleIpAddressResolve(resolver->GetTargetHostName());
Expand Down Expand Up @@ -399,7 +400,7 @@ void MinMdnsResolver::AdvancePendingResolverStates()
}

// SUCCESS. Call the delegates
if (resolver->IsActiveBrowseParse())
if (resolver->IsActiveCommissionParse())
{
MATTER_TRACE_SCOPE("Active commissioning delegate call", "MinMdnsResolver");
DiscoveredNodeData nodeData;
Expand Down Expand Up @@ -452,19 +453,39 @@ void MinMdnsResolver::AdvancePendingResolverStates()
else if (resolver->IsActiveOperationalParse())
{
MATTER_TRACE_SCOPE("Active operational delegate call", "MinMdnsResolver");
ResolvedNodeData nodeData;
ResolvedNodeData nodeResolvedData;
CHIP_ERROR err = resolver->Take(nodeResolvedData);

CHIP_ERROR err = resolver->Take(nodeData);
if (err != CHIP_NO_ERROR)
{
ChipLogError(Discovery, "Failed to take discovery result: %" CHIP_ERROR_FORMAT, err.Format());
ChipLogError(Discovery, "Failed to take NodeData - result: %" CHIP_ERROR_FORMAT, err.Format());
continue;
}

mActiveResolves.Complete(nodeData.operationalData.peerId);
if (mActiveResolves.HasBrowseFor(chip::Dnssd::DiscoveryType::kOperational))
{
if (mDiscoveryContext != nullptr)
{
DiscoveredNodeData nodeData;
OperationalNodeBrowseData opNodeData;

opNodeData.peerId = nodeResolvedData.operationalData.peerId;
opNodeData.hasZeroTTL = nodeResolvedData.operationalData.hasZeroTTL;
nodeData.Set<OperationalNodeBrowseData>(opNodeData);
su-shanka marked this conversation as resolved.
Show resolved Hide resolved
mDiscoveryContext->OnNodeDiscovered(nodeData);
su-shanka marked this conversation as resolved.
Show resolved Hide resolved
}
else
{
#if CHIP_MINMDNS_HIGH_VERBOSITY
ChipLogError(Discovery, "No delegate to report operational node discovery");
#endif
}
}

mActiveResolves.Complete(nodeResolvedData.operationalData.peerId);
su-shanka marked this conversation as resolved.
Show resolved Hide resolved
if (mOperationalDelegate != nullptr)
{
mOperationalDelegate->OnOperationalNodeResolved(nodeData);
mOperationalDelegate->OnOperationalNodeResolved(nodeResolvedData);
}
else
{
Expand Down
18 changes: 15 additions & 3 deletions src/lib/dnssd/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,21 @@ struct CommonResolutionData
struct OperationalNodeData
{
PeerId peerId;

bool hasZeroTTL;
Damian-Nordic marked this conversation as resolved.
Show resolved Hide resolved
void Reset() { peerId = PeerId(); }
};

struct OperationalNodeBrowseData : public OperationalNodeData
{
OperationalNodeBrowseData() { Reset(); };
void LogDetail() const
{
ChipLogDetail(Discovery, "Discovered Operational node:\r\n");
ChipLogDetail(Discovery, "\tNode Instance: " ChipLogFormatPeerId, ChipLogValuePeerId(peerId));
ChipLogDetail(Discovery, "\thasZeroTTL: %s\r\n", hasZeroTTL ? "true" : "false");
}
};

inline constexpr size_t kMaxDeviceNameLen = 32;
inline constexpr size_t kMaxRotatingIdLen = 50;
inline constexpr size_t kMaxPairingInstructionLen = 128;
Expand Down Expand Up @@ -297,12 +308,13 @@ struct ResolvedNodeData
}
};

using DiscoveredNodeData = Variant<CommissionNodeData>;
using DiscoveredNodeData = Variant<CommissionNodeData, OperationalNodeBrowseData>;

/// Callbacks for discovering nodes advertising non-operational status:
/// Callbacks for discovering nodes advertising both operational and non-operational status:
/// - Commissioners
/// - Nodes in commissioning modes over IP (e.g. ethernet devices, devices already
/// connected to thread/wifi or devices with a commissioning window open)
/// - Operational nodes
class DiscoverNodeDelegate
{
public:
Expand Down
26 changes: 14 additions & 12 deletions src/lib/dnssd/tests/TestIncrementalResolve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <string.h>

#include <lib/dnssd/ServiceNaming.h>
#include <lib/dnssd/minimal_mdns/core/tests/QNameStrings.h>
#include <lib/dnssd/minimal_mdns/records/IP.h>
#include <lib/dnssd/minimal_mdns/records/Ptr.h>
Expand Down Expand Up @@ -161,7 +162,7 @@ TEST(TestIncrementalResolve, TestCreation)
IncrementalResolver resolver;

EXPECT_FALSE(resolver.IsActive());
EXPECT_FALSE(resolver.IsActiveBrowseParse());
EXPECT_FALSE(resolver.IsActiveCommissionParse());
EXPECT_FALSE(resolver.IsActiveOperationalParse());
EXPECT_TRUE(
resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kSrvInitialization));
Expand All @@ -177,10 +178,10 @@ TEST(TestIncrementalResolve, TestInactiveResetOnInitError)
PreloadSrvRecord(srvRecord);

// test host name is not a 'matter' name
EXPECT_NE(resolver.InitializeParsing(kTestHostName.Serialized(), srvRecord), CHIP_NO_ERROR);
EXPECT_NE(resolver.InitializeParsing(kTestHostName.Serialized(), 0, srvRecord), CHIP_NO_ERROR);

EXPECT_FALSE(resolver.IsActive());
EXPECT_FALSE(resolver.IsActiveBrowseParse());
EXPECT_FALSE(resolver.IsActiveCommissionParse());
EXPECT_FALSE(resolver.IsActiveOperationalParse());
}

Expand All @@ -193,10 +194,10 @@ TEST(TestIncrementalResolve, TestStartOperational)
SrvRecord srvRecord;
PreloadSrvRecord(srvRecord);

EXPECT_EQ(resolver.InitializeParsing(kTestOperationalName.Serialized(), srvRecord), CHIP_NO_ERROR);
EXPECT_EQ(resolver.InitializeParsing(kTestOperationalName.Serialized(), 1, srvRecord), CHIP_NO_ERROR);

EXPECT_TRUE(resolver.IsActive());
EXPECT_FALSE(resolver.IsActiveBrowseParse());
EXPECT_FALSE(resolver.IsActiveCommissionParse());
EXPECT_TRUE(resolver.IsActiveOperationalParse());
EXPECT_TRUE(resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress));
EXPECT_EQ(resolver.GetTargetHostName(), kTestHostName.Serialized());
Expand All @@ -211,10 +212,10 @@ TEST(TestIncrementalResolve, TestStartCommissionable)
SrvRecord srvRecord;
PreloadSrvRecord(srvRecord);

EXPECT_EQ(resolver.InitializeParsing(kTestCommissionableNode.Serialized(), srvRecord), CHIP_NO_ERROR);
EXPECT_EQ(resolver.InitializeParsing(kTestCommissionableNode.Serialized(), 0, srvRecord), CHIP_NO_ERROR);

EXPECT_TRUE(resolver.IsActive());
EXPECT_TRUE(resolver.IsActiveBrowseParse());
EXPECT_TRUE(resolver.IsActiveCommissionParse());
EXPECT_FALSE(resolver.IsActiveOperationalParse());
EXPECT_TRUE(resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress));
EXPECT_EQ(resolver.GetTargetHostName(), kTestHostName.Serialized());
Expand All @@ -229,10 +230,10 @@ TEST(TestIncrementalResolve, TestStartCommissioner)
SrvRecord srvRecord;
PreloadSrvRecord(srvRecord);

EXPECT_EQ(resolver.InitializeParsing(kTestCommissionerNode.Serialized(), srvRecord), CHIP_NO_ERROR);
EXPECT_EQ(resolver.InitializeParsing(kTestCommissionerNode.Serialized(), 0, srvRecord), CHIP_NO_ERROR);

EXPECT_TRUE(resolver.IsActive());
EXPECT_TRUE(resolver.IsActiveBrowseParse());
EXPECT_TRUE(resolver.IsActiveCommissionParse());
EXPECT_FALSE(resolver.IsActiveOperationalParse());
EXPECT_TRUE(resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress));
EXPECT_EQ(resolver.GetTargetHostName(), kTestHostName.Serialized());
Expand All @@ -247,7 +248,7 @@ TEST(TestIncrementalResolve, TestParseOperational)
SrvRecord srvRecord;
PreloadSrvRecord(srvRecord);

EXPECT_EQ(resolver.InitializeParsing(kTestOperationalName.Serialized(), srvRecord), CHIP_NO_ERROR);
EXPECT_EQ(resolver.InitializeParsing(kTestOperationalName.Serialized(), 1, srvRecord), CHIP_NO_ERROR);

// once initialized, parsing should be ready however no IP address is available
EXPECT_TRUE(resolver.IsActiveOperationalParse());
Expand Down Expand Up @@ -304,6 +305,7 @@ TEST(TestIncrementalResolve, TestParseOperational)
// validate data as it was passed in
EXPECT_EQ(nodeData.operationalData.peerId,
PeerId().SetCompressedFabricId(0x1234567898765432LL).SetNodeId(0xABCDEFEDCBAABCDELL));
EXPECT_FALSE(nodeData.operationalData.hasZeroTTL);
EXPECT_EQ(nodeData.resolutionData.numIPs, 1u);
EXPECT_EQ(nodeData.resolutionData.port, 0x1234);
EXPECT_FALSE(nodeData.resolutionData.supportsTcp);
Expand All @@ -324,10 +326,10 @@ TEST(TestIncrementalResolve, TestParseCommissionable)
SrvRecord srvRecord;
PreloadSrvRecord(srvRecord);

EXPECT_EQ(resolver.InitializeParsing(kTestCommissionableNode.Serialized(), srvRecord), CHIP_NO_ERROR);
EXPECT_EQ(resolver.InitializeParsing(kTestCommissionableNode.Serialized(), 0, srvRecord), CHIP_NO_ERROR);

// once initialized, parsing should be ready however no IP address is available
EXPECT_TRUE(resolver.IsActiveBrowseParse());
EXPECT_TRUE(resolver.IsActiveCommissionParse());
EXPECT_TRUE(resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress));
EXPECT_EQ(resolver.GetTargetHostName(), kTestHostName.Serialized());

Expand Down
27 changes: 23 additions & 4 deletions src/lib/shell/commands/Dns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,23 @@ class DnsShellResolverDelegate : public Dnssd::DiscoverNodeDelegate, public Addr

AddressResolve::NodeLookupHandle & Handle() { return mSelfHandle; }

void LogOperationalNodeDiscovered(const Dnssd::OperationalNodeBrowseData & nodeData)
{
streamer_printf(streamer_get(), "DNS browse operational succeeded: \r\n");
streamer_printf(streamer_get(), " Node Instance: " ChipLogFormatPeerId, ChipLogValuePeerId(nodeData.peerId));
streamer_printf(streamer_get(), " hasZeroTTL: %s\r\n", nodeData.hasZeroTTL ? "true" : "false");
}

void OnNodeDiscovered(const Dnssd::DiscoveredNodeData & discNodeData) override
{
if (!discNodeData.Is<Dnssd::CommissionNodeData>())
if (discNodeData.Is<Dnssd::OperationalNodeBrowseData>())
{
streamer_printf(streamer_get(), "DNS browse failed - not commission type node \r\n");
LogOperationalNodeDiscovered(discNodeData.Get<Dnssd::OperationalNodeBrowseData>());
return;
}

Dnssd::CommissionNodeData nodeData = discNodeData.Get<Dnssd::CommissionNodeData>();
const auto & nodeData = discNodeData.Get<Dnssd::CommissionNodeData>();

if (!nodeData.IsValid())
{
streamer_printf(streamer_get(), "DNS browse failed - not found valid services \r\n");
Expand Down Expand Up @@ -237,6 +245,16 @@ CHIP_ERROR BrowseCommissionerHandler(int argc, char ** argv)
return sResolverProxy.DiscoverCommissioners(filter);
}

CHIP_ERROR BrowseOperationalHandler(int argc, char ** argv)
{
Dnssd::DiscoveryFilter filter;
VerifyOrReturnError(ParseSubType(argc, argv, filter), CHIP_ERROR_INVALID_ARGUMENT);

streamer_printf(streamer_get(), "Browsing operational...\r\n");

return sResolverProxy.DiscoverOperationalNodes(filter);
}

CHIP_ERROR BrowseHandler(int argc, char ** argv)
{
if (argc == 0)
Expand Down Expand Up @@ -271,13 +289,14 @@ void RegisterDnsCommands()
"Browse Matter commissionable nodes. Usage: dns browse commissionable [subtype]" },
{ &BrowseCommissionerHandler, "commissioner",
"Browse Matter commissioner nodes. Usage: dns browse commissioner [subtype]" },
{ &BrowseOperationalHandler, "operational", "Browse Matter operational nodes. Usage: dns browse operational" },
};

static const shell_command_t sDnsSubCommands[] = {
{ &ResolveHandler, "resolve",
"Resolve the DNS service. Usage: dns resolve <fabric-id> <node-id> (e.g. dns resolve 5544332211 1)" },
{ &BrowseHandler, "browse",
"Browse DNS services published by Matter nodes. Usage: dns browse <commissionable|commissioner>" },
"Browse DNS services published by Matter nodes. Usage: dns browse <commissionable|commissioner|operational>" },
};

static const shell_command_t sDnsCommand = { &DnsHandler, "dns", "Dns client commands" };
Expand Down
Loading