[tlvs] add ReadValueAs() & WriteValueAs() to simplify MeshCop::Tlv (#9661)

This commit introduces template methods `ReadValueAs<>()` and
`WriteValueAs<>()` in `Tlv` class for handling simple TLV types
(single value and uint value). These methods are employed to simplify
the handling of `MeshCoP::Tlv` in `Dataset`. Specifically, the
following TLVs are simplified:

- `PanIdTlv`
- `ExtendedPanIdTlv`
- `PskcTlv`
- `NetworkKeyTlv`
- `MeshLocalPrefixTlv`
- `ActiveTimestampTlv`
- `PendingTimestampTlv`
- `DelayTimerTlv`
- `NetworkKeySequenceTlv`
- `JoinerUdpPortTlv`

These enhance the code by reducing repeated boilerplate code for the
these simple TLVs.
This commit is contained in:
Abtin Keshavarzian
2023-11-29 12:19:52 -08:00
committed by GitHub
parent 1f7ab82ad0
commit 63424e2f0c
12 changed files with 256 additions and 564 deletions
+66
View File
@@ -167,6 +167,23 @@ inline uint64_t ReadUint64(const uint8_t *aBuffer)
(static_cast<uint64_t>(aBuffer[6]) << 8) | (static_cast<uint64_t>(aBuffer[7]) << 0));
}
/**
* Reads a `UintType` integer value from a given buffer assuming big-endian encoding.
*
* @tparam UintType The unsigned int type.
*
* @param[in] aBuffer Pointer to the buffer to read from.
*
* @returns The `UintType` value read from the buffer.
*
*/
template <typename UintType> UintType Read(const uint8_t *aBuffer);
template <> inline uint8_t Read(const uint8_t *aBuffer) { return *aBuffer; }
template <> inline uint16_t Read(const uint8_t *aBuffer) { return ReadUint16(aBuffer); }
template <> inline uint32_t Read(const uint8_t *aBuffer) { return ReadUint32(aBuffer); }
template <> inline uint64_t Read(const uint8_t *aBuffer) { return ReadUint64(aBuffer); }
/**
* Writes a `uint16_t` value to a given buffer using big-endian encoding.
*
@@ -228,6 +245,22 @@ inline void WriteUint64(uint64_t aValue, uint8_t *aBuffer)
aBuffer[7] = (aValue >> 0) & 0xff;
}
/**
* Writes a `UintType` integer value to a given buffer assuming big-endian encoding.
*
* @tparam UintType The unsigned int type.
*
* @param[in] aValue The value to write to buffer.
* @param[in] aBuffer Pointer to the buffer to write to.
*
*/
template <typename UintType> void Write(UintType aValue, uint8_t *aBuffer);
template <> inline void Write(uint8_t aValue, uint8_t *aBuffer) { *aBuffer = aValue; }
template <> inline void Write(uint16_t aValue, uint8_t *aBuffer) { WriteUint16(aValue, aBuffer); }
template <> inline void Write(uint32_t aValue, uint8_t *aBuffer) { WriteUint32(aValue, aBuffer); }
template <> inline void Write(uint64_t aValue, uint8_t *aBuffer) { WriteUint64(aValue, aBuffer); }
} // namespace BigEndian
namespace LittleEndian {
@@ -317,6 +350,23 @@ inline uint64_t ReadUint64(const uint8_t *aBuffer)
(static_cast<uint64_t>(aBuffer[6]) << 48) | (static_cast<uint64_t>(aBuffer[7]) << 56));
}
/**
* Reads a `UintType` integer value from a given buffer assuming little-endian encoding.
*
* @tparam UintType The unsigned int type.
*
* @param[in] aBuffer Pointer to the buffer to read from.
*
* @returns The `UintType` value read from the buffer.
*
*/
template <typename UintType> UintType Read(const uint8_t *aBuffer);
template <> inline uint8_t Read(const uint8_t *aBuffer) { return *aBuffer; }
template <> inline uint16_t Read(const uint8_t *aBuffer) { return ReadUint16(aBuffer); }
template <> inline uint32_t Read(const uint8_t *aBuffer) { return ReadUint32(aBuffer); }
template <> inline uint64_t Read(const uint8_t *aBuffer) { return ReadUint64(aBuffer); }
/**
* Writes a `uint16_t` value to a given buffer using little-endian encoding.
*
@@ -378,6 +428,22 @@ inline void WriteUint64(uint64_t aValue, uint8_t *aBuffer)
aBuffer[7] = (aValue >> 56) & 0xff;
}
/**
* Writes a `UintType` integer value to a given buffer assuming little-endian encoding.
*
* @tparam UintType The unsigned int type.
*
* @param[in] aValue The value to write to buffer.
* @param[in] aBuffer Pointer to the buffer to write to.
*
*/
template <typename UintType> void Write(UintType aValue, uint8_t *aBuffer);
template <> inline void Write(uint8_t aValue, uint8_t *aBuffer) { *aBuffer = aValue; }
template <> inline void Write(uint16_t aValue, uint8_t *aBuffer) { WriteUint16(aValue, aBuffer); }
template <> inline void Write(uint32_t aValue, uint8_t *aBuffer) { WriteUint32(aValue, aBuffer); }
template <> inline void Write(uint64_t aValue, uint8_t *aBuffer) { WriteUint64(aValue, aBuffer); }
} // namespace LittleEndian
} // namespace ot
+68
View File
@@ -173,6 +173,74 @@ public:
*/
Error AppendTo(Message &aMessage) const;
/**
* Reads the value of TLV treating it as a given simple TLV type.
*
* This method requires the TLV to be already validated, in particular, its length MUST NOT be less than the
* required size of the value type. The TLV MUST NOT be extended. If these conditions are not met, the behavior of
* this method is undefined.
*
* @tparam SimpleTlvType The simple TLV type to read (must be a sub-class of `SimpleTlvInfo`).
*
* @returns The TLV value as `SimpleTlvType::ValueType`.
*
*/
template <typename SimpleTlvType> const typename SimpleTlvType::ValueType &ReadValueAs(void) const
{
return *reinterpret_cast<const typename SimpleTlvType::ValueType *>(this + 1);
}
/**
* Reads the value of TLV treating it as a given integer-value TLV type.
*
* This method requires the TLV to be already validated, in particular, its length MUST NOT be less than the
* required size of the value type. The TLV MUST NOT be extended. If these conditions are not met, the behavior of
* this method is undefined.
*
* @tparam UintTlvType The integer simple TLV type to read (must be a sub-class of `UintTlvInfo`).
*
* @returns The TLV value as `UintTlvInfo::UintValueType`.
*
*/
template <typename UintTlvType> typename UintTlvType::UintValueType ReadValueAs(void) const
{
return BigEndian::Read<typename UintTlvType::UintValueType>(reinterpret_cast<const uint8_t *>(this + 1));
}
/**
* Writes the value of TLV treating it as a given simple TLV type.
*
* This method requires the TLV to be already validated, in particular, its length MUST NOT be less than the
* required size of the value type. The TLV MUST NOT be extended. If these conditions are not met, the behavior of
* this method is undefined.
*
* @tparam SimpleTlvType The simple TLV type to read (must be a sub-class of `SimpleTlvInfo`).
*
* @param[in] aValue The new TLV value.
*
*/
template <typename SimpleTlvType> void WriteValueAs(const typename SimpleTlvType::ValueType &aValue)
{
memcpy(this + 1, &aValue, sizeof(aValue));
}
/**
* Writes the value of TLV treating it as a given integer-value TLV type.
*
* This method requires the TLV to be already validated, in particular, its length MUST NOT be less than the
* required size of the value type. The TLV MUST NOT be extended. If these conditions are not met, the behavior of
* this method is undefined.
*
* @tparam UintTlvType The integer simple TLV type to read (must be a sub-class of `UintTlvInfo`).
*
* @param[in] aValue The new TLV value.
*
*/
template <typename UintTlvType> void WriteValueAs(typename UintTlvType::UintValueType aValue)
{
return BigEndian::Write<typename UintTlvType::UintValueType>(aValue, reinterpret_cast<uint8_t *>(this + 1));
}
//------------------------------------------------------------------------------------------------------------------
// Static methods for reading/finding/appending TLVs in a `Message`.
+27 -29
View File
@@ -190,7 +190,7 @@ void Dataset::ConvertTo(Info &aDatasetInfo) const
switch (cur->GetType())
{
case Tlv::kActiveTimestamp:
aDatasetInfo.SetActiveTimestamp(As<ActiveTimestampTlv>(cur)->GetTimestamp());
aDatasetInfo.SetActiveTimestamp(cur->ReadValueAs<ActiveTimestampTlv>());
break;
case Tlv::kChannel:
@@ -210,19 +210,19 @@ void Dataset::ConvertTo(Info &aDatasetInfo) const
}
case Tlv::kDelayTimer:
aDatasetInfo.SetDelay(As<DelayTimerTlv>(cur)->GetDelayTimer());
aDatasetInfo.SetDelay(cur->ReadValueAs<DelayTimerTlv>());
break;
case Tlv::kExtendedPanId:
aDatasetInfo.SetExtendedPanId(As<ExtendedPanIdTlv>(cur)->GetExtendedPanId());
aDatasetInfo.SetExtendedPanId(cur->ReadValueAs<ExtendedPanIdTlv>());
break;
case Tlv::kMeshLocalPrefix:
aDatasetInfo.SetMeshLocalPrefix(As<MeshLocalPrefixTlv>(cur)->GetMeshLocalPrefix());
aDatasetInfo.SetMeshLocalPrefix(cur->ReadValueAs<MeshLocalPrefixTlv>());
break;
case Tlv::kNetworkKey:
aDatasetInfo.SetNetworkKey(As<NetworkKeyTlv>(cur)->GetNetworkKey());
aDatasetInfo.SetNetworkKey(cur->ReadValueAs<NetworkKeyTlv>());
break;
case Tlv::kNetworkName:
@@ -230,15 +230,15 @@ void Dataset::ConvertTo(Info &aDatasetInfo) const
break;
case Tlv::kPanId:
aDatasetInfo.SetPanId(As<PanIdTlv>(cur)->GetPanId());
aDatasetInfo.SetPanId(cur->ReadValueAs<PanIdTlv>());
break;
case Tlv::kPendingTimestamp:
aDatasetInfo.SetPendingTimestamp(As<PendingTimestampTlv>(cur)->GetTimestamp());
aDatasetInfo.SetPendingTimestamp(cur->ReadValueAs<PendingTimestampTlv>());
break;
case Tlv::kPskc:
aDatasetInfo.SetPskc(As<PskcTlv>(cur)->GetPskc());
aDatasetInfo.SetPskc(cur->ReadValueAs<PskcTlv>());
break;
case Tlv::kSecurityPolicy:
@@ -366,21 +366,20 @@ Error Dataset::SetFrom(const Info &aDatasetInfo)
Error Dataset::GetTimestamp(Type aType, Timestamp &aTimestamp) const
{
Error error = kErrorNone;
Error error = kErrorNone;
const Tlv *tlv;
if (aType == kActive)
{
const ActiveTimestampTlv *tlv = GetTlv<ActiveTimestampTlv>();
tlv = GetTlv(Tlv::kActiveTimestamp);
VerifyOrExit(tlv != nullptr, error = kErrorNotFound);
aTimestamp = tlv->GetTimestamp();
aTimestamp = tlv->ReadValueAs<ActiveTimestampTlv>();
}
else
{
const PendingTimestampTlv *tlv = GetTlv<PendingTimestampTlv>();
tlv = GetTlv(Tlv::kPendingTimestamp);
VerifyOrExit(tlv != nullptr, error = kErrorNotFound);
aTimestamp = tlv->GetTimestamp();
aTimestamp = tlv->ReadValueAs<PendingTimestampTlv>();
}
exit:
@@ -479,19 +478,19 @@ Error Dataset::AppendMleDatasetTlv(Type aType, Message &aMessage) const
}
else if (cur->GetType() == Tlv::kDelayTimer)
{
uint32_t elapsed = TimerMilli::GetNow() - mUpdateTime;
DelayTimerTlv delayTimer = *As<DelayTimerTlv>(cur);
uint32_t elapsed = TimerMilli::GetNow() - mUpdateTime;
uint32_t delayTimer = cur->ReadValueAs<DelayTimerTlv>();
if (delayTimer.GetDelayTimer() > elapsed)
if (delayTimer > elapsed)
{
delayTimer.SetDelayTimer(delayTimer.GetDelayTimer() - elapsed);
delayTimer -= elapsed;
}
else
{
delayTimer.SetDelayTimer(0);
delayTimer = 0;
}
SuccessOrExit(error = delayTimer.AppendTo(aMessage));
SuccessOrExit(error = Tlv::Append<DelayTimerTlv>(aMessage, delayTimer));
}
else
{
@@ -545,11 +544,11 @@ Error Dataset::ApplyConfiguration(Instance &aInstance, bool *aIsNetworkKeyUpdate
}
case Tlv::kPanId:
mac.SetPanId(As<PanIdTlv>(cur)->GetPanId());
mac.SetPanId(cur->ReadValueAs<PanIdTlv>());
break;
case Tlv::kExtendedPanId:
aInstance.Get<ExtendedPanIdManager>().SetExtPanId(As<ExtendedPanIdTlv>(cur)->GetExtendedPanId());
aInstance.Get<ExtendedPanIdManager>().SetExtPanId(cur->ReadValueAs<ExtendedPanIdTlv>());
break;
case Tlv::kNetworkName:
@@ -558,30 +557,29 @@ Error Dataset::ApplyConfiguration(Instance &aInstance, bool *aIsNetworkKeyUpdate
case Tlv::kNetworkKey:
{
const NetworkKeyTlv *key = As<NetworkKeyTlv>(cur);
NetworkKey networkKey;
NetworkKey networkKey;
keyManager.GetNetworkKey(networkKey);
if (aIsNetworkKeyUpdated && (key->GetNetworkKey() != networkKey))
if (aIsNetworkKeyUpdated && (cur->ReadValueAs<NetworkKeyTlv>() != networkKey))
{
*aIsNetworkKeyUpdated = true;
}
keyManager.SetNetworkKey(key->GetNetworkKey());
keyManager.SetNetworkKey(cur->ReadValueAs<NetworkKeyTlv>());
break;
}
#if OPENTHREAD_FTD
case Tlv::kPskc:
keyManager.SetPskc(As<PskcTlv>(cur)->GetPskc());
keyManager.SetPskc(cur->ReadValueAs<PskcTlv>());
break;
#endif
case Tlv::kMeshLocalPrefix:
aInstance.Get<Mle::MleRouter>().SetMeshLocalPrefix(As<MeshLocalPrefixTlv>(cur)->GetMeshLocalPrefix());
aInstance.Get<Mle::MleRouter>().SetMeshLocalPrefix(cur->ReadValueAs<MeshLocalPrefixTlv>());
break;
case Tlv::kSecurityPolicy:
+13 -9
View File
@@ -90,9 +90,7 @@ exit:
Error DatasetLocal::Read(Dataset &aDataset) const
{
DelayTimerTlv *delayTimer;
uint32_t elapsed;
Error error;
Error error;
error = Get<Settings>().ReadOperationalDataset(mType, aDataset);
VerifyOrExit(error == kErrorNone, aDataset.mLength = 0);
@@ -108,19 +106,25 @@ Error DatasetLocal::Read(Dataset &aDataset) const
}
else
{
delayTimer = aDataset.GetTlv<DelayTimerTlv>();
VerifyOrExit(delayTimer);
uint32_t elapsed;
uint32_t delayTimer;
Tlv *tlv = aDataset.GetTlv(Tlv::kDelayTimer);
elapsed = TimerMilli::GetNow() - mUpdateTime;
VerifyOrExit(tlv != nullptr);
if (delayTimer->GetDelayTimer() > elapsed)
elapsed = TimerMilli::GetNow() - mUpdateTime;
delayTimer = tlv->ReadValueAs<DelayTimerTlv>();
if (delayTimer > elapsed)
{
delayTimer->SetDelayTimer(delayTimer->GetDelayTimer() - elapsed);
delayTimer -= elapsed;
}
else
{
delayTimer->SetDelayTimer(0);
delayTimer = 0;
}
tlv->WriteValueAs<DelayTimerTlv>(delayTimer);
}
aDataset.mUpdateTime = TimerMilli::GetNow();
+18 -17
View File
@@ -738,41 +738,42 @@ exit:
void PendingDatasetManager::StartDelayTimer(void)
{
DelayTimerTlv *delayTimer;
Dataset dataset;
Tlv *tlv;
uint32_t delay;
Dataset dataset;
IgnoreError(Read(dataset));
mDelayTimer.Stop();
if ((delayTimer = dataset.GetTlv<DelayTimerTlv>()) != nullptr)
{
uint32_t delay = delayTimer->GetDelayTimer();
tlv = dataset.GetTlv(Tlv::kDelayTimer);
VerifyOrExit(tlv != nullptr);
// the Timer implementation does not support the full 32 bit range
if (delay > Timer::kMaxDelay)
{
delay = Timer::kMaxDelay;
}
delay = tlv->ReadValueAs<DelayTimerTlv>();
mDelayTimer.StartAt(dataset.GetUpdateTime(), delay);
LogInfo("delay timer started %lu", ToUlong(delay));
}
// the Timer implementation does not support the full 32 bit range
delay = Min(delay, Timer::kMaxDelay);
mDelayTimer.StartAt(dataset.GetUpdateTime(), delay);
LogInfo("delay timer started %lu", ToUlong(delay));
exit:
return;
}
void PendingDatasetManager::HandleDelayTimer(void)
{
DelayTimerTlv *delayTimer;
Dataset dataset;
Tlv *tlv;
Dataset dataset;
IgnoreError(Read(dataset));
// 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 = dataset.GetTlv<DelayTimerTlv>()) != nullptr)
if ((tlv = dataset.GetTlv(Tlv::kDelayTimer)) != nullptr)
{
uint32_t elapsed = mDelayTimer.GetFireTime() - dataset.GetUpdateTime();
uint32_t delay = delayTimer->GetDelayTimer();
uint32_t delay = tlv->ReadValueAs<DelayTimerTlv>();
if (elapsed < delay)
{
+6
View File
@@ -182,6 +182,12 @@ public:
#endif
protected:
/**
* Default Delay Timer value for a Pending Operational Dataset (ms)
*
*/
static constexpr uint32_t kDefaultDelayTimer = OPENTHREAD_CONFIG_TMF_PENDING_DATASET_DEFAULT_DELAY;
/**
* Defines a generic Dataset TLV to read from a message.
*
+7 -5
View File
@@ -203,16 +203,18 @@ Error DatasetManager::HandleSet(Coap::Message &aMessage, const Ip6::MessageInfo
case Tlv::kDelayTimer:
{
DelayTimerTlv &delayTimerTlv = As<DelayTimerTlv>(datasetTlv);
uint32_t delayTimer = datasetTlv.ReadValueAs<DelayTimerTlv>();
if (doesAffectNetworkKey && delayTimerTlv.GetDelayTimer() < DelayTimerTlv::kDelayTimerDefault)
if (doesAffectNetworkKey && delayTimer < kDefaultDelayTimer)
{
delayTimerTlv.SetDelayTimer(DelayTimerTlv::kDelayTimerDefault);
delayTimer = kDefaultDelayTimer;
}
else if (delayTimerTlv.GetDelayTimer() < Get<Leader>().GetDelayTimerMinimal())
else
{
delayTimerTlv.SetDelayTimer(Get<Leader>().GetDelayTimerMinimal());
delayTimer = Max(delayTimer, Get<Leader>().GetDelayTimerMinimal());
}
datasetTlv.WriteValueAs<DelayTimerTlv>(delayTimer);
}
OT_FALL_THROUGH;
+3 -2
View File
@@ -143,9 +143,10 @@ void DatasetUpdater::PreparePendingDataset(void)
}
{
ActiveTimestampTlv *tlv = dataset.GetTlv<ActiveTimestampTlv>();
Timestamp timestamp = dataset.GetTlv(Tlv::kActiveTimestamp)->ReadValueAs<ActiveTimestampTlv>();
tlv->GetTimestamp().AdvanceRandomTicks();
timestamp.AdvanceRandomTicks();
dataset.SetTimestamp(Dataset::kActive, timestamp);
}
SuccessOrExit(error = Get<PendingDatasetManager>().Save(dataset));
+2 -5
View File
@@ -58,7 +58,7 @@ RegisterLogModule("MeshCoPLeader");
Leader::Leader(Instance &aInstance)
: InstanceLocator(aInstance)
, mTimer(aInstance)
, mDelayTimerMinimal(DelayTimerTlv::kDelayTimerMinimal)
, mDelayTimerMinimal(kMinDelayTimer)
, mSessionId(Random::NonCrypto::GetUint16())
{
}
@@ -218,16 +218,13 @@ Error Leader::SetDelayTimerMinimal(uint32_t aDelayTimerMinimal)
{
Error error = kErrorNone;
VerifyOrExit((aDelayTimerMinimal != 0 && aDelayTimerMinimal < DelayTimerTlv::kDelayTimerDefault),
error = kErrorInvalidArgs);
VerifyOrExit((aDelayTimerMinimal != 0 && aDelayTimerMinimal < kMinDelayTimer), error = kErrorInvalidArgs);
mDelayTimerMinimal = aDelayTimerMinimal;
exit:
return error;
}
uint32_t Leader::GetDelayTimerMinimal(void) const { return mDelayTimerMinimal; }
void Leader::HandleTimer(void)
{
VerifyOrExit(Get<Mle::MleRouter>().IsLeader());
+2 -1
View File
@@ -95,7 +95,7 @@ public:
* @retval the minimal delay timer (in ms).
*
*/
uint32_t GetDelayTimerMinimal(void) const;
uint32_t GetDelayTimerMinimal(void) const { return mDelayTimerMinimal; }
/**
* Sets empty Commissioner Data TLV in the Thread Network Data.
@@ -104,6 +104,7 @@ public:
void SetEmptyCommissionerData(void);
private:
static constexpr uint32_t kMinDelayTimer = OPENTHREAD_CONFIG_TMF_PENDING_DATASET_MINIMUM_DELAY; // (msec)
static constexpr uint32_t kTimeoutLeaderPetition = 50; // TIMEOUT_LEAD_PET (seconds)
OT_TOOL_PACKED_BEGIN
+24 -23
View File
@@ -45,51 +45,52 @@ namespace MeshCoP {
bool Tlv::IsValid(const Tlv &aTlv)
{
bool rval = true;
bool isValid = true;
uint8_t minLength = 0;
switch (aTlv.GetType())
{
case Tlv::kChannel:
rval = As<ChannelTlv>(aTlv).IsValid();
break;
case Tlv::kPanId:
rval = As<PanIdTlv>(aTlv).IsValid();
minLength = sizeof(PanIdTlv::UintValueType);
break;
case Tlv::kExtendedPanId:
rval = As<ExtendedPanIdTlv>(aTlv).IsValid();
minLength = sizeof(ExtendedPanIdTlv::ValueType);
break;
case Tlv::kNetworkName:
rval = As<NetworkNameTlv>(aTlv).IsValid();
break;
case Tlv::kNetworkKey:
rval = As<NetworkKeyTlv>(aTlv).IsValid();
break;
case Tlv::kPskc:
rval = As<PskcTlv>(aTlv).IsValid();
minLength = sizeof(PskcTlv::ValueType);
break;
case Tlv::kNetworkKey:
minLength = sizeof(NetworkKeyTlv::ValueType);
break;
case Tlv::kMeshLocalPrefix:
minLength = sizeof(MeshLocalPrefixTlv::ValueType);
break;
case Tlv::kMeshLocalPrefix:
rval = As<MeshLocalPrefixTlv>(aTlv).IsValid();
case Tlv::kChannel:
isValid = As<ChannelTlv>(aTlv).IsValid();
break;
case Tlv::kNetworkName:
isValid = As<NetworkNameTlv>(aTlv).IsValid();
break;
case Tlv::kSecurityPolicy:
rval = As<SecurityPolicyTlv>(aTlv).IsValid();
isValid = As<SecurityPolicyTlv>(aTlv).IsValid();
break;
case Tlv::kChannelMask:
rval = As<ChannelMaskTlv>(aTlv).IsValid();
isValid = As<ChannelMaskTlv>(aTlv).IsValid();
break;
default:
break;
}
return rval;
if (minLength > 0)
{
isValid = (aTlv.GetLength() >= minLength);
}
return isValid;
}
NameData NetworkNameTlv::GetNetworkName(void) const
+20 -473
View File
@@ -316,98 +316,16 @@ private:
} OT_TOOL_PACKED_END;
/**
* Implements PAN ID TLV generation and parsing.
* Defines PAN ID TLV constants and types.
*
*/
OT_TOOL_PACKED_BEGIN
class PanIdTlv : public Tlv, public UintTlvInfo<Tlv::kPanId, uint16_t>
{
public:
/**
* Initializes the TLV.
*
*/
void Init(void)
{
SetType(kPanId);
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* Indicates whether or not the TLV appears to be well-formed.
*
* @retval TRUE If the TLV appears to be well-formed.
* @retval FALSE If the TLV does not appear to be well-formed.
*
*/
bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
/**
* Returns the PAN ID value.
*
* @returns The PAN ID value.
*
*/
uint16_t GetPanId(void) const { return BigEndian::HostSwap16(mPanId); }
/**
* Sets the PAN ID value.
*
* @param[in] aPanId The PAN ID value.
*
*/
void SetPanId(uint16_t aPanId) { mPanId = BigEndian::HostSwap16(aPanId); }
private:
uint16_t mPanId;
} OT_TOOL_PACKED_END;
typedef UintTlvInfo<Tlv::kPanId, uint16_t> PanIdTlv;
/**
* Implements Extended PAN ID TLV generation and parsing.
* Defines Extended PAN ID TLV constants and types.
*
*/
OT_TOOL_PACKED_BEGIN
class ExtendedPanIdTlv : public Tlv, public SimpleTlvInfo<Tlv::kExtendedPanId, ExtendedPanId>
{
public:
/**
* Initializes the TLV.
*
*/
void Init(void)
{
SetType(kExtendedPanId);
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* Indicates whether or not the TLV appears to be well-formed.
*
* @retval TRUE If the TLV appears to be well-formed.
* @retval FALSE If the TLV does not appear to be well-formed.
*
*/
bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
/**
* Returns the Extended PAN ID value.
*
* @returns The Extended PAN ID value.
*
*/
const ExtendedPanId &GetExtendedPanId(void) const { return mExtendedPanId; }
/**
* Sets the Extended PAN ID value.
*
* @param[in] aExtendedPanId An Extended PAN ID value.
*
*/
void SetExtendedPanId(const ExtendedPanId &aExtendedPanId) { mExtendedPanId = aExtendedPanId; }
private:
ExtendedPanId mExtendedPanId;
} OT_TOOL_PACKED_END;
typedef SimpleTlvInfo<Tlv::kExtendedPanId, ExtendedPanId> ExtendedPanIdTlv;
/**
* Implements Network Name TLV generation and parsing.
@@ -457,203 +375,28 @@ private:
} OT_TOOL_PACKED_END;
/**
* Implements PSKc TLV generation and parsing.
* Defines PSKc TLV constants and types.
*
*/
OT_TOOL_PACKED_BEGIN
class PskcTlv : public Tlv, public SimpleTlvInfo<Tlv::kPskc, Pskc>
{
public:
/**
* Initializes the TLV.
*
*/
void Init(void)
{
SetType(kPskc);
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* Indicates whether or not the TLV appears to be well-formed.
*
* @retval TRUE If the TLV appears to be well-formed.
* @retval FALSE If the TLV does not appear to be well-formed.
*
*/
bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
/**
* Returns the PSKc value.
*
* @returns The PSKc value.
*
*/
const Pskc &GetPskc(void) const { return mPskc; }
/**
* Sets the PSKc value.
*
* @param[in] aPskc A pointer to the PSKc value.
*
*/
void SetPskc(const Pskc &aPskc) { mPskc = aPskc; }
private:
Pskc mPskc;
} OT_TOOL_PACKED_END;
typedef SimpleTlvInfo<Tlv::kPskc, Pskc> PskcTlv;
/**
* Implements Network Network Key TLV generation and parsing.
* Defines Network Key TLV constants and types.
*
*/
OT_TOOL_PACKED_BEGIN
class NetworkKeyTlv : public Tlv, public SimpleTlvInfo<Tlv::kNetworkKey, NetworkKey>
{
public:
/**
* Initializes the TLV.
*
*/
void Init(void)
{
SetType(kNetworkKey);
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* Indicates whether or not the TLV appears to be well-formed.
*
* @retval TRUE If the TLV appears to be well-formed.
* @retval FALSE If the TLV does not appear to be well-formed.
*
*/
bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
/**
* Returns the Network Network Key value.
*
* @returns The Network Network Key value.
*
*/
const NetworkKey &GetNetworkKey(void) const { return mNetworkKey; }
/**
* Sets the Network Network Key value.
*
* @param[in] aNetworkKey The Network Network Key.
*
*/
void SetNetworkKey(const NetworkKey &aNetworkKey) { mNetworkKey = aNetworkKey; }
private:
NetworkKey mNetworkKey;
} OT_TOOL_PACKED_END;
typedef SimpleTlvInfo<Tlv::kNetworkKey, NetworkKey> NetworkKeyTlv;
/**
* Implements Network Key Sequence TLV generation and parsing.
* Defines Network Key Sequence TLV constants and types.
*
*/
OT_TOOL_PACKED_BEGIN
class NetworkKeySequenceTlv : public Tlv, public UintTlvInfo<Tlv::kNetworkKeySequence, uint32_t>
{
public:
/**
* Initializes the TLV.
*
*/
void Init(void)
{
SetType(kNetworkKeySequence);
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* Indicates whether or not the TLV appears to be well-formed.
*
* @retval TRUE If the TLV appears to be well-formed.
* @retval FALSE If the TLV does not appear to be well-formed.
*
*/
bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
/**
* Returns the Network Key Sequence value.
*
* @returns The Network Key Sequence value.
*
*/
uint32_t GetNetworkKeySequence(void) const { return BigEndian::HostSwap32(mNetworkKeySequence); }
/**
* Sets the Network Key Sequence value.
*
* @param[in] aNetworkKeySequence The Network Key Sequence value.
*
*/
void SetNetworkKeySequence(uint32_t aNetworkKeySequence)
{
mNetworkKeySequence = BigEndian::HostSwap32(aNetworkKeySequence);
}
private:
uint32_t mNetworkKeySequence;
} OT_TOOL_PACKED_END;
typedef UintTlvInfo<Tlv::kNetworkKeySequence, uint32_t> NetworkKeySequenceTlv;
/**
* Implements Mesh Local Prefix TLV generation and parsing.
* Defines Mesh Local Prefix TLV constants and types.
*
*/
OT_TOOL_PACKED_BEGIN
class MeshLocalPrefixTlv : public Tlv, public SimpleTlvInfo<Tlv::kMeshLocalPrefix, Ip6::NetworkPrefix>
{
public:
/**
* Initializes the TLV.
*
*/
void Init(void)
{
SetType(kMeshLocalPrefix);
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* Indicates whether or not the TLV appears to be well-formed.
*
* @retval TRUE If the TLV appears to be well-formed.
* @retval FALSE If the TLV does not appear to be well-formed.
*
*/
bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
/**
* Returns the size (in bytes) of the Mesh Local Prefix field.
*
* @returns The size (in bytes) of the Mesh Local Prefix field (8 bytes).
*
*/
uint8_t GetMeshLocalPrefixLength(void) const { return sizeof(mMeshLocalPrefix); }
/**
* Returns the Mesh Local Prefix value.
*
* @returns The Mesh Local Prefix value.
*
*/
const Ip6::NetworkPrefix &GetMeshLocalPrefix(void) const { return mMeshLocalPrefix; }
/**
* Sets the Mesh Local Prefix value.
*
* @param[in] aMeshLocalPrefix A pointer to the Mesh Local Prefix value.
*
*/
void SetMeshLocalPrefix(const Ip6::NetworkPrefix &aMeshLocalPrefix) { mMeshLocalPrefix = aMeshLocalPrefix; }
private:
Ip6::NetworkPrefix mMeshLocalPrefix;
} OT_TOOL_PACKED_END;
typedef SimpleTlvInfo<Tlv::kMeshLocalPrefix, Ip6::NetworkPrefix> MeshLocalPrefixTlv;
class SteeringData;
@@ -868,60 +611,10 @@ private:
} OT_TOOL_PACKED_END;
/**
* Implements Active Timestamp TLV generation and parsing.
* Defines Active Timestamp TLV constants and types.
*
*/
OT_TOOL_PACKED_BEGIN
class ActiveTimestampTlv : public Tlv, public SimpleTlvInfo<Tlv::kActiveTimestamp, Timestamp>
{
public:
/**
* Initializes the TLV.
*
*/
void Init(void)
{
SetType(kActiveTimestamp);
SetLength(sizeof(*this) - sizeof(Tlv));
mTimestamp.Clear();
}
/**
* Indicates whether or not the TLV appears to be well-formed.
*
* @retval TRUE If the TLV appears to be well-formed.
* @retval FALSE If the TLV does not appear to be well-formed.
*
*/
bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
/**
* Gets the timestamp.
*
* @returns The timestamp.
*
*/
const Timestamp &GetTimestamp(void) const { return mTimestamp; }
/**
* Returns a reference to the timestamp.
*
* @returns A reference to the timestamp.
*
*/
Timestamp &GetTimestamp(void) { return mTimestamp; }
/**
* Sets the timestamp.
*
* @param[in] aTimestamp The new timestamp.
*
*/
void SetTimestamp(const Timestamp &aTimestamp) { mTimestamp = aTimestamp; }
private:
Timestamp mTimestamp;
} OT_TOOL_PACKED_END;
typedef SimpleTlvInfo<Tlv::kActiveTimestamp, Timestamp> ActiveTimestampTlv;
/**
* Implements State TLV generation and parsing.
@@ -955,168 +648,22 @@ public:
};
/**
* Implements Joiner UDP Port TLV generation and parsing.
* Defines Joiner UDP Port TLV constants and types.
*
*/
OT_TOOL_PACKED_BEGIN
class JoinerUdpPortTlv : public Tlv, public UintTlvInfo<Tlv::kJoinerUdpPort, uint16_t>
{
public:
/**
* Initializes the TLV.
*
*/
void Init(void)
{
SetType(kJoinerUdpPort);
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* Indicates whether or not the TLV appears to be well-formed.
*
* @retval TRUE If the TLV appears to be well-formed.
* @retval FALSE If the TLV does not appear to be well-formed.
*
*/
bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
/**
* Returns the UDP Port value.
*
* @returns The UDP Port value.
*
*/
uint16_t GetUdpPort(void) const { return BigEndian::HostSwap16(mUdpPort); }
/**
* Sets the UDP Port value.
*
* @param[in] aUdpPort The UDP Port value.
*
*/
void SetUdpPort(uint16_t aUdpPort) { mUdpPort = BigEndian::HostSwap16(aUdpPort); }
private:
uint16_t mUdpPort;
} OT_TOOL_PACKED_END;
typedef UintTlvInfo<Tlv::kJoinerUdpPort, uint16_t> JoinerUdpPortTlv;
/**
* Implements Pending Timestamp TLV generation and parsing.
* Defines Pending Timestamp TLV constants and types.
*
*/
OT_TOOL_PACKED_BEGIN
class PendingTimestampTlv : public Tlv, public SimpleTlvInfo<Tlv::kPendingTimestamp, Timestamp>
{
public:
/**
* Initializes the TLV.
*
*/
void Init(void)
{
SetType(kPendingTimestamp);
SetLength(sizeof(*this) - sizeof(Tlv));
mTimestamp.Clear();
}
/**
* Indicates whether or not the TLV appears to be well-formed.
*
* @retval TRUE If the TLV appears to be well-formed.
* @retval FALSE If the TLV does not appear to be well-formed.
*
*/
bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
/**
* Gets the timestamp.
*
* @returns The timestamp.
*
*/
const Timestamp &GetTimestamp(void) const { return mTimestamp; }
/**
* Returns a reference to the timestamp.
*
* @returns A reference to the timestamp.
*
*/
Timestamp &GetTimestamp(void) { return mTimestamp; }
/**
* Sets the timestamp.
*
* @param[in] aTimestamp The new timestamp.
*
*/
void SetTimestamp(const Timestamp &aTimestamp) { mTimestamp = aTimestamp; }
private:
Timestamp mTimestamp;
} OT_TOOL_PACKED_END;
typedef SimpleTlvInfo<Tlv::kPendingTimestamp, Timestamp> PendingTimestampTlv;
/**
* Implements Delay Timer TLV generation and parsing.
* Defines Delay Timer TLV constants and types.
*
*/
OT_TOOL_PACKED_BEGIN
class DelayTimerTlv : public Tlv, public UintTlvInfo<Tlv::kDelayTimer, uint32_t>
{
public:
/**
* Initializes the TLV.
*
*/
void Init(void)
{
SetType(kDelayTimer);
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* Indicates whether or not the TLV appears to be well-formed.
*
* @retval TRUE If the TLV appears to be well-formed.
* @retval FALSE If the TLV does not appear to be well-formed.
*
*/
bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
/**
* Returns the Delay Timer value.
*
* @returns The Delay Timer value.
*
*/
uint32_t GetDelayTimer(void) const { return BigEndian::HostSwap32(mDelayTimer); }
/**
* Sets the Delay Timer value.
*
* @param[in] aDelayTimer The Delay Timer value.
*
*/
void SetDelayTimer(uint32_t aDelayTimer) { mDelayTimer = BigEndian::HostSwap32(aDelayTimer); }
static constexpr uint32_t kMaxDelayTimer = 259200; ///< Maximum delay timer value for a Pending Dataset in seconds
/**
* Minimum Delay Timer value for a Pending Operational Dataset (ms)
*
*/
static constexpr uint32_t kDelayTimerMinimal = OPENTHREAD_CONFIG_TMF_PENDING_DATASET_MINIMUM_DELAY;
/**
* Default Delay Timer value for a Pending Operational Dataset (ms)
*
*/
static constexpr uint32_t kDelayTimerDefault = OPENTHREAD_CONFIG_TMF_PENDING_DATASET_DEFAULT_DELAY;
private:
uint32_t mDelayTimer;
} OT_TOOL_PACKED_END;
typedef UintTlvInfo<Tlv::kDelayTimer, uint32_t> DelayTimerTlv;
// forward declare ChannelMaskTlv
class ChannelMaskTlv;