Skip to content

Commit cd85f36

Browse files
[Dns-sd] Added Operational Discovery and made browse delegate common (#32750)
* Added operational discovery support * Restyled by whitespace * Restyled by clang-format * Updates as per review feedback * Restyled by whitespace * Restyled by clang-format * Updates based on additional feedback * Restyled by whitespace * updates as per feedback from review --------- Co-authored-by: Restyled.io <commits@restyled.io>
1 parent e079364 commit cd85f36

8 files changed

+105
-37
lines changed

src/lib/dnssd/IncrementalResolve.cpp

+12-7
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ SerializedQNameIterator StoredServerName::Get() const
137137
return SerializedQNameIterator(BytesRange(mNameBuffer, mNameBuffer + sizeof(mNameBuffer)), mNameBuffer);
138138
}
139139

140-
CHIP_ERROR IncrementalResolver::InitializeParsing(mdns::Minimal::SerializedQNameIterator name, const mdns::Minimal::SrvRecord & srv)
140+
CHIP_ERROR IncrementalResolver::InitializeParsing(mdns::Minimal::SerializedQNameIterator name, const uint64_t ttl,
141+
const mdns::Minimal::SrvRecord & srv)
141142
{
142143
AutoInactiveResetter inactiveReset(*this);
143144

@@ -183,6 +184,7 @@ CHIP_ERROR IncrementalResolver::InitializeParsing(mdns::Minimal::SerializedQName
183184
{
184185
return err;
185186
}
187+
mSpecificResolutionData.Get<OperationalNodeData>().hasZeroTTL = (ttl == 0);
186188
}
187189

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

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

344346
CHIP_ERROR IncrementalResolver::Take(DiscoveredNodeData & outputData)
345347
{
346-
VerifyOrReturnError(IsActiveBrowseParse(), CHIP_ERROR_INCORRECT_STATE);
348+
VerifyOrReturnError(IsActiveCommissionParse(), CHIP_ERROR_INCORRECT_STATE);
347349

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

350-
outputData.Set<CommissionNodeData>();
351-
CommissionNodeData & nodeData = outputData.Get<CommissionNodeData>();
352-
nodeData = mSpecificResolutionData.Get<CommissionNodeData>();
353-
CommonResolutionData & resolutionData = nodeData;
352+
// Set the DiscoveredNodeData with CommissionNodeData info specific to commissionable/commisssioner
353+
// node available in mSpecificResolutionData.
354+
outputData.Set<CommissionNodeData>(mSpecificResolutionData.Get<CommissionNodeData>());
355+
356+
// IncrementalResolver stored CommonResolutionData separately in mCommonResolutionData hence copy the
357+
// CommonResolutionData info from mCommonResolutionData, to CommissionNodeData within DiscoveredNodeData
358+
CommonResolutionData & resolutionData = outputData.Get<CommissionNodeData>();
354359
resolutionData = mCommonResolutionData;
355360

356361
ResetToInactive();

src/lib/dnssd/IncrementalResolve.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class IncrementalResolver
100100
/// method.
101101
bool IsActive() const { return mSpecificResolutionData.Valid(); }
102102

103-
bool IsActiveBrowseParse() const { return mSpecificResolutionData.Is<CommissionNodeData>(); }
103+
bool IsActiveCommissionParse() const { return mSpecificResolutionData.Is<CommissionNodeData>(); }
104104
bool IsActiveOperationalParse() const { return mSpecificResolutionData.Is<OperationalNodeData>(); }
105105

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

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

151152
/// Take the current value of the object and clear it once returned.
152153
///
153-
/// Object must be in `IsActiveBrowseParse()` for this to succeed.
154+
/// Object must be in `IsActive()` for this to succeed.
154155
/// Data will be returned (and cleared) even if not yet complete based
155156
/// on `GetMissingRequiredInformation()`. This method takes as much data as
156157
/// it was parsed so far.

src/lib/dnssd/ResolverProxy.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ CHIP_ERROR ResolverProxy::DiscoverCommissioners(DiscoveryFilter filter)
5555
return mResolver.StartDiscovery(DiscoveryType::kCommissionerNode, filter, *mContext);
5656
}
5757

58+
CHIP_ERROR ResolverProxy::DiscoverOperationalNodes(DiscoveryFilter filter)
59+
{
60+
VerifyOrReturnError(mContext != nullptr, CHIP_ERROR_INCORRECT_STATE);
61+
62+
return mResolver.StartDiscovery(DiscoveryType::kOperational, filter, *mContext);
63+
}
64+
5865
CHIP_ERROR ResolverProxy::StopDiscovery()
5966
{
6067
VerifyOrReturnError(mContext != nullptr, CHIP_ERROR_INCORRECT_STATE);

src/lib/dnssd/ResolverProxy.h

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class ResolverProxy
5454

5555
CHIP_ERROR DiscoverCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter());
5656
CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter = DiscoveryFilter());
57+
CHIP_ERROR DiscoverOperationalNodes(DiscoveryFilter filter = DiscoveryFilter());
5758
CHIP_ERROR StopDiscovery();
5859

