[network-diag] introduce RouterNeighborTlv (#12827)

This commit updates `RouterNeighborTlv` to follow the `SimpleTlvInfo`
pattern, separating the TLV value structure from its type/length
header.

Specifically, it defines `RouterNeighborTlvValue` to hold the data
fields for a router neighbor's diagnostic information, while
`RouterNeighborTlv` is redefined as a `SimpleTlvInfo` using the value
structure and the `kRouterNeighbor` type.

This allows the use of generic `Tlv::Append<RouterNeighborTlv>()` and
`tlvInfo.Read<RouterNeighborTlv>()` methods,  which are generally
safer and allow value type reuse.

The `NetworkDiagnostic`  and `MeshDiag` module are updated to
utilize these new methods.
This commit is contained in:
Abtin Keshavarzian
2026-04-04 01:17:03 -05:00
committed by GitHub
parent aec6b5d795
commit 9f28df1e30
5 changed files with 38 additions and 37 deletions
+8 -8
View File
@@ -162,15 +162,15 @@ exit:
Error Server::AppendRouterNeighborTlvs(Message &aMessage)
{
Error error = kErrorNone;
RouterNeighborTlv neighborTlv;
Error error = kErrorNone;
RouterNeighborTlvValue neighborTlvValue;
for (Router &router : Get<RouterTable>())
{
if (router.IsStateValid())
{
neighborTlv.InitFrom(router);
SuccessOrExit(error = neighborTlv.AppendTo(aMessage));
neighborTlvValue.InitFrom(router);
SuccessOrExit(error = Tlv::Append<RouterNeighborTlv>(aMessage, neighborTlvValue));
}
}
@@ -755,8 +755,8 @@ exit:
Error Server::AppendRouterNeighborTlvs(Coap::Message *&aAnswer, AnswerInfo &aInfo)
{
Error error = kErrorNone;
RouterNeighborTlv neighborTlv;
Error error = kErrorNone;
RouterNeighborTlvValue neighborTlvValue;
for (Router &router : Get<RouterTable>())
{
@@ -765,9 +765,9 @@ Error Server::AppendRouterNeighborTlvs(Coap::Message *&aAnswer, AnswerInfo &aInf
continue;
}
neighborTlv.InitFrom(router);
neighborTlvValue.InitFrom(router);
SuccessOrExit(error = neighborTlv.AppendTo(*aAnswer));
SuccessOrExit(error = Tlv::Append<RouterNeighborTlv>(*aAnswer, neighborTlvValue));
SuccessOrExit(error = CheckAnswerLength(aAnswer, aInfo));
}
+2 -5
View File
@@ -170,15 +170,12 @@ void ChildTlvValue::InitFrom(const Child &aChild)
}
//---------------------------------------------------------------------------------------------------------------------
// RouterNeighborTlv
// RouterNeighborTlvValue
void RouterNeighborTlv::InitFrom(const Router &aRouter)
void RouterNeighborTlvValue::InitFrom(const Router &aRouter)
{
Clear();
SetType(kRouterNeighbor);
SetLength(sizeof(*this) - sizeof(Tlv));
mFlags |= kFlagsTrackErrRate;
mRloc16 = BigEndian::HostSwap16(aRouter.GetRloc16());
mExtAddress = aRouter.GetExtAddress();
+7 -2
View File
@@ -647,10 +647,10 @@ private:
} OT_TOOL_PACKED_END;
/**
* Implements Router Neighbor TLV generation and parsing.
* Implements Router Neighbor TLV Value generation and parsing.
*/
OT_TOOL_PACKED_BEGIN
class RouterNeighborTlv : public Tlv, public TlvInfo<Tlv::kRouterNeighbor>, public Clearable<RouterNeighborTlv>
class RouterNeighborTlvValue : public Clearable<RouterNeighborTlvValue>
{
public:
static constexpr uint8_t kFlagsTrackErrRate = 1 << 7; ///< Supports tracking error rates.
@@ -751,6 +751,11 @@ private:
uint16_t mMessageErrorRate; // (IPv6) msg error rate (0x0000->0%, 0xffff->100%)
} OT_TOOL_PACKED_END;
/**
* Defines Router Neighbor TLV constants and types.
*/
typedef SimpleTlvInfo<Tlv::kRouterNeighbor, RouterNeighborTlvValue> RouterNeighborTlv;
#endif // OPENTHREAD_FTD
/**
+20 -21
View File
@@ -325,21 +325,20 @@ exit:
bool MeshDiag::ProcessRouterNeighborTableAnswer(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
bool didProcess = false;
RouterNeighborTlv neighborTlv;
RouterNeighborEntry entry;
uint16_t offset;
bool didProcess = false;
Tlv::Info tlvInfo;
RouterNeighborTlvValue neighborTlvValue;
RouterNeighborEntry entry;
SuccessOrExit(ProcessMessage(aMessage, aMessageInfo, mQueryRouterNeighborTable.mRouterRloc16));
while (true)
{
SuccessOrExit(Tlv::FindTlv(aMessage, neighborTlv, offset));
VerifyOrExit(!neighborTlv.IsExtended());
SuccessOrExit(tlvInfo.FindIn(aMessage, RouterNeighborTlv::kType));
didProcess = true;
if (neighborTlv.GetLength() == 0)
if (tlvInfo.GetLength() == 0)
{
// We reached end of the list.
mState = kStateIdle;
@@ -348,16 +347,16 @@ bool MeshDiag::ProcessRouterNeighborTableAnswer(Coap::Message &aMessage, const I
ExitNow();
}
VerifyOrExit(neighborTlv.GetLength() >= sizeof(RouterNeighborTlv) - sizeof(Tlv));
SuccessOrExit(tlvInfo.Read<RouterNeighborTlv>(aMessage, neighborTlvValue));
entry.SetFrom(neighborTlv);
entry.SetFrom(neighborTlvValue);
mQueryRouterNeighborTable.mCallback.InvokeIfSet(kErrorPending, &entry);
// Make sure query operation is not canceled from the
// callback.
VerifyOrExit(mState == kStateQueryRouterNeighborTable);
aMessage.SetOffset(static_cast<uint16_t>(offset + neighborTlv.GetSize()));
aMessage.SetOffset(tlvInfo.GetTlvOffsetRange().GetEndOffset());
}
exit:
@@ -607,18 +606,18 @@ void MeshDiag::ChildEntry::SetFrom(const ChildTlvValue &aChildTlvValue)
//---------------------------------------------------------------------------------------------------------------------
// MeshDiag::RouterNeighborEntry
void MeshDiag::RouterNeighborEntry::SetFrom(const RouterNeighborTlv &aTlv)
void MeshDiag::RouterNeighborEntry::SetFrom(const RouterNeighborTlvValue &aTlvValue)
{
mSupportsErrRate = (aTlv.GetFlags() & RouterNeighborTlv::kFlagsTrackErrRate);
mRloc16 = aTlv.GetRloc16();
mExtAddress = aTlv.GetExtAddress();
mVersion = aTlv.GetVersion();
mConnectionTime = aTlv.GetConnectionTime();
mLinkMargin = aTlv.GetLinkMargin();
mAverageRssi = aTlv.GetAverageRssi();
mLastRssi = aTlv.GetLastRssi();
mFrameErrorRate = aTlv.GetFrameErrorRate();
mMessageErrorRate = aTlv.GetMessageErrorRate();
mSupportsErrRate = (aTlvValue.GetFlags() & RouterNeighborTlvValue::kFlagsTrackErrRate);
mRloc16 = aTlvValue.GetRloc16();
mExtAddress = aTlvValue.GetExtAddress();
mVersion = aTlvValue.GetVersion();
mConnectionTime = aTlvValue.GetConnectionTime();
mLinkMargin = aTlvValue.GetLinkMargin();
mAverageRssi = aTlvValue.GetAverageRssi();
mLastRssi = aTlvValue.GetLastRssi();
mFrameErrorRate = aTlvValue.GetFrameErrorRate();
mMessageErrorRate = aTlvValue.GetMessageErrorRate();
}
} // namespace Utils
+1 -1
View File
@@ -294,7 +294,7 @@ private:
friend class MeshDiag;
private:
void SetFrom(const NetworkDiagnostic::RouterNeighborTlv &aTlv);
void SetFrom(const NetworkDiagnostic::RouterNeighborTlvValue &aTlvValue);
};
Error SendQuery(uint16_t aRloc16, const uint8_t *aTlvs, uint8_t aTlvsLength);