[link-metrics] simplify sending MLE Mgmt Request (#8073)

This commit adds `FwdProbingRegSubTlv` which is used to simplify
`SendMgmtRequestForwardTrackingSeries()` implementation. Similarly
`EnhAckConfigSubTlv` is updated and used to simplify method
`SendMgmtRequestEnhAckProbing()`.
This commit is contained in:
Abtin Keshavarzian
2022-08-25 11:17:56 -07:00
committed by GitHub
parent cd83fc1477
commit 10c9a365f2
6 changed files with 133 additions and 70 deletions
+21 -29
View File
@@ -94,37 +94,28 @@ Error LinkMetrics::SendMgmtRequestForwardTrackingSeries(const Ip6::Address &
const SeriesFlags::Info &aSeriesFlags,
const Metrics * aMetrics)
{
Error error = kErrorNone;
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;
Neighbor * neighbor = GetNeighborFromLinkLocalAddr(aDestination);
Error error = kErrorNone;
Neighbor * neighbor = GetNeighborFromLinkLocalAddr(aDestination);
uint8_t typeIdCount = 0;
FwdProbingRegSubTlv fwdProbingSubTlv;
VerifyOrExit(neighbor != nullptr, error = kErrorUnknownNeighbor);
VerifyOrExit(neighbor->IsThreadVersion1p2OrHigher(), error = kErrorNotCapable);
// Directly transform `aMetrics` into TypeIdFlags and put them into `subTlvs`
if (aMetrics != nullptr)
{
typeIdFlagsCount =
TypeIdFlagsFromMetrics(reinterpret_cast<TypeIdFlags *>(subTlvs + typeIdFlagsOffset), *aMetrics);
}
VerifyOrExit(aSeriesId > kQueryIdSingleProbe, error = kErrorInvalidArgs);
fwdProbingSubTlv->SetType(SubTlv::kFwdProbingReg);
fwdProbingSubTlv.Init();
fwdProbingSubTlv.SetSeriesId(aSeriesId);
fwdProbingSubTlv.GetSeriesFlags().SetFrom(aSeriesFlags);
// SeriesId + SeriesFlags + typeIdFlagsCount * TypeIdFlags
fwdProbingSubTlv->SetLength(sizeof(uint8_t) * 2 + sizeof(TypeIdFlags) * typeIdFlagsCount);
if (aMetrics != nullptr)
{
typeIdCount = TypeIdFlagsFromMetrics(fwdProbingSubTlv.GetTypeIds(), *aMetrics);
}
memcpy(subTlvs + sizeof(Tlv), &aSeriesId, sizeof(aSeriesId));
fwdProbingSubTlv.SetLength(sizeof(aSeriesId) + sizeof(SeriesFlags) + typeIdCount * sizeof(TypeIdFlags));
seriesFlags->SetFrom(aSeriesFlags);
error = Get<Mle::MleRouter>().SendLinkMetricsManagementRequest(aDestination, subTlvs,
static_cast<uint8_t>(fwdProbingSubTlv->GetSize()));
error = Get<Mle::MleRouter>().SendLinkMetricsManagementRequest(aDestination, fwdProbingSubTlv);
exit:
LogDebg("SendMgmtRequestForwardTrackingSeries, error:%s, Series ID:%u", ErrorToString(error), aSeriesId);
@@ -135,10 +126,10 @@ Error LinkMetrics::SendMgmtRequestEnhAckProbing(const Ip6::Address &aDestination
const EnhAckFlags aEnhAckFlags,
const Metrics * aMetrics)
{
Error error = kErrorNone;
Error error = kErrorNone;
Neighbor * neighbor = GetNeighborFromLinkLocalAddr(aDestination);
uint8_t typeIdCount = 0;
EnhAckConfigSubTlv enhAckConfigSubTlv;
Mac::Address macAddress;
Neighbor * neighbor = GetNeighborFromLinkLocalAddr(aDestination);
VerifyOrExit(neighbor != nullptr, error = kErrorUnknownNeighbor);
VerifyOrExit(neighbor->IsThreadVersion1p2OrHigher(), error = kErrorNotCapable);
@@ -148,16 +139,17 @@ Error LinkMetrics::SendMgmtRequestEnhAckProbing(const Ip6::Address &aDestination
VerifyOrExit(aMetrics == nullptr, error = kErrorInvalidArgs);
}
enhAckConfigSubTlv.Init();
enhAckConfigSubTlv.SetEnhAckFlags(aEnhAckFlags);
if (aMetrics != nullptr)
{
enhAckConfigSubTlv.SetTypeIdFlags(*aMetrics);
typeIdCount = TypeIdFlagsFromMetrics(enhAckConfigSubTlv.GetTypeIds(), *aMetrics);
}
error = Get<Mle::MleRouter>().SendLinkMetricsManagementRequest(
aDestination, reinterpret_cast<const uint8_t *>(&enhAckConfigSubTlv),
static_cast<uint8_t>(enhAckConfigSubTlv.GetSize()));
enhAckConfigSubTlv.SetLength(EnhAckConfigSubTlv::kMinLength + typeIdCount * sizeof(TypeIdFlags));
error = Get<Mle::MleRouter>().SendLinkMetricsManagementRequest(aDestination, enhAckConfigSubTlv);
if (aMetrics != nullptr)
{
-2
View File
@@ -265,8 +265,6 @@ public:
void ProcessEnhAckIeData(const uint8_t *aData, uint8_t aLength, const Neighbor &aNeighbor);
private:
static constexpr uint8_t kMaxTypeIdFlags = 4;
// Max number of SeriesInfo that could be allocated by the pool.
static constexpr uint16_t kMaxSeriesSupported = OPENTHREAD_CONFIG_MLE_LINK_METRICS_MAX_SERIES_SUPPORTED;
+100 -27
View File
@@ -209,15 +209,86 @@ public:
} OT_TOOL_PACKED_END;
/**
* This class defines Link Metrics Forward Probing Registration Sub-TLV.
*
*/
OT_TOOL_PACKED_BEGIN
class FwdProbingRegSubTlv : public Tlv, public TlvInfo<SubTlv::kFwdProbingReg>
{
public:
static constexpr uint8_t kMinLength = sizeof(uint8_t) + sizeof(SeriesFlags); ///< Minimum expected TLV length
/**
* This method initializes the TLV.
*
*/
void Init(void)
{
SetType(SubTlv::kFwdProbingReg);
SetLength(kMinLength);
}
/**
* This method indicates whether or not the TLV appears to be well-formed.
*
* @retval true The TLV appears to be well-formed.
* @retval false The TLV does not appear to be well-formed.
*
*/
bool IsValid(void) const { return GetLength() >= kMinLength; }
/**
* This method gets the Forward Series ID value.
*
* @returns The Forward Series ID.
*
*/
uint8_t GetSeriesId(void) const { return mSeriesId; }
/**
* This method sets the Forward Series ID value.
*
* @param[in] aSeriesId The Forward Series ID.
*
*/
void SetSeriesId(uint8_t aSeriesId) { mSeriesId = aSeriesId; }
/**
* This method gets the Forward Series Flags.
*
* @returns The Forward Series Flags.
*
*/
SeriesFlags &GetSeriesFlags(void) { return mSeriesFlags; }
/**
* This method sets the Forward Series Flags.
*
* @param[in] aSeriesFlags The Forward Series Flags.
*
*/
void SetSeriesFlags(const SeriesFlags &aSeriesFlags) { mSeriesFlags = aSeriesFlags; }
/**
* This method gets the start of Type ID Flags array.
*
* @returns The start of Type ID Flags array. Array has `kMaxTypeIdFlags` max length.
*
*/
TypeIdFlags *GetTypeIds(void) { return mTypeIds; }
private:
uint8_t mSeriesId;
SeriesFlags mSeriesFlags;
TypeIdFlags mTypeIds[kMaxTypeIdFlags];
} OT_TOOL_PACKED_END;
OT_TOOL_PACKED_BEGIN
class EnhAckConfigSubTlv : public Tlv, public TlvInfo<SubTlv::kEnhAckConfig>
{
public:
/**
* Default constructor
*
*/
EnhAckConfigSubTlv(void) { Init(); }
static constexpr uint8_t kMinLength = sizeof(uint8_t); ///< Minimum TLV length (only `EnhAckFlags`).
/**
* This method initializes the TLV.
@@ -226,43 +297,45 @@ public:
void Init(void)
{
SetType(SubTlv::kEnhAckConfig);
SetLength(sizeof(EnhAckFlags));
SetLength(kMinLength);
}
/**
* This method indicates whether or not the TLV appears to be well-formed.
*
* @retval true The TLV appears to be well-formed.
* @retval false The TLV does not appear to be well-formed.
*
*/
bool IsValid(void) const { return GetLength() >= kMinLength; }
/**
* This method gets the Enhanced ACK Flags.
*
* @returns The Enhanced ACK Flags.
*
*/
uint8_t GetEnhAckFlags(void) const { return mEnhAckFlags; }
/**
* This method sets Enhanced ACK Flags.
*
* @param[in] aEnhAckFlags The value of Enhanced ACK Flags.
*
*/
void SetEnhAckFlags(EnhAckFlags aEnhAckFlags)
{
memcpy(mSubTlvs + kEnhAckFlagsOffset, &aEnhAckFlags, sizeof(aEnhAckFlags));
}
void SetEnhAckFlags(EnhAckFlags aEnhAckFlags) { mEnhAckFlags = aEnhAckFlags; }
/**
* This method sets Type ID Flags.
* This method gets the start of Type ID Flags array.
*
* @param[in] aMetrics A metrics flags to indicate the Type ID Flags.
* @returns The start of Type ID Flags array. Array has `kMaxTypeIdFlags` max length.
*
*/
void SetTypeIdFlags(const Metrics &aMetrics)
{
uint8_t count;
count = TypeIdFlagsFromMetrics(reinterpret_cast<TypeIdFlags *>(mSubTlvs + kTypeIdFlagsOffset), aMetrics);
OT_ASSERT(count <= kMaxTypeIdFlagsEnhAck);
SetLength(sizeof(EnhAckFlags) + sizeof(TypeIdFlags) * count);
}
TypeIdFlags *GetTypeIds(void) { return mTypeIds; }
private:
static constexpr uint8_t kMaxTypeIdFlagsEnhAck = 3;
static constexpr uint8_t kEnhAckFlagsOffset = 0;
static constexpr uint16_t kTypeIdFlagsOffset = sizeof(TypeIdFlags);
uint8_t mSubTlvs[sizeof(EnhAckFlags) + sizeof(TypeIdFlags) * kMaxTypeIdFlagsEnhAck];
uint8_t mEnhAckFlags;
TypeIdFlags mTypeIds[kMaxTypeIdFlags];
} OT_TOOL_PACKED_END;
} // namespace LinkMetrics
+2
View File
@@ -445,6 +445,8 @@ enum EnhAckFlags : uint8_t
kEnhAckRegister = OT_LINK_METRICS_ENH_ACK_REGISTER, ///< Register.
};
constexpr uint8_t kMaxTypeIdFlags = 4; ///< Maximum number of TypeIdFlags in a `Metrics`
uint8_t TypeIdFlagsFromMetrics(TypeIdFlags aTypeIdFlags[], const Metrics &aMetrics);
/**
+8 -9
View File
@@ -4248,22 +4248,21 @@ const char *Mle::ReattachStateToString(ReattachState aState)
// LCOV_EXCL_STOP
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
Error Mle::SendLinkMetricsManagementRequest(const Ip6::Address &aDestination, const uint8_t *aSubTlvs, uint8_t aLength)
Error Mle::SendLinkMetricsManagementRequest(const Ip6::Address &aDestination, const ot::Tlv &aSubTlv)
{
Error error = kErrorNone;
TxMessage *message;
Error error = kErrorNone;
TxMessage *message = NewMleMessage(kCommandLinkMetricsManagementRequest);
Tlv tlv;
VerifyOrExit((message = NewMleMessage(kCommandLinkMetricsManagementRequest)) != nullptr, error = kErrorNoBufs);
VerifyOrExit(message != nullptr, error = kErrorNoBufs);
// Link Metrics Management TLV
tlv.SetType(Tlv::kLinkMetricsManagement);
tlv.SetLength(aLength);
tlv.SetLength(static_cast<uint8_t>(aSubTlv.GetSize()));
SuccessOrExit(error = message->AppendBytes(&tlv, sizeof(tlv)));
SuccessOrExit(error = message->AppendBytes(aSubTlvs, aLength));
SuccessOrExit(error = message->Append(tlv));
SuccessOrExit(error = aSubTlv.AppendTo(*message));
SuccessOrExit(error = message->SendTo(aDestination));
error = message->SendTo(aDestination);
exit:
FreeMessageOnError(message, error);
+2 -3
View File
@@ -1650,14 +1650,13 @@ protected:
* This method sends a Link Metrics Management Request message.
*
* @param[in] aDestination A reference to the IPv6 address of the destination.
* @param[in] aSubTlvs A pointer to the buffer of the sub-TLVs in the message.
* @param[in] aLength The overall length of @p aSubTlvs.
* @param[in] aSubTlv A reference to the sub-TLV to include.
*
* @retval kErrorNone Successfully sent a Link Metrics Management Request.
* @retval kErrorNoBufs Insufficient buffers to generate the MLE Link Metrics Management Request message.
*
*/
Error SendLinkMetricsManagementRequest(const Ip6::Address &aDestination, const uint8_t *aSubTlvs, uint8_t aLength);
Error SendLinkMetricsManagementRequest(const Ip6::Address &aDestination, const ot::Tlv &aSubTlv);
/**
* This method sends an MLE Link Probe message.