mirror of
https://github.com/espressif/openthread.git
synced 2026-08-23 18:59:51 +00:00
[link-metrics] simplify handling of Type IDs (#8246)
This commit simplifies the handling of Type IDs in `LinkMetrics` modules.
This commit is contained in:
@@ -78,7 +78,7 @@ Error LinkMetrics::Query(const Ip6::Address &aDestination, uint8_t aSeriesId, co
|
||||
|
||||
if (aMetrics != nullptr)
|
||||
{
|
||||
info.mTypeIdCount = TypeIdFlagsFromMetrics(info.mTypeIds, *aMetrics);
|
||||
info.mTypeIdCount = aMetrics->ConvertToTypeIds(info.mTypeIds);
|
||||
}
|
||||
|
||||
if (aSeriesId != 0)
|
||||
@@ -114,10 +114,10 @@ Error LinkMetrics::SendMgmtRequestForwardTrackingSeries(const Ip6::Address &aDes
|
||||
|
||||
if (aMetrics != nullptr)
|
||||
{
|
||||
typeIdCount = TypeIdFlagsFromMetrics(fwdProbingSubTlv.GetTypeIds(), *aMetrics);
|
||||
typeIdCount = aMetrics->ConvertToTypeIds(fwdProbingSubTlv.GetTypeIds());
|
||||
}
|
||||
|
||||
fwdProbingSubTlv.SetLength(sizeof(aSeriesId) + sizeof(uint8_t) + typeIdCount * sizeof(TypeIdFlags));
|
||||
fwdProbingSubTlv.SetLength(sizeof(aSeriesId) + sizeof(uint8_t) + typeIdCount);
|
||||
|
||||
error = Get<Mle::MleRouter>().SendLinkMetricsManagementRequest(aDestination, fwdProbingSubTlv);
|
||||
|
||||
@@ -148,10 +148,10 @@ Error LinkMetrics::SendMgmtRequestEnhAckProbing(const Ip6::Address &aDestination
|
||||
|
||||
if (aMetrics != nullptr)
|
||||
{
|
||||
typeIdCount = TypeIdFlagsFromMetrics(enhAckConfigSubTlv.GetTypeIds(), *aMetrics);
|
||||
typeIdCount = aMetrics->ConvertToTypeIds(enhAckConfigSubTlv.GetTypeIds());
|
||||
}
|
||||
|
||||
enhAckConfigSubTlv.SetLength(EnhAckConfigSubTlv::kMinLength + typeIdCount * sizeof(TypeIdFlags));
|
||||
enhAckConfigSubTlv.SetLength(EnhAckConfigSubTlv::kMinLength + typeIdCount);
|
||||
|
||||
error = Get<Mle::MleRouter>().SendLinkMetricsManagementRequest(aDestination, enhAckConfigSubTlv);
|
||||
|
||||
@@ -225,9 +225,9 @@ Error LinkMetrics::AppendReport(Message &aMessage, const Message &aRequestMessag
|
||||
break;
|
||||
|
||||
case SubTlv::kQueryOptions:
|
||||
SuccessOrExit(error = ReadTypeIdFlagsFromMessage(aRequestMessage, offset + sizeof(tlv),
|
||||
static_cast<uint16_t>(offset + tlv.GetSize()),
|
||||
values.GetMetrics()));
|
||||
SuccessOrExit(error = ReadTypeIdsFromMessage(aRequestMessage, offset + sizeof(tlv),
|
||||
static_cast<uint16_t>(offset + tlv.GetSize()),
|
||||
values.GetMetrics()));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -321,7 +321,7 @@ Error LinkMetrics::HandleManagementRequest(const Message &aMessage, Neighbor &aN
|
||||
pos += sizeof(seriesId);
|
||||
SuccessOrExit(aMessage.Read(pos, seriesFlagsMask));
|
||||
pos += sizeof(seriesFlagsMask);
|
||||
SuccessOrExit(error = ReadTypeIdFlagsFromMessage(
|
||||
SuccessOrExit(error = ReadTypeIdsFromMessage(
|
||||
aMessage, pos, static_cast<uint16_t>(offset + index + tlv.GetSize()), metrics));
|
||||
hasForwardProbingRegistrationTlv = true;
|
||||
break;
|
||||
@@ -331,7 +331,7 @@ Error LinkMetrics::HandleManagementRequest(const Message &aMessage, Neighbor &aN
|
||||
VerifyOrExit(tlv.GetLength() >= sizeof(EnhAckFlags), error = kErrorParse);
|
||||
SuccessOrExit(aMessage.Read(pos, enhAckFlags));
|
||||
pos += sizeof(enhAckFlags);
|
||||
SuccessOrExit(error = ReadTypeIdFlagsFromMessage(
|
||||
SuccessOrExit(error = ReadTypeIdsFromMessage(
|
||||
aMessage, pos, static_cast<uint16_t>(offset + index + tlv.GetSize()), metrics));
|
||||
hasEnhAckProbingTlv = true;
|
||||
break;
|
||||
@@ -414,6 +414,7 @@ void LinkMetrics::HandleReport(const Message & aMessage,
|
||||
ReportSubTlv reportTlv;
|
||||
MetricsValues values;
|
||||
uint8_t status;
|
||||
uint8_t typeId;
|
||||
|
||||
OT_UNUSED_VARIABLE(error);
|
||||
|
||||
@@ -447,40 +448,42 @@ void LinkMetrics::HandleReport(const Message & aMessage,
|
||||
VerifyOrExit(reportTlv.IsValid(), error = kErrorParse);
|
||||
hasReport = true;
|
||||
|
||||
if (reportTlv.GetMetricsTypeId().IsExtendedFlagSet())
|
||||
typeId = reportTlv.GetMetricsTypeId();
|
||||
|
||||
if (TypeId::IsExtended(typeId))
|
||||
{
|
||||
// Skip the sub-TLV if `E` flag is set.
|
||||
break;
|
||||
}
|
||||
|
||||
if (reportTlv.GetMetricsTypeId().IsLengthFlagSet())
|
||||
if (TypeId::GetValueLength(typeId) > sizeof(uint8_t))
|
||||
{
|
||||
// If Type ID indicates metric value has 4 bytes length, we
|
||||
// read the full `reportTlv`.
|
||||
SuccessOrExit(error = aMessage.Read(offset, reportTlv));
|
||||
}
|
||||
|
||||
switch (reportTlv.GetMetricsTypeId().GetRawValue())
|
||||
switch (typeId)
|
||||
{
|
||||
case TypeIdFlags::kPdu:
|
||||
case TypeId::kPdu:
|
||||
values.mMetrics.mPduCount = true;
|
||||
values.mPduCountValue = reportTlv.GetMetricsValue32();
|
||||
LogDebg(" - PDU Counter: %d (Count/Summation)", values.mPduCountValue);
|
||||
break;
|
||||
|
||||
case TypeIdFlags::kLqi:
|
||||
case TypeId::kLqi:
|
||||
values.mMetrics.mLqi = true;
|
||||
values.mLqiValue = reportTlv.GetMetricsValue8();
|
||||
LogDebg(" - LQI: %d (Exponential Moving Average)", values.mLqiValue);
|
||||
break;
|
||||
|
||||
case TypeIdFlags::kLinkMargin:
|
||||
case TypeId::kLinkMargin:
|
||||
values.mMetrics.mLinkMargin = true;
|
||||
values.mLinkMarginValue = ScaleRawValueToLinkMargin(reportTlv.GetMetricsValue8());
|
||||
LogDebg(" - Margin: %d (dB) (Exponential Moving Average)", values.mLinkMarginValue);
|
||||
break;
|
||||
|
||||
case TypeIdFlags::kRssi:
|
||||
case TypeId::kRssi:
|
||||
values.mMetrics.mRssi = true;
|
||||
values.mRssiValue = ScaleRawValueToRssi(reportTlv.GetMetricsValue8());
|
||||
LogDebg(" - RSSI: %d (dBm) (Exponential Moving Average)", values.mRssiValue);
|
||||
@@ -678,47 +681,47 @@ exit:
|
||||
return neighbor;
|
||||
}
|
||||
|
||||
Error LinkMetrics::ReadTypeIdFlagsFromMessage(const Message &aMessage,
|
||||
uint16_t aStartPos,
|
||||
uint16_t aEndPos,
|
||||
Metrics & aMetrics)
|
||||
Error LinkMetrics::ReadTypeIdsFromMessage(const Message &aMessage,
|
||||
uint16_t aStartOffset,
|
||||
uint16_t aEndOffset,
|
||||
Metrics & aMetrics)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
memset(&aMetrics, 0, sizeof(aMetrics));
|
||||
aMetrics.Clear();
|
||||
|
||||
for (uint16_t pos = aStartPos; pos < aEndPos; pos += sizeof(TypeIdFlags))
|
||||
for (uint16_t offset = aStartOffset; offset < aEndOffset; offset++)
|
||||
{
|
||||
TypeIdFlags typeIdFlags;
|
||||
uint8_t typeId;
|
||||
|
||||
SuccessOrExit(aMessage.Read(pos, typeIdFlags));
|
||||
SuccessOrExit(aMessage.Read(offset, typeId));
|
||||
|
||||
switch (typeIdFlags.GetRawValue())
|
||||
switch (typeId)
|
||||
{
|
||||
case TypeIdFlags::kPdu:
|
||||
case TypeId::kPdu:
|
||||
VerifyOrExit(!aMetrics.mPduCount, error = kErrorParse);
|
||||
aMetrics.mPduCount = true;
|
||||
break;
|
||||
|
||||
case TypeIdFlags::kLqi:
|
||||
case TypeId::kLqi:
|
||||
VerifyOrExit(!aMetrics.mLqi, error = kErrorParse);
|
||||
aMetrics.mLqi = true;
|
||||
break;
|
||||
|
||||
case TypeIdFlags::kLinkMargin:
|
||||
case TypeId::kLinkMargin:
|
||||
VerifyOrExit(!aMetrics.mLinkMargin, error = kErrorParse);
|
||||
aMetrics.mLinkMargin = true;
|
||||
break;
|
||||
|
||||
case TypeIdFlags::kRssi:
|
||||
case TypeId::kRssi:
|
||||
VerifyOrExit(!aMetrics.mRssi, error = kErrorParse);
|
||||
aMetrics.mRssi = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (typeIdFlags.IsExtendedFlagSet())
|
||||
if (TypeId::IsExtended(typeId))
|
||||
{
|
||||
pos += sizeof(uint8_t); // Skip the additional second flags byte.
|
||||
offset += sizeof(uint8_t); // Skip the additional second byte.
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -741,28 +744,28 @@ Error LinkMetrics::AppendReportSubTlvToMessage(Message &aMessage, const MetricsV
|
||||
|
||||
if (aValues.mMetrics.mPduCount)
|
||||
{
|
||||
reportTlv.SetMetricsTypeId(TypeIdFlags(TypeIdFlags::kPdu));
|
||||
reportTlv.SetMetricsTypeId(TypeId::kPdu);
|
||||
reportTlv.SetMetricsValue32(aValues.mPduCountValue);
|
||||
SuccessOrExit(error = reportTlv.AppendTo(aMessage));
|
||||
}
|
||||
|
||||
if (aValues.mMetrics.mLqi)
|
||||
{
|
||||
reportTlv.SetMetricsTypeId(TypeIdFlags(TypeIdFlags::kLqi));
|
||||
reportTlv.SetMetricsTypeId(TypeId::kLqi);
|
||||
reportTlv.SetMetricsValue8(aValues.mLqiValue);
|
||||
SuccessOrExit(error = reportTlv.AppendTo(aMessage));
|
||||
}
|
||||
|
||||
if (aValues.mMetrics.mLinkMargin)
|
||||
{
|
||||
reportTlv.SetMetricsTypeId(TypeIdFlags(TypeIdFlags::kLinkMargin));
|
||||
reportTlv.SetMetricsTypeId(TypeId::kLinkMargin);
|
||||
reportTlv.SetMetricsValue8(ScaleLinkMarginToRawValue(aValues.mLinkMarginValue));
|
||||
SuccessOrExit(error = reportTlv.AppendTo(aMessage));
|
||||
}
|
||||
|
||||
if (aValues.mMetrics.mRssi)
|
||||
{
|
||||
reportTlv.SetMetricsTypeId(TypeIdFlags(TypeIdFlags::kRssi));
|
||||
reportTlv.SetMetricsTypeId(TypeId::kRssi);
|
||||
reportTlv.SetMetricsValue8(ScaleRssiToRawValue(aValues.mRssiValue));
|
||||
SuccessOrExit(error = reportTlv.AppendTo(aMessage));
|
||||
}
|
||||
|
||||
@@ -90,9 +90,9 @@ public:
|
||||
*/
|
||||
struct QueryInfo : public Clearable<QueryInfo>
|
||||
{
|
||||
uint8_t mSeriesId; ///< Series ID.
|
||||
TypeIdFlags mTypeIds[kMaxTypeIdFlags]; ///< Type ID flags.
|
||||
uint8_t mTypeIdCount; ///< Number of entries in `mTypeIds[]`.
|
||||
uint8_t mSeriesId; ///< Series ID.
|
||||
uint8_t mTypeIds[kMaxTypeIds]; ///< Type IDs.
|
||||
uint8_t mTypeIdCount; ///< Number of entries in `mTypeIds[]`.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
*
|
||||
* @retval kErrorNone Successfully sent a Link Metrics query message.
|
||||
* @retval kErrorNoBufs Insufficient buffers to generate the MLE Data Request message.
|
||||
* @retval kErrorInvalidArgs TypeIdFlags are not valid or exceed the count limit.
|
||||
* @retval kErrorInvalidArgs Type IDs are not valid or exceed the count limit.
|
||||
* @retval kErrorUnknownNeighbor @p aDestination is not link-local or the neighbor is not found.
|
||||
*
|
||||
*/
|
||||
@@ -309,10 +309,10 @@ private:
|
||||
|
||||
Neighbor *GetNeighborFromLinkLocalAddr(const Ip6::Address &aDestination);
|
||||
|
||||
static Error ReadTypeIdFlagsFromMessage(const Message &aMessage,
|
||||
uint16_t aStartPos,
|
||||
uint16_t aEndPos,
|
||||
Metrics & aMetrics);
|
||||
static Error ReadTypeIdsFromMessage(const Message &aMessage,
|
||||
uint16_t aStartOffset,
|
||||
uint16_t aEndOffset,
|
||||
Metrics & aMetrics);
|
||||
static Error AppendReportSubTlvToMessage(Message &aMessage, const MetricsValues &aValues);
|
||||
|
||||
static uint8_t ScaleLinkMarginToRawValue(uint8_t aLinkMargin);
|
||||
|
||||
@@ -94,17 +94,13 @@ OT_TOOL_PACKED_BEGIN
|
||||
class ReportSubTlv : public Tlv, public TlvInfo<SubTlv::kReport>
|
||||
{
|
||||
public:
|
||||
static constexpr uint8_t kMinLength = sizeof(TypeIdFlags) + sizeof(uint8_t); ///< Minimum expected TLV length.
|
||||
static constexpr uint8_t kMinLength = 2; ///< Minimum expected TLV length (type ID and u8 value).
|
||||
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
*
|
||||
*/
|
||||
void Init(void)
|
||||
{
|
||||
SetType(SubTlv::kReport);
|
||||
SetLength(sizeof(*this) - sizeof(Tlv));
|
||||
}
|
||||
void Init(void) { SetType(SubTlv::kReport); }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the TLV appears to be well-formed.
|
||||
@@ -121,7 +117,7 @@ public:
|
||||
* @returns The Link Metrics Type ID.
|
||||
*
|
||||
*/
|
||||
TypeIdFlags GetMetricsTypeId(void) const { return mMetricsTypeId; }
|
||||
uint8_t GetMetricsTypeId(void) const { return mMetricsTypeId; }
|
||||
|
||||
/**
|
||||
* This method sets the Link Metrics Type ID.
|
||||
@@ -129,15 +125,7 @@ public:
|
||||
* @param[in] aMetricsTypeId The Link Metrics Type ID to set.
|
||||
*
|
||||
*/
|
||||
void SetMetricsTypeId(TypeIdFlags aMetricsTypeId)
|
||||
{
|
||||
mMetricsTypeId = aMetricsTypeId;
|
||||
|
||||
if (!aMetricsTypeId.IsLengthFlagSet())
|
||||
{
|
||||
SetLength(sizeof(*this) - sizeof(Tlv) - sizeof(uint32_t) + sizeof(uint8_t)); // The value is 1 byte long
|
||||
}
|
||||
}
|
||||
void SetMetricsTypeId(uint8_t aMetricsTypeId) { mMetricsTypeId = aMetricsTypeId; }
|
||||
|
||||
/**
|
||||
* This method returns the metric value in 8 bits.
|
||||
@@ -161,7 +149,11 @@ public:
|
||||
* @param[in] aMetricsValue Metrics value.
|
||||
*
|
||||
*/
|
||||
void SetMetricsValue8(uint8_t aMetricsValue) { mMetricsValue.m8 = aMetricsValue; }
|
||||
void SetMetricsValue8(uint8_t aMetricsValue)
|
||||
{
|
||||
mMetricsValue.m8 = aMetricsValue;
|
||||
SetLength(kMinLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the metric value (32 bits).
|
||||
@@ -169,10 +161,14 @@ public:
|
||||
* @param[in] aMetricsValue Metrics value.
|
||||
*
|
||||
*/
|
||||
void SetMetricsValue32(uint32_t aMetricsValue) { mMetricsValue.m32 = HostSwap32(aMetricsValue); }
|
||||
void SetMetricsValue32(uint32_t aMetricsValue)
|
||||
{
|
||||
mMetricsValue.m32 = HostSwap32(aMetricsValue);
|
||||
SetLength(sizeof(*this) - sizeof(Tlv));
|
||||
}
|
||||
|
||||
private:
|
||||
TypeIdFlags mMetricsTypeId;
|
||||
uint8_t mMetricsTypeId;
|
||||
union
|
||||
{
|
||||
uint8_t m8;
|
||||
@@ -205,7 +201,7 @@ public:
|
||||
* @retval FALSE If the TLV does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return GetLength() >= sizeof(TypeIdFlags); }
|
||||
bool IsValid(void) const { return GetLength() >= sizeof(uint8_t); }
|
||||
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
@@ -271,17 +267,17 @@ public:
|
||||
void SetSeriesFlagsMask(uint8_t aSeriesFlagsMask) { mSeriesFlagsMask = aSeriesFlagsMask; }
|
||||
|
||||
/**
|
||||
* This method gets the start of Type ID Flags array.
|
||||
* This method gets the start of Type ID array.
|
||||
*
|
||||
* @returns The start of Type ID Flags array. Array has `kMaxTypeIdFlags` max length.
|
||||
* @returns The start of Type ID array. Array has `kMaxTypeIds` max length.
|
||||
*
|
||||
*/
|
||||
TypeIdFlags *GetTypeIds(void) { return mTypeIds; }
|
||||
uint8_t *GetTypeIds(void) { return mTypeIds; }
|
||||
|
||||
private:
|
||||
uint8_t mSeriesId;
|
||||
uint8_t mSeriesFlagsMask;
|
||||
TypeIdFlags mTypeIds[kMaxTypeIdFlags];
|
||||
uint8_t mSeriesId;
|
||||
uint8_t mSeriesFlagsMask;
|
||||
uint8_t mTypeIds[kMaxTypeIds];
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
@@ -326,16 +322,16 @@ public:
|
||||
void SetEnhAckFlags(EnhAckFlags aEnhAckFlags) { mEnhAckFlags = aEnhAckFlags; }
|
||||
|
||||
/**
|
||||
* This method gets the start of Type ID Flags array.
|
||||
* This method gets the start of Type ID array.
|
||||
*
|
||||
* @returns The start of Type ID Flags array. Array has `kMaxTypeIdFlags` max length.
|
||||
* @returns The start of Type ID array. Array has `kMaxTypeIds` max length.
|
||||
*
|
||||
*/
|
||||
TypeIdFlags *GetTypeIds(void) { return mTypeIds; }
|
||||
uint8_t *GetTypeIds(void) { return mTypeIds; }
|
||||
|
||||
private:
|
||||
uint8_t mEnhAckFlags;
|
||||
TypeIdFlags mTypeIds[kMaxTypeIdFlags];
|
||||
uint8_t mEnhAckFlags;
|
||||
uint8_t mTypeIds[kMaxTypeIds];
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
} // namespace LinkMetrics
|
||||
|
||||
@@ -41,36 +41,39 @@
|
||||
namespace ot {
|
||||
namespace LinkMetrics {
|
||||
|
||||
uint8_t TypeIdFlagsFromMetrics(TypeIdFlags aTypeIdFlags[], const Metrics &aMetrics)
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Metrics
|
||||
|
||||
uint8_t Metrics::ConvertToTypeIds(uint8_t aTypeIds[]) const
|
||||
{
|
||||
uint8_t count = 0;
|
||||
|
||||
if (aMetrics.mPduCount)
|
||||
if (mPduCount)
|
||||
{
|
||||
aTypeIdFlags[count++].SetRawValue(TypeIdFlags::kPdu);
|
||||
aTypeIds[count++] = TypeId::kPdu;
|
||||
}
|
||||
|
||||
if (aMetrics.mLqi)
|
||||
if (mLqi)
|
||||
{
|
||||
aTypeIdFlags[count++].SetRawValue(TypeIdFlags::kLqi);
|
||||
aTypeIds[count++] = TypeId::kLqi;
|
||||
}
|
||||
|
||||
if (aMetrics.mLinkMargin)
|
||||
if (mLinkMargin)
|
||||
{
|
||||
aTypeIdFlags[count++].SetRawValue(TypeIdFlags::kLinkMargin);
|
||||
aTypeIds[count++] = TypeId::kLinkMargin;
|
||||
}
|
||||
|
||||
if (aMetrics.mRssi)
|
||||
if (mRssi)
|
||||
{
|
||||
aTypeIdFlags[count++].SetRawValue(TypeIdFlags::kRssi);
|
||||
aTypeIds[count++] = TypeId::kRssi;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
if (aMetrics.mReserved)
|
||||
if (mReserved)
|
||||
{
|
||||
for (uint8_t i = 0; i < count; i++)
|
||||
{
|
||||
aTypeIdFlags[i].SetTypeEnum(TypeIdFlags::kTypeReserved);
|
||||
TypeId::MarkAsReserverd(aTypeIds[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
namespace ot {
|
||||
namespace LinkMetrics {
|
||||
|
||||
constexpr uint8_t kMaxTypeIds = 4; ///< Maximum number of Type IDs in a `Metrics`.
|
||||
|
||||
/**
|
||||
* This type represents Link Metric Flags indicating a set of metrics.
|
||||
*
|
||||
@@ -57,6 +59,16 @@ namespace LinkMetrics {
|
||||
*/
|
||||
class Metrics : public otLinkMetrics, public Clearable<Metrics>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method converts the `Metrics` into an array of Type IDs.
|
||||
*
|
||||
* @param[out] aTypeIds The array of Type IDs to populate. MUST have at least `kMaxTypeIds` elements.
|
||||
*
|
||||
* @returns Number of entries added in the array @p aTypeIds.
|
||||
*
|
||||
*/
|
||||
uint8_t ConvertToTypeIds(uint8_t aTypeIds[]) const;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -93,209 +105,78 @@ public:
|
||||
void SetMetrics(const Metrics &aMetrics) { mMetrics = aMetrics; }
|
||||
};
|
||||
|
||||
/**
|
||||
* This class implements Link Metrics Type ID Flags generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN class TypeIdFlags
|
||||
class TypeId
|
||||
{
|
||||
static constexpr uint8_t kExtendedFlag = 1 << 7;
|
||||
static constexpr uint8_t kLengthOffset = 6;
|
||||
static constexpr uint8_t kLengthFlag = 1 << kLengthOffset;
|
||||
static constexpr uint8_t kTypeEnumOffset = 3;
|
||||
static constexpr uint8_t kTypeEnumMask = 7 << kTypeEnumOffset;
|
||||
static constexpr uint8_t kMetricEnumOffset = 0;
|
||||
static constexpr uint8_t kMetricEnumMask = 7 << kMetricEnumOffset;
|
||||
// Type ID Flags
|
||||
//
|
||||
// 7 6 5 4 3 2 1 0
|
||||
// +---+---+---+---+---+---+---+---+
|
||||
// | E | L | Type | Metric |
|
||||
// +---+---+---+---+---+---+---+---+
|
||||
//
|
||||
|
||||
static constexpr uint8_t kExtendedFlag = 1 << 7;
|
||||
static constexpr uint8_t kLengthFlag = 1 << 6;
|
||||
static constexpr uint8_t kTypeOffset = 3;
|
||||
static constexpr uint8_t kMetricOffset = 0;
|
||||
static constexpr uint8_t kTypeMask = (7 << kTypeOffset);
|
||||
|
||||
static constexpr uint8_t kTypeCount = (0 << kTypeOffset); // Count/summation
|
||||
static constexpr uint8_t kTypeAve = (1 << kTypeOffset); // Exponential Moving average
|
||||
static constexpr uint8_t kTypeReserved = (2 << kTypeOffset); // Reserved
|
||||
|
||||
static constexpr uint8_t kMetricPdu = (0 << kMetricOffset); // Number of PDUs received.
|
||||
static constexpr uint8_t kMetricLqi = (1 << kMetricOffset);
|
||||
static constexpr uint8_t kMetricLinkMargin = (2 << kMetricOffset);
|
||||
static constexpr uint8_t kMetricRssi = (3 << kMetricOffset);
|
||||
|
||||
public:
|
||||
static constexpr uint8_t kPdu = (kMetricPdu | kTypeCount | kLengthFlag); ///< Type ID for num PDU received.
|
||||
static constexpr uint8_t kLqi = (kMetricLqi | kTypeAve); ///< Type ID for LQI.
|
||||
static constexpr uint8_t kLinkMargin = (kMetricLinkMargin | kTypeAve); ///< Type ID for Link Margin.
|
||||
static constexpr uint8_t kRssi = (kMetricRssi | kTypeAve); ///< Type ID for RSSI.
|
||||
|
||||
/**
|
||||
* This enumeration specifies the Length field in Type ID Flags.
|
||||
* This static method indicates whether or not a given Type ID is extended.
|
||||
*
|
||||
* Extended Type IDs are reserved for future use. When set an additional second byte follows the current ID flags.
|
||||
*
|
||||
* @param[in] aTypeId The Type ID to check.
|
||||
*
|
||||
* @retval TRUE The @p aTypeId is extended.
|
||||
* @retval FALSE The @p aTypeId is not extended.
|
||||
*
|
||||
*/
|
||||
enum Length
|
||||
{
|
||||
kShortLength = 0, ///< Short value length (1 byte value)
|
||||
kExtendedLength = 1, ///< Extended value length (4 bytes value)
|
||||
};
|
||||
static bool IsExtended(uint8_t aTypeId) { return (aTypeId & kExtendedFlag); }
|
||||
|
||||
/**
|
||||
* This enumeration specifies the Type values in Type ID Flags.
|
||||
* This static method determines the value length (number of bytes) associated with a given Type ID.
|
||||
*
|
||||
*/
|
||||
enum TypeEnum : uint8_t
|
||||
{
|
||||
kTypeCountSummation = 0, ///< Count or summation
|
||||
kTypeExpMovingAverage = 1, ///< Exponential moving average.
|
||||
kTypeReserved = 2, ///< Reserved for future use.
|
||||
};
|
||||
|
||||
/**
|
||||
* This enumeration specifies the Metric values in Type ID Flag.
|
||||
*
|
||||
*/
|
||||
enum MetricEnum : uint8_t
|
||||
{
|
||||
kMetricPdusReceived = 0, ///< Number of PDUs received.
|
||||
kMetricLqi = 1, ///< Link Quality Indicator.
|
||||
kMetricLinkMargin = 2, ///< Link Margin.
|
||||
kMetricRssi = 3, ///< RSSI in dbm.
|
||||
};
|
||||
|
||||
/**
|
||||
* This constant defines the raw value for Type ID Flag for PDU.
|
||||
*
|
||||
*/
|
||||
static constexpr uint8_t kPdu = (kExtendedLength << kLengthOffset) | (kTypeCountSummation << kTypeEnumOffset) |
|
||||
(kMetricPdusReceived << kMetricEnumOffset);
|
||||
|
||||
/**
|
||||
* This constant defines the raw value for Type ID Flag for LQI.
|
||||
*
|
||||
*/
|
||||
static constexpr uint8_t kLqi = (kShortLength << kLengthOffset) | (kTypeExpMovingAverage << kTypeEnumOffset) |
|
||||
(kMetricLqi << kMetricEnumOffset);
|
||||
|
||||
/**
|
||||
* This constant defines the raw value for Type ID Flag for Link Margin.
|
||||
* Type IDs can either have a short value as a `uint8_t` (e.g., `kLqi`, `kLinkMargin` or `kRssi`) or a long value as
|
||||
* a `uint32_t` (`kPdu`).
|
||||
*
|
||||
*/
|
||||
static constexpr uint8_t kLinkMargin = (kShortLength << kLengthOffset) |
|
||||
(kTypeExpMovingAverage << kTypeEnumOffset) |
|
||||
(kMetricLinkMargin << kMetricEnumOffset);
|
||||
|
||||
/**
|
||||
* This constant defines the raw value for Type ID Flag for RSSI
|
||||
*
|
||||
*/
|
||||
static constexpr uint8_t kRssi = (kShortLength << kLengthOffset) | (kTypeExpMovingAverage << kTypeEnumOffset) |
|
||||
(kMetricRssi << kMetricEnumOffset);
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*
|
||||
*/
|
||||
TypeIdFlags(void) = default;
|
||||
|
||||
/**
|
||||
* Constructor to initialize from raw value.
|
||||
* @param[in] aTypeId The Type ID.
|
||||
*
|
||||
* @param[in] aFlags The raw flags value.
|
||||
* @returns the associated value length of @p aTypeId.
|
||||
*
|
||||
*/
|
||||
explicit TypeIdFlags(uint8_t aFlags)
|
||||
: mFlags(aFlags)
|
||||
static uint8_t GetValueLength(uint8_t aTypeId)
|
||||
{
|
||||
return (aTypeId & kLengthFlag) ? sizeof(uint32_t) : sizeof(uint8_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes the Type ID value
|
||||
* This static method updates a Type ID to mark it as reversed.
|
||||
*
|
||||
* This is used for testing only.
|
||||
*
|
||||
* @param[in, out] aTypeId A reference to a Type ID variable to update.
|
||||
*
|
||||
*/
|
||||
void Init(void) { mFlags = 0; }
|
||||
static void MarkAsReserverd(uint8_t &aTypeId) { aTypeId = (aTypeId & ~kTypeMask) | kTypeReserved; }
|
||||
|
||||
/**
|
||||
* This method clears the Extended flag.
|
||||
*
|
||||
*/
|
||||
void ClearExtendedFlag(void) { mFlags &= ~kExtendedFlag; }
|
||||
|
||||
/**
|
||||
* This method sets the Extended flag, indicating an additional second flags byte after the current 1-byte flags.
|
||||
* MUST NOT set in Thread 1.2.1.
|
||||
*
|
||||
*/
|
||||
void SetExtendedFlag(void) { mFlags |= kExtendedFlag; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the Extended flag is set.
|
||||
*
|
||||
* @retval true The Extended flag is set.
|
||||
* @retval false The Extended flag is not set.
|
||||
*
|
||||
*/
|
||||
bool IsExtendedFlagSet(void) const { return (mFlags & kExtendedFlag) != 0; }
|
||||
|
||||
/**
|
||||
* This method clears value length flag.
|
||||
*
|
||||
*/
|
||||
void ClearLengthFlag(void) { mFlags &= ~kLengthFlag; }
|
||||
|
||||
/**
|
||||
* This method sets the value length flag.
|
||||
*
|
||||
*/
|
||||
void SetLengthFlag(void) { mFlags |= kLengthFlag; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the value length flag is set.
|
||||
*
|
||||
* @retval true The value length flag is set, extended value length (4 bytes)
|
||||
* @retval false The value length flag is not set, short value length (1 byte)
|
||||
*
|
||||
*/
|
||||
bool IsLengthFlagSet(void) const { return (mFlags & kLengthFlag) != 0; }
|
||||
|
||||
/**
|
||||
* This method sets the Type/Average Enum.
|
||||
*
|
||||
* @param[in] aTypeEnum Type/Average Enum.
|
||||
*
|
||||
*/
|
||||
void SetTypeEnum(TypeEnum aTypeEnum)
|
||||
{
|
||||
mFlags = (mFlags & ~kTypeEnumMask) | ((aTypeEnum << kTypeEnumOffset) & kTypeEnumMask);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the Type/Average Enum.
|
||||
*
|
||||
* @returns The Type/Average Enum.
|
||||
*
|
||||
*/
|
||||
TypeEnum GetTypeEnum(void) const { return static_cast<TypeEnum>((mFlags & kTypeEnumMask) >> kTypeEnumOffset); }
|
||||
|
||||
/**
|
||||
* This method sets the Metric Enum.
|
||||
*
|
||||
* @param[in] aMetricEnum Metric Enum.
|
||||
*
|
||||
*/
|
||||
void SetMetricEnum(MetricEnum aMetricEnum)
|
||||
{
|
||||
mFlags = (mFlags & ~kMetricEnumMask) | ((aMetricEnum << kMetricEnumOffset) & kMetricEnumMask);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the Metric Enum.
|
||||
*
|
||||
* @returns The Metric Enum.
|
||||
*
|
||||
*/
|
||||
MetricEnum GetMetricEnum(void) const
|
||||
{
|
||||
return static_cast<MetricEnum>((mFlags & kMetricEnumMask) >> kMetricEnumOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the raw value of the entire TypeIdFlags.
|
||||
*
|
||||
* @returns The raw value of TypeIdFlags.
|
||||
*
|
||||
*/
|
||||
uint8_t GetRawValue(void) const { return mFlags; }
|
||||
|
||||
/**
|
||||
* This method sets the raw value of the entire TypeIdFlags.
|
||||
*
|
||||
* @param[in] aFlags The raw flags value.
|
||||
*
|
||||
*/
|
||||
void SetRawValue(uint8_t aFlags) { mFlags = aFlags; }
|
||||
|
||||
private:
|
||||
uint8_t mFlags;
|
||||
} OT_TOOL_PACKED_END;
|
||||
TypeId(void) = delete;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class represents the Series Flags for Forward Tracking Series.
|
||||
@@ -373,10 +254,6 @@ enum EnhAckFlags : uint8_t
|
||||
kEnhAckRegister = OT_LINK_METRICS_ENH_ACK_REGISTER, ///< Register.
|
||||
};
|
||||
|
||||
constexpr uint8_t kMaxTypeIdFlags = 4; ///< Maximum number of TypeIdFlags in a `Metrics`
|
||||
|
||||
uint8_t TypeIdFlagsFromMetrics(TypeIdFlags aTypeIdFlags[], const Metrics &aMetrics);
|
||||
|
||||
/**
|
||||
* This class represents one Series that is being tracked by the Subject.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user