mirror of
https://github.com/espressif/openthread.git
synced 2026-08-01 08:37:47 +00:00
[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:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user