1 /* 2 * Copyright (c) 2016, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * This file includes definitions and methods for generating and processing Thread Network Layer TLVs. 32 */ 33 34 #ifndef THREAD_TLVS_HPP_ 35 #define THREAD_TLVS_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include "common/encoding.hpp" 40 #include "common/message.hpp" 41 #include "common/tlvs.hpp" 42 #include "meshcop/network_name.hpp" 43 #include "net/ip6_address.hpp" 44 #include "thread/mle.hpp" 45 #include "thread/mle_types.hpp" 46 47 namespace ot { 48 49 /** 50 * Implements Network Layer TLV generation and parsing. 51 */ 52 OT_TOOL_PACKED_BEGIN 53 class ThreadTlv : public ot::Tlv 54 { 55 public: 56 /** 57 * Network Layer TLV Types. 58 */ 59 enum Type : uint8_t 60 { 61 kTarget = 0, ///< Target EID TLV 62 kExtMacAddress = 1, ///< Extended MAC Address TLV 63 kRloc16 = 2, ///< RLOC16 TLV 64 kMeshLocalEid = 3, ///< ML-EID TLV 65 kStatus = 4, ///< Status TLV 66 kLastTransactionTime = 6, ///< Time Since Last Transaction TLV 67 kRouterMask = 7, ///< Router Mask TLV 68 kNdOption = 8, ///< ND Option TLV 69 kNdData = 9, ///< ND Data TLV 70 kThreadNetworkData = 10, ///< Thread Network Data TLV 71 kTimeout = 11, ///< Timeout TLV 72 kNetworkName = 12, ///< Network Name TLV 73 kIp6Addresses = 14, ///< IPv6 Addresses TLV 74 kCommissionerSessionId = 15, ///< Commissioner Session ID TLV 75 }; 76 77 /** 78 * Returns the Type value. 79 * 80 * @returns The Type value. 81 */ GetType(void) const82 Type GetType(void) const { return static_cast<Type>(ot::Tlv::GetType()); } 83 84 /** 85 * Sets the Type value. 86 * 87 * @param[in] aType The Type value. 88 */ SetType(Type aType)89 void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); } 90 91 } OT_TOOL_PACKED_END; 92 93 /** 94 * Defines Target TLV constants and types. 95 */ 96 typedef SimpleTlvInfo<ThreadTlv::kTarget, Ip6::Address> ThreadTargetTlv; 97 98 /** 99 * Defines Extended MAC Address TLV constants and types. 100 */ 101 typedef SimpleTlvInfo<ThreadTlv::kExtMacAddress, Mac::ExtAddress> ThreadExtMacAddressTlv; 102 103 /** 104 * Defines RLOC16 TLV constants and types. 105 */ 106 typedef UintTlvInfo<ThreadTlv::kRloc16, uint16_t> ThreadRloc16Tlv; 107 108 /** 109 * Defines ML-EID TLV constants and types. 110 */ 111 typedef SimpleTlvInfo<ThreadTlv::kMeshLocalEid, Ip6::InterfaceIdentifier> ThreadMeshLocalEidTlv; 112 113 /** 114 * Defines Time Since Last Transaction TLV constants and types. 115 */ 116 typedef UintTlvInfo<ThreadTlv::kLastTransactionTime, uint32_t> ThreadLastTransactionTimeTlv; 117 118 /** 119 * Defines Timeout TLV constants and types. 120 */ 121 typedef UintTlvInfo<ThreadTlv::kTimeout, uint32_t> ThreadTimeoutTlv; 122 123 /** 124 * Defines Network Name TLV constants and types. 125 */ 126 typedef StringTlvInfo<ThreadTlv::kNetworkName, MeshCoP::NetworkName::kMaxSize> ThreadNetworkNameTlv; 127 128 /** 129 * Defines Commissioner Session ID TLV constants and types. 130 */ 131 typedef UintTlvInfo<ThreadTlv::kCommissionerSessionId, uint16_t> ThreadCommissionerSessionIdTlv; 132 133 /** 134 * Defines Status TLV constants and types. 135 */ 136 class ThreadStatusTlv : public UintTlvInfo<ThreadTlv::kStatus, uint8_t> 137 { 138 public: 139 /** 140 * Status values. 141 */ 142 enum Status : uint8_t 143 { 144 kSuccess = 0, ///< Success. 145 kNoAddressAvailable = 1, ///< No address available. 146 kTooFewRouters = 2, ///< Address Solicit due to too few routers. 147 kHaveChildIdRequest = 3, ///< Address Solicit due to child ID request. 148 kParentPartitionChange = 4, ///< Address Solicit due to parent partition change 149 kBorderRouterRequest = 5, ///< Address Solicit from Border Router request. 150 kUnrecognizedStatus = 6, ///< The requested status is unrecognized or not meaningful in a request. 151 }; 152 153 /** 154 * Multicast Listener Registration (MLR) Status values 155 */ 156 enum MlrStatus 157 { 158 kMlrSuccess = 0, ///< Successful (de)registration of all IPv6 addresses. 159 kMlrInvalid = 2, ///< Invalid IPv6 address(es) in request. 160 kMlrNoPersistent = 3, ///< This device does not support persistent registrations. 161 kMlrNoResources = 4, ///< BBR resource shortage. 162 kMlrBbrNotPrimary = 5, ///< BBR is not Primary at this moment. 163 kMlrGeneralFailure = 6, ///< Reason(s) for failure are not further specified. 164 kMlrStatusMax = 6, ///< Max MLR status. 165 }; 166 167 /** 168 * Domain Unicast Address (DUA) Registration Status values 169 */ 170 enum DuaStatus : uint8_t 171 { 172 kDuaSuccess = 0, ///< Successful registration. 173 kDuaReRegister = 1, ///< Registration was accepted but immediate reregistration is required to solve. 174 kDuaInvalid = 2, ///< Registration rejected (Fatal): Target EID is not a valid DUA. 175 kDuaDuplicate = 3, ///< Registration rejected (Fatal): DUA is already in use by another device. 176 kDuaNoResources = 4, ///< Registration rejected (Non-fatal): Backbone Router Resource shortage. 177 kDuaNotPrimary = 5, ///< Registration rejected (Non-fatal): Backbone Router is not primary at this moment. 178 kDuaGeneralFailure = 6, ///< Registration failure (Non-fatal): Reason(s) not further specified. 179 }; 180 }; 181 182 /** 183 * Implements Router Mask TLV generation and parsing. 184 */ 185 class ThreadRouterMaskTlv : public ThreadTlv, public TlvInfo<ThreadTlv::kRouterMask> 186 { 187 public: 188 /** 189 * Initializes the TLV. 190 */ Init(void)191 void Init(void) 192 { 193 SetType(kRouterMask); 194 SetLength(sizeof(*this) - sizeof(ThreadTlv)); 195 mAssignedRouterIdMask.Clear(); 196 } 197 198 /** 199 * Indicates whether or not the TLV appears to be well-formed. 200 * 201 * @retval TRUE If the TLV appears to be well-formed. 202 * @retval FALSE If the TLV does not appear to be well-formed. 203 */ IsValid(void) const204 bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(ThreadTlv); } 205 206 /** 207 * Returns the ID Sequence value. 208 * 209 * @returns The ID Sequence value. 210 */ GetIdSequence(void) const211 uint8_t GetIdSequence(void) const { return mIdSequence; } 212 213 /** 214 * Sets the ID Sequence value. 215 * 216 * @param[in] aSequence The ID Sequence value. 217 */ SetIdSequence(uint8_t aSequence)218 void SetIdSequence(uint8_t aSequence) { mIdSequence = aSequence; } 219 220 /** 221 * Gets the Assigned Router ID Mask. 222 * 223 * @returns The Assigned Router ID Mask. 224 */ GetAssignedRouterIdMask(void) const225 const Mle::RouterIdSet &GetAssignedRouterIdMask(void) const { return mAssignedRouterIdMask; } 226 227 /** 228 * Gets the Assigned Router ID Mask. 229 * 230 * @returns The Assigned Router ID Mask. 231 */ GetAssignedRouterIdMask(void)232 Mle::RouterIdSet &GetAssignedRouterIdMask(void) { return mAssignedRouterIdMask; } 233 234 /** 235 * Sets the Assigned Router ID Mask. 236 * 237 * @param[in] aRouterIdSet A reference to the Assigned Router ID Mask. 238 */ SetAssignedRouterIdMask(const Mle::RouterIdSet & aRouterIdSet)239 void SetAssignedRouterIdMask(const Mle::RouterIdSet &aRouterIdSet) { mAssignedRouterIdMask = aRouterIdSet; } 240 241 private: 242 uint8_t mIdSequence; 243 Mle::RouterIdSet mAssignedRouterIdMask; 244 }; 245 246 /** 247 * Implements Thread Network Data TLV generation and parsing. 248 */ 249 OT_TOOL_PACKED_BEGIN 250 class ThreadNetworkDataTlv : public ThreadTlv, public TlvInfo<ThreadTlv::kThreadNetworkData> 251 { 252 public: 253 /** 254 * Initializes the TLV. 255 */ Init(void)256 void Init(void) 257 { 258 SetType(kThreadNetworkData); 259 SetLength(0); 260 } 261 262 /** 263 * Overrides same method of the base class 264 * 265 * @retval TRUE the TLV appears to be well-formed. 266 */ IsValid(void) const267 bool IsValid(void) const { return true; } 268 269 /** 270 * Returns a pointer to the Network Data TLVs. 271 * 272 * @returns A pointer to the Network Data TLVs. 273 */ GetTlvs(void)274 uint8_t *GetTlvs(void) { return mTlvs; } 275 276 private: 277 static constexpr uint8_t kMaxSize = 255; 278 279 uint8_t mTlvs[kMaxSize]; 280 } OT_TOOL_PACKED_END; 281 282 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 283 284 /** 285 * Implements IPv6 Addresses TLV generation and parsing. 286 */ 287 OT_TOOL_PACKED_BEGIN 288 class Ip6AddressesTlv : public ThreadTlv, public TlvInfo<ThreadTlv::kIp6Addresses> 289 { 290 public: 291 // Thread 1.2.0 5.19.13 limits the number of IPv6 addresses to [1, 15]. 292 static constexpr uint8_t kMinAddresses = 1; 293 static constexpr uint8_t kMaxAddresses = OT_IP6_MAX_MLR_ADDRESSES; 294 295 /** 296 * Initializes the TLV. 297 */ Init(void)298 void Init(void) { SetType(kIp6Addresses); } 299 300 /** 301 * Indicates whether or not the TLV appears to be well-formed. 302 * 303 * @retval TRUE If the TLV appears to be well-formed. 304 * @retval FALSE If the TLV does not appear to be well-formed. 305 */ IsValid(void) const306 bool IsValid(void) const 307 { 308 return GetLength() >= sizeof(Ip6::Address) * Ip6AddressesTlv::kMinAddresses && 309 GetLength() <= sizeof(Ip6::Address) * Ip6AddressesTlv::kMaxAddresses && 310 (GetLength() % sizeof(Ip6::Address)) == 0; 311 } 312 313 /** 314 * Returns a pointer to the IPv6 address entry. 315 * 316 * @param[in] aIndex The index into the IPv6 address list. 317 * 318 * @returns A reference to the IPv6 address. 319 */ GetIp6Address(uint8_t aIndex) const320 const Ip6::Address &GetIp6Address(uint8_t aIndex) const 321 { 322 return *reinterpret_cast<const Ip6::Address *>(GetValue() + (aIndex * sizeof(Ip6::Address))); 323 } 324 } OT_TOOL_PACKED_END; 325 326 #endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 327 328 } // namespace ot 329 330 #endif // THREAD_TLVS_HPP_ 331