diff --git a/src/core/meshcop/dataset.hpp b/src/core/meshcop/dataset.hpp index a552e00ba..c81173e05 100644 --- a/src/core/meshcop/dataset.hpp +++ b/src/core/meshcop/dataset.hpp @@ -63,7 +63,6 @@ class Dataset public: static constexpr uint8_t kMaxSize = OT_OPERATIONAL_DATASET_MAX_LENGTH; ///< Max size of MeshCoP Dataset (bytes) static constexpr uint8_t kMaxValueSize = 16; ///< Max size of a TLV value (bytes) - static constexpr uint8_t kMaxGetTypes = 64; ///< Max number of types in MGMT_GET.req /** * Represents the Dataset type (active or pending). diff --git a/src/core/meshcop/dataset_manager.cpp b/src/core/meshcop/dataset_manager.cpp index 94fbe6954..09f0682fb 100644 --- a/src/core/meshcop/dataset_manager.cpp +++ b/src/core/meshcop/dataset_manager.cpp @@ -53,6 +53,9 @@ namespace MeshCoP { RegisterLogModule("DatasetManager"); +//--------------------------------------------------------------------------------------------------------------------- +// DatasetManager + DatasetManager::DatasetManager(Instance &aInstance, Dataset::Type aType, Timer::Handler aTimerHandler) : InstanceLocator(aInstance) , mLocal(aInstance, aType) @@ -344,53 +347,34 @@ exit: void DatasetManager::HandleGet(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const { - Tlv tlv; - uint16_t offset = aMessage.GetOffset(); - uint8_t tlvs[Dataset::kMaxGetTypes]; - uint8_t length = 0; + TlvList tlvList; + uint8_t tlvType; + uint16_t offset; + uint16_t length; - while (offset < aMessage.GetLength()) + SuccessOrExit(Tlv::FindTlvValueOffset(aMessage, Tlv::kGet, offset, length)); + + for (; length > 0; length--, offset++) { - SuccessOrExit(aMessage.Read(offset, tlv)); - - if (tlv.GetType() == Tlv::kGet) - { - length = tlv.GetLength(); - - if (length > (sizeof(tlvs) - 1)) - { - // leave space for potential DelayTimer type below - length = sizeof(tlvs) - 1; - } - - aMessage.ReadBytes(offset + sizeof(Tlv), tlvs, length); - break; - } - - offset += sizeof(tlv) + tlv.GetLength(); + IgnoreError(aMessage.Read(offset, tlvType)); + tlvList.Add(tlvType); } - // MGMT_PENDING_GET.rsp must include Delay Timer TLV (Thread 1.1.1 Section 8.7.5.4) - VerifyOrExit(length > 0 && IsPendingDataset()); + // MGMT_PENDING_GET.rsp must include Delay Timer TLV (Thread 1.1.1 + // Section 8.7.5.4). - for (uint8_t i = 0; i < length; i++) + if (!tlvList.IsEmpty() && IsPendingDataset()) { - if (tlvs[i] == Tlv::kDelayTimer) - { - ExitNow(); - } + tlvList.Add(Tlv::kDelayTimer); } - tlvs[length++] = Tlv::kDelayTimer; - exit: - SendGetResponse(aMessage, aMessageInfo, tlvs, length); + SendGetResponse(aMessage, aMessageInfo, tlvList); } void DatasetManager::SendGetResponse(const Coap::Message &aRequest, const Ip6::MessageInfo &aMessageInfo, - uint8_t *aTlvs, - uint8_t aLength) const + const TlvList &aTlvList) const { Error error = kErrorNone; Coap::Message *message; @@ -401,31 +385,23 @@ void DatasetManager::SendGetResponse(const Coap::Message &aRequest, message = Get().NewPriorityResponseMessage(aRequest); VerifyOrExit(message != nullptr, error = kErrorNoBufs); - if (aLength == 0) + for (const Tlv *tlv = dataset.GetTlvsStart(); tlv < dataset.GetTlvsEnd(); tlv = tlv->GetNext()) { - for (const Tlv *cur = dataset.GetTlvsStart(); cur < dataset.GetTlvsEnd(); cur = cur->GetNext()) + bool shouldAppend = true; + + if (!aTlvList.IsEmpty()) { - if (cur->GetType() != Tlv::kNetworkKey || Get().GetSecurityPolicy().mObtainNetworkKeyEnabled) - { - SuccessOrExit(error = cur->AppendTo(*message)); - } + shouldAppend = aTlvList.Contains(tlv->GetType()); } - } - else - { - for (uint8_t index = 0; index < aLength; index++) + + if ((tlv->GetType() == Tlv::kNetworkKey) && !Get().GetSecurityPolicy().mObtainNetworkKeyEnabled) { - const Tlv *tlv; + shouldAppend = false; + } - if (aTlvs[index] == Tlv::kNetworkKey && !Get().GetSecurityPolicy().mObtainNetworkKeyEnabled) - { - continue; - } - - if ((tlv = dataset.FindTlv(static_cast(aTlvs[index]))) != nullptr) - { - SuccessOrExit(error = tlv->AppendTo(*message)); - } + if (shouldAppend) + { + SuccessOrExit(error = tlv->AppendTo(*message)); } } @@ -603,6 +579,17 @@ exit: return error; } +void DatasetManager::TlvList::Add(uint8_t aTlvType) +{ + if (!Contains(aTlvType)) + { + IgnoreError(PushBack(aTlvType)); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +// ActiveDatasetManager + ActiveDatasetManager::ActiveDatasetManager(Instance &aInstance) : DatasetManager(aInstance, Dataset::kActive, ActiveDatasetManager::HandleTimer) { @@ -651,6 +638,9 @@ void ActiveDatasetManager::HandleTmf(Coap::Message &aMessage, con void ActiveDatasetManager::HandleTimer(Timer &aTimer) { aTimer.Get().HandleTimer(); } +//--------------------------------------------------------------------------------------------------------------------- +// PendingDatasetManager + PendingDatasetManager::PendingDatasetManager(Instance &aInstance) : DatasetManager(aInstance, Dataset::kPending, PendingDatasetManager::HandleTimer) , mDelayTimer(aInstance) diff --git a/src/core/meshcop/dataset_manager.hpp b/src/core/meshcop/dataset_manager.hpp index c0d90fe5f..5c17de7a2 100644 --- a/src/core/meshcop/dataset_manager.hpp +++ b/src/core/meshcop/dataset_manager.hpp @@ -339,6 +339,15 @@ protected: bool mTimestampValid : 1; private: + static constexpr uint8_t kMaxGetTypes = 64; // Max number of types in MGMT_GET.req + + class TlvList : public Array + { + public: + TlvList(void) = default; + void Add(uint8_t aTlvType); + }; + static void HandleMgmtSetResponse(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo, @@ -353,8 +362,7 @@ private: void SendSet(void); void SendGetResponse(const Coap::Message &aRequest, const Ip6::MessageInfo &aMessageInfo, - uint8_t *aTlvs, - uint8_t aLength) const; + const TlvList &aTlvList) const; #if OPENTHREAD_FTD void SendSetResponse(const Coap::Message &aRequest, const Ip6::MessageInfo &aMessageInfo, StateTlv::State aState);