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 NETWORK_DIAGNOSTIC_TLVS_HPP_ 35 #define NETWORK_DIAGNOSTIC_TLVS_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <openthread/thread.h> 40 41 #include "common/encoding.hpp" 42 #include "common/message.hpp" 43 #include "common/tlvs.hpp" 44 #include "net/ip6_address.hpp" 45 #include "radio/radio.hpp" 46 #include "thread/mle_types.hpp" 47 48 namespace ot { 49 50 namespace NetworkDiagnostic { 51 52 using ot::Encoding::BigEndian::HostSwap16; 53 using ot::Encoding::BigEndian::HostSwap32; 54 55 /** 56 * @addtogroup core-mle-tlvs 57 * 58 * @brief 59 * This module includes definitions for generating and processing MLE TLVs. 60 * 61 * @{ 62 * 63 */ 64 65 /** 66 * This class implements MLE TLV generation and parsing. 67 * 68 */ 69 OT_TOOL_PACKED_BEGIN 70 class NetworkDiagnosticTlv : public ot::Tlv 71 { 72 public: 73 /** 74 * MLE TLV Types. 75 * 76 */ 77 enum Type : uint8_t 78 { 79 kExtMacAddress = OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS, 80 kAddress16 = OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS, 81 kMode = OT_NETWORK_DIAGNOSTIC_TLV_MODE, 82 kTimeout = OT_NETWORK_DIAGNOSTIC_TLV_TIMEOUT, 83 kConnectivity = OT_NETWORK_DIAGNOSTIC_TLV_CONNECTIVITY, 84 kRoute = OT_NETWORK_DIAGNOSTIC_TLV_ROUTE, 85 kLeaderData = OT_NETWORK_DIAGNOSTIC_TLV_LEADER_DATA, 86 kNetworkData = OT_NETWORK_DIAGNOSTIC_TLV_NETWORK_DATA, 87 kIp6AddressList = OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST, 88 kMacCounters = OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS, 89 kBatteryLevel = OT_NETWORK_DIAGNOSTIC_TLV_BATTERY_LEVEL, 90 kSupplyVoltage = OT_NETWORK_DIAGNOSTIC_TLV_SUPPLY_VOLTAGE, 91 kChildTable = OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE, 92 kChannelPages = OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES, 93 kTypeList = OT_NETWORK_DIAGNOSTIC_TLV_TYPE_LIST, 94 kMaxChildTimeout = OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT, 95 }; 96 97 /** 98 * This method returns the Type value. 99 * 100 * @returns The Type value. 101 * 102 */ GetType(void) const103 Type GetType(void) const { return static_cast<Type>(ot::Tlv::GetType()); } 104 105 /** 106 * This method sets the Type value. 107 * 108 * @param[in] aType The Type value. 109 * 110 */ SetType(Type aType)111 void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); } 112 113 } OT_TOOL_PACKED_END; 114 115 /** 116 * This class defines Extended MAC Address TLV constants and types. 117 * 118 */ 119 typedef SimpleTlvInfo<NetworkDiagnosticTlv::kExtMacAddress, Mac::ExtAddress> ExtMacAddressTlv; 120 121 /** 122 * This class defines Address16 TLV constants and types. 123 * 124 */ 125 typedef UintTlvInfo<NetworkDiagnosticTlv::kAddress16, uint16_t> Address16Tlv; 126 127 /** 128 * This class defines Mode TLV constants and types. 129 * 130 */ 131 typedef UintTlvInfo<NetworkDiagnosticTlv::kMode, uint8_t> ModeTlv; 132 133 /** 134 * This class defines Timeout TLV constants and types. 135 * 136 */ 137 typedef UintTlvInfo<NetworkDiagnosticTlv::kTimeout, uint32_t> TimeoutTlv; 138 139 /** 140 * This class defines Battery Level TLV constants and types. 141 * 142 */ 143 typedef UintTlvInfo<NetworkDiagnosticTlv::kBatteryLevel, uint8_t> BatteryLevelTlv; 144 145 /** 146 * This class defines Supply Voltage TLV constants and types. 147 * 148 */ 149 typedef UintTlvInfo<NetworkDiagnosticTlv::kSupplyVoltage, uint16_t> SupplyVoltageTlv; 150 151 /** 152 * This class defines Max Child Timeout TLV constants and types. 153 * 154 */ 155 typedef UintTlvInfo<NetworkDiagnosticTlv::kMaxChildTimeout, uint32_t> MaxChildTimeoutTlv; 156 157 /** 158 * This class implements Connectivity TLV generation and parsing. 159 * 160 */ 161 OT_TOOL_PACKED_BEGIN 162 class ConnectivityTlv : public NetworkDiagnosticTlv, public TlvInfo<NetworkDiagnosticTlv::kConnectivity> 163 { 164 public: 165 /** 166 * This method initializes the TLV. 167 * 168 */ Init(void)169 void Init(void) 170 { 171 SetType(kConnectivity); 172 SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv)); 173 } 174 175 /** 176 * This method indicates whether or not the TLV appears to be well-formed. 177 * 178 * @retval TRUE If the TLV appears to be well-formed. 179 * @retval FALSE If the TLV does not appear to be well-formed. 180 * 181 */ IsValid(void) const182 bool IsValid(void) const 183 { 184 return IsSedBufferingIncluded() || (GetLength() == sizeof(*this) - sizeof(NetworkDiagnosticTlv) - 185 sizeof(mSedBufferSize) - sizeof(mSedDatagramCount)); 186 } 187 188 /** 189 * This method indicates whether or not the sed buffer size and datagram count are included. 190 * 191 * @retval TRUE If the sed buffer size and datagram count are included. 192 * @retval FALSE If the sed buffer size and datagram count are not included. 193 * 194 */ IsSedBufferingIncluded(void) const195 bool IsSedBufferingIncluded(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); } 196 197 /** 198 * This method returns the Parent Priority value. 199 * 200 * @returns The Parent Priority value. 201 * 202 */ GetParentPriority(void) const203 int8_t GetParentPriority(void) const { return (mParentPriority & kParentPriorityMask) >> kParentPriorityOffset; } 204 205 /** 206 * This method sets the Parent Priority value. 207 * 208 * @param[in] aParentPriority The Parent Priority value. 209 * 210 */ SetParentPriority(int8_t aParentPriority)211 void SetParentPriority(int8_t aParentPriority) 212 { 213 mParentPriority = (aParentPriority << kParentPriorityOffset) & kParentPriorityMask; 214 } 215 216 /** 217 * This method returns the Link Quality 3 value. 218 * 219 * @returns The Link Quality 3 value. 220 * 221 */ GetLinkQuality3(void) const222 uint8_t GetLinkQuality3(void) const { return mLinkQuality3; } 223 224 /** 225 * This method sets the Link Quality 3 value. 226 * 227 * @param[in] aLinkQuality The Link Quality 3 value. 228 * 229 */ SetLinkQuality3(uint8_t aLinkQuality)230 void SetLinkQuality3(uint8_t aLinkQuality) { mLinkQuality3 = aLinkQuality; } 231 232 /** 233 * This method returns the Link Quality 2 value. 234 * 235 * @returns The Link Quality 2 value. 236 * 237 */ GetLinkQuality2(void) const238 uint8_t GetLinkQuality2(void) const { return mLinkQuality2; } 239 240 /** 241 * This method sets the Link Quality 2 value. 242 * 243 * @param[in] aLinkQuality The Link Quality 2 value. 244 * 245 */ SetLinkQuality2(uint8_t aLinkQuality)246 void SetLinkQuality2(uint8_t aLinkQuality) { mLinkQuality2 = aLinkQuality; } 247 248 /** 249 * This method sets the Link Quality 1 value. 250 * 251 * @returns The Link Quality 1 value. 252 * 253 */ GetLinkQuality1(void) const254 uint8_t GetLinkQuality1(void) const { return mLinkQuality1; } 255 256 /** 257 * This method sets the Link Quality 1 value. 258 * 259 * @param[in] aLinkQuality The Link Quality 1 value. 260 * 261 */ SetLinkQuality1(uint8_t aLinkQuality)262 void SetLinkQuality1(uint8_t aLinkQuality) { mLinkQuality1 = aLinkQuality; } 263 264 /** 265 * This method sets the Active Routers value. 266 * 267 * @returns The Active Routers value. 268 * 269 */ GetActiveRouters(void) const270 uint8_t GetActiveRouters(void) const { return mActiveRouters; } 271 272 /** 273 * This method sets the Active Routers value. 274 * 275 * @param[in] aActiveRouters The Active Routers value. 276 * 277 */ SetActiveRouters(uint8_t aActiveRouters)278 void SetActiveRouters(uint8_t aActiveRouters) { mActiveRouters = aActiveRouters; } 279 280 /** 281 * This method returns the Leader Cost value. 282 * 283 * @returns The Leader Cost value. 284 * 285 */ GetLeaderCost(void) const286 uint8_t GetLeaderCost(void) const { return mLeaderCost; } 287 288 /** 289 * This method sets the Leader Cost value. 290 * 291 * @param[in] aCost The Leader Cost value. 292 * 293 */ SetLeaderCost(uint8_t aCost)294 void SetLeaderCost(uint8_t aCost) { mLeaderCost = aCost; } 295 296 /** 297 * This method returns the ID Sequence value. 298 * 299 * @returns The ID Sequence value. 300 * 301 */ GetIdSequence(void) const302 uint8_t GetIdSequence(void) const { return mIdSequence; } 303 304 /** 305 * This method sets the ID Sequence value. 306 * 307 * @param[in] aSequence The ID Sequence value. 308 * 309 */ SetIdSequence(uint8_t aSequence)310 void SetIdSequence(uint8_t aSequence) { mIdSequence = aSequence; } 311 312 /** 313 * This method returns the SED Buffer Size value. 314 * 315 * @returns The SED Buffer Size value. 316 * 317 */ GetSedBufferSize(void) const318 uint16_t GetSedBufferSize(void) const 319 { 320 uint16_t buffersize = OPENTHREAD_CONFIG_DEFAULT_SED_BUFFER_SIZE; 321 322 if (IsSedBufferingIncluded()) 323 { 324 buffersize = HostSwap16(mSedBufferSize); 325 } 326 return buffersize; 327 } 328 329 /** 330 * This method sets the SED Buffer Size value. 331 * 332 * @param[in] aSedBufferSize The SED Buffer Size value. 333 * 334 */ SetSedBufferSize(uint16_t aSedBufferSize)335 void SetSedBufferSize(uint16_t aSedBufferSize) { mSedBufferSize = HostSwap16(aSedBufferSize); } 336 337 /** 338 * This method returns the SED Datagram Count value. 339 * 340 * @returns The SED Datagram Count value. 341 * 342 */ GetSedDatagramCount(void) const343 uint8_t GetSedDatagramCount(void) const 344 { 345 uint8_t count = OPENTHREAD_CONFIG_DEFAULT_SED_DATAGRAM_COUNT; 346 347 if (IsSedBufferingIncluded()) 348 { 349 count = mSedDatagramCount; 350 } 351 return count; 352 } 353 354 /** 355 * This method sets the SED Datagram Count value. 356 * 357 * @param[in] aSedDatagramCount The SED Datagram Count value. 358 * 359 */ SetSedDatagramCount(uint8_t aSedDatagramCount)360 void SetSedDatagramCount(uint8_t aSedDatagramCount) { mSedDatagramCount = aSedDatagramCount; } 361 362 private: 363 static constexpr uint8_t kParentPriorityOffset = 6; 364 static constexpr uint8_t kParentPriorityMask = 3 << kParentPriorityOffset; 365 366 uint8_t mParentPriority; 367 uint8_t mLinkQuality3; 368 uint8_t mLinkQuality2; 369 uint8_t mLinkQuality1; 370 uint8_t mLeaderCost; 371 uint8_t mIdSequence; 372 uint8_t mActiveRouters; 373 uint16_t mSedBufferSize; 374 uint8_t mSedDatagramCount; 375 } OT_TOOL_PACKED_END; 376 377 /** 378 * This class implements Route TLV generation and parsing. 379 * 380 */ 381 OT_TOOL_PACKED_BEGIN 382 class RouteTlv : public NetworkDiagnosticTlv, public TlvInfo<NetworkDiagnosticTlv::kRoute> 383 { 384 public: 385 /** 386 * This method initializes the TLV. 387 * 388 */ Init(void)389 void Init(void) 390 { 391 SetType(kRoute); 392 SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv)); 393 mRouterIdMask.Clear(); 394 } 395 396 /** 397 * This method indicates whether or not the TLV appears to be well-formed. 398 * 399 * @retval TRUE If the TLV appears to be well-formed. 400 * @retval FALSE If the TLV does not appear to be well-formed. 401 * 402 */ IsValid(void) const403 bool IsValid(void) const { return GetLength() >= sizeof(mRouterIdSequence) + sizeof(mRouterIdMask); } 404 405 /** 406 * This method returns the Router ID Sequence value. 407 * 408 * @returns The Router ID Sequence value. 409 * 410 */ GetRouterIdSequence(void) const411 uint8_t GetRouterIdSequence(void) const { return mRouterIdSequence; } 412 413 /** 414 * This method sets the Router ID Sequence value. 415 * 416 * @param[in] aSequence The Router ID Sequence value. 417 * 418 */ SetRouterIdSequence(uint8_t aSequence)419 void SetRouterIdSequence(uint8_t aSequence) { mRouterIdSequence = aSequence; } 420 421 /** 422 * This method indicates whether or not a Router ID bit is set. 423 * 424 * @param[in] aRouterId The Router ID. 425 * 426 * @retval TRUE If the Router ID bit is set. 427 * @retval FALSE If the Router ID bit is not set. 428 * 429 */ IsRouterIdSet(uint8_t aRouterId) const430 bool IsRouterIdSet(uint8_t aRouterId) const { return mRouterIdMask.Contains(aRouterId); } 431 432 /** 433 * This method sets the Router ID bit. 434 * 435 * @param[in] aRouterId The Router ID bit to set. 436 * 437 */ SetRouterId(uint8_t aRouterId)438 void SetRouterId(uint8_t aRouterId) { mRouterIdMask.Add(aRouterId); } 439 440 /** 441 * This method returns the Route Data Length value. 442 * 443 * @returns The Route Data Length value. 444 * 445 */ GetRouteDataLength(void) const446 uint8_t GetRouteDataLength(void) const { return GetLength() - sizeof(mRouterIdSequence) - sizeof(mRouterIdMask); } 447 448 /** 449 * This method sets the Route Data Length value. 450 * 451 * @param[in] aLength The Route Data Length value. 452 * 453 */ SetRouteDataLength(uint8_t aLength)454 void SetRouteDataLength(uint8_t aLength) { SetLength(sizeof(mRouterIdSequence) + sizeof(mRouterIdMask) + aLength); } 455 456 /** 457 * This method returns the Route Cost value for a given Router index. 458 * 459 * @param[in] aRouterIndex The Router index. 460 * 461 * @returns The Route Cost value for a given Router index. 462 * 463 */ GetRouteCost(uint8_t aRouterIndex) const464 uint8_t GetRouteCost(uint8_t aRouterIndex) const { return mRouteData[aRouterIndex] & kRouteCostMask; } 465 466 /** 467 * This method sets the Route Cost value for a given Router index. 468 * 469 * @param[in] aRouterIndex The Router index. 470 * @param[in] aRouteCost The Route Cost value. 471 * 472 */ SetRouteCost(uint8_t aRouterIndex,uint8_t aRouteCost)473 void SetRouteCost(uint8_t aRouterIndex, uint8_t aRouteCost) 474 { 475 mRouteData[aRouterIndex] = (mRouteData[aRouterIndex] & ~kRouteCostMask) | aRouteCost; 476 } 477 478 /** 479 * This method returns the Link Quality In value for a given Router index. 480 * 481 * @param[in] aRouterIndex The Router index. 482 * 483 * @returns The Link Quality In value for a given Router index. 484 * 485 */ GetLinkQualityIn(uint8_t aRouterIndex) const486 uint8_t GetLinkQualityIn(uint8_t aRouterIndex) const 487 { 488 return (mRouteData[aRouterIndex] & kLinkQualityInMask) >> kLinkQualityInOffset; 489 } 490 491 /** 492 * This method sets the Link Quality In value for a given Router index. 493 * 494 * @param[in] aRouterIndex The Router index. 495 * @param[in] aLinkQuality The Link Quality In value for a given Router index. 496 * 497 */ SetLinkQualityIn(uint8_t aRouterIndex,uint8_t aLinkQuality)498 void SetLinkQualityIn(uint8_t aRouterIndex, uint8_t aLinkQuality) 499 { 500 mRouteData[aRouterIndex] = (mRouteData[aRouterIndex] & ~kLinkQualityInMask) | 501 ((aLinkQuality << kLinkQualityInOffset) & kLinkQualityInMask); 502 } 503 504 /** 505 * This method returns the Link Quality Out value for a given Router index. 506 * 507 * @param[in] aRouterIndex The Router index. 508 * 509 * @returns The Link Quality Out value for a given Router index. 510 * 511 */ GetLinkQualityOut(uint8_t aRouterIndex) const512 uint8_t GetLinkQualityOut(uint8_t aRouterIndex) const 513 { 514 return (mRouteData[aRouterIndex] & kLinkQualityOutMask) >> kLinkQualityOutOffset; 515 } 516 517 /** 518 * This method sets the Link Quality Out value for a given Router index. 519 * 520 * @param[in] aRouterIndex The Router index. 521 * @param[in] aLinkQuality The Link Quality Out value for a given Router index. 522 * 523 */ SetLinkQualityOut(uint8_t aRouterIndex,uint8_t aLinkQuality)524 void SetLinkQualityOut(uint8_t aRouterIndex, uint8_t aLinkQuality) 525 { 526 mRouteData[aRouterIndex] = (mRouteData[aRouterIndex] & ~kLinkQualityOutMask) | 527 ((aLinkQuality << kLinkQualityOutOffset) & kLinkQualityOutMask); 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 538 uint8_t mRouterIdSequence; 539 Mle::RouterIdSet mRouterIdMask; 540 uint8_t mRouteData[Mle::kMaxRouterId + 1]; 541 } OT_TOOL_PACKED_END; 542 543 /** 544 * This class implements Leader Data TLV generation and parsing. 545 * 546 */ 547 OT_TOOL_PACKED_BEGIN 548 class LeaderDataTlv : public NetworkDiagnosticTlv, public TlvInfo<NetworkDiagnosticTlv::kLeaderData> 549 { 550 public: 551 /** 552 * This method initializes the TLV. 553 * 554 */ Init(void)555 void Init(void) 556 { 557 SetType(kLeaderData); 558 SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv)); 559 } 560 561 /** 562 * This method indicates whether or not the TLV appears to be well-formed. 563 * 564 * @retval TRUE If the TLV appears to be well-formed. 565 * @retval FALSE If the TLV does not appear to be well-formed. 566 * 567 */ IsValid(void) const568 bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(NetworkDiagnosticTlv); } 569 570 /** 571 * This method returns the Partition ID value. 572 * 573 * @returns The Partition ID value. 574 * 575 */ GetPartitionId(void) const576 uint32_t GetPartitionId(void) const { return HostSwap32(mPartitionId); } 577 578 /** 579 * This method sets the Partition ID value. 580 * 581 * @param[in] aPartitionId The Partition ID value. 582 * 583 */ SetPartitionId(uint32_t aPartitionId)584 void SetPartitionId(uint32_t aPartitionId) { mPartitionId = HostSwap32(aPartitionId); } 585 586 /** 587 * This method returns the Weighting value. 588 * 589 * @returns The Weighting value. 590 * 591 */ GetWeighting(void) const592 uint8_t GetWeighting(void) const { return mWeighting; } 593 594 /** 595 * This method sets the Weighting value. 596 * 597 * @param[in] aWeighting The Weighting value. 598 * 599 */ SetWeighting(uint8_t aWeighting)600 void SetWeighting(uint8_t aWeighting) { mWeighting = aWeighting; } 601 602 /** 603 * This method returns the Data Version value. 604 * 605 * @returns The Data Version value. 606 * 607 */ GetDataVersion(void) const608 uint8_t GetDataVersion(void) const { return mDataVersion; } 609 610 /** 611 * This method sets the Data Version value. 612 * 613 * @param[in] aVersion The Data Version value. 614 * 615 */ SetDataVersion(uint8_t aVersion)616 void SetDataVersion(uint8_t aVersion) { mDataVersion = aVersion; } 617 618 /** 619 * This method returns the Stable Data Version value. 620 * 621 * @returns The Stable Data Version value. 622 * 623 */ GetStableDataVersion(void) const624 uint8_t GetStableDataVersion(void) const { return mStableDataVersion; } 625 626 /** 627 * This method sets the Stable Data Version value. 628 * 629 * @param[in] aVersion The Stable Data Version value. 630 * 631 */ SetStableDataVersion(uint8_t aVersion)632 void SetStableDataVersion(uint8_t aVersion) { mStableDataVersion = aVersion; } 633 634 /** 635 * This method returns the Leader Router ID value. 636 * 637 * @returns The Leader Router ID value. 638 * 639 */ GetLeaderRouterId(void) const640 uint8_t GetLeaderRouterId(void) const { return mLeaderRouterId; } 641 642 /** 643 * This method sets the Leader Router ID value. 644 * 645 * @param[in] aRouterId The Leader Router ID value. 646 * 647 */ SetLeaderRouterId(uint8_t aRouterId)648 void SetLeaderRouterId(uint8_t aRouterId) { mLeaderRouterId = aRouterId; } 649 650 private: 651 uint32_t mPartitionId; 652 uint8_t mWeighting; 653 uint8_t mDataVersion; 654 uint8_t mStableDataVersion; 655 uint8_t mLeaderRouterId; 656 } OT_TOOL_PACKED_END; 657 658 /** 659 * This class implements Network Data TLV generation and parsing. 660 * 661 */ 662 OT_TOOL_PACKED_BEGIN 663 class NetworkDataTlv : public NetworkDiagnosticTlv, public TlvInfo<NetworkDiagnosticTlv::kNetworkData> 664 { 665 public: 666 /** 667 * This method initializes the TLV. 668 * 669 */ Init(void)670 void Init(void) 671 { 672 SetType(kNetworkData); 673 SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv)); 674 } 675 676 /** 677 * This method indicates whether or not the TLV appears to be well-formed. 678 * 679 * @retval TRUE If the TLV appears to be well-formed. 680 * @retval FALSE If the TLV does not appear to be well-formed. 681 * 682 */ IsValid(void) const683 bool IsValid(void) const { return GetLength() < sizeof(*this) - sizeof(NetworkDiagnosticTlv); } 684 685 /** 686 * This method returns a pointer to the Network Data. 687 * 688 * @returns A pointer to the Network Data. 689 * 690 */ GetNetworkData(void)691 uint8_t *GetNetworkData(void) { return mNetworkData; } 692 693 /** 694 * This method sets the Network Data. 695 * 696 * @param[in] aNetworkData A pointer to the Network Data. 697 * 698 */ SetNetworkData(const uint8_t * aNetworkData)699 void SetNetworkData(const uint8_t *aNetworkData) { memcpy(mNetworkData, aNetworkData, GetLength()); } 700 701 private: 702 uint8_t mNetworkData[255]; 703 } OT_TOOL_PACKED_END; 704 705 /** 706 * This class implements IPv6 Address List TLV generation and parsing. 707 * 708 */ 709 OT_TOOL_PACKED_BEGIN 710 class Ip6AddressListTlv : public NetworkDiagnosticTlv, public TlvInfo<NetworkDiagnosticTlv::kIp6AddressList> 711 { 712 public: 713 /** 714 * This method initializes the TLV. 715 * 716 */ Init(void)717 void Init(void) 718 { 719 SetType(kIp6AddressList); 720 SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv)); 721 } 722 723 /** 724 * This method indicates whether or not the TLV appears to be well-formed. 725 * 726 * @retval TRUE If the TLV appears to be well-formed. 727 * @retval FALSE If the TLV does not appear to be well-formed. 728 * 729 */ IsValid(void) const730 bool IsValid(void) const { return !IsExtended() && (GetLength() % sizeof(Ip6::Address) == 0); } 731 732 /** 733 * This method returns a pointer to the IPv6 address entry. 734 * 735 * @param[in] aIndex The index into the IPv6 address list. 736 * 737 * @returns A reference to the IPv6 address. 738 * 739 */ GetIp6Address(uint8_t aIndex) const740 const Ip6::Address &GetIp6Address(uint8_t aIndex) const 741 { 742 return *reinterpret_cast<const Ip6::Address *>(GetValue() + (aIndex * sizeof(Ip6::Address))); 743 } 744 745 } OT_TOOL_PACKED_END; 746 747 /** 748 * This class implements Mac Counters TLV generation and parsing. 749 * 750 */ 751 OT_TOOL_PACKED_BEGIN 752 class MacCountersTlv : public NetworkDiagnosticTlv, public TlvInfo<NetworkDiagnosticTlv::kMacCounters> 753 { 754 public: 755 /** 756 * This method initializes the TLV. 757 * 758 */ Init(void)759 void Init(void) 760 { 761 SetType(kMacCounters); 762 SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv)); 763 } 764 765 /** 766 * This method indicates whether or not the TLV appears to be well-formed. 767 * 768 * @retval TRUE If the TLV appears to be well-formed. 769 * @retval FALSE If the TLV does not appear to be well-formed. 770 * 771 */ IsValid(void) const772 bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(NetworkDiagnosticTlv); } 773 774 /** 775 * This method returns the IfInUnknownProtos counter. 776 * 777 * @returns The IfInUnknownProtos counter 778 * 779 */ GetIfInUnknownProtos(void) const780 uint32_t GetIfInUnknownProtos(void) const { return HostSwap32(mIfInUnknownProtos); } 781 782 /** 783 * This method sets the IfInUnknownProtos counter. 784 * 785 * @param[in] aIfInUnknownProtos The IfInUnknownProtos counter 786 * 787 */ SetIfInUnknownProtos(const uint32_t aIfInUnknownProtos)788 void SetIfInUnknownProtos(const uint32_t aIfInUnknownProtos) 789 { 790 mIfInUnknownProtos = HostSwap32(aIfInUnknownProtos); 791 } 792 793 /** 794 * This method returns the IfInErrors counter. 795 * 796 * @returns The IfInErrors counter 797 * 798 */ GetIfInErrors(void) const799 uint32_t GetIfInErrors(void) const { return HostSwap32(mIfInErrors); } 800 801 /** 802 * This method sets the IfInErrors counter. 803 * 804 * @param[in] aIfInErrors The IfInErrors counter 805 * 806 */ SetIfInErrors(const uint32_t aIfInErrors)807 void SetIfInErrors(const uint32_t aIfInErrors) { mIfInErrors = HostSwap32(aIfInErrors); } 808 809 /** 810 * This method returns the IfOutErrors counter. 811 * 812 * @returns The IfOutErrors counter 813 * 814 */ GetIfOutErrors(void) const815 uint32_t GetIfOutErrors(void) const { return HostSwap32(mIfOutErrors); } 816 817 /** 818 * This method sets the IfOutErrors counter. 819 * 820 * @param[in] aIfOutErrors The IfOutErrors counter. 821 * 822 */ SetIfOutErrors(const uint32_t aIfOutErrors)823 void SetIfOutErrors(const uint32_t aIfOutErrors) { mIfOutErrors = HostSwap32(aIfOutErrors); } 824 825 /** 826 * This method returns the IfInUcastPkts counter. 827 * 828 * @returns The IfInUcastPkts counter 829 * 830 */ GetIfInUcastPkts(void) const831 uint32_t GetIfInUcastPkts(void) const { return HostSwap32(mIfInUcastPkts); } 832 833 /** 834 * This method sets the IfInUcastPkts counter. 835 * 836 * @param[in] aIfInUcastPkts The IfInUcastPkts counter. 837 * 838 */ SetIfInUcastPkts(const uint32_t aIfInUcastPkts)839 void SetIfInUcastPkts(const uint32_t aIfInUcastPkts) { mIfInUcastPkts = HostSwap32(aIfInUcastPkts); } 840 /** 841 * This method returns the IfInBroadcastPkts counter. 842 * 843 * @returns The IfInBroadcastPkts counter 844 * 845 */ GetIfInBroadcastPkts(void) const846 uint32_t GetIfInBroadcastPkts(void) const { return HostSwap32(mIfInBroadcastPkts); } 847 848 /** 849 * This method sets the IfInBroadcastPkts counter. 850 * 851 * @param[in] aIfInBroadcastPkts The IfInBroadcastPkts counter. 852 * 853 */ SetIfInBroadcastPkts(const uint32_t aIfInBroadcastPkts)854 void SetIfInBroadcastPkts(const uint32_t aIfInBroadcastPkts) 855 { 856 mIfInBroadcastPkts = HostSwap32(aIfInBroadcastPkts); 857 } 858 859 /** 860 * This method returns the IfInDiscards counter. 861 * 862 * @returns The IfInDiscards counter 863 * 864 */ GetIfInDiscards(void) const865 uint32_t GetIfInDiscards(void) const { return HostSwap32(mIfInDiscards); } 866 867 /** 868 * This method sets the IfInDiscards counter. 869 * 870 * @param[in] aIfInDiscards The IfInDiscards counter. 871 * 872 */ SetIfInDiscards(const uint32_t aIfInDiscards)873 void SetIfInDiscards(const uint32_t aIfInDiscards) { mIfInDiscards = HostSwap32(aIfInDiscards); } 874 875 /** 876 * This method returns the IfOutUcastPkts counter. 877 * 878 * @returns The IfOutUcastPkts counter 879 * 880 */ GetIfOutUcastPkts(void) const881 uint32_t GetIfOutUcastPkts(void) const { return HostSwap32(mIfOutUcastPkts); } 882 883 /** 884 * This method sets the IfOutUcastPkts counter. 885 * 886 * @param[in] aIfOutUcastPkts The IfOutUcastPkts counter. 887 * 888 */ SetIfOutUcastPkts(const uint32_t aIfOutUcastPkts)889 void SetIfOutUcastPkts(const uint32_t aIfOutUcastPkts) { mIfOutUcastPkts = HostSwap32(aIfOutUcastPkts); } 890 891 /** 892 * This method returns the IfOutBroadcastPkts counter. 893 * 894 * @returns The IfOutBroadcastPkts counter 895 * 896 */ GetIfOutBroadcastPkts(void) const897 uint32_t GetIfOutBroadcastPkts(void) const { return HostSwap32(mIfOutBroadcastPkts); } 898 899 /** 900 * This method sets the IfOutBroadcastPkts counter. 901 * 902 * @param[in] aIfOutBroadcastPkts The IfOutBroadcastPkts counter. 903 * 904 */ SetIfOutBroadcastPkts(const uint32_t aIfOutBroadcastPkts)905 void SetIfOutBroadcastPkts(const uint32_t aIfOutBroadcastPkts) 906 { 907 mIfOutBroadcastPkts = HostSwap32(aIfOutBroadcastPkts); 908 } 909 910 /** 911 * This method returns the IfOutDiscards counter. 912 * 913 * @returns The IfOutDiscards counter 914 * 915 */ GetIfOutDiscards(void) const916 uint32_t GetIfOutDiscards(void) const { return HostSwap32(mIfOutDiscards); } 917 918 /** 919 * This method sets the IfOutDiscards counter. 920 * 921 * @param[in] aIfOutDiscards The IfOutDiscards counter. 922 * 923 */ SetIfOutDiscards(const uint32_t aIfOutDiscards)924 void SetIfOutDiscards(const uint32_t aIfOutDiscards) { mIfOutDiscards = HostSwap32(aIfOutDiscards); } 925 926 private: 927 uint32_t mIfInUnknownProtos; 928 uint32_t mIfInErrors; 929 uint32_t mIfOutErrors; 930 uint32_t mIfInUcastPkts; 931 uint32_t mIfInBroadcastPkts; 932 uint32_t mIfInDiscards; 933 uint32_t mIfOutUcastPkts; 934 uint32_t mIfOutBroadcastPkts; 935 uint32_t mIfOutDiscards; 936 } OT_TOOL_PACKED_END; 937 938 /** 939 * This class implements Child Table Entry generation and parsing. 940 * 941 */ 942 OT_TOOL_PACKED_BEGIN 943 class ChildTableEntry 944 { 945 public: 946 /** 947 * Default constructor. 948 * 949 */ ChildTableEntry(void)950 ChildTableEntry(void) 951 : mTimeoutRsvChildId(0) 952 , mMode(0) 953 { 954 } 955 956 /** 957 * This method returns the Timeout value. 958 * 959 * @returns The Timeout value. 960 * 961 */ GetTimeout(void) const962 uint8_t GetTimeout(void) const { return (HostSwap16(mTimeoutRsvChildId) & kTimeoutMask) >> kTimeoutOffset; } 963 964 /** 965 * This method sets the Timeout value. 966 * 967 * @param[in] aTimeout The Timeout value. 968 * 969 */ SetTimeout(uint8_t aTimeout)970 void SetTimeout(uint8_t aTimeout) 971 { 972 mTimeoutRsvChildId = HostSwap16((HostSwap16(mTimeoutRsvChildId) & ~kTimeoutMask) | 973 ((aTimeout << kTimeoutOffset) & kTimeoutMask)); 974 } 975 976 /** 977 * This method returns the Child ID value. 978 * 979 * @returns The Child ID value. 980 * 981 */ GetChildId(void) const982 uint16_t GetChildId(void) const { return HostSwap16(mTimeoutRsvChildId) & kChildIdMask; } 983 984 /** 985 * This method sets the Child ID value. 986 * 987 * @param[in] aChildId The Child ID value. 988 * 989 */ SetChildId(uint16_t aChildId)990 void SetChildId(uint16_t aChildId) 991 { 992 mTimeoutRsvChildId = HostSwap16((HostSwap16(mTimeoutRsvChildId) & ~kChildIdMask) | (aChildId & kChildIdMask)); 993 } 994 995 /** 996 * This method returns the Device Mode 997 * 998 * @returns The Device Mode 999 * 1000 */ GetMode(void) const1001 Mle::DeviceMode GetMode(void) const { return Mle::DeviceMode(mMode); } 1002 1003 /** 1004 * This method sets the Device Mode. 1005 * 1006 * @param[in] aMode The Device Mode. 1007 * 1008 */ SetMode(Mle::DeviceMode aMode)1009 void SetMode(Mle::DeviceMode aMode) { mMode = aMode.Get(); } 1010 1011 /** 1012 * This method returns the Reserved value. 1013 * 1014 * @returns The Reserved value. 1015 * 1016 */ GetReserved(void) const1017 uint8_t GetReserved(void) const { return (HostSwap16(mTimeoutRsvChildId) & kReservedMask) >> kReservedOffset; } 1018 1019 /** 1020 * This method sets the Reserved value. 1021 * 1022 * @param[in] aReserved The Reserved value. 1023 * 1024 */ SetReserved(uint8_t aReserved)1025 void SetReserved(uint8_t aReserved) 1026 { 1027 mTimeoutRsvChildId = HostSwap16((HostSwap16(mTimeoutRsvChildId) & ~kReservedMask) | 1028 ((aReserved << kReservedOffset) & kReservedMask)); 1029 } 1030 1031 private: 1032 static constexpr uint8_t kTimeoutOffset = 11; 1033 static constexpr uint8_t kReservedOffset = 9; 1034 static constexpr uint16_t kTimeoutMask = 0xf800; 1035 static constexpr uint16_t kReservedMask = 0x0600; 1036 static constexpr uint16_t kChildIdMask = 0x1f; 1037 1038 uint16_t mTimeoutRsvChildId; 1039 uint8_t mMode; 1040 } OT_TOOL_PACKED_END; 1041 1042 /** 1043 * This class implements Child Table TLV generation and parsing. 1044 * 1045 */ 1046 OT_TOOL_PACKED_BEGIN 1047 class ChildTableTlv : public NetworkDiagnosticTlv, public TlvInfo<NetworkDiagnosticTlv::kChildTable> 1048 { 1049 public: 1050 /** 1051 * This method initializes the TLV. 1052 * 1053 */ Init(void)1054 void Init(void) 1055 { 1056 SetType(kChildTable); 1057 SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv)); 1058 } 1059 1060 /** 1061 * This method indicates whether or not the TLV appears to be well-formed. 1062 * 1063 * @retval TRUE If the TLV appears to be well-formed. 1064 * @retval FALSE If the TLV does not appear to be well-formed. 1065 * 1066 */ IsValid(void) const1067 bool IsValid(void) const { return (GetLength() % sizeof(ChildTableEntry)) == 0; } 1068 1069 /** 1070 * This method returns the number of Child Table entries. 1071 * 1072 * @returns The number of Child Table entries. 1073 * 1074 */ GetNumEntries(void) const1075 uint8_t GetNumEntries(void) const { return GetLength() / sizeof(ChildTableEntry); } 1076 1077 /** 1078 * This method returns the Child Table entry at @p aIndex. 1079 * 1080 * @param[in] aIndex The index into the Child Table list. 1081 * 1082 * @returns A reference to the Child Table entry. 1083 * 1084 */ GetEntry(uint16_t aIndex)1085 ChildTableEntry &GetEntry(uint16_t aIndex) 1086 { 1087 return *reinterpret_cast<ChildTableEntry *>(GetValue() + (aIndex * sizeof(ChildTableEntry))); 1088 } 1089 1090 /** 1091 * This method reads the Child Table entry at @p aIndex. 1092 * 1093 * @param[out] aEntry A reference to a ChildTableEntry. 1094 * @param[in] aMessage A reference to the message. 1095 * @param[in] aOffset The offset of the ChildTableTLV in aMessage. 1096 * @param[in] aIndex The index into the Child Table list. 1097 * 1098 * @retval kErrorNotFound No such entry is found. 1099 * @retval kErrorNone Successfully read the entry. 1100 * 1101 */ ReadEntry(ChildTableEntry & aEntry,const Message & aMessage,uint16_t aOffset,uint8_t aIndex) const1102 Error ReadEntry(ChildTableEntry &aEntry, const Message &aMessage, uint16_t aOffset, uint8_t aIndex) const 1103 { 1104 return ((aIndex < GetNumEntries()) && 1105 (aMessage.Read(aOffset + sizeof(ChildTableTlv) + (aIndex * sizeof(ChildTableEntry)), aEntry) == 1106 kErrorNone)) 1107 ? kErrorNone 1108 : kErrorInvalidArgs; 1109 } 1110 1111 } OT_TOOL_PACKED_END; 1112 1113 /** 1114 * This class implements Channel Pages TLV generation and parsing. 1115 * 1116 */ 1117 OT_TOOL_PACKED_BEGIN 1118 class ChannelPagesTlv : public NetworkDiagnosticTlv, public TlvInfo<NetworkDiagnosticTlv::kChannelPages> 1119 { 1120 public: 1121 /** 1122 * This method initializes the TLV. 1123 * 1124 */ Init(void)1125 void Init(void) 1126 { 1127 SetType(kChannelPages); 1128 SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv)); 1129 } 1130 1131 /** 1132 * This method indicates whether or not the TLV appears to be well-formed. 1133 * 1134 * @retval TRUE If the TLV appears to be well-formed. 1135 * @retval FALSE If the TLV does not appear to be well-formed. 1136 * 1137 */ IsValid(void) const1138 bool IsValid(void) const 1139 { 1140 // At least one channel page must be included. 1141 return GetLength() >= 1; 1142 } 1143 1144 /** 1145 * This method returns a pointer to the list of Channel Pages. 1146 * 1147 * @returns A pointer to the list of Channel Pages. 1148 * 1149 */ GetChannelPages(void)1150 uint8_t *GetChannelPages(void) { return mChannelPages; } 1151 1152 private: 1153 uint8_t mChannelPages[Radio::kNumChannelPages]; 1154 } OT_TOOL_PACKED_END; 1155 1156 /** 1157 * This class implements IPv6 Address List TLV generation and parsing. 1158 * 1159 */ 1160 OT_TOOL_PACKED_BEGIN 1161 class TypeListTlv : public NetworkDiagnosticTlv, public TlvInfo<NetworkDiagnosticTlv::kTypeList> 1162 { 1163 public: 1164 /** 1165 * This method initializes the TLV. 1166 * 1167 */ Init(void)1168 void Init(void) 1169 { 1170 SetType(kTypeList); 1171 SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv)); 1172 } 1173 } OT_TOOL_PACKED_END; 1174 1175 /** 1176 * @} 1177 * 1178 */ 1179 1180 } // namespace NetworkDiagnostic 1181 1182 } // namespace ot 1183 1184 #endif // NETWORK_DIAGNOSTIC_TLVS_HPP_ 1185