diff --git a/src/core/api/link_metrics_api.cpp b/src/core/api/link_metrics_api.cpp index c83160b78..bc5c307b6 100644 --- a/src/core/api/link_metrics_api.cpp +++ b/src/core/api/link_metrics_api.cpp @@ -51,10 +51,11 @@ otError otLinkMetricsQuery(otInstance * aInstance, { OT_ASSERT(aDestination != nullptr); - static_cast(aInstance)->Get().SetLinkMetricsReportCallback(aCallback, aCallbackContext); + static_cast(aInstance)->Get().SetReportCallback(aCallback, aCallbackContext); - return static_cast(aInstance)->Get().LinkMetricsQuery( - static_cast(*aDestination), aSeriesId, aLinkMetricsFlags); + return static_cast(aInstance)->Get().Query( + static_cast(*aDestination), aSeriesId, + static_cast(aLinkMetricsFlags)); } otError otLinkMetricsConfigForwardTrackingSeries(otInstance * aInstance, @@ -67,17 +68,19 @@ otError otLinkMetricsConfigForwardTrackingSeries(otInstance * { OT_ASSERT(aDestination != nullptr); - static_cast(aInstance)->Get().SetLinkMetricsMgmtResponseCallback(aCallback, - aCallbackContext); + LinkMetrics::LinkMetrics &linkMetrics = static_cast(aInstance)->Get(); - return static_cast(aInstance)->Get().SendMgmtRequestForwardTrackingSeries( - static_cast(*aDestination), aSeriesId, aSeriesFlags, aLinkMetricsFlags); + linkMetrics.SetMgmtResponseCallback(aCallback, aCallbackContext); + + return linkMetrics.SendMgmtRequestForwardTrackingSeries( + static_cast(*aDestination), aSeriesId, aSeriesFlags, + static_cast(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(aInstance)->Get().SetLinkMetricsMgmtResponseCallback(aCallback, - aCallbackContext); - static_cast(aInstance)->Get().SetLinkMetricsEnhAckProbingCallback(aEnhAckCallback, - aEnhAckCallbackContext); + LinkMetrics::LinkMetrics &linkMetrics = static_cast(aInstance)->Get(); - return static_cast(aInstance)->Get().SendMgmtRequestEnhAckProbing( - static_cast(*aDestination), aEnhAckFlags, aLinkMetricsFlags); + linkMetrics.SetMgmtResponseCallback(aCallback, aCallbackContext); + linkMetrics.SetEnhAckProbingCallback(aEnhAckCallback, aEnhAckCallbackContext); + + return linkMetrics.SendMgmtRequestEnhAckProbing(static_cast(*aDestination), + static_cast(aEnhAckFlags), + static_cast(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(aInstance)->Get(); - return static_cast(aInstance)->Get().SendLinkProbe( - static_cast(*aDestination), aSeriesId, aLength); + return linkMetrics.SendLinkProbe(static_cast(*aDestination), aSeriesId, aLength); } #endif diff --git a/src/core/common/instance.hpp b/src/core/common/instance.hpp index 366804c24..c14323059 100644 --- a/src/core/common/instance.hpp +++ b/src/core/common/instance.hpp @@ -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; } diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index 466cdb89c..1157fbd89 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -2449,7 +2449,7 @@ void Mac::ProcessEnhAckProbing(const RxFrame &aFrame, const Neighbor &aNeighbor) dataLen = enhAckProbingIe->GetLength() - sizeof(VendorIeHeader); VerifyOrExit(dataLen <= kEnhAckProbingIeMaxLen); - Get().ProcessEnhAckIeData(data, dataLen, aNeighbor); + Get().ProcessEnhAckIeData(data, dataLen, aNeighbor); exit: return; } diff --git a/src/core/thread/link_metrics.cpp b/src/core/thread/link_metrics.cpp index 886bfe8d9..1ccfa0367 100644 --- a/src/core/thread/link_metrics.cpp +++ b/src/core/thread/link_metrics.cpp @@ -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(subTlvs); + uint8_t subTlvs[sizeof(Tlv) + sizeof(uint8_t) * 2 + sizeof(TypeIdFlags) * kMaxTypeIdFlags]; + Tlv * fwdProbingSubTlv = reinterpret_cast(subTlvs); SeriesFlags *seriesFlags = reinterpret_cast(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(subTlvs + typeIdFlagsOffset), *aLinkMetricsFlags); + typeIdFlagsCount = + TypeIdFlagsFromMetrics(reinterpret_cast(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().SendLinkMetricsManagementRequest(aDestination, subTlvs, - forwardProbingRegistrationSubTlv->GetSize()); + error = Get().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().SendLinkMetricsManagementRequest( - aDestination, reinterpret_cast(&enhAckLinkMetricsConfigurationSubTlv), - enhAckLinkMetricsConfigurationSubTlv.GetSize()); + aDestination, reinterpret_cast(&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(aRequestMessage, offset, queryId)); + case SubTlv::kQueryId: + SuccessOrExit(error = Tlv::Read(aRequestMessage, offset, queryId)); hasQueryId = true; break; - case kLinkMetricsQueryOptions: + case SubTlv::kQueryOptions: SuccessOrExit(error = ReadTypeIdFlagsFromMessage(aRequestMessage, offset + sizeof(tlv), static_cast(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().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().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().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(offset + index + tlv.GetSize()), linkMetrics)); + aMessage, pos, static_cast(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(offset + index + tlv.GetSize()), linkMetrics)); + aMessage, pos, static_cast(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(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(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().ConfigureEnhAckProbing(aLinkMetrics, aNeighbor.GetRloc16(), aNeighbor.GetExtAddress()); + error = Get().ConfigureEnhAckProbing(aMetrics, aNeighbor.GetRloc16(), aNeighbor.GetExtAddress()); } else if (aEnhAckFlags == kEnhAckClear) { - VerifyOrExit(!aLinkMetrics.mLqi && !aLinkMetrics.mLinkMargin && !aLinkMetrics.mRssi, - status = kLinkMetricsStatusOtherError); - error = Get().ConfigureEnhAckProbing(aLinkMetrics, aNeighbor.GetRloc16(), aNeighbor.GetExtAddress()); + VerifyOrExit(!aMetrics.mLqi && !aMetrics.mLinkMargin && !aMetrics.mRssi, status = kStatusOtherError); + error = Get().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 diff --git a/src/core/thread/link_metrics.hpp b/src/core/thread/link_metrics.hpp index aed182896..8bfc2b061 100644 --- a/src/core/thread/link_metrics.hpp +++ b/src/core/thread/link_metrics.hpp @@ -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 +#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 +{ +public: + /** + * This method gets the metrics flags. + * + * @returns The metrics flags. + * + */ + Metrics &GetMetrics(void) { return static_cast(mMetrics); } + + /** + * This method gets the metrics flags. + * + * @returns The metrics flags. + * + */ + const Metrics &GetMetrics(void) const { return static_cast(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 +class SeriesInfo : public LinkedListEntry { - friend class LinkedList; - friend class LinkedListEntry; + friend class LinkedList; + friend class LinkedListEntry; 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 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 mSeriesInfoPool; }; /** * @} */ +} // namespace LinkMetrics } // namespace ot #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE diff --git a/src/core/thread/link_metrics_tlvs.hpp b/src/core/thread/link_metrics_tlvs.hpp index fbac0b1bb..21e0a3e3a 100644 --- a/src/core/thread/link_metrics_tlvs.hpp +++ b/src/core/thread/link_metrics_tlvs.hpp @@ -41,77 +41,143 @@ #include +#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 { - 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 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 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((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((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 +class ReportSubTlv : public Tlv, public TlvInfo { 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 +class QueryOptionsSubTlv : public Tlv, public TlvInfo { 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 { 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(mSubTlvs + kTypeIdFlagsOffset), *aLinkMetricsFlags); - OT_ASSERT(typeIdFlagsCount <= kMaxTypeIdFlagsEnhAck); + count = TypeIdFlagsFromMetrics(reinterpret_cast(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 diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 48198697c..078b65b1d 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -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().HandleLinkMetricsReport(aMessage, metricsReportValueOffset, length, - aMessageInfo.GetPeerAddr()); + Get().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().HandleLinkMetricsManagementRequest(aMessage, *aNeighbor, status)); + SuccessOrExit(error = Get().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().HandleLinkMetricsManagementResponse(aMessage, aMessageInfo.GetPeerAddr()); + error = Get().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().HandleLinkProbe(aMessage, seriesId)); - aNeighbor->AggregateLinkMetrics(seriesId, LinkMetricsSeriesInfo::kSeriesTypeLinkProbe, aMessage.GetAverageLqi(), + SuccessOrExit(error = Get().HandleLinkProbe(aMessage, seriesId)); + aNeighbor->AggregateLinkMetrics(seriesId, LinkMetrics::SeriesInfo::kSeriesTypeLinkProbe, aMessage.GetAverageLqi(), aMessage.GetAverageRss()); exit: diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 109fb6922..1d4427223 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -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); diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 213612cc6..2879bda5e 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -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().AppendLinkMetricsReport(*message, *aRequestMessage, *neighbor)); + SuccessOrExit(error = Get().AppendReport(*message, *aRequestMessage, *neighbor)); break; #endif } diff --git a/src/core/thread/thread_netif.hpp b/src/core/thread/thread_netif.hpp index 017868ad3..14b0647c7 100644 --- a/src/core/thread/thread_netif.hpp +++ b/src/core/thread/thread_netif.hpp @@ -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 }; diff --git a/src/core/thread/topology.cpp b/src/core/thread/topology.cpp index 249b9d88a..d5acd473b 100644 --- a/src/core/thread/topology.cpp +++ b/src/core/thread/topology.cpp @@ -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().mLinkMetricsSeriesInfoPool.Free(*seriesInfo); + LinkMetrics::SeriesInfo *seriesInfo = mLinkMetricsSeriesInfoList.Pop(); + Get().mSeriesInfoPool.Free(*seriesInfo); } } #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE diff --git a/src/core/thread/topology.hpp b/src/core/thread/topology.hpp index 3267e9af5..ca5bfbe43 100644 --- a/src/core/thread/topology.hpp +++ b/src/core/thread/topology.hpp @@ -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 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 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 };