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