| /* |
| * 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 generating and processing Thread Network Data TLVs. |
| */ |
| |
| #ifndef NETWORK_DATA_TLVS_HPP_ |
| #define NETWORK_DATA_TLVS_HPP_ |
| |
| #include "openthread-core-config.h" |
| |
| #include <openthread/netdata.h> |
| |
| #include "common/debug.hpp" |
| #include "common/encoding.hpp" |
| #include "common/equatable.hpp" |
| #include "net/ip6_address.hpp" |
| |
| namespace ot { |
| namespace NetworkData { |
| |
| using ot::Encoding::BigEndian::HostSwap16; |
| using ot::Encoding::BigEndian::HostSwap32; |
| |
| /** |
| * @addtogroup core-netdata-tlvs |
| * |
| * @brief |
| * This module includes definitions for generating and processing Thread Network Data TLVs. |
| * |
| * @{ |
| * |
| */ |
| |
| /** |
| * This class implements Thread Network Data TLV generation and parsing. |
| * |
| */ |
| OT_TOOL_PACKED_BEGIN |
| class NetworkDataTlv |
| { |
| public: |
| /** |
| * This method initializes TLV. |
| * |
| */ |
| void Init(void) |
| { |
| mType = 0; |
| mLength = 0; |
| } |
| |
| /** |
| * Thread Network Data Type values. |
| * |
| */ |
| enum Type |
| { |
| kTypeHasRoute = 0, ///< Has Route TLV |
| kTypePrefix = 1, ///< Prefix TLV |
| kTypeBorderRouter = 2, ///< Border Router TLV |
| kTypeContext = 3, ///< Context TLV |
| kTypeCommissioningData = 4, ///< Commissioning Dataset TLV |
| kTypeService = 5, ///< Service TLV |
| kTypeServer = 6, ///< Server TLV |
| }; |
| |
| /** |
| * This method returns the Type value. |
| * |
| * @returns The Type value. |
| * |
| */ |
| Type GetType(void) const { return static_cast<Type>(mType >> kTypeOffset); } |
| |
| /** |
| * This method sets the Type value. |
| * |
| * @param[in] aType The Type value. |
| * |
| */ |
| void SetType(Type aType) { mType = (mType & ~kTypeMask) | ((aType << kTypeOffset) & kTypeMask); } |
| |
| /** |
| * This method returns the Length value. |
| * |
| * @returns The Length value. |
| * |
| */ |
| uint8_t GetLength(void) const { return mLength; } |
| |
| /** |
| * This method sets the Length value. |
| * |
| * @param[in] aLength The Length value. |
| * |
| */ |
| void SetLength(uint8_t aLength) { mLength = aLength; } |
| |
| /** |
| * This methods increases the Length value by a given amount. |
| * |
| * @param[in] aIncrement The increment amount to increase the length. |
| * |
| */ |
| void IncreaseLength(uint8_t aIncrement) { mLength += aIncrement; } |
| |
| /** |
| * This methods decreases the Length value by a given amount. |
| * |
| * @param[in] aDecrement The decrement amount to decrease the length. |
| * |
| */ |
| void DecreaseLength(uint8_t aDecrement) { mLength -= aDecrement; } |
| |
| /** |
| * This method returns the TLV's total size (number of bytes) including Type, Length, and Value fields. |
| * |
| * @returns The total size include Type, Length, and Value fields. |
| * |
| */ |
| uint8_t GetSize(void) const { return sizeof(NetworkDataTlv) + mLength; } |
| |
| /** |
| * This method returns a pointer to the Value. |
| * |
| * @returns A pointer to the value. |
| * |
| */ |
| uint8_t *GetValue(void) { return reinterpret_cast<uint8_t *>(this) + sizeof(NetworkDataTlv); } |
| |
| /** |
| * This method returns a pointer to the Value. |
| * |
| * @returns A pointer to the value. |
| * |
| */ |
| const uint8_t *GetValue(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(NetworkDataTlv); } |
| |
| /** |
| * This method returns a pointer to the next Network Data TLV. |
| * |
| * @returns A pointer to the next Network Data TLV. |
| * |
| */ |
| NetworkDataTlv *GetNext(void) |
| { |
| return reinterpret_cast<NetworkDataTlv *>(reinterpret_cast<uint8_t *>(this) + sizeof(*this) + mLength); |
| } |
| |
| /** |
| * This method returns a pointer to the next Network Data TLV. |
| * |
| * @returns A pointer to the next Network Data TLV. |
| * |
| */ |
| const NetworkDataTlv *GetNext(void) const |
| { |
| return reinterpret_cast<const NetworkDataTlv *>(reinterpret_cast<const uint8_t *>(this) + sizeof(*this) + |
| mLength); |
| } |
| |
| /** |
| * This method clears the Stable bit. |
| * |
| */ |
| void ClearStable(void) { mType &= ~kStableMask; } |
| |
| /** |
| * This method indicates whether or not the Stable bit is set. |
| * |
| * @retval TRUE If the Stable bit is set. |
| * @retval FALSE If the Stable bit is not set. |
| * |
| */ |
| bool IsStable(void) const { return (mType & kStableMask); } |
| |
| /** |
| * This method sets the Stable bit. |
| * |
| */ |
| void SetStable(void) { mType |= kStableMask; } |
| |
| private: |
| enum |
| { |
| kTypeOffset = 1, |
| kTypeMask = 0x7f << kTypeOffset, |
| kStableMask = 1 << 0, |
| }; |
| uint8_t mType; |
| uint8_t mLength; |
| } OT_TOOL_PACKED_END; |
| |
| /** |
| * This class implements Has Route TLV entry generation and parsing. |
| * |
| */ |
| OT_TOOL_PACKED_BEGIN |
| class HasRouteEntry : public Equatable<HasRouteEntry> |
| { |
| public: |
| /** |
| * This method initializes the header. |
| * |
| */ |
| void Init(void) |
| { |
| SetRloc(Mac::kShortAddrInvalid); |
| mFlags = 0; |
| } |
| |
| /** |
| * This method returns the RLOC16 value. |
| * |
| * @returns The RLOC16 value. |
| */ |
| uint16_t GetRloc(void) const { return HostSwap16(mRloc); } |
| |
| /** |
| * This method sets the RLOC16 value. |
| * |
| * @param[in] aRloc16 The RLOC16 value. |
| * |
| */ |
| void SetRloc(uint16_t aRloc16) { mRloc = HostSwap16(aRloc16); } |
| |
| /** |
| * This method returns the Preference value. |
| * |
| * @returns The preference value. |
| * |
| */ |
| int8_t GetPreference(void) const { return static_cast<int8_t>(mFlags) >> kPreferenceOffset; } |
| |
| /** |
| * This method sets the Preference value. |
| * |
| * @param[in] aPrf The Preference value. |
| * |
| */ |
| void SetPreference(int8_t aPrf) |
| { |
| OT_ASSERT((aPrf == OT_ROUTE_PREFERENCE_LOW) || (aPrf == OT_ROUTE_PREFERENCE_MED) || |
| (aPrf == OT_ROUTE_PREFERENCE_HIGH)); |
| mFlags = (mFlags & ~kPreferenceMask) | ((static_cast<uint8_t>(aPrf) << kPreferenceOffset) & kPreferenceMask); |
| } |
| |
| /** |
| * This method returns a pointer to the next HasRouteEntry. |
| * |
| * @returns A pointer to the next HasRouteEntry. |
| * |
| */ |
| HasRouteEntry *GetNext(void) { return (this + 1); } |
| |
| /** |
| * This method returns a pointer to the next HasRouteEntry. |
| * |
| * @returns A pointer to the next HasRouteEntry. |
| * |
| */ |
| const HasRouteEntry *GetNext(void) const { return (this + 1); } |
| |
| private: |
| enum |
| { |
| kPreferenceOffset = 6, |
| kPreferenceMask = 3 << kPreferenceOffset, |
| }; |
| |
| uint16_t mRloc; |
| uint8_t mFlags; |
| } OT_TOOL_PACKED_END; |
| |
| /** |
| * This class implements Has Route TLV generation and parsing. |
| * |
| */ |
| OT_TOOL_PACKED_BEGIN |
| class HasRouteTlv : public NetworkDataTlv |
| { |
| public: |
| enum |
| { |
| kType = kTypeHasRoute, ///< The TLV Type. |
| }; |
| |
| /** |
| * This method initializes the TLV. |
| * |
| */ |
| void Init(void) |
| { |
| NetworkDataTlv::Init(); |
| SetType(kTypeHasRoute); |
| SetLength(0); |
| } |
| |
| /** |
| * This method returns the number of HasRoute entries. |
| * |
| * @returns The number of HasRoute entries. |
| * |
| */ |
| uint8_t GetNumEntries(void) const { return GetLength() / sizeof(HasRouteEntry); } |
| |
| /** |
| * This method returns a pointer to the HasRoute entry at a given index. |
| * |
| * @param[in] aIndex An index. |
| * |
| * @returns A pointer to the HasRoute entry at @p aIndex. |
| * |
| */ |
| HasRouteEntry *GetEntry(uint8_t aIndex) |
| { |
| return reinterpret_cast<HasRouteEntry *>(GetValue() + (aIndex * sizeof(HasRouteEntry))); |
| } |
| |
| /** |
| * This method returns a pointer to the HasRoute entry at a given index. |
| * |
| * @param[in] aIndex An index. |
| * |
| * @returns A pointer to the HasRoute entry at @p aIndex. |
| * |
| */ |
| const HasRouteEntry *GetEntry(uint8_t aIndex) const |
| { |
| return reinterpret_cast<const HasRouteEntry *>(GetValue() + (aIndex * sizeof(HasRouteEntry))); |
| } |
| |
| /** |
| * This method returns a pointer to the first HasRouteEntry (at index 0'th). |
| * |
| * @returns A pointer to the first HasRouteEntry. |
| * |
| */ |
| HasRouteEntry *GetFirstEntry(void) { return reinterpret_cast<HasRouteEntry *>(GetValue()); } |
| |
| /** |
| * This method returns a pointer to the first HasRouteEntry (at index 0'th). |
| * |
| * @returns A pointer to the first HasRouteEntry. |
| * |
| */ |
| const HasRouteEntry *GetFirstEntry(void) const { return reinterpret_cast<const HasRouteEntry *>(GetValue()); } |
| |
| /** |
| * This method returns a pointer to the last HasRouteEntry. |
| * |
| * If there are no entries the pointer will be invalid but guaranteed to be before the `GetFirstEntry()` pointer. |
| * |
| * @returns A pointer to the last HasRouteEntry. |
| * |
| */ |
| HasRouteEntry *GetLastEntry(void) |
| { |
| return reinterpret_cast<HasRouteEntry *>(GetValue() + GetLength() - sizeof(HasRouteEntry)); |
| } |
| |
| /** |
| * This method returns a pointer to the last HasRouteEntry. |
| * |
| * If there are no entries the pointer will be invalid but guaranteed to be before the `GetFirstEntry()` pointer. |
| * |
| * @returns A pointer to the last HasRouteEntry. |
| * |
| */ |
| const HasRouteEntry *GetLastEntry(void) const |
| { |
| return reinterpret_cast<const HasRouteEntry *>(GetValue() + GetLength() - sizeof(HasRouteEntry)); |
| } |
| |
| } OT_TOOL_PACKED_END; |
| |
| /** |
| * This class implements Prefix TLV generation and parsing. |
| * |
| */ |
| OT_TOOL_PACKED_BEGIN |
| class PrefixTlv : public NetworkDataTlv |
| { |
| public: |
| enum |
| { |
| kType = kTypePrefix, ///< The TLV Type. |
| }; |
| |
| /** |
| * This method initializes the TLV. |
| * |
| * @param[in] aDomainId The Domain ID. |
| * @param[in] aPrefixLength The Prefix Length in bits. |
| * @param[in] aPrefix A pointer to the prefix. |
| * |
| */ |
| void Init(uint8_t aDomainId, uint8_t aPrefixLength, const uint8_t *aPrefix) |
| { |
| NetworkDataTlv::Init(); |
| SetType(kTypePrefix); |
| mDomainId = aDomainId; |
| mPrefixLength = aPrefixLength; |
| memcpy(GetPrefix(), aPrefix, BitVectorBytes(aPrefixLength)); |
| SetSubTlvsLength(0); |
| } |
| |
| /** |
| * This method indicates whether or not the TLV appears to be well-formed. |
| * |
| * @retval TRUE If the TLV appears to be well-formed. |
| * @retval FALSE If the TLV does not appear to be well-formed. |
| * |
| */ |
| bool IsValid(void) const |
| { |
| return ((GetLength() >= sizeof(*this) - sizeof(NetworkDataTlv)) && |
| (GetLength() >= BitVectorBytes(mPrefixLength) + sizeof(*this) - sizeof(NetworkDataTlv)) && |
| (BitVectorBytes(mPrefixLength) <= sizeof(Ip6::Address))); |
| } |
| |
| /** |
| * This method returns the Domain ID value. |
| * |
| * @returns The Domain ID value. |
| * |
| */ |
| uint8_t GetDomainId(void) const { return mDomainId; } |
| |
| /** |
| * This method returns the Prefix Length value. |
| * |
| * @returns The Prefix Length value (in bits). |
| * |
| */ |
| uint8_t GetPrefixLength(void) const { return mPrefixLength; } |
| |
| /** |
| * This method returns a pointer to the Prefix. |
| * |
| * @returns A pointer to the Prefix. |
| * |
| */ |
| uint8_t *GetPrefix(void) { return reinterpret_cast<uint8_t *>(this) + sizeof(*this); } |
| |
| /** |
| * This method returns a pointer to the Prefix. |
| * |
| * @returns A pointer to the Prefix. |
| * |
| */ |
| const uint8_t *GetPrefix(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); } |
| |
| /** |
| * This method returns a pointer to the Sub-TLVs. |
| * |
| * @returns A pointer to the Sub-TLVs. |
| * |
| */ |
| NetworkDataTlv *GetSubTlvs(void) |
| { |
| return reinterpret_cast<NetworkDataTlv *>(GetPrefix() + BitVectorBytes(mPrefixLength)); |
| } |
| |
| /** |
| * This method returns a pointer to the Sub-TLVs. |
| * |
| * @returns A pointer to the Sub-TLVs. |
| * |
| */ |
| const NetworkDataTlv *GetSubTlvs(void) const |
| { |
| return reinterpret_cast<const NetworkDataTlv *>(GetPrefix() + BitVectorBytes(mPrefixLength)); |
| } |
| |
| /** |
| * This method returns the Sub-TLVs length in bytes. |
| * |
| * @returns The Sub-TLVs length in bytes. |
| * |
| */ |
| uint8_t GetSubTlvsLength(void) const |
| { |
| return GetLength() - (sizeof(*this) - sizeof(NetworkDataTlv) + BitVectorBytes(mPrefixLength)); |
| } |
| |
| /** |
| * This method sets the Sub-TLVs length in bytes. |
| * |
| * @param[in] aLength The Sub-TLVs length in bytes. |
| * |
| */ |
| void SetSubTlvsLength(uint8_t aLength) |
| { |
| SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + BitVectorBytes(mPrefixLength) + aLength); |
| } |
| |
| /** |
| * This static method calculates the total size (number of bytes) of a Prefix TLV with a given Prefix Length value. |
| * |
| * Note that the returned size does include the Type and Length fields in the TLV, but does not account for any |
| * sub TLVs of the Prefix TLV. |
| * |
| * @param[in] aPrefixLength A Prefix Length in bits. |
| |
| * @returns The size (number of bytes) of the Prefix TLV. |
| * |
| */ |
| static uint16_t CalculateSize(uint8_t aPrefixLength) { return sizeof(PrefixTlv) + BitVectorBytes(aPrefixLength); } |
| |
| private: |
| uint8_t mDomainId; |
| uint8_t mPrefixLength; |
| } OT_TOOL_PACKED_END; |
| |
| /** |
| * This class implements Border Router Entry generation and parsing. |
| * |
| */ |
| OT_TOOL_PACKED_BEGIN |
| class BorderRouterEntry : public Equatable<BorderRouterEntry> |
| { |
| public: |
| enum |
| { |
| kPreferenceOffset = 14, |
| kPreferenceMask = 3 << kPreferenceOffset, |
| kPreferredFlag = 1 << 13, |
| kSlaacFlag = 1 << 12, |
| kDhcpFlag = 1 << 11, |
| kConfigureFlag = 1 << 10, |
| kDefaultRouteFlag = 1 << 9, |
| kOnMeshFlag = 1 << 8, |
| kNdDnsFlag = 1 << 7, |
| kDpFlag = 1 << 6, |
| }; |
| |
| /** |
| * This method initializes the TLV. |
| * |
| */ |
| void Init(void) |
| { |
| SetRloc(Mac::kShortAddrInvalid); |
| mFlags = 0; |
| } |
| |
| /** |
| * This method returns the RLOC16 value. |
| * |
| * @returns The RLOC16 value. |
| */ |
| uint16_t GetRloc(void) const { return HostSwap16(mRloc); } |
| |
| /** |
| * This method sets the RLOC16 value. |
| * |
| * @param[in] aRloc16 The RLOC16 value. |
| * |
| */ |
| void SetRloc(uint16_t aRloc16) { mRloc = HostSwap16(aRloc16); } |
| |
| /** |
| * This method returns the Flags value. |
| * |
| * @returns The Flags value. |
| * |
| */ |
| uint16_t GetFlags(void) const { return HostSwap16(mFlags) & ~kPreferenceMask; } |
| |
| /** |
| * This method sets the Flags value. |
| * |
| * @param[in] aFlags The Flags value. |
| * |
| */ |
| void SetFlags(uint16_t aFlags) |
| { |
| mFlags = HostSwap16((HostSwap16(mFlags) & kPreferenceMask) | (aFlags & ~kPreferenceMask)); |
| } |
| |
| /** |
| * This method returns the Preference value. |
| * |
| * @returns the Preference value. |
| * |
| */ |
| int8_t GetPreference(void) const |
| { |
| return static_cast<int8_t>(static_cast<int16_t>(HostSwap16(mFlags)) >> kPreferenceOffset); |
| } |
| |
| /** |
| * This method sets the Preference value. |
| * |
| * @param[in] aPrf The Preference value. |
| * |
| */ |
| void SetPreference(int8_t aPrf) |
| { |
| mFlags = HostSwap16(GetFlags() | ((static_cast<uint16_t>(aPrf) << kPreferenceOffset) & kPreferenceMask)); |
| } |
| |
| /** |
| * This method indicates whether or not the Preferred flag is set. |
| * |
| * @retval TRUE If the Preferred flag is set. |
| * @retval FALSE If the Preferred flag is not set. |
| * |
| */ |
| bool IsPreferred(void) const { return (HostSwap16(mFlags) & kPreferredFlag) != 0; } |
| |
| /** |
| * This method indicates whether or not the SLAAC flag is set. |
| * |
| * @retval TRUE If the SLAAC flag is set. |
| * @retval FALSE If the SLAAC flag is not set. |
| * |
| */ |
| bool IsSlaac(void) const { return (HostSwap16(mFlags) & kSlaacFlag) != 0; } |
| |
| /** |
| * This method indicates whether or not the DHCP flag is set. |
| * |
| * @retval TRUE If the DHCP flag is set. |
| * @retval FALSE If the DHCP flag is not set. |
| * |
| */ |
| bool IsDhcp(void) const { return (HostSwap16(mFlags) & kDhcpFlag) != 0; } |
| |
| /** |
| * This method indicates whether or not the Configure flag is set. |
| * |
| * @retval TRUE If the Configure flag is set. |
| * @retval FALSE If the Configure flag is not set. |
| * |
| */ |
| bool IsConfigure(void) const { return (HostSwap16(mFlags) & kConfigureFlag) != 0; } |
| |
| /** |
| * This method indicates whether or not the Default Route flag is set. |
| * |
| * @retval TRUE If the Default Route flag is set. |
| * @retval FALSE If the Default Route flag is not set. |
| * |
| */ |
| bool IsDefaultRoute(void) const { return (HostSwap16(mFlags) & kDefaultRouteFlag) != 0; } |
| |
| /** |
| * This method indicates whether or not the On-Mesh flag is set. |
| * |
| * @retval TRUE If the On-Mesh flag is set. |
| * @retval FALSE If the On-Mesh flag is not set. |
| * |
| */ |
| bool IsOnMesh(void) const { return (HostSwap16(mFlags) & kOnMeshFlag) != 0; } |
| |
| /** |
| * This method indicates whether or not the Nd-Dns flag is set. |
| * |
| * @retval TRUE If the Nd-Dns flag is set. |
| * @retval FALSE If the Nd-Dns flag is not set. |
| * |
| */ |
| bool IsNdDns(void) const { return (HostSwap16(mFlags) & kNdDnsFlag) != 0; } |
| |
| /** |
| * This method indicates whether or not the Domain Prefix flag is set. |
| * |
| * @retval TRUE If the Domain Prefix flag is set. |
| * @retval FALSE If the Domain Prefix flag is not set. |
| * |
| */ |
| bool IsDp(void) const { return (HostSwap16(mFlags) & kDpFlag) != 0; } |
| |
| /** |
| * This method returns a pointer to the next BorderRouterEntry |
| * |
| * @returns A pointer to the next BorderRouterEntry. |
| * |
| */ |
| BorderRouterEntry *GetNext(void) { return (this + 1); } |
| |
| /** |
| * This method returns a pointer to the next BorderRouterEntry |
| * |
| * @returns A pointer to the next BorderRouterEntry. |
| * |
| */ |
| const BorderRouterEntry *GetNext(void) const { return (this + 1); } |
| |
| private: |
| uint16_t mRloc; |
| uint16_t mFlags; |
| } OT_TOOL_PACKED_END; |
| |
| /** |
| * This class implements Border Router TLV generation and parsing. |
| * |
| */ |
| OT_TOOL_PACKED_BEGIN |
| class BorderRouterTlv : public NetworkDataTlv |
| { |
| public: |
| enum |
| { |
| kType = kTypeBorderRouter, ///< The TLV Type. |
| }; |
| |
| /** |
| * This method initializes the TLV. |
| * |
| */ |
| void Init(void) |
| { |
| NetworkDataTlv::Init(); |
| SetType(kTypeBorderRouter); |
| SetLength(0); |
| } |
| |
| /** |
| * This method returns the number of Border Router entries. |
| * |
| * @returns The number of Border Router entries. |
| * |
| */ |
| uint8_t GetNumEntries(void) const { return GetLength() / sizeof(BorderRouterEntry); } |
| |
| /** |
| * This method returns a pointer to the Border Router entry at a given index |
| * |
| * @param[in] aIndex The index. |
| * |
| * @returns A pointer to the Border Router entry at @p aIndex. |
| * |
| */ |
| BorderRouterEntry *GetEntry(uint8_t aIndex) |
| { |
| return reinterpret_cast<BorderRouterEntry *>(GetValue() + (aIndex * sizeof(BorderRouterEntry))); |
| } |
| |
| /** |
| * This method returns a pointer to the Border Router entry at a given index. |
| * |
| * @param[in] aIndex The index. |
| * |
| * @returns A pointer to the Border Router entry at @p aIndex |
| * |
| */ |
| const BorderRouterEntry *GetEntry(uint8_t aIndex) const |
| { |
| return reinterpret_cast<const BorderRouterEntry *>(GetValue() + (aIndex * sizeof(BorderRouterEntry))); |
| } |
| |
| /** |
| * This method returns a pointer to the first BorderRouterEntry (at index 0'th). |
| * |
| * @returns A pointer to the first BorderRouterEntry. |
| * |
| */ |
| BorderRouterEntry *GetFirstEntry(void) { return reinterpret_cast<BorderRouterEntry *>(GetValue()); } |
| |
| /** |
| * This method returns a pointer to the first BorderRouterEntry (at index 0'th). |
| * |
| * @returns A pointer to the first BorderRouterEntry. |
| * |
| */ |
| const BorderRouterEntry *GetFirstEntry(void) const |
| { |
| return reinterpret_cast<const BorderRouterEntry *>(GetValue()); |
| } |
| |
| /** |
| * This method returns a pointer to the last BorderRouterEntry. |
| * |
| * If there are no entries the pointer will be invalid but guaranteed to be before the `GetFirstEntry()` pointer. |
| * |
| * @returns A pointer to the last BorderRouterEntry. |
| * |
| */ |
| BorderRouterEntry *GetLastEntry(void) |
| { |
| return reinterpret_cast<BorderRouterEntry *>(GetValue() + GetLength() - sizeof(BorderRouterEntry)); |
| } |
| |
| /** |
| * This method returns a pointer to the last BorderRouterEntry. |
| * |
| * If there are no entries the pointer will be invalid but guaranteed to be before the `GetFirstEntry()` pointer. |
| * |
| * @returns A pointer to the last BorderRouterEntry. |
| * |
| */ |
| const BorderRouterEntry *GetLastEntry(void) const |
| { |
| return reinterpret_cast<const BorderRouterEntry *>(GetValue() + GetLength() - sizeof(BorderRouterEntry)); |
| } |
| |
| } OT_TOOL_PACKED_END; |
| |
| /** |
| * This class implements Context TLV generation and processing. |
| * |
| */ |
| OT_TOOL_PACKED_BEGIN |
| class ContextTlv : public NetworkDataTlv |
| { |
| public: |
| enum |
| { |
| kType = kTypeContext, ///< The TLV Type. |
| }; |
| |
| /** |
| * This method initializes the Context TLV. |
| * |
| * @param[in] aConextId The Context ID value. |
| * @param[in] aLength The Context Length value. |
| * |
| */ |
| void Init(uint8_t aContextId, uint8_t aConextLength) |
| { |
| NetworkDataTlv::Init(); |
| SetType(kTypeContext); |
| SetLength(sizeof(ContextTlv) - sizeof(NetworkDataTlv)); |
| mFlags = ((aContextId << kContextIdOffset) & kContextIdMask); |
| mContextLength = aConextLength; |
| } |
| |
| /** |
| * This method indicates whether or not the Compress flag is set. |
| * |
| * @retval TRUE The Compress flag is set. |
| * @retval FALSE The Compress flags is not set. |
| * |
| */ |
| bool IsCompress(void) const { return (mFlags & kCompressFlag) != 0; } |
| |
| /** |
| * This method clears the Compress flag. |
| * |
| */ |
| void ClearCompress(void) { mFlags &= ~kCompressFlag; } |
| |
| /** |
| * This method sets the Compress flag. |
| * |
| */ |
| void SetCompress(void) { mFlags |= kCompressFlag; } |
| |
| /** |
| * This method returns the Context ID value. |
| * |
| * @returns The Context ID value. |
| * |
| */ |
| uint8_t GetContextId(void) const { return mFlags & kContextIdMask; } |
| |
| /** |
| * This method returns the Context Length value. |
| * |
| * @returns The Context Length value. |
| * |
| */ |
| uint8_t GetContextLength(void) const { return mContextLength; } |
| |
| private: |
| enum |
| { |
| kCompressFlag = 1 << 4, |
| kContextIdOffset = 0, |
| kContextIdMask = 0xf << kContextIdOffset, |
| }; |
| uint8_t mFlags; |
| uint8_t mContextLength; |
| } OT_TOOL_PACKED_END; |
| |
| /** |
| * This class implements Commissioning Data TLV generation and parsing. |
| * |
| */ |
| OT_TOOL_PACKED_BEGIN |
| class CommissioningDataTlv : public NetworkDataTlv |
| { |
| public: |
| enum |
| { |
| kType = kTypeCommissioningData, ///< The TLV Type. |
| }; |
| |
| /** |
| * This method initializes the TLV. |
| * |
| */ |
| void Init(void) |
| { |
| NetworkDataTlv::Init(); |
| SetType(kTypeCommissioningData); |
| SetLength(0); |
| } |
| } OT_TOOL_PACKED_END; |
| |
| /** |
| * This class implements Service Data TLV generation and parsing. |
| * |
| */ |
| OT_TOOL_PACKED_BEGIN |
| class ServiceTlv : public NetworkDataTlv |
| { |
| public: |
| enum |
| { |
| kType = kTypeService, ///< The TLV Type. |
| kThreadEnterpriseNumber = 44970, ///< Thread enterprise number. |
| kServiceDataBackboneRouter = 0x01, ///< const THREAD_SERVICE_DATA_BBR |
| }; |
| |
| /** |
| * This method initializes the TLV. |
| * |
| * @param[in] aServiceId The Service Id value. |
| * @param[in] aEnterpriseNumber The Enterprise Number. |
| * @param[in] aServiceData The Service Data. |
| * @param[in] aServiceDataLength The Service Data length (number of bytes). |
| * |
| */ |
| void Init(uint8_t aServiceId, uint32_t aEnterpriseNumber, const uint8_t *aServiceData, uint8_t aServiceDataLength) |
| { |
| NetworkDataTlv::Init(); |
| SetType(kTypeService); |
| |
| mFlagsServiceId = (aEnterpriseNumber == kThreadEnterpriseNumber) ? kThreadEnterpriseFlag : 0; |
| mFlagsServiceId |= (aServiceId & kServiceIdMask); |
| |
| if (aEnterpriseNumber != kThreadEnterpriseNumber) |
| { |
| mShared.mEnterpriseNumber = HostSwap32(aEnterpriseNumber); |
| mServiceDataLength = aServiceDataLength; |
| memcpy(&mServiceDataLength + sizeof(uint8_t), aServiceData, aServiceDataLength); |
| } |
| else |
| { |
| mShared.mServiceDataLengthThreadEnterprise = aServiceDataLength; |
| memcpy(&mShared.mServiceDataLengthThreadEnterprise + sizeof(uint8_t), aServiceData, aServiceDataLength); |
| } |
| |
| SetLength(GetFieldsLength()); |
| } |
| |
| /** |
| * This method indicates whether or not the TLV appears to be well-formed. |
| * |
| * @retval TRUE If the TLV appears to be well-formed. |
| * @retval FALSE If the TLV does not appear to be well-formed. |
| * |
| */ |
| bool IsValid(void) const |
| { |
| uint8_t length = GetLength(); |
| |
| return (length >= sizeof(mFlagsServiceId)) && |
| (length >= kMinLength + (IsThreadEnterprise() ? 0 : sizeof(uint32_t))) && |
| (static_cast<uint16_t>(length) + sizeof(NetworkDataTlv) >= |
| CalculateSize(GetEnterpriseNumber(), GetServiceDataLength())); |
| } |
| |
| /** |
| * This method returns the Service ID. It is in range 0x00-0x0f. |
| * |
| * @returns the Service ID. |
| * |
| */ |
| uint8_t GetServiceId(void) const { return (mFlagsServiceId & kServiceIdMask); } |
| |
| /** |
| * This method returns Enterprise Number field. |
| * |
| * @returns The Enterprise Number. |
| * |
| */ |
| uint32_t GetEnterpriseNumber(void) const |
| { |
| return IsThreadEnterprise() ? static_cast<uint32_t>(kThreadEnterpriseNumber) |
| : HostSwap32(mShared.mEnterpriseNumber); |
| } |
| |
| /** |
| * This method gets Service Data length. |
| * |
| * @returns length of the Service Data field in bytes. |
| * |
| */ |
| uint8_t GetServiceDataLength(void) const |
| { |
| return IsThreadEnterprise() ? mShared.mServiceDataLengthThreadEnterprise : mServiceDataLength; |
| } |
| |
| /** |
| * This method returns a pointer to the Service Data. |
| * |
| * @returns A pointer to the Service Data. |
| * |
| */ |
| uint8_t *GetServiceData(void) |
| { |
| return (IsThreadEnterprise() ? &mShared.mServiceDataLengthThreadEnterprise : &mServiceDataLength) + |
| sizeof(uint8_t); |
| } |
| |
| /** |
| * This method returns a pointer to the Service Data. |
| * |
| * @returns A pointer to the Service Data. |
| * |
| */ |
| const uint8_t *GetServiceData(void) const |
| { |
| return (IsThreadEnterprise() ? &mShared.mServiceDataLengthThreadEnterprise : &mServiceDataLength) + |
| sizeof(uint8_t); |
| } |
| |
| /** |
| * This method returns the Sub-TLVs length in bytes. |
| * |
| * @returns The Sub-TLVs length in bytes. |
| * |
| */ |
| uint8_t GetSubTlvsLength(void) { return GetLength() - GetFieldsLength(); } |
| |
| /** |
| * This method sets the Sub-TLVs length in bytes. |
| * |
| * @param[in] aLength The Sub-TLVs length in bytes. |
| * |
| */ |
| void SetSubTlvsLength(uint8_t aLength) { SetLength(GetFieldsLength() + aLength); } |
| |
| /** |
| * This method returns a pointer to the Sub-TLVs. |
| * |
| * @returns A pointer to the Sub-TLVs. |
| * |
| */ |
| NetworkDataTlv *GetSubTlvs(void) { return reinterpret_cast<NetworkDataTlv *>(GetValue() + GetFieldsLength()); } |
| |
| /** |
| * This method returns a pointer to the Sub-TLVs. |
| * |
| * @returns A pointer to the Sub-TLVs. |
| * |
| */ |
| const NetworkDataTlv *GetSubTlvs(void) const |
| { |
| return reinterpret_cast<const NetworkDataTlv *>(GetValue() + GetFieldsLength()); |
| } |
| |
| /** |
| * This static method calculates the total size (number of bytes) of a Service TLV with a given Enterprise Number |
| * and Service Data length. |
| * |
| * Note that the returned size does include the Type and Length fields in the TLV, but does not account for any |
| * sub-TLVs of the Service TLV. |
| * |
| * @param[in] aEnterpriseNumber A Enterprise Number. |
| * @param[in] aServiceDataLength A Service Data length. |
| * |
| * @returns The size (number of bytes) of the Service TLV. |
| * |
| */ |
| static uint16_t CalculateSize(uint32_t aEnterpriseNumber, uint8_t aServiceDataLength) |
| { |
| return sizeof(NetworkDataTlv) + kMinLength + aServiceDataLength + |
| ((aEnterpriseNumber == kThreadEnterpriseNumber) ? 0 : sizeof(uint32_t) /* mEnterpriseNumber */); |
| } |
| |
| private: |
| bool IsThreadEnterprise(void) const { return (mFlagsServiceId & kThreadEnterpriseFlag) != 0; } |
| |
| uint8_t GetFieldsLength(void) const |
| { |
| // Returns the length of TLV value's common fields (flags, enterprise |
| // number and service data) excluding any sub-TLVs. |
| |
| return kMinLength + (IsThreadEnterprise() ? 0 : sizeof(uint32_t)) + GetServiceDataLength(); |
| } |
| |
| enum |
| { |
| kThreadEnterpriseFlag = (1 << 7), |
| kServiceIdMask = 0xf, |
| kMinLength = sizeof(uint8_t) + sizeof(uint8_t), // Flags and Service Data length. |
| }; |
| |
| // When `kThreadEnterpriseFlag is set in the `mFlagsServiceId`, the |
| // `mEnterpriseNumber` field is elided and `mFlagsServiceId` is |
| // immediately followed by the Service Data length field (which is |
| // represented by `mServiceDataLengthThreadEnterprise`) |
| |
| uint8_t mFlagsServiceId; |
| union OT_TOOL_PACKED_FIELD |
| { |
| uint32_t mEnterpriseNumber; |
| uint8_t mServiceDataLengthThreadEnterprise; |
| } mShared; |
| uint8_t mServiceDataLength; |
| |
| } OT_TOOL_PACKED_END; |
| |
| /** |
| * This class implements Server Data TLV generation and parsing. |
| * |
| */ |
| OT_TOOL_PACKED_BEGIN |
| class ServerTlv : public NetworkDataTlv |
| { |
| public: |
| enum |
| { |
| kType = kTypeServer, ///< The TLV Type. |
| }; |
| |
| /** |
| * This method initializes the Server TLV. |
| * |
| * @param[in] aServer16 The Server16 value. |
| * @param[in] aServerData The Server Data. |
| * @param[in] aServerDataLength Server Data length in bytes. |
| * |
| */ |
| void Init(uint16_t aServer16, const uint8_t *aServerData, uint8_t aServerDataLength) |
| { |
| NetworkDataTlv::Init(); |
| SetType(kTypeServer); |
| SetServer16(aServer16); |
| memcpy(reinterpret_cast<uint8_t *>(this) + sizeof(*this), aServerData, aServerDataLength); |
| SetLength(sizeof(*this) - sizeof(NetworkDataTlv) + aServerDataLength); |
| } |
| |
| /** |
| * This method indicates whether or not the TLV appears to be well-formed. |
| * |
| * @retval TRUE If the TLV appears to be well-formed. |
| * @retval FALSE If the TLV does not appear to be well-formed. |
| * |
| */ |
| bool IsValid(void) const { return GetLength() >= (sizeof(*this) - sizeof(NetworkDataTlv)); } |
| |
| /** |
| * This method returns the Server16 value. |
| * |
| * @returns The Server16 value. |
| * |
| */ |
| uint16_t GetServer16(void) const { return HostSwap16(mServer16); } |
| |
| /* |
| * This method sets the Server16 value. |
| * |
| * @param[in] aServer16 The Server16 value. |
| * |
| */ |
| void SetServer16(uint16_t aServer16) { mServer16 = HostSwap16(aServer16); } |
| |
| /** |
| * This method returns the Server Data. |
| * |
| * @returns A pointer to the Server Data. |
| * |
| */ |
| const uint8_t *GetServerData(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); } |
| |
| /** |
| * This method returns the Server Data length in bytes. |
| * |
| * @returns The Server Data length in bytes. |
| * |
| */ |
| uint8_t GetServerDataLength(void) const { return GetLength() - (sizeof(*this) - sizeof(NetworkDataTlv)); } |
| |
| /** |
| * This method indicates whether two Server TLVs fully match. |
| * |
| * @param[in] aOther Another Server TLV to compare with it. |
| * |
| * @retval TRUE The two TLVs are equal. |
| * @retval FALSE The two TLVs are not equal. |
| * |
| */ |
| bool operator==(const ServerTlv &aOther) const |
| { |
| return (GetLength() == aOther.GetLength()) && (memcmp(GetValue(), aOther.GetValue(), GetLength()) == 0); |
| } |
| |
| /** |
| * This static method calculates the total size (number of bytes) of a Service TLV with a given Server Data length. |
| * |
| * Note that the returned size does include the Type and Length fields in the TLV. |
| * |
| * @param[in] aServerDataLength Server Data length in bytes. |
| * |
| * @returns The size (number of bytes) of the Server TLV. |
| * |
| */ |
| static uint16_t CalculateSize(uint8_t aServerDataLength) { return sizeof(ServerTlv) + aServerDataLength; } |
| |
| private: |
| uint16_t mServer16; |
| } OT_TOOL_PACKED_END; |
| |
| OT_TOOL_PACKED_BEGIN |
| class BackboneRouterServerData |
| { |
| public: |
| /** |
| * This method returns the sequence number of Backbone Router. |
| * |
| * @returns The sequence number of the Backbone Router. |
| * |
| */ |
| uint8_t GetSequenceNumber(void) const { return mSequenceNumber; } |
| |
| /** |
| * This method sets the sequence number of Backbone Router. |
| * |
| * @param[in] aSequenceNumber The sequence number of Backbone Router. |
| * |
| */ |
| void SetSequenceNumber(uint8_t aSequenceNumber) { mSequenceNumber = aSequenceNumber; } |
| |
| /** |
| * This method returns the Registration Delay (in seconds) of Backbone Router. |
| * |
| * @returns The BBR Registration Delay (in seconds) of Backbone Router. |
| * |
| */ |
| uint16_t GetReregistrationDelay(void) const { return HostSwap16(mReregistrationDelay); } |
| |
| /** |
| * This method sets the Registration Delay (in seconds) of Backbone Router. |
| * |
| * @param[in] aReregistrationDelay The Registration Delay (in seconds) of Backbone Router. |
| * |
| */ |
| void SetReregistrationDelay(uint16_t aReregistrationDelay) |
| { |
| mReregistrationDelay = HostSwap16(aReregistrationDelay); |
| } |
| |
| /** |
| * This method returns the multicast listener report timeout (in seconds) of Backbone Router. |
| * |
| * @returns The multicast listener report timeout (in seconds) of Backbone Router. |
| * |
| */ |
| uint32_t GetMlrTimeout(void) const { return HostSwap32(mMlrTimeout); } |
| |
| /** |
| * This method sets multicast listener report timeout (in seconds) of Backbone Router. |
| * |
| * @param[in] aMlrTimeout The multicast listener report timeout (in seconds) of Backbone Router. |
| * |
| */ |
| void SetMlrTimeout(uint32_t aMlrTimeout) { mMlrTimeout = HostSwap32(aMlrTimeout); } |
| |
| private: |
| uint8_t mSequenceNumber; |
| uint16_t mReregistrationDelay; |
| uint32_t mMlrTimeout; |
| } OT_TOOL_PACKED_END; |
| |
| /** |
| * @} |
| * |
| */ |
| |
| } // namespace NetworkData |
| } // namespace ot |
| |
| #endif // NETWORK_DATA_TLVS_HPP_ |