Skip to content

Commit 771c430

Browse files
authored
[netdiag] define AnswerTlvValue to allow reuse (openthread#12792)
This commit defines `AnswerTlvValue` to represent the value of an Answer TLV, allowing it to be reused across different modules, specifically `NetworkDiagnostic` and `HistoryTracker`. The `AnswerTlv` implementation is also updated to use the template-based `SimpleTlvInfo` pattern. This enables the use of generic `Tlv::Append<AnswerTlv>()` and `Tlv::Find<AnswerTlv>()` methods, which improves type safety and reduces manual TLV handling.
1 parent 9bb7e37 commit 771c430

8 files changed

Lines changed: 52 additions & 87 deletions

src/core/thread/network_diagnostic.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ void Server::SendAnswer(const Ip6::Address &aDestination, const Message &aReques
511511
{
512512
Error error = kErrorNone;
513513
Coap::Message *answer = nullptr;
514-
AnswerTlv answerTlv;
514+
AnswerTlvValue answerTlvValue;
515515
uint16_t queryId;
516516

517517
answer = Get<Tmf::Agent>().AllocateAndInitConfirmablePostMessage(kUriDiagnosticGetAnswer);
@@ -526,8 +526,8 @@ void Server::SendAnswer(const Ip6::Address &aDestination, const Message &aReques
526526

527527
SuccessOrExit(error = AppendRequestedTlvs(aRequest, *answer));
528528

529-
answerTlv.Init(0, AnswerTlv::kIsLast);
530-
SuccessOrExit(answer->Append(answerTlv));
529+
answerTlvValue.Init(0, AnswerTlvValue::kIsLast);
530+
SuccessOrExit(error = Tlv::Append<AnswerTlv>(*answer, answerTlvValue));
531531

532532
error = Get<Tmf::Agent>().SendMessageAllowMulticastLoop(*answer, aDestination);
533533

@@ -572,13 +572,13 @@ bool Server::IsLastAnswer(const Coap::Message &aAnswer) const
572572
// Indicates whether `aAnswer` is the last one associated with
573573
// the same query.
574574

575-
bool isLast = true;
576-
AnswerTlv answerTlv;
575+
bool isLast = true;
576+
AnswerTlvValue answerTlvValue;
577577

578578
// If there is no Answer TLV, we assume it is the last answer.
579579

580-
SuccessOrExit(Tlv::FindTlv(aAnswer, answerTlv));
581-
isLast = answerTlv.IsLast();
580+
SuccessOrExit(Tlv::Find<AnswerTlv>(aAnswer, answerTlvValue));
581+
isLast = answerTlvValue.IsLast();
582582

583583
exit:
584584
return isLast;
@@ -608,7 +608,7 @@ void Server::PrepareAndSendAnswers(const Ip6::Address &aDestination, const Messa
608608
AnswerInfo info;
609609
uint8_t tlvType;
610610
TlvTypeListIterator iterator;
611-
AnswerTlv answerTlv;
611+
AnswerTlvValue answerTlvValue;
612612

613613
if (Tlv::Find<QueryIdTlv>(aRequest, info.mQueryId) == kErrorNone)
614614
{
@@ -642,8 +642,8 @@ void Server::PrepareAndSendAnswers(const Ip6::Address &aDestination, const Messa
642642
SuccessOrExit(error = CheckAnswerLength(answer, info));
643643
}
644644

645-
answerTlv.Init(info.mAnswerIndex, AnswerTlv::kIsLast);
646-
SuccessOrExit(error = answer->Append(answerTlv));
645+
answerTlvValue.Init(info.mAnswerIndex, AnswerTlvValue::kIsLast);
646+
SuccessOrExit(error = Tlv::Append<AnswerTlv>(*answer, answerTlvValue));
647647

648648
SendNextAnswer(*info.mFirstAnswer, aDestination);
649649

@@ -662,13 +662,13 @@ Error Server::CheckAnswerLength(Coap::Message *&aAnswer, AnswerInfo &aInfo)
662662
// message. In this case, it will also allocate a new answer
663663
// message.
664664

665-
Error error = kErrorNone;
666-
AnswerTlv answerTlv;
665+
Error error = kErrorNone;
666+
AnswerTlvValue answerTlvValue;
667667

668668
VerifyOrExit(aAnswer->GetLength() >= kAnswerMessageLengthThreshold);
669669

670-
answerTlv.Init(aInfo.mAnswerIndex++, AnswerTlv::kMoreToFollow);
671-
SuccessOrExit(error = aAnswer->Append(answerTlv));
670+
answerTlvValue.Init(aInfo.mAnswerIndex++, AnswerTlvValue::kMoreToFollow);
671+
SuccessOrExit(error = Tlv::Append<AnswerTlv>(*aAnswer, answerTlvValue));
672672

673673
error = AllocateAnswer(aAnswer, aInfo);
674674

src/core/thread/network_diagnostic_tlvs.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,13 +197,10 @@ void RouterNeighborTlv::InitFrom(const Router &aRouter)
197197
#endif // OPENTHREAD_FTD
198198

199199
//---------------------------------------------------------------------------------------------------------------------
200-
// AnswerTlv
200+
// AnswerTlvValue
201201

202-
void AnswerTlv::Init(uint16_t aIndex, IsLastFlag aIsLastFlag)
202+
void AnswerTlvValue::Init(uint16_t aIndex, IsLastFlag aIsLastFlag)
203203
{
204-
SetType(kAnswer);
205-
SetLength(sizeof(*this) - sizeof(Tlv));
206-
207204
SetFlagsIndex((aIndex & kIndexMask) | (aIsLastFlag == kIsLast ? kIsLastFlag : 0));
208205
}
209206

src/core/thread/network_diagnostic_tlvs.hpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -802,10 +802,10 @@ class EnhancedRouteTlvEntry
802802
} OT_TOOL_PACKED_END;
803803

804804
/**
805-
* Implements Answer TLV generation and parsing.
805+
* Represents an Answer TLV value.
806806
*/
807807
OT_TOOL_PACKED_BEGIN
808-
class AnswerTlv : public Tlv, public TlvInfo<Tlv::kAnswer>
808+
class AnswerTlvValue
809809
{
810810
public:
811811
enum IsLastFlag : uint8_t
@@ -815,7 +815,7 @@ class AnswerTlv : public Tlv, public TlvInfo<Tlv::kAnswer>
815815
};
816816

817817
/**
818-
* Initializes the TLV.
818+
* Initializes the TLV value.
819819
*
820820
* @param[in] aIndex The index value.
821821
* @param[in] aIsLastFlag Indicates the `IsLastFlag` value.
@@ -847,6 +847,11 @@ class AnswerTlv : public Tlv, public TlvInfo<Tlv::kAnswer>
847847
uint16_t mFlagsIndex;
848848
} OT_TOOL_PACKED_END;
849849

850+
/**
851+
* Defines Answer TLV constants and types.
852+
*/
853+
typedef SimpleTlvInfo<Tlv::kAnswer, AnswerTlvValue> AnswerTlv;
854+
850855
/**
851856
* Represents the MLE Counters.
852857
*/

src/core/utils/history_tracker_client.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ template <> void Client::HandleTmf<kUriHistoryAnswer>(Coap::Msg &aMsg)
133133

134134
Error Client::ProcessAnswer(const Coap::Msg &aMsg)
135135
{
136-
Error error = kErrorFailed;
137-
AnswerTlv answerTlv;
138-
uint16_t queryId;
136+
Error error = kErrorFailed;
137+
AnswerTlvValue answerTlvValue;
138+
uint16_t queryId;
139139

140140
VerifyOrExit(mActive);
141141
VerifyOrExit(Get<Mle::Mle>().IsRoutingLocator(aMsg.mMessageInfo.GetPeerAddr()));
@@ -144,9 +144,9 @@ Error Client::ProcessAnswer(const Coap::Msg &aMsg)
144144
SuccessOrExit(Tlv::Find<QueryIdTlv>(aMsg.mMessage, queryId));
145145
VerifyOrExit(queryId == mQueryId);
146146

147-
SuccessOrExit(Tlv::FindTlv(aMsg.mMessage, answerTlv));
147+
SuccessOrExit(Tlv::Find<AnswerTlv>(aMsg.mMessage, answerTlvValue));
148148

149-
if (answerTlv.GetIndex() != mAnswerIndex)
149+
if (answerTlvValue.GetIndex() != mAnswerIndex)
150150
{
151151
Finalize(kErrorResponseTimeout);
152152
ExitNow();

src/core/utils/history_tracker_server.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,13 @@ bool Server::IsLastAnswer(const Coap::Message &aAnswer) const
9393
// Indicates whether `aAnswer` is the last one associated with
9494
// the same query.
9595

96-
bool isLast = true;
97-
AnswerTlv answerTlv;
96+
bool isLast = true;
97+
AnswerTlvValue answerTlvValue;
9898

9999
// If there is no Answer TLV, we assume it is the last answer.
100100

101-
SuccessOrExit(Tlv::FindTlv(aAnswer, answerTlv));
102-
isLast = answerTlv.IsLast();
101+
SuccessOrExit(Tlv::Find<AnswerTlv>(aAnswer, answerTlvValue));
102+
isLast = answerTlvValue.IsLast();
103103

104104
exit:
105105
return isLast;
@@ -130,7 +130,7 @@ void Server::PrepareAndSendAnswers(const Ip6::Address &aDestination, const Messa
130130
OffsetRange offsetRange;
131131
Tlv::Info tlvInfo;
132132
RequestTlv requestTlv;
133-
AnswerTlv answerTlv;
133+
AnswerTlvValue answerTlvValue;
134134

135135
if (Tlv::Find<QueryIdTlv>(aRequest, info.mQueryId) == kErrorNone)
136136
{
@@ -171,8 +171,8 @@ void Server::PrepareAndSendAnswers(const Ip6::Address &aDestination, const Messa
171171
}
172172
}
173173

174-
answerTlv.Init(info.mAnswerIndex, /* aIsLast */ true);
175-
SuccessOrExit(error = answer->Append(answerTlv));
174+
answerTlvValue.Init(info.mAnswerIndex, AnswerTlvValue::kIsLast);
175+
SuccessOrExit(error = Tlv::Append<AnswerTlv>(*answer, answerTlvValue));
176176

177177
SendNextAnswer(*info.mFirstAnswer, aDestination);
178178

@@ -190,13 +190,13 @@ Error Server::CheckAnswerLength(Coap::Message *&aAnswer, AnswerInfo &aInfo)
190190
// appending an Answer TLV with the current index to the message.
191191
// In this case, it will also allocate a new answer message.
192192

193-
Error error = kErrorNone;
194-
AnswerTlv answerTlv;
193+
Error error = kErrorNone;
194+
AnswerTlvValue answerTlvValue;
195195

196196
VerifyOrExit(aAnswer->GetLength() >= kAnswerMessageLengthThreshold);
197197

198-
answerTlv.Init(aInfo.mAnswerIndex++, /* aIsLast */ false);
199-
SuccessOrExit(error = aAnswer->Append(answerTlv));
198+
answerTlvValue.Init(aInfo.mAnswerIndex++, AnswerTlvValue::kMoreToFollow);
199+
SuccessOrExit(error = Tlv::Append<AnswerTlv>(*aAnswer, answerTlvValue));
200200

201201
error = AllocateAnswer(aAnswer, aInfo);
202202

src/core/utils/history_tracker_tlvs.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,6 @@
3838
namespace ot {
3939
namespace HistoryTracker {
4040

41-
void AnswerTlv::Init(uint16_t aIndex, bool aIsLast)
42-
{
43-
SetType(kAnswer);
44-
SetLength(sizeof(*this) - sizeof(Tlv));
45-
46-
SetFlagsIndex((aIndex & kIndexMask) | (aIsLast ? kIsLastFlag : 0));
47-
}
48-
4941
void RequestTlv::Init(uint8_t aTlvType, uint16_t aNumEntries, uint32_t aMaxEntryAge)
5042
{
5143
SetType(kRequest);

src/core/utils/history_tracker_tlvs.hpp

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
#include "common/encoding.hpp"
4444
#include "common/tlvs.hpp"
45+
#include "thread/network_diagnostic_tlvs.hpp"
4546
#include "utils/history_tracker.hpp"
4647

4748
namespace ot {
@@ -72,44 +73,14 @@ class Tlv : public ot::Tlv
7273
typedef UintTlvInfo<Tlv::kQueryId, uint16_t> QueryIdTlv;
7374

7475
/**
75-
* Implements Answer TLV generation and parsing.
76+
* Represents an Answer TLV value.
7677
*/
77-
OT_TOOL_PACKED_BEGIN
78-
class AnswerTlv : public Tlv, public TlvInfo<Tlv::kAnswer>
79-
{
80-
public:
81-
/**
82-
* Initializes the TLV.
83-
*
84-
* @param[in] aIndex The index value.
85-
* @param[in] aIsLast The "IsLast" flag value.
86-
*/
87-
void Init(uint16_t aIndex, bool aIsLast);
88-
89-
/**
90-
* Indicates whether or not the "IsLast" flag is set
91-
*
92-
* @retval TRUE "IsLast" flag is set (this is the last answer for this query).
93-
* @retval FALSE "IsLast" flag is not set (more answer messages are expected for this query).
94-
*/
95-
bool IsLast(void) const { return GetFlagsIndex() & kIsLastFlag; }
78+
typedef NetworkDiagnostic::AnswerTlvValue AnswerTlvValue;
9679

97-
/**
98-
* Gets the index.
99-
*
100-
* @returns The index.
101-
*/
102-
uint16_t GetIndex(void) const { return GetFlagsIndex() & kIndexMask; }
103-
104-
private:
105-
static constexpr uint16_t kIsLastFlag = 1 << 15;
106-
static constexpr uint16_t kIndexMask = 0x7fff;
107-
108-
uint16_t GetFlagsIndex(void) const { return BigEndian::HostSwap16(mFlagsIndex); }
109-
void SetFlagsIndex(uint16_t aFlagsIndex) { mFlagsIndex = BigEndian::HostSwap16(aFlagsIndex); }
110-
111-
uint16_t mFlagsIndex;
112-
} OT_TOOL_PACKED_END;
80+
/**
81+
* Defines Answer TLV constants and types.
82+
*/
83+
typedef SimpleTlvInfo<Tlv::kAnswer, AnswerTlvValue> AnswerTlv;
11384

11485
/**
11586
* Implements Request TLV generation and parsing.

src/core/utils/mesh_diag.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,19 +258,19 @@ Error MeshDiag::ProcessMessage(Coap::Message &aMessage, const Ip6::MessageInfo &
258258
// check whether it is from the intended sender and matches
259259
// the expected query ID and answer index.
260260

261-
Error error = kErrorFailed;
262-
AnswerTlv answerTlv;
263-
uint16_t queryId;
261+
Error error = kErrorFailed;
262+
AnswerTlvValue answerTlvValue;
263+
uint16_t queryId;
264264

265265
VerifyOrExit(Get<Mle::Mle>().IsRoutingLocator(aMessageInfo.GetPeerAddr()));
266266
VerifyOrExit(aMessageInfo.GetPeerAddr().GetIid().GetLocator() == aSenderRloc16);
267267

268268
SuccessOrExit(Tlv::Find<QueryIdTlv>(aMessage, queryId));
269269
VerifyOrExit(queryId == mExpectedQueryId);
270270

271-
SuccessOrExit(Tlv::FindTlv(aMessage, answerTlv));
271+
SuccessOrExit(Tlv::Find<AnswerTlv>(aMessage, answerTlvValue));
272272

273-
if (answerTlv.GetIndex() != mExpectedAnswerIndex)
273+
if (answerTlvValue.GetIndex() != mExpectedAnswerIndex)
274274
{
275275
Finalize(kErrorResponseTimeout);
276276
ExitNow();

0 commit comments

Comments
 (0)