mirror of
https://github.com/espressif/openthread.git
synced 2026-08-06 02:37:47 +00:00
[link-metrics] renames, using namespace, and style changes (#6848)
This commit contains style changes, simplifications, and renames in Link Metrics modules. It moves all the definitions under a new namespace `LinkMetrics` which allows the use of shorter and simpler names for types, methods, and constants (omit the `LinkMetrics` prefix from names). For example, `LinkMetricsTypeIdFlags` and `LinkMetricsSeriesInfo` are renamed to simpler `TypeIdFlags` and `SeriesInfo` respectively.
This commit is contained in:
@@ -51,10 +51,11 @@ otError otLinkMetricsQuery(otInstance * aInstance,
|
||||
{
|
||||
OT_ASSERT(aDestination != nullptr);
|
||||
|
||||
static_cast<Instance *>(aInstance)->Get<LinkMetrics>().SetLinkMetricsReportCallback(aCallback, aCallbackContext);
|
||||
static_cast<Instance *>(aInstance)->Get<LinkMetrics::LinkMetrics>().SetReportCallback(aCallback, aCallbackContext);
|
||||
|
||||
return static_cast<Instance *>(aInstance)->Get<LinkMetrics>().LinkMetricsQuery(
|
||||
static_cast<const Ip6::Address &>(*aDestination), aSeriesId, aLinkMetricsFlags);
|
||||
return static_cast<Instance *>(aInstance)->Get<LinkMetrics::LinkMetrics>().Query(
|
||||
static_cast<const Ip6::Address &>(*aDestination), aSeriesId,
|
||||
static_cast<const LinkMetrics::Metrics *>(aLinkMetricsFlags));
|
||||
}
|
||||
|
||||
otError otLinkMetricsConfigForwardTrackingSeries(otInstance * aInstance,
|
||||
@@ -67,17 +68,19 @@ otError otLinkMetricsConfigForwardTrackingSeries(otInstance *
|
||||
{
|
||||
OT_ASSERT(aDestination != nullptr);
|
||||
|
||||
static_cast<Instance *>(aInstance)->Get<LinkMetrics>().SetLinkMetricsMgmtResponseCallback(aCallback,
|
||||
aCallbackContext);
|
||||
LinkMetrics::LinkMetrics &linkMetrics = static_cast<Instance *>(aInstance)->Get<LinkMetrics::LinkMetrics>();
|
||||
|
||||
return static_cast<Instance *>(aInstance)->Get<LinkMetrics>().SendMgmtRequestForwardTrackingSeries(
|
||||
static_cast<const Ip6::Address &>(*aDestination), aSeriesId, aSeriesFlags, aLinkMetricsFlags);
|
||||
linkMetrics.SetMgmtResponseCallback(aCallback, aCallbackContext);
|
||||
|
||||
return linkMetrics.SendMgmtRequestForwardTrackingSeries(
|
||||
static_cast<const Ip6::Address &>(*aDestination), aSeriesId, aSeriesFlags,
|
||||
static_cast<const LinkMetrics::Metrics *>(aLinkMetricsFlags));
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
|
||||
otError otLinkMetricsConfigEnhAckProbing(otInstance * aInstance,
|
||||
const otIp6Address * aDestination,
|
||||
const otLinkMetricsEnhAckFlags aEnhAckFlags,
|
||||
otLinkMetricsEnhAckFlags aEnhAckFlags,
|
||||
const otLinkMetrics * aLinkMetricsFlags,
|
||||
otLinkMetricsMgmtResponseCallback aCallback,
|
||||
void * aCallbackContext,
|
||||
@@ -86,13 +89,14 @@ otError otLinkMetricsConfigEnhAckProbing(otInstance *
|
||||
{
|
||||
OT_ASSERT(aDestination != nullptr);
|
||||
|
||||
static_cast<Instance *>(aInstance)->Get<LinkMetrics>().SetLinkMetricsMgmtResponseCallback(aCallback,
|
||||
aCallbackContext);
|
||||
static_cast<Instance *>(aInstance)->Get<LinkMetrics>().SetLinkMetricsEnhAckProbingCallback(aEnhAckCallback,
|
||||
aEnhAckCallbackContext);
|
||||
LinkMetrics::LinkMetrics &linkMetrics = static_cast<Instance *>(aInstance)->Get<LinkMetrics::LinkMetrics>();
|
||||
|
||||
return static_cast<Instance *>(aInstance)->Get<LinkMetrics>().SendMgmtRequestEnhAckProbing(
|
||||
static_cast<const Ip6::Address &>(*aDestination), aEnhAckFlags, aLinkMetricsFlags);
|
||||
linkMetrics.SetMgmtResponseCallback(aCallback, aCallbackContext);
|
||||
linkMetrics.SetEnhAckProbingCallback(aEnhAckCallback, aEnhAckCallbackContext);
|
||||
|
||||
return linkMetrics.SendMgmtRequestEnhAckProbing(static_cast<const Ip6::Address &>(*aDestination),
|
||||
static_cast<LinkMetrics::EnhAckFlags>(aEnhAckFlags),
|
||||
static_cast<const LinkMetrics::Metrics *>(aLinkMetricsFlags));
|
||||
}
|
||||
|
||||
otError otLinkMetricsSendLinkProbe(otInstance * aInstance,
|
||||
@@ -101,9 +105,9 @@ otError otLinkMetricsSendLinkProbe(otInstance * aInstance,
|
||||
uint8_t aLength)
|
||||
{
|
||||
OT_ASSERT(aDestination != nullptr);
|
||||
LinkMetrics::LinkMetrics &linkMetrics = static_cast<Instance *>(aInstance)->Get<LinkMetrics::LinkMetrics>();
|
||||
|
||||
return static_cast<Instance *>(aInstance)->Get<LinkMetrics>().SendLinkProbe(
|
||||
static_cast<const Ip6::Address &>(*aDestination), aSeriesId, aLength);
|
||||
return linkMetrics.SendLinkProbe(static_cast<const Ip6::Address &>(*aDestination), aSeriesId, aLength);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -899,7 +899,7 @@ template <> inline DuaManager &Instance::Get(void)
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
template <> inline LinkMetrics &Instance::Get(void)
|
||||
template <> inline LinkMetrics::LinkMetrics &Instance::Get(void)
|
||||
{
|
||||
return mThreadNetif.mLinkMetrics;
|
||||
}
|
||||
|
||||
@@ -2449,7 +2449,7 @@ void Mac::ProcessEnhAckProbing(const RxFrame &aFrame, const Neighbor &aNeighbor)
|
||||
dataLen = enhAckProbingIe->GetLength() - sizeof(VendorIeHeader);
|
||||
VerifyOrExit(dataLen <= kEnhAckProbingIeMaxLen);
|
||||
|
||||
Get<LinkMetrics>().ProcessEnhAckIeData(data, dataLen, aNeighbor);
|
||||
Get<LinkMetrics::LinkMetrics>().ProcessEnhAckIeData(data, dataLen, aNeighbor);
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
+272
-289
@@ -39,27 +39,24 @@
|
||||
#include "common/instance.hpp"
|
||||
#include "common/locator_getters.hpp"
|
||||
#include "common/logging.hpp"
|
||||
#include "mac/mac.hpp"
|
||||
#include "thread/link_metrics_tlvs.hpp"
|
||||
#include "thread/neighbor_table.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace LinkMetrics {
|
||||
|
||||
void LinkMetricsSeriesInfo::Init(uint8_t aSeriesId,
|
||||
const SeriesFlags & aSeriesFlags,
|
||||
const otLinkMetrics &aLinkMetricsFlags)
|
||||
void SeriesInfo::Init(uint8_t aSeriesId, const SeriesFlags &aSeriesFlags, const Metrics &aMetrics)
|
||||
{
|
||||
mSeriesId = aSeriesId;
|
||||
mSeriesFlags = aSeriesFlags;
|
||||
mLinkMetrics.mPduCount = aLinkMetricsFlags.mPduCount;
|
||||
mLinkMetrics.mLqi = aLinkMetricsFlags.mLqi;
|
||||
mLinkMetrics.mLinkMargin = aLinkMetricsFlags.mLinkMargin;
|
||||
mLinkMetrics.mRssi = aLinkMetricsFlags.mRssi;
|
||||
mSeriesId = aSeriesId;
|
||||
mSeriesFlags = aSeriesFlags;
|
||||
mMetrics = aMetrics;
|
||||
mRssAverager.Clear();
|
||||
mLqiAverager.Clear();
|
||||
mPduCount = 0;
|
||||
}
|
||||
|
||||
void LinkMetricsSeriesInfo::AggregateLinkMetrics(uint8_t aFrameType, uint8_t aLqi, int8_t aRss)
|
||||
void SeriesInfo::AggregateLinkMetrics(uint8_t aFrameType, uint8_t aLqi, int8_t aRss)
|
||||
{
|
||||
if (IsFrameTypeMatch(aFrameType))
|
||||
{
|
||||
@@ -69,15 +66,7 @@ void LinkMetricsSeriesInfo::AggregateLinkMetrics(uint8_t aFrameType, uint8_t aLq
|
||||
}
|
||||
}
|
||||
|
||||
void LinkMetricsSeriesInfo::GetLinkMetrics(otLinkMetrics &aLinkMetrics) const
|
||||
{
|
||||
aLinkMetrics.mPduCount = mLinkMetrics.mPduCount;
|
||||
aLinkMetrics.mLqi = mLinkMetrics.mLqi;
|
||||
aLinkMetrics.mLinkMargin = mLinkMetrics.mLinkMargin;
|
||||
aLinkMetrics.mRssi = mLinkMetrics.mRssi;
|
||||
}
|
||||
|
||||
bool LinkMetricsSeriesInfo::IsFrameTypeMatch(uint8_t aFrameType) const
|
||||
bool SeriesInfo::IsFrameTypeMatch(uint8_t aFrameType) const
|
||||
{
|
||||
bool match = false;
|
||||
|
||||
@@ -106,26 +95,28 @@ exit:
|
||||
|
||||
LinkMetrics::LinkMetrics(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mLinkMetricsReportCallback(nullptr)
|
||||
, mLinkMetricsReportCallbackContext(nullptr)
|
||||
, mReportCallback(nullptr)
|
||||
, mReportCallbackContext(nullptr)
|
||||
, mMgmtResponseCallback(nullptr)
|
||||
, mMgmtResponseCallbackContext(nullptr)
|
||||
, mEnhAckProbingIeReportCallback(nullptr)
|
||||
, mEnhAckProbingIeReportCallbackContext(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Error LinkMetrics::LinkMetricsQuery(const Ip6::Address & aDestination,
|
||||
uint8_t aSeriesId,
|
||||
const otLinkMetrics *aLinkMetricsFlags)
|
||||
Error LinkMetrics::Query(const Ip6::Address &aDestination, uint8_t aSeriesId, const Metrics *aMetrics)
|
||||
{
|
||||
Error error;
|
||||
LinkMetricsTypeIdFlags typeIdFlags[kMaxTypeIdFlags];
|
||||
uint8_t typeIdFlagsCount = 0;
|
||||
Neighbor * neighbor = GetNeighborFromLinkLocalAddr(aDestination);
|
||||
Error error;
|
||||
TypeIdFlags typeIdFlags[kMaxTypeIdFlags];
|
||||
uint8_t typeIdFlagsCount = 0;
|
||||
Neighbor * neighbor = GetNeighborFromLinkLocalAddr(aDestination);
|
||||
|
||||
VerifyOrExit(neighbor != nullptr, error = kErrorUnknownNeighbor);
|
||||
VerifyOrExit(neighbor->IsThreadVersion1p2(), error = kErrorNotCapable);
|
||||
|
||||
if (aLinkMetricsFlags != nullptr)
|
||||
if (aMetrics != nullptr)
|
||||
{
|
||||
typeIdFlagsCount = TypeIdFlagsFromLinkMetricsFlags(typeIdFlags, *aLinkMetricsFlags);
|
||||
typeIdFlagsCount = TypeIdFlagsFromMetrics(typeIdFlags, *aMetrics);
|
||||
}
|
||||
|
||||
if (aSeriesId != 0)
|
||||
@@ -140,14 +131,14 @@ exit:
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
|
||||
Error LinkMetrics::SendMgmtRequestForwardTrackingSeries(const Ip6::Address & aDestination,
|
||||
uint8_t aSeriesId,
|
||||
const otLinkMetricsSeriesFlags &aSeriesFlags,
|
||||
const otLinkMetrics * aLinkMetricsFlags)
|
||||
Error LinkMetrics::SendMgmtRequestForwardTrackingSeries(const Ip6::Address & aDestination,
|
||||
uint8_t aSeriesId,
|
||||
const SeriesFlags::Info &aSeriesFlags,
|
||||
const Metrics * aMetrics)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
uint8_t subTlvs[sizeof(Tlv) + sizeof(uint8_t) * 2 + sizeof(LinkMetricsTypeIdFlags) * kMaxTypeIdFlags];
|
||||
Tlv * forwardProbingRegistrationSubTlv = reinterpret_cast<Tlv *>(subTlvs);
|
||||
uint8_t subTlvs[sizeof(Tlv) + sizeof(uint8_t) * 2 + sizeof(TypeIdFlags) * kMaxTypeIdFlags];
|
||||
Tlv * fwdProbingSubTlv = reinterpret_cast<Tlv *>(subTlvs);
|
||||
SeriesFlags *seriesFlags = reinterpret_cast<SeriesFlags *>(subTlvs + sizeof(Tlv) + sizeof(aSeriesId));
|
||||
uint8_t typeIdFlagsOffset = sizeof(Tlv) + sizeof(uint8_t) * 2;
|
||||
uint8_t typeIdFlagsCount = 0;
|
||||
@@ -156,70 +147,68 @@ Error LinkMetrics::SendMgmtRequestForwardTrackingSeries(const Ip6::Address &
|
||||
VerifyOrExit(neighbor != nullptr, error = kErrorUnknownNeighbor);
|
||||
VerifyOrExit(neighbor->IsThreadVersion1p2(), error = kErrorNotCapable);
|
||||
|
||||
// Directly transform `aLinkMetricsFlags` into LinkMetricsTypeIdFlags and put them into `subTlvs`
|
||||
if (aLinkMetricsFlags != nullptr)
|
||||
// Directly transform `aMetrics` into TypeIdFlags and put them into `subTlvs`
|
||||
if (aMetrics != nullptr)
|
||||
{
|
||||
typeIdFlagsCount = TypeIdFlagsFromLinkMetricsFlags(
|
||||
reinterpret_cast<LinkMetricsTypeIdFlags *>(subTlvs + typeIdFlagsOffset), *aLinkMetricsFlags);
|
||||
typeIdFlagsCount =
|
||||
TypeIdFlagsFromMetrics(reinterpret_cast<TypeIdFlags *>(subTlvs + typeIdFlagsOffset), *aMetrics);
|
||||
}
|
||||
|
||||
VerifyOrExit(aSeriesId > kQueryIdSingleProbe, error = kErrorInvalidArgs);
|
||||
|
||||
forwardProbingRegistrationSubTlv->SetType(kForwardProbingRegistration);
|
||||
forwardProbingRegistrationSubTlv->SetLength(
|
||||
sizeof(uint8_t) * 2 +
|
||||
sizeof(LinkMetricsTypeIdFlags) *
|
||||
typeIdFlagsCount); // SeriesId + SeriesFlags + typeIdFlagsCount * LinkMetricsTypeIdFlags
|
||||
fwdProbingSubTlv->SetType(SubTlv::kFwdProbingReg);
|
||||
|
||||
// SeriesId + SeriesFlags + typeIdFlagsCount * TypeIdFlags
|
||||
fwdProbingSubTlv->SetLength(sizeof(uint8_t) * 2 + sizeof(TypeIdFlags) * typeIdFlagsCount);
|
||||
|
||||
memcpy(subTlvs + sizeof(Tlv), &aSeriesId, sizeof(aSeriesId));
|
||||
|
||||
seriesFlags->SetFromOtSeriesFlags(aSeriesFlags);
|
||||
seriesFlags->SetFrom(aSeriesFlags);
|
||||
|
||||
error = Get<Mle::MleRouter>().SendLinkMetricsManagementRequest(aDestination, subTlvs,
|
||||
forwardProbingRegistrationSubTlv->GetSize());
|
||||
error = Get<Mle::MleRouter>().SendLinkMetricsManagementRequest(aDestination, subTlvs, fwdProbingSubTlv->GetSize());
|
||||
|
||||
exit:
|
||||
otLogDebgMle("SendMgmtRequestForwardTrackingSeries, error:%s, Series ID:%u", ErrorToString(error), aSeriesId);
|
||||
return error;
|
||||
}
|
||||
|
||||
Error LinkMetrics::SendMgmtRequestEnhAckProbing(const Ip6::Address & aDestination,
|
||||
const otLinkMetricsEnhAckFlags aEnhAckFlags,
|
||||
const otLinkMetrics * aLinkMetricsFlags)
|
||||
Error LinkMetrics::SendMgmtRequestEnhAckProbing(const Ip6::Address &aDestination,
|
||||
const EnhAckFlags aEnhAckFlags,
|
||||
const Metrics * aMetrics)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
EnhAckLinkMetricsConfigurationSubTlv enhAckLinkMetricsConfigurationSubTlv;
|
||||
Mac::Address macAddress;
|
||||
Neighbor * neighbor = GetNeighborFromLinkLocalAddr(aDestination);
|
||||
Error error = kErrorNone;
|
||||
EnhAckConfigSubTlv enhAckConfigSubTlv;
|
||||
Mac::Address macAddress;
|
||||
Neighbor * neighbor = GetNeighborFromLinkLocalAddr(aDestination);
|
||||
|
||||
VerifyOrExit(neighbor != nullptr, error = kErrorUnknownNeighbor);
|
||||
VerifyOrExit(neighbor->IsThreadVersion1p2(), error = kErrorNotCapable);
|
||||
|
||||
if (aEnhAckFlags == OT_LINK_METRICS_ENH_ACK_CLEAR)
|
||||
if (aEnhAckFlags == kEnhAckClear)
|
||||
{
|
||||
VerifyOrExit(aLinkMetricsFlags == nullptr, error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aMetrics == nullptr, error = kErrorInvalidArgs);
|
||||
}
|
||||
|
||||
enhAckLinkMetricsConfigurationSubTlv.SetEnhAckFlags(aEnhAckFlags);
|
||||
enhAckConfigSubTlv.SetEnhAckFlags(aEnhAckFlags);
|
||||
|
||||
if (aLinkMetricsFlags != nullptr)
|
||||
if (aMetrics != nullptr)
|
||||
{
|
||||
enhAckLinkMetricsConfigurationSubTlv.SetTypeIdFlags(aLinkMetricsFlags);
|
||||
enhAckConfigSubTlv.SetTypeIdFlags(*aMetrics);
|
||||
}
|
||||
|
||||
error = Get<Mle::MleRouter>().SendLinkMetricsManagementRequest(
|
||||
aDestination, reinterpret_cast<const uint8_t *>(&enhAckLinkMetricsConfigurationSubTlv),
|
||||
enhAckLinkMetricsConfigurationSubTlv.GetSize());
|
||||
aDestination, reinterpret_cast<const uint8_t *>(&enhAckConfigSubTlv), enhAckConfigSubTlv.GetSize());
|
||||
|
||||
if (aLinkMetricsFlags != nullptr)
|
||||
if (aMetrics != nullptr)
|
||||
{
|
||||
neighbor->SetEnhAckProbingMetrics(*aLinkMetricsFlags);
|
||||
neighbor->SetEnhAckProbingMetrics(*aMetrics);
|
||||
}
|
||||
else
|
||||
{
|
||||
otLinkMetrics linkMetrics;
|
||||
memset(&linkMetrics, 0, sizeof(linkMetrics));
|
||||
neighbor->SetEnhAckProbingMetrics(linkMetrics);
|
||||
Metrics metrics;
|
||||
|
||||
metrics.Clear();
|
||||
neighbor->SetEnhAckProbingMetrics(metrics);
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -247,19 +236,19 @@ exit:
|
||||
#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
Error LinkMetrics::AppendLinkMetricsReport(Message &aMessage, const Message &aRequestMessage, Neighbor &aNeighbor)
|
||||
Error LinkMetrics::AppendReport(Message &aMessage, const Message &aRequestMessage, Neighbor &aNeighbor)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Tlv tlv;
|
||||
uint8_t queryId;
|
||||
bool hasQueryId = false;
|
||||
uint8_t length = 0;
|
||||
uint16_t startOffset = aMessage.GetLength();
|
||||
uint16_t offset;
|
||||
uint16_t endOffset;
|
||||
otLinkMetricsValues linkMetricsValues;
|
||||
Error error = kErrorNone;
|
||||
Tlv tlv;
|
||||
uint8_t queryId;
|
||||
bool hasQueryId = false;
|
||||
uint8_t length = 0;
|
||||
uint16_t startOffset = aMessage.GetLength();
|
||||
uint16_t offset;
|
||||
uint16_t endOffset;
|
||||
MetricsValues values;
|
||||
|
||||
memset(&linkMetricsValues, 0, sizeof(linkMetricsValues));
|
||||
values.Clear();
|
||||
|
||||
SuccessOrExit(error = Tlv::FindTlvValueOffset(aRequestMessage, Mle::Tlv::Type::kLinkMetricsQuery, offset,
|
||||
endOffset)); // `endOffset` is used to store tlv length here
|
||||
@@ -272,15 +261,15 @@ Error LinkMetrics::AppendLinkMetricsReport(Message &aMessage, const Message &aRe
|
||||
|
||||
switch (tlv.GetType())
|
||||
{
|
||||
case kLinkMetricsQueryId:
|
||||
SuccessOrExit(error = Tlv::Read<LinkMetricsQueryIdTlv>(aRequestMessage, offset, queryId));
|
||||
case SubTlv::kQueryId:
|
||||
SuccessOrExit(error = Tlv::Read<QueryIdSubTlv>(aRequestMessage, offset, queryId));
|
||||
hasQueryId = true;
|
||||
break;
|
||||
|
||||
case kLinkMetricsQueryOptions:
|
||||
case SubTlv::kQueryOptions:
|
||||
SuccessOrExit(error = ReadTypeIdFlagsFromMessage(aRequestMessage, offset + sizeof(tlv),
|
||||
static_cast<uint16_t>(offset + tlv.GetSize()),
|
||||
linkMetricsValues.mMetrics));
|
||||
values.GetMetrics()));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -298,41 +287,41 @@ Error LinkMetrics::AppendLinkMetricsReport(Message &aMessage, const Message &aRe
|
||||
|
||||
if (queryId == kQueryIdSingleProbe)
|
||||
{
|
||||
linkMetricsValues.mPduCountValue = aRequestMessage.GetPsduCount();
|
||||
linkMetricsValues.mLqiValue = aRequestMessage.GetAverageLqi();
|
||||
linkMetricsValues.mLinkMarginValue =
|
||||
values.mPduCountValue = aRequestMessage.GetPsduCount();
|
||||
values.mLqiValue = aRequestMessage.GetAverageLqi();
|
||||
// Linearly scale Link Margin from [0, 130] to [0, 255]
|
||||
values.mLinkMarginValue =
|
||||
LinkQualityInfo::ConvertRssToLinkMargin(Get<Mac::Mac>().GetNoiseFloor(), aRequestMessage.GetAverageRss()) *
|
||||
255 / 130; // Linear scale Link Margin from [0, 130] to [0, 255]
|
||||
linkMetricsValues.mRssiValue =
|
||||
(aRequestMessage.GetAverageRss() + 130) * 255 / 130; // Linear scale rss from [-130, 0] to [0, 255]
|
||||
255 / 130;
|
||||
// Linearly scale rss from [-130, 0] to [0, 255]
|
||||
values.mRssiValue = (aRequestMessage.GetAverageRss() + 130) * 255 / 130;
|
||||
|
||||
SuccessOrExit(error = AppendReportSubTlvToMessage(aMessage, length, linkMetricsValues));
|
||||
SuccessOrExit(error = AppendReportSubTlvToMessage(aMessage, length, values));
|
||||
}
|
||||
else
|
||||
{
|
||||
LinkMetricsSeriesInfo *seriesInfo = aNeighbor.GetForwardTrackingSeriesInfo(queryId);
|
||||
SeriesInfo *seriesInfo = aNeighbor.GetForwardTrackingSeriesInfo(queryId);
|
||||
|
||||
if (seriesInfo == nullptr)
|
||||
{
|
||||
SuccessOrExit(error =
|
||||
AppendStatusSubTlvToMessage(aMessage, length, kLinkMetricsStatusSeriesIdNotRecognized));
|
||||
SuccessOrExit(error = AppendStatusSubTlvToMessage(aMessage, length, kStatusSeriesIdNotRecognized));
|
||||
}
|
||||
else if (seriesInfo->GetPduCount() == 0)
|
||||
{
|
||||
SuccessOrExit(
|
||||
error = AppendStatusSubTlvToMessage(aMessage, length, kLinkMetricsStatusNoMatchingFramesReceived));
|
||||
SuccessOrExit(error = AppendStatusSubTlvToMessage(aMessage, length, kStatusNoMatchingFramesReceived));
|
||||
}
|
||||
else
|
||||
{
|
||||
seriesInfo->GetLinkMetrics(linkMetricsValues.mMetrics);
|
||||
linkMetricsValues.mPduCountValue = seriesInfo->GetPduCount();
|
||||
linkMetricsValues.mLqiValue = seriesInfo->GetAverageLqi();
|
||||
linkMetricsValues.mLinkMarginValue =
|
||||
LinkQualityInfo::ConvertRssToLinkMargin(Get<Mac::Mac>().GetNoiseFloor(),
|
||||
seriesInfo->GetAverageRss()) *
|
||||
255 / 130; // Linear scale Link Margin from [0, 130] to [0, 255]
|
||||
linkMetricsValues.mRssiValue =
|
||||
(seriesInfo->GetAverageRss() + 130) * 255 / 130; // Linear scale RSSI from [-130, 0] to [0, 255]
|
||||
SuccessOrExit(error = AppendReportSubTlvToMessage(aMessage, length, linkMetricsValues));
|
||||
values.SetMetrics(seriesInfo->GetLinkMetrics());
|
||||
values.mPduCountValue = seriesInfo->GetPduCount();
|
||||
values.mLqiValue = seriesInfo->GetAverageLqi();
|
||||
// Linearly scale Link Margin from [0, 130] to [0, 255]
|
||||
values.mLinkMarginValue =
|
||||
LinkQualityInfo::ConvertRssToLinkMargin(Get<Mac::Mac>().GetNoiseFloor(), seriesInfo->GetAverageRss()) *
|
||||
255 / 130;
|
||||
// Linearly scale RSSI from [-130, 0] to [0, 255]
|
||||
values.mRssiValue = (seriesInfo->GetAverageRss() + 130) * 255 / 130;
|
||||
SuccessOrExit(error = AppendReportSubTlvToMessage(aMessage, length, values));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,38 +329,37 @@ Error LinkMetrics::AppendLinkMetricsReport(Message &aMessage, const Message &aRe
|
||||
aMessage.Write(startOffset, tlv);
|
||||
|
||||
exit:
|
||||
otLogDebgMle("AppendLinkMetricsReport, error:%s", ErrorToString(error));
|
||||
otLogDebgMle("AppendReport, error:%s", ErrorToString(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
Error LinkMetrics::HandleLinkMetricsManagementRequest(const Message & aMessage,
|
||||
Neighbor & aNeighbor,
|
||||
LinkMetricsStatus &aStatus)
|
||||
Error LinkMetrics::HandleManagementRequest(const Message &aMessage, Neighbor &aNeighbor, Status &aStatus)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Tlv tlv;
|
||||
uint8_t seriesId;
|
||||
SeriesFlags seriesFlags;
|
||||
LinkMetricsEnhAckFlags enhAckFlags;
|
||||
otLinkMetrics linkMetrics;
|
||||
bool hasForwardProbingRegistrationTlv = false;
|
||||
bool hasEnhAckProbingTlv = false;
|
||||
uint16_t offset;
|
||||
uint16_t length;
|
||||
uint16_t index = 0;
|
||||
Error error = kErrorNone;
|
||||
Tlv tlv;
|
||||
uint8_t seriesId;
|
||||
SeriesFlags seriesFlags;
|
||||
EnhAckFlags enhAckFlags;
|
||||
Metrics metrics;
|
||||
bool hasForwardProbingRegistrationTlv = false;
|
||||
bool hasEnhAckProbingTlv = false;
|
||||
uint16_t offset;
|
||||
uint16_t length;
|
||||
uint16_t index = 0;
|
||||
|
||||
SuccessOrExit(error = Tlv::FindTlvValueOffset(aMessage, Mle::Tlv::Type::kLinkMetricsManagement, offset, length));
|
||||
|
||||
while (index < length)
|
||||
{
|
||||
uint16_t pos = offset + index;
|
||||
|
||||
SuccessOrExit(aMessage.Read(pos, tlv));
|
||||
|
||||
pos += sizeof(tlv);
|
||||
|
||||
switch (tlv.GetType())
|
||||
{
|
||||
case kForwardProbingRegistration:
|
||||
case SubTlv::kFwdProbingReg:
|
||||
VerifyOrExit(!hasForwardProbingRegistrationTlv && !hasEnhAckProbingTlv, error = kErrorParse);
|
||||
VerifyOrExit(tlv.GetLength() >= sizeof(seriesId) + sizeof(seriesFlags), error = kErrorParse);
|
||||
SuccessOrExit(aMessage.Read(pos, seriesId));
|
||||
@@ -379,17 +367,17 @@ Error LinkMetrics::HandleLinkMetricsManagementRequest(const Message & aMessag
|
||||
SuccessOrExit(aMessage.Read(pos, seriesFlags));
|
||||
pos += sizeof(seriesFlags);
|
||||
SuccessOrExit(error = ReadTypeIdFlagsFromMessage(
|
||||
aMessage, pos, static_cast<uint16_t>(offset + index + tlv.GetSize()), linkMetrics));
|
||||
aMessage, pos, static_cast<uint16_t>(offset + index + tlv.GetSize()), metrics));
|
||||
hasForwardProbingRegistrationTlv = true;
|
||||
break;
|
||||
|
||||
case kEnhancedACKConfiguration:
|
||||
case SubTlv::kEnhAckConfig:
|
||||
VerifyOrExit(!hasForwardProbingRegistrationTlv && !hasEnhAckProbingTlv, error = kErrorParse);
|
||||
VerifyOrExit(tlv.GetLength() >= sizeof(LinkMetricsEnhAckFlags), error = kErrorParse);
|
||||
VerifyOrExit(tlv.GetLength() >= sizeof(EnhAckFlags), error = kErrorParse);
|
||||
SuccessOrExit(aMessage.Read(pos, enhAckFlags));
|
||||
pos += sizeof(enhAckFlags);
|
||||
SuccessOrExit(error = ReadTypeIdFlagsFromMessage(
|
||||
aMessage, pos, static_cast<uint16_t>(offset + index + tlv.GetSize()), linkMetrics));
|
||||
aMessage, pos, static_cast<uint16_t>(offset + index + tlv.GetSize()), metrics));
|
||||
hasEnhAckProbingTlv = true;
|
||||
break;
|
||||
|
||||
@@ -402,11 +390,11 @@ Error LinkMetrics::HandleLinkMetricsManagementRequest(const Message & aMessag
|
||||
|
||||
if (hasForwardProbingRegistrationTlv)
|
||||
{
|
||||
aStatus = ConfigureForwardTrackingSeries(seriesId, seriesFlags, linkMetrics, aNeighbor);
|
||||
aStatus = ConfigureForwardTrackingSeries(seriesId, seriesFlags, metrics, aNeighbor);
|
||||
}
|
||||
else if (hasEnhAckProbingTlv)
|
||||
{
|
||||
aStatus = ConfigureEnhAckProbing(enhAckFlags, linkMetrics, aNeighbor);
|
||||
aStatus = ConfigureEnhAckProbing(enhAckFlags, metrics, aNeighbor);
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -414,17 +402,17 @@ exit:
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
|
||||
Error LinkMetrics::HandleLinkMetricsManagementResponse(const Message &aMessage, const Ip6::Address &aAddress)
|
||||
Error LinkMetrics::HandleManagementResponse(const Message &aMessage, const Ip6::Address &aAddress)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Tlv tlv;
|
||||
uint16_t offset;
|
||||
uint16_t length;
|
||||
uint16_t index = 0;
|
||||
LinkMetricsStatus status;
|
||||
bool hasStatus = false;
|
||||
Error error = kErrorNone;
|
||||
Tlv tlv;
|
||||
uint16_t offset;
|
||||
uint16_t length;
|
||||
uint16_t index = 0;
|
||||
Status status;
|
||||
bool hasStatus = false;
|
||||
|
||||
VerifyOrExit(mLinkMetricsMgmtResponseCallback != nullptr);
|
||||
VerifyOrExit(mMgmtResponseCallback != nullptr);
|
||||
|
||||
SuccessOrExit(error = Tlv::FindTlvValueOffset(aMessage, Mle::Tlv::Type::kLinkMetricsManagement, offset, length));
|
||||
|
||||
@@ -434,7 +422,7 @@ Error LinkMetrics::HandleLinkMetricsManagementResponse(const Message &aMessage,
|
||||
|
||||
switch (tlv.GetType())
|
||||
{
|
||||
case kLinkMetricsStatus:
|
||||
case SubTlv::kStatus:
|
||||
VerifyOrExit(!hasStatus, error = kErrorParse);
|
||||
VerifyOrExit(tlv.GetLength() == sizeof(status), error = kErrorParse);
|
||||
SuccessOrExit(aMessage.Read(offset + index + sizeof(tlv), status));
|
||||
@@ -450,98 +438,100 @@ Error LinkMetrics::HandleLinkMetricsManagementResponse(const Message &aMessage,
|
||||
|
||||
VerifyOrExit(hasStatus, error = kErrorParse);
|
||||
|
||||
mLinkMetricsMgmtResponseCallback(&aAddress, status, mLinkMetricsMgmtResponseCallbackContext);
|
||||
mMgmtResponseCallback(&aAddress, status, mMgmtResponseCallbackContext);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void LinkMetrics::HandleLinkMetricsReport(const Message & aMessage,
|
||||
uint16_t aOffset,
|
||||
uint16_t aLength,
|
||||
const Ip6::Address &aAddress)
|
||||
void LinkMetrics::HandleReport(const Message & aMessage,
|
||||
uint16_t aOffset,
|
||||
uint16_t aLength,
|
||||
const Ip6::Address &aAddress)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
otLinkMetricsValues metricsValues;
|
||||
uint8_t metricsRawValue;
|
||||
uint16_t pos = aOffset;
|
||||
uint16_t endPos = aOffset + aLength;
|
||||
Tlv tlv;
|
||||
LinkMetricsTypeIdFlags typeIdFlags;
|
||||
bool hasStatus = false;
|
||||
bool hasReport = false;
|
||||
LinkMetricsStatus status;
|
||||
Error error = kErrorNone;
|
||||
MetricsValues values;
|
||||
uint8_t rawValue;
|
||||
uint16_t pos = aOffset;
|
||||
uint16_t endPos = aOffset + aLength;
|
||||
Tlv tlv;
|
||||
TypeIdFlags typeIdFlags;
|
||||
bool hasStatus = false;
|
||||
bool hasReport = false;
|
||||
Status status;
|
||||
|
||||
OT_UNUSED_VARIABLE(error);
|
||||
|
||||
VerifyOrExit(mLinkMetricsReportCallback != nullptr);
|
||||
VerifyOrExit(mReportCallback != nullptr);
|
||||
|
||||
memset(&metricsValues, 0, sizeof(metricsValues));
|
||||
values.Clear();
|
||||
|
||||
while (pos < endPos)
|
||||
{
|
||||
SuccessOrExit(aMessage.Read(pos, tlv));
|
||||
VerifyOrExit(tlv.GetType() == kLinkMetricsReportSub);
|
||||
VerifyOrExit(tlv.GetType() == SubTlv::kReport);
|
||||
pos += sizeof(Tlv);
|
||||
|
||||
VerifyOrExit(pos + tlv.GetLength() <= endPos, error = kErrorParse);
|
||||
|
||||
switch (tlv.GetType())
|
||||
{
|
||||
case kLinkMetricsStatus:
|
||||
VerifyOrExit(!hasStatus && !hasReport,
|
||||
error = kErrorDrop); // There should be either: one Status TLV or some Report-Sub TLVs
|
||||
case SubTlv::kStatus:
|
||||
// There should be either: one Status TLV or some Report-Sub TLVs
|
||||
VerifyOrExit(!hasStatus && !hasReport, error = kErrorDrop);
|
||||
VerifyOrExit(tlv.GetLength() == sizeof(status), error = kErrorParse);
|
||||
SuccessOrExit(aMessage.Read(pos, status));
|
||||
hasStatus = true;
|
||||
pos += sizeof(status);
|
||||
break;
|
||||
|
||||
case kLinkMetricsReportSub:
|
||||
VerifyOrExit(!hasStatus,
|
||||
error = kErrorDrop); // There shouldn't be any Report-Sub TLV when there's a Status TLV
|
||||
case SubTlv::kReport:
|
||||
// There shouldn't be any Report-Sub TLV when there's a Status TLV
|
||||
VerifyOrExit(!hasStatus, error = kErrorDrop);
|
||||
VerifyOrExit(tlv.GetLength() > sizeof(typeIdFlags), error = kErrorParse);
|
||||
SuccessOrExit(aMessage.Read(pos, typeIdFlags));
|
||||
|
||||
if (typeIdFlags.IsExtendedFlagSet())
|
||||
{
|
||||
pos += tlv.GetLength(); // Skip the whole sub-TLV if `E` flag is set
|
||||
continue;
|
||||
}
|
||||
|
||||
hasReport = true;
|
||||
pos += sizeof(LinkMetricsTypeIdFlags);
|
||||
pos += sizeof(TypeIdFlags);
|
||||
|
||||
switch (typeIdFlags.GetRawValue())
|
||||
{
|
||||
case kTypeIdFlagPdu:
|
||||
metricsValues.mMetrics.mPduCount = true;
|
||||
SuccessOrExit(aMessage.Read(pos, metricsValues.mPduCountValue));
|
||||
case TypeIdFlags::kPdu:
|
||||
values.GetMetrics().mPduCount = true;
|
||||
SuccessOrExit(aMessage.Read(pos, values.mPduCountValue));
|
||||
pos += sizeof(uint32_t);
|
||||
otLogDebgMle(" - PDU Counter: %d (Count/Summation)", metricsValues.mPduCountValue);
|
||||
otLogDebgMle(" - PDU Counter: %d (Count/Summation)", values.mPduCountValue);
|
||||
break;
|
||||
|
||||
case kTypeIdFlagLqi:
|
||||
metricsValues.mMetrics.mLqi = true;
|
||||
SuccessOrExit(aMessage.Read(pos, metricsValues.mLqiValue));
|
||||
case TypeIdFlags::kLqi:
|
||||
values.GetMetrics().mLqi = true;
|
||||
SuccessOrExit(aMessage.Read(pos, values.mLqiValue));
|
||||
pos += sizeof(uint8_t);
|
||||
otLogDebgMle(" - LQI: %d (Exponential Moving Average)", metricsValues.mLqiValue);
|
||||
otLogDebgMle(" - LQI: %d (Exponential Moving Average)", values.mLqiValue);
|
||||
break;
|
||||
|
||||
case kTypeIdFlagLinkMargin:
|
||||
metricsValues.mMetrics.mLinkMargin = true;
|
||||
SuccessOrExit(aMessage.Read(pos, metricsRawValue));
|
||||
metricsValues.mLinkMarginValue =
|
||||
metricsRawValue * 130 / 255; // Reverse operation for linear scale, map from [0, 255] to [0, 130]
|
||||
case TypeIdFlags::kLinkMargin:
|
||||
values.GetMetrics().mLinkMargin = true;
|
||||
SuccessOrExit(aMessage.Read(pos, rawValue));
|
||||
// Reverse operation for linear scale, map from [0, 255] to [0, 130]
|
||||
values.mLinkMarginValue = rawValue * 130 / 255;
|
||||
pos += sizeof(uint8_t);
|
||||
otLogDebgMle(" - Margin: %d (dB) (Exponential Moving Average)", metricsValues.mLinkMarginValue);
|
||||
otLogDebgMle(" - Margin: %d (dB) (Exponential Moving Average)", values.mLinkMarginValue);
|
||||
break;
|
||||
|
||||
case kTypeIdFlagRssi:
|
||||
metricsValues.mMetrics.mRssi = true;
|
||||
SuccessOrExit(aMessage.Read(pos, metricsRawValue));
|
||||
metricsValues.mRssiValue = metricsRawValue * 130 / 255 -
|
||||
130; // Reverse operation for linear scale, map from [0, 255] to [-130, 0]
|
||||
case TypeIdFlags::kRssi:
|
||||
values.GetMetrics().mRssi = true;
|
||||
SuccessOrExit(aMessage.Read(pos, rawValue));
|
||||
// Reverse operation for linear scale, map from [0, 255] to [-130, 0]
|
||||
values.mRssiValue = rawValue * 130 / 255 - 130;
|
||||
pos += sizeof(uint8_t);
|
||||
otLogDebgMle(" - RSSI: %d (dBm) (Exponential Moving Average)", metricsValues.mRssiValue);
|
||||
otLogDebgMle(" - RSSI: %d (dBm) (Exponential Moving Average)", values.mRssiValue);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -553,16 +543,15 @@ void LinkMetrics::HandleLinkMetricsReport(const Message & aMessage,
|
||||
|
||||
if (hasStatus)
|
||||
{
|
||||
mLinkMetricsReportCallback(&aAddress, nullptr, status, mLinkMetricsReportCallbackContext);
|
||||
mReportCallback(&aAddress, nullptr, status, mReportCallbackContext);
|
||||
}
|
||||
else if (hasReport)
|
||||
{
|
||||
mLinkMetricsReportCallback(&aAddress, &metricsValues, OT_LINK_METRICS_STATUS_SUCCESS,
|
||||
mLinkMetricsReportCallbackContext);
|
||||
mReportCallback(&aAddress, &values, OT_LINK_METRICS_STATUS_SUCCESS, mReportCallbackContext);
|
||||
}
|
||||
|
||||
exit:
|
||||
otLogDebgMle("HandleLinkMetricsReport, error:%s", ErrorToString(error));
|
||||
otLogDebgMle("HandleReport, error:%s", ErrorToString(error));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -574,84 +563,82 @@ Error LinkMetrics::HandleLinkProbe(const Message &aMessage, uint8_t &aSeriesId)
|
||||
|
||||
SuccessOrExit(error = Tlv::FindTlvValueOffset(aMessage, Mle::Tlv::Type::kLinkProbe, offset, length));
|
||||
VerifyOrExit(length >= sizeof(aSeriesId), error = kErrorParse);
|
||||
SuccessOrExit(error = aMessage.Read(offset, aSeriesId));
|
||||
VerifyOrExit(aSeriesId >= kQueryIdSingleProbe && aSeriesId <= kSeriesIdAllSeries, error = kErrorInvalidArgs);
|
||||
error = aMessage.Read(offset, aSeriesId);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void LinkMetrics::SetLinkMetricsReportCallback(otLinkMetricsReportCallback aCallback, void *aCallbackContext)
|
||||
void LinkMetrics::SetReportCallback(ReportCallback aCallback, void *aContext)
|
||||
{
|
||||
mLinkMetricsReportCallback = aCallback;
|
||||
mLinkMetricsReportCallbackContext = aCallbackContext;
|
||||
mReportCallback = aCallback;
|
||||
mReportCallbackContext = aContext;
|
||||
}
|
||||
|
||||
void LinkMetrics::SetLinkMetricsMgmtResponseCallback(otLinkMetricsMgmtResponseCallback aCallback,
|
||||
void * aCallbackContext)
|
||||
void LinkMetrics::SetMgmtResponseCallback(MgmtResponseCallback aCallback, void *aContext)
|
||||
{
|
||||
mLinkMetricsMgmtResponseCallback = aCallback;
|
||||
mLinkMetricsMgmtResponseCallbackContext = aCallbackContext;
|
||||
mMgmtResponseCallback = aCallback;
|
||||
mMgmtResponseCallbackContext = aContext;
|
||||
}
|
||||
|
||||
void LinkMetrics::SetLinkMetricsEnhAckProbingCallback(otLinkMetricsEnhAckProbingIeReportCallback aCallback,
|
||||
void * aCallbackContext)
|
||||
void LinkMetrics::SetEnhAckProbingCallback(EnhAckProbingIeReportCallback aCallback, void *aContext)
|
||||
{
|
||||
mLinkMetricsEnhAckProbingIeReportCallback = aCallback;
|
||||
mLinkMetricsEnhAckProbingIeReportCallbackContext = aCallbackContext;
|
||||
mEnhAckProbingIeReportCallback = aCallback;
|
||||
mEnhAckProbingIeReportCallbackContext = aContext;
|
||||
}
|
||||
|
||||
void LinkMetrics::ProcessEnhAckIeData(const uint8_t *aData, uint8_t aLen, const Neighbor &aNeighbor)
|
||||
void LinkMetrics::ProcessEnhAckIeData(const uint8_t *aData, uint8_t aLength, const Neighbor &aNeighbor)
|
||||
{
|
||||
otLinkMetricsValues linkMetricsValues;
|
||||
uint8_t idx = 0;
|
||||
MetricsValues values;
|
||||
uint8_t idx = 0;
|
||||
|
||||
VerifyOrExit(mLinkMetricsEnhAckProbingIeReportCallback != nullptr);
|
||||
VerifyOrExit(mEnhAckProbingIeReportCallback != nullptr);
|
||||
|
||||
linkMetricsValues.mMetrics = aNeighbor.GetEnhAckProbingMetrics();
|
||||
values.SetMetrics(aNeighbor.GetEnhAckProbingMetrics());
|
||||
|
||||
if (linkMetricsValues.mMetrics.mLqi && idx < aLen)
|
||||
if (values.GetMetrics().mLqi && idx < aLength)
|
||||
{
|
||||
linkMetricsValues.mLqiValue = aData[idx++];
|
||||
values.mLqiValue = aData[idx++];
|
||||
}
|
||||
if (linkMetricsValues.mMetrics.mLinkMargin && idx < aLen)
|
||||
if (values.GetMetrics().mLinkMargin && idx < aLength)
|
||||
{
|
||||
linkMetricsValues.mLinkMarginValue = aData[idx++];
|
||||
values.mLinkMarginValue = aData[idx++];
|
||||
}
|
||||
if (linkMetricsValues.mMetrics.mRssi && idx < aLen)
|
||||
if (values.GetMetrics().mRssi && idx < aLength)
|
||||
{
|
||||
linkMetricsValues.mRssiValue = aData[idx++];
|
||||
values.mRssiValue = aData[idx++];
|
||||
}
|
||||
|
||||
mLinkMetricsEnhAckProbingIeReportCallback(aNeighbor.GetRloc16(), &aNeighbor.GetExtAddress(), &linkMetricsValues,
|
||||
mLinkMetricsEnhAckProbingIeReportCallbackContext);
|
||||
mEnhAckProbingIeReportCallback(aNeighbor.GetRloc16(), &aNeighbor.GetExtAddress(), &values,
|
||||
mEnhAckProbingIeReportCallbackContext);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
Error LinkMetrics::SendLinkMetricsQuery(const Ip6::Address & aDestination,
|
||||
uint8_t aSeriesId,
|
||||
const LinkMetricsTypeIdFlags *aTypeIdFlags,
|
||||
uint8_t aTypeIdFlagsCount)
|
||||
Error LinkMetrics::SendLinkMetricsQuery(const Ip6::Address &aDestination,
|
||||
uint8_t aSeriesId,
|
||||
const TypeIdFlags * aTypeIdFlags,
|
||||
uint8_t aTypeIdFlagsCount)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
LinkMetricsQueryOptionsTlv linkMetricsQueryOptionsTlv;
|
||||
uint8_t length = 0;
|
||||
static const uint8_t tlvs[] = {Mle::Tlv::kLinkMetricsReport};
|
||||
uint8_t buf[sizeof(Tlv) * 3 + sizeof(uint8_t) +
|
||||
sizeof(LinkMetricsTypeIdFlags) *
|
||||
kMaxTypeIdFlags]; // LinkMetricsQuery Tlv + LinkMetricsQueryId sub-TLV (value-length: 1 byte) +
|
||||
// LinkMetricsQueryOptions sub-TLV (value-length: `kMaxTypeIdFlags` bytes)
|
||||
Tlv *tlv = reinterpret_cast<Tlv *>(buf);
|
||||
Tlv subTlv;
|
||||
// LinkMetricsQuery Tlv + LinkMetricsQueryId sub-TLV (value-length: 1 byte) +
|
||||
// LinkMetricsQueryOptions sub-TLV (value-length: `kMaxTypeIdFlags` bytes)
|
||||
constexpr uint16_t kBufferSize = sizeof(Tlv) * 3 + sizeof(uint8_t) + sizeof(TypeIdFlags) * kMaxTypeIdFlags;
|
||||
|
||||
Error error = kErrorNone;
|
||||
QueryOptionsSubTlv queryOptionsTlv;
|
||||
uint8_t length = 0;
|
||||
static const uint8_t tlvs[] = {Mle::Tlv::kLinkMetricsReport};
|
||||
uint8_t buf[kBufferSize];
|
||||
Tlv * tlv = reinterpret_cast<Tlv *>(buf);
|
||||
Tlv subTlv;
|
||||
|
||||
// Link Metrics Query TLV
|
||||
tlv->SetType(Mle::Tlv::kLinkMetricsQuery);
|
||||
length += sizeof(Tlv);
|
||||
|
||||
// Link Metrics Query ID sub-TLV
|
||||
subTlv.SetType(kLinkMetricsQueryId);
|
||||
subTlv.SetType(SubTlv::kQueryId);
|
||||
subTlv.SetLength(sizeof(uint8_t));
|
||||
memcpy(buf + length, &subTlv, sizeof(subTlv));
|
||||
length += sizeof(subTlv);
|
||||
@@ -661,13 +648,13 @@ Error LinkMetrics::SendLinkMetricsQuery(const Ip6::Address & aDestinati
|
||||
// Link Metrics Query Options sub-TLV
|
||||
if (aTypeIdFlagsCount > 0)
|
||||
{
|
||||
linkMetricsQueryOptionsTlv.Init();
|
||||
linkMetricsQueryOptionsTlv.SetLength(aTypeIdFlagsCount * sizeof(LinkMetricsTypeIdFlags));
|
||||
queryOptionsTlv.Init();
|
||||
queryOptionsTlv.SetLength(aTypeIdFlagsCount * sizeof(TypeIdFlags));
|
||||
|
||||
memcpy(buf + length, &linkMetricsQueryOptionsTlv, sizeof(linkMetricsQueryOptionsTlv));
|
||||
length += sizeof(linkMetricsQueryOptionsTlv);
|
||||
memcpy(buf + length, aTypeIdFlags, linkMetricsQueryOptionsTlv.GetLength());
|
||||
length += linkMetricsQueryOptionsTlv.GetLength();
|
||||
memcpy(buf + length, &queryOptionsTlv, sizeof(queryOptionsTlv));
|
||||
length += sizeof(queryOptionsTlv);
|
||||
memcpy(buf + length, aTypeIdFlags, queryOptionsTlv.GetLength());
|
||||
length += queryOptionsTlv.GetLength();
|
||||
}
|
||||
|
||||
// Set Length for Link Metrics Report TLV
|
||||
@@ -679,14 +666,14 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
LinkMetrics::LinkMetricsStatus LinkMetrics::ConfigureForwardTrackingSeries(uint8_t aSeriesId,
|
||||
const SeriesFlags & aSeriesFlags,
|
||||
const otLinkMetrics &aLinkMetrics,
|
||||
Neighbor & aNeighbor)
|
||||
Status LinkMetrics::ConfigureForwardTrackingSeries(uint8_t aSeriesId,
|
||||
const SeriesFlags &aSeriesFlags,
|
||||
const Metrics & aMetrics,
|
||||
Neighbor & aNeighbor)
|
||||
{
|
||||
LinkMetricsStatus status = kLinkMetricsStatusSuccess;
|
||||
Status status = kStatusSuccess;
|
||||
|
||||
VerifyOrExit(0 < aSeriesId, status = kLinkMetricsStatusOtherError);
|
||||
VerifyOrExit(0 < aSeriesId, status = kStatusOtherError);
|
||||
if (aSeriesFlags.GetRawValue() == 0) // Remove the series
|
||||
{
|
||||
if (aSeriesId == kSeriesIdAllSeries) // Remove all
|
||||
@@ -695,19 +682,19 @@ LinkMetrics::LinkMetricsStatus LinkMetrics::ConfigureForwardTrackingSeries(uint8
|
||||
}
|
||||
else
|
||||
{
|
||||
LinkMetricsSeriesInfo *seriesInfo = aNeighbor.RemoveForwardTrackingSeriesInfo(aSeriesId);
|
||||
VerifyOrExit(seriesInfo != nullptr, status = kLinkMetricsStatusSeriesIdNotRecognized);
|
||||
mLinkMetricsSeriesInfoPool.Free(*seriesInfo);
|
||||
SeriesInfo *seriesInfo = aNeighbor.RemoveForwardTrackingSeriesInfo(aSeriesId);
|
||||
VerifyOrExit(seriesInfo != nullptr, status = kStatusSeriesIdNotRecognized);
|
||||
mSeriesInfoPool.Free(*seriesInfo);
|
||||
}
|
||||
}
|
||||
else // Add a new series
|
||||
{
|
||||
LinkMetricsSeriesInfo *seriesInfo = aNeighbor.GetForwardTrackingSeriesInfo(aSeriesId);
|
||||
VerifyOrExit(seriesInfo == nullptr, status = kLinkMetricsStatusSeriesIdAlreadyRegistered);
|
||||
seriesInfo = mLinkMetricsSeriesInfoPool.Allocate();
|
||||
VerifyOrExit(seriesInfo != nullptr, status = kLinkMetricsStatusCannotSupportNewSeries);
|
||||
SeriesInfo *seriesInfo = aNeighbor.GetForwardTrackingSeriesInfo(aSeriesId);
|
||||
VerifyOrExit(seriesInfo == nullptr, status = kStatusSeriesIdAlreadyRegistered);
|
||||
seriesInfo = mSeriesInfoPool.Allocate();
|
||||
VerifyOrExit(seriesInfo != nullptr, status = kStatusCannotSupportNewSeries);
|
||||
|
||||
seriesInfo->Init(aSeriesId, aSeriesFlags, aLinkMetrics);
|
||||
seriesInfo->Init(aSeriesId, aSeriesFlags, aMetrics);
|
||||
|
||||
aNeighbor.AddForwardTrackingSeriesInfo(*seriesInfo);
|
||||
}
|
||||
@@ -717,37 +704,32 @@ exit:
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
LinkMetrics::LinkMetricsStatus LinkMetrics::ConfigureEnhAckProbing(LinkMetricsEnhAckFlags aEnhAckFlags,
|
||||
const otLinkMetrics & aLinkMetrics,
|
||||
Neighbor & aNeighbor)
|
||||
Status LinkMetrics::ConfigureEnhAckProbing(EnhAckFlags aEnhAckFlags, const Metrics &aMetrics, Neighbor &aNeighbor)
|
||||
{
|
||||
LinkMetricsStatus status = kLinkMetricsStatusSuccess;
|
||||
Error error = kErrorNone;
|
||||
Status status = kStatusSuccess;
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(!aLinkMetrics.mReserved, status = kLinkMetricsStatusOtherError);
|
||||
VerifyOrExit(!aMetrics.mReserved, status = kStatusOtherError);
|
||||
|
||||
if (aEnhAckFlags == kEnhAckRegister)
|
||||
{
|
||||
VerifyOrExit(!aLinkMetrics.mPduCount, status = kLinkMetricsStatusOtherError);
|
||||
VerifyOrExit(aLinkMetrics.mLqi || aLinkMetrics.mLinkMargin || aLinkMetrics.mRssi,
|
||||
status = kLinkMetricsStatusOtherError);
|
||||
VerifyOrExit(!(aLinkMetrics.mLqi && aLinkMetrics.mLinkMargin && aLinkMetrics.mRssi),
|
||||
status = kLinkMetricsStatusOtherError);
|
||||
VerifyOrExit(!aMetrics.mPduCount, status = kStatusOtherError);
|
||||
VerifyOrExit(aMetrics.mLqi || aMetrics.mLinkMargin || aMetrics.mRssi, status = kStatusOtherError);
|
||||
VerifyOrExit(!(aMetrics.mLqi && aMetrics.mLinkMargin && aMetrics.mRssi), status = kStatusOtherError);
|
||||
|
||||
error = Get<Radio>().ConfigureEnhAckProbing(aLinkMetrics, aNeighbor.GetRloc16(), aNeighbor.GetExtAddress());
|
||||
error = Get<Radio>().ConfigureEnhAckProbing(aMetrics, aNeighbor.GetRloc16(), aNeighbor.GetExtAddress());
|
||||
}
|
||||
else if (aEnhAckFlags == kEnhAckClear)
|
||||
{
|
||||
VerifyOrExit(!aLinkMetrics.mLqi && !aLinkMetrics.mLinkMargin && !aLinkMetrics.mRssi,
|
||||
status = kLinkMetricsStatusOtherError);
|
||||
error = Get<Radio>().ConfigureEnhAckProbing(aLinkMetrics, aNeighbor.GetRloc16(), aNeighbor.GetExtAddress());
|
||||
VerifyOrExit(!aMetrics.mLqi && !aMetrics.mLinkMargin && !aMetrics.mRssi, status = kStatusOtherError);
|
||||
error = Get<Radio>().ConfigureEnhAckProbing(aMetrics, aNeighbor.GetRloc16(), aNeighbor.GetExtAddress());
|
||||
}
|
||||
else
|
||||
{
|
||||
status = kLinkMetricsStatusOtherError;
|
||||
status = kStatusOtherError;
|
||||
}
|
||||
|
||||
VerifyOrExit(error == kErrorNone, status = kLinkMetricsStatusOtherError);
|
||||
VerifyOrExit(error == kErrorNone, status = kStatusOtherError);
|
||||
|
||||
exit:
|
||||
return status;
|
||||
@@ -770,38 +752,38 @@ exit:
|
||||
Error LinkMetrics::ReadTypeIdFlagsFromMessage(const Message &aMessage,
|
||||
uint8_t aStartPos,
|
||||
uint8_t aEndPos,
|
||||
otLinkMetrics &aLinkMetrics)
|
||||
Metrics & aMetrics)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
memset(&aLinkMetrics, 0, sizeof(aLinkMetrics));
|
||||
memset(&aMetrics, 0, sizeof(aMetrics));
|
||||
|
||||
for (uint16_t pos = aStartPos; pos < aEndPos; pos += sizeof(LinkMetricsTypeIdFlags))
|
||||
for (uint16_t pos = aStartPos; pos < aEndPos; pos += sizeof(TypeIdFlags))
|
||||
{
|
||||
LinkMetricsTypeIdFlags typeIdFlags;
|
||||
TypeIdFlags typeIdFlags;
|
||||
|
||||
SuccessOrExit(aMessage.Read(pos, typeIdFlags));
|
||||
|
||||
switch (typeIdFlags.GetRawValue())
|
||||
{
|
||||
case kTypeIdFlagPdu:
|
||||
VerifyOrExit(!aLinkMetrics.mPduCount, error = kErrorParse);
|
||||
aLinkMetrics.mPduCount = true;
|
||||
case TypeIdFlags::kPdu:
|
||||
VerifyOrExit(!aMetrics.mPduCount, error = kErrorParse);
|
||||
aMetrics.mPduCount = true;
|
||||
break;
|
||||
|
||||
case kTypeIdFlagLqi:
|
||||
VerifyOrExit(!aLinkMetrics.mLqi, error = kErrorParse);
|
||||
aLinkMetrics.mLqi = true;
|
||||
case TypeIdFlags::kLqi:
|
||||
VerifyOrExit(!aMetrics.mLqi, error = kErrorParse);
|
||||
aMetrics.mLqi = true;
|
||||
break;
|
||||
|
||||
case kTypeIdFlagLinkMargin:
|
||||
VerifyOrExit(!aLinkMetrics.mLinkMargin, error = kErrorParse);
|
||||
aLinkMetrics.mLinkMargin = true;
|
||||
case TypeIdFlags::kLinkMargin:
|
||||
VerifyOrExit(!aMetrics.mLinkMargin, error = kErrorParse);
|
||||
aMetrics.mLinkMargin = true;
|
||||
break;
|
||||
|
||||
case kTypeIdFlagRssi:
|
||||
VerifyOrExit(!aLinkMetrics.mRssi, error = kErrorParse);
|
||||
aLinkMetrics.mRssi = true;
|
||||
case TypeIdFlags::kRssi:
|
||||
VerifyOrExit(!aMetrics.mRssi, error = kErrorParse);
|
||||
aMetrics.mRssi = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -811,7 +793,7 @@ Error LinkMetrics::ReadTypeIdFlagsFromMessage(const Message &aMessage,
|
||||
}
|
||||
else
|
||||
{
|
||||
aLinkMetrics.mReserved = true;
|
||||
aMetrics.mReserved = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -821,10 +803,10 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error LinkMetrics::AppendReportSubTlvToMessage(Message &aMessage, uint8_t &aLength, const otLinkMetricsValues &aValues)
|
||||
Error LinkMetrics::AppendReportSubTlvToMessage(Message &aMessage, uint8_t &aLength, const MetricsValues &aValues)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
LinkMetricsReportSubTlv metric;
|
||||
Error error = kErrorNone;
|
||||
ReportSubTlv metric;
|
||||
|
||||
aLength = 0;
|
||||
|
||||
@@ -832,7 +814,7 @@ Error LinkMetrics::AppendReportSubTlvToMessage(Message &aMessage, uint8_t &aLeng
|
||||
if (aValues.mMetrics.mPduCount)
|
||||
{
|
||||
metric.Init();
|
||||
metric.SetMetricsTypeId(LinkMetricsTypeIdFlags(kTypeIdFlagPdu));
|
||||
metric.SetMetricsTypeId(TypeIdFlags(TypeIdFlags::kPdu));
|
||||
metric.SetMetricsValue32(aValues.mPduCountValue);
|
||||
SuccessOrExit(error = aMessage.AppendBytes(&metric, metric.GetSize()));
|
||||
aLength += metric.GetSize();
|
||||
@@ -841,7 +823,7 @@ Error LinkMetrics::AppendReportSubTlvToMessage(Message &aMessage, uint8_t &aLeng
|
||||
if (aValues.mMetrics.mLqi)
|
||||
{
|
||||
metric.Init();
|
||||
metric.SetMetricsTypeId(LinkMetricsTypeIdFlags(kTypeIdFlagLqi));
|
||||
metric.SetMetricsTypeId(TypeIdFlags(TypeIdFlags::kLqi));
|
||||
metric.SetMetricsValue8(aValues.mLqiValue);
|
||||
SuccessOrExit(error = aMessage.AppendBytes(&metric, metric.GetSize()));
|
||||
aLength += metric.GetSize();
|
||||
@@ -850,7 +832,7 @@ Error LinkMetrics::AppendReportSubTlvToMessage(Message &aMessage, uint8_t &aLeng
|
||||
if (aValues.mMetrics.mLinkMargin)
|
||||
{
|
||||
metric.Init();
|
||||
metric.SetMetricsTypeId(LinkMetricsTypeIdFlags(kTypeIdFlagLinkMargin));
|
||||
metric.SetMetricsTypeId(TypeIdFlags(TypeIdFlags::kLinkMargin));
|
||||
metric.SetMetricsValue8(aValues.mLinkMarginValue);
|
||||
SuccessOrExit(error = aMessage.AppendBytes(&metric, metric.GetSize()));
|
||||
aLength += metric.GetSize();
|
||||
@@ -859,7 +841,7 @@ Error LinkMetrics::AppendReportSubTlvToMessage(Message &aMessage, uint8_t &aLeng
|
||||
if (aValues.mMetrics.mRssi)
|
||||
{
|
||||
metric.Init();
|
||||
metric.SetMetricsTypeId(LinkMetricsTypeIdFlags(kTypeIdFlagRssi));
|
||||
metric.SetMetricsTypeId(TypeIdFlags(TypeIdFlags::kRssi));
|
||||
metric.SetMetricsValue8(aValues.mRssiValue);
|
||||
SuccessOrExit(error = aMessage.AppendBytes(&metric, metric.GetSize()));
|
||||
aLength += metric.GetSize();
|
||||
@@ -869,12 +851,12 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error LinkMetrics::AppendStatusSubTlvToMessage(Message &aMessage, uint8_t &aLength, LinkMetricsStatus aStatus)
|
||||
Error LinkMetrics::AppendStatusSubTlvToMessage(Message &aMessage, uint8_t &aLength, Status aStatus)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Tlv statusTlv;
|
||||
|
||||
statusTlv.SetType(kLinkMetricsStatus);
|
||||
statusTlv.SetType(SubTlv::kStatus);
|
||||
statusTlv.SetLength(sizeof(uint8_t));
|
||||
SuccessOrExit(error = aMessage.AppendBytes(&statusTlv, sizeof(statusTlv)));
|
||||
SuccessOrExit(error = aMessage.AppendBytes(&aStatus, sizeof(aStatus)));
|
||||
@@ -884,6 +866,7 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace LinkMetrics
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
|
||||
+160
-121
@@ -39,12 +39,13 @@
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
|
||||
#if (OPENTHREAD_CONFIG_THREAD_VERSION < OT_THREAD_VERSION_1_2)
|
||||
#error \
|
||||
"Thread 1.2 or higher version is required for OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE and OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE."
|
||||
#error "Thread 1.2 or higher version is required for OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE" \
|
||||
"and OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE."
|
||||
#endif
|
||||
|
||||
#include <openthread/link.h>
|
||||
|
||||
#include "common/clearable.hpp"
|
||||
#include "common/locator.hpp"
|
||||
#include "common/message.hpp"
|
||||
#include "common/non_copyable.hpp"
|
||||
@@ -54,9 +55,10 @@
|
||||
#include "thread/link_quality.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
class Neighbor;
|
||||
|
||||
namespace LinkMetrics {
|
||||
|
||||
/**
|
||||
* @addtogroup core-link-metrics
|
||||
*
|
||||
@@ -66,41 +68,74 @@ class Neighbor;
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* This type represents the results (values) for a set of metrics.
|
||||
*
|
||||
* @sa otLinkMetricsValues.
|
||||
*
|
||||
*/
|
||||
class MetricsValues : public otLinkMetricsValues, public Clearable<MetricsValues>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method gets the metrics flags.
|
||||
*
|
||||
* @returns The metrics flags.
|
||||
*
|
||||
*/
|
||||
Metrics &GetMetrics(void) { return static_cast<Metrics &>(mMetrics); }
|
||||
|
||||
/**
|
||||
* This method gets the metrics flags.
|
||||
*
|
||||
* @returns The metrics flags.
|
||||
*
|
||||
*/
|
||||
const Metrics &GetMetrics(void) const { return static_cast<const Metrics &>(mMetrics); }
|
||||
|
||||
/**
|
||||
* This method set the metrics flags.
|
||||
*
|
||||
* @param[in] aMetrics The metrics flags to set from.
|
||||
*
|
||||
*/
|
||||
void SetMetrics(const Metrics &aMetrics) { mMetrics = aMetrics; }
|
||||
};
|
||||
|
||||
/**
|
||||
* This class represents one Series that is being tracked by the Subject.
|
||||
*
|
||||
* When an Initiator successfully configured a Forward Tracking Series, the Subject would use an instance of this class
|
||||
* to track the information of the Series. The Subject has a `Pool` of `LinkMetricsSeriesInfo`. It would allocate one
|
||||
* when a new Series comes, and free it when a Series finishes.
|
||||
* to track the information of the Series. The Subject has a `Pool` of `SeriesInfo`. It would allocate one when a new
|
||||
* Series comes, and free it when a Series finishes.
|
||||
*
|
||||
* This class inherits `LinkedListEntry` and each `Neighbor` has a list of `LinkMetricsSeriesInfo` so that the Subject
|
||||
* could track per Series initiated by neighbors as long as it has available resources.
|
||||
* This class inherits `LinkedListEntry` and each `Neighbor` has a list of `SeriesInfo` so that the Subject could track
|
||||
* per Series initiated by neighbors as long as it has available resources.
|
||||
*
|
||||
*/
|
||||
class LinkMetricsSeriesInfo : public LinkedListEntry<LinkMetricsSeriesInfo>
|
||||
class SeriesInfo : public LinkedListEntry<SeriesInfo>
|
||||
{
|
||||
friend class LinkedList<LinkMetricsSeriesInfo>;
|
||||
friend class LinkedListEntry<LinkMetricsSeriesInfo>;
|
||||
friend class LinkedList<SeriesInfo>;
|
||||
friend class LinkedListEntry<SeriesInfo>;
|
||||
|
||||
public:
|
||||
///< This represents Link Probe when filtering frames to be accounted using Series Flag. There's
|
||||
///< already `kFcfFrameData`, `kFcfFrameAck` and `kFcfFrameMacCmd`. This item is added so that we can
|
||||
///< filter a Link Probe for series in the same way as other frames.
|
||||
enum
|
||||
{
|
||||
kSeriesTypeLinkProbe = 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* This method initializes the object.
|
||||
*
|
||||
* @param[in] aSeriesId The Series ID.
|
||||
* @param[in] aSeriesFlags A reference to the Series Flags which specify what types of frames are to be
|
||||
* accounted.
|
||||
* @param[in] aLinkMetricsFlags A reference to flags specifying what metrics to query.
|
||||
* This constant represents Link Probe when filtering frames to be accounted using Series Flag. There's
|
||||
* already `kFcfFrameData`, `kFcfFrameAck` and `kFcfFrameMacCmd`. This item is added so that we can
|
||||
* filter a Link Probe for series in the same way as other frames.
|
||||
*
|
||||
*/
|
||||
void Init(uint8_t aSeriesId, const SeriesFlags &aSeriesFlags, const otLinkMetrics &aLinkMetrics);
|
||||
static constexpr uint8_t kSeriesTypeLinkProbe = 0;
|
||||
|
||||
/**
|
||||
* This method initializes the SeriesInfo object.
|
||||
*
|
||||
* @param[in] aSeriesId The Series ID.
|
||||
* @param[in] aSeriesFlags The Series Flags which specify what types of frames are to be accounted.
|
||||
* @param[in] aMetrics Metrics to query.
|
||||
*
|
||||
*/
|
||||
void Init(uint8_t aSeriesId, const SeriesFlags &aSeriesFlags, const Metrics &aMetrics);
|
||||
|
||||
/**
|
||||
* This method gets the Series ID.
|
||||
@@ -145,42 +180,52 @@ public:
|
||||
void AggregateLinkMetrics(uint8_t aFrameType, uint8_t aLqi, int8_t aRss);
|
||||
|
||||
/**
|
||||
* This methods gets the Link Metrics Flags.
|
||||
* This methods gets the metrics.
|
||||
*
|
||||
* @param[out] aLinkMetrics A reference to a `LinkMetrics` object to get the values.
|
||||
* @returns The metrics associated with `SeriesInfo`.
|
||||
*
|
||||
*/
|
||||
void GetLinkMetrics(otLinkMetrics &aLinkMetrics) const;
|
||||
const Metrics &GetLinkMetrics(void) const { return mMetrics; }
|
||||
|
||||
private:
|
||||
LinkMetricsSeriesInfo *mNext;
|
||||
|
||||
uint8_t mSeriesId;
|
||||
SeriesFlags mSeriesFlags;
|
||||
otLinkMetrics mLinkMetrics;
|
||||
RssAverager mRssAverager;
|
||||
LqiAverager mLqiAverager;
|
||||
uint32_t mPduCount;
|
||||
|
||||
bool Matches(const uint8_t &aSeriesId) const { return mSeriesId == aSeriesId; }
|
||||
|
||||
bool IsFrameTypeMatch(uint8_t aFrameType) const;
|
||||
|
||||
SeriesInfo *mNext;
|
||||
uint8_t mSeriesId;
|
||||
SeriesFlags mSeriesFlags;
|
||||
Metrics mMetrics;
|
||||
RssAverager mRssAverager;
|
||||
LqiAverager mLqiAverager;
|
||||
uint32_t mPduCount;
|
||||
};
|
||||
|
||||
/**
|
||||
* This enumeration type represent Link Metrics Status.
|
||||
*
|
||||
*/
|
||||
enum Status : uint8_t
|
||||
{
|
||||
kStatusSuccess = OT_LINK_METRICS_STATUS_SUCCESS,
|
||||
kStatusCannotSupportNewSeries = OT_LINK_METRICS_STATUS_CANNOT_SUPPORT_NEW_SERIES,
|
||||
kStatusSeriesIdAlreadyRegistered = OT_LINK_METRICS_STATUS_SERIESID_ALREADY_REGISTERED,
|
||||
kStatusSeriesIdNotRecognized = OT_LINK_METRICS_STATUS_SERIESID_NOT_RECOGNIZED,
|
||||
kStatusNoMatchingFramesReceived = OT_LINK_METRICS_STATUS_NO_MATCHING_FRAMES_RECEIVED,
|
||||
kStatusOtherError = OT_LINK_METRICS_STATUS_OTHER_ERROR,
|
||||
};
|
||||
|
||||
/**
|
||||
* This class implements Thread Link Metrics query and management.
|
||||
*
|
||||
*/
|
||||
class LinkMetrics : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
friend class Neighbor;
|
||||
friend class ot::Neighbor;
|
||||
|
||||
public:
|
||||
enum LinkMetricsStatus : uint8_t
|
||||
{
|
||||
kLinkMetricsStatusSuccess = OT_LINK_METRICS_STATUS_SUCCESS,
|
||||
kLinkMetricsStatusCannotSupportNewSeries = OT_LINK_METRICS_STATUS_CANNOT_SUPPORT_NEW_SERIES,
|
||||
kLinkMetricsStatusSeriesIdAlreadyRegistered = OT_LINK_METRICS_STATUS_SERIESID_ALREADY_REGISTERED,
|
||||
kLinkMetricsStatusSeriesIdNotRecognized = OT_LINK_METRICS_STATUS_SERIESID_NOT_RECOGNIZED,
|
||||
kLinkMetricsStatusNoMatchingFramesReceived = OT_LINK_METRICS_STATUS_NO_MATCHING_FRAMES_RECEIVED,
|
||||
kLinkMetricsStatusOtherError = OT_LINK_METRICS_STATUS_OTHER_ERROR,
|
||||
};
|
||||
typedef otLinkMetricsReportCallback ReportCallback;
|
||||
typedef otLinkMetricsMgmtResponseCallback MgmtResponseCallback;
|
||||
typedef otLinkMetricsEnhAckProbingIeReportCallback EnhAckProbingIeReportCallback;
|
||||
|
||||
/**
|
||||
* This constructor initializes an instance of the LinkMetrics class.
|
||||
@@ -197,7 +242,7 @@ public:
|
||||
*
|
||||
* @param[in] aDestination A reference to the IPv6 address of the destination.
|
||||
* @param[in] aSeriesId The Series ID to query, 0 for single probe.
|
||||
* @param[in] aLinkMetricsFlags A pointer to flags specifying what metrics to query.
|
||||
* @param[in] aMetrics A pointer to metrics to query.
|
||||
*
|
||||
* @retval kErrorNone Successfully sent a Link Metrics query message.
|
||||
* @retval kErrorNoBufs Insufficient buffers to generate the MLE Data Request message.
|
||||
@@ -205,16 +250,15 @@ public:
|
||||
* @retval kErrorUnknownNeighbor @p aDestination is not link-local or the neighbor is not found.
|
||||
*
|
||||
*/
|
||||
Error LinkMetricsQuery(const Ip6::Address &aDestination, uint8_t aSeriesId, const otLinkMetrics *aLinkMetricsFlags);
|
||||
Error Query(const Ip6::Address &aDestination, uint8_t aSeriesId, const Metrics *aMetrics);
|
||||
|
||||
/**
|
||||
* This method sends an MLE Link Metrics Management Request to configure/clear a Forward Tracking Series.
|
||||
*
|
||||
* @param[in] aDestination A reference to the IPv6 address of the destination.
|
||||
* @param[in] aSeriesId The Series ID.
|
||||
* @param[in] aSeriesFlags A reference to the Series Flags which specify what types of frames are to be
|
||||
* accounted.
|
||||
* @param[in] aLinkMetricsFlags A pointer to flags specifying what metrics to query.
|
||||
* @param[in] aSeriesFlags The Series Flags info which specify what types of frames are to be accounted.
|
||||
* @param[in] aMetrics A pointer to flags specifying what metrics to query.
|
||||
*
|
||||
* @retval kErrorNone Successfully sent a Link Metrics Management Request message.
|
||||
* @retval kErrorNoBufs Insufficient buffers to generate the MLE Link Metrics Management Request message.
|
||||
@@ -222,10 +266,10 @@ public:
|
||||
* @retval kErrorUnknownNeighbor @p aDestination is not link-local or the neighbor is not found.
|
||||
*
|
||||
*/
|
||||
Error SendMgmtRequestForwardTrackingSeries(const Ip6::Address & aDestination,
|
||||
uint8_t aSeriesId,
|
||||
const otLinkMetricsSeriesFlags &aSeriesFlags,
|
||||
const otLinkMetrics * aLinkMetricsFlags);
|
||||
Error SendMgmtRequestForwardTrackingSeries(const Ip6::Address & aDestination,
|
||||
uint8_t aSeriesId,
|
||||
const SeriesFlags::Info &aSeriesFlags,
|
||||
const Metrics * aMetrics);
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
|
||||
/**
|
||||
@@ -234,18 +278,18 @@ public:
|
||||
* @param[in] aDestination A reference to the IPv6 address of the destination.
|
||||
* @param[in] aEnhAckFlags Enh-ACK Flags to indicate whether to register or clear the probing. `0` to clear
|
||||
* and `1` to register. Other values are reserved.
|
||||
* @param[in] aLinkMetricsFlags A pointer to flags specifying what metrics to query. Should be `NULL` when
|
||||
* @param[in] aMetrics A pointer to flags specifying what metrics to query. Should be `nullptr` when
|
||||
* `aEnhAckFlags` is `0`.
|
||||
*
|
||||
* @retval kErrorNone Successfully sent a Link Metrics Management Request message.
|
||||
* @retval kErrorNoBufs Insufficient buffers to generate the MLE Link Metrics Management Request message.
|
||||
* @retval kErrorInvalidArgs @p aEnhAckFlags is not a valid value or @p aLinkMetricsFlags isn't correct.
|
||||
* @retval kErrorInvalidArgs @p aEnhAckFlags is not a valid value or @p aMetrics isn't correct.
|
||||
* @retval kErrorUnknownNeighbor @p aDestination is not link-local or the neighbor is not found.
|
||||
*
|
||||
*/
|
||||
Error SendMgmtRequestEnhAckProbing(const Ip6::Address & aDestination,
|
||||
otLinkMetricsEnhAckFlags aEnhAckFlags,
|
||||
const otLinkMetrics * aLinkMetricsFlags);
|
||||
Error SendMgmtRequestEnhAckProbing(const Ip6::Address &aDestination,
|
||||
EnhAckFlags aEnhAckFlags,
|
||||
const Metrics * aMetrics);
|
||||
|
||||
/**
|
||||
* This method sends an MLE Link Probe message.
|
||||
@@ -276,7 +320,7 @@ public:
|
||||
* @retval kErrorInvalidArgs QueryId is invalid or any Type ID is invalid.
|
||||
*
|
||||
*/
|
||||
Error AppendLinkMetricsReport(Message &aMessage, const Message &aRequestMessage, Neighbor &aNeighbor);
|
||||
Error AppendReport(Message &aMessage, const Message &aRequestMessage, Neighbor &aNeighbor);
|
||||
#endif
|
||||
/**
|
||||
* This method handles the received Link Metrics Management Request contained in @p aMessage and return a status.
|
||||
@@ -289,7 +333,7 @@ public:
|
||||
* @retval kErrorParse Cannot parse sub-TLVs from @p aMessage successfully.
|
||||
*
|
||||
*/
|
||||
Error HandleLinkMetricsManagementRequest(const Message &aMessage, Neighbor &aNeighbor, LinkMetricsStatus &aStatus);
|
||||
Error HandleManagementRequest(const Message &aMessage, Neighbor &aNeighbor, Status &aStatus);
|
||||
|
||||
/**
|
||||
* This method handles the received Link Metrics Management Response contained in @p aMessage.
|
||||
@@ -301,7 +345,7 @@ public:
|
||||
* @retval kErrorParse Cannot parse sub-TLVs from @p aMessage successfully.
|
||||
*
|
||||
*/
|
||||
Error HandleLinkMetricsManagementResponse(const Message &aMessage, const Ip6::Address &aAddress);
|
||||
Error HandleManagementResponse(const Message &aMessage, const Ip6::Address &aAddress);
|
||||
|
||||
/**
|
||||
* This method handles the received Link Metrics report contained in @p aMessage.
|
||||
@@ -312,10 +356,7 @@ public:
|
||||
* @param[in] aAddress A reference to the source address of the message.
|
||||
*
|
||||
*/
|
||||
void HandleLinkMetricsReport(const Message & aMessage,
|
||||
uint16_t aOffset,
|
||||
uint16_t aLength,
|
||||
const Ip6::Address &aAddress);
|
||||
void HandleReport(const Message &aMessage, uint16_t aOffset, uint16_t aLength, const Ip6::Address &aAddress);
|
||||
|
||||
/**
|
||||
* This method handles the Link Probe contained in @p aMessage.
|
||||
@@ -332,88 +373,86 @@ public:
|
||||
/**
|
||||
* This method registers a callback to handle Link Metrics report received.
|
||||
*
|
||||
* @param[in] aCallback A pointer to a function that is called when a Link Metrics report is received.
|
||||
* @param[in] aCallbackContext A pointer to application-specific context.
|
||||
* @param[in] aCallback A pointer to a function that is called when a Link Metrics report is received.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
*/
|
||||
void SetLinkMetricsReportCallback(otLinkMetricsReportCallback aCallback, void *aCallbackContext);
|
||||
void SetReportCallback(ReportCallback aCallback, void *aContext);
|
||||
|
||||
/**
|
||||
* This method registers a callback to handle Link Metrics Management Response received.
|
||||
*
|
||||
* @param[in] aCallback A pointer to a function that is called when a Link Metrics Management Response is
|
||||
* received.
|
||||
* @param[in] aCallbackContext A pointer to application-specific context.
|
||||
* @param[in] aCallback A pointer to a function that is called when a Link Metrics Management Response is received.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
*/
|
||||
void SetLinkMetricsMgmtResponseCallback(otLinkMetricsMgmtResponseCallback aCallback, void *aCallbackContext);
|
||||
void SetMgmtResponseCallback(MgmtResponseCallback aCallback, void *aContext);
|
||||
|
||||
void SetLinkMetricsEnhAckProbingCallback(otLinkMetricsEnhAckProbingIeReportCallback aCallback,
|
||||
void * aCallbackContext);
|
||||
void ProcessEnhAckIeData(const uint8_t *aData, uint8_t aLen, const Neighbor &aNeighbor);
|
||||
/**
|
||||
* This method registers a callback to handle Link Metrics when Enh-ACK Probing IE is received.
|
||||
*
|
||||
* @param[in] aCallback A pointer to a function that is called when Enh-ACK Probing IE is received is received.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
*/
|
||||
void SetEnhAckProbingCallback(EnhAckProbingIeReportCallback aCallback, void *aContext);
|
||||
|
||||
/**
|
||||
* This method processes received Enh-ACK Probing IE data.
|
||||
*
|
||||
* @param[in] aData A pointer to buffer containing the Enh-ACK Probing IE data.
|
||||
* @param[in] aLen The length of @p aData.
|
||||
* @param[in] aNeighbor The neighbor from which the Enh-ACK Probing IE was received.
|
||||
*
|
||||
*/
|
||||
void ProcessEnhAckIeData(const uint8_t *aData, uint8_t aLength, const Neighbor &aNeighbor);
|
||||
|
||||
private:
|
||||
/*
|
||||
* TypeIdFlagPdu: 0x0_1_000_000 -> 0x40 ==> L bit set, type = 0 (count/summation), metric-enum = 0 (PDU rxed).
|
||||
* TypeIdFlagLqi: 0x0_0_001_001 -> 0x00 ==> L bit not set, type = 1 (exp ave), metric-enum = 1 (LQI).
|
||||
* TypeIdFlagLinkMargin: 0x0_0_001_010 -> 0x00 ==> L bit not set, type = 1 (exp ave), metric-enum = 2 (Link Margin).
|
||||
* TypeIdFlagRssi: 0x0_0_001_011 -> 0x00 ==> L bit not set, type = 1 (exp ave), metric-enum = 3 (RSSI).
|
||||
*
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kMaxTypeIdFlags = 4,
|
||||
static constexpr uint8_t kMaxTypeIdFlags = 4;
|
||||
|
||||
kMaxSeriesSupported =
|
||||
OPENTHREAD_CONFIG_MLE_LINK_METRICS_MAX_SERIES_SUPPORTED, ///< Max number of LinkMetricsSeriesInfo that could
|
||||
///< be allocated by the pool.
|
||||
// Max number of SeriesInfo that could be allocated by the pool.
|
||||
static constexpr uint16_t kMaxSeriesSupported = OPENTHREAD_CONFIG_MLE_LINK_METRICS_MAX_SERIES_SUPPORTED;
|
||||
|
||||
kQueryIdSingleProbe = 0, ///< This query ID represents Single Probe.
|
||||
static constexpr uint8_t kQueryIdSingleProbe = 0; // This query ID represents Single Probe.
|
||||
static constexpr uint8_t kSeriesIdAllSeries = 255; // This series ID represents all series.
|
||||
static constexpr uint8_t kLinkProbeMaxLen = 64; // Max length of data payload in Link Probe TLV.
|
||||
|
||||
kSeriesIdAllSeries = 255, ///< This series ID represents all series.
|
||||
Error SendLinkMetricsQuery(const Ip6::Address &aDestination,
|
||||
uint8_t aSeriesId,
|
||||
const TypeIdFlags * aTypeIdFlags,
|
||||
uint8_t aTypeIdFlagsCount);
|
||||
|
||||
kLinkProbeMaxLen = 64, ///< Max length of data payload in Link Probe TLV.
|
||||
};
|
||||
Status ConfigureForwardTrackingSeries(uint8_t aSeriesId,
|
||||
const SeriesFlags &aSeriesFlags,
|
||||
const Metrics & aMetrics,
|
||||
Neighbor & aNeighbor);
|
||||
|
||||
otLinkMetricsReportCallback mLinkMetricsReportCallback;
|
||||
void * mLinkMetricsReportCallbackContext;
|
||||
otLinkMetricsMgmtResponseCallback mLinkMetricsMgmtResponseCallback;
|
||||
void * mLinkMetricsMgmtResponseCallbackContext;
|
||||
otLinkMetricsEnhAckProbingIeReportCallback mLinkMetricsEnhAckProbingIeReportCallback;
|
||||
void * mLinkMetricsEnhAckProbingIeReportCallbackContext;
|
||||
|
||||
Pool<LinkMetricsSeriesInfo, kMaxSeriesSupported> mLinkMetricsSeriesInfoPool;
|
||||
|
||||
Error SendLinkMetricsQuery(const Ip6::Address & aDestination,
|
||||
uint8_t aSeriesId,
|
||||
const LinkMetricsTypeIdFlags *aTypeIdFlags,
|
||||
uint8_t aTypeIdFlagsCount);
|
||||
|
||||
LinkMetricsStatus ConfigureForwardTrackingSeries(uint8_t aSeriesId,
|
||||
const SeriesFlags & aSeriesFlags,
|
||||
const otLinkMetrics &aLinkMetrics,
|
||||
Neighbor & aNeighbor);
|
||||
|
||||
LinkMetricsStatus ConfigureEnhAckProbing(LinkMetricsEnhAckFlags aEnhAckFlags,
|
||||
const otLinkMetrics & aLinkMetrics,
|
||||
Neighbor & aNeighbor);
|
||||
Status ConfigureEnhAckProbing(EnhAckFlags aEnhAckFlags, const Metrics &aMetrics, Neighbor &aNeighbor);
|
||||
|
||||
Neighbor *GetNeighborFromLinkLocalAddr(const Ip6::Address &aDestination);
|
||||
|
||||
static Error ReadTypeIdFlagsFromMessage(const Message &aMessage,
|
||||
uint8_t aStartPos,
|
||||
uint8_t aEndPos,
|
||||
otLinkMetrics &aLinkMetrics);
|
||||
Metrics & aMetrics);
|
||||
static Error AppendReportSubTlvToMessage(Message &aMessage, uint8_t &aLength, const MetricsValues &aValues);
|
||||
static Error AppendStatusSubTlvToMessage(Message &aMessage, uint8_t &aLength, Status aStatus);
|
||||
|
||||
static Error AppendReportSubTlvToMessage(Message &aMessage, uint8_t &aLength, const otLinkMetricsValues &aValues);
|
||||
ReportCallback mReportCallback;
|
||||
void * mReportCallbackContext;
|
||||
MgmtResponseCallback mMgmtResponseCallback;
|
||||
void * mMgmtResponseCallbackContext;
|
||||
EnhAckProbingIeReportCallback mEnhAckProbingIeReportCallback;
|
||||
void * mEnhAckProbingIeReportCallbackContext;
|
||||
|
||||
static Error AppendStatusSubTlvToMessage(Message &aMessage, uint8_t &aLength, LinkMetricsStatus aStatus);
|
||||
Pool<SeriesInfo, kMaxSeriesSupported> mSeriesInfoPool;
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
} // namespace LinkMetrics
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
|
||||
@@ -41,77 +41,143 @@
|
||||
|
||||
#include <openthread/link_metrics.h>
|
||||
|
||||
#include "common/clearable.hpp"
|
||||
#include "common/encoding.hpp"
|
||||
#include "common/message.hpp"
|
||||
#include "common/tlvs.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace LinkMetrics {
|
||||
|
||||
/**
|
||||
* Link Metrics parameters.
|
||||
* This type represents Link Metric Flags indicating a set of metrics.
|
||||
*
|
||||
* @sa otLinkMetrics
|
||||
*
|
||||
*/
|
||||
enum
|
||||
class Metrics : public otLinkMetrics, public Clearable<Metrics>
|
||||
{
|
||||
kLinkMetricsMaxTypeIdFlags = 4, ///< Max count of Link Metrics Type ID Flags.
|
||||
};
|
||||
|
||||
/**
|
||||
* Link Metrics Sub-TLV types.
|
||||
* This class defines constants related to Link Metrics Sub-TLVs.
|
||||
*
|
||||
*/
|
||||
enum Type : uint8_t
|
||||
{
|
||||
kLinkMetricsReportSub = 0, ///< Link Metrics Report Sub-TLV
|
||||
kLinkMetricsQueryId = 1, ///< Link Metrics Query ID Sub-TLV
|
||||
kLinkMetricsQueryOptions = 2, ///< Link Metrics Query Options Sub-TLV
|
||||
kForwardProbingRegistration = 3, ///< Forward Probing Registration Sub-TLV
|
||||
kLinkMetricsStatus = 5, ///< Link Metrics Status Sub-TLV
|
||||
kEnhancedACKConfiguration = 7, ///< Enhanced ACK Configuration Sub-TLV
|
||||
};
|
||||
|
||||
/**
|
||||
* Valid values for Link Metrics Type Id Flags.
|
||||
*
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kTypeIdFlagPdu = 0x40,
|
||||
kTypeIdFlagLqi = 0x09,
|
||||
kTypeIdFlagLinkMargin = 0x0a,
|
||||
kTypeIdFlagRssi = 0x0b,
|
||||
};
|
||||
|
||||
/**
|
||||
* This class defines Link Metrics Query ID TLV constants and types.
|
||||
*
|
||||
*/
|
||||
typedef UintTlvInfo<kLinkMetricsQueryId, uint8_t> LinkMetricsQueryIdTlv;
|
||||
|
||||
/**
|
||||
* This class implements Link Metrics Type Id Flags generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN class LinkMetricsTypeIdFlags
|
||||
class SubTlv
|
||||
{
|
||||
public:
|
||||
enum : uint8_t
|
||||
/**
|
||||
* Link Metrics Sub-TLV types.
|
||||
*
|
||||
*/
|
||||
enum Type : uint8_t
|
||||
{
|
||||
kTypeEnumReserved = 2,
|
||||
kReport = 0, ///< Report Sub-TLV
|
||||
kQueryId = 1, ///< Query ID Sub-TLV
|
||||
kQueryOptions = 2, ///< Query Options Sub-TLV
|
||||
kFwdProbingReg = 3, ///< Forward Probing Registration Sub-TLV
|
||||
kStatus = 5, ///< Status Sub-TLV
|
||||
kEnhAckConfig = 7, ///< Enhanced ACK Configuration Sub-TLV
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* This class defines Link Metrics Query ID Sub-TLV constants and types.
|
||||
*
|
||||
*/
|
||||
typedef UintTlvInfo<SubTlv::kQueryId, uint8_t> QueryIdSubTlv;
|
||||
|
||||
/**
|
||||
* This class implements Link Metrics Type ID Flags generation and parsing.
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN class TypeIdFlags
|
||||
{
|
||||
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;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This enumeration specifies the Length field in Type ID Flags.
|
||||
*
|
||||
*/
|
||||
enum Length
|
||||
{
|
||||
kShortLength = 0, ///< Short value length (1 byte value)
|
||||
kExtendedLength = 1, ///< Extended value length (4 bytes value)
|
||||
};
|
||||
|
||||
/**
|
||||
* This enumeration specifies the Type values in Type ID Flags.
|
||||
*
|
||||
*/
|
||||
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.
|
||||
*
|
||||
*/
|
||||
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.
|
||||
*
|
||||
*/
|
||||
LinkMetricsTypeIdFlags(void) = default;
|
||||
TypeIdFlags(void) = default;
|
||||
|
||||
/**
|
||||
* Constructor for implicit cast from `uint8_t` to `LinkMetricsTypeIdFlags`.
|
||||
* Constructor to initialize from raw value.
|
||||
*
|
||||
* @param[in] aFlags The raw flags value.
|
||||
*
|
||||
*/
|
||||
explicit LinkMetricsTypeIdFlags(uint8_t aTypeIdFlags)
|
||||
: mTypeIdFlags(aTypeIdFlags)
|
||||
explicit TypeIdFlags(uint8_t aFlags)
|
||||
: mFlags(aFlags)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -119,20 +185,20 @@ public:
|
||||
* This method initializes the Type ID value
|
||||
*
|
||||
*/
|
||||
void Init(void) { mTypeIdFlags = 0; }
|
||||
void Init(void) { mFlags = 0; }
|
||||
|
||||
/**
|
||||
* This method clears the Extended flag.
|
||||
*
|
||||
*/
|
||||
void ClearExtendedFlag(void) { mTypeIdFlags &= ~kExtendedFlag; }
|
||||
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) { mTypeIdFlags |= kExtendedFlag; }
|
||||
void SetExtendedFlag(void) { mFlags |= kExtendedFlag; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the Extended flag is set.
|
||||
@@ -141,19 +207,19 @@ public:
|
||||
* @retval false The Extended flag is not set.
|
||||
*
|
||||
*/
|
||||
bool IsExtendedFlagSet(void) const { return (mTypeIdFlags & kExtendedFlag) != 0; }
|
||||
bool IsExtendedFlagSet(void) const { return (mFlags & kExtendedFlag) != 0; }
|
||||
|
||||
/**
|
||||
* This method clears value length flag.
|
||||
*
|
||||
*/
|
||||
void ClearLengthFlag(void) { mTypeIdFlags &= ~kLengthFlag; }
|
||||
void ClearLengthFlag(void) { mFlags &= ~kLengthFlag; }
|
||||
|
||||
/**
|
||||
* This method sets the value length flag.
|
||||
*
|
||||
*/
|
||||
void SetLengthFlag(void) { mTypeIdFlags |= kLengthFlag; }
|
||||
void SetLengthFlag(void) { mFlags |= kLengthFlag; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the value length flag is set.
|
||||
@@ -162,7 +228,7 @@ public:
|
||||
* @retval false The value length flag is not set, short value length (1 byte)
|
||||
*
|
||||
*/
|
||||
bool IsLengthFlagSet(void) const { return (mTypeIdFlags & kLengthFlag) != 0; }
|
||||
bool IsLengthFlagSet(void) const { return (mFlags & kLengthFlag) != 0; }
|
||||
|
||||
/**
|
||||
* This method sets the Type/Average Enum.
|
||||
@@ -170,9 +236,9 @@ public:
|
||||
* @param[in] aTypeEnum Type/Average Enum.
|
||||
*
|
||||
*/
|
||||
void SetTypeEnum(uint8_t aTypeEnum)
|
||||
void SetTypeEnum(TypeEnum aTypeEnum)
|
||||
{
|
||||
mTypeIdFlags = (mTypeIdFlags & ~kTypeEnumMask) | ((aTypeEnum << kTypeEnumOffset) & kTypeEnumMask);
|
||||
mFlags = (mFlags & ~kTypeEnumMask) | ((aTypeEnum << kTypeEnumOffset) & kTypeEnumMask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,7 +247,7 @@ public:
|
||||
* @returns The Type/Average Enum.
|
||||
*
|
||||
*/
|
||||
uint8_t GetTypeEnum(void) const { return (mTypeIdFlags & kTypeEnumMask) >> kTypeEnumOffset; }
|
||||
TypeEnum GetTypeEnum(void) const { return static_cast<TypeEnum>((mFlags & kTypeEnumMask) >> kTypeEnumOffset); }
|
||||
|
||||
/**
|
||||
* This method sets the Metric Enum.
|
||||
@@ -189,9 +255,9 @@ public:
|
||||
* @param[in] aMetricEnum Metric Enum.
|
||||
*
|
||||
*/
|
||||
void SetMetricEnum(uint8_t aMetricEnum)
|
||||
void SetMetricEnum(MetricEnum aMetricEnum)
|
||||
{
|
||||
mTypeIdFlags = (mTypeIdFlags & ~kMetricEnumMask) | ((aMetricEnum << kMetricEnumOffset) & kMetricEnumMask);
|
||||
mFlags = (mFlags & ~kMetricEnumMask) | ((aMetricEnum << kMetricEnumOffset) & kMetricEnumMask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,7 +266,10 @@ public:
|
||||
* @returns The Metric Enum.
|
||||
*
|
||||
*/
|
||||
uint8_t GetMetricEnum(void) const { return (mTypeIdFlags & kMetricEnumMask) >> kMetricEnumOffset; }
|
||||
MetricEnum GetMetricEnum(void) const
|
||||
{
|
||||
return static_cast<MetricEnum>((mFlags & kMetricEnumMask) >> kMetricEnumOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the raw value of the entire TypeIdFlags.
|
||||
@@ -208,28 +277,18 @@ public:
|
||||
* @returns The raw value of TypeIdFlags.
|
||||
*
|
||||
*/
|
||||
uint8_t GetRawValue(void) const { return mTypeIdFlags; }
|
||||
uint8_t GetRawValue(void) const { return mFlags; }
|
||||
|
||||
/**
|
||||
* This method sets the raw value of the entire TypeIdFlags.
|
||||
*
|
||||
* @param[in] aTypeIdFlags The value of entire TypeIdFlags.
|
||||
* @param[in] aFlags The raw flags value.
|
||||
*
|
||||
*/
|
||||
void SetRawValue(uint8_t aTypeIdFlags) { mTypeIdFlags = aTypeIdFlags; }
|
||||
void SetRawValue(uint8_t aFlags) { mFlags = aFlags; }
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kLengthFlag = 1 << 6,
|
||||
kExtendedFlag = 1 << 7,
|
||||
kTypeEnumOffset = 3,
|
||||
kTypeEnumMask = 7 << kTypeEnumOffset,
|
||||
kMetricEnumOffset = 0,
|
||||
kMetricEnumMask = 7 << kMetricEnumOffset,
|
||||
};
|
||||
|
||||
uint8_t mTypeIdFlags;
|
||||
uint8_t mFlags;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
/**
|
||||
@@ -237,7 +296,7 @@ private:
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class LinkMetricsReportSubTlv : public Tlv, public TlvInfo<kLinkMetricsReportSub>
|
||||
class ReportSubTlv : public Tlv, public TlvInfo<SubTlv::kReport>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@@ -246,7 +305,7 @@ public:
|
||||
*/
|
||||
void Init(void)
|
||||
{
|
||||
SetType(kLinkMetricsReportSub);
|
||||
SetType(SubTlv::kReport);
|
||||
SetLength(sizeof(*this) - sizeof(Tlv));
|
||||
}
|
||||
|
||||
@@ -257,7 +316,7 @@ public:
|
||||
* @retval false The TLV does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return GetLength() >= sizeof(LinkMetricsTypeIdFlags) + sizeof(uint8_t); }
|
||||
bool IsValid(void) const { return GetLength() >= sizeof(TypeIdFlags) + sizeof(uint8_t); }
|
||||
|
||||
/**
|
||||
* This method returns the Link Metrics Type ID.
|
||||
@@ -265,7 +324,7 @@ public:
|
||||
* @returns The Link Metrics Type ID.
|
||||
*
|
||||
*/
|
||||
LinkMetricsTypeIdFlags GetMetricsTypeId(void) const { return mMetricsTypeId; }
|
||||
TypeIdFlags GetMetricsTypeId(void) const { return mMetricsTypeId; }
|
||||
|
||||
/**
|
||||
* This method sets the Link Metrics Type ID.
|
||||
@@ -273,9 +332,10 @@ public:
|
||||
* @param[in] aMetricsTypeID The Link Metrics Type ID to set.
|
||||
*
|
||||
*/
|
||||
void SetMetricsTypeId(LinkMetricsTypeIdFlags aMetricsTypeId)
|
||||
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
|
||||
@@ -315,7 +375,7 @@ public:
|
||||
void SetMetricsValue32(uint32_t aMetricsValue) { mMetricsValue.m32 = aMetricsValue; }
|
||||
|
||||
private:
|
||||
LinkMetricsTypeIdFlags mMetricsTypeId;
|
||||
TypeIdFlags mMetricsTypeId;
|
||||
union
|
||||
{
|
||||
uint8_t m8;
|
||||
@@ -328,7 +388,7 @@ private:
|
||||
*
|
||||
*/
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class LinkMetricsQueryOptionsTlv : public Tlv, public TlvInfo<kLinkMetricsQueryOptions>
|
||||
class QueryOptionsSubTlv : public Tlv, public TlvInfo<SubTlv::kQueryOptions>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@@ -337,7 +397,7 @@ public:
|
||||
*/
|
||||
void Init(void)
|
||||
{
|
||||
SetType(kLinkMetricsQueryOptions);
|
||||
SetType(SubTlv::kQueryOptions);
|
||||
SetLength(0);
|
||||
}
|
||||
|
||||
@@ -348,7 +408,7 @@ public:
|
||||
* @retval FALSE If the TLV does not appear to be well-formed.
|
||||
*
|
||||
*/
|
||||
bool IsValid(void) const { return GetLength() >= sizeof(LinkMetricsTypeIdFlags); }
|
||||
bool IsValid(void) const { return GetLength() >= sizeof(TypeIdFlags); }
|
||||
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
@@ -361,38 +421,47 @@ class SeriesFlags
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default constructor
|
||||
* This type represents which frames to be accounted in a Forward Tracking Series.
|
||||
*
|
||||
* @sa otLinkMetricsSeriesFlags
|
||||
*
|
||||
*/
|
||||
SeriesFlags(void) { mSeriesFlags = 0; }
|
||||
typedef otLinkMetricsSeriesFlags Info;
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
* Default constructor.
|
||||
*
|
||||
*/
|
||||
SeriesFlags(const SeriesFlags &aSeriesFlags) { mSeriesFlags = aSeriesFlags.mSeriesFlags; }
|
||||
SeriesFlags(void)
|
||||
: mFlags(0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the values of this object from a `otLinkMetricsSeriesFlags` object.
|
||||
* This method sets the values from an `Info` object.
|
||||
*
|
||||
* @param[in] aSeriesFlags The `otLinkMetricsSeriesFlags` object.
|
||||
* @param[in] aSeriesFlags The `Info` object.
|
||||
*
|
||||
*/
|
||||
void SetFromOtSeriesFlags(const otLinkMetricsSeriesFlags aSeriesFlags)
|
||||
void SetFrom(const Info &aSeriesFlags)
|
||||
{
|
||||
Clear();
|
||||
|
||||
if (aSeriesFlags.mLinkProbe)
|
||||
{
|
||||
SetLinkProbeFlag();
|
||||
}
|
||||
|
||||
if (aSeriesFlags.mMacData)
|
||||
{
|
||||
SetMacDataFlag();
|
||||
}
|
||||
|
||||
if (aSeriesFlags.mMacDataRequest)
|
||||
{
|
||||
SetMacDataRequestFlag();
|
||||
}
|
||||
|
||||
if (aSeriesFlags.mMacAck)
|
||||
{
|
||||
SetMacAckFlag();
|
||||
@@ -403,13 +472,13 @@ public:
|
||||
* This method clears the Link Probe flag.
|
||||
*
|
||||
*/
|
||||
void ClearLinkProbeFlag(void) { mSeriesFlags &= ~kLinkProbeFlag; }
|
||||
void ClearLinkProbeFlag(void) { mFlags &= ~kLinkProbeFlag; }
|
||||
|
||||
/**
|
||||
* This method sets the Link Probe flag.
|
||||
*
|
||||
*/
|
||||
void SetLinkProbeFlag(void) { mSeriesFlags |= kLinkProbeFlag; }
|
||||
void SetLinkProbeFlag(void) { mFlags |= kLinkProbeFlag; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the Link Probe flag is set.
|
||||
@@ -418,19 +487,19 @@ public:
|
||||
* @retval false The Link Probe flag is not set.
|
||||
*
|
||||
*/
|
||||
bool IsLinkProbeFlagSet(void) const { return (mSeriesFlags & kLinkProbeFlag) != 0; }
|
||||
bool IsLinkProbeFlagSet(void) const { return (mFlags & kLinkProbeFlag) != 0; }
|
||||
|
||||
/**
|
||||
* This method clears the MAC Data flag.
|
||||
*
|
||||
*/
|
||||
void ClearMacDataFlag(void) { mSeriesFlags &= ~kMacDataFlag; }
|
||||
void ClearMacDataFlag(void) { mFlags &= ~kMacDataFlag; }
|
||||
|
||||
/**
|
||||
* This method sets the MAC Data flag.
|
||||
*
|
||||
*/
|
||||
void SetMacDataFlag(void) { mSeriesFlags |= kMacDataFlag; }
|
||||
void SetMacDataFlag(void) { mFlags |= kMacDataFlag; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the MAC Data flag is set.
|
||||
@@ -439,19 +508,19 @@ public:
|
||||
* @retval false The MAC Data flag is not set.
|
||||
*
|
||||
*/
|
||||
bool IsMacDataFlagSet(void) const { return (mSeriesFlags & kMacDataFlag) != 0; }
|
||||
bool IsMacDataFlagSet(void) const { return (mFlags & kMacDataFlag) != 0; }
|
||||
|
||||
/**
|
||||
* This method clears the MAC Data Request flag.
|
||||
*
|
||||
*/
|
||||
void ClearMacDataRequestFlag(void) { mSeriesFlags &= ~kMacDataRequestFlag; }
|
||||
void ClearMacDataRequestFlag(void) { mFlags &= ~kMacDataRequestFlag; }
|
||||
|
||||
/**
|
||||
* This method sets the MAC Data Request flag.
|
||||
*
|
||||
*/
|
||||
void SetMacDataRequestFlag(void) { mSeriesFlags |= kMacDataRequestFlag; }
|
||||
void SetMacDataRequestFlag(void) { mFlags |= kMacDataRequestFlag; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the MAC Data Request flag is set.
|
||||
@@ -460,19 +529,19 @@ public:
|
||||
* @retval false The MAC Data Request flag is not set.
|
||||
*
|
||||
*/
|
||||
bool IsMacDataRequestFlagSet(void) const { return (mSeriesFlags & kMacDataRequestFlag) != 0; }
|
||||
bool IsMacDataRequestFlagSet(void) const { return (mFlags & kMacDataRequestFlag) != 0; }
|
||||
|
||||
/**
|
||||
* This method clears the Mac Ack flag.
|
||||
*
|
||||
*/
|
||||
void ClearMacAckFlag(void) { mSeriesFlags &= ~kMacAckFlag; }
|
||||
void ClearMacAckFlag(void) { mFlags &= ~kMacAckFlag; }
|
||||
|
||||
/**
|
||||
* This method sets the Mac Ack flag.
|
||||
*
|
||||
*/
|
||||
void SetMacAckFlag(void) { mSeriesFlags |= kMacAckFlag; }
|
||||
void SetMacAckFlag(void) { mFlags |= kMacAckFlag; }
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the Mac Ack flag is set.
|
||||
@@ -481,75 +550,69 @@ public:
|
||||
* @retval false The Mac Ack flag is not set.
|
||||
*
|
||||
*/
|
||||
bool IsMacAckFlagSet(void) const { return (mSeriesFlags & kMacAckFlag) != 0; }
|
||||
bool IsMacAckFlagSet(void) const { return (mFlags & kMacAckFlag) != 0; }
|
||||
|
||||
/**
|
||||
* This method returns the raw value of mSeriesFlags.
|
||||
* This method returns the raw value of flags.
|
||||
*
|
||||
*/
|
||||
uint8_t GetRawValue(void) const { return mSeriesFlags; }
|
||||
uint8_t GetRawValue(void) const { return mFlags; }
|
||||
|
||||
/**
|
||||
* This method clears the all the flags.
|
||||
*
|
||||
*/
|
||||
void Clear(void) { mSeriesFlags = 0; }
|
||||
|
||||
/**
|
||||
* This method overloads the assignment operator.
|
||||
*
|
||||
*/
|
||||
void operator=(const SeriesFlags &aSeriesFlags) { mSeriesFlags = aSeriesFlags.mSeriesFlags; }
|
||||
void Clear(void) { mFlags = 0; }
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kLinkProbeFlag = 1 << 0,
|
||||
kMacDataFlag = 1 << 1,
|
||||
kMacDataRequestFlag = 1 << 2,
|
||||
kMacAckFlag = 1 << 3,
|
||||
};
|
||||
static constexpr uint8_t kLinkProbeFlag = 1 << 0;
|
||||
static constexpr uint8_t kMacDataFlag = 1 << 1;
|
||||
static constexpr uint8_t kMacDataRequestFlag = 1 << 2;
|
||||
static constexpr uint8_t kMacAckFlag = 1 << 3;
|
||||
|
||||
uint8_t mSeriesFlags;
|
||||
uint8_t mFlags;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
enum LinkMetricsEnhAckFlags : uint8_t
|
||||
/**
|
||||
* This enumeration type represent Enhanced-ACK Flags.
|
||||
*
|
||||
*/
|
||||
enum EnhAckFlags : uint8_t
|
||||
{
|
||||
kEnhAckClear = OT_LINK_METRICS_ENH_ACK_CLEAR, ///< Clear.
|
||||
kEnhAckRegister = OT_LINK_METRICS_ENH_ACK_REGISTER, ///< Register.
|
||||
};
|
||||
|
||||
static uint8_t TypeIdFlagsFromLinkMetricsFlags(LinkMetricsTypeIdFlags *aTypeIdFlags,
|
||||
const otLinkMetrics & aLinkMetricsFlags)
|
||||
static uint8_t TypeIdFlagsFromMetrics(TypeIdFlags aTypeIdFlags[], const Metrics &aMetrics)
|
||||
{
|
||||
uint8_t count = 0;
|
||||
|
||||
if (aLinkMetricsFlags.mPduCount)
|
||||
if (aMetrics.mPduCount)
|
||||
{
|
||||
aTypeIdFlags[count++].SetRawValue(kTypeIdFlagPdu);
|
||||
aTypeIdFlags[count++].SetRawValue(TypeIdFlags::kPdu);
|
||||
}
|
||||
|
||||
if (aLinkMetricsFlags.mLqi)
|
||||
if (aMetrics.mLqi)
|
||||
{
|
||||
aTypeIdFlags[count++].SetRawValue(kTypeIdFlagLqi);
|
||||
aTypeIdFlags[count++].SetRawValue(TypeIdFlags::kLqi);
|
||||
}
|
||||
|
||||
if (aLinkMetricsFlags.mLinkMargin)
|
||||
if (aMetrics.mLinkMargin)
|
||||
{
|
||||
aTypeIdFlags[count++].SetRawValue(kTypeIdFlagLinkMargin);
|
||||
aTypeIdFlags[count++].SetRawValue(TypeIdFlags::kLinkMargin);
|
||||
}
|
||||
|
||||
if (aLinkMetricsFlags.mRssi)
|
||||
if (aMetrics.mRssi)
|
||||
{
|
||||
aTypeIdFlags[count++].SetRawValue(kTypeIdFlagRssi);
|
||||
aTypeIdFlags[count++].SetRawValue(TypeIdFlags::kRssi);
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
if (aLinkMetricsFlags.mReserved)
|
||||
if (aMetrics.mReserved)
|
||||
{
|
||||
for (uint8_t i = 0; i < count; i++)
|
||||
{
|
||||
aTypeIdFlags[i].SetTypeEnum(LinkMetricsTypeIdFlags::kTypeEnumReserved);
|
||||
aTypeIdFlags[i].SetTypeEnum(TypeIdFlags::kTypeReserved);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -558,14 +621,14 @@ static uint8_t TypeIdFlagsFromLinkMetricsFlags(LinkMetricsTypeIdFlags *aTypeIdFl
|
||||
}
|
||||
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
class EnhAckLinkMetricsConfigurationSubTlv : public Tlv
|
||||
class EnhAckConfigSubTlv : public Tlv, public TlvInfo<SubTlv::kEnhAckConfig>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
*/
|
||||
EnhAckLinkMetricsConfigurationSubTlv(void) { Init(); }
|
||||
EnhAckConfigSubTlv(void) { Init(); }
|
||||
|
||||
/**
|
||||
* This method initializes the TLV.
|
||||
@@ -573,8 +636,8 @@ public:
|
||||
*/
|
||||
void Init(void)
|
||||
{
|
||||
SetType(kEnhancedACKConfiguration);
|
||||
SetLength(sizeof(LinkMetricsEnhAckFlags));
|
||||
SetType(SubTlv::kEnhAckConfig);
|
||||
SetLength(sizeof(EnhAckFlags));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -583,27 +646,26 @@ public:
|
||||
* @param[in] aEnhAckFlags The value of Enhanced ACK Flags.
|
||||
*
|
||||
*/
|
||||
void SetEnhAckFlags(otLinkMetricsEnhAckFlags aEnhAckFlags)
|
||||
void SetEnhAckFlags(EnhAckFlags aEnhAckFlags)
|
||||
{
|
||||
memcpy(mSubTlvs + kEnhAckFlagsOffset, &aEnhAckFlags, sizeof(aEnhAckFlags));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets Type Id Flags.
|
||||
* This method sets Type ID Flags.
|
||||
*
|
||||
* @param[in] aLinkMetricsFlags A pointer to a `otLinkMetrics` representing the Type Id Flags.
|
||||
* @param[in] aMetrics A metrics flags to indicate the Type ID Flags.
|
||||
*
|
||||
*/
|
||||
void SetTypeIdFlags(const otLinkMetrics *aLinkMetricsFlags)
|
||||
void SetTypeIdFlags(const Metrics &aMetrics)
|
||||
{
|
||||
uint8_t typeIdFlagsCount;
|
||||
uint8_t count;
|
||||
|
||||
OT_ASSERT(aLinkMetricsFlags != nullptr);
|
||||
typeIdFlagsCount = TypeIdFlagsFromLinkMetricsFlags(
|
||||
reinterpret_cast<LinkMetricsTypeIdFlags *>(mSubTlvs + kTypeIdFlagsOffset), *aLinkMetricsFlags);
|
||||
OT_ASSERT(typeIdFlagsCount <= kMaxTypeIdFlagsEnhAck);
|
||||
count = TypeIdFlagsFromMetrics(reinterpret_cast<TypeIdFlags *>(mSubTlvs + kTypeIdFlagsOffset), aMetrics);
|
||||
|
||||
SetLength(sizeof(LinkMetricsEnhAckFlags) + sizeof(LinkMetricsTypeIdFlags) * typeIdFlagsCount);
|
||||
OT_ASSERT(count <= kMaxTypeIdFlagsEnhAck);
|
||||
|
||||
SetLength(sizeof(EnhAckFlags) + sizeof(TypeIdFlags) * count);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -612,12 +674,13 @@ private:
|
||||
kMaxTypeIdFlagsEnhAck = 3,
|
||||
|
||||
kEnhAckFlagsOffset = 0,
|
||||
kTypeIdFlagsOffset = sizeof(LinkMetricsTypeIdFlags),
|
||||
kTypeIdFlagsOffset = sizeof(TypeIdFlags),
|
||||
};
|
||||
|
||||
uint8_t mSubTlvs[sizeof(LinkMetricsEnhAckFlags) + sizeof(LinkMetricsTypeIdFlags) * kMaxTypeIdFlagsEnhAck];
|
||||
uint8_t mSubTlvs[sizeof(EnhAckFlags) + sizeof(TypeIdFlags) * kMaxTypeIdFlagsEnhAck];
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
} // namespace LinkMetrics
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
|
||||
+10
-10
@@ -2512,7 +2512,7 @@ exit:
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
Error Mle::SendLinkMetricsManagementResponse(const Ip6::Address &aDestination, LinkMetrics::LinkMetricsStatus aStatus)
|
||||
Error Mle::SendLinkMetricsManagementResponse(const Ip6::Address &aDestination, LinkMetrics::Status aStatus)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
Message *message;
|
||||
@@ -2523,7 +2523,7 @@ Error Mle::SendLinkMetricsManagementResponse(const Ip6::Address &aDestination, L
|
||||
SuccessOrExit(error = AppendHeader(*message, kCommandLinkMetricsManagementResponse));
|
||||
|
||||
tlv.SetType(Tlv::kLinkMetricsManagement);
|
||||
statusSubTlv.SetType(kLinkMetricsStatus);
|
||||
statusSubTlv.SetType(LinkMetrics::SubTlv::kStatus);
|
||||
statusSubTlv.SetLength(sizeof(aStatus));
|
||||
tlv.SetLength(statusSubTlv.GetSize());
|
||||
|
||||
@@ -3031,8 +3031,8 @@ void Mle::HandleDataResponse(const Message &aMessage, const Ip6::MessageInfo &aM
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
|
||||
if (Tlv::FindTlvValueOffset(aMessage, Tlv::kLinkMetricsReport, metricsReportValueOffset, length) == kErrorNone)
|
||||
{
|
||||
Get<LinkMetrics>().HandleLinkMetricsReport(aMessage, metricsReportValueOffset, length,
|
||||
aMessageInfo.GetPeerAddr());
|
||||
Get<LinkMetrics::LinkMetrics>().HandleReport(aMessage, metricsReportValueOffset, length,
|
||||
aMessageInfo.GetPeerAddr());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3942,14 +3942,14 @@ void Mle::HandleLinkMetricsManagementRequest(const Message & aMessage,
|
||||
const Ip6::MessageInfo &aMessageInfo,
|
||||
Neighbor * aNeighbor)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
LinkMetrics::LinkMetricsStatus status;
|
||||
Error error = kErrorNone;
|
||||
LinkMetrics::Status status;
|
||||
|
||||
Log(kMessageReceive, kTypeLinkMetricsManagementRequest, aMessageInfo.GetPeerAddr());
|
||||
|
||||
VerifyOrExit(aNeighbor != nullptr, error = kErrorInvalidState);
|
||||
|
||||
SuccessOrExit(error = Get<LinkMetrics>().HandleLinkMetricsManagementRequest(aMessage, *aNeighbor, status));
|
||||
SuccessOrExit(error = Get<LinkMetrics::LinkMetrics>().HandleManagementRequest(aMessage, *aNeighbor, status));
|
||||
error = SendLinkMetricsManagementResponse(aMessageInfo.GetPeerAddr(), status);
|
||||
|
||||
exit:
|
||||
@@ -3969,7 +3969,7 @@ void Mle::HandleLinkMetricsManagementResponse(const Message & aMessage,
|
||||
|
||||
VerifyOrExit(aNeighbor != nullptr, error = kErrorInvalidState);
|
||||
|
||||
error = Get<LinkMetrics>().HandleLinkMetricsManagementResponse(aMessage, aMessageInfo.GetPeerAddr());
|
||||
error = Get<LinkMetrics::LinkMetrics>().HandleManagementResponse(aMessage, aMessageInfo.GetPeerAddr());
|
||||
|
||||
exit:
|
||||
LogProcessError(kTypeLinkMetricsManagementResponse, error);
|
||||
@@ -3984,8 +3984,8 @@ void Mle::HandleLinkProbe(const Message &aMessage, const Ip6::MessageInfo &aMess
|
||||
|
||||
Log(kMessageReceive, kTypeLinkProbe, aMessageInfo.GetPeerAddr());
|
||||
|
||||
SuccessOrExit(error = Get<LinkMetrics>().HandleLinkProbe(aMessage, seriesId));
|
||||
aNeighbor->AggregateLinkMetrics(seriesId, LinkMetricsSeriesInfo::kSeriesTypeLinkProbe, aMessage.GetAverageLqi(),
|
||||
SuccessOrExit(error = Get<LinkMetrics::LinkMetrics>().HandleLinkProbe(aMessage, seriesId));
|
||||
aNeighbor->AggregateLinkMetrics(seriesId, LinkMetrics::SeriesInfo::kSeriesTypeLinkProbe, aMessage.GetAverageLqi(),
|
||||
aMessage.GetAverageRss());
|
||||
|
||||
exit:
|
||||
|
||||
@@ -97,7 +97,7 @@ class Mle : public InstanceLocator, private NonCopyable
|
||||
friend class DiscoverScanner;
|
||||
friend class ot::Notifier;
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
friend class ot::LinkMetrics;
|
||||
friend class ot::LinkMetrics::LinkMetrics;
|
||||
#endif
|
||||
|
||||
public:
|
||||
@@ -1809,7 +1809,7 @@ private:
|
||||
bool PrepareAnnounceState(void);
|
||||
void SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce, const Ip6::Address &aDestination);
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
Error SendLinkMetricsManagementResponse(const Ip6::Address &aDestination, LinkMetrics::LinkMetricsStatus aStatus);
|
||||
Error SendLinkMetricsManagementResponse(const Ip6::Address &aDestination, LinkMetrics::Status aStatus);
|
||||
#endif
|
||||
uint32_t Reattach(void);
|
||||
|
||||
|
||||
@@ -3290,7 +3290,7 @@ void MleRouter::SendDataResponse(const Ip6::Address &aDestination,
|
||||
OT_ASSERT(aRequestMessage != nullptr);
|
||||
neighbor = mNeighborTable.FindNeighbor(aDestination);
|
||||
VerifyOrExit(neighbor != nullptr, error = kErrorInvalidState);
|
||||
SuccessOrExit(error = Get<LinkMetrics>().AppendLinkMetricsReport(*message, *aRequestMessage, *neighbor));
|
||||
SuccessOrExit(error = Get<LinkMetrics::LinkMetrics>().AppendReport(*message, *aRequestMessage, *neighbor));
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -302,7 +302,7 @@ private:
|
||||
TimeSync mTimeSync;
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
LinkMetrics mLinkMetrics;
|
||||
LinkMetrics::LinkMetrics mLinkMetrics;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -163,8 +163,8 @@ void Neighbor::GenerateChallenge(void)
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
void Neighbor::AggregateLinkMetrics(uint8_t aSeriesId, uint8_t aFrameType, uint8_t aLqi, int8_t aRss)
|
||||
{
|
||||
for (LinkMetricsSeriesInfo *entry = mLinkMetricsSeriesInfoList.GetHead(); entry != nullptr;
|
||||
entry = entry->GetNext())
|
||||
for (LinkMetrics::SeriesInfo *entry = mLinkMetricsSeriesInfoList.GetHead(); entry != nullptr;
|
||||
entry = entry->GetNext())
|
||||
{
|
||||
if (aSeriesId == 0 || aSeriesId == entry->GetSeriesId())
|
||||
{
|
||||
@@ -173,17 +173,17 @@ void Neighbor::AggregateLinkMetrics(uint8_t aSeriesId, uint8_t aFrameType, uint8
|
||||
}
|
||||
}
|
||||
|
||||
LinkMetricsSeriesInfo *Neighbor::GetForwardTrackingSeriesInfo(const uint8_t &aSeriesId)
|
||||
LinkMetrics::SeriesInfo *Neighbor::GetForwardTrackingSeriesInfo(const uint8_t &aSeriesId)
|
||||
{
|
||||
return mLinkMetricsSeriesInfoList.FindMatching(aSeriesId);
|
||||
}
|
||||
|
||||
void Neighbor::AddForwardTrackingSeriesInfo(LinkMetricsSeriesInfo &aLinkMetricsSeriesInfo)
|
||||
void Neighbor::AddForwardTrackingSeriesInfo(LinkMetrics::SeriesInfo &aSeriesInfo)
|
||||
{
|
||||
mLinkMetricsSeriesInfoList.Push(aLinkMetricsSeriesInfo);
|
||||
mLinkMetricsSeriesInfoList.Push(aSeriesInfo);
|
||||
}
|
||||
|
||||
LinkMetricsSeriesInfo *Neighbor::RemoveForwardTrackingSeriesInfo(const uint8_t &aSeriesId)
|
||||
LinkMetrics::SeriesInfo *Neighbor::RemoveForwardTrackingSeriesInfo(const uint8_t &aSeriesId)
|
||||
{
|
||||
return mLinkMetricsSeriesInfoList.RemoveMatching(aSeriesId);
|
||||
}
|
||||
@@ -192,8 +192,8 @@ void Neighbor::RemoveAllForwardTrackingSeriesInfo(void)
|
||||
{
|
||||
while (!mLinkMetricsSeriesInfoList.IsEmpty())
|
||||
{
|
||||
LinkMetricsSeriesInfo *seriesInfo = mLinkMetricsSeriesInfoList.Pop();
|
||||
Get<LinkMetrics>().mLinkMetricsSeriesInfoPool.Free(*seriesInfo);
|
||||
LinkMetrics::SeriesInfo *seriesInfo = mLinkMetricsSeriesInfoList.Pop();
|
||||
Get<LinkMetrics::LinkMetrics>().mSeriesInfoPool.Free(*seriesInfo);
|
||||
}
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
|
||||
@@ -681,32 +681,32 @@ public:
|
||||
void AggregateLinkMetrics(uint8_t aSeriesId, uint8_t aFrameType, uint8_t aLqi, int8_t aRss);
|
||||
|
||||
/**
|
||||
* This method adds a new LinkMetricsSeriesInfo to the neighbor's list.
|
||||
* This method adds a new LinkMetrics::SeriesInfo to the neighbor's list.
|
||||
*
|
||||
* @param[in] A reference to the new LinkMetricsSeriesInfo.
|
||||
* @param[in] A reference to the new SeriesInfo.
|
||||
*
|
||||
*/
|
||||
void AddForwardTrackingSeriesInfo(LinkMetricsSeriesInfo &aLinkMetricsSeriesInfo);
|
||||
void AddForwardTrackingSeriesInfo(LinkMetrics::SeriesInfo &aSeriesInfo);
|
||||
|
||||
/**
|
||||
* This method finds a specific LinkMetricsSeriesInfo by Series ID.
|
||||
* This method finds a specific LinkMetrics::SeriesInfo by Series ID.
|
||||
*
|
||||
* @param[in] aSeriesId A reference to the Series ID.
|
||||
*
|
||||
* @returns The pointer to the LinkMetricsSeriesInfo. `nullptr` if not found.
|
||||
* @returns The pointer to the LinkMetrics::SeriesInfo. `nullptr` if not found.
|
||||
*
|
||||
*/
|
||||
LinkMetricsSeriesInfo *GetForwardTrackingSeriesInfo(const uint8_t &aSeriesId);
|
||||
LinkMetrics::SeriesInfo *GetForwardTrackingSeriesInfo(const uint8_t &aSeriesId);
|
||||
|
||||
/**
|
||||
* This method removes a specific LinkMetricsSeriesInfo by Series ID.
|
||||
* This method removes a specific LinkMetrics::SeriesInfo by Series ID.
|
||||
*
|
||||
* @param[in] aSeriesId A reference to the Series ID to remove.
|
||||
*
|
||||
* @returns The pointer to the LinkMetricsSeriesInfo. `nullptr` if not found.
|
||||
* @returns The pointer to the LinkMetrics::SeriesInfo. `nullptr` if not found.
|
||||
*
|
||||
*/
|
||||
LinkMetricsSeriesInfo *RemoveForwardTrackingSeriesInfo(const uint8_t &aSeriesId);
|
||||
LinkMetrics::SeriesInfo *RemoveForwardTrackingSeriesInfo(const uint8_t &aSeriesId);
|
||||
|
||||
/**
|
||||
* This method removes all the Series and return the data structures to the Pool.
|
||||
@@ -720,7 +720,7 @@ public:
|
||||
* @returns Enh-ACK Probing metrics configured.
|
||||
*
|
||||
*/
|
||||
const otLinkMetrics &GetEnhAckProbingMetrics(void) const { return mEnhAckProbingMetrics; }
|
||||
const LinkMetrics::Metrics &GetEnhAckProbingMetrics(void) const { return mEnhAckProbingMetrics; }
|
||||
|
||||
/**
|
||||
* This method sets the Enh-ACK Probing metrics (this `Neighbor` object is the Probing Subject).
|
||||
@@ -728,7 +728,7 @@ public:
|
||||
* @param[in] aEnhAckProbingMetrics The metrics value to set.
|
||||
*
|
||||
*/
|
||||
void SetEnhAckProbingMetrics(const otLinkMetrics &aEnhAckProbingMetrics)
|
||||
void SetEnhAckProbingMetrics(const LinkMetrics::Metrics &aEnhAckProbingMetrics)
|
||||
{
|
||||
mEnhAckProbingMetrics = aEnhAckProbingMetrics;
|
||||
}
|
||||
@@ -802,13 +802,15 @@ private:
|
||||
uint8_t mVersion; ///< The MLE version
|
||||
LinkQualityInfo mLinkInfo; ///< Link quality info (contains average RSS, link margin and link quality)
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
LinkedList<LinkMetricsSeriesInfo> mLinkMetricsSeriesInfoList; ///< A list of Link Metrics Forward Tracking Series
|
||||
///< that is being tracked for this neighbor. Note
|
||||
///< that this device is the Subject and this
|
||||
///< this neighbor is the Initiator.
|
||||
otLinkMetrics mEnhAckProbingMetrics; ///< Metrics configured for Enh-ACK Based Probing at the Probing Subject
|
||||
///< (this neighbor). Note that this device is the Initiator and this neighbor
|
||||
///< is the Subject.
|
||||
// A list of Link Metrics Forward Tracking Series that is being
|
||||
// tracked for this neighbor. Note that this device is the
|
||||
// Subject and this neighbor is the Initiator.
|
||||
LinkedList<LinkMetrics::SeriesInfo> mLinkMetricsSeriesInfoList;
|
||||
|
||||
// Metrics configured for Enh-ACK Based Probing at the Probing
|
||||
// Subject (this neighbor). Note that this device is the Initiator
|
||||
// and this neighbor is the Subject.
|
||||
LinkMetrics::Metrics mEnhAckProbingMetrics;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user