mirror of
https://github.com/espressif/openthread.git
synced 2026-08-15 07:07:46 +00:00
[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:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user