5960
private:

src/lib/dnssd/Resolver_ImplMinimalMdns.cpp

+29-8
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ void PacketParser::ParseSRVResource(const ResourceData & data)
213213
continue;
214214
}
215215

216-
CHIP_ERROR err = resolver.InitializeParsing(data.GetName(), srv);
216+
CHIP_ERROR err = resolver.InitializeParsing(data.GetName(), data.GetTtlSeconds(), srv);
217217
if (err != CHIP_NO_ERROR)
218218
{
219219
// Receiving records that we do not need to parse is normal:
@@ -363,14 +363,15 @@ void MinMdnsResolver::AdvancePendingResolverStates()
363363
{
364364
if (!resolver->IsActive())
365365
{
366+
ChipLogError(Discovery, "resolver inactive, continue to next");
366367
continue;
367368
}
368369

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

371372
if (missing.Has(IncrementalResolver::RequiredInformationBitFlags::kIpAddress))
372373
{
373-
if (resolver->IsActiveBrowseParse())
374+
if (resolver->IsActiveCommissionParse())
374375
{
375376
// Browse wants IP addresses
376377
ScheduleIpAddressResolve(resolver->GetTargetHostName());
@@ -399,7 +400,7 @@ void MinMdnsResolver::AdvancePendingResolverStates()
399400
}
400401

401402
// SUCCESS. Call the delegates
402-
if (resolver->IsActiveBrowseParse())
403+
if (resolver->IsActiveCommissionParse())
403404
{
404405
MATTER_TRACE_SCOPE("Active commissioning delegate call", "MinMdnsResolver");
405406
DiscoveredNodeData nodeData;
@@ -452,19 +453,39 @@ void MinMdnsResolver::AdvancePendingResolverStates()
452453
else if (resolver->IsActiveOperationalParse())
453454
{
454455
MATTER_TRACE_SCOPE("Active operational delegate call", "MinMdnsResolver");
455-
ResolvedNodeData nodeData;
456+
ResolvedNodeData nodeResolvedData;
457+
CHIP_ERROR err = resolver->Take(nodeResolvedData);
456458

457-
CHIP_ERROR err = resolver->Take(nodeData);
458459
if (err != CHIP_NO_ERROR)
459460
{
460-
ChipLogError(Discovery, "Failed to take discovery result: %" CHIP_ERROR_FORMAT, err.Format());
461+
ChipLogError(Discovery, "Failed to take NodeData - result: %" CHIP_ERROR_FORMAT, err.Format());
461462
continue;
462463
}
463464

464-
mActiveResolves.Complete(nodeData.operationalData.peerId);
465+
if (mActiveResolves.HasBrowseFor(chip::Dnssd::DiscoveryType::kOperational))
466+
{
467+
if (mDiscoveryContext != nullptr)
468+
{
469+
DiscoveredNodeData nodeData;
470+
OperationalNodeBrowseData opNodeData;
471+
472+
opNodeData.peerId = nodeResolvedData.operationalData.peerId;
473+
opNodeData.hasZeroTTL = nodeResolvedData.operationalData.hasZeroTTL;
474+
nodeData.Set<OperationalNodeBrowseData>(opNodeData);
475+
mDiscoveryContext->OnNodeDiscovered(nodeData);
476+
}
477+
else
478+
{
479+
#if CHIP_MINMDNS_HIGH_VERBOSITY
480+
ChipLogError(Discovery, "No delegate to report operational node discovery");
481+
#endif
482+
}
483+
}
484+
485+
mActiveResolves.Complete(nodeResolvedData.operationalData.peerId);
465486
if (mOperationalDelegate != nullptr)
466487
{
467-
mOperationalDelegate->OnOperationalNodeResolved(nodeData);
488+
mOperationalDelegate->OnOperationalNodeResolved(nodeResolvedData);
468489
}
469490
else
470491
{

src/lib/dnssd/Types.h

+15-3
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,21 @@ struct CommonResolutionData
197197
struct OperationalNodeData
198198
{
199199
PeerId peerId;
200-
200+
bool hasZeroTTL;
201201
void Reset() { peerId = PeerId(); }
202202
};
203203

204+
struct OperationalNodeBrowseData : public OperationalNodeData
205+
{
206+
OperationalNodeBrowseData() { Reset(); };
207+
void LogDetail() const
208+
{
209+
ChipLogDetail(Discovery, "Discovered Operational node:\r\n");
210+
ChipLogDetail(Discovery, "\tNode Instance: " ChipLogFormatPeerId, ChipLogValuePeerId(peerId));
211+
ChipLogDetail(Discovery, "\thasZeroTTL: %s\r\n", hasZeroTTL ? "true" : "false");
212+
}
213+
};
214+
204215
inline constexpr size_t kMaxDeviceNameLen = 32;
205216
inline constexpr size_t kMaxRotatingIdLen = 50;
206217
inline constexpr size_t kMaxPairingInstructionLen = 128;
@@ -297,12 +308,13 @@ struct ResolvedNodeData
297308
}
298309
};
299310

300-
using DiscoveredNodeData = Variant<CommissionNodeData>;
311+
using DiscoveredNodeData = Variant<CommissionNodeData, OperationalNodeBrowseData>;
301312

302-
/// Callbacks for discovering nodes advertising non-operational status:
313+
/// Callbacks for discovering nodes advertising both operational and non-operational status:
303314
/// - Commissioners
304315
/// - Nodes in commissioning modes over IP (e.g. ethernet devices, devices already
305316
/// connected to thread/wifi or devices with a commissioning window open)
317+
/// - Operational nodes
306318
class DiscoverNodeDelegate
307319
{
308320
public:

src/lib/dnssd/tests/TestIncrementalResolve.cpp

+14-12
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include <string.h>
2222

23+
#include <lib/dnssd/ServiceNaming.h>
2324
#include <lib/dnssd/minimal_mdns/core/tests/QNameStrings.h>
2425
#include <lib/dnssd/minimal_mdns/records/IP.h>
2526
#include <lib/dnssd/minimal_mdns/records/Ptr.h>
@@ -161,7 +162,7 @@ TEST(TestIncrementalResolve, TestCreation)
161162
IncrementalResolver resolver;
162163

163164
EXPECT_FALSE(resolver.IsActive());
164-
EXPECT_FALSE(resolver.IsActiveBrowseParse());
165+
EXPECT_FALSE(resolver.IsActiveCommissionParse());
165166
EXPECT_FALSE(resolver.IsActiveOperationalParse());
166167
EXPECT_TRUE(
167168
resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kSrvInitialization));
@@ -177,10 +178,10 @@ TEST(TestIncrementalResolve, TestInactiveResetOnInitError)
177178
PreloadSrvRecord(srvRecord);
178179

179180
// test host name is not a 'matter' name
180-
EXPECT_NE(resolver.InitializeParsing(kTestHostName.Serialized(), srvRecord), CHIP_NO_ERROR);
181+
EXPECT_NE(resolver.InitializeParsing(kTestHostName.Serialized(), 0, srvRecord), CHIP_NO_ERROR);
181182

182183
EXPECT_FALSE(resolver.IsActive());
183-
EXPECT_FALSE(resolver.IsActiveBrowseParse());
184+
EXPECT_FALSE(resolver.IsActiveCommissionParse());
184185
EXPECT_FALSE(resolver.IsActiveOperationalParse());
185186
}
186187

@@ -193,10 +194,10 @@ TEST(TestIncrementalResolve, TestStartOperational)
193194
SrvRecord srvRecord;
194195
PreloadSrvRecord(srvRecord);
195196

196-
EXPECT_EQ(resolver.InitializeParsing(kTestOperationalName.Serialized(), srvRecord), CHIP_NO_ERROR);
197+
EXPECT_EQ(resolver.InitializeParsing(kTestOperationalName.Serialized(), 1, srvRecord), CHIP_NO_ERROR);
197198

198199
EXPECT_TRUE(resolver.IsActive());
199-
EXPECT_FALSE(resolver.IsActiveBrowseParse());
200+
EXPECT_FALSE(resolver.IsActiveCommissionParse());
200201
EXPECT_TRUE(resolver.IsActiveOperationalParse());
201202
EXPECT_TRUE(resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress));
202203
EXPECT_EQ(resolver.GetTargetHostName(), kTestHostName.Serialized());
@@ -211,10 +212,10 @@ TEST(TestIncrementalResolve, TestStartCommissionable)
211212
SrvRecord srvRecord;
212213
PreloadSrvRecord(srvRecord);
213214

214-
EXPECT_EQ(resolver.InitializeParsing(kTestCommissionableNode.Serialized(), srvRecord), CHIP_NO_ERROR);
215+
EXPECT_EQ(resolver.InitializeParsing(kTestCommissionableNode.Serialized(), 0, srvRecord), CHIP_NO_ERROR);
215216

216217
EXPECT_TRUE(resolver.IsActive());
217-
EXPECT_TRUE(resolver.IsActiveBrowseParse());
218+
EXPECT_TRUE(resolver.IsActiveCommissionParse());
218219
EXPECT_FALSE(resolver.IsActiveOperationalParse());
219220
EXPECT_TRUE(resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress));
220221
EXPECT_EQ(resolver.GetTargetHostName(), kTestHostName.Serialized());
@@ -229,10 +230,10 @@ TEST(TestIncrementalResolve, TestStartCommissioner)
229230
SrvRecord srvRecord;
230231
PreloadSrvRecord(srvRecord);
231232

232-
EXPECT_EQ(resolver.InitializeParsing(kTestCommissionerNode.Serialized(), srvRecord), CHIP_NO_ERROR);
233+
EXPECT_EQ(resolver.InitializeParsing(kTestCommissionerNode.Serialized(), 0, srvRecord), CHIP_NO_ERROR);
233234

234235
EXPECT_TRUE(resolver.IsActive());
235-
EXPECT_TRUE(resolver.IsActiveBrowseParse());
236+
EXPECT_TRUE(resolver.IsActiveCommissionParse());
236237
EXPECT_FALSE(resolver.IsActiveOperationalParse());
237238
EXPECT_TRUE(resolver.GetMissingRequiredInformation().HasOnly(IncrementalResolver::RequiredInformationBitFlags::kIpAddress));
238239
EXPECT_EQ(resolver.GetTargetHostName(), kTestHostName.Serialized());
@@ -247,7 +248,7 @@ TEST(TestIncrementalResolve, TestParseOperational)
247248
SrvRecord srvRecord;
248249
PreloadSrvRecord(srvRecord);
249250

250-
EXPECT_EQ(resolver.InitializeParsing(kTestOperationalName.Serialized(), srvRecord), CHIP_NO_ERROR);
251+
EXPECT_EQ(resolver.InitializeParsing(kTestOperationalName.Serialized(), 1, srvRecord), CHIP_NO_ERROR);
251252

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

327-
EXPECT_EQ(resolver.InitializeParsing(kTestCommissionableNode.Serialized(), srvRecord), CHIP_NO_ERROR);
329+
EXPECT_EQ(resolver.InitializeParsing(kTestCommissionableNode.Serialized(), 0, srvRecord), CHIP_NO_ERROR);
328330

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

src/lib/shell/commands/Dns.cpp

+23-4
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,23 @@ class DnsShellResolverDelegate : public Dnssd::DiscoverNodeDelegate, public Addr
8383

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

86+
void LogOperationalNodeDiscovered(const Dnssd::OperationalNodeBrowseData & nodeData)
87+
{
88+
streamer_printf(streamer_get(), "DNS browse operational succeeded: \r\n");
89+
streamer_printf(streamer_get(), " Node Instance: " ChipLogFormatPeerId, ChipLogValuePeerId(nodeData.peerId));
90+
streamer_printf(streamer_get(), " hasZeroTTL: %s\r\n", nodeData.hasZeroTTL ? "true" : "false");
91+
}
92+
8693
void OnNodeDiscovered(const Dnssd::DiscoveredNodeData & discNodeData) override
8794
{
88-
if (!discNodeData.Is<Dnssd::CommissionNodeData>())
95+
if (discNodeData.Is<Dnssd::OperationalNodeBrowseData>())
8996
{
90-
streamer_printf(streamer_get(), "DNS browse failed - not commission type node \r\n");
97+
LogOperationalNodeDiscovered(discNodeData.Get<Dnssd::OperationalNodeBrowseData>());
9198
return;
9299
}
93100

94-
Dnssd::CommissionNodeData nodeData = discNodeData.Get<Dnssd::CommissionNodeData>();
101+
const auto & nodeData = discNodeData.Get<Dnssd::CommissionNodeData>();
102+
95103
if (!nodeData.IsValid())
96104
{
97105
streamer_printf(streamer_get(), "DNS browse failed - not found valid services \r\n");
@@ -237,6 +245,16 @@ CHIP_ERROR BrowseCommissionerHandler(int argc, char ** argv)
237245
return sResolverProxy.DiscoverCommissioners(filter);
238246
}
239247

248+
CHIP_ERROR BrowseOperationalHandler(int argc, char ** argv)
249+
{
250+
Dnssd::DiscoveryFilter filter;
251+
VerifyOrReturnError(ParseSubType(argc, argv, filter), CHIP_ERROR_INVALID_ARGUMENT);
252+
253+
streamer_printf(streamer_get(), "Browsing operational...\r\n");
254+
255+
return sResolverProxy.DiscoverOperationalNodes(filter);
256+
}
257+
240258
CHIP_ERROR BrowseHandler(int argc, char ** argv)
241259
{
242260
if (argc == 0)
@@ -271,13 +289,14 @@ void RegisterDnsCommands()
271289
"Browse Matter commissionable nodes. Usage: dns browse commissionable [subtype]" },
272290
{ &BrowseCommissionerHandler, "commissioner",
273291
"Browse Matter commissioner nodes. Usage: dns browse commissioner [subtype]" },
292+
{ &BrowseOperationalHandler, "operational", "Browse Matter operational nodes. Usage: dns browse operational" },
274293
};
275294

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

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

0 commit comments

Comments
 (0)