939 lines
38 KiB
C++
939 lines
38 KiB
C++
/*
|
|
* 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 "common/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 uint16_t *aRlocs, uint16_t aRlocsLength, const uint16_t (&aExpectedRlocs)[kLength])
|
|
{
|
|
VerifyOrQuit(aRlocsLength == kLength);
|
|
|
|
printf("\nRLOCs: { ");
|
|
|
|
for (uint8_t index = 0; index < aRlocsLength; index++)
|
|
{
|
|
VerifyOrQuit(aRlocs[index] == aExpectedRlocs[index]);
|
|
printf("0x%04x ", aRlocs[index]);
|
|
}
|
|
|
|
printf("}");
|
|
}
|
|
|
|
void TestNetworkDataIterator(void)
|
|
{
|
|
static constexpr uint8_t kMaxRlocsArray = 10;
|
|
|
|
ot::Instance * instance;
|
|
Iterator iter = kIteratorInit;
|
|
ExternalRouteConfig rconfig;
|
|
OnMeshPrefixConfig pconfig;
|
|
uint16_t rlocs[kMaxRlocsArray];
|
|
uint8_t rlocsLength;
|
|
|
|
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
|
|
},
|
|
{
|
|
{
|
|
{{{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
|
|
},
|
|
};
|
|
|
|
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));
|
|
}
|
|
|
|
rlocsLength = GetArrayLength(rlocs);
|
|
SuccessOrQuit(netData.FindBorderRouters(kAnyRole, rlocs, rlocsLength));
|
|
VerifyRlocsArray(rlocs, rlocsLength, kRlocs);
|
|
VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kRlocs));
|
|
|
|
rlocsLength = GetArrayLength(rlocs);
|
|
SuccessOrQuit(netData.FindBorderRouters(kRouterRoleOnly, rlocs, rlocsLength));
|
|
VerifyRlocsArray(rlocs, rlocsLength, kRlocs);
|
|
VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kRlocs));
|
|
|
|
rlocsLength = GetArrayLength(rlocs);
|
|
SuccessOrQuit(netData.FindBorderRouters(kChildRoleOnly, rlocs, rlocsLength));
|
|
VerifyOrQuit(rlocsLength == 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));
|
|
}
|
|
|
|
rlocsLength = GetArrayLength(rlocs);
|
|
SuccessOrQuit(netData.FindBorderRouters(kAnyRole, rlocs, rlocsLength));
|
|
VerifyRlocsArray(rlocs, rlocsLength, kRlocsAnyRole);
|
|
VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kRlocsAnyRole));
|
|
|
|
rlocsLength = GetArrayLength(rlocs);
|
|
SuccessOrQuit(netData.FindBorderRouters(kRouterRoleOnly, rlocs, rlocsLength));
|
|
VerifyRlocsArray(rlocs, rlocsLength, kRlocsRouterRole);
|
|
VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kRlocsRouterRole));
|
|
|
|
rlocsLength = GetArrayLength(rlocs);
|
|
SuccessOrQuit(netData.FindBorderRouters(kChildRoleOnly, rlocs, rlocsLength));
|
|
VerifyRlocsArray(rlocs, rlocsLength, kRlocsChildRole);
|
|
VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == GetArrayLength(kRlocsChildRole));
|
|
|
|
// Test failure case when given array is smaller than number of RLOCs.
|
|
rlocsLength = GetArrayLength(kRlocsAnyRole) - 1;
|
|
VerifyOrQuit(netData.FindBorderRouters(kAnyRole, rlocs, rlocsLength) == kErrorNoBufs);
|
|
VerifyOrQuit(rlocsLength == GetArrayLength(kRlocsAnyRole) - 1);
|
|
for (uint8_t index = 0; index < rlocsLength; index++)
|
|
{
|
|
VerifyOrQuit(rlocs[index] == kRlocsAnyRole[index]);
|
|
}
|
|
|
|
rlocsLength = GetArrayLength(kRlocsAnyRole);
|
|
SuccessOrQuit(netData.FindBorderRouters(kAnyRole, rlocs, rlocsLength));
|
|
VerifyRlocsArray(rlocs, rlocsLength, 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};
|
|
const uint16_t kRlocsRouterRole[] = {0xec00, 0x2800};
|
|
const uint16_t kRlocsChildRole[] = {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));
|
|
}
|
|
|
|
rlocsLength = GetArrayLength(rlocs);
|
|
SuccessOrQuit(netData.FindBorderRouters(kAnyRole, rlocs, rlocsLength));
|
|
VerifyRlocsArray(rlocs, rlocsLength, kRlocsAnyRole);
|
|
VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kRlocsAnyRole));
|
|
|
|
rlocsLength = GetArrayLength(rlocs);
|
|
SuccessOrQuit(netData.FindBorderRouters(kRouterRoleOnly, rlocs, rlocsLength));
|
|
VerifyRlocsArray(rlocs, rlocsLength, kRlocsRouterRole);
|
|
VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kRlocsRouterRole));
|
|
|
|
rlocsLength = GetArrayLength(rlocs);
|
|
SuccessOrQuit(netData.FindBorderRouters(kChildRoleOnly, rlocs, rlocsLength));
|
|
VerifyRlocsArray(rlocs, rlocsLength, kRlocsChildRole);
|
|
VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == GetArrayLength(kRlocsChildRole));
|
|
|
|
for (uint16_t rloc16 : kRlocsAnyRole)
|
|
{
|
|
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(ot::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)
|
|
{
|
|
ot::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);
|
|
}
|
|
};
|
|
|
|
ot::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;
|
|
|
|
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);
|
|
}
|
|
};
|
|
|
|
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},
|
|
{"fd00:aabb:ccdd:eeff:11:2233:4455:6677", 0xabcd, Service::DnsSrpUnicast::kFromServerData},
|
|
{"fdde:ad00:beef:0:0:ff:fe00:2800", 0x5678, Service::DnsSrpUnicast::kFromServerData},
|
|
{"fd00:1234:5678:9abc:def0:123:4567:89ab", 0x0e, Service::DnsSrpUnicast::kFromServerData},
|
|
{"fdde:ad00:beef:0:0:ff:fe00:6c00", 0xcd12, Service::DnsSrpUnicast::kFromServerData},
|
|
};
|
|
|
|
const uint8_t kPreferredAnycastEntryIndex = 2;
|
|
|
|
Service::Manager & manager = instance->Get<Service::Manager>();
|
|
Service::Manager::Iterator iterator;
|
|
Service::DnsSrpAnycast::Info anycastInfo;
|
|
Service::DnsSrpUnicast::Info unicastInfo;
|
|
|
|
reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(kNetworkData, sizeof(kNetworkData));
|
|
|
|
DumpBuffer("netdata", kNetworkData, sizeof(kNetworkData));
|
|
|
|
// 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 }", unicastInfo.mSockAddr.ToString().AsCString(),
|
|
kOriginStrings[unicastInfo.mOrigin]);
|
|
|
|
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;
|
|
};
|
|
|
|
ot::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;
|
|
}
|