21
21
22
22
#include " lib/dnssd/platform/Dnssd.h"
23
23
#include " platform/CHIPDeviceLayer.h"
24
+ #include " platform/ConnectivityManager.h"
24
25
#include " platform/PlatformManager.h"
26
+ #include < lib/dnssd/minimal_mdns/AddressPolicy.h>
27
+ #include < lib/dnssd/minimal_mdns/AddressPolicy_DefaultImpl.h>
28
+ #include < lib/dnssd/minimal_mdns/Parser.h>
29
+ #include < lib/dnssd/minimal_mdns/RecordData.h>
30
+ #include < lib/dnssd/minimal_mdns/ResponseSender.h>
31
+ #include < lib/dnssd/minimal_mdns/Server.h>
32
+ #include < lib/dnssd/minimal_mdns/responders/IP.h>
33
+ #include < lib/dnssd/minimal_mdns/responders/Ptr.h>
34
+ #include < lib/dnssd/minimal_mdns/responders/Srv.h>
35
+ #include < lib/dnssd/minimal_mdns/responders/Txt.h>
25
36
#include < lib/support/CHIPMem.h>
26
37
#include < lib/support/UnitTestRegistration.h>
27
38
@@ -44,6 +55,35 @@ struct DnssdContext
44
55
bool mEndOfInput = false ;
45
56
};
46
57
58
+ class TestDnssdResolveServerDelegate : public mdns ::Minimal::ServerDelegate, public mdns::Minimal::ParserDelegate
59
+ {
60
+ public:
61
+ TestDnssdResolveServerDelegate (mdns::Minimal::ResponseSender * responder) : mResponder (responder) {}
62
+ virtual ~TestDnssdResolveServerDelegate () = default ;
63
+
64
+ // Implementation of mdns::Minimal::ServerDelegate
65
+
66
+ void OnResponse (const mdns::Minimal::BytesRange & data, const chip::Inet::IPPacketInfo * info) override {}
67
+ void OnQuery (const mdns::Minimal::BytesRange & data, const chip::Inet::IPPacketInfo * info) override
68
+ {
69
+ mCurSrc = info;
70
+ mdns::Minimal::ParsePacket (data, this );
71
+ mCurSrc = nullptr ;
72
+ }
73
+
74
+ // Implementation of mdns::Minimal::ParserDelegate
75
+
76
+ void OnHeader (mdns::Minimal::ConstHeaderRef & header) override { mMsgId = header.GetMessageId (); }
77
+ void OnQuery (const mdns::Minimal::QueryData & data) override { mResponder ->Respond (mMsgId , data, mCurSrc , mRespConfig ); }
78
+ void OnResource (mdns::Minimal::ResourceType type, const mdns::Minimal::ResourceData & data) override {}
79
+
80
+ private:
81
+ mdns::Minimal::ResponseSender * mResponder ;
82
+ mdns::Minimal::ResponseConfiguration mRespConfig ;
83
+ const chip::Inet::IPPacketInfo * mCurSrc = nullptr ;
84
+ uint16_t mMsgId = 0 ;
85
+ };
86
+
47
87
} // namespace
48
88
49
89
static void Timeout (chip::System::Layer * systemLayer, void * context)
@@ -64,6 +104,10 @@ static void HandleResolve(void * context, DnssdService * result, const chip::Spa
64
104
NL_TEST_ASSERT (suite, result != nullptr );
65
105
NL_TEST_ASSERT (suite, error == CHIP_NO_ERROR);
66
106
107
+ // The NL_TEST_ASSERT above will not abort the test, so we need to
108
+ // explicitly abort it here to avoid dereferencing a null pointer.
109
+ VerifyOrReturn (result != nullptr , );
110
+
67
111
if (!addresses.empty ())
68
112
{
69
113
addresses.data ()[0 ].ToString (addrBuf, sizeof (addrBuf));
@@ -122,13 +166,96 @@ static void DnssdErrorCallback(void * context, CHIP_ERROR error)
122
166
NL_TEST_ASSERT (ctx->mTestSuite , error == CHIP_NO_ERROR);
123
167
}
124
168
169
+ void TestDnssdBrowse_DnssdInitCallback (void * context, CHIP_ERROR error)
170
+ {
171
+ auto * ctx = static_cast <DnssdContext *>(context);
172
+ NL_TEST_ASSERT (ctx->mTestSuite , error == CHIP_NO_ERROR);
173
+ auto * suite = ctx->mTestSuite ;
174
+
175
+ NL_TEST_ASSERT (suite,
176
+ ChipDnssdBrowse (" _mock" , DnssdServiceProtocol::kDnssdProtocolUdp , chip::Inet::IPAddressType::kAny ,
177
+ chip::Inet::InterfaceId::Null (), HandleBrowse, context,
178
+ &ctx->mBrowseIdentifier ) == CHIP_NO_ERROR);
179
+ }
180
+
181
+ // Verify that platform DNS-SD implementation can browse and resolve services.
182
+ //
183
+ // This test case uses platform-independent mDNS server implementation based on
184
+ // minimal mdns library. The server is configured to respond to PTR, SRV, TXT,
185
+ // A and AAAA queries without additional records. In order to pass this test,
186
+ // the platform DNS-SD client implementation must be able to browse and resolve
187
+ // services by querying for all of these records separately.
188
+ void TestDnssdBrowse (nlTestSuite * inSuite, void * inContext)
189
+ {
190
+ DnssdContext context;
191
+ context.mTestSuite = inSuite;
192
+
193
+ mdns::Minimal::SetDefaultAddressPolicy ();
194
+
195
+ mdns::Minimal::Server<10 > server;
196
+ mdns::Minimal::QNamePart serverName[] = { " resolve-tester" , " _mock" , chip::Dnssd::kCommissionProtocol ,
197
+ chip::Dnssd::kLocalDomain };
198
+ mdns::Minimal::ResponseSender responseSender (&server);
199
+
200
+ mdns::Minimal::QueryResponder<16 > queryResponder;
201
+ responseSender.AddQueryResponder (&queryResponder);
202
+
203
+ // Respond to PTR queries for _mock._udp.local
204
+ mdns::Minimal::QNamePart serviceName[] = { " _mock" , chip::Dnssd::kCommissionProtocol , chip::Dnssd::kLocalDomain };
205
+ mdns::Minimal::QNamePart serverServiceName[] = { " INSTANCE" , chip::Dnssd::kCommissionableServiceName ,
206
+ chip::Dnssd::kCommissionProtocol , chip::Dnssd::kLocalDomain };
207
+ mdns::Minimal::PtrResponder ptrUdpResponder (serviceName, serverServiceName);
208
+ queryResponder.AddResponder (&ptrUdpResponder);
209
+
210
+ // Respond to SRV queries for INSTANCE._matterc._udp.local
211
+ mdns::Minimal::SrvResponder srvResponder (mdns::Minimal::SrvResourceRecord (serverServiceName, serverName, CHIP_PORT));
212
+ queryResponder.AddResponder (&srvResponder);
213
+
214
+ // Respond to TXT queries for INSTANCE._matterc._udp.local
215
+ const char * txtEntries[] = { " key=val" };
216
+ mdns::Minimal::TxtResponder txtResponder (mdns::Minimal::TxtResourceRecord (serverServiceName, txtEntries));
217
+ queryResponder.AddResponder (&txtResponder);
218
+
219
+ // Respond to A queries
220
+ mdns::Minimal::IPv4Responder ipv4Responder (serverName);
221
+ queryResponder.AddResponder (&ipv4Responder);
222
+
223
+ // Respond to AAAA queries
224
+ mdns::Minimal::IPv6Responder ipv6Responder (serverName);
225
+ queryResponder.AddResponder (&ipv6Responder);
226
+
227
+ TestDnssdResolveServerDelegate delegate (&responseSender);
228
+ server.SetDelegate (&delegate);
229
+
230
+ auto endpoints = mdns::Minimal::GetAddressPolicy ()->GetListenEndpoints ();
231
+ NL_TEST_ASSERT (inSuite, server.Listen (chip::DeviceLayer::UDPEndPointManager (), endpoints.get (), 5353 ) == CHIP_NO_ERROR);
232
+
233
+ NL_TEST_ASSERT (inSuite,
234
+ chip::Dnssd::ChipDnssdInit (TestDnssdBrowse_DnssdInitCallback, DnssdErrorCallback, &context) == CHIP_NO_ERROR);
235
+ NL_TEST_ASSERT (inSuite,
236
+ chip::DeviceLayer::SystemLayer ().StartTimer (chip::System::Clock::Seconds32 (5 ), Timeout, &context) ==
237
+ CHIP_NO_ERROR);
238
+
239
+ ChipLogProgress (DeviceLayer, " Start EventLoop" );
240
+ chip::DeviceLayer::PlatformMgr ().RunEventLoop ();
241
+ ChipLogProgress (DeviceLayer, " End EventLoop" );
242
+
243
+ NL_TEST_ASSERT (inSuite, context.mResolvedServicesCount > 0 );
244
+ NL_TEST_ASSERT (inSuite, !context.mTimeoutExpired );
245
+
246
+ // Stop browsing so we can safely shutdown DNS-SD
247
+ chip::Dnssd::ChipDnssdStopBrowse (context.mBrowseIdentifier );
248
+
249
+ chip::Dnssd::ChipDnssdShutdown ();
250
+ }
251
+
125
252
static void HandlePublish (void * context, const char * type, const char * instanceName, CHIP_ERROR error)
126
253
{
127
254
auto * ctx = static_cast <DnssdContext *>(context);
128
255
NL_TEST_ASSERT (ctx->mTestSuite , error == CHIP_NO_ERROR);
129
256
}
130
257
131
- static void TestDnssdPubSub_DnssdInitCallback (void * context, CHIP_ERROR error)
258
+ static void TestDnssdPublishService_DnssdInitCallback (void * context, CHIP_ERROR error)
132
259
{
133
260
auto * ctx = static_cast <DnssdContext *>(context);
134
261
NL_TEST_ASSERT (ctx->mTestSuite , error == CHIP_NO_ERROR);
@@ -157,13 +284,19 @@ static void TestDnssdPubSub_DnssdInitCallback(void * context, CHIP_ERROR error)
157
284
&ctx->mBrowseIdentifier ) == CHIP_NO_ERROR);
158
285
}
159
286
160
- void TestDnssdPubSub (nlTestSuite * inSuite, void * inContext)
287
+ // Verify that the platform DNS-SD implementation can publish services.
288
+ //
289
+ // This test uses platform implementation of DNS-SD server and client. Since
290
+ // client implementation should be verified by the TestDnssdBrowse test case,
291
+ // here we only verify that the server implementation can publish services.
292
+ void TestDnssdPublishService (nlTestSuite * inSuite, void * inContext)
161
293
{
162
294
DnssdContext context;
163
295
context.mTestSuite = inSuite;
164
296
165
297
NL_TEST_ASSERT (inSuite,
166
- chip::Dnssd::ChipDnssdInit (TestDnssdPubSub_DnssdInitCallback, DnssdErrorCallback, &context) == CHIP_NO_ERROR);
298
+ chip::Dnssd::ChipDnssdInit (TestDnssdPublishService_DnssdInitCallback, DnssdErrorCallback, &context) ==
299
+ CHIP_NO_ERROR);
167
300
NL_TEST_ASSERT (inSuite,
168
301
chip::DeviceLayer::SystemLayer ().StartTimer (chip::System::Clock::Seconds32 (5 ), Timeout, &context) ==
169
302
CHIP_NO_ERROR);
@@ -172,6 +305,7 @@ void TestDnssdPubSub(nlTestSuite * inSuite, void * inContext)
172
305
chip::DeviceLayer::PlatformMgr ().RunEventLoop ();
173
306
ChipLogProgress (DeviceLayer, " End EventLoop" );
174
307
308
+ NL_TEST_ASSERT (inSuite, context.mResolvedServicesCount > 0 );
175
309
NL_TEST_ASSERT (inSuite, !context.mTimeoutExpired );
176
310
177
311
// Stop browsing so we can safely shutdown DNS-SD
@@ -180,7 +314,11 @@ void TestDnssdPubSub(nlTestSuite * inSuite, void * inContext)
180
314
chip::Dnssd::ChipDnssdShutdown ();
181
315
}
182
316
183
- static const nlTest sTests [] = { NL_TEST_DEF (" Test Dnssd::PubSub" , TestDnssdPubSub), NL_TEST_SENTINEL () };
317
+ static const nlTest sTests [] = {
318
+ NL_TEST_DEF (" Test ChipDnssdBrowse" , TestDnssdBrowse),
319
+ NL_TEST_DEF (" Test ChipDnssdPublishService" , TestDnssdPublishService),
320
+ NL_TEST_SENTINEL (),
321
+ };
184
322
185
323
int TestDnssd_Setup (void * inContext)
186
324
{
0 commit comments