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