1 /*
2 * Copyright (c) 2017, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <openthread/config.h>
30
31 #include "common/array.hpp"
32 #include "common/code_utils.hpp"
33 #include "instance/instance.hpp"
34 #include "thread/network_data_leader.hpp"
35 #include "thread/network_data_local.hpp"
36 #include "thread/network_data_service.hpp"
37
38 #include "test_platform.h"
39 #include "test_util.hpp"
40
41 namespace ot {
42 namespace NetworkData {
43
PrintExternalRouteConfig(const ExternalRouteConfig & aConfig)44 void PrintExternalRouteConfig(const ExternalRouteConfig &aConfig)
45 {
46 printf("\nroute-prefix:");
47
48 for (uint8_t b : aConfig.mPrefix.mPrefix.mFields.m8)
49 {
50 printf("%02x", b);
51 }
52
53 printf(", length:%d, rloc16:%04x, preference:%d, nat64:%d, stable:%d, nexthop:%d", aConfig.mPrefix.mLength,
54 aConfig.mRloc16, aConfig.mPreference, aConfig.mNat64, aConfig.mStable, aConfig.mNextHopIsThisDevice);
55 }
56
PrintOnMeshPrefixConfig(const OnMeshPrefixConfig & aConfig)57 void PrintOnMeshPrefixConfig(const OnMeshPrefixConfig &aConfig)
58 {
59 printf("\non-mesh-prefix:");
60
61 for (uint8_t b : aConfig.mPrefix.mPrefix.mFields.m8)
62 {
63 printf("%02x", b);
64 }
65
66 printf(", length:%d, rloc16:%04x, preference:%d, stable:%d, def-route:%d", aConfig.mPrefix.mLength, aConfig.mRloc16,
67 aConfig.mPreference, aConfig.mStable, aConfig.mDefaultRoute);
68 }
69
70 // Returns true if the two given ExternalRouteConfig match (intentionally ignoring mNextHopIsThisDevice).
CompareExternalRouteConfig(const otExternalRouteConfig & aConfig1,const otExternalRouteConfig & aConfig2)71 bool CompareExternalRouteConfig(const otExternalRouteConfig &aConfig1, const otExternalRouteConfig &aConfig2)
72 {
73 return (memcmp(aConfig1.mPrefix.mPrefix.mFields.m8, aConfig2.mPrefix.mPrefix.mFields.m8,
74 sizeof(aConfig1.mPrefix.mPrefix)) == 0) &&
75 (aConfig1.mPrefix.mLength == aConfig2.mPrefix.mLength) && (aConfig1.mRloc16 == aConfig2.mRloc16) &&
76 (aConfig1.mPreference == aConfig2.mPreference) && (aConfig1.mStable == aConfig2.mStable);
77 }
78
79 // Returns true if the two given OnMeshprefix match.
CompareOnMeshPrefixConfig(const otBorderRouterConfig & aConfig1,const otBorderRouterConfig & aConfig2)80 bool CompareOnMeshPrefixConfig(const otBorderRouterConfig &aConfig1, const otBorderRouterConfig &aConfig2)
81 {
82 return (memcmp(aConfig1.mPrefix.mPrefix.mFields.m8, aConfig2.mPrefix.mPrefix.mFields.m8,
83 sizeof(aConfig1.mPrefix.mPrefix)) == 0) &&
84 (aConfig1.mPrefix.mLength == aConfig2.mPrefix.mLength) && (aConfig1.mRloc16 == aConfig2.mRloc16) &&
85 (aConfig1.mPreference == aConfig2.mPreference) && (aConfig1.mStable == aConfig2.mStable) &&
86 (aConfig1.mDefaultRoute == aConfig2.mDefaultRoute) && (aConfig1.mOnMesh == aConfig2.mOnMesh);
87 }
88
VerifyRlocsArray(const Rlocs & aRlocs,const uint16_t (& aExpectedRlocs)[kLength])89 template <uint8_t kLength> void VerifyRlocsArray(const Rlocs &aRlocs, const uint16_t (&aExpectedRlocs)[kLength])
90 {
91 VerifyOrQuit(aRlocs.GetLength() == kLength);
92
93 printf("\nRLOCs: { ");
94
95 for (uint16_t rloc : aRlocs)
96 {
97 printf("0x%04x ", rloc);
98 }
99
100 printf("}");
101
102 for (uint16_t index = 0; index < kLength; index++)
103 {
104 VerifyOrQuit(aRlocs.Contains(aExpectedRlocs[index]));
105 }
106 }
107
TestNetworkDataIterator(void)108 void TestNetworkDataIterator(void)
109 {
110 Instance *instance;
111 Iterator iter = kIteratorInit;
112 ExternalRouteConfig rconfig;
113 OnMeshPrefixConfig pconfig;
114 Rlocs rlocs;
115
116 instance = testInitInstance();
117 VerifyOrQuit(instance != nullptr);
118
119 {
120 const uint8_t kNetworkData[] = {
121 0x08, 0x04, 0x0B, 0x02, 0x00, 0x00, 0x03, 0x14, 0x00, 0x40, 0xFD, 0x00, 0x12, 0x34,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC8, 0x00, 0x40, 0x01, 0x03, 0x54, 0x00, 0x00,
123 };
124
125 otExternalRouteConfig routes[] = {
126 {
127 {
128 {{{0xfd, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00}}},
130 64,
131 },
132 0xc800, // mRloc16
133 1, // mPreference
134 false, // mNat64
135 false, // mStable
136 false, // mNextHopIsThisDevice
137 false, // mAdvPio
138 },
139 {
140 {
141 {{{0xfd, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00}}},
143 64,
144 },
145 0x5400, // mRloc16
146 0, // mPreference
147 false, // mNat64
148 true, // mStable
149 false, // mNextHopIsThisDevice
150 false, // mAdvPio
151 },
152 };
153
154 const uint16_t kRlocs[] = {0xc800, 0x5400};
155 const uint16_t kNonExistingRlocs[] = {0xc700, 0x0000, 0x5401};
156
157 NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData));
158
159 iter = OT_NETWORK_DATA_ITERATOR_INIT;
160
161 printf("\nTest #1: Network data 1");
162 printf("\n-------------------------------------------------");
163
164 for (const auto &route : routes)
165 {
166 SuccessOrQuit(netData.GetNextExternalRoute(iter, rconfig));
167 PrintExternalRouteConfig(rconfig);
168 VerifyOrQuit(CompareExternalRouteConfig(rconfig, route));
169 }
170
171 netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
172 VerifyRlocsArray(rlocs, kRlocs);
173
174 netData.FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
175 VerifyRlocsArray(rlocs, kRlocs);
176
177 netData.FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
178 VerifyOrQuit(rlocs.GetLength() == 0);
179
180 netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
181 VerifyRlocsArray(rlocs, kRlocs);
182 VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kRlocs));
183
184 netData.FindRlocs(kBrProvidingExternalIpConn, kRouterRoleOnly, rlocs);
185 VerifyRlocsArray(rlocs, kRlocs);
186 VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kRlocs));
187
188 netData.FindRlocs(kBrProvidingExternalIpConn, kChildRoleOnly, rlocs);
189 VerifyOrQuit(rlocs.GetLength() == 0);
190 VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == 0);
191
192 for (uint16_t rloc16 : kRlocs)
193 {
194 VerifyOrQuit(netData.ContainsBorderRouterWithRloc(rloc16));
195 }
196
197 for (uint16_t rloc16 : kNonExistingRlocs)
198 {
199 VerifyOrQuit(!netData.ContainsBorderRouterWithRloc(rloc16));
200 }
201 }
202
203 {
204 const uint8_t kNetworkData[] = {
205 0x08, 0x04, 0x0B, 0x02, 0x00, 0x00, 0x03, 0x1E, 0x00, 0x40, 0xFD, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00,
206 0x07, 0x02, 0x11, 0x40, 0x00, 0x03, 0x10, 0x00, 0x40, 0x01, 0x03, 0x54, 0x00, 0x00, 0x05, 0x04, 0x54, 0x00,
207 0x31, 0x00, 0x02, 0x0F, 0x00, 0x40, 0xFD, 0x00, 0xAB, 0xBA, 0xCD, 0xDC, 0x00, 0x00, 0x00, 0x03, 0x10, 0x00,
208 0x20, 0x03, 0x0E, 0x00, 0x20, 0xFD, 0x00, 0xAB, 0xBA, 0x01, 0x06, 0x54, 0x00, 0x00, 0x04, 0x01, 0x00,
209 };
210
211 otExternalRouteConfig routes[] = {
212 {
213 {
214 {{{0xfd, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215 0x00}}},
216 64,
217 },
218 0x1000, // mRloc16
219 1, // mPreference
220 false, // mNat64
221 false, // mStable
222 false, // mNextHopIsThisDevice
223 },
224 {
225 {
226 {{{0xfd, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227 0x00}}},
228 64,
229 },
230 0x5400, // mRloc16
231 0, // mPreference
232 false, // mNat64
233 true, // mStable
234 false, // mNextHopIsThisDevice
235 },
236 {
237 {
238 {{{0xfd, 0x00, 0xab, 0xba, 0xcd, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x00}}},
240 64,
241 },
242 0x1000, // mRloc16
243 0, // mPreference
244 true, // mNat64
245 false, // mStable
246 false, // mNextHopIsThisDevice
247 },
248 {
249 {
250 {{{0xfd, 0x00, 0xab, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251 0x00}}},
252 32,
253 },
254 0x5400, // mRloc16
255 0, // mPreference
256 false, // mNat64
257 true, // mStable
258 false, // mNextHopIsThisDevice
259 },
260 {
261 {
262 {{{0xfd, 0x00, 0xab, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
263 0x00}}},
264 32,
265 },
266 0x0401, // mRloc16
267 0, // mPreference
268 false, // mNat64
269 true, // mStable
270 false, // mNextHopIsThisDevice
271 },
272 };
273
274 const uint16_t kRlocsAnyRole[] = {0x1000, 0x5400, 0x0401};
275 const uint16_t kRlocsRouterRole[] = {0x1000, 0x5400};
276 const uint16_t kRlocsChildRole[] = {0x0401};
277 const uint16_t kNonExistingRlocs[] = {0x6000, 0x0000, 0x0402};
278
279 NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData));
280
281 iter = OT_NETWORK_DATA_ITERATOR_INIT;
282
283 printf("\nTest #2: Network data 2");
284 printf("\n-------------------------------------------------");
285
286 for (const auto &route : routes)
287 {
288 SuccessOrQuit(netData.GetNextExternalRoute(iter, rconfig));
289 PrintExternalRouteConfig(rconfig);
290 VerifyOrQuit(CompareExternalRouteConfig(rconfig, route));
291 }
292
293 netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
294 VerifyRlocsArray(rlocs, kRlocsAnyRole);
295
296 netData.FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
297 VerifyRlocsArray(rlocs, kRlocsRouterRole);
298
299 netData.FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
300 VerifyRlocsArray(rlocs, kRlocsChildRole);
301
302 netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
303 VerifyRlocsArray(rlocs, kRlocsAnyRole);
304 VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kRlocsAnyRole));
305
306 netData.FindRlocs(kBrProvidingExternalIpConn, kRouterRoleOnly, rlocs);
307 VerifyRlocsArray(rlocs, kRlocsRouterRole);
308 VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kRlocsRouterRole));
309
310 netData.FindRlocs(kBrProvidingExternalIpConn, kChildRoleOnly, rlocs);
311 VerifyRlocsArray(rlocs, kRlocsChildRole);
312 VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == GetArrayLength(kRlocsChildRole));
313
314 netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
315 VerifyRlocsArray(rlocs, kRlocsAnyRole);
316
317 for (uint16_t rloc16 : kRlocsAnyRole)
318 {
319 VerifyOrQuit(netData.ContainsBorderRouterWithRloc(rloc16));
320 }
321
322 for (uint16_t rloc16 : kNonExistingRlocs)
323 {
324 VerifyOrQuit(!netData.ContainsBorderRouterWithRloc(rloc16));
325 }
326 }
327
328 {
329 const uint8_t kNetworkData[] = {
330 0x08, 0x04, 0x0b, 0x02, 0x36, 0xcc, 0x03, 0x1c, 0x00, 0x40, 0xfd, 0x00, 0xbe, 0xef, 0xca, 0xfe,
331 0x00, 0x00, 0x05, 0x0c, 0x28, 0x00, 0x33, 0x00, 0x28, 0x01, 0x33, 0x00, 0x4c, 0x00, 0x31, 0x00,
332 0x07, 0x02, 0x11, 0x40, 0x03, 0x14, 0x00, 0x40, 0xfd, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
333 0x05, 0x04, 0x28, 0x00, 0x73, 0x00, 0x07, 0x02, 0x12, 0x40, 0x03, 0x12, 0x00, 0x40, 0xfd, 0x00,
334 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0xec, 0x00, 0x00, 0x28, 0x01, 0xc0,
335 };
336
337 otExternalRouteConfig routes[] = {
338 {
339 {
340 {{{0xfd, 0x00, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00}}},
342 64,
343 },
344 0xec00, // mRloc16
345 0, // mPreference
346 false, // mNat64
347 true, // mStable
348 false, // mNextHopIsThisDevice
349 },
350 {
351 {
352 {{{0xfd, 0x00, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353 0x00}}},
354 64,
355 },
356 0x2801, // mRloc16
357 -1, // mPreference
358 false, // mNat64
359 true, // mStable
360 false, // mNextHopIsThisDevice
361 },
362 };
363
364 otBorderRouterConfig prefixes[] = {
365 {
366 {
367 {{{0xfd, 0x00, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x00}}},
369 64,
370 },
371 0, // mPreference
372 true, // mPreferred
373 true, // mSlaac
374 false, // mDhcp
375 true, // mConfigure
376 true, // mDefaultRoute
377 true, // mOnMesh
378 true, // mStable
379 false, // mNdDns
380 false, // mDp
381 0x2800, // mRloc16
382 },
383 {
384 {
385 {{{0xfd, 0x00, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386 0x00}}},
387 64,
388 },
389 0, // mPreference
390 true, // mPreferred
391 true, // mSlaac
392 false, // mDhcp
393 true, // mConfigure
394 true, // mDefaultRoute
395 true, // mOnMesh
396 true, // mStable
397 false, // mNdDns
398 false, // mDp
399 0x2801, // mRloc16
400 },
401 {
402 {
403 {{{0xfd, 0x00, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404 0x00}}},
405 64,
406 },
407 0, // mPreference
408 true, // mPreferred
409 true, // mSlaac
410 false, // mDhcp
411 true, // mConfigure
412 false, // mDefaultRoute
413 true, // mOnMesh
414 true, // mStable
415 false, // mNdDns
416 false, // mDp
417 0x4c00, // mRloc16
418 },
419 {
420 {
421 {{{0xfd, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422 0x00}}},
423 64,
424 },
425 1, // mPreference
426 true, // mPreferred
427 true, // mSlaac
428 false, // mDhcp
429 true, // mConfigure
430 true, // mDefaultRoute
431 true, // mOnMesh
432 true, // mStable
433 false, // mNdDns
434 false, // mDp
435 0x2800, // mRloc16
436 },
437 };
438
439 const uint16_t kRlocsAnyRole[] = {0xec00, 0x2801, 0x2800, 0x4c00};
440 const uint16_t kRlocsRouterRole[] = {0xec00, 0x2800, 0x4c00};
441 const uint16_t kRlocsChildRole[] = {0x2801};
442 const uint16_t kBrRlocsAnyRole[] = {0xec00, 0x2801, 0x2800};
443 const uint16_t kBrRlocsRouterRole[] = {0xec00, 0x2800};
444 const uint16_t kBrRlocsChildRole[] = {0x2801};
445 const uint16_t kNonExistingRlocs[] = {0x6000, 0x0000, 0x2806, 0x4c00};
446
447 NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData));
448
449 printf("\nTest #3: Network data 3");
450 printf("\n-------------------------------------------------");
451
452 iter = OT_NETWORK_DATA_ITERATOR_INIT;
453
454 for (const auto &route : routes)
455 {
456 SuccessOrQuit(netData.GetNextExternalRoute(iter, rconfig));
457 PrintExternalRouteConfig(rconfig);
458 VerifyOrQuit(CompareExternalRouteConfig(rconfig, route));
459 }
460
461 iter = OT_NETWORK_DATA_ITERATOR_INIT;
462
463 for (const auto &prefix : prefixes)
464 {
465 SuccessOrQuit(netData.GetNextOnMeshPrefix(iter, pconfig));
466 PrintOnMeshPrefixConfig(pconfig);
467 VerifyOrQuit(CompareOnMeshPrefixConfig(pconfig, prefix));
468 }
469
470 netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
471 VerifyRlocsArray(rlocs, kRlocsAnyRole);
472
473 netData.FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
474 VerifyRlocsArray(rlocs, kRlocsRouterRole);
475
476 netData.FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
477 VerifyRlocsArray(rlocs, kRlocsChildRole);
478
479 netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
480 VerifyRlocsArray(rlocs, kBrRlocsAnyRole);
481 VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kBrRlocsAnyRole));
482
483 netData.FindRlocs(kBrProvidingExternalIpConn, kRouterRoleOnly, rlocs);
484 VerifyRlocsArray(rlocs, kBrRlocsRouterRole);
485 VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kBrRlocsRouterRole));
486
487 netData.FindRlocs(kBrProvidingExternalIpConn, kChildRoleOnly, rlocs);
488 VerifyRlocsArray(rlocs, kBrRlocsChildRole);
489 VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == GetArrayLength(kBrRlocsChildRole));
490
491 for (uint16_t rloc16 : kBrRlocsAnyRole)
492 {
493 VerifyOrQuit(netData.ContainsBorderRouterWithRloc(rloc16));
494 }
495
496 for (uint16_t rloc16 : kNonExistingRlocs)
497 {
498 VerifyOrQuit(!netData.ContainsBorderRouterWithRloc(rloc16));
499 }
500 }
501
502 testFreeInstance(instance);
503 }
504
505 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
506
507 class TestNetworkData : public Local
508 {
509 public:
TestNetworkData(Instance & aInstance)510 explicit TestNetworkData(Instance &aInstance)
511 : Local(aInstance)
512 {
513 }
514
AddService(const ServiceData & aServiceData)515 Error AddService(const ServiceData &aServiceData)
516 {
517 return Local::AddService(ServiceTlv::kThreadEnterpriseNumber, aServiceData, true, ServerData());
518 }
519
ValidateServiceData(const ServiceTlv * aServiceTlv,const ServiceData & aServiceData) const520 Error ValidateServiceData(const ServiceTlv *aServiceTlv, const ServiceData &aServiceData) const
521 {
522 Error error = kErrorFailed;
523 ServiceData serviceData;
524
525 VerifyOrExit(aServiceTlv != nullptr);
526 aServiceTlv->GetServiceData(serviceData);
527
528 VerifyOrExit(aServiceData == serviceData);
529 error = kErrorNone;
530
531 exit:
532 return error;
533 }
534
Test(void)535 void Test(void)
536 {
537 const uint8_t kServiceData1[] = {0x02};
538 const uint8_t kServiceData2[] = {0xab};
539 const uint8_t kServiceData3[] = {0xab, 0x00};
540 const uint8_t kServiceData4[] = {0x02, 0xab, 0xcd, 0xef};
541 const uint8_t kServiceData5[] = {0x02, 0xab, 0xcd};
542
543 const ServiceTlv *tlv;
544 ServiceData serviceData1;
545 ServiceData serviceData2;
546 ServiceData serviceData3;
547 ServiceData serviceData4;
548 ServiceData serviceData5;
549
550 serviceData1.InitFrom(kServiceData1);
551 serviceData2.InitFrom(kServiceData2);
552 serviceData3.InitFrom(kServiceData3);
553 serviceData4.InitFrom(kServiceData4);
554 serviceData5.InitFrom(kServiceData5);
555
556 SuccessOrQuit(AddService(serviceData1));
557 SuccessOrQuit(AddService(serviceData2));
558 SuccessOrQuit(AddService(serviceData3));
559 SuccessOrQuit(AddService(serviceData4));
560 SuccessOrQuit(AddService(serviceData5));
561
562 DumpBuffer("netdata", GetBytes(), GetLength());
563
564 // Iterate through all entries that start with { 0x02 } (kServiceData1)
565 tlv = nullptr;
566 tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
567 SuccessOrQuit(ValidateServiceData(tlv, serviceData1));
568 tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
569 SuccessOrQuit(ValidateServiceData(tlv, serviceData4));
570 tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
571 SuccessOrQuit(ValidateServiceData(tlv, serviceData5));
572 tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
573 VerifyOrQuit(tlv == nullptr, "FindNextService() returned extra TLV");
574
575 // Iterate through all entries that start with { 0xab } (serviceData2)
576 tlv = nullptr;
577 tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData2, kServicePrefixMatch);
578 SuccessOrQuit(ValidateServiceData(tlv, serviceData2));
579 tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData2, kServicePrefixMatch);
580 SuccessOrQuit(ValidateServiceData(tlv, serviceData3));
581 tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData2, kServicePrefixMatch);
582 VerifyOrQuit(tlv == nullptr, "FindNextService() returned extra TLV");
583
584 // Iterate through all entries that start with serviceData5
585 tlv = nullptr;
586 tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData5, kServicePrefixMatch);
587 SuccessOrQuit(ValidateServiceData(tlv, serviceData4));
588 tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData5, kServicePrefixMatch);
589 SuccessOrQuit(ValidateServiceData(tlv, serviceData5));
590 tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData5, kServicePrefixMatch);
591 VerifyOrQuit(tlv == nullptr, "FindNextService() returned extra TLV");
592 }
593 };
594
TestNetworkDataFindNextService(void)595 void TestNetworkDataFindNextService(void)
596 {
597 Instance *instance;
598
599 printf("\n\n-------------------------------------------------");
600 printf("\nTestNetworkDataFindNextService()\n");
601
602 instance = testInitInstance();
603 VerifyOrQuit(instance != nullptr);
604
605 {
606 TestNetworkData netData(*instance);
607 netData.Test();
608 }
609 }
610
611 #endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
612
TestNetworkDataDsnSrpServices(void)613 void TestNetworkDataDsnSrpServices(void)
614 {
615 static const char *kOriginStrings[] = {
616 "service-data", // (0) Service::DnsSrpUnicast::kFromServiceData
617 "server-data", // (1) Service::DnsSrpUnicast::kFromServerData
618 };
619
620 class TestLeader : public Leader
621 {
622 public:
623 void Populate(const uint8_t *aTlvs, uint8_t aTlvsLength)
624 {
625 memcpy(GetBytes(), aTlvs, aTlvsLength);
626 SetLength(aTlvsLength);
627 }
628 };
629
630 Instance *instance;
631
632 printf("\n\n-------------------------------------------------");
633 printf("\nTestNetworkDataDsnSrpServices()\n");
634
635 instance = testInitInstance();
636 VerifyOrQuit(instance != nullptr);
637
638 {
639 struct AnycastEntry
640 {
641 uint16_t mAloc16;
642 uint8_t mSequenceNumber;
643
644 bool Matches(Service::DnsSrpAnycast::Info aInfo) const
645 {
646 VerifyOrQuit(aInfo.mAnycastAddress.GetIid().IsAnycastServiceLocator());
647
648 return (aInfo.mAnycastAddress.GetIid().GetLocator() == mAloc16) &&
649 (aInfo.mSequenceNumber == mSequenceNumber);
650 }
651 };
652
653 struct UnicastEntry
654 {
655 const char *mAddress;
656 uint16_t mPort;
657 Service::DnsSrpUnicast::Origin mOrigin;
658 uint16_t mRloc16;
659
660 bool Matches(Service::DnsSrpUnicast::Info aInfo) const
661 {
662 Ip6::SockAddr sockAddr;
663
664 SuccessOrQuit(sockAddr.GetAddress().FromString(mAddress));
665 sockAddr.SetPort(mPort);
666
667 return (aInfo.mSockAddr == sockAddr) && (aInfo.mOrigin == mOrigin) && (aInfo.mRloc16 == mRloc16);
668 }
669 };
670
671 const uint8_t kNetworkData[] = {
672 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x28, 0x00, 0x0b, 0x08, 0x81, 0x02, 0x5c, 0xff, 0x0d, 0x02,
673 0x6c, 0x00, 0x0b, 0x09, 0x82, 0x02, 0x5c, 0x03, 0x0d, 0x03, 0x4c, 0x00, 0xaa, 0x0b, 0x35, 0x83, 0x13, 0x5d,
674 0xfd, 0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0x00, 0x2d, 0x0e, 0xc6, 0x27, 0x55, 0x56, 0x18, 0xd9, 0x12, 0x34,
675 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x14, 0x6c, 0x00, 0xfd, 0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11,
676 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0xab, 0xcd, 0x0d, 0x04, 0x28, 0x00, 0x56, 0x78, 0x0b, 0x23, 0x84, 0x01,
677 0x5d, 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x14, 0x4c, 0x00, 0xfd, 0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde,
678 0xf0, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0x00, 0x0e, 0x0d, 0x04, 0x6c, 0x00, 0xcd, 0x12,
679 };
680
681 const AnycastEntry kAnycastEntries[] = {
682 {0xfc10, 0x02},
683 {0xfc11, 0xff},
684 {0xfc12, 0x03},
685 };
686
687 const UnicastEntry kUnicastEntries[] = {
688 {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, Service::DnsSrpUnicast::kFromServiceData, 0xfffe},
689 {"fd00:aabb:ccdd:eeff:11:2233:4455:6677", 0xabcd, Service::DnsSrpUnicast::kFromServerData, 0x6c00},
690 {"fdde:ad00:beef:0:0:ff:fe00:2800", 0x5678, Service::DnsSrpUnicast::kFromServerData, 0x2800},
691 {"fd00:1234:5678:9abc:def0:123:4567:89ab", 0x0e, Service::DnsSrpUnicast::kFromServerData, 0x4c00},
692 {"fdde:ad00:beef:0:0:ff:fe00:6c00", 0xcd12, Service::DnsSrpUnicast::kFromServerData, 0x6c00},
693 };
694
695 const uint16_t kExpectedRlocs[] = {0x6c00, 0x2800, 0x4c00, 0x0000};
696
697 const uint8_t kPreferredAnycastEntryIndex = 2;
698
699 Service::Manager &manager = instance->Get<Service::Manager>();
700 Service::Manager::Iterator iterator;
701 Service::DnsSrpAnycast::Info anycastInfo;
702 Service::DnsSrpUnicast::Info unicastInfo;
703 Rlocs rlocs;
704
705 reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(kNetworkData, sizeof(kNetworkData));
706
707 DumpBuffer("netdata", kNetworkData, sizeof(kNetworkData));
708
709 // Verify `FindRlocs()`
710
711 instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
712 VerifyRlocsArray(rlocs, kExpectedRlocs);
713
714 instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
715 VerifyRlocsArray(rlocs, kExpectedRlocs);
716
717 instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
718 VerifyOrQuit(rlocs.GetLength() == 0);
719
720 instance->Get<Leader>().FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
721 VerifyOrQuit(rlocs.GetLength() == 0);
722
723 // Verify all the "DNS/SRP Anycast Service" entries in Network Data
724
725 printf("\n- - - - - - - - - - - - - - - - - - - -");
726 printf("\nDNS/SRP Anycast Service entries\n");
727
728 for (const AnycastEntry &entry : kAnycastEntries)
729 {
730 SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo));
731
732 printf("\nanycastInfo { %s, seq:%d }", anycastInfo.mAnycastAddress.ToString().AsCString(),
733 anycastInfo.mSequenceNumber);
734
735 VerifyOrQuit(entry.Matches(anycastInfo), "GetNextDnsSrpAnycastInfo() returned incorrect info");
736 }
737
738 VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound,
739 "GetNextDnsSrpAnycastInfo() returned unexpected extra entry");
740
741 // Find the preferred "DNS/SRP Anycast Service" entries in Network Data
742
743 SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo));
744
745 printf("\n\nPreferred anycastInfo { %s, seq:%d }", anycastInfo.mAnycastAddress.ToString().AsCString(),
746 anycastInfo.mSequenceNumber);
747
748 VerifyOrQuit(kAnycastEntries[kPreferredAnycastEntryIndex].Matches(anycastInfo),
749 "FindPreferredDnsSrpAnycastInfo() returned invalid info");
750
751 printf("\n\n- - - - - - - - - - - - - - - - - - - -");
752 printf("\nDNS/SRP Unicast Service entries\n");
753
754 iterator.Clear();
755
756 for (const UnicastEntry &entry : kUnicastEntries)
757 {
758 SuccessOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, unicastInfo));
759 printf("\nunicastInfo { %s, origin:%s, rloc16:%04x }", unicastInfo.mSockAddr.ToString().AsCString(),
760 kOriginStrings[unicastInfo.mOrigin], unicastInfo.mRloc16);
761
762 VerifyOrQuit(entry.Matches(unicastInfo), "GetNextDnsSrpUnicastInfo() returned incorrect info");
763 }
764
765 VerifyOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, unicastInfo) == kErrorNotFound,
766 "GetNextDnsSrpUnicastInfo() returned unexpected extra entry");
767
768 printf("\n");
769 }
770
771 testFreeInstance(instance);
772 }
773
TestNetworkDataDsnSrpAnycastSeqNumSelection(void)774 void TestNetworkDataDsnSrpAnycastSeqNumSelection(void)
775 {
776 class TestLeader : public Leader
777 {
778 public:
779 void Populate(const uint8_t *aTlvs, uint8_t aTlvsLength)
780 {
781 memcpy(GetBytes(), aTlvs, aTlvsLength);
782 SetLength(aTlvsLength);
783 }
784 };
785
786 struct TestInfo
787 {
788 const uint8_t *mNetworkData;
789 uint8_t mNetworkDataLength;
790 const uint8_t *mSeqNumbers;
791 uint8_t mSeqNumbersLength;
792 uint8_t mPreferredSeqNum;
793 };
794
795 Instance *instance;
796
797 printf("\n\n-------------------------------------------------");
798 printf("\nTestNetworkDataDsnSrpAnycastSeqNumSelection()\n");
799
800 instance = testInitInstance();
801 VerifyOrQuit(instance != nullptr);
802
803 const uint8_t kNetworkData1[] = {
804 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
805 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
806 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x81, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
807 };
808 const uint8_t kSeqNumbers1[] = {1, 129};
809 const uint8_t kPreferredSeqNum1 = 129;
810
811 const uint8_t kNetworkData2[] = {
812 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
813 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x85, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
814 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x05, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
815 };
816 const uint8_t kSeqNumbers2[] = {133, 5};
817 const uint8_t kPreferredSeqNum2 = 133;
818
819 const uint8_t kNetworkData3[] = {
820 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
821 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
822 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
823 0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
824 };
825 const uint8_t kSeqNumbers3[] = {1, 2, 255};
826 const uint8_t kPreferredSeqNum3 = 2;
827
828 const uint8_t kNetworkData4[] = {
829 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
830 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
831 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
832 0x0b, 0x08, 0x82, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
833 };
834 const uint8_t kSeqNumbers4[] = {10, 130, 250};
835 const uint8_t kPreferredSeqNum4 = 250;
836
837 const uint8_t kNetworkData5[] = {
838 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
839 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
840 0x0b, 0x08, 0x81, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
841 0x0b, 0x08, 0x82, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
842 };
843 const uint8_t kSeqNumbers5[] = {130, 250, 10};
844 const uint8_t kPreferredSeqNum5 = 250;
845
846 const uint8_t kNetworkData6[] = {
847 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
848 0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
849 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
850 0x0b, 0x08, 0x82, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
851 };
852 const uint8_t kSeqNumbers6[] = {250, 10, 130};
853 const uint8_t kPreferredSeqNum6 = 250;
854
855 const uint8_t kNetworkData7[] = {
856 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
857 0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
858 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
859 0x0b, 0x08, 0x82, 0x02, 0x5c, 0x8A, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
860 };
861 const uint8_t kSeqNumbers7[] = {250, 10, 138};
862 const uint8_t kPreferredSeqNum7 = 250;
863
864 const uint8_t kNetworkData8[] = {
865 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
866 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
867 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
868 0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
869 0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
870
871 };
872 const uint8_t kSeqNumbers8[] = {1, 2, 255, 254};
873 const uint8_t kPreferredSeqNum8 = 2;
874
875 const uint8_t kNetworkData9[] = {
876 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
877 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
878 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
879 0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
880 0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
881
882 };
883 const uint8_t kSeqNumbers9[] = {1, 2, 255, 254};
884 const uint8_t kPreferredSeqNum9 = 2;
885
886 const uint8_t kNetworkData10[] = {
887 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
888 0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
889 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
890 0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
891 0x0b, 0x08, 0x83, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
892
893 };
894 const uint8_t kSeqNumbers10[] = {254, 2, 120, 1};
895 const uint8_t kPreferredSeqNum10 = 120;
896
897 const uint8_t kNetworkData11[] = {
898 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
899 0x0b, 0x08, 0x80, 0x02, 0x5c, 0xf0, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
900 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
901 0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
902 0x0b, 0x08, 0x83, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
903
904 };
905 const uint8_t kSeqNumbers11[] = {240, 2, 120, 1};
906 const uint8_t kPreferredSeqNum11 = 240;
907
908 const TestInfo kTests[] = {
909 {kNetworkData1, sizeof(kNetworkData1), kSeqNumbers1, sizeof(kSeqNumbers1), kPreferredSeqNum1},
910 {kNetworkData2, sizeof(kNetworkData2), kSeqNumbers2, sizeof(kSeqNumbers2), kPreferredSeqNum2},
911 {kNetworkData3, sizeof(kNetworkData3), kSeqNumbers3, sizeof(kSeqNumbers3), kPreferredSeqNum3},
912 {kNetworkData4, sizeof(kNetworkData4), kSeqNumbers4, sizeof(kSeqNumbers4), kPreferredSeqNum4},
913 {kNetworkData5, sizeof(kNetworkData5), kSeqNumbers5, sizeof(kSeqNumbers5), kPreferredSeqNum5},
914 {kNetworkData6, sizeof(kNetworkData6), kSeqNumbers6, sizeof(kSeqNumbers6), kPreferredSeqNum6},
915 {kNetworkData7, sizeof(kNetworkData7), kSeqNumbers7, sizeof(kSeqNumbers7), kPreferredSeqNum7},
916 {kNetworkData8, sizeof(kNetworkData8), kSeqNumbers8, sizeof(kSeqNumbers8), kPreferredSeqNum8},
917 {kNetworkData9, sizeof(kNetworkData9), kSeqNumbers9, sizeof(kSeqNumbers9), kPreferredSeqNum9},
918 {kNetworkData10, sizeof(kNetworkData10), kSeqNumbers10, sizeof(kSeqNumbers10), kPreferredSeqNum10},
919 {kNetworkData11, sizeof(kNetworkData11), kSeqNumbers11, sizeof(kSeqNumbers11), kPreferredSeqNum11},
920 };
921
922 Service::Manager &manager = instance->Get<Service::Manager>();
923 uint8_t testIndex = 0;
924
925 for (const TestInfo &test : kTests)
926 {
927 Service::Manager::Iterator iterator;
928 Service::DnsSrpAnycast::Info anycastInfo;
929
930 reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(test.mNetworkData, test.mNetworkDataLength);
931
932 printf("\n- - - - - - - - - - - - - - - - - - - -");
933 printf("\nDNS/SRP Anycast Service entries for test %d", ++testIndex);
934
935 for (uint8_t index = 0; index < test.mSeqNumbersLength; index++)
936 {
937 SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo));
938
939 printf("\n { %s, seq:%d }", anycastInfo.mAnycastAddress.ToString().AsCString(),
940 anycastInfo.mSequenceNumber);
941
942 VerifyOrQuit(anycastInfo.mSequenceNumber == test.mSeqNumbers[index]);
943 }
944
945 VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound);
946 SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo));
947
948 printf("\n preferred -> seq:%d ", anycastInfo.mSequenceNumber);
949 VerifyOrQuit(anycastInfo.mSequenceNumber == test.mPreferredSeqNum);
950 }
951
952 testFreeInstance(instance);
953 }
954
955 } // namespace NetworkData
956 } // namespace ot
957
main(void)958 int main(void)
959 {
960 ot::NetworkData::TestNetworkDataIterator();
961 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
962 ot::NetworkData::TestNetworkDataFindNextService();
963 #endif
964 ot::NetworkData::TestNetworkDataDsnSrpServices();
965 ot::NetworkData::TestNetworkDataDsnSrpAnycastSeqNumSelection();
966
967 printf("\nAll tests passed\n");
968 return 0;
969 }
970