forked from project-chip/connectedhomeip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTestAdvertiser.cpp
608 lines (547 loc) · 32.5 KB
/
TestAdvertiser.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
/*
*
* 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.
*/
#include <app/icd/server/ICDServerConfig.h>
#include <lib/dnssd/Advertiser.h>
#include <string>
#include <utility>
#include <lib/dnssd/Advertiser.h>
#include <lib/dnssd/MinimalMdnsServer.h>
#include <lib/dnssd/minimal_mdns/Query.h>
#include <lib/dnssd/minimal_mdns/QueryBuilder.h>
#include <lib/dnssd/minimal_mdns/core/QName.h>
#include <lib/dnssd/minimal_mdns/records/Ptr.h>
#include <lib/dnssd/minimal_mdns/records/Srv.h>
#include <lib/dnssd/minimal_mdns/records/Txt.h>
#include <lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h>
#include <system/SystemPacketBuffer.h>
#include <transport/raw/tests/NetworkTestHelpers.h>
#include <gtest/gtest.h>
namespace {
using namespace std;
using namespace chip;
using namespace chip::Dnssd;
using namespace mdns::Minimal;
using namespace mdns::Minimal::test;
// Used for everything.
const QNamePart kDnsSdQueryParts[] = { "_services", "_dns-sd", "_udp", "local" };
const FullQName kDnsSdQueryName = FullQName(kDnsSdQueryParts);
constexpr size_t kMdnsMaxPacketSize = 512;
const uint8_t kMac[kMaxMacSize] = { 1, 2, 3, 4, 5, 6, 7, 8 };
const QNamePart kHostnameParts[] = { "0102030405060708", "local" };
const FullQName kHostnameName = FullQName(kHostnameParts);
// Operational records and queries.
const QNamePart kMatterOperationalQueryParts[3] = { "_matter", "_tcp", "local" };
const FullQName kMatterOperationalQueryName = FullQName(kMatterOperationalQueryParts);
const PeerId kPeerId1 = PeerId().SetCompressedFabricId(0xBEEFBEEFF00DF00D).SetNodeId(0x1111222233334444);
const PeerId kPeerId2 = PeerId().SetCompressedFabricId(0x5555666677778888).SetNodeId(0x1212343456567878);
const PeerId kPeerId3 = PeerId().SetCompressedFabricId(0x3333333333333333).SetNodeId(0x3333333333333333);
const PeerId kPeerId4 = PeerId().SetCompressedFabricId(0x4444444444444444).SetNodeId(0x4444444444444444);
const PeerId kPeerId5 = PeerId().SetCompressedFabricId(0x5555555555555555).SetNodeId(0x5555555555555555);
const PeerId kPeerId6 = PeerId().SetCompressedFabricId(0x6666666666666666).SetNodeId(0x6666666666666666);
const QNamePart kInstanceNameParts1[] = { "BEEFBEEFF00DF00D-1111222233334444", "_matter", "_tcp", "local" };
const FullQName kInstanceName1 = FullQName(kInstanceNameParts1);
const QNamePart kInstanceNameParts2[] = { "5555666677778888-1212343456567878", "_matter", "_tcp", "local" };
const FullQName kInstanceName2 = FullQName(kInstanceNameParts2);
const QNamePart kTxtRecordEmptyParts[] = { "=" };
const FullQName kTxtRecordEmptyName = FullQName(kTxtRecordEmptyParts);
const QNamePart kCompressedIdSubParts1[] = { "_IBEEFBEEFF00DF00D", "_sub", "_matter", "_tcp", "local" };
FullQName kCompressedIdSubName1 = FullQName(kCompressedIdSubParts1);
const QNamePart kCompressedIdSubParts2[] = { "_I5555666677778888", "_sub", "_matter", "_tcp", "local" };
FullQName kCompressedIdSubName2 = FullQName(kCompressedIdSubParts2);
PtrResourceRecord ptrServiceSubCompressedId1 = PtrResourceRecord(kDnsSdQueryName, kCompressedIdSubName1);
PtrResourceRecord ptrServiceSubCompressedId2 = PtrResourceRecord(kDnsSdQueryName, kCompressedIdSubName2);
OperationalAdvertisingParameters operationalParams1 =
OperationalAdvertisingParameters()
.SetPeerId(kPeerId1)
.SetMac(ByteSpan(kMac))
.SetPort(CHIP_PORT)
.EnableIpV4(true)
.SetLocalMRPConfig(std::make_optional<ReliableMessageProtocolConfig>(
32_ms32, 30_ms32)) // Match SII, SAI. SAT not provided so it uses default 4000ms
.SetTCPSupportModes(chip::Dnssd::TCPModeAdvertise::kTCPClientServer);
OperationalAdvertisingParameters operationalParams2 =
OperationalAdvertisingParameters().SetPeerId(kPeerId2).SetMac(ByteSpan(kMac)).SetPort(CHIP_PORT).EnableIpV4(true);
OperationalAdvertisingParameters operationalParams3 =
OperationalAdvertisingParameters().SetPeerId(kPeerId3).SetMac(ByteSpan(kMac)).SetPort(CHIP_PORT).EnableIpV4(true);
OperationalAdvertisingParameters operationalParams4 =
OperationalAdvertisingParameters().SetPeerId(kPeerId4).SetMac(ByteSpan(kMac)).SetPort(CHIP_PORT).EnableIpV4(true);
OperationalAdvertisingParameters operationalParams5 =
OperationalAdvertisingParameters().SetPeerId(kPeerId5).SetMac(ByteSpan(kMac)).SetPort(CHIP_PORT).EnableIpV4(true);
OperationalAdvertisingParameters operationalParams6 =
OperationalAdvertisingParameters().SetPeerId(kPeerId6).SetMac(ByteSpan(kMac)).SetPort(CHIP_PORT).EnableIpV4(true);
const QNamePart txtOperational1Parts[] = { "SII=32", "SAI=30", "SAT=4000", "T=6" };
PtrResourceRecord ptrOperationalService = PtrResourceRecord(kDnsSdQueryName, kMatterOperationalQueryName);
PtrResourceRecord ptrOperational1 = PtrResourceRecord(kMatterOperationalQueryName, kInstanceName1);
SrvResourceRecord srvOperational1 = SrvResourceRecord(kInstanceName1, kHostnameName, CHIP_PORT);
TxtResourceRecord txtOperational1 = TxtResourceRecord(kInstanceName1, txtOperational1Parts);
PtrResourceRecord ptrOperational2 = PtrResourceRecord(kMatterOperationalQueryName, kInstanceName2);
SrvResourceRecord srvOperational2 = SrvResourceRecord(kInstanceName2, kHostnameName, CHIP_PORT);
TxtResourceRecord txtOperational2 = TxtResourceRecord(kInstanceName2, kTxtRecordEmptyName);
// Commissionable node records and queries.
const QNamePart kMatterCommissionableNodeQueryParts[3] = { "_matterc", "_udp", "local" };
const QNamePart kLongSubPartsFullLen[] = { "_L4094", "_sub", "_matterc", "_udp", "local" };
const QNamePart kShortSubPartsFullLen[] = { "_S15", "_sub", "_matterc", "_udp", "local" };
const QNamePart kCmSubParts[] = { "_CM", "_sub", "_matterc", "_udp", "local" };
const QNamePart kLongSubParts[] = { "_L22", "_sub", "_matterc", "_udp", "local" };
const QNamePart kShortSubParts[] = { "_S2", "_sub", "_matterc", "_udp", "local" };
const QNamePart kVendorSubParts[] = { "_V555", "_sub", "_matterc", "_udp", "local" };
const QNamePart kDeviceTypeSubParts[] = { "_T70000", "_sub", "_matterc", "_udp", "local" };
const FullQName kMatterCommissionableNodeQueryName = FullQName(kMatterCommissionableNodeQueryParts);
FullQName kLongSubFullLenName = FullQName(kLongSubPartsFullLen);
FullQName kShortSubFullLenName = FullQName(kShortSubPartsFullLen);
FullQName kCmSubName = FullQName(kCmSubParts);
FullQName kLongSubName = FullQName(kLongSubParts);
FullQName kShortSubName = FullQName(kShortSubParts);
FullQName kVendorSubName = FullQName(kVendorSubParts);
FullQName kDeviceTypeSubName = FullQName(kDeviceTypeSubParts);
PtrResourceRecord ptrCommissionableNodeService = PtrResourceRecord(kDnsSdQueryName, kMatterCommissionableNodeQueryName);
PtrResourceRecord ptrServiceSubLFullLen = PtrResourceRecord(kDnsSdQueryName, kLongSubFullLenName);
PtrResourceRecord ptrServiceSubSFullLen = PtrResourceRecord(kDnsSdQueryName, kShortSubFullLenName);
PtrResourceRecord ptrServiceSubCM = PtrResourceRecord(kDnsSdQueryName, kCmSubName);
PtrResourceRecord ptrServiceSubLong = PtrResourceRecord(kDnsSdQueryName, kLongSubName);
PtrResourceRecord ptrServiceSubShort = PtrResourceRecord(kDnsSdQueryName, kShortSubName);
PtrResourceRecord ptrServiceSubVendor = PtrResourceRecord(kDnsSdQueryName, kVendorSubName);
PtrResourceRecord ptrServiceSubDeviceType = PtrResourceRecord(kDnsSdQueryName, kDeviceTypeSubName);
// For commissioning, the instance name is chosen randomly by the advertiser, so we have to get this value from it. We can, however,
// pre-populate the records with the ptr.
char instanceNamePrefix[17];
QNamePart instanceNameParts[] = { instanceNamePrefix, "_matterc", "_udp", "local" };
FullQName instanceName = FullQName(instanceNameParts);
PtrResourceRecord ptrCommissionableNode = PtrResourceRecord(kMatterCommissionableNodeQueryName, instanceName);
SrvResourceRecord srvCommissionableNode = SrvResourceRecord(instanceName, kHostnameName, CHIP_PORT);
CommissionAdvertisingParameters commissionableNodeParamsSmall =
CommissionAdvertisingParameters()
.SetCommissionAdvertiseMode(CommssionAdvertiseMode::kCommissionableNode)
.SetMac(ByteSpan(kMac))
.SetLongDiscriminator(0xFFE)
.SetShortDiscriminator(0xF)
.SetCommissioningMode(CommissioningMode::kDisabled);
const QNamePart txtCommissionableNodeParamsSmallParts[] = { "CM=0", "D=4094" };
FullQName txtCommissionableNodeParamsSmallName = FullQName(txtCommissionableNodeParamsSmallParts);
TxtResourceRecord txtCommissionableNodeParamsSmall = TxtResourceRecord(instanceName, txtCommissionableNodeParamsSmallName);
CommissionAdvertisingParameters commissionableNodeParamsLargeBasic =
CommissionAdvertisingParameters()
.SetCommissionAdvertiseMode(CommssionAdvertiseMode::kCommissionableNode)
.SetMac(ByteSpan(kMac, sizeof(kMac)))
.SetLongDiscriminator(22)
.SetShortDiscriminator(2)
.SetVendorId(std::make_optional<uint16_t>(555))
.SetDeviceType(std::make_optional<uint32_t>(70000))
.SetCommissioningMode(CommissioningMode::kEnabledBasic)
.SetDeviceName(std::make_optional<const char *>("testy-test"))
.SetPairingHint(std::make_optional<uint16_t>(3))
.SetPairingInstruction(std::make_optional<const char *>("Pair me"))
.SetProductId(std::make_optional<uint16_t>(897))
.SetRotatingDeviceId(std::make_optional<const char *>("id_that_spins"));
QNamePart txtCommissionableNodeParamsLargeBasicParts[] = { "D=22", "VP=555+897", "CM=1", "DT=70000",
"DN=testy-test", "RI=id_that_spins", "PI=Pair me", "PH=3" };
FullQName txtCommissionableNodeParamsLargeBasicName = FullQName(txtCommissionableNodeParamsLargeBasicParts);
TxtResourceRecord txtCommissionableNodeParamsLargeBasic =
TxtResourceRecord(instanceName, txtCommissionableNodeParamsLargeBasicName);
CommissionAdvertisingParameters commissionableNodeParamsLargeEnhanced =
CommissionAdvertisingParameters()
.SetCommissionAdvertiseMode(CommssionAdvertiseMode::kCommissionableNode)
.SetMac(ByteSpan(kMac, sizeof(kMac)))
.SetLongDiscriminator(22)
.SetShortDiscriminator(2)
.SetVendorId(std::make_optional<uint16_t>(555))
.SetDeviceType(std::make_optional<uint32_t>(70000))
.SetCommissioningMode(CommissioningMode::kEnabledEnhanced)
.SetDeviceName(std::make_optional<const char *>("testy-test"))
.SetPairingHint(std::make_optional<uint16_t>(3))
.SetPairingInstruction(std::make_optional<const char *>("Pair me"))
.SetProductId(std::make_optional<uint16_t>(897))
.SetRotatingDeviceId(std::make_optional<const char *>("id_that_spins"))
.SetICDModeToAdvertise(ICDModeAdvertise::kSIT)
// 3600005 is more than the max so should be adjusted down
.SetLocalMRPConfig(std::make_optional<ReliableMessageProtocolConfig>(3600000_ms32, 3600005_ms32, 65535_ms16));
QNamePart txtCommissionableNodeParamsLargeEnhancedParts[] = { "D=22", "VP=555+897", "CM=2", "DT=70000",
"DN=testy-test", "RI=id_that_spins", "PI=Pair me", "PH=3",
"SAI=3600000", "SII=3600000", "SAT=65535", "ICD=0" };
FullQName txtCommissionableNodeParamsLargeEnhancedName = FullQName(txtCommissionableNodeParamsLargeEnhancedParts);
TxtResourceRecord txtCommissionableNodeParamsLargeEnhanced =
TxtResourceRecord(instanceName, txtCommissionableNodeParamsLargeEnhancedName);
#if CHIP_CONFIG_ENABLE_ICD_SERVER
CommissionAdvertisingParameters commissionableNodeParamsEnhancedAsICDLIT =
CommissionAdvertisingParameters()
.SetCommissionAdvertiseMode(CommssionAdvertiseMode::kCommissionableNode)
.SetMac(ByteSpan(kMac, sizeof(kMac)))
.SetLongDiscriminator(22)
.SetShortDiscriminator(2)
.SetVendorId(std::make_optional<uint16_t>(555))
.SetDeviceType(std::make_optional<uint32_t>(70000))
.SetCommissioningMode(CommissioningMode::kEnabledEnhanced)
.SetDeviceName(std::make_optional<const char *>("testy-test"))
.SetPairingHint(std::make_optional<uint16_t>(3))
.SetPairingInstruction(std::make_optional<const char *>("Pair me"))
.SetProductId(std::make_optional<uint16_t>(897))
.SetICDModeToAdvertise(ICDModeAdvertise::kLIT)
.SetLocalMRPConfig(std::make_optional<ReliableMessageProtocolConfig>(3600000_ms32, 3600000_ms32, 65535_ms16));
// With ICD Operation as LIT, SII key will not be added to the advertisement
QNamePart txtCommissionableNodeParamsEnhancedAsICDLITParts[] = { "D=22", "VP=555+897", "CM=2", "DT=70000",
"DN=testy-test", "PI=Pair me", "PH=3", "SAI=3600000",
"SAT=65535", "ICD=1" };
FullQName txtCommissionableNodeParamsEnhancedAsICDLITName = FullQName(txtCommissionableNodeParamsEnhancedAsICDLITParts);
TxtResourceRecord txtCommissionableNodeParamsEnhancedAsICDLIT =
TxtResourceRecord(instanceName, txtCommissionableNodeParamsEnhancedAsICDLITName);
#endif
// Our server doesn't do anything with this, blank is fine.
Inet::IPPacketInfo packetInfo;
CHIP_ERROR SendQuery(FullQName qname)
{
System::PacketBufferHandle queryBuffer = System::PacketBufferHandle::New(kMdnsMaxPacketSize);
if (queryBuffer.IsNull())
{
return CHIP_ERROR_NO_MEMORY;
}
QueryBuilder queryBuilder(std::move(queryBuffer));
queryBuilder.Header().SetMessageId(0);
Query query = Query(qname).SetClass(QClass::IN).SetType(QType::ANY);
queryBuilder.AddQuery(query);
queryBuffer = queryBuilder.ReleasePacket();
// Send the query to the advertiser directly.
BytesRange range = BytesRange(queryBuffer->Start(), queryBuffer->Start() + queryBuffer->DataLength());
GlobalMinimalMdnsServer::Instance().OnQuery(range, &packetInfo);
return CHIP_NO_ERROR;
}
class TestAdvertiser : public ::testing::Test
{
public:
static chip::Test::IOContext context;
static CheckOnlyServer server;
static chip::Dnssd::ServiceAdvertiser * mdnsAdvertiser;
static void SetUpTestSuite()
{
chip::Platform::MemoryInit();
context.Init();
chip::Dnssd::GlobalMinimalMdnsServer::Instance().Server().Shutdown();
chip::Dnssd::GlobalMinimalMdnsServer::Instance().SetReplacementServer(&server);
mdnsAdvertiser = &chip::Dnssd::ServiceAdvertiser::Instance();
mdnsAdvertiser->Init(context.GetUDPEndPointManager());
}
static void TearDownTestSuite()
{
server.Shutdown();
context.Shutdown();
mdnsAdvertiser->RemoveServices();
mdnsAdvertiser->Shutdown();
chip::Dnssd::GlobalMinimalMdnsServer::Instance().SetReplacementServer(nullptr);
chip::Platform::MemoryShutdown();
}
};
chip::Test::IOContext TestAdvertiser::context;
CheckOnlyServer TestAdvertiser::server;
chip::Dnssd::ServiceAdvertiser * TestAdvertiser::mdnsAdvertiser;
TEST_F(TestAdvertiser, OperationalAdverts)
{
EXPECT_EQ(mdnsAdvertiser->RemoveServices(), CHIP_NO_ERROR);
server.Reset();
// Start a single operational advertiser
ChipLogProgress(Discovery, "Testing single operational advertiser");
EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams1), CHIP_NO_ERROR);
EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR);
// Test for PTR response to _services request.
ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local");
server.AddExpectedRecord(&ptrOperationalService);
server.AddExpectedRecord(&ptrServiceSubCompressedId1);
EXPECT_EQ(SendQuery(kDnsSdQueryName), CHIP_NO_ERROR);
// These check that the requested records added are sent out correctly.
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
// Want PTR response to _matter.tcp. We will also get the SRV and TXT as additionals.
// We won't get any A/AAAA because this is a test and we don't have addresses.
ChipLogProgress(Discovery, "Testing response to _matter._tcp.local");
server.Reset();
// For now, we don't check TXT records content, just that they exist. Operational currently
// sends a TXT record regardless of content being present or not.
server.AddExpectedRecord(&ptrOperational1);
server.AddExpectedRecord(&srvOperational1);
server.AddExpectedRecord(&txtOperational1);
EXPECT_EQ(SendQuery(kMatterOperationalQueryName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
ChipLogProgress(Discovery, "Testing response to instance name");
server.Reset();
// Just the SRV and TXT should return
server.AddExpectedRecord(&srvOperational1);
server.AddExpectedRecord(&txtOperational1);
EXPECT_EQ(SendQuery(kInstanceName1), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
// If we try to re-advertise with the same operational parameters, we should not get duplicates
EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams1), CHIP_NO_ERROR);
EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR);
ChipLogProgress(Discovery, "Testing single operational advertiser with Advertise called twice");
// We should get a single PTR back for _services
ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local");
server.Reset();
server.AddExpectedRecord(&ptrOperationalService);
server.AddExpectedRecord(&ptrServiceSubCompressedId1);
EXPECT_EQ(SendQuery(kDnsSdQueryName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
// Same records should come back for _matter._tcp.local queries.
ChipLogProgress(Discovery, "Testing response to _matter._tcp.local");
server.Reset();
server.AddExpectedRecord(&ptrOperational1);
server.AddExpectedRecord(&srvOperational1);
server.AddExpectedRecord(&txtOperational1);
EXPECT_EQ(SendQuery(kMatterOperationalQueryName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
// Adding a second operational advertiser.
ChipLogProgress(Discovery, "Adding a second operational Advertiser");
server.Reset();
// Mac is the same, peer id is different
EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams2), CHIP_NO_ERROR);
EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR);
// For now, we'll get back two copies of the PTR. Not sure if that's totally correct, but for now, that's expected.
ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local");
server.AddExpectedRecord(&ptrOperationalService);
server.AddExpectedRecord(&ptrOperationalService);
server.AddExpectedRecord(&ptrServiceSubCompressedId1);
server.AddExpectedRecord(&ptrServiceSubCompressedId2);
EXPECT_EQ(SendQuery(kDnsSdQueryName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
// Requests for _matter._tcp.local will respond with all records from both parameter sets
ChipLogProgress(Discovery, "Testing response to _matter._tcp.local");
server.Reset();
server.AddExpectedRecord(&ptrOperational1);
server.AddExpectedRecord(&srvOperational1);
server.AddExpectedRecord(&txtOperational1);
server.AddExpectedRecord(&ptrOperational2);
server.AddExpectedRecord(&srvOperational2);
server.AddExpectedRecord(&txtOperational2);
EXPECT_EQ(SendQuery(kMatterOperationalQueryName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
// Requests for each SRV record should give only records specific to that fabric.
ChipLogProgress(Discovery, "Testing response to instance name for fabric 1");
server.Reset();
// Just the SRV and TXT should return
server.AddExpectedRecord(&srvOperational1);
server.AddExpectedRecord(&txtOperational1);
EXPECT_EQ(SendQuery(kInstanceName1), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
ChipLogProgress(Discovery, "Testing response to instance name for fabric 2");
server.Reset();
// Just the SRV and TXT should return
server.AddExpectedRecord(&srvOperational2);
server.AddExpectedRecord(&txtOperational2);
EXPECT_EQ(SendQuery(kInstanceName2), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
// All devices should support at least 5 operational network additions (spec min)
// however larger devices may support more.
EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams3), CHIP_NO_ERROR);
EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams4), CHIP_NO_ERROR);
EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams5), CHIP_NO_ERROR);
}
TEST_F(TestAdvertiser, CommissionableAdverts)
{
EXPECT_EQ(mdnsAdvertiser->RemoveServices(), CHIP_NO_ERROR);
server.Reset();
// Start a single operational advertiser
ChipLogProgress(Discovery, "Testing commissionable advertiser");
// Start very basic - only the mandatory values (short and long discriminator and commissioning modes)
EXPECT_EQ(mdnsAdvertiser->Advertise(commissionableNodeParamsSmall), CHIP_NO_ERROR);
EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR);
// Test for PTR response to _services request.
ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local for small parameters");
server.AddExpectedRecord(&ptrCommissionableNodeService);
server.AddExpectedRecord(&ptrServiceSubLFullLen);
server.AddExpectedRecord(&ptrServiceSubSFullLen);
EXPECT_EQ(SendQuery(kDnsSdQueryName), CHIP_NO_ERROR);
// These check that the requested records added are sent out correctly.
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
// Want PTR response to _matterc._udp. We will also get the SRV and TXT as additionals.
// We won't get any A/AAAA because this is a test and we don't have addresses.
// First fill in the instance name - FullQNames already have this space included.
EXPECT_EQ(mdnsAdvertiser->GetCommissionableInstanceName(instanceNamePrefix, sizeof(instanceNamePrefix)), CHIP_NO_ERROR);
ChipLogProgress(Discovery, "Testing response to _matterc._udp.local for small parameters");
server.Reset();
server.AddExpectedRecord(&ptrCommissionableNode);
server.AddExpectedRecord(&srvCommissionableNode);
server.AddExpectedRecord(&txtCommissionableNodeParamsSmall);
EXPECT_EQ(SendQuery(kMatterCommissionableNodeQueryName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
ChipLogProgress(Discovery, "Testing response to instance name for small parameters");
server.Reset();
// Just the SRV and TXT should return
server.AddExpectedRecord(&srvCommissionableNode);
server.AddExpectedRecord(&txtCommissionableNodeParamsSmall);
EXPECT_EQ(SendQuery(instanceName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
// Add more parameters, check that the subtypes and TXT values get set correctly.
// Also check that we get proper values when the discriminators are small (no leading 0's)
EXPECT_EQ(mdnsAdvertiser->Advertise(commissionableNodeParamsLargeBasic), CHIP_NO_ERROR);
EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR);
ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local for large basic parameters");
server.Reset();
server.AddExpectedRecord(&ptrCommissionableNodeService);
server.AddExpectedRecord(&ptrServiceSubLong);
server.AddExpectedRecord(&ptrServiceSubShort);
server.AddExpectedRecord(&ptrServiceSubCM);
server.AddExpectedRecord(&ptrServiceSubVendor);
server.AddExpectedRecord(&ptrServiceSubDeviceType);
EXPECT_EQ(SendQuery(kDnsSdQueryName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
ChipLogProgress(Discovery, "Testing response to _matterc._udp.local for large basic parameters");
server.Reset();
server.AddExpectedRecord(&ptrCommissionableNode);
server.AddExpectedRecord(&srvCommissionableNode);
server.AddExpectedRecord(&txtCommissionableNodeParamsLargeBasic);
EXPECT_EQ(SendQuery(kMatterCommissionableNodeQueryName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
ChipLogProgress(Discovery, "Testing response to instance name for large basic parameters");
server.Reset();
// Just the SRV and TXT should return
server.AddExpectedRecord(&srvCommissionableNode);
server.AddExpectedRecord(&txtCommissionableNodeParamsLargeBasic);
EXPECT_EQ(SendQuery(instanceName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
EXPECT_EQ(mdnsAdvertiser->Advertise(commissionableNodeParamsLargeEnhanced), CHIP_NO_ERROR);
EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR);
ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local for large enhanced parameters");
server.Reset();
server.AddExpectedRecord(&ptrCommissionableNodeService);
server.AddExpectedRecord(&ptrServiceSubLong);
server.AddExpectedRecord(&ptrServiceSubShort);
server.AddExpectedRecord(&ptrServiceSubCM);
server.AddExpectedRecord(&ptrServiceSubVendor);
server.AddExpectedRecord(&ptrServiceSubDeviceType);
EXPECT_EQ(SendQuery(kDnsSdQueryName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
ChipLogProgress(Discovery, "Testing response to _matterc._udp.local for large enhanced parameters");
server.Reset();
server.AddExpectedRecord(&ptrCommissionableNode);
server.AddExpectedRecord(&srvCommissionableNode);
server.AddExpectedRecord(&txtCommissionableNodeParamsLargeEnhanced);
EXPECT_EQ(SendQuery(kMatterCommissionableNodeQueryName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
ChipLogProgress(Discovery, "Testing response to instance name for large enhanced parameters");
server.Reset();
// Just the SRV and TXT should return
server.AddExpectedRecord(&srvCommissionableNode);
server.AddExpectedRecord(&txtCommissionableNodeParamsLargeEnhanced);
EXPECT_EQ(SendQuery(instanceName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
#if CHIP_CONFIG_ENABLE_ICD_SERVER
EXPECT_EQ(mdnsAdvertiser->Advertise(commissionableNodeParamsEnhancedAsICDLIT), CHIP_NO_ERROR);
EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR);
ChipLogProgress(Discovery, "Testing response to _matterc._udp.local for enhanced parameters With ICD as LIT");
server.Reset();
server.AddExpectedRecord(&ptrCommissionableNode);
server.AddExpectedRecord(&srvCommissionableNode);
server.AddExpectedRecord(&txtCommissionableNodeParamsEnhancedAsICDLIT);
EXPECT_EQ(SendQuery(kMatterCommissionableNodeQueryName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
ChipLogProgress(Discovery, "Testing response to instance name for enhanced parameters With ICD as LIT");
server.Reset();
// Just the SRV and TXT should return
server.AddExpectedRecord(&srvCommissionableNode);
server.AddExpectedRecord(&txtCommissionableNodeParamsEnhancedAsICDLIT);
EXPECT_EQ(SendQuery(instanceName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
#endif
}
TEST_F(TestAdvertiser, CommissionableAndOperationalAdverts)
{
EXPECT_EQ(mdnsAdvertiser->RemoveServices(), CHIP_NO_ERROR);
server.Reset();
// Add two operational and a commissionable and test that we get the correct values back.
EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams1), CHIP_NO_ERROR);
EXPECT_EQ(mdnsAdvertiser->Advertise(operationalParams2), CHIP_NO_ERROR);
EXPECT_EQ(mdnsAdvertiser->Advertise(commissionableNodeParamsLargeEnhanced), CHIP_NO_ERROR);
EXPECT_EQ(mdnsAdvertiser->FinalizeServiceUpdate(), CHIP_NO_ERROR);
// Services listing should have two operational ptrs, the base commissionable node ptr and the various _sub ptrs
ChipLogProgress(Discovery, "Checking response to _services._dns-sd._udp.local");
server.Reset();
server.AddExpectedRecord(&ptrOperationalService);
server.AddExpectedRecord(&ptrOperationalService);
server.AddExpectedRecord(&ptrCommissionableNodeService);
server.AddExpectedRecord(&ptrServiceSubLong);
server.AddExpectedRecord(&ptrServiceSubShort);
server.AddExpectedRecord(&ptrServiceSubCM);
server.AddExpectedRecord(&ptrServiceSubVendor);
server.AddExpectedRecord(&ptrServiceSubDeviceType);
server.AddExpectedRecord(&ptrServiceSubCompressedId1);
server.AddExpectedRecord(&ptrServiceSubCompressedId2);
EXPECT_EQ(SendQuery(kDnsSdQueryName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
// Requests for _matter._tcp.local will respond with all records from both operational records, but no commissionable.
ChipLogProgress(Discovery, "Testing response to _matter._tcp.local");
server.Reset();
server.AddExpectedRecord(&ptrOperational1);
server.AddExpectedRecord(&srvOperational1);
server.AddExpectedRecord(&txtOperational1);
server.AddExpectedRecord(&ptrOperational2);
server.AddExpectedRecord(&srvOperational2);
server.AddExpectedRecord(&txtOperational2);
EXPECT_EQ(SendQuery(kMatterOperationalQueryName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
// Responses to _matterc query should return commissionable node, but no operational.
ChipLogProgress(Discovery, "Testing response to _matterc._udp.local");
server.Reset();
server.AddExpectedRecord(&ptrCommissionableNode);
server.AddExpectedRecord(&srvCommissionableNode);
server.AddExpectedRecord(&txtCommissionableNodeParamsLargeEnhanced);
EXPECT_EQ(SendQuery(kMatterCommissionableNodeQueryName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
// Requests for each SRV record should give only records specific to that fabric.
ChipLogProgress(Discovery, "Testing response to operational instance name for fabric 1");
server.Reset();
// Just the SRV and TXT should return
server.AddExpectedRecord(&srvOperational1);
server.AddExpectedRecord(&txtOperational1);
EXPECT_EQ(SendQuery(kInstanceName1), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
ChipLogProgress(Discovery, "Testing response to operational instance name for fabric 2");
server.Reset();
// Just the SRV and TXT should return
server.AddExpectedRecord(&srvOperational2);
server.AddExpectedRecord(&txtOperational2);
EXPECT_EQ(SendQuery(kInstanceName2), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
ChipLogProgress(Discovery, "Testing response to commissionable instance name");
server.Reset();
// Just the SRV and TXT should return
server.AddExpectedRecord(&srvCommissionableNode);
server.AddExpectedRecord(&txtCommissionableNodeParamsLargeEnhanced);
EXPECT_EQ(SendQuery(instanceName), CHIP_NO_ERROR);
EXPECT_TRUE(server.GetSendCalled());
EXPECT_TRUE(server.GetHeaderFound());
}
} // namespace