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