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