[tlv] introduce LeaderDataTlvValue to share TLV format (#12289)

This commit introduces `LeaderDataTlvValue` as a distinct type to
represent the content of a Leader Data TLV. This allows the same value
format to be shared between the MLE and Network Diagnostic modules.

Previously, `NetworkDiagnostic::LeaderDataTlv` inherited from
`Mle::LeaderDataTlv` to reuse the implementation of the value format.
This inheritance was semantically incorrect, as a Network Diagnostic
TLV is not a specialization of an MLE TLV. The new approach of using
a shared `LeaderDataTlvValue` type provides a cleaner and more
accurate design.

With this change, `LeaderDataTlv` in both modules is now defined as a
`SimpleTlvInfo` type. This enables replacing manual TLV manipulation
with the generic `Tlv::Append<T>()` and `Tlv::Find<T>()` helpers,
making the code at the call sites cleaner and less error-prone.
This commit is contained in:
Abtin Keshavarzian
2026-01-12 15:59:43 -08:00
committed by GitHub
parent a32e1f752e
commit 0c68f3ad8b
5 changed files with 47 additions and 73 deletions
+5 -11
View File
@@ -3558,15 +3558,10 @@ Error Mle::TxMessage::AppendAddress16Tlv(uint16_t aRloc16) { return Tlv::Append<
Error Mle::TxMessage::AppendLeaderDataTlv(void)
{
LeaderDataTlv leaderDataTlv;
Get<Mle>().mLeaderData.SetDataVersion(Get<NetworkData::Leader>().GetVersion(NetworkData::kFullSet));
Get<Mle>().mLeaderData.SetStableDataVersion(Get<NetworkData::Leader>().GetVersion(NetworkData::kStableSubset));
leaderDataTlv.Init();
leaderDataTlv.Set(Get<Mle>().mLeaderData);
return leaderDataTlv.AppendTo(*this);
return Tlv::Append<LeaderDataTlv>(*this, LeaderDataTlvValue(Get<Mle>().mLeaderData));
}
Error Mle::TxMessage::AppendNetworkDataTlv(NetworkData::Type aType)
@@ -4066,12 +4061,11 @@ exit:
Error Mle::RxMessage::ReadLeaderDataTlv(LeaderData &aLeaderData) const
{
Error error;
LeaderDataTlv leaderDataTlv;
Error error;
LeaderDataTlvValue tlvValue;
SuccessOrExit(error = Tlv::FindTlv(*this, leaderDataTlv));
VerifyOrExit(leaderDataTlv.IsValid(), error = kErrorParse);
leaderDataTlv.Get(aLeaderData);
SuccessOrExit(error = Tlv::Find<LeaderDataTlv>(*this, tlvValue));
tlvValue.Get(aLeaderData);
exit:
return error;
+18
View File
@@ -137,5 +137,23 @@ exit:
return isValid;
}
LeaderDataTlvValue::LeaderDataTlvValue(const LeaderData &aLeaderData)
: mPartitionId(BigEndian::HostSwap32(aLeaderData.GetPartitionId()))
, mWeighting(aLeaderData.GetWeighting())
, mDataVersion(aLeaderData.GetDataVersion(NetworkData::kFullSet))
, mStableDataVersion(aLeaderData.GetDataVersion(NetworkData::kStableSubset))
, mLeaderRouterId(aLeaderData.GetLeaderRouterId())
{
}
void LeaderDataTlvValue::Get(LeaderData &aLeaderData) const
{
aLeaderData.SetPartitionId(BigEndian::HostSwap32(mPartitionId));
aLeaderData.SetWeighting(mWeighting);
aLeaderData.SetDataVersion(mDataVersion);
aLeaderData.SetStableDataVersion(mStableDataVersion);
aLeaderData.SetLeaderRouterId(mLeaderRouterId);
}
} // namespace Mle
} // namespace ot
+14 -35
View File
@@ -584,56 +584,30 @@ private:
#endif // OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
/**
* Implements Leader Data TLV generation and parsing.
* Represents Leader Data TLV value.
*/
OT_TOOL_PACKED_BEGIN
class LeaderDataTlv : public Tlv, public TlvInfo<Tlv::kLeaderData>
class LeaderDataTlvValue
{
public:
/**
* Initializes the TLV.
* Default constructor.
*/
void Init(void)
{
SetType(kLeaderData);
SetLength(sizeof(*this) - sizeof(Tlv));
}
LeaderDataTlvValue(void) = default;
/**
* Indicates whether or not the TLV appears to be well-formed.
* Initializes the `LeaderDataTlvValue` from a given `LeaderData`.
*
* @retval TRUE If the TLV appears to be well-formed.
* @retval FALSE If the TLV does not appear to be well-formed.
* @param[in] aLeaderData The `LeaderData` info to use for initialization.
*/
bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); }
explicit LeaderDataTlvValue(const LeaderData &aLeaderData);
/**
* Gets the Leader Data info from TLV.
* Gets the Leader Data info from TLV value.
*
* @param[out] aLeaderData A reference to output Leader Data info.
*/
void Get(LeaderData &aLeaderData) const
{
aLeaderData.SetPartitionId(BigEndian::HostSwap32(mPartitionId));
aLeaderData.SetWeighting(mWeighting);
aLeaderData.SetDataVersion(mDataVersion);
aLeaderData.SetStableDataVersion(mStableDataVersion);
aLeaderData.SetLeaderRouterId(mLeaderRouterId);
}
/**
* Sets the Leader Data.
*
* @param[in] aLeaderData A Leader Data.
*/
void Set(const LeaderData &aLeaderData)
{
mPartitionId = BigEndian::HostSwap32(aLeaderData.GetPartitionId());
mWeighting = aLeaderData.GetWeighting();
mDataVersion = aLeaderData.GetDataVersion(NetworkData::kFullSet);
mStableDataVersion = aLeaderData.GetDataVersion(NetworkData::kStableSubset);
mLeaderRouterId = aLeaderData.GetLeaderRouterId();
}
void Get(LeaderData &aLeaderData) const;
private:
uint32_t mPartitionId;
@@ -643,6 +617,11 @@ private:
uint8_t mLeaderRouterId;
} OT_TOOL_PACKED_END;
/**
* Defines Leader Data TLV constants and types.
*/
typedef SimpleTlvInfo<Tlv::kLeaderData, LeaderDataTlvValue> LeaderDataTlv;
/**
* Implements Scan Mask TLV generation and parsing.
*/
+4 -12
View File
@@ -473,14 +473,8 @@ Error Server::AppendDiagTlv(uint8_t aTlvType, Message &aMessage)
break;
case Tlv::kLeaderData:
{
LeaderDataTlv tlv;
tlv.Init();
tlv.Set(Get<Mle::Mle>().GetLeaderData());
error = tlv.AppendTo(aMessage);
error = Tlv::Append<LeaderDataTlv>(aMessage, LeaderDataTlvValue(Get<Mle::Mle>().GetLeaderData()));
break;
}
case Tlv::kNetworkData:
error = Tlv::Append<NetworkDataTlv>(aMessage, Get<NetworkData::Leader>().GetBytes(),
@@ -1351,12 +1345,10 @@ Error Client::GetNextDiagTlv(const Coap::Message &aMessage, Iterator &aIterator,
case Tlv::kLeaderData:
{
LeaderDataTlv leaderDataTlv;
LeaderDataTlvValue tlvValue;
VerifyOrExit(!tlv.IsExtended(), error = kErrorParse);
SuccessOrExit(error = aMessage.Read(offset, leaderDataTlv));
VerifyOrExit(leaderDataTlv.IsValid(), error = kErrorParse);
leaderDataTlv.Get(AsCoreType(&aTlvInfo.mData.mLeaderData));
SuccessOrExit(error = Tlv::Read<LeaderDataTlv>(aMessage, offset, tlvValue));
tlvValue.Get(AsCoreType(&aTlvInfo.mData.mLeaderData));
break;
}
+6 -15
View File
@@ -336,23 +336,14 @@ public:
} OT_TOOL_PACKED_END;
/**
* Implements Leader Data TLV generation and parsing.
* Represents a Leader Data TLV value.
*/
OT_TOOL_PACKED_BEGIN
class LeaderDataTlv : public Mle::LeaderDataTlv
{
public:
static constexpr uint8_t kType = ot::NetworkDiagnostic::Tlv::kLeaderData; ///< The TLV Type value.
typedef Mle::LeaderDataTlvValue LeaderDataTlvValue;
/**
* Initializes the TLV.
*/
void Init(void)
{
Mle::LeaderDataTlv::Init();
ot::Tlv::SetType(kType);
}
} OT_TOOL_PACKED_END;
/**
* Defines Leader Data TLV constants and types.
*/
typedef SimpleTlvInfo<Tlv::kLeaderData, LeaderDataTlvValue> LeaderDataTlv;
/**
* Implements Mac Counters TLV generation and parsing.