[dataset] add GetTlv<Type>(), and SetTlv() for simple TLVs (#4856)

This commit adds helper method `MeshCoP::Tlv::FindTlv()` to search
within a given sequence of TLVs for a specific TLV type. This is used
to simplify `Dataset::GetTlv()` and provide a template version
`GetTlv<TlvType>()`. This commit also adds new flavors of `SetTlv()`
for simple TLVs, i.e, TLVs with a single value which is either an
`uint16_t` or `uint32_t` value or can be treated a data blob.
This commit is contained in:
Abtin Keshavarzian
2020-04-21 10:42:33 -07:00
committed by GitHub
parent 7fd9715d71
commit 29d7e69f23
9 changed files with 366 additions and 175 deletions
+52 -96
View File
@@ -37,6 +37,7 @@
#include <stdio.h>
#include "common/code_utils.hpp"
#include "common/encoding.hpp"
#include "common/instance.hpp"
#include "common/locator-getters.hpp"
#include "common/logging.hpp"
@@ -47,6 +48,9 @@
namespace ot {
namespace MeshCoP {
using ot::Encoding::BigEndian::HostSwap16;
using ot::Encoding::BigEndian::HostSwap32;
Dataset::Dataset(Type aType)
: mUpdateTime(0)
, mLength(0)
@@ -75,44 +79,9 @@ exit:
return rval;
}
Tlv *Dataset::GetTlv(Tlv::Type aType)
{
Tlv *cur = reinterpret_cast<Tlv *>(mTlvs);
Tlv *end = reinterpret_cast<Tlv *>(mTlvs + mLength);
Tlv *rval = NULL;
while (cur < end)
{
if (cur->GetType() == aType)
{
ExitNow(rval = cur);
}
cur = cur->GetNext();
}
exit:
return rval;
}
const Tlv *Dataset::GetTlv(Tlv::Type aType) const
{
const Tlv *cur = reinterpret_cast<const Tlv *>(mTlvs);
const Tlv *end = reinterpret_cast<const Tlv *>(mTlvs + mLength);
const Tlv *rval = NULL;
while (cur < end)
{
if (cur->GetType() == aType)
{
ExitNow(rval = cur);
}
cur = cur->GetNext();
}
exit:
return rval;
return Tlv::FindTlv(mTlvs, mLength, aType);
}
void Dataset::ConvertTo(otOperationalDataset &aDataset) const
@@ -230,10 +199,8 @@ void Dataset::ConvertTo(otOperationalDataset &aDataset) const
}
default:
{
break;
}
}
cur = cur->GetNext();
}
@@ -259,7 +226,7 @@ otError Dataset::SetFrom(const otOperationalDataset &aDataset)
if (aDataset.mComponents.mIsActiveTimestampPresent)
{
MeshCoP::ActiveTimestampTlv tlv;
ActiveTimestampTlv tlv;
tlv.Init();
tlv.SetSeconds(aDataset.mActiveTimestamp);
tlv.SetTicks(0);
@@ -268,7 +235,7 @@ otError Dataset::SetFrom(const otOperationalDataset &aDataset)
if (aDataset.mComponents.mIsPendingTimestampPresent)
{
MeshCoP::PendingTimestampTlv tlv;
PendingTimestampTlv tlv;
tlv.Init();
tlv.SetSeconds(aDataset.mPendingTimestamp);
tlv.SetTicks(0);
@@ -277,15 +244,12 @@ otError Dataset::SetFrom(const otOperationalDataset &aDataset)
if (aDataset.mComponents.mIsDelayPresent)
{
MeshCoP::DelayTimerTlv tlv;
tlv.Init();
tlv.SetDelayTimer(aDataset.mDelay);
SetTlv(tlv);
SetUint32Tlv(Tlv::kDelayTimer, aDataset.mDelay);
}
if (aDataset.mComponents.mIsChannelPresent)
{
MeshCoP::ChannelTlv tlv;
ChannelTlv tlv;
tlv.Init();
tlv.SetChannel(aDataset.mChannel);
SetTlv(tlv);
@@ -293,7 +257,7 @@ otError Dataset::SetFrom(const otOperationalDataset &aDataset)
if (aDataset.mComponents.mIsChannelMaskPresent)
{
MeshCoP::ChannelMaskTlv tlv;
ChannelMaskTlv tlv;
tlv.Init();
tlv.SetChannelMask(aDataset.mChannelMask);
SetTlv(tlv);
@@ -301,55 +265,39 @@ otError Dataset::SetFrom(const otOperationalDataset &aDataset)
if (aDataset.mComponents.mIsExtendedPanIdPresent)
{
MeshCoP::ExtendedPanIdTlv tlv;
tlv.Init();
tlv.SetExtendedPanId(static_cast<const Mac::ExtendedPanId &>(aDataset.mExtendedPanId));
SetTlv(tlv);
SetTlv(Tlv::kExtendedPanId, &aDataset.mExtendedPanId, sizeof(Mac::ExtendedPanId));
}
if (aDataset.mComponents.mIsMeshLocalPrefixPresent)
{
MeshCoP::MeshLocalPrefixTlv tlv;
tlv.Init();
tlv.SetMeshLocalPrefix(static_cast<const Mle::MeshLocalPrefix &>(aDataset.mMeshLocalPrefix));
SetTlv(tlv);
SetTlv(Tlv::kMeshLocalPrefix, &aDataset.mMeshLocalPrefix, sizeof(Mle::MeshLocalPrefix));
}
if (aDataset.mComponents.mIsMasterKeyPresent)
{
MeshCoP::NetworkMasterKeyTlv tlv;
tlv.Init();
tlv.SetNetworkMasterKey(static_cast<const MasterKey &>(aDataset.mMasterKey));
SetTlv(tlv);
SetTlv(Tlv::kNetworkMasterKey, &aDataset.mMasterKey, sizeof(MasterKey));
}
if (aDataset.mComponents.mIsNetworkNamePresent)
{
MeshCoP::NetworkNameTlv tlv;
tlv.Init();
tlv.SetNetworkName(static_cast<const Mac::NetworkName &>(aDataset.mNetworkName).GetAsData());
SetTlv(tlv);
Mac::NameData nameData = static_cast<const Mac::NetworkName &>(aDataset.mNetworkName).GetAsData();
SetTlv(Tlv::kNetworkName, nameData.GetBuffer(), nameData.GetLength());
}
if (aDataset.mComponents.mIsPanIdPresent)
{
MeshCoP::PanIdTlv tlv;
tlv.Init();
tlv.SetPanId(aDataset.mPanId);
SetTlv(tlv);
SetUint16Tlv(Tlv::kPanId, aDataset.mPanId);
}
if (aDataset.mComponents.mIsPskcPresent)
{
MeshCoP::PskcTlv tlv;
tlv.Init();
tlv.SetPskc(static_cast<const Pskc &>(aDataset.mPskc));
SetTlv(tlv);
SetTlv(Tlv::kPskc, &aDataset.mPskc, sizeof(Pskc));
}
if (aDataset.mComponents.mIsSecurityPolicyPresent)
{
MeshCoP::SecurityPolicyTlv tlv;
SecurityPolicyTlv tlv;
tlv.Init();
tlv.SetRotationTime(aDataset.mSecurityPolicy.mRotationTime);
tlv.SetFlags(aDataset.mSecurityPolicy.mFlags);
@@ -367,13 +315,13 @@ const Timestamp *Dataset::GetTimestamp(void) const
if (mType == kActive)
{
const ActiveTimestampTlv *tlv = static_cast<const ActiveTimestampTlv *>(GetTlv(Tlv::kActiveTimestamp));
const ActiveTimestampTlv *tlv = GetTlv<ActiveTimestampTlv>();
VerifyOrExit(tlv != NULL, OT_NOOP);
timestamp = static_cast<const Timestamp *>(tlv);
}
else
{
const PendingTimestampTlv *tlv = static_cast<const PendingTimestampTlv *>(GetTlv(Tlv::kPendingTimestamp));
const PendingTimestampTlv *tlv = GetTlv<PendingTimestampTlv>();
VerifyOrExit(tlv != NULL, OT_NOOP);
timestamp = static_cast<const Timestamp *>(tlv);
}
@@ -384,44 +332,35 @@ exit:
void Dataset::SetTimestamp(const Timestamp &aTimestamp)
{
if (mType == kActive)
{
ActiveTimestampTlv activeTimestamp;
activeTimestamp.Init();
*static_cast<Timestamp *>(&activeTimestamp) = aTimestamp;
SetTlv(activeTimestamp);
}
else
{
PendingTimestampTlv pendingTimestamp;
pendingTimestamp.Init();
*static_cast<Timestamp *>(&pendingTimestamp) = aTimestamp;
SetTlv(pendingTimestamp);
}
SetTlv((mType == kActive) ? Tlv::kActiveTimestamp : Tlv::kPendingTimestamp, &aTimestamp, sizeof(Timestamp));
}
otError Dataset::SetTlv(const Tlv &aTlv)
otError Dataset::SetTlv(Tlv::Type aType, const void *aValue, uint8_t aLength)
{
otError error = OT_ERROR_NONE;
uint16_t bytesAvailable = sizeof(mTlvs) - mLength;
Tlv * old = GetTlv(aTlv.GetType());
Tlv * old = GetTlv(aType);
Tlv tlv;
if (old != NULL)
{
bytesAvailable += sizeof(Tlv) + old->GetLength();
}
VerifyOrExit(sizeof(Tlv) + aTlv.GetLength() <= bytesAvailable, error = OT_ERROR_NO_BUFS);
VerifyOrExit(sizeof(Tlv) + aLength <= bytesAvailable, error = OT_ERROR_NO_BUFS);
// remove old TLV
if (old != NULL)
{
Remove(reinterpret_cast<uint8_t *>(old), sizeof(Tlv) + old->GetLength());
}
// add new TLV
memcpy(mTlvs + mLength, &aTlv, sizeof(Tlv) + aTlv.GetLength());
mLength += sizeof(Tlv) + aTlv.GetLength();
tlv.SetType(aType);
tlv.SetLength(aLength);
memcpy(mTlvs + mLength, &tlv, sizeof(Tlv));
mLength += sizeof(Tlv);
memcpy(mTlvs + mLength, aValue, aLength);
mLength += aLength;
mUpdateTime = TimerMilli::GetNow();
@@ -429,6 +368,25 @@ exit:
return error;
}
otError Dataset::SetTlv(const Tlv &aTlv)
{
return SetTlv(aTlv.GetType(), aTlv.GetValue(), aTlv.GetLength());
}
otError Dataset::SetUint16Tlv(Tlv::Type aType, uint16_t aValue)
{
uint16_t value16 = HostSwap16(aValue);
return SetTlv(aType, &value16, sizeof(uint16_t));
}
otError Dataset::SetUint32Tlv(Tlv::Type aType, uint32_t aValue)
{
uint32_t value32 = HostSwap32(aValue);
return SetTlv(aType, &value32, sizeof(uint32_t));
}
otError Dataset::Set(const Message &aMessage, uint16_t aOffset, uint8_t aLength)
{
otError error = OT_ERROR_NONE;
@@ -600,10 +558,8 @@ otError Dataset::ApplyConfiguration(Instance &aInstance, bool *aIsMasterKeyUpdat
}
default:
{
break;
}
}
cur = cur->GetNext();
}
+60 -1
View File
@@ -103,7 +103,7 @@ public:
* @returns A pointer to the TLV or NULL if none is found.
*
*/
Tlv *GetTlv(Tlv::Type aType);
Tlv *GetTlv(Tlv::Type aType) { return const_cast<Tlv *>(const_cast<const Dataset *>(this)->GetTlv(aType)); }
/**
* This method returns a pointer to the TLV with a given type.
@@ -115,6 +115,28 @@ public:
*/
const Tlv *GetTlv(Tlv::Type aType) const;
/**
* This template method returns a pointer to the TLV with a given template type `TlvType`
*
* @returns A pointer to the TLV or NULL if none is found.
*
*/
template <typename TlvType> TlvType *GetTlv(void)
{
return static_cast<TlvType *>(GetTlv(static_cast<Tlv::Type>(TlvType::kType)));
}
/**
* This template method returns a pointer to the TLV with a given template type `TlvType`
*
* @returns A pointer to the TLV or NULL if none is found.
*
*/
template <typename TlvType> const TlvType *GetTlv(void) const
{
return static_cast<const TlvType *>(GetTlv(static_cast<Tlv::Type>(TlvType::kType)));
}
/**
* This method returns a pointer to the byte representation of the Dataset.
*
@@ -190,6 +212,43 @@ public:
*/
otError SetTlv(const Tlv &aTlv);
/**
* This method sets a TLV with a given TLV Type and Value.
*
* @param[in] aType The TLV Type.
* @param[in] aValue A pointer to TLV Value.
* @param[in] aLength The TLV Length in bytes (length of @p aValue).
*
* @retval OT_ERROR_NONE Successfully set the TLV.
* @retval OT_ERROR_NO_BUFS Could not set the TLV due to insufficient buffer space.
*
*/
otError SetTlv(Tlv::Type aType, const void *aValue, uint8_t aLength);
/**
* This method sets a TLV with a given TLV Type and a `uint16_t` Value.
*
* @param[in] aType The TLV Type.
* @param[in] aValue The TLV value (as `uint16_t`).
*
* @retval OT_ERROR_NONE Successfully set the TLV.
* @retval OT_ERROR_NO_BUFS Could not set the TLV due to insufficient buffer space.
*
*/
otError SetUint16Tlv(Tlv::Type aType, uint16_t aValue);
/**
* This method sets a TLV with a given TLV Type and a `uint32_t` Value.
*
* @param[in] aType The TLV Type.
* @param[in] aValue The TLV value (as `uint32_t`).
*
* @retval OT_ERROR_NONE Successfully set the TLV.
* @retval OT_ERROR_NO_BUFS Could not set the TLV due to insufficient buffer space.
*
*/
otError SetUint32Tlv(Tlv::Type aType, uint32_t aValue);
/**
* This method sets the Dataset using TLVs stored in a message buffer.
*
+1 -1
View File
@@ -105,7 +105,7 @@ otError DatasetLocal::Read(Dataset &aDataset) const
}
else
{
delayTimer = static_cast<DelayTimerTlv *>(aDataset.GetTlv(Tlv::kDelayTimer));
delayTimer = aDataset.GetTlv<DelayTimerTlv>();
VerifyOrExit(delayTimer, OT_NOOP);
elapsed = TimerMilli::GetNow() - mUpdateTime;
+4 -4
View File
@@ -218,7 +218,7 @@ otError DatasetManager::GetChannelMask(Mac::ChannelMask &aChannelMask) const
SuccessOrExit(error = mLocal.Read(dataset));
channelMaskTlv = static_cast<const MeshCoP::ChannelMaskTlv *>(dataset.GetTlv(MeshCoP::Tlv::kChannelMask));
channelMaskTlv = dataset.GetTlv<ChannelMaskTlv>();
VerifyOrExit(channelMaskTlv != NULL, error = OT_ERROR_NOT_FOUND);
VerifyOrExit((mask = channelMaskTlv->GetChannelMask()) != 0, OT_NOOP);
@@ -241,7 +241,7 @@ void DatasetManager::HandleTimer(void)
Dataset dataset(Dataset::kPending);
Get<PendingDataset>().Read(dataset);
const ActiveTimestampTlv *tlv = static_cast<const ActiveTimestampTlv *>(dataset.GetTlv(Tlv::kActiveTimestamp));
const ActiveTimestampTlv *tlv = dataset.GetTlv<ActiveTimestampTlv>();
const Timestamp * pendingActiveTimestamp = static_cast<const Timestamp *>(tlv);
if (pendingActiveTimestamp != NULL && mLocal.Compare(pendingActiveTimestamp) == 0)
@@ -790,7 +790,7 @@ void PendingDataset::StartDelayTimer(void)
mDelayTimer.Stop();
if ((delayTimer = static_cast<DelayTimerTlv *>(dataset.GetTlv(Tlv::kDelayTimer))) != NULL)
if ((delayTimer = dataset.GetTlv<DelayTimerTlv>()) != NULL)
{
uint32_t delay = delayTimer->GetDelayTimer();
@@ -819,7 +819,7 @@ void PendingDataset::HandleDelayTimer(void)
// if the Delay Timer value is larger than what our Timer implementation can handle, we have to compute
// the remainder and wait some more.
if ((delayTimer = static_cast<DelayTimerTlv *>(dataset.GetTlv(Tlv::kDelayTimer))) != NULL)
if ((delayTimer = dataset.GetTlv<DelayTimerTlv>()) != NULL)
{
uint32_t elapsed = mDelayTimer.GetFireTime() - dataset.GetUpdateTime();
uint32_t delay = delayTimer->GetDelayTimer();
+23 -55
View File
@@ -366,8 +366,7 @@ otError ActiveDataset::GenerateLocal(void)
mLocal.Read(dataset);
// Active Timestamp
if (dataset.GetTlv(Tlv::kActiveTimestamp) == NULL)
if (dataset.GetTlv<ActiveTimestampTlv>() == NULL)
{
ActiveTimestampTlv activeTimestampTlv;
activeTimestampTlv.Init();
@@ -376,8 +375,7 @@ otError ActiveDataset::GenerateLocal(void)
dataset.SetTlv(activeTimestampTlv);
}
// Channel
if (dataset.GetTlv(Tlv::kChannel) == NULL)
if (dataset.GetTlv<ChannelTlv>() == NULL)
{
ChannelTlv tlv;
tlv.Init();
@@ -385,8 +383,7 @@ otError ActiveDataset::GenerateLocal(void)
dataset.SetTlv(tlv);
}
// channelMask
if (dataset.GetTlv(Tlv::kChannelMask) == NULL)
if (dataset.GetTlv<ChannelMaskTlv>() == NULL)
{
ChannelMaskTlv tlv;
tlv.Init();
@@ -394,62 +391,39 @@ otError ActiveDataset::GenerateLocal(void)
dataset.SetTlv(tlv);
}
// Extended PAN ID
if (dataset.GetTlv(Tlv::kExtendedPanId) == NULL)
if (dataset.GetTlv<ExtendedPanIdTlv>() == NULL)
{
ExtendedPanIdTlv tlv;
tlv.Init();
tlv.SetExtendedPanId(Get<Mac::Mac>().GetExtendedPanId());
dataset.SetTlv(tlv);
dataset.SetTlv(Tlv::kExtendedPanId, &Get<Mac::Mac>().GetExtendedPanId(), sizeof(Mac::ExtendedPanId));
}
// Mesh-Local Prefix
if (dataset.GetTlv(Tlv::kMeshLocalPrefix) == NULL)
if (dataset.GetTlv<MeshLocalPrefixTlv>() == NULL)
{
MeshLocalPrefixTlv tlv;
tlv.Init();
tlv.SetMeshLocalPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
dataset.SetTlv(tlv);
dataset.SetTlv(Tlv::kMeshLocalPrefix, &Get<Mle::MleRouter>().GetMeshLocalPrefix(),
sizeof(Mle::MeshLocalPrefix));
}
// Master Key
if (dataset.GetTlv(Tlv::kNetworkMasterKey) == NULL)
if (dataset.GetTlv<NetworkMasterKeyTlv>() == NULL)
{
NetworkMasterKeyTlv tlv;
tlv.Init();
tlv.SetNetworkMasterKey(Get<KeyManager>().GetMasterKey());
dataset.SetTlv(tlv);
dataset.SetTlv(Tlv::kNetworkMasterKey, &Get<KeyManager>().GetMasterKey(), sizeof(MasterKey));
}
// Network Name
if (dataset.GetTlv(Tlv::kNetworkName) == NULL)
if (dataset.GetTlv<NetworkNameTlv>() == NULL)
{
NetworkNameTlv tlv;
tlv.Init();
tlv.SetNetworkName(Get<Mac::Mac>().GetNetworkName().GetAsData());
dataset.SetTlv(tlv);
Mac::NameData nameData = Get<Mac::Mac>().GetNetworkName().GetAsData();
dataset.SetTlv(Tlv::kNetworkName, nameData.GetBuffer(), nameData.GetLength());
}
// Pan ID
if (dataset.GetTlv(Tlv::kPanId) == NULL)
if (dataset.GetTlv<PanIdTlv>() == NULL)
{
PanIdTlv tlv;
tlv.Init();
tlv.SetPanId(Get<Mac::Mac>().GetPanId());
dataset.SetTlv(tlv);
dataset.SetUint16Tlv(Tlv::kPanId, Get<Mac::Mac>().GetPanId());
}
// PSKc
if (dataset.GetTlv(Tlv::kPskc) == NULL)
if (dataset.GetTlv<PskcTlv>() == NULL)
{
PskcTlv tlv;
tlv.Init();
if (Get<KeyManager>().IsPskcSet())
{
// use configured PSKc
tlv.SetPskc(Get<KeyManager>().GetPskc());
dataset.SetTlv(Tlv::kPskc, &Get<KeyManager>().GetPskc(), sizeof(Pskc));
}
else
{
@@ -457,14 +431,11 @@ otError ActiveDataset::GenerateLocal(void)
Pskc pskc;
SuccessOrExit(error = pskc.GenerateRandom());
tlv.SetPskc(pskc);
dataset.SetTlv(Tlv::kPskc, &pskc, sizeof(Pskc));
}
dataset.SetTlv(tlv);
}
// Security Policy
if (dataset.GetTlv(Tlv::kSecurityPolicy) == NULL)
if (dataset.GetTlv<SecurityPolicyTlv>() == NULL)
{
SecurityPolicyTlv tlv;
tlv.Init();
@@ -536,9 +507,8 @@ exit:
void PendingDataset::ApplyActiveDataset(const Timestamp &aTimestamp, Coap::Message &aMessage)
{
uint16_t offset = aMessage.GetOffset();
Dataset dataset(mLocal.GetType());
DelayTimerTlv delayTimer;
uint16_t offset = aMessage.GetOffset();
Dataset dataset(mLocal.GetType());
VerifyOrExit(Get<Mle::MleRouter>().IsAttached(), OT_NOOP);
@@ -558,9 +528,7 @@ void PendingDataset::ApplyActiveDataset(const Timestamp &aTimestamp, Coap::Messa
}
// add delay timer tlv
delayTimer.Init();
delayTimer.SetDelayTimer(Get<Leader>().GetDelayTimerMinimal());
dataset.SetTlv(delayTimer);
dataset.SetUint32Tlv(Tlv::kDelayTimer, Get<Leader>().GetDelayTimerMinimal());
// add pending timestamp tlv
dataset.SetTimestamp(aTimestamp);
+4 -4
View File
@@ -370,7 +370,7 @@ Coap::Message *JoinerRouter::PrepareJoinerEntrustMessage(void)
Get<ActiveDataset>().Read(dataset);
if ((tlv = dataset.GetTlv(Tlv::kActiveTimestamp)) != NULL)
if ((tlv = dataset.GetTlv<ActiveTimestampTlv>()) != NULL)
{
SuccessOrExit(error = tlv->AppendTo(*message));
}
@@ -381,7 +381,7 @@ Coap::Message *JoinerRouter::PrepareJoinerEntrustMessage(void)
SuccessOrExit(error = activeTimestamp.AppendTo(*message));
}
if ((tlv = dataset.GetTlv(Tlv::kChannelMask)) != NULL)
if ((tlv = dataset.GetTlv<ChannelMaskTlv>()) != NULL)
{
SuccessOrExit(error = tlv->AppendTo(*message));
}
@@ -392,7 +392,7 @@ Coap::Message *JoinerRouter::PrepareJoinerEntrustMessage(void)
SuccessOrExit(error = channelMask.AppendTo(*message));
}
if ((tlv = dataset.GetTlv(Tlv::kPskc)) != NULL)
if ((tlv = dataset.GetTlv<PskcTlv>()) != NULL)
{
SuccessOrExit(error = tlv->AppendTo(*message));
}
@@ -403,7 +403,7 @@ Coap::Message *JoinerRouter::PrepareJoinerEntrustMessage(void)
SuccessOrExit(error = pskc.AppendTo(*message));
}
if ((tlv = dataset.GetTlv(Tlv::kSecurityPolicy)) != NULL)
if ((tlv = dataset.GetTlv<SecurityPolicyTlv>()) != NULL)
{
SuccessOrExit(error = tlv->AppendTo(*message));
}
+25
View File
@@ -83,6 +83,31 @@ 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 = NULL);
VerifyOrExit(!tlv->IsExtended() ||
(reinterpret_cast<const ExtendedTlv *>(tlv) + 1 <= reinterpret_cast<const ExtendedTlv *>(end)),
tlv = NULL);
VerifyOrExit(tlv->GetNext() <= end, tlv = NULL);
if (tlv->GetType() == aType)
{
ExitNow();
}
}
tlv = NULL;
exit:
return tlv;
}
Mac::NameData NetworkNameTlv::GetNetworkName(void) const
{
uint8_t len = GetLength();
+196 -2
View File
@@ -190,6 +190,63 @@ public:
*/
static bool IsValid(const Tlv &aTlv);
/**
* This static method 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 NULL if not found.
*
*/
static Tlv *FindTlv(uint8_t *aTlvsStart, uint16_t aTlvsLength, Type aType)
{
return const_cast<Tlv *>(FindTlv(const_cast<const uint8_t *>(aTlvsStart), aTlvsLength, aType));
}
/**
* This static method 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 NULL 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 NULL if not found.
*
*/
template <typename TlvType> static TlvType *FindTlv(uint8_t *aTlvsStart, uint16_t aTlvsLength)
{
return static_cast<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 NULL if not found.
*
*/
template <typename TlvType> static const TlvType *FindTlv(const uint8_t *aTlvsStart, uint16_t aTlvsLength)
{
return static_cast<const TlvType *>(FindTlv(aTlvsStart, aTlvsLength, static_cast<Tlv::Type>(TlvType::kType)));
}
} OT_TOOL_PACKED_END;
/**
@@ -225,6 +282,11 @@ OT_TOOL_PACKED_BEGIN
class ChannelTlv : public Tlv
{
public:
enum
{
kType = kChannel, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -290,6 +352,11 @@ OT_TOOL_PACKED_BEGIN
class PanIdTlv : public Tlv
{
public:
enum
{
kType = kPanId, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -337,6 +404,11 @@ OT_TOOL_PACKED_BEGIN
class ExtendedPanIdTlv : public Tlv
{
public:
enum
{
kType = kExtendedPanId, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -384,6 +456,11 @@ OT_TOOL_PACKED_BEGIN
class NetworkNameTlv : public Tlv
{
public:
enum
{
kType = kNetworkName, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -431,6 +508,11 @@ OT_TOOL_PACKED_BEGIN
class PskcTlv : public Tlv
{
public:
enum
{
kType = kPskc, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -478,6 +560,11 @@ OT_TOOL_PACKED_BEGIN
class NetworkMasterKeyTlv : public Tlv
{
public:
enum
{
kType = kNetworkMasterKey, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -525,6 +612,11 @@ OT_TOOL_PACKED_BEGIN
class NetworkKeySequenceTlv : public Tlv
{
public:
enum
{
kType = kNetworkKeySequence, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -572,6 +664,11 @@ OT_TOOL_PACKED_BEGIN
class MeshLocalPrefixTlv : public Tlv
{
public:
enum
{
kType = kMeshLocalPrefix, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -627,6 +724,11 @@ OT_TOOL_PACKED_BEGIN
class SteeringDataTlv : public Tlv
{
public:
enum
{
kType = kSteeringData, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -760,6 +862,11 @@ OT_TOOL_PACKED_BEGIN
class BorderAgentLocatorTlv : public Tlv
{
public:
enum
{
kType = kBorderAgentLocator, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -809,7 +916,8 @@ class CommissionerIdTlv : public Tlv
public:
enum
{
kMaxLength = 64, ///< maximum length (bytes)
kType = kCommissionerId, ///< The TLV Type.
kMaxLength = 64, ///< maximum length (bytes)
};
/**
@@ -866,6 +974,11 @@ OT_TOOL_PACKED_BEGIN
class CommissionerSessionIdTlv : public Tlv
{
public:
enum
{
kType = kCommissionerSessionId, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -913,6 +1026,11 @@ OT_TOOL_PACKED_BEGIN
class SecurityPolicyTlv : public Tlv
{
public:
enum
{
kType = kSecurityPolicy, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -986,6 +1104,11 @@ OT_TOOL_PACKED_BEGIN
class ActiveTimestampTlv : public Tlv, public Timestamp
{
public:
enum
{
kType = kActiveTimestamp, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -1015,6 +1138,11 @@ OT_TOOL_PACKED_BEGIN
class StateTlv : public Tlv
{
public:
enum
{
kType = kState, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -1073,6 +1201,11 @@ OT_TOOL_PACKED_BEGIN
class JoinerUdpPortTlv : public Tlv
{
public:
enum
{
kType = kJoinerUdpPort, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -1120,6 +1253,11 @@ OT_TOOL_PACKED_BEGIN
class PendingTimestampTlv : public Tlv, public Timestamp
{
public:
enum
{
kType = kPendingTimestamp, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -1149,6 +1287,11 @@ OT_TOOL_PACKED_BEGIN
class DelayTimerTlv : public Tlv
{
public:
enum
{
kType = kDelayTimer, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -1374,6 +1517,11 @@ OT_TOOL_PACKED_BEGIN
class ChannelMaskBaseTlv : public Tlv
{
public:
enum
{
kType = kChannelMask, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -1472,6 +1620,11 @@ OT_TOOL_PACKED_BEGIN
class EnergyListTlv : public Tlv
{
public:
enum
{
kType = kEnergyList, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -1502,7 +1655,8 @@ class ProvisioningUrlTlv : public Tlv
public:
enum
{
kMaxLength = OT_PROVISIONING_URL_MAX_SIZE, // Maximum number of chars in the Provisioning URL string.
kType = kProvisioningUrl, ///< The TLV Type.
kMaxLength = OT_PROVISIONING_URL_MAX_SIZE, ///< Maximum number of chars in the Provisioning URL string.
};
/**
@@ -1564,6 +1718,11 @@ OT_TOOL_PACKED_BEGIN
class VendorNameTlv : public Tlv
{
public:
enum
{
kType = kVendorName, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -1628,6 +1787,11 @@ OT_TOOL_PACKED_BEGIN
class VendorModelTlv : public Tlv
{
public:
enum
{
kType = kVendorModel, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -1692,6 +1856,11 @@ OT_TOOL_PACKED_BEGIN
class VendorSwVersionTlv : public Tlv
{
public:
enum
{
kType = kVendorSwVersion, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -1756,6 +1925,11 @@ OT_TOOL_PACKED_BEGIN
class VendorDataTlv : public Tlv
{
public:
enum
{
kType = kVendorData, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -1820,6 +1994,11 @@ OT_TOOL_PACKED_BEGIN
class VendorStackVersionTlv : public Tlv
{
public:
enum
{
kType = kVendorStackVersion, ///< The TLV Type.
};
/**
* Default constructor.
*
@@ -1981,6 +2160,11 @@ OT_TOOL_PACKED_BEGIN
class UdpEncapsulationTlv : public ExtendedTlv
{
public:
enum
{
kType = MeshCoP::Tlv::kUdpEncapsulation, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -2061,6 +2245,11 @@ OT_TOOL_PACKED_BEGIN
class DiscoveryRequestTlv : public Tlv
{
public:
enum
{
kType = kDiscoveryRequest, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
@@ -2148,6 +2337,11 @@ OT_TOOL_PACKED_BEGIN
class DiscoveryResponseTlv : public Tlv
{
public:
enum
{
kType = kDiscoveryResponse, ///< The TLV Type.
};
/**
* This method initializes the TLV.
*
+1 -12
View File
@@ -485,22 +485,11 @@ const MeshCoP::Tlv *LeaderBase::GetCommissioningDataSubTlv(MeshCoP::Tlv::Type aT
{
const MeshCoP::Tlv * rval = NULL;
const NetworkDataTlv *commissioningDataTlv;
const MeshCoP::Tlv * cur;
const MeshCoP::Tlv * end;
commissioningDataTlv = GetCommissioningData();
VerifyOrExit(commissioningDataTlv != NULL, OT_NOOP);
cur = reinterpret_cast<const MeshCoP::Tlv *>(commissioningDataTlv->GetValue());
end = reinterpret_cast<const MeshCoP::Tlv *>(commissioningDataTlv->GetValue() + commissioningDataTlv->GetLength());
for (; cur < end; cur = cur->GetNext())
{
if (cur->GetType() == aType)
{
ExitNow(rval = cur);
}
}
rval = MeshCoP::Tlv::FindTlv(commissioningDataTlv->GetValue(), commissioningDataTlv->GetLength(), aType);
exit:
return rval;