mirror of
https://github.com/espressif/openthread.git
synced 2026-08-03 09:27:47 +00:00
[netdata] get the list or count of RLOC16s of border routers (#7543)
This commit adds a new method in `NetworkData` to find the list of RLOC16 of all border routers providing external IP connectivity. A border router is considered to provide external IP connectivity if it has added at least one external route entry, or an on-mesh prefix with default-route and on-mesh flags set. It also adds a method to count the number of border routers. The methods allow filtering based on the border router device role, including devices in any role, or in router role only, or in child role only. This commit also updates `test_network_data` unit test to validate the behavior of the newly added methods.
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
#include "network_data.hpp"
|
||||
|
||||
#include "coap/coap_message.hpp"
|
||||
#include "common/array.hpp"
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/debug.hpp"
|
||||
#include "common/instance.hpp"
|
||||
@@ -709,5 +710,113 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error NetworkData::FindBorderRouters(RoleFilter aRoleFilter, uint16_t aRlocs[], uint8_t &aRlocsLength) const
|
||||
{
|
||||
class Rlocs // Wrapper over an array of RLOC16s.
|
||||
{
|
||||
public:
|
||||
Rlocs(RoleFilter aRoleFilter, uint16_t *aRlocs, uint8_t aRlocsMaxLength)
|
||||
: mRoleFilter(aRoleFilter)
|
||||
, mRlocs(aRlocs)
|
||||
, mLength(0)
|
||||
, mMaxLength(aRlocsMaxLength)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t GetLength(void) const { return mLength; }
|
||||
|
||||
Error AddRloc16(uint16_t aRloc16)
|
||||
{
|
||||
// Add `aRloc16` into the array if it matches `RoleFilter` and
|
||||
// it is not in the array already. If we need to add the `aRloc16`
|
||||
// but there is no more room in the array, return `kErrorNoBufs`.
|
||||
|
||||
Error error = kErrorNone;
|
||||
uint8_t index;
|
||||
|
||||
switch (mRoleFilter)
|
||||
{
|
||||
case kAnyRole:
|
||||
break;
|
||||
|
||||
case kRouterRoleOnly:
|
||||
VerifyOrExit(Mle::Mle::IsActiveRouter(aRloc16));
|
||||
break;
|
||||
|
||||
case kChildRoleOnly:
|
||||
VerifyOrExit(!Mle::Mle::IsActiveRouter(aRloc16));
|
||||
break;
|
||||
}
|
||||
|
||||
for (index = 0; index < mLength; index++)
|
||||
{
|
||||
if (mRlocs[index] == aRloc16)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == mLength)
|
||||
{
|
||||
VerifyOrExit(mLength < mMaxLength, error = kErrorNoBufs);
|
||||
mRlocs[mLength++] = aRloc16;
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
private:
|
||||
RoleFilter mRoleFilter;
|
||||
uint16_t * mRlocs;
|
||||
uint8_t mLength;
|
||||
uint8_t mMaxLength;
|
||||
};
|
||||
|
||||
Error error = kErrorNone;
|
||||
Rlocs rlocs(aRoleFilter, aRlocs, aRlocsLength);
|
||||
Iterator iterator = kIteratorInit;
|
||||
ExternalRouteConfig route;
|
||||
OnMeshPrefixConfig prefix;
|
||||
|
||||
while (GetNextExternalRoute(iterator, route) == kErrorNone)
|
||||
{
|
||||
SuccessOrExit(error = rlocs.AddRloc16(route.mRloc16));
|
||||
}
|
||||
|
||||
iterator = kIteratorInit;
|
||||
|
||||
while (GetNextOnMeshPrefix(iterator, prefix) == kErrorNone)
|
||||
{
|
||||
if (!prefix.mDefaultRoute || !prefix.mOnMesh)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SuccessOrExit(error = rlocs.AddRloc16(prefix.mRloc16));
|
||||
}
|
||||
|
||||
exit:
|
||||
aRlocsLength = rlocs.GetLength();
|
||||
return error;
|
||||
}
|
||||
|
||||
uint8_t NetworkData::CountBorderRouters(RoleFilter aRoleFilter) const
|
||||
{
|
||||
// We use an over-estimate of max number of border routers in the
|
||||
// Network Data using the facts that network data is limited to 254
|
||||
// bytes and that an external route entry uses at minimum 3 bytes
|
||||
// for RLOC16 and flag, so `ceil(254/3) = 85`.
|
||||
|
||||
static constexpr uint16_t kMaxRlocs = 85;
|
||||
|
||||
uint16_t rlocs[kMaxRlocs];
|
||||
uint8_t rlocsLength = kMaxRlocs;
|
||||
|
||||
SuccessOrAssert(FindBorderRouters(aRoleFilter, rlocs, rlocsLength));
|
||||
|
||||
return rlocsLength;
|
||||
}
|
||||
|
||||
} // namespace NetworkData
|
||||
} // namespace ot
|
||||
|
||||
@@ -324,6 +324,43 @@ public:
|
||||
*/
|
||||
Error GetNextServer(Iterator &aIterator, uint16_t &aRloc16) const;
|
||||
|
||||
/**
|
||||
* This method finds and returns the list of RLOCs of border routers providing external IPv6 connectivity.
|
||||
*
|
||||
* A border router is considered to provide external IPv6 connectivity if it has added at least one external route
|
||||
* entry, or an on-mesh prefix with default-route and on-mesh flags set.
|
||||
*
|
||||
* This method should be used when the RLOC16s are present in the Network Data (when the Network Data contains the
|
||||
* full set and not the stable subset).
|
||||
*
|
||||
* @param[in] aRoleFilter Indicates which devices to include (any role, router role only, or child only).
|
||||
* @param[out] aRlocs Array to output the list of RLOCs.
|
||||
* @param[in,out] aRlocsLength On entry, @p aRlocs array length (max number of elements).
|
||||
* On exit, number RLOC16 entries added in @p aRlocs.
|
||||
*
|
||||
* @retval kErrorNone Successfully found all RLOC16s and updated @p aRlocs and @p aRlocsLength.
|
||||
* @retval kErrorNoBufs Ran out of space in @p aRlocs array. @p aRlocs and @p aRlocsLength are still updated up
|
||||
* to the maximum array length.
|
||||
*
|
||||
*/
|
||||
Error FindBorderRouters(RoleFilter aRoleFilter, uint16_t aRlocs[], uint8_t &aRlocsLength) const;
|
||||
|
||||
/**
|
||||
* This method counts the number of border routers providing external IPv6 connectivity.
|
||||
*
|
||||
* A border router is considered to provide external IPv6 connectivity if it has added at least one external route
|
||||
* entry, or an on-mesh prefix with default-route and on-mesh flags set.
|
||||
*
|
||||
* This method should be used when the RLOC16s are present in the Network Data (when the Network Data contains the
|
||||
* full set and not the stable subset).
|
||||
*
|
||||
* @param[in] aRoleFilter Indicates which RLOCs to include (any role, router only, or child only).
|
||||
*
|
||||
* @returns The number of border routers in Thread Network Data matching @p aRoleFilter.
|
||||
*
|
||||
*/
|
||||
uint8_t CountBorderRouters(RoleFilter aRoleFilter) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* This enumeration defines Service Data match mode.
|
||||
|
||||
@@ -89,6 +89,18 @@ enum RoutePreference : int8_t
|
||||
kRoutePreferenceHigh = OT_ROUTE_PREFERENCE_HIGH, ///< High route preference.
|
||||
};
|
||||
|
||||
/**
|
||||
* This enumeration represents the border router RLOC role filter used when searching for border routers in the Network
|
||||
* Data.
|
||||
*
|
||||
*/
|
||||
enum RoleFilter : uint8_t
|
||||
{
|
||||
kAnyRole, ///< Include devices in any role.
|
||||
kRouterRoleOnly, ///< Include devices that act as Thread router.
|
||||
kChildRoleOnly, ///< Include devices that act as Thread child (end-device).
|
||||
};
|
||||
|
||||
/**
|
||||
* This function indicates whether a given `int8_t` preference value is a valid route preference (i.e., one of the
|
||||
* values from `RoutePreference` enumeration).
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include <openthread/config.h>
|
||||
|
||||
#include "common/array.hpp"
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/instance.hpp"
|
||||
#include "thread/network_data_leader.hpp"
|
||||
@@ -42,7 +43,7 @@ namespace NetworkData {
|
||||
|
||||
void PrintExternalRouteConfig(const ExternalRouteConfig &aConfig)
|
||||
{
|
||||
printf("\nprefix:");
|
||||
printf("\nroute-prefix:");
|
||||
|
||||
for (uint8_t b : aConfig.mPrefix.mPrefix.mFields.m8)
|
||||
{
|
||||
@@ -53,6 +54,19 @@ void PrintExternalRouteConfig(const ExternalRouteConfig &aConfig)
|
||||
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)
|
||||
{
|
||||
@@ -62,11 +76,42 @@ bool CompareExternalRouteConfig(const otExternalRouteConfig &aConfig1, const otE
|
||||
(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 config;
|
||||
ExternalRouteConfig rconfig;
|
||||
OnMeshPrefixConfig pconfig;
|
||||
uint16_t rlocs[kMaxRlocsArray];
|
||||
uint8_t rlocsLength;
|
||||
|
||||
instance = testInitInstance();
|
||||
VerifyOrQuit(instance != nullptr);
|
||||
@@ -104,6 +149,8 @@ void TestNetworkDataIterator(void)
|
||||
},
|
||||
};
|
||||
|
||||
const uint16_t kRlocs[] = {0xc800, 0x5400};
|
||||
|
||||
NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData));
|
||||
|
||||
iter = OT_NETWORK_DATA_ITERATOR_INIT;
|
||||
@@ -113,10 +160,25 @@ void TestNetworkDataIterator(void)
|
||||
|
||||
for (const auto &route : routes)
|
||||
{
|
||||
SuccessOrQuit(netData.GetNextExternalRoute(iter, config));
|
||||
PrintExternalRouteConfig(config);
|
||||
VerifyOrQuit(CompareExternalRouteConfig(config, route));
|
||||
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);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -124,7 +186,7 @@ void TestNetworkDataIterator(void)
|
||||
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, 0x00, 0x00,
|
||||
0x20, 0x03, 0x0E, 0x00, 0x20, 0xFD, 0x00, 0xAB, 0xBA, 0x01, 0x06, 0x54, 0x00, 0x00, 0x04, 0x01, 0x00,
|
||||
};
|
||||
|
||||
otExternalRouteConfig routes[] = {
|
||||
@@ -182,7 +244,7 @@ void TestNetworkDataIterator(void)
|
||||
0x00}}},
|
||||
32,
|
||||
},
|
||||
0x0400, // mRloc16
|
||||
0x0401, // mRloc16
|
||||
0, // mPreference
|
||||
false, // mNat64
|
||||
true, // mStable
|
||||
@@ -190,6 +252,10 @@ void TestNetworkDataIterator(void)
|
||||
},
|
||||
};
|
||||
|
||||
const uint16_t kRlocsAnyRole[] = {0x1000, 0x5400, 0x0401};
|
||||
const uint16_t kRlocsRouterRole[] = {0x1000, 0x5400};
|
||||
const uint16_t kRlocsChildRole[] = {0x0401};
|
||||
|
||||
NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData));
|
||||
|
||||
iter = OT_NETWORK_DATA_ITERATOR_INIT;
|
||||
@@ -199,10 +265,192 @@ void TestNetworkDataIterator(void)
|
||||
|
||||
for (const auto &route : routes)
|
||||
{
|
||||
SuccessOrQuit(netData.GetNextExternalRoute(iter, config));
|
||||
PrintExternalRouteConfig(config);
|
||||
VerifyOrQuit(CompareExternalRouteConfig(config, route));
|
||||
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);
|
||||
}
|
||||
|
||||
{
|
||||
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};
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
testFreeInstance(instance);
|
||||
|
||||
Reference in New Issue
Block a user