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 for generating and processing MLE TLVs. 32 */ 33 34 #ifndef MLE_TLVS_HPP_ 35 #define MLE_TLVS_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include "common/encoding.hpp" 40 #include "common/message.hpp" 41 #include "common/preference.hpp" 42 #include "common/tlvs.hpp" 43 #include "meshcop/timestamp.hpp" 44 #include "net/ip6_address.hpp" 45 #include "thread/link_metrics_tlvs.hpp" 46 #include "thread/mle_types.hpp" 47 48 namespace ot { 49 50 namespace Mle { 51 52 /** 53 * @addtogroup core-mle-tlvs 54 * 55 * @brief 56 * This module includes definitions for generating and processing MLE TLVs. 57 * 58 * @{ 59 */ 60 61 /** 62 * Implements MLE TLV generation and parsing. 63 */ 64 OT_TOOL_PACKED_BEGIN 65 class Tlv : public ot::Tlv 66 { 67 public: 68 /** 69 * MLE TLV Types. 70 */ 71 enum Type : uint8_t 72 { 73 kSourceAddress = 0, ///< Source Address TLV 74 kMode = 1, ///< Mode TLV 75 kTimeout = 2, ///< Timeout TLV 76 kChallenge = 3, ///< Challenge TLV 77 kResponse = 4, ///< Response TLV 78 kLinkFrameCounter = 5, ///< Link-Layer Frame Counter TLV 79 kLinkQuality = 6, ///< Link Quality TLV 80 kNetworkParameter = 7, ///< Network Parameter TLV 81 kMleFrameCounter = 8, ///< MLE Frame Counter TLV 82 kRoute = 9, ///< Route64 TLV 83 kAddress16 = 10, ///< Address16 TLV 84 kLeaderData = 11, ///< Leader Data TLV 85 kNetworkData = 12, ///< Network Data TLV 86 kTlvRequest = 13, ///< TLV Request TLV 87 kScanMask = 14, ///< Scan Mask TLV 88 kConnectivity = 15, ///< Connectivity TLV 89 kLinkMargin = 16, ///< Link Margin TLV 90 kStatus = 17, ///< Status TLV 91 kVersion = 18, ///< Version TLV 92 kAddressRegistration = 19, ///< Address Registration TLV 93 kChannel = 20, ///< Channel TLV 94 kPanId = 21, ///< PAN ID TLV 95 kActiveTimestamp = 22, ///< Active Timestamp TLV 96 kPendingTimestamp = 23, ///< Pending Timestamp TLV 97 kActiveDataset = 24, ///< Active Operational Dataset TLV 98 kPendingDataset = 25, ///< Pending Operational Dataset TLV 99 kDiscovery = 26, ///< Thread Discovery TLV 100 kSupervisionInterval = 27, ///< Supervision Interval TLV 101 kWakeupChannel = 74, ///< Wakeup Channel TLV 102 kCslChannel = 80, ///< CSL Channel TLV 103 kCslTimeout = 85, ///< CSL Timeout TLV 104 kCslClockAccuracy = 86, ///< CSL Clock Accuracy TLV 105 kLinkMetricsQuery = 87, ///< Link Metrics Query TLV 106 kLinkMetricsManagement = 88, ///< Link Metrics Management TLV 107 kLinkMetricsReport = 89, ///< Link Metrics Report TLV 108 kLinkProbe = 90, ///< Link Probe TLV 109 110 /** 111 * Applicable/Required only when time synchronization service 112 * (`OPENTHREAD_CONFIG_TIME_SYNC_ENABLE`) is enabled. 113 */ 114 kTimeRequest = 252, ///< Time Request TLV 115 kTimeParameter = 253, ///< Time Parameter TLV 116 kXtalAccuracy = 254, ///< XTAL Accuracy TLV 117 118 kInvalid = 255, 119 }; 120 121 /** 122 * Returns the Type value. 123 * 124 * @returns The Type value. 125 */ GetType(void) const126 Type GetType(void) const { return static_cast<Type>(ot::Tlv::GetType()); } 127 128 /** 129 * Sets the Type value. 130 * 131 * @param[in] aType The Type value. 132 */ SetType(Type aType)133 void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); } 134 135 } OT_TOOL_PACKED_END; 136 137 /** 138 * Defines Source Address TLV constants and types. 139 */ 140 typedef UintTlvInfo<Tlv::kSourceAddress, uint16_t> SourceAddressTlv; 141 142 /** 143 * Defines Mode TLV constants and types. 144 */ 145 typedef UintTlvInfo<Tlv::kMode, uint8_t> ModeTlv; 146 147 /** 148 * Defines Timeout TLV constants and types. 149 */ 150 typedef UintTlvInfo<Tlv::kTimeout, uint32_t> TimeoutTlv; 151 152 /** 153 * Defines Challenge TLV constants and types. 154 */ 155 typedef TlvInfo<Tlv::kChallenge> ChallengeTlv; 156 157 /** 158 * Defines Response TLV constants and types. 159 */ 160 typedef TlvInfo<Tlv::kResponse> ResponseTlv; 161 162 /** 163 * Defines Link Frame Counter TLV constants and types. 164 */ 165 typedef UintTlvInfo<Tlv::kLinkFrameCounter, uint32_t> LinkFrameCounterTlv; 166 167 /** 168 * Defines MLE Frame Counter TLV constants and types. 169 */ 170 typedef UintTlvInfo<Tlv::kMleFrameCounter, uint32_t> MleFrameCounterTlv; 171 172 /** 173 * Defines Address16 TLV constants and types. 174 */ 175 typedef UintTlvInfo<Tlv::kAddress16, uint16_t> Address16Tlv; 176 177 /** 178 * Defines Network Data TLV constants and types. 179 */ 180 typedef TlvInfo<Tlv::kNetworkData> NetworkDataTlv; 181 182 /** 183 * Defines TLV Request TLV constants and types. 184 */ 185 typedef TlvInfo<Tlv::kTlvRequest> TlvRequestTlv; 186 187 /** 188 * Defines Link Margin TLV constants and types. 189 */ 190 typedef UintTlvInfo<Tlv::kLinkMargin, uint8_t> LinkMarginTlv; 191 192 /** 193 * Defines Version TLV constants and types. 194 */ 195 typedef UintTlvInfo<Tlv::kVersion, uint16_t> VersionTlv; 196 197 /** 198 * Defines PAN ID TLV constants and types. 199 */ 200 typedef UintTlvInfo<Tlv::kPanId, uint16_t> PanIdTlv; 201 202 /** 203 * Defines Active Timestamp TLV constants and types. 204 */ 205 typedef SimpleTlvInfo<Tlv::kActiveTimestamp, MeshCoP::Timestamp> ActiveTimestampTlv; 206 207 /** 208 * Defines Pending Timestamp TLV constants and types. 209 */ 210 typedef SimpleTlvInfo<Tlv::kPendingTimestamp, MeshCoP::Timestamp> PendingTimestampTlv; 211 212 /** 213 * Defines Timeout TLV constants and types. 214 */ 215 typedef UintTlvInfo<Tlv::kSupervisionInterval, uint16_t> SupervisionIntervalTlv; 216 217 /** 218 * Defines CSL Timeout TLV constants and types. 219 */ 220 typedef UintTlvInfo<Tlv::kCslTimeout, uint32_t> CslTimeoutTlv; 221 222 /** 223 * Defines XTAL Accuracy TLV constants and types. 224 */ 225 typedef UintTlvInfo<Tlv::kXtalAccuracy, uint16_t> XtalAccuracyTlv; 226 227 #if !OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE 228 229 /** 230 * Implements Route TLV generation and parsing. 231 */ 232 OT_TOOL_PACKED_BEGIN 233 class RouteTlv : public Tlv, public TlvInfo<Tlv::kRoute> 234 { 235 public: 236 /** 237 * Initializes the TLV. 238 */ 239 void Init(void); 240 241 /** 242 * Indicates whether or not the TLV appears to be well-formed. 243 * 244 * @retval TRUE If the TLV appears to be well-formed. 245 * @retval FALSE If the TLV does not appear to be well-formed. 246 */ 247 bool IsValid(void) const; 248 249 /** 250 * Returns the Router ID Sequence value. 251 * 252 * @returns The Router ID Sequence value. 253 */ GetRouterIdSequence(void) const254 uint8_t GetRouterIdSequence(void) const { return mRouterIdSequence; } 255 256 /** 257 * Sets the Router ID Sequence value. 258 * 259 * @param[in] aSequence The Router ID Sequence value. 260 */ SetRouterIdSequence(uint8_t aSequence)261 void SetRouterIdSequence(uint8_t aSequence) { mRouterIdSequence = aSequence; } 262 263 /** 264 * Gets the Router ID Mask. 265 */ GetRouterIdMask(void) const266 const RouterIdSet &GetRouterIdMask(void) const { return mRouterIdMask; } 267 268 /** 269 * Sets the Router ID Mask. 270 * 271 * @param[in] aRouterIdSet The Router ID Mask to set. 272 */ SetRouterIdMask(const RouterIdSet & aRouterIdSet)273 void SetRouterIdMask(const RouterIdSet &aRouterIdSet) { mRouterIdMask = aRouterIdSet; } 274 275 /** 276 * Indicates whether or not a Router ID bit is set. 277 * 278 * @param[in] aRouterId The Router ID bit. 279 * 280 * @retval TRUE If the Router ID bit is set. 281 * @retval FALSE If the Router ID bit is not set. 282 */ IsRouterIdSet(uint8_t aRouterId) const283 bool IsRouterIdSet(uint8_t aRouterId) const { return mRouterIdMask.Contains(aRouterId); } 284 285 /** 286 * Indicates whether the `RouteTlv` is a singleton, i.e., only one router is allocated. 287 * 288 * @retval TRUE It is a singleton. 289 * @retval FALSE It is not a singleton. 290 */ IsSingleton(void) const291 bool IsSingleton(void) const { return IsValid() && (mRouterIdMask.GetNumberOfAllocatedIds() <= 1); } 292 293 /** 294 * Returns the Route Data Length value. 295 * 296 * @returns The Route Data Length value. 297 */ GetRouteDataLength(void) const298 uint8_t GetRouteDataLength(void) const { return GetLength() - sizeof(mRouterIdSequence) - sizeof(mRouterIdMask); } 299 300 /** 301 * Sets the Route Data Length value. 302 * 303 * @param[in] aLength The Route Data Length value. 304 */ SetRouteDataLength(uint8_t aLength)305 void SetRouteDataLength(uint8_t aLength) { SetLength(sizeof(mRouterIdSequence) + sizeof(mRouterIdMask) + aLength); } 306 307 /** 308 * Returns the Route Cost value for a given Router index. 309 * 310 * @param[in] aRouterIndex The Router index. 311 * 312 * @returns The Route Cost value for a given Router index. 313 */ GetRouteCost(uint8_t aRouterIndex) const314 uint8_t GetRouteCost(uint8_t aRouterIndex) const { return mRouteData[aRouterIndex] & kRouteCostMask; } 315 316 /** 317 * Returns the Link Quality In value for a given Router index. 318 * 319 * @param[in] aRouterIndex The Router index. 320 * 321 * @returns The Link Quality In value for a given Router index. 322 */ GetLinkQualityIn(uint8_t aRouterIndex) const323 LinkQuality GetLinkQualityIn(uint8_t aRouterIndex) const 324 { 325 return static_cast<LinkQuality>((mRouteData[aRouterIndex] & kLinkQualityInMask) >> kLinkQualityInOffset); 326 } 327 328 /** 329 * Returns the Link Quality Out value for a given Router index. 330 * 331 * @param[in] aRouterIndex The Router index. 332 * 333 * @returns The Link Quality Out value for a given Router index. 334 */ GetLinkQualityOut(uint8_t aRouterIndex) const335 LinkQuality GetLinkQualityOut(uint8_t aRouterIndex) const 336 { 337 return static_cast<LinkQuality>((mRouteData[aRouterIndex] & kLinkQualityOutMask) >> kLinkQualityOutOffset); 338 } 339 340 /** 341 * Sets the Route Data (Link Quality In/Out and Route Cost) for a given Router index. 342 * 343 * @param[in] aRouterIndex The Router index. 344 * @param[in] aLinkQualityIn The Link Quality In value. 345 * @param[in] aLinkQualityOut The Link Quality Out value. 346 * @param[in] aRouteCost The Route Cost value. 347 */ SetRouteData(uint8_t aRouterIndex,LinkQuality aLinkQualityIn,LinkQuality aLinkQualityOut,uint8_t aRouteCost)348 void SetRouteData(uint8_t aRouterIndex, LinkQuality aLinkQualityIn, LinkQuality aLinkQualityOut, uint8_t aRouteCost) 349 { 350 mRouteData[aRouterIndex] = (((aLinkQualityIn << kLinkQualityInOffset) & kLinkQualityInMask) | 351 ((aLinkQualityOut << kLinkQualityOutOffset) & kLinkQualityOutMask) | 352 ((aRouteCost << kRouteCostOffset) & kRouteCostMask)); 353 } 354 355 private: 356 static constexpr uint8_t kLinkQualityOutOffset = 6; 357 static constexpr uint8_t kLinkQualityOutMask = 3 << kLinkQualityOutOffset; 358 static constexpr uint8_t kLinkQualityInOffset = 4; 359 static constexpr uint8_t kLinkQualityInMask = 3 << kLinkQualityInOffset; 360 static constexpr uint8_t kRouteCostOffset = 0; 361 static constexpr uint8_t kRouteCostMask = 0xf << kRouteCostOffset; 362 363 uint8_t mRouterIdSequence; 364 RouterIdSet mRouterIdMask; 365 uint8_t mRouteData[kMaxRouterId + 1]; 366 } OT_TOOL_PACKED_END; 367 368 #else // OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE 369 370 /** 371 * Implements Route TLV generation and parsing. 372 */ 373 OT_TOOL_PACKED_BEGIN 374 class RouteTlv : public Tlv, public TlvInfo<Tlv::kRoute> 375 { 376 public: 377 /** 378 * Initializes the TLV. 379 */ Init(void)380 void Init(void) 381 { 382 SetType(kRoute); 383 SetLength(sizeof(*this) - sizeof(Tlv)); 384 } 385 386 /** 387 * Indicates whether or not the TLV appears to be well-formed. 388 * 389 * @retval TRUE If the TLV appears to be well-formed. 390 * @retval FALSE If the TLV does not appear to be well-formed. 391 */ IsValid(void) const392 bool IsValid(void) const { return GetLength() >= sizeof(mRouterIdSequence) + sizeof(mRouterIdMask); } 393 394 /** 395 * Returns the Router ID Sequence value. 396 * 397 * @returns The Router ID Sequence value. 398 */ GetRouterIdSequence(void) const399 uint8_t GetRouterIdSequence(void) const { return mRouterIdSequence; } 400 401 /** 402 * Sets the Router ID Sequence value. 403 * 404 * @param[in] aSequence The Router ID Sequence value. 405 */ SetRouterIdSequence(uint8_t aSequence)406 void SetRouterIdSequence(uint8_t aSequence) { mRouterIdSequence = aSequence; } 407 408 /** 409 * Gets the Router ID Mask. 410 */ GetRouterIdMask(void) const411 const RouterIdSet &GetRouterIdMask(void) const { return mRouterIdMask; } 412 413 /** 414 * Sets the Router ID Mask. 415 * 416 * @param[in] aRouterIdSet The Router ID Mask to set. 417 */ SetRouterIdMask(const RouterIdSet & aRouterIdSet)418 void SetRouterIdMask(const RouterIdSet &aRouterIdSet) { mRouterIdMask = aRouterIdSet; } 419 420 /** 421 * Indicates whether or not a Router ID bit is set. 422 * 423 * @param[in] aRouterId The Router ID. 424 * 425 * @retval TRUE If the Router ID bit is set. 426 * @retval FALSE If the Router ID bit is not set. 427 */ IsRouterIdSet(uint8_t aRouterId) const428 bool IsRouterIdSet(uint8_t aRouterId) const { return mRouterIdMask.Contains(aRouterId); } 429 430 /** 431 * Indicates whether the `RouteTlv` is a singleton, i.e., only one router is allocated. 432 * 433 * @retval TRUE It is a singleton. 434 * @retval FALSE It is not a singleton. 435 */ IsSingleton(void) const436 bool IsSingleton(void) const { return IsValid() && (mRouterIdMask.GetNumberOfAllocatedIds() <= 1); } 437 438 /** 439 * Sets the Router ID bit. 440 * 441 * @param[in] aRouterId The Router ID bit to set. 442 */ SetRouterId(uint8_t aRouterId)443 void SetRouterId(uint8_t aRouterId) { mRouterIdMask.Add(aRouterId); } 444 445 /** 446 * Returns the Route Data Length value. 447 * 448 * @returns The Route Data Length value in bytes 449 */ GetRouteDataLength(void) const450 uint8_t GetRouteDataLength(void) const { return GetLength() - sizeof(mRouterIdSequence) - sizeof(mRouterIdMask); } 451 452 /** 453 * Sets the Route Data Length value. 454 * 455 * @param[in] aLength The Route Data Length value in number of router entries 456 */ SetRouteDataLength(uint8_t aLength)457 void SetRouteDataLength(uint8_t aLength) 458 { 459 SetLength(sizeof(mRouterIdSequence) + sizeof(mRouterIdMask) + aLength + (aLength + 1) / 2); 460 } 461 462 /** 463 * Returns the Route Cost value for a given Router index. 464 * 465 * @param[in] aRouterIndex The Router index. 466 * 467 * @returns The Route Cost value for a given Router index. 468 */ GetRouteCost(uint8_t aRouterIndex) const469 uint8_t GetRouteCost(uint8_t aRouterIndex) const 470 { 471 if (aRouterIndex & 1) 472 { 473 return mRouteData[aRouterIndex + aRouterIndex / 2 + 1]; 474 } 475 else 476 { 477 return static_cast<uint8_t>((mRouteData[aRouterIndex + aRouterIndex / 2] & kRouteCostMask) 478 << kOddEntryOffset) | 479 ((mRouteData[aRouterIndex + aRouterIndex / 2 + 1] & 480 static_cast<uint8_t>(kRouteCostMask << kOddEntryOffset)) >> 481 kOddEntryOffset); 482 } 483 } 484 485 /** 486 * Returns the Link Quality In value for a given Router index. 487 * 488 * @param[in] aRouterIndex The Router index. 489 * 490 * @returns The Link Quality In value for a given Router index. 491 */ GetLinkQualityIn(uint8_t aRouterIndex) const492 LinkQuality GetLinkQualityIn(uint8_t aRouterIndex) const 493 { 494 int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0); 495 return static_cast<LinkQuality>( 496 (mRouteData[aRouterIndex + aRouterIndex / 2] & (kLinkQualityInMask >> offset)) >> 497 (kLinkQualityInOffset - offset)); 498 } 499 500 /** 501 * Returns the Link Quality Out value for a given Router index. 502 * 503 * @param[in] aRouterIndex The Router index. 504 * 505 * @returns The Link Quality Out value for a given Router index. 506 */ GetLinkQualityOut(uint8_t aRouterIndex) const507 LinkQuality GetLinkQualityOut(uint8_t aRouterIndex) const 508 { 509 int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0); 510 return static_cast<LinkQuality>( 511 (mRouteData[aRouterIndex + aRouterIndex / 2] & (kLinkQualityOutMask >> offset)) >> 512 (kLinkQualityOutOffset - offset)); 513 } 514 515 /** 516 * Sets the Route Data (Link Quality In/Out and Route Cost) for a given Router index. 517 * 518 * @param[in] aRouterIndex The Router index. 519 * @param[in] aLinkQualityIn The Link Quality In value. 520 * @param[in] aLinkQualityOut The Link Quality Out value. 521 * @param[in] aRouteCost The Route Cost value. 522 */ SetRouteData(uint8_t aRouterIndex,LinkQuality aLinkQualityIn,LinkQuality aLinkQualityOut,uint8_t aRouteCost)523 void SetRouteData(uint8_t aRouterIndex, LinkQuality aLinkQualityIn, LinkQuality aLinkQualityOut, uint8_t aRouteCost) 524 { 525 SetLinkQualityIn(aRouterIndex, aLinkQualityIn); 526 SetLinkQualityOut(aRouterIndex, aLinkQualityOut); 527 SetRouteCost(aRouterIndex, aRouteCost); 528 } 529 530 private: 531 static constexpr uint8_t kLinkQualityOutOffset = 6; 532 static constexpr uint8_t kLinkQualityOutMask = 3 << kLinkQualityOutOffset; 533 static constexpr uint8_t kLinkQualityInOffset = 4; 534 static constexpr uint8_t kLinkQualityInMask = 3 << kLinkQualityInOffset; 535 static constexpr uint8_t kRouteCostOffset = 0; 536 static constexpr uint8_t kRouteCostMask = 0xf << kRouteCostOffset; 537 static constexpr uint8_t kOddEntryOffset = 4; 538 SetRouteCost(uint8_t aRouterIndex,uint8_t aRouteCost)539 void SetRouteCost(uint8_t aRouterIndex, uint8_t aRouteCost) 540 { 541 if (aRouterIndex & 1) 542 { 543 mRouteData[aRouterIndex + aRouterIndex / 2 + 1] = aRouteCost; 544 } 545 else 546 { 547 mRouteData[aRouterIndex + aRouterIndex / 2] = 548 (mRouteData[aRouterIndex + aRouterIndex / 2] & ~kRouteCostMask) | 549 ((aRouteCost >> kOddEntryOffset) & kRouteCostMask); 550 mRouteData[aRouterIndex + aRouterIndex / 2 + 1] = static_cast<uint8_t>( 551 (mRouteData[aRouterIndex + aRouterIndex / 2 + 1] & ~(kRouteCostMask << kOddEntryOffset)) | 552 ((aRouteCost & kRouteCostMask) << kOddEntryOffset)); 553 } 554 } 555 SetLinkQualityIn(uint8_t aRouterIndex,uint8_t aLinkQuality)556 void SetLinkQualityIn(uint8_t aRouterIndex, uint8_t aLinkQuality) 557 { 558 int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0); 559 mRouteData[aRouterIndex + aRouterIndex / 2] = 560 (mRouteData[aRouterIndex + aRouterIndex / 2] & ~(kLinkQualityInMask >> offset)) | 561 ((aLinkQuality << (kLinkQualityInOffset - offset)) & (kLinkQualityInMask >> offset)); 562 } 563 SetLinkQualityOut(uint8_t aRouterIndex,LinkQuality aLinkQuality)564 void SetLinkQualityOut(uint8_t aRouterIndex, LinkQuality aLinkQuality) 565 { 566 int offset = ((aRouterIndex & 1) ? kOddEntryOffset : 0); 567 mRouteData[aRouterIndex + aRouterIndex / 2] = 568 (mRouteData[aRouterIndex + aRouterIndex / 2] & ~(kLinkQualityOutMask >> offset)) | 569 ((aLinkQuality << (kLinkQualityOutOffset - offset)) & (kLinkQualityOutMask >> offset)); 570 } 571 572 uint8_t mRouterIdSequence; 573 RouterIdSet mRouterIdMask; 574 // Since we do hold 12 (compressible to 11) bits of data per router, each entry occupies 1.5 bytes, 575 // consecutively. First 4 bits are link qualities, remaining 8 bits are route cost. 576 uint8_t mRouteData[kMaxRouterId + 1 + kMaxRouterId / 2 + 1]; 577 } OT_TOOL_PACKED_END; 578 579 #endif // OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE 580 581 /** 582 * Implements Leader Data TLV generation and parsing. 583 */ 584 OT_TOOL_PACKED_BEGIN 585 class LeaderDataTlv : public Tlv, public TlvInfo<Tlv::kLeaderData> 586 { 587 public: 588 /** 589 * Initializes the TLV. 590 */ Init(void)591 void Init(void) 592 { 593 SetType(kLeaderData); 594 SetLength(sizeof(*this) - sizeof(Tlv)); 595 } 596 597 /** 598 * Indicates whether or not the TLV appears to be well-formed. 599 * 600 * @retval TRUE If the TLV appears to be well-formed. 601 * @retval FALSE If the TLV does not appear to be well-formed. 602 */ IsValid(void) const603 bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); } 604 605 /** 606 * Gets the Leader Data info from TLV. 607 * 608 * @param[out] aLeaderData A reference to output Leader Data info. 609 */ Get(LeaderData & aLeaderData) const610 void Get(LeaderData &aLeaderData) const 611 { 612 aLeaderData.SetPartitionId(BigEndian::HostSwap32(mPartitionId)); 613 aLeaderData.SetWeighting(mWeighting); 614 aLeaderData.SetDataVersion(mDataVersion); 615 aLeaderData.SetStableDataVersion(mStableDataVersion); 616 aLeaderData.SetLeaderRouterId(mLeaderRouterId); 617 } 618 619 /** 620 * Sets the Leader Data. 621 * 622 * @param[in] aLeaderData A Leader Data. 623 */ Set(const LeaderData & aLeaderData)624 void Set(const LeaderData &aLeaderData) 625 { 626 mPartitionId = BigEndian::HostSwap32(aLeaderData.GetPartitionId()); 627 mWeighting = aLeaderData.GetWeighting(); 628 mDataVersion = aLeaderData.GetDataVersion(NetworkData::kFullSet); 629 mStableDataVersion = aLeaderData.GetDataVersion(NetworkData::kStableSubset); 630 mLeaderRouterId = aLeaderData.GetLeaderRouterId(); 631 } 632 633 private: 634 uint32_t mPartitionId; 635 uint8_t mWeighting; 636 uint8_t mDataVersion; 637 uint8_t mStableDataVersion; 638 uint8_t mLeaderRouterId; 639 } OT_TOOL_PACKED_END; 640 641 /** 642 * Implements Scan Mask TLV generation and parsing. 643 */ 644 class ScanMaskTlv : public UintTlvInfo<Tlv::kScanMask, uint8_t> 645 { 646 public: 647 static constexpr uint8_t kRouterFlag = 1 << 7; ///< Scan Mask Router Flag. 648 static constexpr uint8_t kEndDeviceFlag = 1 << 6; ///< Scan Mask End Device Flag. 649 650 /** 651 * Indicates whether or not the Router flag is set. 652 * 653 * @param[in] aMask A scan mask value. 654 * 655 * @retval TRUE If the Router flag is set. 656 * @retval FALSE If the Router flag is not set. 657 */ IsRouterFlagSet(uint8_t aMask)658 static bool IsRouterFlagSet(uint8_t aMask) { return (aMask & kRouterFlag) != 0; } 659 660 /** 661 * Indicates whether or not the End Device flag is set. 662 * 663 * @param[in] aMask A scan mask value. 664 * 665 * @retval TRUE If the End Device flag is set. 666 * @retval FALSE If the End Device flag is not set. 667 */ IsEndDeviceFlagSet(uint8_t aMask)668 static bool IsEndDeviceFlagSet(uint8_t aMask) { return (aMask & kEndDeviceFlag) != 0; } 669 }; 670 671 /** 672 * Implements Connectivity TLV generation and parsing. 673 */ 674 OT_TOOL_PACKED_BEGIN 675 class ConnectivityTlv : public Tlv, public TlvInfo<Tlv::kConnectivity> 676 { 677 public: 678 /** 679 * Initializes the TLV. 680 */ Init(void)681 void Init(void) 682 { 683 SetType(kConnectivity); 684 SetLength(sizeof(*this) - sizeof(Tlv)); 685 } 686 687 /** 688 * Indicates whether or not the TLV appears to be well-formed. 689 * 690 * @retval TRUE If the TLV appears to be well-formed. 691 * @retval FALSE If the TLV does not appear to be well-formed. 692 */ IsValid(void) const693 bool IsValid(void) const 694 { 695 return IsSedBufferingIncluded() || 696 (GetLength() == sizeof(*this) - sizeof(Tlv) - sizeof(mSedBufferSize) - sizeof(mSedDatagramCount)); 697 } 698 699 /** 700 * Indicates whether or not the sed buffer size and datagram count are included. 701 * 702 * @retval TRUE If the sed buffer size and datagram count are included. 703 * @retval FALSE If the sed buffer size and datagram count are not included. 704 */ IsSedBufferingIncluded(void) const705 bool IsSedBufferingIncluded(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); } 706 707 /** 708 * Returns the Parent Priority value. 709 * 710 * @returns The Parent Priority value. 711 */ 712 int8_t GetParentPriority(void) const; 713 714 /** 715 * Sets the Parent Priority value. 716 * 717 * @param[in] aParentPriority The Parent Priority value. 718 */ 719 void SetParentPriority(int8_t aParentPriority); 720 721 /** 722 * Returns the Link Quality 3 value. 723 * 724 * @returns The Link Quality 3 value. 725 */ GetLinkQuality3(void) const726 uint8_t GetLinkQuality3(void) const { return mLinkQuality3; } 727 728 /** 729 * Sets the Link Quality 3 value. 730 * 731 * @param[in] aLinkQuality The Link Quality 3 value. 732 */ SetLinkQuality3(uint8_t aLinkQuality)733 void SetLinkQuality3(uint8_t aLinkQuality) { mLinkQuality3 = aLinkQuality; } 734 735 /** 736 * Returns the Link Quality 2 value. 737 * 738 * @returns The Link Quality 2 value. 739 */ GetLinkQuality2(void) const740 uint8_t GetLinkQuality2(void) const { return mLinkQuality2; } 741 742 /** 743 * Sets the Link Quality 2 value. 744 * 745 * @param[in] aLinkQuality The Link Quality 2 value. 746 */ SetLinkQuality2(uint8_t aLinkQuality)747 void SetLinkQuality2(uint8_t aLinkQuality) { mLinkQuality2 = aLinkQuality; } 748 749 /** 750 * Sets the Link Quality 1 value. 751 * 752 * @returns The Link Quality 1 value. 753 */ GetLinkQuality1(void) const754 uint8_t GetLinkQuality1(void) const { return mLinkQuality1; } 755 756 /** 757 * Sets the Link Quality 1 value. 758 * 759 * @param[in] aLinkQuality The Link Quality 1 value. 760 */ SetLinkQuality1(uint8_t aLinkQuality)761 void SetLinkQuality1(uint8_t aLinkQuality) { mLinkQuality1 = aLinkQuality; } 762 763 /** 764 * Increments the Link Quality N field in TLV for a given Link Quality N (1,2,3). 765 * 766 * The Link Quality N field specifies the number of neighboring router devices with which the sender shares a link 767 * of quality N. 768 * 769 * @param[in] aLinkQuality The Link Quality N (1,2,3) field to update. 770 */ 771 void IncrementLinkQuality(LinkQuality aLinkQuality); 772 773 /** 774 * Sets the Active Routers value. 775 * 776 * @returns The Active Routers value. 777 */ GetActiveRouters(void) const778 uint8_t GetActiveRouters(void) const { return mActiveRouters; } 779 780 /** 781 * Indicates whether or not the partition is a singleton based on Active Routers value. 782 * 783 * @retval TRUE The partition is a singleton. 784 * @retval FALSE The partition is not a singleton. 785 */ IsSingleton(void) const786 bool IsSingleton(void) const { return (mActiveRouters <= 1); } 787 788 /** 789 * Sets the Active Routers value. 790 * 791 * @param[in] aActiveRouters The Active Routers value. 792 */ SetActiveRouters(uint8_t aActiveRouters)793 void SetActiveRouters(uint8_t aActiveRouters) { mActiveRouters = aActiveRouters; } 794 795 /** 796 * Returns the Leader Cost value. 797 * 798 * @returns The Leader Cost value. 799 */ GetLeaderCost(void) const800 uint8_t GetLeaderCost(void) const { return mLeaderCost; } 801 802 /** 803 * Sets the Leader Cost value. 804 * 805 * @param[in] aCost The Leader Cost value. 806 */ SetLeaderCost(uint8_t aCost)807 void SetLeaderCost(uint8_t aCost) { mLeaderCost = aCost; } 808 809 /** 810 * Returns the ID Sequence value. 811 * 812 * @returns The ID Sequence value. 813 */ GetIdSequence(void) const814 uint8_t GetIdSequence(void) const { return mIdSequence; } 815 816 /** 817 * Sets the ID Sequence value. 818 * 819 * @param[in] aSequence The ID Sequence value. 820 */ SetIdSequence(uint8_t aSequence)821 void SetIdSequence(uint8_t aSequence) { mIdSequence = aSequence; } 822 823 /** 824 * Returns the SED Buffer Size value. 825 * 826 * @returns The SED Buffer Size value. 827 */ GetSedBufferSize(void) const828 uint16_t GetSedBufferSize(void) const 829 { 830 uint16_t buffersize = OPENTHREAD_CONFIG_DEFAULT_SED_BUFFER_SIZE; 831 832 if (IsSedBufferingIncluded()) 833 { 834 buffersize = BigEndian::HostSwap16(mSedBufferSize); 835 } 836 return buffersize; 837 } 838 839 /** 840 * Sets the SED Buffer Size value. 841 * 842 * @param[in] aSedBufferSize The SED Buffer Size value. 843 */ SetSedBufferSize(uint16_t aSedBufferSize)844 void SetSedBufferSize(uint16_t aSedBufferSize) { mSedBufferSize = BigEndian::HostSwap16(aSedBufferSize); } 845 846 /** 847 * Returns the SED Datagram Count value. 848 * 849 * @returns The SED Datagram Count value. 850 */ GetSedDatagramCount(void) const851 uint8_t GetSedDatagramCount(void) const 852 { 853 uint8_t count = OPENTHREAD_CONFIG_DEFAULT_SED_DATAGRAM_COUNT; 854 855 if (IsSedBufferingIncluded()) 856 { 857 count = mSedDatagramCount; 858 } 859 return count; 860 } 861 862 /** 863 * Sets the SED Datagram Count value. 864 * 865 * @param[in] aSedDatagramCount The SED Datagram Count value. 866 */ SetSedDatagramCount(uint8_t aSedDatagramCount)867 void SetSedDatagramCount(uint8_t aSedDatagramCount) { mSedDatagramCount = aSedDatagramCount; } 868 869 private: 870 static constexpr uint8_t kFlagsParentPriorityOffset = 6; 871 static constexpr uint8_t kFlagsParentPriorityMask = (3 << kFlagsParentPriorityOffset); 872 873 uint8_t mFlags; 874 uint8_t mLinkQuality3; 875 uint8_t mLinkQuality2; 876 uint8_t mLinkQuality1; 877 uint8_t mLeaderCost; 878 uint8_t mIdSequence; 879 uint8_t mActiveRouters; 880 uint16_t mSedBufferSize; 881 uint8_t mSedDatagramCount; 882 } OT_TOOL_PACKED_END; 883 884 /** 885 * Specifies Status TLV status values. 886 */ 887 struct StatusTlv : public UintTlvInfo<Tlv::kStatus, uint8_t> 888 { 889 /** 890 * Status values. 891 */ 892 enum Status : uint8_t 893 { 894 kError = 1, ///< Error. 895 }; 896 }; 897 898 /** 899 * Provides constants and methods for generation and parsing of Address Registration TLV. 900 */ 901 class AddressRegistrationTlv : public TlvInfo<Tlv::kAddressRegistration> 902 { 903 public: 904 /** 905 * This constant defines the control byte to use in an uncompressed entry where the full IPv6 address is included in 906 * the TLV. 907 */ 908 static constexpr uint8_t kControlByteUncompressed = 0; 909 910 /** 911 * Returns the control byte to use in a compressed entry where the 64-prefix is replaced with a 912 * 6LoWPAN context identifier. 913 * 914 * @param[in] aContextId The 6LoWPAN context ID. 915 * 916 * @returns The control byte associated with compressed entry with @p aContextId. 917 */ ControlByteFor(uint8_t aContextId)918 static uint8_t ControlByteFor(uint8_t aContextId) { return kCompressed | (aContextId & kContextIdMask); } 919 920 /** 921 * Indicates whether or not an address entry is using compressed format. 922 * 923 * @param[in] aControlByte The control byte (the first byte in the entry). 924 * 925 * @retval TRUE If the entry uses compressed format. 926 * @retval FALSE If the entry uses uncompressed format. 927 */ IsEntryCompressed(uint8_t aControlByte)928 static bool IsEntryCompressed(uint8_t aControlByte) { return (aControlByte & kCompressed); } 929 930 /** 931 * Gets the context ID in a compressed entry. 932 * 933 * @param[in] aControlByte The control byte (the first byte in the entry). 934 * 935 * @returns The 6LoWPAN context ID. 936 */ GetContextId(uint8_t aControlByte)937 static uint8_t GetContextId(uint8_t aControlByte) { return (aControlByte & kContextIdMask); } 938 939 AddressRegistrationTlv(void) = delete; 940 941 private: 942 static constexpr uint8_t kCompressed = 1 << 7; 943 static constexpr uint8_t kContextIdMask = 0xf; 944 }; 945 946 /** 947 * Implements Channel TLV value format. 948 * 949 * This is used by both Channel TLV and CSL Channel TLV. 950 */ 951 OT_TOOL_PACKED_BEGIN 952 class ChannelTlvValue 953 { 954 public: 955 /** 956 * Default constructor. 957 */ 958 ChannelTlvValue(void) = default; 959 960 /** 961 * Initializes the `ChannelTlvValue` with a given channel page and channel values. 962 * 963 * @param[in] aChannelPage The channel page. 964 * @param[in] aChannel The channel. 965 */ ChannelTlvValue(uint8_t aChannelPage,uint16_t aChannel)966 ChannelTlvValue(uint8_t aChannelPage, uint16_t aChannel) 967 : mChannelPage(aChannelPage) 968 , mChannel(BigEndian::HostSwap16(aChannel)) 969 { 970 } 971 972 /** 973 * Initializes the `ChannelTlvValue` with zero channel page and a given channel value. 974 * 975 * @param[in] aChannel The channel. 976 */ ChannelTlvValue(uint16_t aChannel)977 ChannelTlvValue(uint16_t aChannel) 978 : ChannelTlvValue(0, aChannel) 979 { 980 } 981 982 /** 983 * Returns the Channel Page value. 984 * 985 * @returns The Channel Page value. 986 */ GetChannelPage(void) const987 uint8_t GetChannelPage(void) const { return mChannelPage; } 988 989 /** 990 * Sets the Channel Page value. 991 * 992 * @param[in] aChannelPage The Channel Page value. 993 */ SetChannelPage(uint8_t aChannelPage)994 void SetChannelPage(uint8_t aChannelPage) { mChannelPage = aChannelPage; } 995 996 /** 997 * Returns the Channel value. 998 * 999 * @returns The Channel value. 1000 */ GetChannel(void) const1001 uint16_t GetChannel(void) const { return BigEndian::HostSwap16(mChannel); } 1002 1003 /** 1004 * Sets the Channel value. 1005 * 1006 * @param[in] aChannel The Channel value. 1007 */ SetChannel(uint16_t aChannel)1008 void SetChannel(uint16_t aChannel) { mChannel = BigEndian::HostSwap16(aChannel); } 1009 1010 /** 1011 * Sets the Channel and determines and sets the Channel Page from the given channel. 1012 * 1013 * @param[in] aChannel The Channel value. 1014 */ 1015 void SetChannelAndPage(uint16_t aChannel); 1016 1017 /** 1018 * Indicates whether or not the Channel and Channel Page values are valid. 1019 * 1020 * @retval TRUE If the Channel and Channel Page values are valid. 1021 * @retval FALSE If the Channel and Channel Page values are not valid. 1022 */ 1023 bool IsValid(void) const; 1024 1025 private: 1026 uint8_t mChannelPage; 1027 uint16_t mChannel; 1028 } OT_TOOL_PACKED_END; 1029 1030 /** 1031 * Defines Channel TLV constants and types. 1032 */ 1033 typedef SimpleTlvInfo<Tlv::kChannel, ChannelTlvValue> ChannelTlv; 1034 1035 /** 1036 * Defines CSL Channel TLV constants and types. 1037 */ 1038 typedef SimpleTlvInfo<Tlv::kCslChannel, ChannelTlvValue> CslChannelTlv; 1039 1040 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1041 /** 1042 * Defines Time Request TLV constants and types. 1043 */ 1044 typedef TlvInfo<Tlv::kTimeRequest> TimeRequestTlv; 1045 1046 /** 1047 * Implements Time Parameter TLV generation and parsing. 1048 */ 1049 OT_TOOL_PACKED_BEGIN 1050 class TimeParameterTlv : public Tlv, public TlvInfo<Tlv::kTimeParameter> 1051 { 1052 public: 1053 /** 1054 * Initializes the TLV. 1055 */ Init(void)1056 void Init(void) 1057 { 1058 SetType(kTimeParameter); 1059 SetLength(sizeof(*this) - sizeof(Tlv)); 1060 } 1061 1062 /** 1063 * Indicates whether or not the TLV appears to be well-formed. 1064 * 1065 * @retval TRUE If the TLV appears to be well-formed. 1066 * @retval FALSE If the TLV does not appear to be well-formed. 1067 */ IsValid(void) const1068 bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); } 1069 1070 /** 1071 * Returns the time sync period. 1072 * 1073 * @returns The time sync period. 1074 */ GetTimeSyncPeriod(void) const1075 uint16_t GetTimeSyncPeriod(void) const { return BigEndian::HostSwap16(mTimeSyncPeriod); } 1076 1077 /** 1078 * Sets the time sync period. 1079 * 1080 * @param[in] aTimeSyncPeriod The time sync period. 1081 */ SetTimeSyncPeriod(uint16_t aTimeSyncPeriod)1082 void SetTimeSyncPeriod(uint16_t aTimeSyncPeriod) { mTimeSyncPeriod = BigEndian::HostSwap16(aTimeSyncPeriod); } 1083 1084 /** 1085 * Returns the XTAL accuracy threshold. 1086 * 1087 * @returns The XTAL accuracy threshold. 1088 */ GetXtalThreshold(void) const1089 uint16_t GetXtalThreshold(void) const { return BigEndian::HostSwap16(mXtalThreshold); } 1090 1091 /** 1092 * Sets the XTAL accuracy threshold. 1093 * 1094 * @param[in] aXTALThreshold The XTAL accuracy threshold. 1095 */ SetXtalThreshold(uint16_t aXtalThreshold)1096 void SetXtalThreshold(uint16_t aXtalThreshold) { mXtalThreshold = BigEndian::HostSwap16(aXtalThreshold); } 1097 1098 private: 1099 uint16_t mTimeSyncPeriod; 1100 uint16_t mXtalThreshold; 1101 } OT_TOOL_PACKED_END; 1102 1103 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1104 1105 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE 1106 /** 1107 * Implements CSL Clock Accuracy TLV generation and parsing. 1108 */ 1109 OT_TOOL_PACKED_BEGIN 1110 class CslClockAccuracyTlv : public Tlv, public TlvInfo<Tlv::kCslClockAccuracy> 1111 { 1112 public: 1113 /** 1114 * Initializes the TLV. 1115 */ Init(void)1116 void Init(void) 1117 { 1118 SetType(kCslClockAccuracy); 1119 SetLength(sizeof(*this) - sizeof(Tlv)); 1120 } 1121 1122 /** 1123 * Indicates whether or not the TLV appears to be well-formed. 1124 * 1125 * @retval TRUE If the TLV appears to be well-formed. 1126 * @retval FALSE If the TLV does not appear to be well-formed. 1127 */ IsValid(void) const1128 bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); } 1129 1130 /** 1131 * Returns the CSL Clock Accuracy value. 1132 * 1133 * @returns The CSL Clock Accuracy value. 1134 */ GetCslClockAccuracy(void) const1135 uint8_t GetCslClockAccuracy(void) const { return mCslClockAccuracy; } 1136 1137 /** 1138 * Sets the CSL Clock Accuracy value. 1139 * 1140 * @param[in] aCslClockAccuracy The CSL Clock Accuracy value. 1141 */ SetCslClockAccuracy(uint8_t aCslClockAccuracy)1142 void SetCslClockAccuracy(uint8_t aCslClockAccuracy) { mCslClockAccuracy = aCslClockAccuracy; } 1143 1144 /** 1145 * Returns the Clock Uncertainty value. 1146 * 1147 * @returns The Clock Uncertainty value. 1148 */ GetCslUncertainty(void) const1149 uint8_t GetCslUncertainty(void) const { return mCslUncertainty; } 1150 1151 /** 1152 * Sets the CSL Uncertainty value. 1153 * 1154 * @param[in] aCslUncertainty The CSL Uncertainty value. 1155 */ SetCslUncertainty(uint8_t aCslUncertainty)1156 void SetCslUncertainty(uint8_t aCslUncertainty) { mCslUncertainty = aCslUncertainty; } 1157 1158 private: 1159 uint8_t mCslClockAccuracy; 1160 uint8_t mCslUncertainty; 1161 } OT_TOOL_PACKED_END; 1162 1163 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE 1164 /** 1165 * @} 1166 */ 1167 1168 } // namespace Mle 1169 1170 } // namespace ot 1171 1172 #endif // MLE_TLVS_HPP_ 1173