mirror of
https://github.com/espressif/openthread.git
synced 2026-08-23 10:49:51 +00:00
[tlv] add helper method to find/read TLVs in a sequence of TLVs (#9538)
This commit moves the helper methods to find a specific TLV in a sequence of TLVs from the `MeshCoP::Tlv` class to the base `Tlv` class. This makes these helper methods accessible to all subclasses.
This commit is contained in:
@@ -271,7 +271,7 @@ template Error Tlv::FindUintTlv<uint8_t>(const Message &aMessage, uint8_t aType,
|
||||
template Error Tlv::FindUintTlv<uint16_t>(const Message &aMessage, uint8_t aType, uint16_t &aValue);
|
||||
template Error Tlv::FindUintTlv<uint32_t>(const Message &aMessage, uint8_t aType, uint32_t &aValue);
|
||||
|
||||
Error Tlv::FindTlv(const Message &aMessage, uint8_t aType, void *aValue, uint8_t aLength)
|
||||
Error Tlv::FindTlv(const Message &aMessage, uint8_t aType, void *aValue, uint16_t aLength)
|
||||
{
|
||||
Error error;
|
||||
uint16_t offset;
|
||||
@@ -322,4 +322,32 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
const Tlv *Tlv::FindTlv(const void *aTlvsStart, uint16_t aTlvsLength, uint8_t aType)
|
||||
{
|
||||
const Tlv *tlv;
|
||||
const Tlv *end = reinterpret_cast<const Tlv *>(reinterpret_cast<const uint8_t *>(aTlvsStart) + aTlvsLength);
|
||||
|
||||
for (tlv = reinterpret_cast<const Tlv *>(aTlvsStart); tlv < end; tlv = tlv->GetNext())
|
||||
{
|
||||
VerifyOrExit((tlv + 1) <= end, tlv = nullptr);
|
||||
|
||||
if (tlv->IsExtended())
|
||||
{
|
||||
VerifyOrExit((As<ExtendedTlv>(tlv) + 1) <= As<ExtendedTlv>(end), tlv = nullptr);
|
||||
}
|
||||
|
||||
VerifyOrExit(tlv->GetNext() <= end, tlv = nullptr);
|
||||
|
||||
if (tlv->GetType() == aType)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
tlv = nullptr;
|
||||
|
||||
exit:
|
||||
return tlv;
|
||||
}
|
||||
|
||||
} // namespace ot
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <openthread/thread.h>
|
||||
#include <openthread/platform/toolchain.h>
|
||||
|
||||
#include "common/const_cast.hpp"
|
||||
#include "common/encoding.hpp"
|
||||
#include "common/error.hpp"
|
||||
#include "common/type_traits.hpp"
|
||||
@@ -174,6 +175,9 @@ public:
|
||||
*/
|
||||
Error AppendTo(Message &aMessage) const;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Static methods for reading/finding/appending TLVs in a `Message`.
|
||||
|
||||
/**
|
||||
* Reads a TLV's value in a message at a given offset expecting a minimum length for the value.
|
||||
*
|
||||
@@ -538,6 +542,68 @@ public:
|
||||
return AppendStringTlv(aMessage, StringTlvType::kType, StringTlvType::kMaxStringLength, aValue);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Static methods for finding TLVs within a sequence of TLVs.
|
||||
|
||||
/**
|
||||
* Searches in a given sequence of TLVs to find the first TLV of a given type.
|
||||
*
|
||||
* @param[in] aTlvsStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aTlvsLength The length (number of bytes) in the TLV sequence.
|
||||
* @param[in] aType The TLV type to search for.
|
||||
*
|
||||
* @returns A pointer to the TLV within the TLV sequence if found, or `nullptr` if not found.
|
||||
*
|
||||
*/
|
||||
static const Tlv *FindTlv(const void *aTlvsStart, uint16_t aTlvsLength, uint8_t aType);
|
||||
|
||||
/**
|
||||
* Searches in a given sequence of TLVs to find the first TLV of a given type.
|
||||
*
|
||||
* @param[in] aTlvsStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aTlvsLength The length (number of bytes) in the TLV sequence.
|
||||
* @param[in] aType The TLV type to search for.
|
||||
*
|
||||
* @returns A pointer to the TLV within the TLV sequence if found, or `nullptr` if not found.
|
||||
*
|
||||
*/
|
||||
static Tlv *FindTlv(void *aTlvsStart, uint16_t aTlvsLength, uint8_t aType)
|
||||
{
|
||||
return AsNonConst(FindTlv(AsConst(aTlvsStart), aTlvsLength, aType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches in a given sequence of TLVs to find the first TLV with a give template `TlvType`.
|
||||
*
|
||||
* @tparam kTlvType The TLV Type.
|
||||
*
|
||||
* @param[in] aTlvsStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aTlvsLength The length (number of bytes) in TLV sequence.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or `nullptr` if not found.
|
||||
*
|
||||
*/
|
||||
template <typename TlvType> static TlvType *Find(void *aTlvsStart, uint16_t aTlvsLength)
|
||||
{
|
||||
return static_cast<TlvType *>(FindTlv(aTlvsStart, aTlvsLength, TlvType::kType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches in a given sequence of TLVs to find the first TLV with a give template `TlvType`.
|
||||
*
|
||||
* @tparam kTlvType The TLV Type.
|
||||
*
|
||||
* @param[in] aTlvsStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aTlvsLength The length (number of bytes) in TLV sequence.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or `nullptr` if not found.
|
||||
*
|
||||
*/
|
||||
template <typename TlvType> static const TlvType *Find(const void *aTlvsStart, uint16_t aTlvsLength)
|
||||
{
|
||||
return static_cast<const TlvType *>(FindTlv(aTlvsStart, aTlvsLength, TlvType::kType));
|
||||
}
|
||||
|
||||
protected:
|
||||
static const uint8_t kExtendedLength = 255; // Extended Length value.
|
||||
|
||||
@@ -554,7 +620,7 @@ private:
|
||||
uint16_t mSize;
|
||||
};
|
||||
|
||||
static Error FindTlv(const Message &aMessage, uint8_t aType, void *aValue, uint8_t aLength);
|
||||
static Error FindTlv(const Message &aMessage, uint8_t aType, void *aValue, uint16_t aLength);
|
||||
static Error AppendTlv(Message &aMessage, uint8_t aType, const void *aValue, uint8_t aLength);
|
||||
static Error ReadStringTlv(const Message &aMessage, uint16_t aOffset, uint8_t aMaxStringLength, char *aValue);
|
||||
static Error FindStringTlv(const Message &aMessage, uint8_t aType, uint8_t aMaxStringLength, char *aValue);
|
||||
|
||||
@@ -179,7 +179,7 @@ exit:
|
||||
return rval;
|
||||
}
|
||||
|
||||
const Tlv *Dataset::GetTlv(Tlv::Type aType) const { return Tlv::FindTlv(mTlvs, mLength, aType); }
|
||||
const Tlv *Dataset::GetTlv(Tlv::Type aType) const { return As<Tlv>(Tlv::FindTlv(mTlvs, mLength, aType)); }
|
||||
|
||||
void Dataset::ConvertTo(Info &aDatasetInfo) const
|
||||
{
|
||||
|
||||
@@ -91,31 +91,6 @@ bool Tlv::IsValid(const Tlv &aTlv)
|
||||
return rval;
|
||||
}
|
||||
|
||||
const Tlv *Tlv::FindTlv(const uint8_t *aTlvsStart, uint16_t aTlvsLength, Type aType)
|
||||
{
|
||||
const Tlv *tlv;
|
||||
const Tlv *end = reinterpret_cast<const Tlv *>(aTlvsStart + aTlvsLength);
|
||||
|
||||
for (tlv = reinterpret_cast<const Tlv *>(aTlvsStart); tlv < end; tlv = tlv->GetNext())
|
||||
{
|
||||
VerifyOrExit((tlv + 1) <= end, tlv = nullptr);
|
||||
VerifyOrExit(!tlv->IsExtended() ||
|
||||
(reinterpret_cast<const ExtendedTlv *>(tlv) + 1 <= reinterpret_cast<const ExtendedTlv *>(end)),
|
||||
tlv = nullptr);
|
||||
VerifyOrExit(tlv->GetNext() <= end, tlv = nullptr);
|
||||
|
||||
if (tlv->GetType() == aType)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
tlv = nullptr;
|
||||
|
||||
exit:
|
||||
return tlv;
|
||||
}
|
||||
|
||||
NameData NetworkNameTlv::GetNetworkName(void) const
|
||||
{
|
||||
uint8_t len = GetLength();
|
||||
|
||||
@@ -163,43 +163,6 @@ public:
|
||||
*/
|
||||
const Tlv *GetNext(void) const { return As<Tlv>(ot::Tlv::GetNext()); }
|
||||
|
||||
/**
|
||||
* Reads the requested TLV out of @p aMessage.
|
||||
*
|
||||
* @param[in] aMessage A reference to the message.
|
||||
* @param[in] aType The Type value to search for.
|
||||
* @param[in] aMaxLength Maximum number of bytes to read.
|
||||
* @param[out] aTlv A reference to the TLV that will be copied to.
|
||||
*
|
||||
* @retval kErrorNone Successfully copied the TLV.
|
||||
* @retval kErrorNotFound Could not find the TLV with Type @p aType.
|
||||
*
|
||||
*/
|
||||
static Error FindTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv)
|
||||
{
|
||||
return ot::Tlv::FindTlv(aMessage, static_cast<uint8_t>(aType), aMaxLength, aTlv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the requested TLV out of @p aMessage.
|
||||
*
|
||||
* Can be used independent of whether the read TLV (from message) is an Extended TLV or not.
|
||||
*
|
||||
* @tparam TlvType The TlvType to search for (must be a sub-class of `Tlv`).
|
||||
*
|
||||
* @param[in] aMessage A reference to the message.
|
||||
* @param[out] aTlv A reference to the TLV that will be copied to.
|
||||
*
|
||||
* @retval kErrorNone Successfully copied the TLV.
|
||||
* @retval kErrorNotFound Could not find the TLV with Type @p aType.
|
||||
*
|
||||
*/
|
||||
|
||||
template <typename TlvType> static Error FindTlv(const Message &aMessage, TlvType &aTlv)
|
||||
{
|
||||
return ot::Tlv::FindTlv(aMessage, aTlv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether a TLV appears to be well-formed.
|
||||
*
|
||||
@@ -210,63 +173,6 @@ public:
|
||||
*/
|
||||
static bool IsValid(const Tlv &aTlv);
|
||||
|
||||
/**
|
||||
* Searches in a given sequence of TLVs to find the first TLV with a given template Type.
|
||||
*
|
||||
* @param[in] aTlvsStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aTlvsLength The length (number of bytes) in TLV sequence.
|
||||
* @param[in] aType The TLV Type to search for.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or `nullptr` if not found.
|
||||
*
|
||||
*/
|
||||
static Tlv *FindTlv(uint8_t *aTlvsStart, uint16_t aTlvsLength, Type aType)
|
||||
{
|
||||
return AsNonConst(FindTlv(AsConst(aTlvsStart), aTlvsLength, aType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches in a given sequence of TLVs to find the first TLV with a given template Type.
|
||||
*
|
||||
* @param[in] aTlvsStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aTlvsLength The length (number of bytes) in TLV sequence.
|
||||
* @param[in] aType The TLV Type to search for.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or `nullptr` if not found.
|
||||
*
|
||||
*/
|
||||
static const Tlv *FindTlv(const uint8_t *aTlvsStart, uint16_t aTlvsLength, 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] aTlvsStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aTlvsLength The length (number of bytes) in TLV sequence.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or `nullptr` if not found.
|
||||
*
|
||||
*/
|
||||
template <typename TlvType> static TlvType *FindTlv(uint8_t *aTlvsStart, uint16_t aTlvsLength)
|
||||
{
|
||||
return As<TlvType>(FindTlv(aTlvsStart, aTlvsLength, static_cast<Tlv::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] aTlvsStart A pointer to the start of the sequence of TLVs to search within.
|
||||
* @param[in] aTlvsLength The length (number of bytes) in TLV sequence.
|
||||
*
|
||||
* @returns A pointer to the TLV if found, or `nullptr` if not found.
|
||||
*
|
||||
*/
|
||||
template <typename TlvType> static const TlvType *FindTlv(const uint8_t *aTlvsStart, uint16_t aTlvsLength)
|
||||
{
|
||||
return As<TlvType>(FindTlv(aTlvsStart, aTlvsLength, static_cast<Tlv::Type>(TlvType::kType)));
|
||||
}
|
||||
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
|
||||
@@ -466,7 +466,7 @@ const MeshCoP::Tlv *LeaderBase::GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aT
|
||||
commissioningDataTlv = GetCommissioningData();
|
||||
VerifyOrExit(commissioningDataTlv != nullptr);
|
||||
|
||||
rval = MeshCoP::Tlv::FindTlv(commissioningDataTlv->GetValue(), commissioningDataTlv->GetLength(), aType);
|
||||
rval = As<MeshCoP::Tlv>(Tlv::FindTlv(commissioningDataTlv->GetValue(), commissioningDataTlv->GetLength(), aType));
|
||||
|
||||
exit:
|
||||
return rval;
|
||||
|
||||
Reference in New Issue
Block a user