mirror of
https://github.com/espressif/openthread.git
synced 2026-08-16 23:57:46 +00:00
[network-diag] introduce TlvTypeListIterator (#12672)
This commit introduces a new `TlvTypeListIterator` helper class in the network diagnostic `Server` to simplify the parsing of Type List TLVs. This iterator handles deduplication of requested TLV types using a `BitSet` and centralizes the offset management and iteration logic. The iterator is now used in `AppendRequestedTlvs()`, `AppendRequestedTlvsForTcat()`, `PrepareAndSendAnswers()`, and `HandleTmf<kUriDiagnosticReset>()`, replacing redundant manual iteration and deduplication code. Additionally, the `TypeListTlv` definition is simplified to a `typedef` of `TlvInfo`, as the dedicated class structure is no longer needed.
This commit is contained in:
@@ -296,28 +296,14 @@ exit:
|
|||||||
|
|
||||||
Error Server::AppendRequestedTlvs(const Message &aRequest, Message &aResponse)
|
Error Server::AppendRequestedTlvs(const Message &aRequest, Message &aResponse)
|
||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
OffsetRange offsetRange;
|
TlvTypeListIterator iterator;
|
||||||
TlvTypeBitSet processedTlvs;
|
uint8_t tlvType;
|
||||||
|
|
||||||
processedTlvs.Clear();
|
SuccessOrExit(error = iterator.InitForTypeListTlv(aRequest));
|
||||||
|
|
||||||
SuccessOrExit(error = Tlv::FindTlvValueOffsetRange(aRequest, Tlv::kTypeList, offsetRange));
|
while (iterator.ReadNextTlvType(tlvType) == kErrorNone)
|
||||||
|
|
||||||
while (!offsetRange.IsEmpty())
|
|
||||||
{
|
{
|
||||||
uint8_t tlvType;
|
|
||||||
|
|
||||||
SuccessOrExit(error = aRequest.Read(offsetRange, tlvType));
|
|
||||||
offsetRange.AdvanceOffset(sizeof(tlvType));
|
|
||||||
|
|
||||||
if (processedTlvs.Has(tlvType))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
processedTlvs.Add(tlvType);
|
|
||||||
|
|
||||||
SuccessOrExit(error = AppendDiagTlv(tlvType, aResponse));
|
SuccessOrExit(error = AppendDiagTlv(tlvType, aResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,25 +314,14 @@ exit:
|
|||||||
#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
|
#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
|
||||||
Error Server::AppendRequestedTlvsForTcat(const Message &aRequest, Message &aResponse, OffsetRange &aOffsetRange)
|
Error Server::AppendRequestedTlvsForTcat(const Message &aRequest, Message &aResponse, OffsetRange &aOffsetRange)
|
||||||
{
|
{
|
||||||
Error error = kErrorNone;
|
Error error = kErrorNone;
|
||||||
TlvTypeBitSet processedTlvs;
|
TlvTypeListIterator iterator;
|
||||||
|
uint8_t tlvType;
|
||||||
|
|
||||||
processedTlvs.Clear();
|
iterator.Init(aRequest, aOffsetRange);
|
||||||
|
|
||||||
while (!aOffsetRange.IsEmpty())
|
while (iterator.ReadNextTlvType(tlvType) == kErrorNone)
|
||||||
{
|
{
|
||||||
uint8_t tlvType;
|
|
||||||
|
|
||||||
SuccessOrExit(error = aRequest.Read(aOffsetRange, tlvType));
|
|
||||||
aOffsetRange.AdvanceOffset(sizeof(uint8_t));
|
|
||||||
|
|
||||||
if (processedTlvs.Has(tlvType))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
processedTlvs.Add(tlvType);
|
|
||||||
|
|
||||||
#if OPENTHREAD_FTD
|
#if OPENTHREAD_FTD
|
||||||
switch (tlvType)
|
switch (tlvType)
|
||||||
{
|
{
|
||||||
@@ -669,11 +644,12 @@ void Server::FreeAllRelatedAnswers(Coap::Message &aFirstAnswer)
|
|||||||
|
|
||||||
void Server::PrepareAndSendAnswers(const Ip6::Address &aDestination, const Message &aRequest)
|
void Server::PrepareAndSendAnswers(const Ip6::Address &aDestination, const Message &aRequest)
|
||||||
{
|
{
|
||||||
Coap::Message *answer;
|
Coap::Message *answer;
|
||||||
Error error;
|
Error error;
|
||||||
AnswerInfo info;
|
AnswerInfo info;
|
||||||
OffsetRange offsetRange;
|
uint8_t tlvType;
|
||||||
AnswerTlv answerTlv;
|
TlvTypeListIterator iterator;
|
||||||
|
AnswerTlv answerTlv;
|
||||||
|
|
||||||
if (Tlv::Find<QueryIdTlv>(aRequest, info.mQueryId) == kErrorNone)
|
if (Tlv::Find<QueryIdTlv>(aRequest, info.mQueryId) == kErrorNone)
|
||||||
{
|
{
|
||||||
@@ -684,15 +660,10 @@ void Server::PrepareAndSendAnswers(const Ip6::Address &aDestination, const Messa
|
|||||||
|
|
||||||
SuccessOrExit(error = AllocateAnswer(answer, info));
|
SuccessOrExit(error = AllocateAnswer(answer, info));
|
||||||
|
|
||||||
SuccessOrExit(error = Tlv::FindTlvValueOffsetRange(aRequest, Tlv::kTypeList, offsetRange));
|
SuccessOrExit(error = iterator.InitForTypeListTlv(aRequest));
|
||||||
|
|
||||||
while (!offsetRange.IsEmpty())
|
while (iterator.ReadNextTlvType(tlvType) == kErrorNone)
|
||||||
{
|
{
|
||||||
uint8_t tlvType;
|
|
||||||
|
|
||||||
SuccessOrExit(error = aRequest.Read(offsetRange, tlvType));
|
|
||||||
offsetRange.AdvanceOffset(sizeof(tlvType));
|
|
||||||
|
|
||||||
switch (tlvType)
|
switch (tlvType)
|
||||||
{
|
{
|
||||||
case ChildTlv::kType:
|
case ChildTlv::kType:
|
||||||
@@ -924,26 +895,19 @@ exit:
|
|||||||
|
|
||||||
template <> void Server::HandleTmf<kUriDiagnosticReset>(Coap::Msg &aMsg)
|
template <> void Server::HandleTmf<kUriDiagnosticReset>(Coap::Msg &aMsg)
|
||||||
{
|
{
|
||||||
uint16_t offset = 0;
|
TlvTypeListIterator iterator;
|
||||||
uint8_t type;
|
uint8_t tlvType;
|
||||||
Tlv tlv;
|
|
||||||
|
|
||||||
VerifyOrExit(aMsg.IsConfirmable());
|
VerifyOrExit(aMsg.IsConfirmable());
|
||||||
|
|
||||||
LogInfo("Received %s from %s", UriToString<kUriDiagnosticReset>(),
|
LogInfo("Received %s from %s", UriToString<kUriDiagnosticReset>(),
|
||||||
aMsg.mMessageInfo.GetPeerAddr().ToString().AsCString());
|
aMsg.mMessageInfo.GetPeerAddr().ToString().AsCString());
|
||||||
|
|
||||||
SuccessOrExit(aMsg.mMessage.Read(aMsg.mMessage.GetOffset(), tlv));
|
SuccessOrExit(iterator.InitForTypeListTlv(aMsg.mMessage));
|
||||||
|
|
||||||
VerifyOrExit(tlv.GetType() == Tlv::kTypeList);
|
while (iterator.ReadNextTlvType(tlvType) == kErrorNone)
|
||||||
|
|
||||||
offset = aMsg.mMessage.GetOffset() + sizeof(Tlv);
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < tlv.GetLength(); i++)
|
|
||||||
{
|
{
|
||||||
SuccessOrExit(aMsg.mMessage.Read(offset + i, type));
|
switch (tlvType)
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
{
|
||||||
case Tlv::kMacCounters:
|
case Tlv::kMacCounters:
|
||||||
Get<Mac::Mac>().ResetCounters();
|
Get<Mac::Mac>().ResetCounters();
|
||||||
@@ -968,6 +932,51 @@ exit:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
// Server::TlvTypeListIterator
|
||||||
|
|
||||||
|
void Server::TlvTypeListIterator::Init(const Message &aMessage, const OffsetRange &aOffsetRange)
|
||||||
|
{
|
||||||
|
mMessage = &aMessage;
|
||||||
|
mOffsetRange = aOffsetRange;
|
||||||
|
mProcessedTlvs.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Error Server::TlvTypeListIterator::InitForTypeListTlv(const Message &aMessage)
|
||||||
|
{
|
||||||
|
Error error;
|
||||||
|
|
||||||
|
SuccessOrExit(error = Tlv::FindTlvValueOffsetRange(aMessage, Tlv::kTypeList, mOffsetRange));
|
||||||
|
mMessage = &aMessage;
|
||||||
|
mProcessedTlvs.Clear();
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error Server::TlvTypeListIterator::ReadNextTlvType(uint8_t &aTlvType)
|
||||||
|
{
|
||||||
|
Error error;
|
||||||
|
|
||||||
|
while (!mOffsetRange.IsEmpty())
|
||||||
|
{
|
||||||
|
SuccessOrExit(error = mMessage->Read(mOffsetRange, aTlvType));
|
||||||
|
mOffsetRange.AdvanceOffset(sizeof(uint8_t));
|
||||||
|
|
||||||
|
if (!mProcessedTlvs.Has(aTlvType))
|
||||||
|
{
|
||||||
|
mProcessedTlvs.Add(aTlvType);
|
||||||
|
error = kErrorNone;
|
||||||
|
ExitNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
error = kErrorNotFound;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
#if OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE
|
#if OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -122,7 +122,22 @@ private:
|
|||||||
static constexpr uint16_t kMaxChildEntries = 398;
|
static constexpr uint16_t kMaxChildEntries = 398;
|
||||||
static constexpr uint16_t kAnswerMessageLengthThreshold = 800;
|
static constexpr uint16_t kAnswerMessageLengthThreshold = 800;
|
||||||
|
|
||||||
typedef BitSet<NumericLimits<uint8_t>::kMax + 1> TlvTypeBitSet; // A bitset to store TLV types.
|
class TlvTypeListIterator
|
||||||
|
{
|
||||||
|
// Iterates through a list of TLV types in a message (e.g., in a
|
||||||
|
// `TypeListTlv`), reading them one by one and skipping over any
|
||||||
|
// duplicate TLV type in the list.
|
||||||
|
|
||||||
|
public:
|
||||||
|
void Init(const Message &aMessage, const OffsetRange &aOffsetRange);
|
||||||
|
Error InitForTypeListTlv(const Message &aMessage);
|
||||||
|
Error ReadNextTlvType(uint8_t &aTlvType);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Message *mMessage;
|
||||||
|
OffsetRange mOffsetRange;
|
||||||
|
BitSet<NumericLimits<uint8_t>::kMax + 1> mProcessedTlvs;
|
||||||
|
};
|
||||||
|
|
||||||
#if OPENTHREAD_FTD
|
#if OPENTHREAD_FTD
|
||||||
struct AnswerInfo
|
struct AnswerInfo
|
||||||
|
|||||||
@@ -630,21 +630,9 @@ private:
|
|||||||
} OT_TOOL_PACKED_END;
|
} OT_TOOL_PACKED_END;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements IPv6 Address List TLV generation and parsing.
|
* Defines Type List TLV constants and types.
|
||||||
*/
|
*/
|
||||||
OT_TOOL_PACKED_BEGIN
|
typedef TlvInfo<Tlv::kTypeList> TypeListTlv;
|
||||||
class TypeListTlv : public Tlv, public TlvInfo<Tlv::kTypeList>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Initializes the TLV.
|
|
||||||
*/
|
|
||||||
void Init(void)
|
|
||||||
{
|
|
||||||
SetType(kTypeList);
|
|
||||||
SetLength(sizeof(*this) - sizeof(Tlv));
|
|
||||||
}
|
|
||||||
} OT_TOOL_PACKED_END;
|
|
||||||
|
|
||||||
#if OPENTHREAD_FTD
|
#if OPENTHREAD_FTD
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user