mirror of
https://github.com/espressif/openthread.git
synced 2026-08-23 10:49:51 +00:00
[netdata] add TlvIterator and FindSubTlv<TlvType>() (#6621)
This commit contains the following changes: - It adds `TlvIterator` to help iterate over TLVs of a given type in a given sequence of TLVs or sub-TLVs of another TLV. - It adds helper method `PrefixTlv::FindSubTlv<TlvType>()` to search within the sub-TLVs for a specific one. - It moves the `static` helper methods which find a TLV (with a given type) to `NetworkDataTlv` (from `NetworkData`).
This commit is contained in:
@@ -320,6 +320,7 @@ LOCAL_SRC_FILES := \
|
||||
src/core/thread/network_data_local.cpp \
|
||||
src/core/thread/network_data_notifier.cpp \
|
||||
src/core/thread/network_data_service.cpp \
|
||||
src/core/thread/network_data_tlvs.cpp \
|
||||
src/core/thread/network_data_types.cpp \
|
||||
src/core/thread/network_diagnostic.cpp \
|
||||
src/core/thread/panid_query_server.cpp \
|
||||
|
||||
@@ -589,6 +589,7 @@ openthread_core_files = [
|
||||
"thread/network_data_notifier.hpp",
|
||||
"thread/network_data_service.cpp",
|
||||
"thread/network_data_service.hpp",
|
||||
"thread/network_data_tlvs.cpp",
|
||||
"thread/network_data_tlvs.hpp",
|
||||
"thread/network_data_types.cpp",
|
||||
"thread/network_data_types.hpp",
|
||||
|
||||
@@ -193,6 +193,7 @@ set(COMMON_SOURCES
|
||||
thread/network_data_local.cpp
|
||||
thread/network_data_notifier.cpp
|
||||
thread/network_data_service.cpp
|
||||
thread/network_data_tlvs.cpp
|
||||
thread/network_data_types.cpp
|
||||
thread/network_diagnostic.cpp
|
||||
thread/panid_query_server.cpp
|
||||
|
||||
@@ -270,6 +270,7 @@ SOURCES_COMMON = \
|
||||
thread/network_data_local.cpp \
|
||||
thread/network_data_notifier.cpp \
|
||||
thread/network_data_service.cpp \
|
||||
thread/network_data_tlvs.cpp \
|
||||
thread/network_data_types.cpp \
|
||||
thread/network_diagnostic.cpp \
|
||||
thread/panid_query_server.cpp \
|
||||
|
||||
@@ -54,52 +54,6 @@ NetworkData::NetworkData(Instance &aInstance, Type aType)
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
void NetworkData::Clear(void)
|
||||
{
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
const NetworkDataTlv *NetworkData::FindTlv(const NetworkDataTlv *aStart,
|
||||
const NetworkDataTlv *aEnd,
|
||||
NetworkDataTlv::Type aType)
|
||||
{
|
||||
const NetworkDataTlv *tlv;
|
||||
|
||||
for (tlv = aStart; (tlv + 1 <= aEnd) && (tlv->GetNext() <= aEnd); tlv = tlv->GetNext())
|
||||
{
|
||||
if (tlv->GetType() == aType)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
tlv = nullptr;
|
||||
|
||||
exit:
|
||||
return tlv;
|
||||
}
|
||||
|
||||
const NetworkDataTlv *NetworkData::FindTlv(const NetworkDataTlv *aStart,
|
||||
const NetworkDataTlv *aEnd,
|
||||
NetworkDataTlv::Type aType,
|
||||
bool aStable)
|
||||
{
|
||||
const NetworkDataTlv *tlv;
|
||||
|
||||
for (tlv = aStart; (tlv + 1 <= aEnd) && (tlv->GetNext() <= aEnd); tlv = tlv->GetNext())
|
||||
{
|
||||
if ((tlv->GetType() == aType) && (tlv->IsStable() == aStable))
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
tlv = nullptr;
|
||||
|
||||
exit:
|
||||
return tlv;
|
||||
}
|
||||
|
||||
Error NetworkData::GetNetworkData(bool aStable, uint8_t *aData, uint8_t &aDataLength) const
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
@@ -503,7 +457,7 @@ void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, Pref
|
||||
case NetworkDataTlv::kTypeBorderRouter:
|
||||
{
|
||||
BorderRouterTlv *borderRouter = static_cast<BorderRouterTlv *>(cur);
|
||||
ContextTlv * context = FindContext(aPrefix);
|
||||
ContextTlv * context = aPrefix.FindSubTlv<ContextTlv>();
|
||||
|
||||
// Replace p_border_router_16
|
||||
for (BorderRouterEntry *entry = borderRouter->GetFirstEntry(); entry <= borderRouter->GetLastEntry();
|
||||
@@ -587,31 +541,6 @@ void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, Serv
|
||||
}
|
||||
}
|
||||
|
||||
const BorderRouterTlv *NetworkData::FindBorderRouter(const PrefixTlv &aPrefix)
|
||||
{
|
||||
return FindTlv<BorderRouterTlv>(aPrefix.GetSubTlvs(), aPrefix.GetNext());
|
||||
}
|
||||
|
||||
const BorderRouterTlv *NetworkData::FindBorderRouter(const PrefixTlv &aPrefix, bool aStable)
|
||||
{
|
||||
return FindTlv<BorderRouterTlv>(aPrefix.GetSubTlvs(), aPrefix.GetNext(), aStable);
|
||||
}
|
||||
|
||||
const HasRouteTlv *NetworkData::FindHasRoute(const PrefixTlv &aPrefix)
|
||||
{
|
||||
return FindTlv<HasRouteTlv>(aPrefix.GetSubTlvs(), aPrefix.GetNext());
|
||||
}
|
||||
|
||||
const HasRouteTlv *NetworkData::FindHasRoute(const PrefixTlv &aPrefix, bool aStable)
|
||||
{
|
||||
return FindTlv<HasRouteTlv>(aPrefix.GetSubTlvs(), aPrefix.GetNext(), aStable);
|
||||
}
|
||||
|
||||
const ContextTlv *NetworkData::FindContext(const PrefixTlv &aPrefix)
|
||||
{
|
||||
return FindTlv<ContextTlv>(aPrefix.GetSubTlvs(), aPrefix.GetNext());
|
||||
}
|
||||
|
||||
const PrefixTlv *NetworkData::FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) const
|
||||
{
|
||||
return FindPrefix(aPrefix, aPrefixLength, mTlvs, mLength);
|
||||
@@ -622,27 +551,17 @@ const PrefixTlv *NetworkData::FindPrefix(const uint8_t *aPrefix,
|
||||
const uint8_t *aTlvs,
|
||||
uint8_t aTlvsLength)
|
||||
{
|
||||
const NetworkDataTlv *start = reinterpret_cast<const NetworkDataTlv *>(aTlvs);
|
||||
const NetworkDataTlv *end = reinterpret_cast<const NetworkDataTlv *>(aTlvs + aTlvsLength);
|
||||
const PrefixTlv * prefixTlv;
|
||||
TlvIterator tlvIterator(aTlvs, aTlvsLength);
|
||||
const PrefixTlv *prefixTlv;
|
||||
|
||||
while (start < end)
|
||||
while ((prefixTlv = tlvIterator.Iterate<PrefixTlv>()) != nullptr)
|
||||
{
|
||||
prefixTlv = FindTlv<PrefixTlv>(start, end);
|
||||
|
||||
VerifyOrExit(prefixTlv != nullptr);
|
||||
|
||||
if (prefixTlv->IsEqual(aPrefix, aPrefixLength))
|
||||
{
|
||||
ExitNow();
|
||||
break;
|
||||
}
|
||||
|
||||
start = prefixTlv->GetNext();
|
||||
}
|
||||
|
||||
prefixTlv = nullptr;
|
||||
|
||||
exit:
|
||||
return prefixTlv;
|
||||
}
|
||||
|
||||
@@ -670,30 +589,20 @@ const ServiceTlv *NetworkData::FindService(uint32_t aEnterpriseNumber,
|
||||
const uint8_t *aTlvs,
|
||||
uint8_t aTlvsLength)
|
||||
{
|
||||
const NetworkDataTlv *start = reinterpret_cast<const NetworkDataTlv *>(aTlvs);
|
||||
const NetworkDataTlv *end = reinterpret_cast<const NetworkDataTlv *>(aTlvs + aTlvsLength);
|
||||
const ServiceTlv * serviceTlv;
|
||||
TlvIterator tlvIterator(aTlvs, aTlvsLength);
|
||||
const ServiceTlv *serviceTlv;
|
||||
|
||||
while (start < end)
|
||||
while ((serviceTlv = tlvIterator.Iterate<ServiceTlv>()) != nullptr)
|
||||
{
|
||||
serviceTlv = FindTlv<ServiceTlv>(start, end);
|
||||
|
||||
VerifyOrExit(serviceTlv != nullptr);
|
||||
|
||||
if ((serviceTlv->GetEnterpriseNumber() == aEnterpriseNumber) &&
|
||||
(serviceTlv->GetServiceDataLength() >= aServiceDataLength) &&
|
||||
(!aExactServiceDataMatch || (serviceTlv->GetServiceDataLength() == aServiceDataLength)) &&
|
||||
(memcmp(serviceTlv->GetServiceData(), aServiceData, aServiceDataLength) == 0))
|
||||
{
|
||||
ExitNow();
|
||||
break;
|
||||
}
|
||||
|
||||
start = serviceTlv->GetNext();
|
||||
}
|
||||
|
||||
serviceTlv = nullptr;
|
||||
|
||||
exit:
|
||||
return serviceTlv;
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ public:
|
||||
* This method clears the network data.
|
||||
*
|
||||
*/
|
||||
void Clear(void);
|
||||
void Clear(void) { mLength = 0; }
|
||||
|
||||
/**
|
||||
* This method provides a full or stable copy of the Thread Network Data.
|
||||
@@ -340,125 +340,6 @@ protected:
|
||||
*/
|
||||
const NetworkDataTlv *GetTlvsEnd(void) const { return reinterpret_cast<const NetworkDataTlv *>(mTlvs + mLength); }
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the Border Router TLV within a given Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefix A reference to the Prefix TLV.
|
||||
*
|
||||
* @returns A pointer to the Border Router TLV if one is found or nullptr if no Border Router TLV exists.
|
||||
*
|
||||
*/
|
||||
static BorderRouterTlv *FindBorderRouter(PrefixTlv &aPrefix)
|
||||
{
|
||||
return const_cast<BorderRouterTlv *>(FindBorderRouter(const_cast<const PrefixTlv &>(aPrefix)));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the Border Router TLV within a given Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefix A reference to the Prefix TLV.
|
||||
*
|
||||
* @returns A pointer to the Border Router TLV if one is found or nullptr if no Border Router TLV exists.
|
||||
*
|
||||
*/
|
||||
static const BorderRouterTlv *FindBorderRouter(const PrefixTlv &aPrefix);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the stable or non-stable Border Router TLV within a given Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefix A reference to the Prefix TLV.
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable..
|
||||
*
|
||||
* @returns A pointer to the Border Router TLV if one is found or nullptr if no Border Router TLV exists.
|
||||
*
|
||||
*/
|
||||
static BorderRouterTlv *FindBorderRouter(PrefixTlv &aPrefix, bool aStable)
|
||||
{
|
||||
return const_cast<BorderRouterTlv *>(FindBorderRouter(const_cast<const PrefixTlv &>(aPrefix), aStable));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the stable or non-stable Border Router TLV within a given Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefix A reference to the Prefix TLV.
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable..
|
||||
*
|
||||
* @returns A pointer to the Border Router TLV if one is found or nullptr if no Border Router TLV exists.
|
||||
*
|
||||
*/
|
||||
static const BorderRouterTlv *FindBorderRouter(const PrefixTlv &aPrefix, bool aStable);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the Has Route TLV within a given Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefix A reference to the Prefix TLV.
|
||||
*
|
||||
* @returns A pointer to the Has Route TLV if one is found or nullptr if no Has Route TLV exists.
|
||||
*
|
||||
*/
|
||||
static HasRouteTlv *FindHasRoute(PrefixTlv &aPrefix)
|
||||
{
|
||||
return const_cast<HasRouteTlv *>(FindHasRoute(const_cast<const PrefixTlv &>(aPrefix)));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the Has Route TLV within a given Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefix A reference to the Prefix TLV.
|
||||
*
|
||||
* @returns A pointer to the Has Route TLV if one is found or nullptr if no Has Route TLV exists.
|
||||
*
|
||||
*/
|
||||
static const HasRouteTlv *FindHasRoute(const PrefixTlv &aPrefix);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the stable or non-stable Has Route TLV within a given Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefix A reference to the Prefix TLV.
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
|
||||
*
|
||||
* @returns A pointer to the Has Route TLV if one is found or nullptr if no Has Route TLV exists.
|
||||
*
|
||||
*/
|
||||
static HasRouteTlv *FindHasRoute(PrefixTlv &aPrefix, bool aStable)
|
||||
{
|
||||
return const_cast<HasRouteTlv *>(FindHasRoute(const_cast<const PrefixTlv &>(aPrefix), aStable));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the stable or non-stable Has Route TLV within a given Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefix A reference to the Prefix TLV.
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
|
||||
*
|
||||
* @returns A pointer to the Has Route TLV if one is found or nullptr if no Has Route TLV exists.
|
||||
*
|
||||
*/
|
||||
static const HasRouteTlv *FindHasRoute(const PrefixTlv &aPrefix, bool aStable);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the Context TLV within a given Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefix A reference to the Prefix TLV.
|
||||
*
|
||||
* @returns A pointer to the Context TLV if one is found or nullptr if no Context TLV exists.
|
||||
*
|
||||
*/
|
||||
static ContextTlv *FindContext(PrefixTlv &aPrefix)
|
||||
{
|
||||
return const_cast<ContextTlv *>(FindContext(const_cast<const PrefixTlv &>(aPrefix)));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the Context TLV within a given Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefix A reference to the Prefix TLV.
|
||||
*
|
||||
* @returns A pointer to the Context TLV if one is found or nullptr if no Context TLV exists.
|
||||
*
|
||||
*/
|
||||
static const ContextTlv *FindContext(const PrefixTlv &aPrefix);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a Prefix TLV.
|
||||
*
|
||||
@@ -710,139 +591,6 @@ protected:
|
||||
*/
|
||||
Error SendServerDataNotification(uint16_t aRloc16, Coap::ResponseHandler aHandler, void *aContext);
|
||||
|
||||
/**
|
||||
* This static method searches in a given sequence of TLVs to find the first TLV with a given TLV Type.
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
* @param[in] aType The TLV type to find.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
static NetworkDataTlv *FindTlv(NetworkDataTlv *aStart, NetworkDataTlv *aEnd, NetworkDataTlv::Type aType)
|
||||
{
|
||||
return const_cast<NetworkDataTlv *>(
|
||||
FindTlv(const_cast<const NetworkDataTlv *>(aStart), const_cast<const NetworkDataTlv *>(aEnd), aType));
|
||||
}
|
||||
|
||||
/**
|
||||
* This static method searches in a given sequence of TLVs to find the first TLV with a given TLV Type.
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
* @param[in] aType The TLV type to find.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
static const NetworkDataTlv *FindTlv(const NetworkDataTlv *aStart,
|
||||
const NetworkDataTlv *aEnd,
|
||||
NetworkDataTlv::Type aType);
|
||||
|
||||
/**
|
||||
* This static template method searches in a given sequence of TLVs to find the first TLV with a give template
|
||||
* `TlvType`.
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
template <typename TlvType> static TlvType *FindTlv(NetworkDataTlv *aStart, NetworkDataTlv *aEnd)
|
||||
{
|
||||
return static_cast<TlvType *>(FindTlv(aStart, aEnd, static_cast<NetworkDataTlv::Type>(TlvType::kType)));
|
||||
}
|
||||
|
||||
/**
|
||||
* This static template method searches in a given sequence of TLVs to find the first TLV with a give template
|
||||
* `TlvType`.
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
template <typename TlvType> static const TlvType *FindTlv(const NetworkDataTlv *aStart, const NetworkDataTlv *aEnd)
|
||||
{
|
||||
return static_cast<const TlvType *>(FindTlv(aStart, aEnd, static_cast<NetworkDataTlv::Type>(TlvType::kType)));
|
||||
}
|
||||
|
||||
/**
|
||||
* This static method searches in a given sequence of TLVs to find the first TLV with a given TLV Type and stable
|
||||
* flag.
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param [in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
* @param[in] aType The TLV type to find.
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
static NetworkDataTlv *FindTlv(NetworkDataTlv * aStart,
|
||||
NetworkDataTlv * aEnd,
|
||||
NetworkDataTlv::Type aType,
|
||||
bool aStable)
|
||||
{
|
||||
return const_cast<NetworkDataTlv *>(FindTlv(const_cast<const NetworkDataTlv *>(aStart),
|
||||
const_cast<const NetworkDataTlv *>(aEnd), aType, aStable));
|
||||
}
|
||||
|
||||
/**
|
||||
* This static method searches in a given sequence of TLVs to find the first TLV with a given TLV Type and stable
|
||||
* flag.
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param [in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
* @param[in] aType The TLV type to find.
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
static const NetworkDataTlv *FindTlv(const NetworkDataTlv *aStart,
|
||||
const NetworkDataTlv *aEnd,
|
||||
NetworkDataTlv::Type aType,
|
||||
bool aStable);
|
||||
|
||||
/**
|
||||
* This template static method searches in a given sequence of TLVs to find the first TLV with a given TLV Type and
|
||||
* stable flag.
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param [in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
template <typename TlvType> static TlvType *FindTlv(NetworkDataTlv *aStart, NetworkDataTlv *aEnd, bool aStable)
|
||||
{
|
||||
return static_cast<TlvType *>(
|
||||
FindTlv(aStart, aEnd, static_cast<NetworkDataTlv::Type>(TlvType::kType), aStable));
|
||||
}
|
||||
|
||||
/**
|
||||
* This template static method searches in a given sequence of TLVs to find the first TLV with a given TLV Type and
|
||||
* stable flag.
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param [in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
template <typename TlvType>
|
||||
static const TlvType *FindTlv(const NetworkDataTlv *aStart, const NetworkDataTlv *aEnd, bool aStable)
|
||||
{
|
||||
return static_cast<const TlvType *>(
|
||||
FindTlv(aStart, aEnd, static_cast<NetworkDataTlv::Type>(TlvType::kType), aStable));
|
||||
}
|
||||
|
||||
uint8_t mTlvs[kMaxSize]; ///< The Network Data buffer.
|
||||
uint8_t mLength; ///< The number of valid bytes in @var mTlvs.
|
||||
|
||||
|
||||
@@ -96,17 +96,16 @@ exit:
|
||||
const PrefixTlv *LeaderBase::FindNextMatchingPrefix(const Ip6::Address &aAddress, const PrefixTlv *aPrevTlv) const
|
||||
{
|
||||
const PrefixTlv *prefixTlv;
|
||||
TlvIterator tlvIterator((aPrevTlv == nullptr) ? GetTlvsStart() : aPrevTlv->GetNext(), GetTlvsEnd());
|
||||
|
||||
for (const NetworkDataTlv *start = (aPrevTlv == nullptr) ? GetTlvsStart() : aPrevTlv->GetNext();
|
||||
(prefixTlv = FindTlv<PrefixTlv>(start, GetTlvsEnd())) != nullptr; start = prefixTlv->GetNext())
|
||||
while ((prefixTlv = tlvIterator.Iterate<PrefixTlv>()) != nullptr)
|
||||
{
|
||||
if (aAddress.MatchesPrefix(prefixTlv->GetPrefix(), prefixTlv->GetPrefixLength()))
|
||||
{
|
||||
ExitNow();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return prefixTlv;
|
||||
}
|
||||
|
||||
@@ -126,7 +125,7 @@ Error LeaderBase::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aCon
|
||||
|
||||
while ((prefix = FindNextMatchingPrefix(aAddress, prefix)) != nullptr)
|
||||
{
|
||||
contextTlv = FindContext(*prefix);
|
||||
contextTlv = prefix->FindSubTlv<ContextTlv>();
|
||||
|
||||
if (contextTlv == nullptr)
|
||||
{
|
||||
@@ -147,6 +146,7 @@ Error LeaderBase::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aCon
|
||||
Error LeaderBase::GetContext(uint8_t aContextId, Lowpan::Context &aContext) const
|
||||
{
|
||||
Error error = kErrorNotFound;
|
||||
TlvIterator tlvIterator(GetTlvsStart(), GetTlvsEnd());
|
||||
const PrefixTlv *prefix;
|
||||
|
||||
if (aContextId == Mle::kMeshLocalPrefixContextId)
|
||||
@@ -157,10 +157,9 @@ Error LeaderBase::GetContext(uint8_t aContextId, Lowpan::Context &aContext) cons
|
||||
ExitNow(error = kErrorNone);
|
||||
}
|
||||
|
||||
for (const NetworkDataTlv *start = GetTlvsStart(); (prefix = FindTlv<PrefixTlv>(start, GetTlvsEnd())) != nullptr;
|
||||
start = prefix->GetNext())
|
||||
while ((prefix = tlvIterator.Iterate<PrefixTlv>()) != nullptr)
|
||||
{
|
||||
const ContextTlv *contextTlv = FindContext(*prefix);
|
||||
const ContextTlv *contextTlv = prefix->FindSubTlv<ContextTlv>();
|
||||
|
||||
if ((contextTlv == nullptr) || (contextTlv->GetContextId() != aContextId))
|
||||
{
|
||||
@@ -189,7 +188,7 @@ bool LeaderBase::IsOnMesh(const Ip6::Address &aAddress) const
|
||||
// check both stable and temporary Border Router TLVs
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
const BorderRouterTlv *borderRouter = FindBorderRouter(*prefix, /* aStable */ (i == 0));
|
||||
const BorderRouterTlv *borderRouter = prefix->FindSubTlv<BorderRouterTlv>(/* aStable */ (i == 0));
|
||||
|
||||
if (borderRouter == nullptr)
|
||||
{
|
||||
@@ -247,15 +246,16 @@ Error LeaderBase::ExternalRouteLookup(uint8_t aDomainId,
|
||||
uint16_t * aRloc16) const
|
||||
{
|
||||
Error error = kErrorNoRoute;
|
||||
TlvIterator tlvIterator(GetTlvsStart(), GetTlvsEnd());
|
||||
const PrefixTlv * prefixTlv;
|
||||
const HasRouteEntry *bestRouteEntry = nullptr;
|
||||
uint8_t bestMatchLength = 0;
|
||||
|
||||
for (const NetworkDataTlv *start = GetTlvsStart(); (prefixTlv = FindTlv<PrefixTlv>(start, GetTlvsEnd())) != nullptr;
|
||||
start = prefixTlv->GetNext())
|
||||
while ((prefixTlv = tlvIterator.Iterate<PrefixTlv>()) != nullptr)
|
||||
{
|
||||
const HasRouteTlv *hasRoute;
|
||||
uint8_t prefixLength = prefixTlv->GetPrefixLength();
|
||||
TlvIterator subTlvIterator(*prefixTlv);
|
||||
|
||||
if (prefixTlv->GetDomainId() != aDomainId)
|
||||
{
|
||||
@@ -272,9 +272,7 @@ Error LeaderBase::ExternalRouteLookup(uint8_t aDomainId,
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const NetworkDataTlv *subStart = prefixTlv->GetSubTlvs();
|
||||
(hasRoute = FindTlv<HasRouteTlv>(subStart, prefixTlv->GetNext())) != nullptr;
|
||||
subStart = hasRoute->GetNext())
|
||||
while ((hasRoute = subTlvIterator.Iterate<HasRouteTlv>()) != nullptr)
|
||||
{
|
||||
for (const HasRouteEntry *entry = hasRoute->GetFirstEntry(); entry <= hasRoute->GetLastEntry();
|
||||
entry = entry->GetNext())
|
||||
@@ -314,12 +312,11 @@ Error LeaderBase::ExternalRouteLookup(uint8_t aDomainId,
|
||||
Error LeaderBase::DefaultRouteLookup(const PrefixTlv &aPrefix, uint16_t *aRloc16) const
|
||||
{
|
||||
Error error = kErrorNoRoute;
|
||||
TlvIterator subTlvIterator(aPrefix);
|
||||
const BorderRouterTlv * borderRouter;
|
||||
const BorderRouterEntry *route = nullptr;
|
||||
|
||||
for (const NetworkDataTlv *start = aPrefix.GetSubTlvs();
|
||||
(borderRouter = FindTlv<BorderRouterTlv>(start, aPrefix.GetNext())) != nullptr;
|
||||
start = borderRouter->GetNext())
|
||||
while ((borderRouter = subTlvIterator.Iterate<BorderRouterTlv>()) != nullptr)
|
||||
{
|
||||
for (const BorderRouterEntry *entry = borderRouter->GetFirstEntry(); entry <= borderRouter->GetLastEntry();
|
||||
entry = entry->GetNext())
|
||||
@@ -421,7 +418,7 @@ exit:
|
||||
|
||||
const CommissioningDataTlv *LeaderBase::GetCommissioningData(void) const
|
||||
{
|
||||
return FindTlv<CommissioningDataTlv>(GetTlvsStart(), GetTlvsEnd());
|
||||
return NetworkDataTlv::Find<CommissioningDataTlv>(GetTlvsStart(), GetTlvsEnd());
|
||||
}
|
||||
|
||||
const MeshCoP::Tlv *LeaderBase::GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aType) const
|
||||
|
||||
@@ -575,7 +575,7 @@ bool Leader::ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const
|
||||
// Check whether `aPrefix` has a Has Route sub-TLV with stable
|
||||
// flag `aStable` containing a matching entry to `aEntry`.
|
||||
|
||||
return (aPrefix == nullptr) ? false : ContainsMatchingEntry(FindHasRoute(*aPrefix, aStable), aEntry);
|
||||
return (aPrefix == nullptr) ? false : ContainsMatchingEntry(aPrefix->FindSubTlv<HasRouteTlv>(aStable), aEntry);
|
||||
}
|
||||
|
||||
bool Leader::ContainsMatchingEntry(const HasRouteTlv *aHasRoute, const HasRouteEntry &aEntry)
|
||||
@@ -604,7 +604,7 @@ bool Leader::ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const
|
||||
// Check whether `aPrefix` has a Border Router sub-TLV with stable
|
||||
// flag `aStable` containing a matching entry to `aEntry`.
|
||||
|
||||
return (aPrefix == nullptr) ? false : ContainsMatchingEntry(FindBorderRouter(*aPrefix, aStable), aEntry);
|
||||
return (aPrefix == nullptr) ? false : ContainsMatchingEntry(aPrefix->FindSubTlv<BorderRouterTlv>(aStable), aEntry);
|
||||
}
|
||||
|
||||
bool Leader::ContainsMatchingEntry(const BorderRouterTlv *aBorderRouter, const BorderRouterEntry &aEntry)
|
||||
@@ -634,22 +634,23 @@ bool Leader::ContainsMatchingServer(const ServiceTlv *aService, const ServerTlv
|
||||
// Check whether the `aService` has a matching Server sub-TLV
|
||||
// same as `aServer`.
|
||||
|
||||
bool contains = false;
|
||||
const ServerTlv *server;
|
||||
bool contains = false;
|
||||
|
||||
VerifyOrExit(aService != nullptr);
|
||||
|
||||
for (const NetworkDataTlv *start = aService->GetSubTlvs();
|
||||
(server = FindTlv<ServerTlv>(start, aService->GetNext(), aServer.IsStable())) != nullptr;
|
||||
start = server->GetNext())
|
||||
if (aService != nullptr)
|
||||
{
|
||||
if (*server == aServer)
|
||||
const ServerTlv *server;
|
||||
TlvIterator subTlvIterator(*aService);
|
||||
|
||||
while ((server = subTlvIterator.Iterate<ServerTlv>(aServer.IsStable())) != nullptr)
|
||||
{
|
||||
ExitNow(contains = true);
|
||||
if (*server == aServer)
|
||||
{
|
||||
contains = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return contains;
|
||||
}
|
||||
|
||||
@@ -804,7 +805,7 @@ Error Leader::AddService(const ServiceTlv &aService, ChangedFlags &aChangedFlags
|
||||
aService.GetServiceDataLength());
|
||||
}
|
||||
|
||||
server = FindTlv<ServerTlv>(aService.GetSubTlvs(), aService.GetNext());
|
||||
server = NetworkDataTlv::Find<ServerTlv>(aService.GetSubTlvs(), aService.GetNext());
|
||||
OT_ASSERT(server != nullptr);
|
||||
|
||||
SuccessOrExit(error = AddServer(*server, *dstService, aChangedFlags));
|
||||
@@ -827,7 +828,7 @@ exit:
|
||||
Error Leader::AddHasRoute(const HasRouteTlv &aHasRoute, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
HasRouteTlv * dstHasRoute = FindHasRoute(aDstPrefix, aHasRoute.IsStable());
|
||||
HasRouteTlv * dstHasRoute = aDstPrefix.FindSubTlv<HasRouteTlv>(aHasRoute.IsStable());
|
||||
const HasRouteEntry *entry = aHasRoute.GetFirstEntry();
|
||||
|
||||
if (dstHasRoute == nullptr)
|
||||
@@ -864,8 +865,8 @@ exit:
|
||||
Error Leader::AddBorderRouter(const BorderRouterTlv &aBorderRouter, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
BorderRouterTlv * dstBorderRouter = FindBorderRouter(aDstPrefix, aBorderRouter.IsStable());
|
||||
ContextTlv * dstContext = FindContext(aDstPrefix);
|
||||
BorderRouterTlv * dstBorderRouter = aDstPrefix.FindSubTlv<BorderRouterTlv>(aBorderRouter.IsStable());
|
||||
ContextTlv * dstContext = aDstPrefix.FindSubTlv<ContextTlv>();
|
||||
uint8_t contextId = 0;
|
||||
const BorderRouterEntry *entry = aBorderRouter.GetFirstEntry();
|
||||
|
||||
@@ -976,20 +977,17 @@ Error Leader::AllocateServiceId(uint8_t &aServiceId) const
|
||||
|
||||
const ServiceTlv *Leader::FindServiceById(uint8_t aServiceId) const
|
||||
{
|
||||
const NetworkDataTlv *start = GetTlvsStart();
|
||||
const ServiceTlv * service;
|
||||
const ServiceTlv *service;
|
||||
TlvIterator tlvIterator(GetTlvsStart(), GetTlvsEnd());
|
||||
|
||||
while ((service = FindTlv<ServiceTlv>(start, GetTlvsEnd())) != nullptr)
|
||||
while ((service = tlvIterator.Iterate<ServiceTlv>()) != nullptr)
|
||||
{
|
||||
if (service->GetServiceId() == aServiceId)
|
||||
{
|
||||
ExitNow();
|
||||
break;
|
||||
}
|
||||
|
||||
start = service->GetNext();
|
||||
}
|
||||
|
||||
exit:
|
||||
return service;
|
||||
}
|
||||
|
||||
@@ -1154,7 +1152,7 @@ void Leader::RemoveRlocInPrefix(PrefixTlv & aPrefix,
|
||||
cur = cur->GetNext();
|
||||
}
|
||||
|
||||
if ((context = FindContext(aPrefix)) != nullptr)
|
||||
if ((context = aPrefix.FindSubTlv<ContextTlv>()) != nullptr)
|
||||
{
|
||||
if (aPrefix.GetSubTlvsLength() == sizeof(ContextTlv))
|
||||
{
|
||||
@@ -1181,7 +1179,7 @@ void Leader::RemoveRlocInService(ServiceTlv & aService,
|
||||
NetworkDataTlv *start = aService.GetSubTlvs();
|
||||
ServerTlv * server;
|
||||
|
||||
while ((server = FindTlv<ServerTlv>(start, aService.GetNext())) != nullptr)
|
||||
while ((server = NetworkDataTlv::Find<ServerTlv>(start, aService.GetNext())) != nullptr)
|
||||
{
|
||||
if (RlocMatch(server->GetServer16(), aRloc16, aMatchMode) && !ContainsMatchingServer(aExcludeService, *server))
|
||||
{
|
||||
@@ -1260,7 +1258,7 @@ void Leader::RemoveContext(uint8_t aContextId)
|
||||
NetworkDataTlv *start = GetTlvsStart();
|
||||
PrefixTlv * prefix;
|
||||
|
||||
while ((prefix = FindTlv<PrefixTlv>(start, GetTlvsEnd())) != nullptr)
|
||||
while ((prefix = NetworkDataTlv::Find<PrefixTlv>(start, GetTlvsEnd())) != nullptr)
|
||||
{
|
||||
RemoveContext(*prefix, aContextId);
|
||||
|
||||
@@ -1279,7 +1277,7 @@ void Leader::RemoveContext(PrefixTlv &aPrefix, uint8_t aContextId)
|
||||
NetworkDataTlv *start = aPrefix.GetSubTlvs();
|
||||
ContextTlv * context;
|
||||
|
||||
while ((context = FindTlv<ContextTlv>(start, aPrefix.GetNext())) != nullptr)
|
||||
while ((context = NetworkDataTlv::Find<ContextTlv>(start, aPrefix.GetNext())) != nullptr)
|
||||
{
|
||||
if (context->GetContextId() == aContextId)
|
||||
{
|
||||
@@ -1295,13 +1293,12 @@ void Leader::RemoveContext(PrefixTlv &aPrefix, uint8_t aContextId)
|
||||
|
||||
void Leader::UpdateContextsAfterReset(void)
|
||||
{
|
||||
NetworkDataTlv *start;
|
||||
PrefixTlv * prefix;
|
||||
const PrefixTlv *prefix;
|
||||
TlvIterator tlvIterator(GetTlvsStart(), GetTlvsEnd());
|
||||
|
||||
for (start = GetTlvsStart(); (prefix = FindTlv<PrefixTlv>(start, GetTlvsEnd())) != nullptr;
|
||||
start = prefix->GetNext())
|
||||
while ((prefix = tlvIterator.Iterate<PrefixTlv>()) != nullptr)
|
||||
{
|
||||
ContextTlv *context = FindContext(*prefix);
|
||||
const ContextTlv *context = prefix->FindSubTlv<ContextTlv>();
|
||||
|
||||
if (context == nullptr)
|
||||
{
|
||||
|
||||
@@ -143,7 +143,7 @@ Error Local::RemovePrefix(const Ip6::Prefix &aPrefix, NetworkDataTlv::Type aSubT
|
||||
PrefixTlv *tlv;
|
||||
|
||||
VerifyOrExit((tlv = FindPrefix(aPrefix)) != nullptr, error = kErrorNotFound);
|
||||
VerifyOrExit(FindTlv(tlv->GetSubTlvs(), tlv->GetNext(), aSubTlvType) != nullptr, error = kErrorNotFound);
|
||||
VerifyOrExit(tlv->FindSubTlv(aSubTlvType) != nullptr, error = kErrorNotFound);
|
||||
RemoveTlv(tlv);
|
||||
|
||||
exit:
|
||||
|
||||
@@ -255,7 +255,7 @@ Error Manager::IterateToNextServer(Iterator &aIterator) const
|
||||
|
||||
VerifyOrExit(aIterator.mServiceTlv != nullptr);
|
||||
|
||||
aIterator.mServerSubTlv = NetworkData::FindTlv<ServerTlv>(
|
||||
aIterator.mServerSubTlv = NetworkDataTlv::Find<ServerTlv>(
|
||||
/* aStart */ (aIterator.mServerSubTlv != nullptr) ? aIterator.mServerSubTlv->GetNext()
|
||||
: aIterator.mServiceTlv->GetSubTlvs(),
|
||||
/* aEnd */ aIterator.mServiceTlv->GetNext());
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2016-21, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements methods for generating and processing Thread Network Data TLVs.
|
||||
*/
|
||||
|
||||
#include "network_data_tlvs.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace NetworkData {
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// NetworkDataTlv
|
||||
|
||||
const NetworkDataTlv *NetworkDataTlv::Find(const NetworkDataTlv *aStart, const NetworkDataTlv *aEnd, Type aType)
|
||||
{
|
||||
const NetworkDataTlv *tlv;
|
||||
|
||||
for (tlv = aStart; (tlv + 1 <= aEnd) && (tlv->GetNext() <= aEnd); tlv = tlv->GetNext())
|
||||
{
|
||||
if (tlv->GetType() == aType)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
tlv = nullptr;
|
||||
|
||||
exit:
|
||||
return tlv;
|
||||
}
|
||||
|
||||
const NetworkDataTlv *NetworkDataTlv::Find(const NetworkDataTlv *aStart,
|
||||
const NetworkDataTlv *aEnd,
|
||||
Type aType,
|
||||
bool aStable)
|
||||
{
|
||||
const NetworkDataTlv *tlv;
|
||||
|
||||
for (tlv = aStart; (tlv + 1 <= aEnd) && (tlv->GetNext() <= aEnd); tlv = tlv->GetNext())
|
||||
{
|
||||
if ((tlv->GetType() == aType) && (tlv->IsStable() == aStable))
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
tlv = nullptr;
|
||||
|
||||
exit:
|
||||
return tlv;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// PrefixTlv
|
||||
|
||||
const NetworkDataTlv *PrefixTlv::FindSubTlv(Type aType) const
|
||||
{
|
||||
return Find(GetSubTlvs(), GetNext(), aType);
|
||||
}
|
||||
|
||||
const NetworkDataTlv *PrefixTlv::FindSubTlv(Type aType, bool aStable) const
|
||||
{
|
||||
return Find(GetSubTlvs(), GetNext(), aType, aStable);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// TlvIterator
|
||||
|
||||
const NetworkDataTlv *TlvIterator::Iterate(NetworkDataTlv::Type aType)
|
||||
{
|
||||
const NetworkDataTlv *tlv = NetworkDataTlv::Find(mStart, mEnd, aType);
|
||||
|
||||
VerifyOrExit(tlv != nullptr);
|
||||
mStart = tlv->GetNext();
|
||||
|
||||
exit:
|
||||
return tlv;
|
||||
}
|
||||
|
||||
const NetworkDataTlv *TlvIterator::Iterate(NetworkDataTlv::Type aType, bool aStable)
|
||||
{
|
||||
const NetworkDataTlv *tlv = NetworkDataTlv::Find(mStart, mEnd, aType, aStable);
|
||||
|
||||
VerifyOrExit(tlv != nullptr);
|
||||
mStart = tlv->GetNext();
|
||||
|
||||
exit:
|
||||
return tlv;
|
||||
}
|
||||
|
||||
} // namespace NetworkData
|
||||
} // namespace ot
|
||||
@@ -68,21 +68,11 @@ OT_TOOL_PACKED_BEGIN
|
||||
class NetworkDataTlv
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method initializes TLV.
|
||||
*
|
||||
*/
|
||||
void Init(void)
|
||||
{
|
||||
mType = 0;
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread Network Data Type values.
|
||||
*
|
||||
*/
|
||||
enum Type
|
||||
enum Type : uint8_t
|
||||
{
|
||||
kTypeHasRoute = 0, ///< Has Route TLV
|
||||
kTypePrefix = 1, ///< Prefix TLV
|
||||
@@ -93,6 +83,16 @@ public:
|
||||
kTypeServer = 6, ///< Server TLV
|
||||
};
|
||||
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
*
|
||||
*/
|
||||
void Init(void)
|
||||
{
|
||||
mType = 0;
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the Type value.
|
||||
*
|
||||
@@ -209,6 +209,138 @@ public:
|
||||
*/
|
||||
void SetStable(void) { mType |= kStableMask; }
|
||||
|
||||
/**
|
||||
* This static method searches in a given sequence of TLVs to find the first TLV with a given type.
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
* @param[in] aType The TLV type to find.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
static NetworkDataTlv *Find(NetworkDataTlv *aStart, NetworkDataTlv *aEnd, Type aType)
|
||||
{
|
||||
return const_cast<NetworkDataTlv *>(
|
||||
Find(const_cast<const NetworkDataTlv *>(aStart), const_cast<const NetworkDataTlv *>(aEnd), aType));
|
||||
}
|
||||
|
||||
/**
|
||||
* This static method searches in a given sequence of TLVs to find the first TLV with a given type.
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
* @param[in] aType The TLV type to find.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
static const NetworkDataTlv *Find(const NetworkDataTlv *aStart, const NetworkDataTlv *aEnd, Type aType);
|
||||
|
||||
/**
|
||||
* This template static method searches in a given sequence of TLVs to find the first TLV with a given type.
|
||||
*
|
||||
* @tparam TlvType The TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
template <typename TlvType> static TlvType *Find(NetworkDataTlv *aStart, NetworkDataTlv *aEnd)
|
||||
{
|
||||
return static_cast<TlvType *>(Find(aStart, aEnd, TlvType::kType));
|
||||
}
|
||||
|
||||
/**
|
||||
* This template static method searches in a given sequence of TLVs to find the first TLV with a given type.
|
||||
*
|
||||
* @tparam TlvType The TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
template <typename TlvType> static const TlvType *Find(const NetworkDataTlv *aStart, const NetworkDataTlv *aEnd)
|
||||
{
|
||||
return static_cast<const TlvType *>(Find(aStart, aEnd, TlvType::kType));
|
||||
}
|
||||
|
||||
/**
|
||||
* This static method searches in a given sequence of TLVs to find the first TLV with a given TLV type and stable
|
||||
* flag.
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
* @param[in] aType The TLV type to find.
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
static NetworkDataTlv *Find(NetworkDataTlv *aStart, NetworkDataTlv *aEnd, Type aType, bool aStable)
|
||||
{
|
||||
return const_cast<NetworkDataTlv *>(
|
||||
Find(const_cast<const NetworkDataTlv *>(aStart), const_cast<const NetworkDataTlv *>(aEnd), aType, aStable));
|
||||
}
|
||||
|
||||
/**
|
||||
* This static method searches in a given sequence of TLVs to find the first TLV with a given TLV type and stable
|
||||
* flag.
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
* @param[in] aType The TLV type to find.
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
static const NetworkDataTlv *Find(const NetworkDataTlv *aStart,
|
||||
const NetworkDataTlv *aEnd,
|
||||
Type aType,
|
||||
bool aStable);
|
||||
|
||||
/**
|
||||
* This template static method searches in a given sequence of TLVs to find the first TLV with a given TLV type and
|
||||
* stable flag.
|
||||
*
|
||||
* @tparam TlvType The TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
template <typename TlvType> static TlvType *Find(NetworkDataTlv *aStart, NetworkDataTlv *aEnd, bool aStable)
|
||||
{
|
||||
return static_cast<TlvType *>(Find(aStart, aEnd, TlvType::kType, aStable));
|
||||
}
|
||||
|
||||
/**
|
||||
* This template static method searches in a given sequence of TLVs to find the first TLV with a given TLV type and
|
||||
* stable flag.
|
||||
*
|
||||
* @tparam TlvType The TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aEnd A pointer to the end of the sequence of TLVs.
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
template <typename TlvType>
|
||||
static const TlvType *Find(const NetworkDataTlv *aStart, const NetworkDataTlv *aEnd, bool aStable)
|
||||
{
|
||||
return static_cast<const TlvType *>(Find(aStart, aEnd, TlvType::kType, aStable));
|
||||
}
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
@@ -324,10 +456,7 @@ OT_TOOL_PACKED_BEGIN
|
||||
class HasRouteTlv : public NetworkDataTlv
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kType = kTypeHasRoute, ///< The TLV Type.
|
||||
};
|
||||
static constexpr Type kType = kTypeHasRoute; ///< The TLV Type.
|
||||
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
@@ -426,10 +555,7 @@ OT_TOOL_PACKED_BEGIN
|
||||
class PrefixTlv : public NetworkDataTlv
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kType = kTypePrefix, ///< The TLV Type.
|
||||
};
|
||||
static constexpr Type kType = kTypePrefix; ///< The TLV Type.
|
||||
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
@@ -533,7 +659,7 @@ public:
|
||||
* @param[in] aPrefixLength The prefix length pointed to by @p aPrefix (in bits).
|
||||
*
|
||||
* @retval TRUE The TLV's Prefix is equal to @p aPrefix.
|
||||
* @retval FALSE The TLV's Prefix is not euqal @p aPrefix.
|
||||
* @retval FALSE The TLV's Prefix is not equal @p aPrefix.
|
||||
*
|
||||
*/
|
||||
bool IsEqual(const uint8_t *aPrefix, uint8_t aPrefixLength) const
|
||||
@@ -587,6 +713,110 @@ public:
|
||||
SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + Ip6::Prefix::SizeForLength(mPrefixLength) + aLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* This template method searches in the sub-TLVs to find the first one matching a given TLV type.
|
||||
*
|
||||
* @tparam SubTlvType The sub-TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
template <typename SubTlvType> SubTlvType *FindSubTlv(void)
|
||||
{
|
||||
return static_cast<SubTlvType *>(FindSubTlv(SubTlvType::kType));
|
||||
}
|
||||
|
||||
/**
|
||||
* This template method searches in the sub-TLVs to find the first one matching a given TLV Type.
|
||||
*
|
||||
* @tparam SubTlvType The sub-TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
template <typename SubTlvType> const SubTlvType *FindSubTlv(void) const
|
||||
{
|
||||
return static_cast<const SubTlvType *>(FindSubTlv(SubTlvType::kType));
|
||||
}
|
||||
|
||||
/**
|
||||
* This template method searches in the sub-TLVs to find the first one matching a given TLV type and stable flag.
|
||||
*
|
||||
* @tparam SubTlvType The sub-TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
|
||||
*
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
template <typename SubTlvType> SubTlvType *FindSubTlv(bool aStable)
|
||||
{
|
||||
return static_cast<SubTlvType *>(FindSubTlv(static_cast<Type>(SubTlvType::kType), aStable));
|
||||
}
|
||||
|
||||
/**
|
||||
* This template method searches in the sub-TLVs to find the first one matching a given TLV type and stable flag.
|
||||
*
|
||||
* @tparam SubTlvType The sub-TLV type to search for (MUST be a sub-class of `NetworkDataTlv`).
|
||||
*
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
template <typename SubTlvType> const SubTlvType *FindSubTlv(bool aStable) const
|
||||
{
|
||||
return static_cast<const SubTlvType *>(FindSubTlv(static_cast<Type>(SubTlvType::kType), aStable));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method searches in the sub-TLVs to find the first one matching a given TLV type.
|
||||
*
|
||||
* @param[in] aType The sub-TLV type to search for.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
NetworkDataTlv *FindSubTlv(Type aType)
|
||||
{
|
||||
return const_cast<NetworkDataTlv *>(const_cast<const PrefixTlv *>(this)->FindSubTlv(aType));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method searches in the sub-TLVs to find the first one matching a given TLV type.
|
||||
*
|
||||
* @param[in] aType The sub-TLV type to search for.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
const NetworkDataTlv *FindSubTlv(Type aType) const;
|
||||
|
||||
/**
|
||||
* This method searches in the sub-TLVs to find the first one matching a given TLV type and stable flag.
|
||||
*
|
||||
* @param[in] aType The sub-TLV type to search for.
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
NetworkDataTlv *FindSubTlv(Type aType, bool aStable)
|
||||
{
|
||||
return const_cast<NetworkDataTlv *>(const_cast<const PrefixTlv *>(this)->FindSubTlv(aType, aStable));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method searches in the sub-TLVs to find the first one matching a given TLV type and stable flag.
|
||||
*
|
||||
* @param[in] aType The sub-TLV type to search for.
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or nullptr if not found.
|
||||
*
|
||||
*/
|
||||
const NetworkDataTlv *FindSubTlv(Type aType, bool aStable) const;
|
||||
|
||||
/**
|
||||
* This static method calculates the total size (number of bytes) of a Prefix TLV with a given Prefix Length value.
|
||||
*
|
||||
@@ -789,10 +1019,7 @@ OT_TOOL_PACKED_BEGIN
|
||||
class BorderRouterTlv : public NetworkDataTlv
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kType = kTypeBorderRouter, ///< The TLV Type.
|
||||
};
|
||||
static constexpr Type kType = kTypeBorderRouter; ///< The TLV Type.
|
||||
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
@@ -894,10 +1121,7 @@ OT_TOOL_PACKED_BEGIN
|
||||
class ContextTlv : public NetworkDataTlv
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kType = kTypeContext, ///< The TLV Type.
|
||||
};
|
||||
static constexpr Type kType = kTypeContext; ///< The TLV Type.
|
||||
|
||||
/**
|
||||
* This method initializes the Context TLV.
|
||||
@@ -971,10 +1195,7 @@ OT_TOOL_PACKED_BEGIN
|
||||
class CommissioningDataTlv : public NetworkDataTlv
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kType = kTypeCommissioningData, ///< The TLV Type.
|
||||
};
|
||||
static constexpr Type kType = kTypeCommissioningData; ///< The TLV Type.
|
||||
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
@@ -996,10 +1217,7 @@ OT_TOOL_PACKED_BEGIN
|
||||
class ServiceTlv : public NetworkDataTlv
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kType = kTypeService, ///< The TLV Type.
|
||||
};
|
||||
static constexpr Type kType = kTypeService; ///< The TLV Type.
|
||||
|
||||
enum : uint32_t
|
||||
{
|
||||
@@ -1205,10 +1423,7 @@ OT_TOOL_PACKED_BEGIN
|
||||
class ServerTlv : public NetworkDataTlv
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kType = kTypeServer, ///< The TLV Type.
|
||||
};
|
||||
static constexpr Type kType = kTypeServer; ///< The TLV Type.
|
||||
|
||||
/**
|
||||
* This method initializes the Server TLV.
|
||||
@@ -1298,6 +1513,97 @@ private:
|
||||
uint16_t mServer16;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
* This class represents a Network Data TLV iterator.
|
||||
*
|
||||
*/
|
||||
class TlvIterator
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the `TlvIterator` to iterate over a given sequence of TLVs.
|
||||
*
|
||||
* @param[in] aStart A pointer to the start of the TLV sequence.
|
||||
* @param[in] aEnd A pointer to the end of the TLV sequence.
|
||||
*
|
||||
*/
|
||||
TlvIterator(const NetworkDataTlv *aStart, const NetworkDataTlv *aEnd)
|
||||
: mStart(aStart)
|
||||
, mEnd(aEnd)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor initializes the `TlvIterator` to iterate over TLVs from a given buffer.
|
||||
*
|
||||
* @param[in] aBuffer A pointer to a buffer containing the TLVs.
|
||||
* @param[in] aLength The length (number of bytes) of @p aBuffer.
|
||||
*
|
||||
*/
|
||||
TlvIterator(const uint8_t *aBuffer, uint8_t aLength)
|
||||
: TlvIterator(reinterpret_cast<const NetworkDataTlv *>(aBuffer),
|
||||
reinterpret_cast<const NetworkDataTlv *>(aBuffer + aLength))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor initializes the `TlvIterator` to iterate over sub-TLVs of a given Prefix TLV.
|
||||
*
|
||||
* @param[in] aPrefixTlv A Prefix TLV to iterate over its sub-TLVs.
|
||||
*
|
||||
*/
|
||||
explicit TlvIterator(const PrefixTlv &aPrefixTlv)
|
||||
: TlvIterator(aPrefixTlv.GetSubTlvs(), aPrefixTlv.GetNext())
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor initializes the `TlvIterator` to iterate over sub-TLVs of a given Service TLV.
|
||||
*
|
||||
* @param[in] aServiceTlv A Service TLV to iterate over its sub-TLVs.
|
||||
*
|
||||
*/
|
||||
explicit TlvIterator(const ServiceTlv &aServiceTlv)
|
||||
: TlvIterator(aServiceTlv.GetSubTlvs(), aServiceTlv.GetNext())
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This template method iterates to the next TLV with a given type.
|
||||
*
|
||||
* @tparam TlvType The TLV Type to search for (MUST be a sub-class of `NetworkDataTlv`).
|
||||
*
|
||||
* @returns A pointer to the next TLV, or nullptr if it can not be found.
|
||||
*
|
||||
*/
|
||||
template <typename TlvType> const TlvType *Iterate(void)
|
||||
{
|
||||
return static_cast<const TlvType *>(Iterate(TlvType::kType));
|
||||
}
|
||||
|
||||
/**
|
||||
* This template method iterates to the next TLV with a given type and stable flag.
|
||||
*
|
||||
* @tparam TlvType The TLV Type to search for (MUST be a sub-class of `NetworkDataTlv`).
|
||||
*
|
||||
* @param[in] aStable TRUE to find a stable TLV, FALSE to find a TLV not marked as stable.
|
||||
*
|
||||
* @returns A pointer to the next TLV, or nullptr if it can not be found.
|
||||
*
|
||||
*/
|
||||
template <typename TlvType> const TlvType *Iterate(bool aStable)
|
||||
{
|
||||
return static_cast<const TlvType *>(Iterate(TlvType::kType, aStable));
|
||||
}
|
||||
|
||||
private:
|
||||
const NetworkDataTlv *Iterate(NetworkDataTlv::Type aType);
|
||||
const NetworkDataTlv *Iterate(NetworkDataTlv::Type aType, bool aStable);
|
||||
|
||||
const NetworkDataTlv *mStart;
|
||||
const NetworkDataTlv *mEnd;
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user