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