/* * Copyright (c) 2016, The OpenThread Authors. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holder nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /** * @file * This file includes definitions for managing MeshCoP Datasets. * */ #ifndef MESHCOP_DATASET_HPP_ #define MESHCOP_DATASET_HPP_ #include "openthread-core-config.h" #include #include "common/as_core_type.hpp" #include "common/clearable.hpp" #include "common/const_cast.hpp" #include "common/locator.hpp" #include "common/message.hpp" #include "common/timer.hpp" #include "common/type_traits.hpp" #include "meshcop/meshcop_tlvs.hpp" #include "thread/mle_types.hpp" namespace ot { namespace MeshCoP { /** * This class represents MeshCop Dataset. * */ class Dataset { friend class DatasetLocal; 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 /** * This enumeration represents the Dataset type (active or pending). * */ enum Type : uint8_t { kActive, ///< Active Dataset kPending, ///< Pending Dataset }; /** * This class represents presence of different components in Active or Pending Operational Dataset. * */ class Components : public otOperationalDatasetComponents, public Clearable { public: /** * This method indicates whether or not the Active Timestamp is present in the Dataset. * * @returns TRUE if Active Timestamp is present, FALSE otherwise. * */ bool IsActiveTimestampPresent(void) const { return mIsActiveTimestampPresent; } /** * This method indicates whether or not the Pending Timestamp is present in the Dataset. * * @returns TRUE if Pending Timestamp is present, FALSE otherwise. * */ bool IsPendingTimestampPresent(void) const { return mIsPendingTimestampPresent; } /** * This method indicates whether or not the Network Key is present in the Dataset. * * @returns TRUE if Network Key is present, FALSE otherwise. * */ bool IsNetworkKeyPresent(void) const { return mIsNetworkKeyPresent; } /** * This method indicates whether or not the Network Name is present in the Dataset. * * @returns TRUE if Network Name is present, FALSE otherwise. * */ bool IsNetworkNamePresent(void) const { return mIsNetworkNamePresent; } /** * This method indicates whether or not the Extended PAN ID is present in the Dataset. * * @returns TRUE if Extended PAN ID is present, FALSE otherwise. * */ bool IsExtendedPanIdPresent(void) const { return mIsExtendedPanIdPresent; } /** * This method indicates whether or not the Mesh Local Prefix is present in the Dataset. * * @returns TRUE if Mesh Local Prefix is present, FALSE otherwise. * */ bool IsMeshLocalPrefixPresent(void) const { return mIsMeshLocalPrefixPresent; } /** * This method indicates whether or not the Delay Timer is present in the Dataset. * * @returns TRUE if Delay Timer is present, FALSE otherwise. * */ bool IsDelayPresent(void) const { return mIsDelayPresent; } /** * This method indicates whether or not the PAN ID is present in the Dataset. * * @returns TRUE if PAN ID is present, FALSE otherwise. * */ bool IsPanIdPresent(void) const { return mIsPanIdPresent; } /** * This method indicates whether or not the Channel is present in the Dataset. * * @returns TRUE if Channel is present, FALSE otherwise. * */ bool IsChannelPresent(void) const { return mIsChannelPresent; } /** * This method indicates whether or not the PSKc is present in the Dataset. * * @returns TRUE if PSKc is present, FALSE otherwise. * */ bool IsPskcPresent(void) const { return mIsPskcPresent; } /** * This method indicates whether or not the Security Policy is present in the Dataset. * * @returns TRUE if Security Policy is present, FALSE otherwise. * */ bool IsSecurityPolicyPresent(void) const { return mIsSecurityPolicyPresent; } /** * This method indicates whether or not the Channel Mask is present in the Dataset. * * @returns TRUE if Channel Mask is present, FALSE otherwise. * */ bool IsChannelMaskPresent(void) const { return mIsChannelMaskPresent; } }; /** * This type represents the information about the fields contained an Active or Pending Operational Dataset. * */ class Info : public otOperationalDataset, public Clearable { public: /** * This method indicates whether or not the Active Timestamp is present in the Dataset. * * @returns TRUE if Active Timestamp is present, FALSE otherwise. * */ bool IsActiveTimestampPresent(void) const { return mComponents.mIsActiveTimestampPresent; } /** * This method gets the Active Timestamp in the Dataset. * * This method MUST be used when Active Timestamp component is present in the Dataset, otherwise its behavior is * undefined. * * @returns The Active Timestamp in the Dataset. * */ void GetActiveTimestamp(Timestamp &aTimestamp) const { aTimestamp.SetFromTimestamp(mActiveTimestamp); } /** * This method sets the Active Timestamp in the Dataset. * * @param[in] aTimestamp A Timestamp value. * */ void SetActiveTimestamp(const Timestamp &aTimestamp) { aTimestamp.ConvertTo(mActiveTimestamp); mComponents.mIsActiveTimestampPresent = true; } /** * This method indicates whether or not the Pending Timestamp is present in the Dataset. * * @returns TRUE if Pending Timestamp is present, FALSE otherwise. * */ bool IsPendingTimestampPresent(void) const { return mComponents.mIsPendingTimestampPresent; } /** * This method gets the Pending Timestamp in the Dataset. * * This method MUST be used when Pending Timestamp component is present in the Dataset, otherwise its behavior * is undefined. * * @returns The Pending Timestamp in the Dataset. * */ void GetPendingTimestamp(Timestamp &aTimestamp) const { aTimestamp.SetFromTimestamp(mPendingTimestamp); } /** * This method sets the Pending Timestamp in the Dataset. * * @param[in] aTimestamp A Timestamp value. * */ void SetPendingTimestamp(const Timestamp &aTimestamp) { aTimestamp.ConvertTo(mPendingTimestamp); mComponents.mIsPendingTimestampPresent = true; } /** * This method indicates whether or not the Network Key is present in the Dataset. * * @returns TRUE if Network Key is present, FALSE otherwise. * */ bool IsNetworkKeyPresent(void) const { return mComponents.mIsNetworkKeyPresent; } /** * This method gets the Network Key in the Dataset. * * This method MUST be used when Network Key component is present in the Dataset, otherwise its behavior * is undefined. * * @returns The Network Key in the Dataset. * */ const NetworkKey &GetNetworkKey(void) const { return AsCoreType(&mNetworkKey); } /** * This method sets the Network Key in the Dataset. * * @param[in] aNetworkKey A Network Key. * */ void SetNetworkKey(const NetworkKey &aNetworkKey) { mNetworkKey = aNetworkKey; mComponents.mIsNetworkKeyPresent = true; } /** * This method returns a reference to the Network Key in the Dataset to be updated by caller. * * @returns A reference to the Network Key in the Dataset. * */ NetworkKey &UpdateNetworkKey(void) { mComponents.mIsNetworkKeyPresent = true; return AsCoreType(&mNetworkKey); } /** * This method indicates whether or not the Network Name is present in the Dataset. * * @returns TRUE if Network Name is present, FALSE otherwise. * */ bool IsNetworkNamePresent(void) const { return mComponents.mIsNetworkNamePresent; } /** * This method gets the Network Name in the Dataset. * * This method MUST be used when Network Name component is present in the Dataset, otherwise its behavior is * undefined. * * @returns The Network Name in the Dataset. * */ const NetworkName &GetNetworkName(void) const { return AsCoreType(&mNetworkName); } /** * This method sets the Network Name in the Dataset. * * @param[in] aNetworkNameData A Network Name Data. * */ void SetNetworkName(const NameData &aNetworkNameData) { IgnoreError(AsCoreType(&mNetworkName).Set(aNetworkNameData)); mComponents.mIsNetworkNamePresent = true; } /** * This method indicates whether or not the Extended PAN ID is present in the Dataset. * * @returns TRUE if Extended PAN ID is present, FALSE otherwise. * */ bool IsExtendedPanIdPresent(void) const { return mComponents.mIsExtendedPanIdPresent; } /** * This method gets the Extended PAN ID in the Dataset. * * This method MUST be used when Extended PAN ID component is present in the Dataset, otherwise its behavior is * undefined. * * @returns The Extended PAN ID in the Dataset. * */ const ExtendedPanId &GetExtendedPanId(void) const { return AsCoreType(&mExtendedPanId); } /** * This method sets the Extended PAN ID in the Dataset. * * @param[in] aExtendedPanId An Extended PAN ID. * */ void SetExtendedPanId(const ExtendedPanId &aExtendedPanId) { mExtendedPanId = aExtendedPanId; mComponents.mIsExtendedPanIdPresent = true; } /** * This method indicates whether or not the Mesh Local Prefix is present in the Dataset. * * @returns TRUE if Mesh Local Prefix is present, FALSE otherwise. * */ bool IsMeshLocalPrefixPresent(void) const { return mComponents.mIsMeshLocalPrefixPresent; } /** * This method gets the Mesh Local Prefix in the Dataset. * * This method MUST be used when Mesh Local Prefix component is present in the Dataset, otherwise its behavior * is undefined. * * @returns The Mesh Local Prefix in the Dataset. * */ const Ip6::NetworkPrefix &GetMeshLocalPrefix(void) const { return static_cast(mMeshLocalPrefix); } /** * This method sets the Mesh Local Prefix in the Dataset. * * @param[in] aMeshLocalPrefix A Mesh Local Prefix. * */ void SetMeshLocalPrefix(const Ip6::NetworkPrefix &aMeshLocalPrefix) { mMeshLocalPrefix = aMeshLocalPrefix; mComponents.mIsMeshLocalPrefixPresent = true; } /** * This method indicates whether or not the Delay Timer is present in the Dataset. * * @returns TRUE if Delay Timer is present, FALSE otherwise. * */ bool IsDelayPresent(void) const { return mComponents.mIsDelayPresent; } /** * This method gets the Delay Timer in the Dataset. * * This method MUST be used when Delay Timer component is present in the Dataset, otherwise its behavior is * undefined. * * @returns The Delay Timer in the Dataset. * */ uint32_t GetDelay(void) const { return mDelay; } /** * This method sets the Delay Timer in the Dataset. * * @param[in] aDelay A Delay value. * */ void SetDelay(uint32_t aDelay) { mDelay = aDelay; mComponents.mIsDelayPresent = true; } /** * This method indicates whether or not the PAN ID is present in the Dataset. * * @returns TRUE if PAN ID is present, FALSE otherwise. * */ bool IsPanIdPresent(void) const { return mComponents.mIsPanIdPresent; } /** * This method gets the PAN ID in the Dataset. * * This method MUST be used when PAN ID component is present in the Dataset, otherwise its behavior is * undefined. * * @returns The PAN ID in the Dataset. * */ Mac::PanId GetPanId(void) const { return mPanId; } /** * This method sets the PAN ID in the Dataset. * * @param[in] aPanId A PAN ID. * */ void SetPanId(Mac::PanId aPanId) { mPanId = aPanId; mComponents.mIsPanIdPresent = true; } /** * This method indicates whether or not the Channel is present in the Dataset. * * @returns TRUE if Channel is present, FALSE otherwise. * */ bool IsChannelPresent(void) const { return mComponents.mIsChannelPresent; } /** * This method gets the Channel in the Dataset. * * This method MUST be used when Channel component is present in the Dataset, otherwise its behavior is * undefined. * * @returns The Channel in the Dataset. * */ uint16_t GetChannel(void) const { return mChannel; } /** * This method sets the Channel in the Dataset. * * @param[in] aChannel A Channel. * */ void SetChannel(uint16_t aChannel) { mChannel = aChannel; mComponents.mIsChannelPresent = true; } /** * This method indicates whether or not the PSKc is present in the Dataset. * * @returns TRUE if PSKc is present, FALSE otherwise. * */ bool IsPskcPresent(void) const { return mComponents.mIsPskcPresent; } /** * This method gets the PSKc in the Dataset. * * This method MUST be used when PSKc component is present in the Dataset, otherwise its behavior is undefined. * * @returns The PSKc in the Dataset. * */ const Pskc &GetPskc(void) const { return AsCoreType(&mPskc); } /** * This method set the PSKc in the Dataset. * * @param[in] aPskc A PSKc value. * */ void SetPskc(const Pskc &aPskc) { mPskc = aPskc; mComponents.mIsPskcPresent = true; } /** * This method indicates whether or not the Security Policy is present in the Dataset. * * @returns TRUE if Security Policy is present, FALSE otherwise. * */ bool IsSecurityPolicyPresent(void) const { return mComponents.mIsSecurityPolicyPresent; } /** * This method gets the Security Policy in the Dataset. * * This method MUST be used when Security Policy component is present in the Dataset, otherwise its behavior is * undefined. * * @returns The Security Policy in the Dataset. * */ const SecurityPolicy &GetSecurityPolicy(void) const { return AsCoreType(&mSecurityPolicy); } /** * This method sets the Security Policy in the Dataset. * * @param[in] aSecurityPolicy A Security Policy to set in Dataset. * */ void SetSecurityPolicy(const SecurityPolicy &aSecurityPolicy) { mSecurityPolicy = aSecurityPolicy; mComponents.mIsSecurityPolicyPresent = true; } /** * This method indicates whether or not the Channel Mask is present in the Dataset. * * @returns TRUE if Channel Mask is present, FALSE otherwise. * */ bool IsChannelMaskPresent(void) const { return mComponents.mIsChannelMaskPresent; } /** * This method gets the Channel Mask in the Dataset. * * This method MUST be used when Channel Mask component is present in the Dataset, otherwise its behavior is * undefined. * * @returns The Channel Mask in the Dataset. * */ otChannelMask GetChannelMask(void) const { return mChannelMask; } /** * This method sets the Channel Mask in the Dataset. * * @param[in] aChannelMask A Channel Mask value. * */ void SetChannelMask(otChannelMask aChannelMask) { mChannelMask = aChannelMask; mComponents.mIsChannelMaskPresent = true; } /** * This method populates the Dataset with random fields. * * The Network Key, PSKc, Mesh Local Prefix, PAN ID, and Extended PAN ID are generated randomly (crypto-secure) * with Network Name set to "OpenThread-%04x" with PAN ID appended as hex. The Channel is chosen randomly from * radio's preferred channel mask, Channel Mask is set from radio's supported mask, and Security Policy Flags * from current `KeyManager` value. * * @param[in] aInstance The OpenThread instance. * * @retval kErrorNone If the Dataset was generated successfully. * */ Error GenerateRandom(Instance &aInstance); /** * This method checks whether the Dataset is a subset of another one, i.e., all the components in the current * Dataset are also present in the @p aOther and the component values fully match. * * The matching of components in the two Datasets excludes Active/Pending Timestamp and Delay components. * * @param[in] aOther The other Dataset to check against. * * @retval TRUE The current dataset is a subset of @p aOther. * @retval FALSE The current Dataset is not a subset of @p aOther. * */ bool IsSubsetOf(const Info &aOther) const; }; /** * This constructor initializes the object. * */ Dataset(void); /** * This method clears the Dataset. * */ void Clear(void); /** * This method indicates whether or not the dataset appears to be well-formed. * * @returns TRUE if the dataset appears to be well-formed, FALSE otherwise. * */ bool IsValid(void) const; /** * This method returns a pointer to the TLV with a given type. * * @param[in] aType A TLV type. * * @returns A pointer to the TLV or `nullptr` if none is found. * */ Tlv *GetTlv(Tlv::Type aType) { return AsNonConst(AsConst(this)->GetTlv(aType)); } /** * This method returns a pointer to the TLV with a given type. * * @param[in] aType The TLV type. * * @returns A pointer to the TLV or `nullptr` if none is found. * */ const Tlv *GetTlv(Tlv::Type aType) const; /** * This template method returns a pointer to the TLV with a given template type `TlvType` * * @returns A pointer to the TLV or `nullptr` if none is found. * */ template TlvType *GetTlv(void) { return As(GetTlv(static_cast(TlvType::kType))); } /** * This template method returns a pointer to the TLV with a given template type `TlvType` * * @returns A pointer to the TLV or `nullptr` if none is found. * */ template const TlvType *GetTlv(void) const { return As(GetTlv(static_cast(TlvType::kType))); } /** * This method returns a pointer to the byte representation of the Dataset. * * @returns A pointer to the byte representation of the Dataset. * */ uint8_t *GetBytes(void) { return mTlvs; } /** * This method returns a pointer to the byte representation of the Dataset. * * @returns A pointer to the byte representation of the Dataset. * */ const uint8_t *GetBytes(void) const { return mTlvs; } /** * This method converts the TLV representation to structure representation. * * @param[out] aDatasetInfo A reference to `Info` object to output the Dataset. * */ void ConvertTo(Info &aDatasetInfo) const; /** * This method converts the TLV representation to structure representation. * * @param[out] aDataset A reference to `otOperationalDatasetTlvs` to output the Dataset. * */ void ConvertTo(otOperationalDatasetTlvs &aDataset) const; /** * This method returns the Dataset size in bytes. * * @returns The Dataset size in bytes. * */ uint16_t GetSize(void) const { return mLength; } /** * This method sets the Dataset size in bytes. * * @param[in] aSize The Dataset size in bytes. * */ void SetSize(uint16_t aSize) { mLength = aSize; } /** * This method returns the local time the dataset was last updated. * * @returns The local time the dataset was last updated. * */ TimeMilli GetUpdateTime(void) const { return mUpdateTime; } /** * This method gets the Timestamp (Active or Pending). * * @param[in] aType The type: active or pending. * @param[out] aTimestamp A reference to a `Timestamp` to output the value. * * @retval kErrorNone Timestamp was read successfully. @p aTimestamp is updated. * @retval kErrorNotFound Could not find the requested Timestamp TLV. * */ Error GetTimestamp(Type aType, Timestamp &aTimestamp) const; /** * This method sets the Timestamp value. * * @param[in] aType The type: active or pending. * @param[in] aTimestamp A Timestamp. * */ void SetTimestamp(Type aType, const Timestamp &aTimestamp); /** * This method sets a TLV in the Dataset. * * @param[in] aTlv A reference to the TLV. * * @retval kErrorNone Successfully set the TLV. * @retval kErrorNoBufs Could not set the TLV due to insufficient buffer space. * */ Error SetTlv(const Tlv &aTlv); /** * This method sets a TLV with a given TLV Type and Value. * * @param[in] aType The TLV Type. * @param[in] aValue A pointer to TLV Value. * @param[in] aLength The TLV Length in bytes (length of @p aValue). * * @retval kErrorNone Successfully set the TLV. * @retval kErrorNoBufs Could not set the TLV due to insufficient buffer space. * */ Error SetTlv(Tlv::Type aType, const void *aValue, uint8_t aLength); /** * This template method sets a TLV with a given TLV Type and Value. * * @tparam ValueType The type of TLV's Value. * * @param[in] aType The TLV Type. * @param[in] aValue The TLV Value (of type `ValueType`). * * @retval kErrorNone Successfully set the TLV. * @retval kErrorNoBufs Could not set the TLV due to insufficient buffer space. * */ template Error SetTlv(Tlv::Type aType, const ValueType &aValue) { static_assert(!TypeTraits::IsPointer::kValue, "ValueType must not be a pointer"); return SetTlv(aType, &aValue, sizeof(ValueType)); } /** * This method reads the Dataset from a given message and checks that it is well-formed and valid. * * @param[in] aMessage The message to read from. * @param[in] aOffset The offset in @p aMessage to start reading the Dataset TLVs. * @param[in] aLength The dataset length in bytes. * * @retval kErrorNone Successfully read and validated the Dataset. * @retval kErrorParse Could not read or parse the dataset from @p aMessage. * */ Error ReadFromMessage(const Message &aMessage, uint16_t aOffset, uint16_t aLength); /** * This method sets the Dataset using an existing Dataset. * * If this Dataset is an Active Dataset, any Pending Timestamp and Delay Timer TLVs will be omitted in the copy * from @p aDataset. * * @param[in] aType The type of the dataset, active or pending. * @param[in] aDataset The input Dataset. * */ void Set(Type aType, const Dataset &aDataset); /** * This method sets the Dataset from a given structure representation. * * @param[in] aDatasetInfo The input Dataset as `Dataset::Info`. * * @retval kErrorNone Successfully set the Dataset. * @retval kErrorInvalidArgs Dataset is missing Active and/or Pending Timestamp. * */ Error SetFrom(const Info &aDatasetInfo); /** * This method sets the Dataset using @p aDataset. * * @param[in] aDataset The input Dataset as otOperationalDatasetTlvs. * */ void SetFrom(const otOperationalDatasetTlvs &aDataset); /** * This method removes a TLV from the Dataset. * * @param[in] aType The type of a specific TLV. * */ void RemoveTlv(Tlv::Type aType); /** * This method appends the MLE Dataset TLV but excluding MeshCoP Sub Timestamp TLV. * * @param[in] aType The type of the dataset, active or pending. * @param[in] aMessage A message to append to. * * @retval kErrorNone Successfully append MLE Dataset TLV without MeshCoP Sub Timestamp TLV. * @retval kErrorNoBufs Insufficient available buffers to append the message with MLE Dataset TLV. * */ Error AppendMleDatasetTlv(Type aType, Message &aMessage) const; /** * This method applies the Active or Pending Dataset to the Thread interface. * * @param[in] aInstance A reference to the OpenThread instance. * @param[out] aIsNetworkKeyUpdated A pointer to where to place whether network key was updated. * * @retval kErrorNone Successfully applied configuration. * @retval kErrorParse The dataset has at least one TLV with invalid format. * */ Error ApplyConfiguration(Instance &aInstance, bool *aIsNetworkKeyUpdated = nullptr) const; /** * This method converts a Pending Dataset to an Active Dataset. * * This method removes the Delay Timer and Pending Timestamp TLVs * */ void ConvertToActive(void); /** * This method returns a pointer to the start of Dataset TLVs sequence. * * @return A pointer to the start of Dataset TLVs sequence. * */ Tlv *GetTlvsStart(void) { return reinterpret_cast(mTlvs); } /** * This method returns a pointer to the start of Dataset TLVs sequence. * * @return A pointer to start of Dataset TLVs sequence. * */ const Tlv *GetTlvsStart(void) const { return reinterpret_cast(mTlvs); } /** * This method returns a pointer to the past-the-end of Dataset TLVs sequence. * * Note that past-the-end points to the byte after the end of the last TLV in Dataset TLVs sequence. * * @return A pointer to past-the-end of Dataset TLVs sequence. * */ Tlv *GetTlvsEnd(void) { return reinterpret_cast(mTlvs + mLength); } /** * This method returns a pointer to the past-the-end of Dataset TLVs sequence. * * Note that past-the-end points to the byte after the end of the last TLV in Dataset TLVs sequence. * * @return A pointer to past-the-end of Dataset TLVs sequence. * */ const Tlv *GetTlvsEnd(void) const { return reinterpret_cast(mTlvs + mLength); } /** * This static method converts a Dataset Type to a string. * * @param[in] aType A Dataset type. * */ static const char *TypeToString(Type aType); private: void RemoveTlv(Tlv *aTlv); uint8_t mTlvs[kMaxSize]; ///< The Dataset buffer TimeMilli mUpdateTime; ///< Local time last updated uint16_t mLength; ///< The number of valid bytes in @var mTlvs }; /** * This is a template specialization of `SetTlv` with a `uint16_t` value type. * * @param[in] aType The TLV Type. * @param[in] aValue The TLV value (as `uint16_t`). * * @retval kErrorNone Successfully set the TLV. * @retval kErrorNoBufs Could not set the TLV due to insufficient buffer space. * */ template <> inline Error Dataset::SetTlv(Tlv::Type aType, const uint16_t &aValue) { uint16_t value = Encoding::BigEndian::HostSwap16(aValue); return SetTlv(aType, &value, sizeof(uint16_t)); } /** * This is a template specialization of `SetTlv` with a `uint32_t` value type * * @param[in] aType The TLV Type. * @param[in] aValue The TLV value (as `uint32_t`). * * @retval kErrorNone Successfully set the TLV. * @retval kErrorNoBufs Could not set the TLV due to insufficient buffer space. * */ template <> inline Error Dataset::SetTlv(Tlv::Type aType, const uint32_t &aValue) { uint32_t value = Encoding::BigEndian::HostSwap32(aValue); return SetTlv(aType, &value, sizeof(uint32_t)); } } // namespace MeshCoP DefineCoreType(otOperationalDatasetComponents, MeshCoP::Dataset::Components); DefineCoreType(otOperationalDataset, MeshCoP::Dataset::Info); } // namespace ot #endif // MESHCOP_DATASET_HPP_