blob: 4b1dd6725e7c673076d7ec706a94b1d444170543 [file] [log] [blame]
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for generating and processing MLE TLVs.
*/
#ifndef MLE_TLVS_HPP_
#define MLE_TLVS_HPP_
#include "openthread-core-config.h"
#include "common/encoding.hpp"
#include "common/message.hpp"
#include "common/tlvs.hpp"
#include "meshcop/timestamp.hpp"
#include "net/ip6_address.hpp"
#include "thread/link_metrics_tlvs.hpp"
#include "thread/mle_types.hpp"
namespace ot {
namespace Mle {
using ot::Encoding::BigEndian::HostSwap16;
using ot::Encoding::BigEndian::HostSwap32;
/**
* @addtogroup core-mle-tlvs
*
* @brief
* This module includes definitions for generating and processing MLE TLVs.
*
* @{
*
*/
/**
* This class implements MLE TLV generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class Tlv : public ot::Tlv
{
public:
/**
* MLE TLV Types.
*
*/
enum Type : uint8_t
{
kSourceAddress = 0, ///< Source Address TLV
kMode = 1, ///< Mode TLV
kTimeout = 2, ///< Timeout TLV
kChallenge = 3, ///< Challenge TLV
kResponse = 4, ///< Response TLV
kLinkFrameCounter = 5, ///< Link-Layer Frame Counter TLV
kLinkQuality = 6, ///< Link Quality TLV
kNetworkParameter = 7, ///< Network Parameter TLV
kMleFrameCounter = 8, ///< MLE Frame Counter TLV
kRoute = 9, ///< Route64 TLV
kAddress16 = 10, ///< Address16 TLV
kLeaderData = 11, ///< Leader Data TLV
kNetworkData = 12, ///< Network Data TLV
kTlvRequest = 13, ///< TLV Request TLV
kScanMask = 14, ///< Scan Mask TLV
kConnectivity = 15, ///< Connectivity TLV
kLinkMargin = 16, ///< Link Margin TLV
kStatus = 17, ///< Status TLV
kVersion = 18, ///< Version TLV
kAddressRegistration = 19, ///< Address Registration TLV
kChannel = 20, ///< Channel TLV
kPanId = 21, ///< PAN ID TLV
kActiveTimestamp = 22, ///< Active Timestamp TLV
kPendingTimestamp = 23, ///< Pending Timestamp TLV
kActiveDataset = 24, ///< Active Operational Dataset TLV
kPendingDataset = 25, ///< Pending Operational Dataset TLV
kDiscovery = 26, ///< Thread Discovery TLV
kCslChannel = 80, ///< CSL Channel TLV
kCslTimeout = 85, ///< CSL Timeout TLV
kCslClockAccuracy = 86, ///< CSL Clock Accuracy TLV
kLinkMetricsQuery = 87, ///< Link Metrics Query TLV
kLinkMetricsManagement = 88, ///< Link Metrics Management TLV
kLinkMetricsReport = 89, ///< Link Metrics Report TLV
kLinkProbe = 90, ///< Link Probe TLV
/**
* Applicable/Required only when time synchronization service
* (`OPENTHREAD_CONFIG_TIME_SYNC_ENABLE`) is enabled.
*
*/
kTimeRequest = 252, ///< Time Request TLV
kTimeParameter = 253, ///< Time Parameter TLV
kXtalAccuracy = 254, ///< XTAL Accuracy TLV
kInvalid = 255,
};
/**
* This method returns the Type value.
*
* @returns The Type value.
*
*/
Type GetType(void) const { return static_cast<Type>(ot::Tlv::GetType()); }
/**
* This method sets the Type value.
*
* @param[in] aType The Type value.
*
*/
void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); }
} OT_TOOL_PACKED_END;
/**
* This class defines Source Address TLV constants and types.
*
*/
typedef UintTlvInfo<Tlv::kSourceAddress, uint16_t> SourceAddressTlv;
/**
* This class defines Mode TLV constants and types.
*
*/
typedef UintTlvInfo<Tlv::kMode, uint8_t> ModeTlv;
/**
* This class defines Timeout TLV constants and types.
*
*/
typedef UintTlvInfo<Tlv::kTimeout, uint32_t> TimeoutTlv;
/**
* This class defines Challenge TLV constants and types.
*
*/
typedef TlvInfo<Tlv::kChallenge> ChallengeTlv;
/**
* This class defines Response TLV constants and types.
*
*/
typedef TlvInfo<Tlv::kResponse> ResponseTlv;
/**
* This class defines Link Frame Counter TLV constants and types.
*
*/
typedef UintTlvInfo<Tlv::kLinkFrameCounter, uint32_t> LinkFrameCounterTlv;
/**
* This class defines MLE Frame Counter TLV constants and types.
*
*/
typedef UintTlvInfo<Tlv::kMleFrameCounter, uint32_t> MleFrameCounterTlv;
/**
* This class defines Address16 TLV constants and types.
*
*/
typedef UintTlvInfo<Tlv::kAddress16, uint16_t> Address16Tlv;
/**
* This class defines Network Data TLV constants and types.
*
*/
typedef TlvInfo<Tlv::kNetworkData> NetworkDataTlv;
/**
* This class defines TLV Request TLV constants and types.
*
*/
typedef TlvInfo<Tlv::kTlvRequest> TlvRequestTlv;
/**
* This class defines Link Margin TLV constants and types.
*
*/
typedef UintTlvInfo<Tlv::kLinkMargin, uint8_t> LinkMarginTlv;
/**
* This class defines Version TLV constants and types.
*
*/
typedef UintTlvInfo<Tlv::kVersion, uint16_t> VersionTlv;
/**
* This class defines PAN ID TLV constants and types.
*
*/
typedef UintTlvInfo<Tlv::kPanId, uint16_t> PanIdTlv;
/**
* This class defines Active Timestamp TLV constants and types.
*
*/
typedef SimpleTlvInfo<Tlv::kActiveTimestamp, MeshCoP::Timestamp> ActiveTimestampTlv;
/**
* This class defines Pending Timestamp TLV constants and types.
*
*/
typedef SimpleTlvInfo<Tlv::kPendingTimestamp, MeshCoP::Timestamp> PendingTimestampTlv;
/**
* This class defines CSL Timeout TLV constants and types.
*
*/
typedef UintTlvInfo<Tlv::kCslTimeout, uint32_t> CslTimeoutTlv;
/**
* This class defines XTAL Accuracy TLV constants and types.
*
*/
typedef UintTlvInfo<Tlv::kXtalAccuracy, uint16_t> XtalAccuracyTlv;
#if !OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
/**
* This class implements Route TLV generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class RouteTlv : public Tlv, public TlvInfo<Tlv::kRoute>
{
public:
/**
* This method initializes the TLV.
*
*/
void Init(void)
{
SetType(kRoute);
SetLength(sizeof(*this) - sizeof(Tlv));
mRouterIdMask.Clear();
memset(mRouteData, 0, sizeof(mRouteData));
}
/**
* This method 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(mRouterIdSequence) + sizeof(mRouterIdMask); }
/**
* This method returns the Router ID Sequence value.
*
* @returns The Router ID Sequence value.
*
*/
uint8_t GetRouterIdSequence(void) const { return mRouterIdSequence; }
/**
* This method sets the Router ID Sequence value.
*
* @param[in] aSequence The Router ID Sequence value.
*
*/
void SetRouterIdSequence(uint8_t aSequence) { mRouterIdSequence = aSequence; }
/**
* This method gets the Router ID Mask.
*
*/
const RouterIdSet &GetRouterIdMask(void) const { return mRouterIdMask; }
/**
* This method sets the Router ID Mask.
*
* @param[in] aRouterIdSet The Router ID Mask to set.
*
*/
void SetRouterIdMask(const RouterIdSet &aRouterIdSet) { mRouterIdMask = aRouterIdSet; }
/**
* This method indicates whether or not a Router ID bit is set.
*
* @param[in] aRouterId The Router ID bit.
*
* @retval TRUE If the Router ID bit is set.
* @retval FALSE If the Router ID bit is not set.
*
*/
bool IsRouterIdSet(uint8_t aRouterId) const { return mRouterIdMask.Contains(aRouterId); }
/**
* This method returns the Route Data Length value.
*
* @returns The Route Data Length value.
*
*/
uint8_t GetRouteDataLength(void) const { return GetLength() - sizeof(mRouterIdSequence) - sizeof(mRouterIdMask); }
/**
* This method sets the Route Data Length value.
*
* @param[in] aLength The Route Data Length value.
*
*/
void SetRouteDataLength(uint8_t aLength) { SetLength(sizeof(mRouterIdSequence) + sizeof(mRouterIdMask) + aLength); }
/**
* This method returns the Route Cost value for a given Router index.
*
* @param[in] aRouterIndex The Router index.
*
* @returns The Route Cost value for a given Router index.
*
*/
uint8_t GetRouteCost(uint8_t aRouterIndex) const { return mRouteData[aRouterIndex] & kRouteCostMask; }
/**
* This method sets the Route Cost value for a given Router index.
*
* @param[in] aRouterIndex The Router index.
* @param[in] aRouteCost The Route Cost value.
*
*/
void SetRouteCost(uint8_t aRouterIndex, uint8_t aRouteCost)
{
mRouteData[aRouterIndex] = (mRouteData[aRouterIndex] & ~kRouteCostMask) | aRouteCost;
}
/**
* This method returns the Link Quality In value for a given Router index.
*
* @param[in] aRouterIndex The Router index.
*
* @returns The Link Quality In value for a given Router index.
*
*/
LinkQuality GetLinkQualityIn(uint8_t aRouterIndex) const
{
return static_cast<LinkQuality>((mRouteData[aRouterIndex] & kLinkQualityInMask) >> kLinkQualityInOffset);
}
/**
* This method sets the Link Quality In value for a given Router index.
*
* @param[in] aRouterIndex The Router index.
* @param[in] aLinkQuality The Link Quality In value for a given Router index.
*
*/
void SetLinkQualityIn(uint8_t aRouterIndex, LinkQuality aLinkQuality)
{
mRouteData[aRouterIndex] = (mRouteData[aRouterIndex] & ~kLinkQualityInMask) |
((aLinkQuality << kLinkQualityInOffset) & kLinkQualityInMask);
}
/**
* This method returns the Link Quality Out value for a given Router index.
*
* @param[in] aRouterIndex The Router index.
*
* @returns The Link Quality Out value for a given Router index.
*
*/
LinkQuality GetLinkQualityOut(uint8_t aRouterIndex) const
{
return static_cast<LinkQuality>((mRouteData[aRouterIndex] & kLinkQualityOutMask) >> kLinkQualityOutOffset);
}
/**
* This method sets the Link Quality Out value for a given Router index.
*
* @param[in] aRouterIndex The Router index.
* @param[in] aLinkQuality The Link Quality Out value for a given Router index.
*
*/
void SetLinkQualityOut(uint8_t aRouterIndex, LinkQuality aLinkQuality)
{
mRouteData[aRouterIndex] = (mRouteData[aRouterIndex] & ~kLinkQualityOutMask) |
((aLinkQuality << kLinkQualityOutOffset) & kLinkQualityOutMask);
}
private:
static constexpr uint8_t kLinkQualityOutOffset = 6;
static constexpr uint8_t kLinkQualityOutMask = 3 << kLinkQualityOutOffset;
static constexpr uint8_t kLinkQualityInOffset = 4;
static constexpr uint8_t kLinkQualityInMask = 3 << kLinkQualityInOffset;
static constexpr uint8_t kRouteCostOffset = 0;
static constexpr uint8_t kRouteCostMask = 0xf << kRouteCostOffset;
uint8_t mRouterIdSequence;
RouterIdSet mRouterIdMask;
uint8_t mRouteData[kMaxRouterId + 1];
} OT_TOOL_PACKED_END;
#else // OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
/**
* This class implements Route TLV generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class RouteTlv : public Tlv, public TlvInfo<Tlv::kRoute>
{
public:
/**
* This method initializes the TLV.
*
*/
void Init(void)
{
SetType(kRoute);
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* This method 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(mRouterIdSequence) + sizeof(mRouterIdMask); }
/**
* This method returns the Router ID Sequence value.
*
* @returns The Router ID Sequence value.
*
*/
uint8_t GetRouterIdSequence(void) const { return mRouterIdSequence; }
/**
* This method sets the Router ID Sequence value.
*
* @param[in] aSequence The Router ID Sequence value.
*
*/
void SetRouterIdSequence(uint8_t aSequence) { mRouterIdSequence = aSequence; }
/**
* This method gets the Router ID Mask.
*
*/
const RouterIdSet &GetRouterIdMask(void) const { return mRouterIdMask; }
/**
* This method sets the Router ID Mask.
*
* @param[in] aRouterIdSet The Router ID Mask to set.
*
*/
void SetRouterIdMask(const RouterIdSet &aRouterIdSet) { mRouterIdMask = aRouterIdSet; }
/**
* This method indicates whether or not a Router ID bit is set.
*
* @param[in] aRouterId The Router ID.
*
* @retval TRUE If the Router ID bit is set.
* @retval FALSE If the Router ID bit is not set.
*
*/
bool IsRouterIdSet(uint8_t aRouterId) const { return mRouterIdMask.Contains(aRouterId); }
/**
* This method sets the Router ID bit.
*
* @param[in] aRouterId The Router ID bit to set.
*
*/
void SetRouterId(uint8_t aRouterId) { mRouterIdMask.Add(aRouterId); }
/**
* This method returns the Route Data Length value.
*
* @returns The Route Data Length value in bytes
*
*/
uint8_t GetRouteDataLength(void) const { return GetLength() - sizeof(mRouterIdSequence) - sizeof(mRouterIdMask); }
/**
* This method sets the Route Data Length value.
*
* @param[in] aLength The Route Data Length value in number of router entries
*
*/
void SetRouteDataLength(uint8_t aLength)
{
SetLength(sizeof(mRouterIdSequence) + sizeof(mRouterIdMask) + aLength + (aLength + 1) / 2);
}
/**
* This method returns the Route Cost value for a given Router index.
*
* @param[in] aRouterIndex The Router index.
*
* @returns The Route Cost value for a given Router index.
*
*/
uint8_t GetRouteCost(uint8_t aRouterIndex) const
{
if (aRouterIndex & 1)
{
return mRouteData[aRouterIndex + aRouterIndex / 2 + 1];
}
else
{
return static_cast<uint8_t>((mRouteData[aRouterIndex + aRouterIndex / 2] & kRouteCostMask)
<< kOddEntryOffset) |
((mRouteData[aRouterIndex + aRouterIndex / 2 + 1] &
static_cast<uint8_t>(kRouteCostMask << kOddEntryOffset)) >>
kOddEntryOffset);
}
}
/**
* This method sets the Route Cost value for a given Router index.
*
* @param[in] aRouterIndex The Router index.
* @param[in] aRouteCost The Route Cost value.
*
*/
void SetRouteCost(uint8_t aRouterIndex, uint8_t aRouteCost)
{
if (aRouterIndex & 1)
{
mRouteData[aRouterIndex + aRouterIndex / 2 + 1] = aRouteCost;
}
else
{
mRouteData[aRouterIndex + aRouterIndex / 2] =
(mRouteData[aRouterIndex + aRouterIndex / 2] & ~kRouteCostMask) |
((aRouteCost >> kOddEntryOffset) & kRouteCostMask);
mRouteData[aRouterIndex + aRouterIndex / 2 + 1] = static_cast<uint8_t>(
(mRouteData[aRouterIndex + aRouterIndex / 2 + 1] & ~(kRouteCostMask << kOddEntryOffset)) |
((aRouteCost & kRouteCostMask) << kOddEntryOffset));
}
}
/**
* This method returns the Link Quality In value for a given Router index.
*
* @param[in] aRouterIndex The Router index.
*
* @returns The Link Quality In value for a given Router index.
*
*/
uint8_t GetLinkQualityIn(uint8_t aRouterIndex) const
{
int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0);
return (mRouteData[aRouterIndex + aRouterIndex / 2] & (kLinkQualityInMask >> offset)) >>
(kLinkQualityInOffset - offset);
}
/**
* This method sets the Link Quality In value for a given Router index.
*
* @param[in] aRouterIndex The Router index.
* @param[in] aLinkQuality The Link Quality In value for a given Router index.
*
*/
void SetLinkQualityIn(uint8_t aRouterIndex, uint8_t aLinkQuality)
{
int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0);
mRouteData[aRouterIndex + aRouterIndex / 2] =
(mRouteData[aRouterIndex + aRouterIndex / 2] & ~(kLinkQualityInMask >> offset)) |
((aLinkQuality << (kLinkQualityInOffset - offset)) & (kLinkQualityInMask >> offset));
}
/**
* This method returns the Link Quality Out value for a given Router index.
*
* @param[in] aRouterIndex The Router index.
*
* @returns The Link Quality Out value for a given Router index.
*
*/
LinkQuality GetLinkQualityOut(uint8_t aRouterIndex) const
{
int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0);
return static_cast<LinkQuality>(
(mRouteData[aRouterIndex + aRouterIndex / 2] & (kLinkQualityOutMask >> offset)) >>
(kLinkQualityOutOffset - offset));
}
/**
* This method sets the Link Quality Out value for a given Router index.
*
* @param[in] aRouterIndex The Router index.
* @param[in] aLinkQuality The Link Quality Out value for a given Router index.
*
*/
void SetLinkQualityOut(uint8_t aRouterIndex, LinkQuality aLinkQuality)
{
int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0);
mRouteData[aRouterIndex + aRouterIndex / 2] =
(mRouteData[aRouterIndex + aRouterIndex / 2] & ~(kLinkQualityOutMask >> offset)) |
((aLinkQuality << (kLinkQualityOutOffset - offset)) & (kLinkQualityOutMask >> offset));
}
private:
static constexpr uint8_t kLinkQualityOutOffset = 6;
static constexpr uint8_t kLinkQualityOutMask = 3 << kLinkQualityOutOffset;
static constexpr uint8_t kLinkQualityInOffset = 4;
static constexpr uint8_t kLinkQualityInMask = 3 << kLinkQualityInOffset;
static constexpr uint8_t kRouteCostOffset = 0;
static constexpr uint8_t kRouteCostMask = 0xf << kRouteCostOffset;
static constexpr uint8_t kOddEntryOffset = 4;
uint8_t mRouterIdSequence;
RouterIdSet mRouterIdMask;
// Since we do hold 12 (compressible to 11) bits of data per router, each entry occupies 1.5 bytes,
// consecutively. First 4 bits are link qualities, remaining 8 bits are route cost.
uint8_t mRouteData[kMaxRouterId + 1 + kMaxRouterId / 2 + 1];
} OT_TOOL_PACKED_END;
#endif // OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
/**
* This class implements Leader Data TLV generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class LeaderDataTlv : public Tlv, public TlvInfo<Tlv::kLeaderData>
{
public:
/**
* This method initializes the TLV.
*
*/
void Init(void)
{
SetType(kLeaderData);
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* This method 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); }
/**
* This method gets the Leader Data info from TLV.
*
* @param[out] aLeaderData A reference to output Leader Data info.
*
*/
void Get(LeaderData &aLeaderData) const
{
aLeaderData.SetPartitionId(HostSwap32(mPartitionId));
aLeaderData.SetWeighting(mWeighting);
aLeaderData.SetDataVersion(mDataVersion);
aLeaderData.SetStableDataVersion(mStableDataVersion);
aLeaderData.SetLeaderRouterId(mLeaderRouterId);
}
/**
* This method sets the Leader Data.
*
* @param[in] aLeaderData A Leader Data.
*
*/
void Set(const LeaderData &aLeaderData)
{
mPartitionId = HostSwap32(aLeaderData.GetPartitionId());
mWeighting = aLeaderData.GetWeighting();
mDataVersion = aLeaderData.GetDataVersion(NetworkData::kFullSet);
mStableDataVersion = aLeaderData.GetDataVersion(NetworkData::kStableSubset);
mLeaderRouterId = aLeaderData.GetLeaderRouterId();
}
private:
uint32_t mPartitionId;
uint8_t mWeighting;
uint8_t mDataVersion;
uint8_t mStableDataVersion;
uint8_t mLeaderRouterId;
} OT_TOOL_PACKED_END;
/**
* This class implements Scan Mask TLV generation and parsing.
*
*/
class ScanMaskTlv : public UintTlvInfo<Tlv::kScanMask, uint8_t>
{
public:
static constexpr uint8_t kRouterFlag = 1 << 7; ///< Scan Mask Router Flag.
static constexpr uint8_t kEndDeviceFlag = 1 << 6; ///< Scan Mask End Device Flag.
/**
* This method indicates whether or not the Router flag is set.
*
* @param[in] aMask A scan mask value.
*
* @retval TRUE If the Router flag is set.
* @retval FALSE If the Router flag is not set.
*/
static bool IsRouterFlagSet(uint8_t aMask) { return (aMask & kRouterFlag) != 0; }
/**
* This method indicates whether or not the End Device flag is set.
*
* @param[in] aMask A scan mask value.
*
* @retval TRUE If the End Device flag is set.
* @retval FALSE If the End Device flag is not set.
*/
static bool IsEndDeviceFlagSet(uint8_t aMask) { return (aMask & kEndDeviceFlag) != 0; }
};
/**
* This class implements Connectivity TLV generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class ConnectivityTlv : public Tlv, public TlvInfo<Tlv::kConnectivity>
{
public:
/**
* This method initializes the TLV.
*
*/
void Init(void)
{
SetType(kConnectivity);
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* This method 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 IsSedBufferingIncluded() ||
(GetLength() == sizeof(*this) - sizeof(Tlv) - sizeof(mSedBufferSize) - sizeof(mSedDatagramCount));
}
/**
* This method indicates whether or not the sed buffer size and datagram count are included.
*
* @retval TRUE If the sed buffer size and datagram count are included.
* @retval FALSE If the sed buffer size and datagram count are not included.
*
*/
bool IsSedBufferingIncluded(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
/**
* This method returns the Parent Priority value.
*
* @returns The Parent Priority value.
*
*/
int8_t GetParentPriority(void) const
{
return (static_cast<int8_t>(mParentPriority & kParentPriorityMask)) >> kParentPriorityOffset;
}
/**
* This method sets the Parent Priority value.
*
* @param[in] aParentPriority The Parent Priority value.
*
*/
void SetParentPriority(int8_t aParentPriority)
{
mParentPriority = (static_cast<uint8_t>(aParentPriority) << kParentPriorityOffset) & kParentPriorityMask;
}
/**
* This method returns the Link Quality 3 value.
*
* @returns The Link Quality 3 value.
*
*/
uint8_t GetLinkQuality3(void) const { return mLinkQuality3; }
/**
* This method sets the Link Quality 3 value.
*
* @param[in] aLinkQuality The Link Quality 3 value.
*
*/
void SetLinkQuality3(uint8_t aLinkQuality) { mLinkQuality3 = aLinkQuality; }
/**
* This method returns the Link Quality 2 value.
*
* @returns The Link Quality 2 value.
*
*/
uint8_t GetLinkQuality2(void) const { return mLinkQuality2; }
/**
* This method sets the Link Quality 2 value.
*
* @param[in] aLinkQuality The Link Quality 2 value.
*
*/
void SetLinkQuality2(uint8_t aLinkQuality) { mLinkQuality2 = aLinkQuality; }
/**
* This method sets the Link Quality 1 value.
*
* @returns The Link Quality 1 value.
*
*/
uint8_t GetLinkQuality1(void) const { return mLinkQuality1; }
/**
* This method sets the Link Quality 1 value.
*
* @param[in] aLinkQuality The Link Quality 1 value.
*
*/
void SetLinkQuality1(uint8_t aLinkQuality) { mLinkQuality1 = aLinkQuality; }
/**
* This method sets the Active Routers value.
*
* @returns The Active Routers value.
*
*/
uint8_t GetActiveRouters(void) const { return mActiveRouters; }
/**
* This method sets the Active Routers value.
*
* @param[in] aActiveRouters The Active Routers value.
*
*/
void SetActiveRouters(uint8_t aActiveRouters) { mActiveRouters = aActiveRouters; }
/**
* This method returns the Leader Cost value.
*
* @returns The Leader Cost value.
*
*/
uint8_t GetLeaderCost(void) const { return mLeaderCost; }
/**
* This method sets the Leader Cost value.
*
* @param[in] aCost The Leader Cost value.
*
*/
void SetLeaderCost(uint8_t aCost) { mLeaderCost = aCost; }
/**
* This method returns the ID Sequence value.
*
* @returns The ID Sequence value.
*
*/
uint8_t GetIdSequence(void) const { return mIdSequence; }
/**
* This method sets the ID Sequence value.
*
* @param[in] aSequence The ID Sequence value.
*
*/
void SetIdSequence(uint8_t aSequence) { mIdSequence = aSequence; }
/**
* This method returns the SED Buffer Size value.
*
* @returns The SED Buffer Size value.
*
*/
uint16_t GetSedBufferSize(void) const
{
uint16_t buffersize = OPENTHREAD_CONFIG_DEFAULT_SED_BUFFER_SIZE;
if (IsSedBufferingIncluded())
{
buffersize = HostSwap16(mSedBufferSize);
}
return buffersize;
}
/**
* This method sets the SED Buffer Size value.
*
* @param[in] aSedBufferSize The SED Buffer Size value.
*
*/
void SetSedBufferSize(uint16_t aSedBufferSize) { mSedBufferSize = HostSwap16(aSedBufferSize); }
/**
* This method returns the SED Datagram Count value.
*
* @returns The SED Datagram Count value.
*
*/
uint8_t GetSedDatagramCount(void) const
{
uint8_t count = OPENTHREAD_CONFIG_DEFAULT_SED_DATAGRAM_COUNT;
if (IsSedBufferingIncluded())
{
count = mSedDatagramCount;
}
return count;
}
/**
* This method sets the SED Datagram Count value.
*
* @param[in] aSedDatagramCount The SED Datagram Count value.
*
*/
void SetSedDatagramCount(uint8_t aSedDatagramCount) { mSedDatagramCount = aSedDatagramCount; }
private:
static constexpr uint8_t kParentPriorityOffset = 6;
static constexpr uint8_t kParentPriorityMask = 3 << kParentPriorityOffset;
uint8_t mParentPriority;
uint8_t mLinkQuality3;
uint8_t mLinkQuality2;
uint8_t mLinkQuality1;
uint8_t mLeaderCost;
uint8_t mIdSequence;
uint8_t mActiveRouters;
uint16_t mSedBufferSize;
uint8_t mSedDatagramCount;
} OT_TOOL_PACKED_END;
/**
* This class specifies Status TLV status values.
*
*/
struct StatusTlv : public UintTlvInfo<Tlv::kStatus, uint8_t>
{
/**
* Status values.
*/
enum Status : uint8_t
{
kError = 1, ///< Error.
};
};
/**
* This class implements Source Address TLV generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class AddressRegistrationEntry
{
public:
/**
* This method returns the IPv6 address or IID length.
*
* @returns The IPv6 address length if the Compressed bit is clear, or the IID length if the Compressed bit is
* set.
*
*/
uint8_t GetLength(void) const { return sizeof(mControl) + (IsCompressed() ? sizeof(mIid) : sizeof(mIp6Address)); }
/**
* This method indicates whether or not the Compressed flag is set.
*
* @retval TRUE If the Compressed flag is set.
* @retval FALSE If the Compressed flag is not set.
*
*/
bool IsCompressed(void) const { return (mControl & kCompressed) != 0; }
/**
* This method sets the Uncompressed flag.
*
*/
void SetUncompressed(void) { mControl = 0; }
/**
* This method returns the Context ID for the compressed form.
*
* @returns The Context ID value.
*
*/
uint8_t GetContextId(void) const { return mControl & kCidMask; }
/**
* This method sets the Context ID value.
*
* @param[in] aContextId The Context ID value.
*
*/
void SetContextId(uint8_t aContextId) { mControl = kCompressed | aContextId; }
/**
* This method returns the IID value.
*
* @returns The IID value.
*
*/
const Ip6::InterfaceIdentifier &GetIid(void) const { return mIid; }
/**
* This method sets the IID value.
*
* @param[in] aIid The IID value.
*
*/
void SetIid(const Ip6::InterfaceIdentifier &aIid) { mIid = aIid; }
/**
* This method returns the IPv6 Address value.
*
* @returns The IPv6 Address value.
*
*/
const Ip6::Address &GetIp6Address(void) const { return mIp6Address; }
/**
* This method sets the IPv6 Address value.
*
* @param[in] aAddress A reference to the IPv6 Address value.
*
*/
void SetIp6Address(const Ip6::Address &aAddress) { mIp6Address = aAddress; }
private:
static constexpr uint8_t kCompressed = 1 << 7;
static constexpr uint8_t kCidMask = 0xf;
uint8_t mControl;
union
{
Ip6::InterfaceIdentifier mIid;
Ip6::Address mIp6Address;
} OT_TOOL_PACKED_FIELD;
} OT_TOOL_PACKED_END;
/**
* This class implements Channel TLV generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class ChannelTlv : public Tlv, public TlvInfo<Tlv::kChannel>
{
public:
/**
* This method initializes the TLV.
*
*/
void Init(void)
{
SetType(kChannel);
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* This method 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); }
/**
* This method returns the Channel Page value.
*
* @returns The Channel Page value.
*
*/
uint8_t GetChannelPage(void) const { return mChannelPage; }
/**
* This method sets the Channel Page value.
*
* @param[in] aChannelPage The Channel Page value.
*
*/
void SetChannelPage(uint8_t aChannelPage) { mChannelPage = aChannelPage; }
/**
* This method returns the Channel value.
*
* @returns The Channel value.
*
*/
uint16_t GetChannel(void) const { return HostSwap16(mChannel); }
/**
* This method sets the Channel value.
*
* @param[in] aChannel The Channel value.
*
*/
void SetChannel(uint16_t aChannel) { mChannel = HostSwap16(aChannel); }
private:
uint8_t mChannelPage;
uint16_t mChannel;
} OT_TOOL_PACKED_END;
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
/**
* This class defines Time Request TLV constants and types.
*
*/
typedef TlvInfo<Tlv::kTimeRequest> TimeRequestTlv;
/**
* This class implements Time Parameter TLV generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class TimeParameterTlv : public Tlv, public TlvInfo<Tlv::kTimeParameter>
{
public:
/**
* This method initializes the TLV.
*
*/
void Init(void)
{
SetType(kTimeParameter);
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* This method 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); }
/**
* This method returns the time sync period.
*
* @returns The time sync period.
*
*/
uint16_t GetTimeSyncPeriod(void) const { return HostSwap16(mTimeSyncPeriod); }
/**
* This method sets the time sync period.
*
* @param[in] aTimeSyncPeriod The time sync period.
*
*/
void SetTimeSyncPeriod(uint16_t aTimeSyncPeriod) { mTimeSyncPeriod = HostSwap16(aTimeSyncPeriod); }
/**
* This method returns the XTAL accuracy threshold.
*
* @returns The XTAL accuracy threshold.
*
*/
uint16_t GetXtalThreshold(void) const { return HostSwap16(mXtalThreshold); }
/**
* This method sets the XTAL accuracy threshold.
*
* @param[in] aXTALThreshold The XTAL accuracy threshold.
*
*/
void SetXtalThreshold(uint16_t aXtalThreshold) { mXtalThreshold = HostSwap16(aXtalThreshold); }
private:
uint16_t mTimeSyncPeriod;
uint16_t mXtalThreshold;
} OT_TOOL_PACKED_END;
#endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE)
/**
* This class implements CSL Channel TLV generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class CslChannelTlv : public Tlv, public TlvInfo<Tlv::kCslChannel>
{
public:
/**
* This method initializes the TLV.
*
*/
void Init(void)
{
SetType(kCslChannel);
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* This method 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); }
/**
* This method returns the Channel Page value.
*
* @returns The Channel Page value.
*
*/
uint8_t GetChannelPage(void) const { return mChannelPage; }
/**
* This method sets the Channel Page value.
*
* @param[in] aChannelPage The Channel Page value.
*
*/
void SetChannelPage(uint8_t aChannelPage) { mChannelPage = aChannelPage; }
/**
* This method returns the Channel value.
*
* @returns The Channel value.
*
*/
uint16_t GetChannel(void) const { return HostSwap16(mChannel); }
/**
* This method sets the Channel value.
*
* @param[in] aChannel The Channel value.
*
*/
void SetChannel(uint16_t aChannel) { mChannel = HostSwap16(aChannel); }
private:
uint8_t mChannelPage;
uint16_t mChannel;
} OT_TOOL_PACKED_END;
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE)
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
/**
* This class implements CSL Clock Accuracy TLV generation and parsing.
*
*/
OT_TOOL_PACKED_BEGIN
class CslClockAccuracyTlv : public Tlv, public TlvInfo<Tlv::kCslClockAccuracy>
{
public:
/**
* This method initializes the TLV.
*
*/
void Init(void)
{
SetType(kCslClockAccuracy);
SetLength(sizeof(*this) - sizeof(Tlv));
}
/**
* This method returns the CSL Clock Accuracy value.
*
* @returns The CSL Clock Accuracy value.
*
*/
uint8_t GetCslClockAccuracy(void) { return mCslClockAccuracy; }
/**
* This method sets the CSL Clock Accuracy value.
*
* @param[in] aCslClockAccuracy The CSL Clock Accuracy value.
*
*/
void SetCslClockAccuracy(uint8_t aCslClockAccuracy) { mCslClockAccuracy = aCslClockAccuracy; }
/**
* This method returns the Clock Accuracy value.
*
* @returns The Clock Accuracy value.
*
*/
uint8_t GetCslUncertainty(void) { return mCslUncertainty; }
/**
* This method sets the CSL Uncertainty value.
*
* @param[in] aCslUncertainty The CSL Uncertainty value.
*
*/
void SetCslUncertainty(uint8_t aCslUncertainty) { mCslUncertainty = aCslUncertainty; }
private:
uint8_t mCslClockAccuracy;
uint8_t mCslUncertainty;
} OT_TOOL_PACKED_END;
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
/**
* @}
*
*/
} // namespace Mle
} // namespace ot
#endif // MLE_TLVS_HPP_