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 */ 53 OT_TOOL_PACKED_BEGIN 54 class ThreadTlv : public ot::Tlv 55 { 56 public: 57 /** 58 * Network Layer TLV Types. 59 * 60 */ 61 enum Type : uint8_t 62 { 63 kTarget = 0, ///< Target EID TLV 64 kExtMacAddress = 1, ///< Extended MAC Address TLV 65 kRloc16 = 2, ///< RLOC16 TLV 66 kMeshLocalEid = 3, ///< ML-EID TLV 67 kStatus = 4, ///< Status TLV 68 kLastTransactionTime = 6, ///< Time Since Last Transaction TLV 69 kRouterMask = 7, ///< Router Mask TLV 70 kNdOption = 8, ///< ND Option TLV 71 kNdData = 9, ///< ND Data TLV 72 kThreadNetworkData = 10, ///< Thread Network Data TLV 73 kTimeout = 11, ///< Timeout TLV 74 kNetworkName = 12, ///< Network Name TLV 75 kIp6Addresses = 14, ///< IPv6 Addresses TLV 76 kCommissionerSessionId = 15, ///< Commissioner Session ID TLV 77 }; 78 79 /** 80 * Returns the Type value. 81 * 82 * @returns The Type value. 83 * 84 */ GetType(void) const85 Type GetType(void) const { return static_cast<Type>(ot::Tlv::GetType()); } 86 87 /** 88 * Sets the Type value. 89 * 90 * @param[in] aType The Type value. 91 * 92 */ SetType(Type aType)93 void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); } 94 95 } OT_TOOL_PACKED_END; 96 97 /** 98 * Defines Target TLV constants and types. 99 * 100 */ 101 typedef SimpleTlvInfo<ThreadTlv::kTarget, Ip6::Address> ThreadTargetTlv; 102 103 /** 104 * Defines Extended MAC Address TLV constants and types. 105 * 106 */ 107 typedef SimpleTlvInfo<ThreadTlv::kExtMacAddress, Mac::ExtAddress> ThreadExtMacAddressTlv; 108 109 /** 110 * Defines RLOC16 TLV constants and types. 111 * 112 */ 113 typedef UintTlvInfo<ThreadTlv::kRloc16, uint16_t> ThreadRloc16Tlv; 114 115 /** 116 * Defines ML-EID TLV constants and types. 117 * 118 */ 119 typedef SimpleTlvInfo<ThreadTlv::kMeshLocalEid, Ip6::InterfaceIdentifier> ThreadMeshLocalEidTlv; 120 121 /** 122 * Defines Time Since Last Transaction TLV constants and types. 123 * 124 */ 125 typedef UintTlvInfo<ThreadTlv::kLastTransactionTime, uint32_t> ThreadLastTransactionTimeTlv; 126 127 /** 128 * Defines Timeout TLV constants and types. 129 * 130 */ 131 typedef UintTlvInfo<ThreadTlv::kTimeout, uint32_t> ThreadTimeoutTlv; 132 133 /** 134 * Defines Network Name TLV constants and types. 135 * 136 */ 137 typedef StringTlvInfo<ThreadTlv::kNetworkName, MeshCoP::NetworkName::kMaxSize> ThreadNetworkNameTlv; 138 139 /** 140 * Defines Commissioner Session ID TLV constants and types. 141 * 142 */ 143 typedef UintTlvInfo<ThreadTlv::kCommissionerSessionId, uint16_t> ThreadCommissionerSessionIdTlv; 144 145 /** 146 * Defines Status TLV constants and types. 147 * 148 */ 149 class ThreadStatusTlv : public UintTlvInfo<ThreadTlv::kStatus, uint8_t> 150 { 151 public: 152 /** 153 * Status values. 154 * 155 */ 156 enum Status : uint8_t 157 { 158 kSuccess = 0, ///< Success. 159 kNoAddressAvailable = 1, ///< No address available. 160 kTooFewRouters = 2, ///< Address Solicit due to too few routers. 161 kHaveChildIdRequest = 3, ///< Address Solicit due to child ID request. 162 kParentPartitionChange = 4, ///< Address Solicit due to parent partition change 163 kBorderRouterRequest = 5, ///< Address Solicit from Border Router request. 164 kUnrecognizedStatus = 6, ///< The requested status is unrecognized or not meaningful in a request. 165 }; 166 167 /** 168 * Multicast Listener Registration (MLR) Status values 169 * 170 */ 171 enum MlrStatus 172 { 173 kMlrSuccess = 0, ///< Successful (de)registration of all IPv6 addresses. 174 kMlrInvalid = 2, ///< Invalid IPv6 address(es) in request. 175 kMlrNoPersistent = 3, ///< This device does not support persistent registrations. 176 kMlrNoResources = 4, ///< BBR resource shortage. 177 kMlrBbrNotPrimary = 5, ///< BBR is not Primary at this moment. 178 kMlrGeneralFailure = 6, ///< Reason(s) for failure are not further specified. 179 kMlrStatusMax = 6, ///< Max MLR status. 180 }; 181 182 /** 183 * Domain Unicast Address (DUA) Registration Status values 184 * 185 */ 186 enum DuaStatus : uint8_t 187 { 188 kDuaSuccess = 0, ///< Successful registration. 189 kDuaReRegister = 1, ///< Registration was accepted but immediate reregistration is required to solve. 190 kDuaInvalid = 2, ///< Registration rejected (Fatal): Target EID is not a valid DUA. 191 kDuaDuplicate = 3, ///< Registration rejected (Fatal): DUA is already in use by another device. 192 kDuaNoResources = 4, ///< Registration rejected (Non-fatal): Backbone Router Resource shortage. 193 kDuaNotPrimary = 5, ///< Registration rejected (Non-fatal): Backbone Router is not primary at this moment. 194 kDuaGeneralFailure = 6, ///< Registration failure (Non-fatal): Reason(s) not further specified. 195 }; 196 }; 197 198 /** 199 * Implements Router Mask TLV generation and parsing. 200 * 201 */ 202 class ThreadRouterMaskTlv : public ThreadTlv, public TlvInfo<ThreadTlv::kRouterMask> 203 { 204 public: 205 /** 206 * Initializes the TLV. 207 * 208 */ Init(void)209 void Init(void) 210 { 211 SetType(kRouterMask); 212 SetLength(sizeof(*this) - sizeof(ThreadTlv)); 213 mAssignedRouterIdMask.Clear(); 214 } 215 216 /** 217 * Indicates whether or not the TLV appears to be well-formed. 218 * 219 * @retval TRUE If the TLV appears to be well-formed. 220 * @retval FALSE If the TLV does not appear to be well-formed. 221 * 222 */ IsValid(void) const223 bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(ThreadTlv); } 224 225 /** 226 * Returns the ID Sequence value. 227 * 228 * @returns The ID Sequence value. 229 * 230 */ GetIdSequence(void) const231 uint8_t GetIdSequence(void) const { return mIdSequence; } 232 233 /** 234 * Sets the ID Sequence value. 235 * 236 * @param[in] aSequence The ID Sequence value. 237 * 238 */ SetIdSequence(uint8_t aSequence)239 void SetIdSequence(uint8_t aSequence) { mIdSequence = aSequence; } 240 241 /** 242 * Gets the Assigned Router ID Mask. 243 * 244 * @returns The Assigned Router ID Mask. 245 * 246 */ GetAssignedRouterIdMask(void) const247 const Mle::RouterIdSet &GetAssignedRouterIdMask(void) const { return mAssignedRouterIdMask; } 248 249 /** 250 * Gets the Assigned Router ID Mask. 251 * 252 * @returns The Assigned Router ID Mask. 253 * 254 */ GetAssignedRouterIdMask(void)255 Mle::RouterIdSet &GetAssignedRouterIdMask(void) { return mAssignedRouterIdMask; } 256 257 /** 258 * Sets the Assigned Router ID Mask. 259 * 260 * @param[in] aRouterIdSet A reference to the Assigned Router ID Mask. 261 * 262 */ SetAssignedRouterIdMask(const Mle::RouterIdSet & aRouterIdSet)263 void SetAssignedRouterIdMask(const Mle::RouterIdSet &aRouterIdSet) { mAssignedRouterIdMask = aRouterIdSet; } 264 265 private: 266 uint8_t mIdSequence; 267 Mle::RouterIdSet mAssignedRouterIdMask; 268 }; 269 270 /** 271 * Implements Thread Network Data TLV generation and parsing. 272 * 273 */ 274 OT_TOOL_PACKED_BEGIN 275 class ThreadNetworkDataTlv : public ThreadTlv, public TlvInfo<ThreadTlv::kThreadNetworkData> 276 { 277 public: 278 /** 279 * Initializes the TLV. 280 * 281 */ Init(void)282 void Init(void) 283 { 284 SetType(kThreadNetworkData); 285 SetLength(0); 286 } 287 288 /** 289 * Overrides same method of the base class 290 * 291 * @retval TRUE the TLV appears to be well-formed. 292 * 293 */ IsValid(void) const294 bool IsValid(void) const { return true; } 295 296 /** 297 * Returns a pointer to the Network Data TLVs. 298 * 299 * @returns A pointer to the Network Data TLVs. 300 * 301 */ GetTlvs(void)302 uint8_t *GetTlvs(void) { return mTlvs; } 303 304 private: 305 static constexpr uint8_t kMaxSize = 255; 306 307 uint8_t mTlvs[kMaxSize]; 308 } OT_TOOL_PACKED_END; 309 310 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 311 312 /** 313 * Implements IPv6 Addresses TLV generation and parsing. 314 * 315 */ 316 OT_TOOL_PACKED_BEGIN 317 class Ip6AddressesTlv : public ThreadTlv, public TlvInfo<ThreadTlv::kIp6Addresses> 318 { 319 public: 320 // Thread 1.2.0 5.19.13 limits the number of IPv6 addresses to [1, 15]. 321 static constexpr uint8_t kMinAddresses = 1; 322 static constexpr uint8_t kMaxAddresses = OT_IP6_MAX_MLR_ADDRESSES; 323 324 /** 325 * Initializes the TLV. 326 * 327 */ Init(void)328 void Init(void) { SetType(kIp6Addresses); } 329 330 /** 331 * Indicates whether or not the TLV appears to be well-formed. 332 * 333 * @retval TRUE If the TLV appears to be well-formed. 334 * @retval FALSE If the TLV does not appear to be well-formed. 335 * 336 */ IsValid(void) const337 bool IsValid(void) const 338 { 339 return GetLength() >= sizeof(Ip6::Address) * Ip6AddressesTlv::kMinAddresses && 340 GetLength() <= sizeof(Ip6::Address) * Ip6AddressesTlv::kMaxAddresses && 341 (GetLength() % sizeof(Ip6::Address)) == 0; 342 } 343 344 /** 345 * Returns a pointer to the IPv6 address entry. 346 * 347 * @param[in] aIndex The index into the IPv6 address list. 348 * 349 * @returns A reference to the IPv6 address. 350 * 351 */ GetIp6Address(uint8_t aIndex) const352 const Ip6::Address &GetIp6Address(uint8_t aIndex) const 353 { 354 return *reinterpret_cast<const Ip6::Address *>(GetValue() + (aIndex * sizeof(Ip6::Address))); 355 } 356 } OT_TOOL_PACKED_END; 357 358 #endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 359 360 } // namespace ot 361 362 #endif // THREAD_TLVS_HPP_ 363