| /* |
| * Copyright (c) 2017, The OpenThread Authors. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of the copyright holder nor the |
| * names of its contributors may be used to endorse or promote products |
| * derived from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include <openthread/config.h> |
| |
| #include "common/array.hpp" |
| #include "common/code_utils.hpp" |
| #include "instance/instance.hpp" |
| #include "thread/network_data_leader.hpp" |
| #include "thread/network_data_local.hpp" |
| #include "thread/network_data_service.hpp" |
| |
| #include "test_platform.h" |
| #include "test_util.hpp" |
| |
| namespace ot { |
| namespace NetworkData { |
| |
| void PrintExternalRouteConfig(const ExternalRouteConfig &aConfig) |
| { |
| printf("\nroute-prefix:"); |
| |
| for (uint8_t b : aConfig.mPrefix.mPrefix.mFields.m8) |
| { |
| printf("%02x", b); |
| } |
| |
| printf(", length:%d, rloc16:%04x, preference:%d, nat64:%d, stable:%d, nexthop:%d", aConfig.mPrefix.mLength, |
| aConfig.mRloc16, aConfig.mPreference, aConfig.mNat64, aConfig.mStable, aConfig.mNextHopIsThisDevice); |
| } |
| |
| void PrintOnMeshPrefixConfig(const OnMeshPrefixConfig &aConfig) |
| { |
| printf("\non-mesh-prefix:"); |
| |
| for (uint8_t b : aConfig.mPrefix.mPrefix.mFields.m8) |
| { |
| printf("%02x", b); |
| } |
| |
| printf(", length:%d, rloc16:%04x, preference:%d, stable:%d, def-route:%d", aConfig.mPrefix.mLength, aConfig.mRloc16, |
| aConfig.mPreference, aConfig.mStable, aConfig.mDefaultRoute); |
| } |
| |
| // Returns true if the two given ExternalRouteConfig match (intentionally ignoring mNextHopIsThisDevice). |
| bool CompareExternalRouteConfig(const otExternalRouteConfig &aConfig1, const otExternalRouteConfig &aConfig2) |
| { |
| return (memcmp(aConfig1.mPrefix.mPrefix.mFields.m8, aConfig2.mPrefix.mPrefix.mFields.m8, |
| sizeof(aConfig1.mPrefix.mPrefix)) == 0) && |
| (aConfig1.mPrefix.mLength == aConfig2.mPrefix.mLength) && (aConfig1.mRloc16 == aConfig2.mRloc16) && |
| (aConfig1.mPreference == aConfig2.mPreference) && (aConfig1.mStable == aConfig2.mStable); |
| } |
| |
| // Returns true if the two given OnMeshprefix match. |
| bool CompareOnMeshPrefixConfig(const otBorderRouterConfig &aConfig1, const otBorderRouterConfig &aConfig2) |
| { |
| return (memcmp(aConfig1.mPrefix.mPrefix.mFields.m8, aConfig2.mPrefix.mPrefix.mFields.m8, |
| sizeof(aConfig1.mPrefix.mPrefix)) == 0) && |
| (aConfig1.mPrefix.mLength == aConfig2.mPrefix.mLength) && (aConfig1.mRloc16 == aConfig2.mRloc16) && |
| (aConfig1.mPreference == aConfig2.mPreference) && (aConfig1.mStable == aConfig2.mStable) && |
| (aConfig1.mDefaultRoute == aConfig2.mDefaultRoute) && (aConfig1.mOnMesh == aConfig2.mOnMesh); |
| } |
| |
| template <uint8_t kLength> void VerifyRlocsArray(const Rlocs &aRlocs, const uint16_t (&aExpectedRlocs)[kLength]) |
| { |
| VerifyOrQuit(aRlocs.GetLength() == kLength); |
| |
| printf("\nRLOCs: { "); |
| |
| for (uint16_t rloc : aRlocs) |
| { |
| printf("0x%04x ", rloc); |
| } |
| |
| printf("}"); |
| |
| for (uint16_t index = 0; index < kLength; index++) |
| { |
| VerifyOrQuit(aRlocs.Contains(aExpectedRlocs[index])); |
| } |
| } |
| |
| void TestNetworkDataIterator(void) |
| { |
| Instance *instance; |
| Iterator iter = kIteratorInit; |
| ExternalRouteConfig rconfig; |
| OnMeshPrefixConfig pconfig; |
| Rlocs rlocs; |
| |
| instance = testInitInstance(); |
| VerifyOrQuit(instance != nullptr); |
| |
| { |
| const uint8_t kNetworkData[] = { |
| 0x08, 0x04, 0x0B, 0x02, 0x00, 0x00, 0x03, 0x14, 0x00, 0x40, 0xFD, 0x00, 0x12, 0x34, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC8, 0x00, 0x40, 0x01, 0x03, 0x54, 0x00, 0x00, |
| }; |
| |
| otExternalRouteConfig routes[] = { |
| { |
| { |
| {{{0xfd, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00}}}, |
| 64, |
| }, |
| 0xc800, // mRloc16 |
| 1, // mPreference |
| false, // mNat64 |
| false, // mStable |
| false, // mNextHopIsThisDevice |
| false, // mAdvPio |
| }, |
| { |
| { |
| {{{0xfd, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00}}}, |
| 64, |
| }, |
| 0x5400, // mRloc16 |
| 0, // mPreference |
| false, // mNat64 |
| true, // mStable |
| false, // mNextHopIsThisDevice |
| false, // mAdvPio |
| }, |
| }; |
| |
| const uint16_t kRlocs[] = {0xc800, 0x5400}; |
| const uint16_t kNonExistingRlocs[] = {0xc700, 0x0000, 0x5401}; |
| |
| NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData)); |
| |
| iter = OT_NETWORK_DATA_ITERATOR_INIT; |
| |
| printf("\nTest #1: Network data 1"); |
| printf("\n-------------------------------------------------"); |
| |
| for (const auto &route : routes) |
| { |
| SuccessOrQuit(netData.GetNextExternalRoute(iter, rconfig)); |
| PrintExternalRouteConfig(rconfig); |
| VerifyOrQuit(CompareExternalRouteConfig(rconfig, route)); |
| } |
| |
| netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs); |
| VerifyRlocsArray(rlocs, kRlocs); |
| |
| netData.FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs); |
| VerifyRlocsArray(rlocs, kRlocs); |
| |
| netData.FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs); |
| VerifyOrQuit(rlocs.GetLength() == 0); |
| |
| netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs); |
| VerifyRlocsArray(rlocs, kRlocs); |
| VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kRlocs)); |
| |
| netData.FindRlocs(kBrProvidingExternalIpConn, kRouterRoleOnly, rlocs); |
| VerifyRlocsArray(rlocs, kRlocs); |
| VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kRlocs)); |
| |
| netData.FindRlocs(kBrProvidingExternalIpConn, kChildRoleOnly, rlocs); |
| VerifyOrQuit(rlocs.GetLength() == 0); |
| VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == 0); |
| |
| for (uint16_t rloc16 : kRlocs) |
| { |
| VerifyOrQuit(netData.ContainsBorderRouterWithRloc(rloc16)); |
| } |
| |
| for (uint16_t rloc16 : kNonExistingRlocs) |
| { |
| VerifyOrQuit(!netData.ContainsBorderRouterWithRloc(rloc16)); |
| } |
| } |
| |
| { |
| const uint8_t kNetworkData[] = { |
| 0x08, 0x04, 0x0B, 0x02, 0x00, 0x00, 0x03, 0x1E, 0x00, 0x40, 0xFD, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, |
| 0x07, 0x02, 0x11, 0x40, 0x00, 0x03, 0x10, 0x00, 0x40, 0x01, 0x03, 0x54, 0x00, 0x00, 0x05, 0x04, 0x54, 0x00, |
| 0x31, 0x00, 0x02, 0x0F, 0x00, 0x40, 0xFD, 0x00, 0xAB, 0xBA, 0xCD, 0xDC, 0x00, 0x00, 0x00, 0x03, 0x10, 0x00, |
| 0x20, 0x03, 0x0E, 0x00, 0x20, 0xFD, 0x00, 0xAB, 0xBA, 0x01, 0x06, 0x54, 0x00, 0x00, 0x04, 0x01, 0x00, |
| }; |
| |
| otExternalRouteConfig routes[] = { |
| { |
| { |
| {{{0xfd, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00}}}, |
| 64, |
| }, |
| 0x1000, // mRloc16 |
| 1, // mPreference |
| false, // mNat64 |
| false, // mStable |
| false, // mNextHopIsThisDevice |
| }, |
| { |
| { |
| {{{0xfd, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00}}}, |
| 64, |
| }, |
| 0x5400, // mRloc16 |
| 0, // mPreference |
| false, // mNat64 |
| true, // mStable |
| false, // mNextHopIsThisDevice |
| }, |
| { |
| { |
| {{{0xfd, 0x00, 0xab, 0xba, 0xcd, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00}}}, |
| 64, |
| }, |
| 0x1000, // mRloc16 |
| 0, // mPreference |
| true, // mNat64 |
| false, // mStable |
| false, // mNextHopIsThisDevice |
| }, |
| { |
| { |
| {{{0xfd, 0x00, 0xab, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00}}}, |
| 32, |
| }, |
| 0x5400, // mRloc16 |
| 0, // mPreference |
| false, // mNat64 |
| true, // mStable |
| false, // mNextHopIsThisDevice |
| }, |
| { |
| { |
| {{{0xfd, 0x00, 0xab, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00}}}, |
| 32, |
| }, |
| 0x0401, // mRloc16 |
| 0, // mPreference |
| false, // mNat64 |
| true, // mStable |
| false, // mNextHopIsThisDevice |
| }, |
| }; |
| |
| const uint16_t kRlocsAnyRole[] = {0x1000, 0x5400, 0x0401}; |
| const uint16_t kRlocsRouterRole[] = {0x1000, 0x5400}; |
| const uint16_t kRlocsChildRole[] = {0x0401}; |
| const uint16_t kNonExistingRlocs[] = {0x6000, 0x0000, 0x0402}; |
| |
| NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData)); |
| |
| iter = OT_NETWORK_DATA_ITERATOR_INIT; |
| |
| printf("\nTest #2: Network data 2"); |
| printf("\n-------------------------------------------------"); |
| |
| for (const auto &route : routes) |
| { |
| SuccessOrQuit(netData.GetNextExternalRoute(iter, rconfig)); |
| PrintExternalRouteConfig(rconfig); |
| VerifyOrQuit(CompareExternalRouteConfig(rconfig, route)); |
| } |
| |
| netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs); |
| VerifyRlocsArray(rlocs, kRlocsAnyRole); |
| |
| netData.FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs); |
| VerifyRlocsArray(rlocs, kRlocsRouterRole); |
| |
| netData.FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs); |
| VerifyRlocsArray(rlocs, kRlocsChildRole); |
| |
| netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs); |
| VerifyRlocsArray(rlocs, kRlocsAnyRole); |
| VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kRlocsAnyRole)); |
| |
| netData.FindRlocs(kBrProvidingExternalIpConn, kRouterRoleOnly, rlocs); |
| VerifyRlocsArray(rlocs, kRlocsRouterRole); |
| VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kRlocsRouterRole)); |
| |
| netData.FindRlocs(kBrProvidingExternalIpConn, kChildRoleOnly, rlocs); |
| VerifyRlocsArray(rlocs, kRlocsChildRole); |
| VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == GetArrayLength(kRlocsChildRole)); |
| |
| netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs); |
| VerifyRlocsArray(rlocs, kRlocsAnyRole); |
| |
| for (uint16_t rloc16 : kRlocsAnyRole) |
| { |
| VerifyOrQuit(netData.ContainsBorderRouterWithRloc(rloc16)); |
| } |
| |
| for (uint16_t rloc16 : kNonExistingRlocs) |
| { |
| VerifyOrQuit(!netData.ContainsBorderRouterWithRloc(rloc16)); |
| } |
| } |
| |
| { |
| const uint8_t kNetworkData[] = { |
| 0x08, 0x04, 0x0b, 0x02, 0x36, 0xcc, 0x03, 0x1c, 0x00, 0x40, 0xfd, 0x00, 0xbe, 0xef, 0xca, 0xfe, |
| 0x00, 0x00, 0x05, 0x0c, 0x28, 0x00, 0x33, 0x00, 0x28, 0x01, 0x33, 0x00, 0x4c, 0x00, 0x31, 0x00, |
| 0x07, 0x02, 0x11, 0x40, 0x03, 0x14, 0x00, 0x40, 0xfd, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, |
| 0x05, 0x04, 0x28, 0x00, 0x73, 0x00, 0x07, 0x02, 0x12, 0x40, 0x03, 0x12, 0x00, 0x40, 0xfd, 0x00, |
| 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0xec, 0x00, 0x00, 0x28, 0x01, 0xc0, |
| }; |
| |
| otExternalRouteConfig routes[] = { |
| { |
| { |
| {{{0xfd, 0x00, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00}}}, |
| 64, |
| }, |
| 0xec00, // mRloc16 |
| 0, // mPreference |
| false, // mNat64 |
| true, // mStable |
| false, // mNextHopIsThisDevice |
| }, |
| { |
| { |
| {{{0xfd, 0x00, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00}}}, |
| 64, |
| }, |
| 0x2801, // mRloc16 |
| -1, // mPreference |
| false, // mNat64 |
| true, // mStable |
| false, // mNextHopIsThisDevice |
| }, |
| }; |
| |
| otBorderRouterConfig prefixes[] = { |
| { |
| { |
| {{{0xfd, 0x00, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00}}}, |
| 64, |
| }, |
| 0, // mPreference |
| true, // mPreferred |
| true, // mSlaac |
| false, // mDhcp |
| true, // mConfigure |
| true, // mDefaultRoute |
| true, // mOnMesh |
| true, // mStable |
| false, // mNdDns |
| false, // mDp |
| 0x2800, // mRloc16 |
| }, |
| { |
| { |
| {{{0xfd, 0x00, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00}}}, |
| 64, |
| }, |
| 0, // mPreference |
| true, // mPreferred |
| true, // mSlaac |
| false, // mDhcp |
| true, // mConfigure |
| true, // mDefaultRoute |
| true, // mOnMesh |
| true, // mStable |
| false, // mNdDns |
| false, // mDp |
| 0x2801, // mRloc16 |
| }, |
| { |
| { |
| {{{0xfd, 0x00, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00}}}, |
| 64, |
| }, |
| 0, // mPreference |
| true, // mPreferred |
| true, // mSlaac |
| false, // mDhcp |
| true, // mConfigure |
| false, // mDefaultRoute |
| true, // mOnMesh |
| true, // mStable |
| false, // mNdDns |
| false, // mDp |
| 0x4c00, // mRloc16 |
| }, |
| { |
| { |
| {{{0xfd, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00}}}, |
| 64, |
| }, |
| 1, // mPreference |
| true, // mPreferred |
| true, // mSlaac |
| false, // mDhcp |
| true, // mConfigure |
| true, // mDefaultRoute |
| true, // mOnMesh |
| true, // mStable |
| false, // mNdDns |
| false, // mDp |
| 0x2800, // mRloc16 |
| }, |
| }; |
| |
| const uint16_t kRlocsAnyRole[] = {0xec00, 0x2801, 0x2800, 0x4c00}; |
| const uint16_t kRlocsRouterRole[] = {0xec00, 0x2800, 0x4c00}; |
| const uint16_t kRlocsChildRole[] = {0x2801}; |
| const uint16_t kBrRlocsAnyRole[] = {0xec00, 0x2801, 0x2800}; |
| const uint16_t kBrRlocsRouterRole[] = {0xec00, 0x2800}; |
| const uint16_t kBrRlocsChildRole[] = {0x2801}; |
| const uint16_t kNonExistingRlocs[] = {0x6000, 0x0000, 0x2806, 0x4c00}; |
| |
| NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData)); |
| |
| printf("\nTest #3: Network data 3"); |
| printf("\n-------------------------------------------------"); |
| |
| iter = OT_NETWORK_DATA_ITERATOR_INIT; |
| |
| for (const auto &route : routes) |
| { |
| SuccessOrQuit(netData.GetNextExternalRoute(iter, rconfig)); |
| PrintExternalRouteConfig(rconfig); |
| VerifyOrQuit(CompareExternalRouteConfig(rconfig, route)); |
| } |
| |
| iter = OT_NETWORK_DATA_ITERATOR_INIT; |
| |
| for (const auto &prefix : prefixes) |
| { |
| SuccessOrQuit(netData.GetNextOnMeshPrefix(iter, pconfig)); |
| PrintOnMeshPrefixConfig(pconfig); |
| VerifyOrQuit(CompareOnMeshPrefixConfig(pconfig, prefix)); |
| } |
| |
| netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs); |
| VerifyRlocsArray(rlocs, kRlocsAnyRole); |
| |
| netData.FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs); |
| VerifyRlocsArray(rlocs, kRlocsRouterRole); |
| |
| netData.FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs); |
| VerifyRlocsArray(rlocs, kRlocsChildRole); |
| |
| netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs); |
| VerifyRlocsArray(rlocs, kBrRlocsAnyRole); |
| VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kBrRlocsAnyRole)); |
| |
| netData.FindRlocs(kBrProvidingExternalIpConn, kRouterRoleOnly, rlocs); |
| VerifyRlocsArray(rlocs, kBrRlocsRouterRole); |
| VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kBrRlocsRouterRole)); |
| |
| netData.FindRlocs(kBrProvidingExternalIpConn, kChildRoleOnly, rlocs); |
| VerifyRlocsArray(rlocs, kBrRlocsChildRole); |
| VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == GetArrayLength(kBrRlocsChildRole)); |
| |
| for (uint16_t rloc16 : kBrRlocsAnyRole) |
| { |
| VerifyOrQuit(netData.ContainsBorderRouterWithRloc(rloc16)); |
| } |
| |
| for (uint16_t rloc16 : kNonExistingRlocs) |
| { |
| VerifyOrQuit(!netData.ContainsBorderRouterWithRloc(rloc16)); |
| } |
| } |
| |
| testFreeInstance(instance); |
| } |
| |
| #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE |
| |
| class TestNetworkData : public Local |
| { |
| public: |
| explicit TestNetworkData(Instance &aInstance) |
| : Local(aInstance) |
| { |
| } |
| |
| Error AddService(const ServiceData &aServiceData) |
| { |
| return Local::AddService(ServiceTlv::kThreadEnterpriseNumber, aServiceData, true, ServerData()); |
| } |
| |
| Error ValidateServiceData(const ServiceTlv *aServiceTlv, const ServiceData &aServiceData) const |
| { |
| Error error = kErrorFailed; |
| ServiceData serviceData; |
| |
| VerifyOrExit(aServiceTlv != nullptr); |
| aServiceTlv->GetServiceData(serviceData); |
| |
| VerifyOrExit(aServiceData == serviceData); |
| error = kErrorNone; |
| |
| exit: |
| return error; |
| } |
| |
| void Test(void) |
| { |
| const uint8_t kServiceData1[] = {0x02}; |
| const uint8_t kServiceData2[] = {0xab}; |
| const uint8_t kServiceData3[] = {0xab, 0x00}; |
| const uint8_t kServiceData4[] = {0x02, 0xab, 0xcd, 0xef}; |
| const uint8_t kServiceData5[] = {0x02, 0xab, 0xcd}; |
| |
| const ServiceTlv *tlv; |
| ServiceData serviceData1; |
| ServiceData serviceData2; |
| ServiceData serviceData3; |
| ServiceData serviceData4; |
| ServiceData serviceData5; |
| |
| serviceData1.InitFrom(kServiceData1); |
| serviceData2.InitFrom(kServiceData2); |
| serviceData3.InitFrom(kServiceData3); |
| serviceData4.InitFrom(kServiceData4); |
| serviceData5.InitFrom(kServiceData5); |
| |
| SuccessOrQuit(AddService(serviceData1)); |
| SuccessOrQuit(AddService(serviceData2)); |
| SuccessOrQuit(AddService(serviceData3)); |
| SuccessOrQuit(AddService(serviceData4)); |
| SuccessOrQuit(AddService(serviceData5)); |
| |
| DumpBuffer("netdata", GetBytes(), GetLength()); |
| |
| // Iterate through all entries that start with { 0x02 } (kServiceData1) |
| tlv = nullptr; |
| tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch); |
| SuccessOrQuit(ValidateServiceData(tlv, serviceData1)); |
| tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch); |
| SuccessOrQuit(ValidateServiceData(tlv, serviceData4)); |
| tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch); |
| SuccessOrQuit(ValidateServiceData(tlv, serviceData5)); |
| tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch); |
| VerifyOrQuit(tlv == nullptr, "FindNextService() returned extra TLV"); |
| |
| // Iterate through all entries that start with { 0xab } (serviceData2) |
| tlv = nullptr; |
| tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData2, kServicePrefixMatch); |
| SuccessOrQuit(ValidateServiceData(tlv, serviceData2)); |
| tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData2, kServicePrefixMatch); |
| SuccessOrQuit(ValidateServiceData(tlv, serviceData3)); |
| tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData2, kServicePrefixMatch); |
| VerifyOrQuit(tlv == nullptr, "FindNextService() returned extra TLV"); |
| |
| // Iterate through all entries that start with serviceData5 |
| tlv = nullptr; |
| tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData5, kServicePrefixMatch); |
| SuccessOrQuit(ValidateServiceData(tlv, serviceData4)); |
| tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData5, kServicePrefixMatch); |
| SuccessOrQuit(ValidateServiceData(tlv, serviceData5)); |
| tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData5, kServicePrefixMatch); |
| VerifyOrQuit(tlv == nullptr, "FindNextService() returned extra TLV"); |
| } |
| }; |
| |
| void TestNetworkDataFindNextService(void) |
| { |
| Instance *instance; |
| |
| printf("\n\n-------------------------------------------------"); |
| printf("\nTestNetworkDataFindNextService()\n"); |
| |
| instance = testInitInstance(); |
| VerifyOrQuit(instance != nullptr); |
| |
| { |
| TestNetworkData netData(*instance); |
| netData.Test(); |
| } |
| } |
| |
| #endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE |
| |
| void TestNetworkDataDsnSrpServices(void) |
| { |
| static const char *kOriginStrings[] = { |
| "service-data", // (0) Service::DnsSrpUnicast::kFromServiceData |
| "server-data", // (1) Service::DnsSrpUnicast::kFromServerData |
| }; |
| |
| class TestLeader : public Leader |
| { |
| public: |
| void Populate(const uint8_t *aTlvs, uint8_t aTlvsLength) |
| { |
| memcpy(GetBytes(), aTlvs, aTlvsLength); |
| SetLength(aTlvsLength); |
| } |
| }; |
| |
| Instance *instance; |
| |
| printf("\n\n-------------------------------------------------"); |
| printf("\nTestNetworkDataDsnSrpServices()\n"); |
| |
| instance = testInitInstance(); |
| VerifyOrQuit(instance != nullptr); |
| |
| { |
| struct AnycastEntry |
| { |
| uint16_t mAloc16; |
| uint8_t mSequenceNumber; |
| |
| bool Matches(Service::DnsSrpAnycast::Info aInfo) const |
| { |
| VerifyOrQuit(aInfo.mAnycastAddress.GetIid().IsAnycastServiceLocator()); |
| |
| return (aInfo.mAnycastAddress.GetIid().GetLocator() == mAloc16) && |
| (aInfo.mSequenceNumber == mSequenceNumber); |
| } |
| }; |
| |
| struct UnicastEntry |
| { |
| const char *mAddress; |
| uint16_t mPort; |
| Service::DnsSrpUnicast::Origin mOrigin; |
| uint16_t mRloc16; |
| |
| bool Matches(Service::DnsSrpUnicast::Info aInfo) const |
| { |
| Ip6::SockAddr sockAddr; |
| |
| SuccessOrQuit(sockAddr.GetAddress().FromString(mAddress)); |
| sockAddr.SetPort(mPort); |
| |
| return (aInfo.mSockAddr == sockAddr) && (aInfo.mOrigin == mOrigin) && (aInfo.mRloc16 == mRloc16); |
| } |
| }; |
| |
| const uint8_t kNetworkData[] = { |
| 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x28, 0x00, 0x0b, 0x08, 0x81, 0x02, 0x5c, 0xff, 0x0d, 0x02, |
| 0x6c, 0x00, 0x0b, 0x09, 0x82, 0x02, 0x5c, 0x03, 0x0d, 0x03, 0x4c, 0x00, 0xaa, 0x0b, 0x35, 0x83, 0x13, 0x5d, |
| 0xfd, 0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0x00, 0x2d, 0x0e, 0xc6, 0x27, 0x55, 0x56, 0x18, 0xd9, 0x12, 0x34, |
| 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x14, 0x6c, 0x00, 0xfd, 0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, |
| 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0xab, 0xcd, 0x0d, 0x04, 0x28, 0x00, 0x56, 0x78, 0x0b, 0x23, 0x84, 0x01, |
| 0x5d, 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x14, 0x4c, 0x00, 0xfd, 0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, |
| 0xf0, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0x00, 0x0e, 0x0d, 0x04, 0x6c, 0x00, 0xcd, 0x12, |
| }; |
| |
| const AnycastEntry kAnycastEntries[] = { |
| {0xfc10, 0x02}, |
| {0xfc11, 0xff}, |
| {0xfc12, 0x03}, |
| }; |
| |
| const UnicastEntry kUnicastEntries[] = { |
| {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, Service::DnsSrpUnicast::kFromServiceData, 0xfffe}, |
| {"fd00:aabb:ccdd:eeff:11:2233:4455:6677", 0xabcd, Service::DnsSrpUnicast::kFromServerData, 0x6c00}, |
| {"fdde:ad00:beef:0:0:ff:fe00:2800", 0x5678, Service::DnsSrpUnicast::kFromServerData, 0x2800}, |
| {"fd00:1234:5678:9abc:def0:123:4567:89ab", 0x0e, Service::DnsSrpUnicast::kFromServerData, 0x4c00}, |
| {"fdde:ad00:beef:0:0:ff:fe00:6c00", 0xcd12, Service::DnsSrpUnicast::kFromServerData, 0x6c00}, |
| }; |
| |
| const uint16_t kExpectedRlocs[] = {0x6c00, 0x2800, 0x4c00, 0x0000}; |
| |
| const uint8_t kPreferredAnycastEntryIndex = 2; |
| |
| Service::Manager &manager = instance->Get<Service::Manager>(); |
| Service::Manager::Iterator iterator; |
| Service::DnsSrpAnycast::Info anycastInfo; |
| Service::DnsSrpUnicast::Info unicastInfo; |
| Rlocs rlocs; |
| |
| reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(kNetworkData, sizeof(kNetworkData)); |
| |
| DumpBuffer("netdata", kNetworkData, sizeof(kNetworkData)); |
| |
| // Verify `FindRlocs()` |
| |
| instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kAnyRole, rlocs); |
| VerifyRlocsArray(rlocs, kExpectedRlocs); |
| |
| instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs); |
| VerifyRlocsArray(rlocs, kExpectedRlocs); |
| |
| instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs); |
| VerifyOrQuit(rlocs.GetLength() == 0); |
| |
| instance->Get<Leader>().FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs); |
| VerifyOrQuit(rlocs.GetLength() == 0); |
| |
| // Verify all the "DNS/SRP Anycast Service" entries in Network Data |
| |
| printf("\n- - - - - - - - - - - - - - - - - - - -"); |
| printf("\nDNS/SRP Anycast Service entries\n"); |
| |
| for (const AnycastEntry &entry : kAnycastEntries) |
| { |
| SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo)); |
| |
| printf("\nanycastInfo { %s, seq:%d }", anycastInfo.mAnycastAddress.ToString().AsCString(), |
| anycastInfo.mSequenceNumber); |
| |
| VerifyOrQuit(entry.Matches(anycastInfo), "GetNextDnsSrpAnycastInfo() returned incorrect info"); |
| } |
| |
| VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound, |
| "GetNextDnsSrpAnycastInfo() returned unexpected extra entry"); |
| |
| // Find the preferred "DNS/SRP Anycast Service" entries in Network Data |
| |
| SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo)); |
| |
| printf("\n\nPreferred anycastInfo { %s, seq:%d }", anycastInfo.mAnycastAddress.ToString().AsCString(), |
| anycastInfo.mSequenceNumber); |
| |
| VerifyOrQuit(kAnycastEntries[kPreferredAnycastEntryIndex].Matches(anycastInfo), |
| "FindPreferredDnsSrpAnycastInfo() returned invalid info"); |
| |
| printf("\n\n- - - - - - - - - - - - - - - - - - - -"); |
| printf("\nDNS/SRP Unicast Service entries\n"); |
| |
| iterator.Clear(); |
| |
| for (const UnicastEntry &entry : kUnicastEntries) |
| { |
| SuccessOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, unicastInfo)); |
| printf("\nunicastInfo { %s, origin:%s, rloc16:%04x }", unicastInfo.mSockAddr.ToString().AsCString(), |
| kOriginStrings[unicastInfo.mOrigin], unicastInfo.mRloc16); |
| |
| VerifyOrQuit(entry.Matches(unicastInfo), "GetNextDnsSrpUnicastInfo() returned incorrect info"); |
| } |
| |
| VerifyOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, unicastInfo) == kErrorNotFound, |
| "GetNextDnsSrpUnicastInfo() returned unexpected extra entry"); |
| |
| printf("\n"); |
| } |
| |
| testFreeInstance(instance); |
| } |
| |
| void TestNetworkDataDsnSrpAnycastSeqNumSelection(void) |
| { |
| class TestLeader : public Leader |
| { |
| public: |
| void Populate(const uint8_t *aTlvs, uint8_t aTlvsLength) |
| { |
| memcpy(GetBytes(), aTlvs, aTlvsLength); |
| SetLength(aTlvsLength); |
| } |
| }; |
| |
| struct TestInfo |
| { |
| const uint8_t *mNetworkData; |
| uint8_t mNetworkDataLength; |
| const uint8_t *mSeqNumbers; |
| uint8_t mSeqNumbersLength; |
| uint8_t mPreferredSeqNum; |
| }; |
| |
| Instance *instance; |
| |
| printf("\n\n-------------------------------------------------"); |
| printf("\nTestNetworkDataDsnSrpAnycastSeqNumSelection()\n"); |
| |
| instance = testInitInstance(); |
| VerifyOrQuit(instance != nullptr); |
| |
| const uint8_t kNetworkData1[] = { |
| 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV |
| 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV |
| 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x81, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV |
| }; |
| const uint8_t kSeqNumbers1[] = {1, 129}; |
| const uint8_t kPreferredSeqNum1 = 129; |
| |
| const uint8_t kNetworkData2[] = { |
| 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV |
| 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x85, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV |
| 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x05, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV |
| }; |
| const uint8_t kSeqNumbers2[] = {133, 5}; |
| const uint8_t kPreferredSeqNum2 = 133; |
| |
| const uint8_t kNetworkData3[] = { |
| 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV |
| 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV |
| 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV |
| 0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV |
| }; |
| const uint8_t kSeqNumbers3[] = {1, 2, 255}; |
| const uint8_t kPreferredSeqNum3 = 2; |
| |
| const uint8_t kNetworkData4[] = { |
| 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV |
| 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV |
| 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV |
| 0x0b, 0x08, 0x82, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV |
| }; |
| const uint8_t kSeqNumbers4[] = {10, 130, 250}; |
| const uint8_t kPreferredSeqNum4 = 250; |
| |
| const uint8_t kNetworkData5[] = { |
| 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV |
| 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV |
| 0x0b, 0x08, 0x81, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV |
| 0x0b, 0x08, 0x82, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV |
| }; |
| const uint8_t kSeqNumbers5[] = {130, 250, 10}; |
| const uint8_t kPreferredSeqNum5 = 250; |
| |
| const uint8_t kNetworkData6[] = { |
| 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV |
| 0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV |
| 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV |
| 0x0b, 0x08, 0x82, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV |
| }; |
| const uint8_t kSeqNumbers6[] = {250, 10, 130}; |
| const uint8_t kPreferredSeqNum6 = 250; |
| |
| const uint8_t kNetworkData7[] = { |
| 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV |
| 0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV |
| 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV |
| 0x0b, 0x08, 0x82, 0x02, 0x5c, 0x8A, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV |
| }; |
| const uint8_t kSeqNumbers7[] = {250, 10, 138}; |
| const uint8_t kPreferredSeqNum7 = 250; |
| |
| const uint8_t kNetworkData8[] = { |
| 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV |
| 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV |
| 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV |
| 0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV |
| 0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV |
| |
| }; |
| const uint8_t kSeqNumbers8[] = {1, 2, 255, 254}; |
| const uint8_t kPreferredSeqNum8 = 2; |
| |
| const uint8_t kNetworkData9[] = { |
| 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV |
| 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV |
| 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV |
| 0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV |
| 0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV |
| |
| }; |
| const uint8_t kSeqNumbers9[] = {1, 2, 255, 254}; |
| const uint8_t kPreferredSeqNum9 = 2; |
| |
| const uint8_t kNetworkData10[] = { |
| 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV |
| 0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV |
| 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV |
| 0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV |
| 0x0b, 0x08, 0x83, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV |
| |
| }; |
| const uint8_t kSeqNumbers10[] = {254, 2, 120, 1}; |
| const uint8_t kPreferredSeqNum10 = 120; |
| |
| const uint8_t kNetworkData11[] = { |
| 0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV |
| 0x0b, 0x08, 0x80, 0x02, 0x5c, 0xf0, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV |
| 0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV |
| 0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV |
| 0x0b, 0x08, 0x83, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV |
| |
| }; |
| const uint8_t kSeqNumbers11[] = {240, 2, 120, 1}; |
| const uint8_t kPreferredSeqNum11 = 240; |
| |
| const TestInfo kTests[] = { |
| {kNetworkData1, sizeof(kNetworkData1), kSeqNumbers1, sizeof(kSeqNumbers1), kPreferredSeqNum1}, |
| {kNetworkData2, sizeof(kNetworkData2), kSeqNumbers2, sizeof(kSeqNumbers2), kPreferredSeqNum2}, |
| {kNetworkData3, sizeof(kNetworkData3), kSeqNumbers3, sizeof(kSeqNumbers3), kPreferredSeqNum3}, |
| {kNetworkData4, sizeof(kNetworkData4), kSeqNumbers4, sizeof(kSeqNumbers4), kPreferredSeqNum4}, |
| {kNetworkData5, sizeof(kNetworkData5), kSeqNumbers5, sizeof(kSeqNumbers5), kPreferredSeqNum5}, |
| {kNetworkData6, sizeof(kNetworkData6), kSeqNumbers6, sizeof(kSeqNumbers6), kPreferredSeqNum6}, |
| {kNetworkData7, sizeof(kNetworkData7), kSeqNumbers7, sizeof(kSeqNumbers7), kPreferredSeqNum7}, |
| {kNetworkData8, sizeof(kNetworkData8), kSeqNumbers8, sizeof(kSeqNumbers8), kPreferredSeqNum8}, |
| {kNetworkData9, sizeof(kNetworkData9), kSeqNumbers9, sizeof(kSeqNumbers9), kPreferredSeqNum9}, |
| {kNetworkData10, sizeof(kNetworkData10), kSeqNumbers10, sizeof(kSeqNumbers10), kPreferredSeqNum10}, |
| {kNetworkData11, sizeof(kNetworkData11), kSeqNumbers11, sizeof(kSeqNumbers11), kPreferredSeqNum11}, |
| }; |
| |
| Service::Manager &manager = instance->Get<Service::Manager>(); |
| uint8_t testIndex = 0; |
| |
| for (const TestInfo &test : kTests) |
| { |
| Service::Manager::Iterator iterator; |
| Service::DnsSrpAnycast::Info anycastInfo; |
| |
| reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(test.mNetworkData, test.mNetworkDataLength); |
| |
| printf("\n- - - - - - - - - - - - - - - - - - - -"); |
| printf("\nDNS/SRP Anycast Service entries for test %d", ++testIndex); |
| |
| for (uint8_t index = 0; index < test.mSeqNumbersLength; index++) |
| { |
| SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo)); |
| |
| printf("\n { %s, seq:%d }", anycastInfo.mAnycastAddress.ToString().AsCString(), |
| anycastInfo.mSequenceNumber); |
| |
| VerifyOrQuit(anycastInfo.mSequenceNumber == test.mSeqNumbers[index]); |
| } |
| |
| VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound); |
| SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo)); |
| |
| printf("\n preferred -> seq:%d ", anycastInfo.mSequenceNumber); |
| VerifyOrQuit(anycastInfo.mSequenceNumber == test.mPreferredSeqNum); |
| } |
| |
| testFreeInstance(instance); |
| } |
| |
| } // namespace NetworkData |
| } // namespace ot |
| |
| int main(void) |
| { |
| ot::NetworkData::TestNetworkDataIterator(); |
| #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE |
| ot::NetworkData::TestNetworkDataFindNextService(); |
| #endif |
| ot::NetworkData::TestNetworkDataDsnSrpServices(); |
| ot::NetworkData::TestNetworkDataDsnSrpAnycastSeqNumSelection(); |
| |
| printf("\nAll tests passed\n"); |
| return 0; |
| } |