mirror of
https://github.com/espressif/openthread.git
synced 2026-08-09 04:07:47 +00:00
[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:
+5
-11
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user