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 class TestLeader : public Leader
616 {
617 public:
618 void Populate(const uint8_t *aTlvs, uint8_t aTlvsLength)
619 {
620 memcpy(GetBytes(), aTlvs, aTlvsLength);
621 SetLength(aTlvsLength);
622 }
623 };
624
625 Instance *instance;
626
627 printf("\n\n-------------------------------------------------");
628 printf("\nTestNetworkDataDsnSrpServices()\n");
629
630 instance = testInitInstance();
631 VerifyOrQuit(instance != nullptr);
632
633 {
634 struct AnycastEntry
635 {
636 uint16_t mAloc16;
637 uint8_t mSequenceNumber;
638 uint16_t mRloc16;
639
640 bool Matches(Service::DnsSrpAnycastInfo aInfo) const
641 {
642 VerifyOrQuit(aInfo.mAnycastAddress.GetIid().IsAnycastServiceLocator());
643
644 return (aInfo.mAnycastAddress.GetIid().GetLocator() == mAloc16) &&
645 (aInfo.mSequenceNumber == mSequenceNumber) && (aInfo.mRloc16 == mRloc16);
646 }
647 };
648
649 struct UnicastEntry
650 {
651 const char *mAddress;
652 uint16_t mPort;
653 uint16_t mRloc16;
654
655 bool Matches(const Service::DnsSrpUnicastInfo &aInfo) const
656 {
657 Ip6::SockAddr sockAddr;
658
659 SuccessOrQuit(sockAddr.GetAddress().FromString(mAddress));
660 sockAddr.SetPort(mPort);
661
662 return (aInfo.mSockAddr == sockAddr) && (aInfo.mRloc16 == mRloc16);
663 }
664 };
665
666 const uint8_t kNetworkData[] = {
667 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x28, 0x00, 0x0b, 0x08, 0x81, 0x02, 0x5c, 0xff, 0x0d,
668 0x02, 0x6c, 0x00, 0x0b, 0x09, 0x82, 0x02, 0x5c, 0x03, 0x0d, 0x03, 0x4c, 0x00, 0xaa, 0x0b, 0x35, 0x83,
669 0x13, 0x5d, 0xfd, 0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0x00, 0x2d, 0x0e, 0xc6, 0x27, 0x55, 0x56, 0x18,
670 0xd9, 0x12, 0x34, 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x14, 0x6c, 0x00, 0xfd, 0x00, 0xaa, 0xbb, 0xcc, 0xdd,
671 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0xab, 0xcd, 0x0d, 0x04, 0x28, 0x00, 0x56,
672 0x78, 0x0b, 0x23, 0x84, 0x01, 0x5d, 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x14, 0x4c, 0x00, 0xfd, 0x00, 0x12,
673 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0x00, 0x0e, 0x0d, 0x04,
674 0x6c, 0x00, 0xcd, 0x12, 0x0b, 0x08, 0x84, 0x01, 0x5c, 0x0d, 0x02, 0x14, 0x01, 0x0d, 0x0b, 0x10, 0x83,
675 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x12, 0x00, 0x0d, 0x02, 0x12, 0x01, 0x0d, 0x02, 0x16, 0x00,
676 };
677
678 const AnycastEntry kAnycastEntries[] = {
679 {0xfc10, 0x02, 0x2800}, {0xfc11, 0xff, 0x6c00}, {0xfc12, 0x03, 0x4c00},
680 {0xfc13, 0xfe, 0x1200}, {0xfc13, 0xfe, 0x1201}, {0xfc13, 0xfe, 0x1600},
681 };
682
683 const UnicastEntry kUnicastEntriesFromServerData[] = {
684 {"fd00:aabb:ccdd:eeff:11:2233:4455:6677", 0xabcd, 0x6c00},
685 {"fdde:ad00:beef:0:0:ff:fe00:2800", 0x5678, 0x2800},
686 {"fd00:1234:5678:9abc:def0:123:4567:89ab", 0x0e, 0x4c00},
687 {"fdde:ad00:beef:0:0:ff:fe00:6c00", 0xcd12, 0x6c00},
688 };
689
690 const UnicastEntry kUnicastEntriesFromServiceData[] = {
691 {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 0x0000},
692 {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 0x6c00},
693 {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 0x2800},
694 };
695
696 const uint16_t kExpectedRlocs[] = {0x6c00, 0x2800, 0x4c00, 0x0000, 0x1200, 0x1201, 0x1600, 0x1401};
697 const uint16_t kExpectedRouterRlocs[] = {0x6c00, 0x2800, 0x4c00, 0x0000, 0x1200, 0x1600};
698 const uint16_t kExpectedChildRlocs[] = {0x1201, 0x1401};
699
700 const uint8_t kPreferredAnycastEntryIndex = 2;
701
702 Service::Manager &manager = instance->Get<Service::Manager>();
703 Service::Manager::Iterator iterator;
704 Service::DnsSrpAnycastInfo anycastInfo;
705 Service::DnsSrpUnicastInfo unicastInfo;
706 Service::DnsSrpUnicastType type;
707 Rlocs rlocs;
708
709 reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(kNetworkData, sizeof(kNetworkData));
710
711 DumpBuffer("netdata", kNetworkData, sizeof(kNetworkData));
712
713 // Verify `FindRlocs()`
714
715 instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
716 VerifyRlocsArray(rlocs, kExpectedRlocs);
717
718 instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
719 VerifyRlocsArray(rlocs, kExpectedRouterRlocs);
720
721 instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
722 VerifyRlocsArray(rlocs, kExpectedChildRlocs);
723
724 instance->Get<Leader>().FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
725 VerifyOrQuit(rlocs.GetLength() == 0);
726
727 // Verify all the "DNS/SRP Anycast Service" entries in Network Data
728
729 printf("\n- - - - - - - - - - - - - - - - - - - -");
730 printf("\nDNS/SRP Anycast Service entries\n");
731
732 for (const AnycastEntry &entry : kAnycastEntries)
733 {
734 SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo));
735
736 printf("\nanycastInfo { %s, seq:%d, rlco16:%04x }", anycastInfo.mAnycastAddress.ToString().AsCString(),
737 anycastInfo.mSequenceNumber, anycastInfo.mRloc16);
738
739 VerifyOrQuit(entry.Matches(anycastInfo), "GetNextDnsSrpAnycastInfo() returned incorrect info");
740 }
741
742 VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound,
743 "GetNextDnsSrpAnycastInfo() returned unexpected extra entry");
744
745 // Find the preferred "DNS/SRP Anycast Service" entries in Network Data
746
747 SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo));
748
749 printf("\n\nPreferred anycastInfo { %s, seq:%d }", anycastInfo.mAnycastAddress.ToString().AsCString(),
750 anycastInfo.mSequenceNumber);
751
752 VerifyOrQuit(kAnycastEntries[kPreferredAnycastEntryIndex].Matches(anycastInfo),
753 "FindPreferredDnsSrpAnycastInfo() returned invalid info");
754
755 printf("\n\n- - - - - - - - - - - - - - - - - - - -");
756 printf("\nDNS/SRP Unicast Service entries (server data)\n");
757
758 iterator.Clear();
759 type = Service::kAddrInServerData;
760
761 for (const UnicastEntry &entry : kUnicastEntriesFromServerData)
762 {
763 SuccessOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo));
764 printf("\nunicastInfo { %s, rloc16:%04x }", unicastInfo.mSockAddr.ToString().AsCString(),
765 unicastInfo.mRloc16);
766
767 VerifyOrQuit(entry.Matches(unicastInfo), "GetNextDnsSrpUnicastInfo() returned incorrect info");
768 }
769
770 VerifyOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo) == kErrorNotFound,
771 "GetNextDnsSrpUnicastInfo() returned unexpected extra entry");
772
773 printf("\n\n- - - - - - - - - - - - - - - - - - - -");
774 printf("\nDNS/SRP Unicast Service entries (service data)\n");
775
776 iterator.Clear();
777 type = Service::kAddrInServiceData;
778
779 for (const UnicastEntry &entry : kUnicastEntriesFromServiceData)
780 {
781 SuccessOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo));
782 printf("\nunicastInfo { %s, rloc16:%04x }", unicastInfo.mSockAddr.ToString().AsCString(),
783 unicastInfo.mRloc16);
784
785 VerifyOrQuit(entry.Matches(unicastInfo), "GetNextDnsSrpUnicastInfo() returned incorrect info");
786 }
787
788 VerifyOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo) == kErrorNotFound,
789 "GetNextDnsSrpUnicastInfo() returned unexpected extra entry");
790
791 printf("\n");
792 }
793
794 testFreeInstance(instance);
795 }
796
TestNetworkDataDsnSrpAnycastSeqNumSelection(void)797 void TestNetworkDataDsnSrpAnycastSeqNumSelection(void)
798 {
799 class TestLeader : public Leader
800 {
801 public:
802 void Populate(const uint8_t *aTlvs, uint8_t aTlvsLength)
803 {
804 memcpy(GetBytes(), aTlvs, aTlvsLength);
805 SetLength(aTlvsLength);
806 }
807 };
808
809 struct TestInfo
810 {
811 const uint8_t *mNetworkData;
812 uint8_t mNetworkDataLength;
813 const uint8_t *mSeqNumbers;
814 uint8_t mSeqNumbersLength;
815 uint8_t mPreferredSeqNum;
816 };
817
818 Instance *instance;
819
820 printf("\n\n-------------------------------------------------");
821 printf("\nTestNetworkDataDsnSrpAnycastSeqNumSelection()\n");
822
823 instance = testInitInstance();
824 VerifyOrQuit(instance != nullptr);
825
826 const uint8_t kNetworkData1[] = {
827 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
828 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
829 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x81, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
830 };
831 const uint8_t kSeqNumbers1[] = {1, 129};
832 const uint8_t kPreferredSeqNum1 = 129;
833
834 const uint8_t kNetworkData2[] = {
835 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
836 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x85, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
837 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x05, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
838 };
839 const uint8_t kSeqNumbers2[] = {133, 5};
840 const uint8_t kPreferredSeqNum2 = 133;
841
842 const uint8_t kNetworkData3[] = {
843 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
844 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
845 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
846 0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
847 };
848 const uint8_t kSeqNumbers3[] = {1, 2, 255};
849 const uint8_t kPreferredSeqNum3 = 2;
850
851 const uint8_t kNetworkData4[] = {
852 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
853 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
854 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
855 0x0b, 0x08, 0x82, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
856 };
857 const uint8_t kSeqNumbers4[] = {10, 130, 250};
858 const uint8_t kPreferredSeqNum4 = 250;
859
860 const uint8_t kNetworkData5[] = {
861 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
862 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
863 0x0b, 0x08, 0x81, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
864 0x0b, 0x08, 0x82, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
865 };
866 const uint8_t kSeqNumbers5[] = {130, 250, 10};
867 const uint8_t kPreferredSeqNum5 = 250;
868
869 const uint8_t kNetworkData6[] = {
870 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
871 0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
872 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
873 0x0b, 0x08, 0x82, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
874 };
875 const uint8_t kSeqNumbers6[] = {250, 10, 130};
876 const uint8_t kPreferredSeqNum6 = 250;
877
878 const uint8_t kNetworkData7[] = {
879 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
880 0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
881 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
882 0x0b, 0x08, 0x82, 0x02, 0x5c, 0x8A, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
883 };
884 const uint8_t kSeqNumbers7[] = {250, 10, 138};
885 const uint8_t kPreferredSeqNum7 = 250;
886
887 const uint8_t kNetworkData8[] = {
888 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
889 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
890 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
891 0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
892 0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
893
894 };
895 const uint8_t kSeqNumbers8[] = {1, 2, 255, 254};
896 const uint8_t kPreferredSeqNum8 = 2;
897
898 const uint8_t kNetworkData9[] = {
899 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
900 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
901 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
902 0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
903 0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
904
905 };
906 const uint8_t kSeqNumbers9[] = {1, 2, 255, 254};
907 const uint8_t kPreferredSeqNum9 = 2;
908
909 const uint8_t kNetworkData10[] = {
910 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
911 0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
912 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
913 0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
914 0x0b, 0x08, 0x83, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
915
916 };
917 const uint8_t kSeqNumbers10[] = {254, 2, 120, 1};
918 const uint8_t kPreferredSeqNum10 = 120;
919
920 const uint8_t kNetworkData11[] = {
921 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
922 0x0b, 0x08, 0x80, 0x02, 0x5c, 0xf0, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
923 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
924 0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
925 0x0b, 0x08, 0x83, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
926
927 };
928 const uint8_t kSeqNumbers11[] = {240, 2, 120, 1};
929 const uint8_t kPreferredSeqNum11 = 240;
930
931 const TestInfo kTests[] = {
932 {kNetworkData1, sizeof(kNetworkData1), kSeqNumbers1, sizeof(kSeqNumbers1), kPreferredSeqNum1},
933 {kNetworkData2, sizeof(kNetworkData2), kSeqNumbers2, sizeof(kSeqNumbers2), kPreferredSeqNum2},
934 {kNetworkData3, sizeof(kNetworkData3), kSeqNumbers3, sizeof(kSeqNumbers3), kPreferredSeqNum3},
935 {kNetworkData4, sizeof(kNetworkData4), kSeqNumbers4, sizeof(kSeqNumbers4), kPreferredSeqNum4},
936 {kNetworkData5, sizeof(kNetworkData5), kSeqNumbers5, sizeof(kSeqNumbers5), kPreferredSeqNum5},
937 {kNetworkData6, sizeof(kNetworkData6), kSeqNumbers6, sizeof(kSeqNumbers6), kPreferredSeqNum6},
938 {kNetworkData7, sizeof(kNetworkData7), kSeqNumbers7, sizeof(kSeqNumbers7), kPreferredSeqNum7},
939 {kNetworkData8, sizeof(kNetworkData8), kSeqNumbers8, sizeof(kSeqNumbers8), kPreferredSeqNum8},
940 {kNetworkData9, sizeof(kNetworkData9), kSeqNumbers9, sizeof(kSeqNumbers9), kPreferredSeqNum9},
941 {kNetworkData10, sizeof(kNetworkData10), kSeqNumbers10, sizeof(kSeqNumbers10), kPreferredSeqNum10},
942 {kNetworkData11, sizeof(kNetworkData11), kSeqNumbers11, sizeof(kSeqNumbers11), kPreferredSeqNum11},
943 };
944
945 Service::Manager &manager = instance->Get<Service::Manager>();
946 uint8_t testIndex = 0;
947
948 for (const TestInfo &test : kTests)
949 {
950 Service::Manager::Iterator iterator;
951 Service::DnsSrpAnycastInfo anycastInfo;
952
953 reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(test.mNetworkData, test.mNetworkDataLength);
954
955 printf("\n- - - - - - - - - - - - - - - - - - - -");
956 printf("\nDNS/SRP Anycast Service entries for test %d", ++testIndex);
957
958 for (uint8_t index = 0; index < test.mSeqNumbersLength; index++)
959 {
960 SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo));
961
962 printf("\n { %s, seq:%d, rlco16:%04x }", anycastInfo.mAnycastAddress.ToString().AsCString(),
963 anycastInfo.mSequenceNumber, anycastInfo.mRloc16);
964
965 VerifyOrQuit(anycastInfo.mSequenceNumber == test.mSeqNumbers[index]);
966 VerifyOrQuit(anycastInfo.mRloc16 == 0x5000 + index);
967 }
968
969 VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound);
970 SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo));
971
972 printf("\n preferred -> seq:%d ", anycastInfo.mSequenceNumber);
973 VerifyOrQuit(anycastInfo.mSequenceNumber == test.mPreferredSeqNum);
974 }
975
976 testFreeInstance(instance);
977 }
978
979 } // namespace NetworkData
980 } // namespace ot
981
main(void)982 int main(void)
983 {
984 ot::NetworkData::TestNetworkDataIterator();
985 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
986 ot::NetworkData::TestNetworkDataFindNextService();
987 #endif
988 ot::NetworkData::TestNetworkDataDsnSrpServices();
989 ot::NetworkData::TestNetworkDataDsnSrpAnycastSeqNumSelection();
990
991 printf("\nAll tests passed\n");
992 return 0;
993 }
994