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 Network Diagnostics 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/netdiag.h> 40 #include <openthread/thread.h> 41 42 #include "common/clearable.hpp" 43 #include "common/encoding.hpp" 44 #include "common/message.hpp" 45 #include "common/tlvs.hpp" 46 #include "net/ip6_address.hpp" 47 #include "radio/radio.hpp" 48 #include "thread/child.hpp" 49 #include "thread/link_quality.hpp" 50 #include "thread/mle_tlvs.hpp" 51 #include "thread/mle_types.hpp" 52 #include "thread/router.hpp" 53 54 namespace ot { 55 namespace NetworkDiagnostic { 56 57 /** 58 * Implements Network Diagnostic TLV generation and parsing. 59 * 60 */ 61 OT_TOOL_PACKED_BEGIN 62 class Tlv : public ot::Tlv 63 { 64 public: 65 /** 66 * Network Diagnostic TLV Types. 67 * 68 */ 69 enum Type : uint8_t 70 { 71 kExtMacAddress = OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS, 72 kAddress16 = OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS, 73 kMode = OT_NETWORK_DIAGNOSTIC_TLV_MODE, 74 kTimeout = OT_NETWORK_DIAGNOSTIC_TLV_TIMEOUT, 75 kConnectivity = OT_NETWORK_DIAGNOSTIC_TLV_CONNECTIVITY, 76 kRoute = OT_NETWORK_DIAGNOSTIC_TLV_ROUTE, 77 kLeaderData = OT_NETWORK_DIAGNOSTIC_TLV_LEADER_DATA, 78 kNetworkData = OT_NETWORK_DIAGNOSTIC_TLV_NETWORK_DATA, 79 kIp6AddressList = OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST, 80 kMacCounters = OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS, 81 kBatteryLevel = OT_NETWORK_DIAGNOSTIC_TLV_BATTERY_LEVEL, 82 kSupplyVoltage = OT_NETWORK_DIAGNOSTIC_TLV_SUPPLY_VOLTAGE, 83 kChildTable = OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE, 84 kChannelPages = OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES, 85 kTypeList = OT_NETWORK_DIAGNOSTIC_TLV_TYPE_LIST, 86 kMaxChildTimeout = OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT, 87 kEui64 = OT_NETWORK_DIAGNOSTIC_TLV_EUI64, 88 kVersion = OT_NETWORK_DIAGNOSTIC_TLV_VERSION, 89 kVendorName = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_NAME, 90 kVendorModel = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_MODEL, 91 kVendorSwVersion = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_SW_VERSION, 92 kThreadStackVersion = OT_NETWORK_DIAGNOSTIC_TLV_THREAD_STACK_VERSION, 93 kChild = OT_NETWORK_DIAGNOSTIC_TLV_CHILD, 94 kChildIp6AddressList = OT_NETWORK_DIAGNOSTIC_TLV_CHILD_IP6_ADDR_LIST, 95 kRouterNeighbor = OT_NETWORK_DIAGNOSTIC_TLV_ROUTER_NEIGHBOR, 96 kAnswer = OT_NETWORK_DIAGNOSTIC_TLV_ANSWER, 97 kQueryId = OT_NETWORK_DIAGNOSTIC_TLV_QUERY_ID, 98 kMleCounters = OT_NETWORK_DIAGNOSTIC_TLV_MLE_COUNTERS, 99 kVendorAppUrl = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_APP_URL, 100 }; 101 102 /** 103 * Maximum length of Vendor Name TLV. 104 * 105 */ 106 static constexpr uint8_t kMaxVendorNameLength = OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_NAME_TLV_LENGTH; 107 108 /** 109 * Maximum length of Vendor Model TLV. 110 * 111 */ 112 static constexpr uint8_t kMaxVendorModelLength = OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_MODEL_TLV_LENGTH; 113 114 /** 115 * Maximum length of Vendor SW Version TLV. 116 * 117 */ 118 static constexpr uint8_t kMaxVendorSwVersionLength = OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_SW_VERSION_TLV_LENGTH; 119 120 /** 121 * Maximum length of Vendor SW Version TLV. 122 * 123 */ 124 static constexpr uint8_t kMaxThreadStackVersionLength = OT_NETWORK_DIAGNOSTIC_MAX_THREAD_STACK_VERSION_TLV_LENGTH; 125 126 /** 127 * Maximum length of Vendor SW Version TLV. 128 * 129 */ 130 static constexpr uint8_t kMaxVendorAppUrlLength = OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_APP_URL_TLV_LENGTH; 131 132 /** 133 * Returns the Type value. 134 * 135 * @returns The Type value. 136 * 137 */ GetType(void) const138 Type GetType(void) const { return static_cast<Type>(ot::Tlv::GetType()); } 139 140 /** 141 * Sets the Type value. 142 * 143 * @param[in] aType The Type value. 144 * 145 */ SetType(Type aType)146 void SetType(Type aType) { ot::Tlv::SetType(static_cast<uint8_t>(aType)); } 147 148 } OT_TOOL_PACKED_END; 149 150 /** 151 * Defines Extended MAC Address TLV constants and types. 152 * 153 */ 154 typedef SimpleTlvInfo<Tlv::kExtMacAddress, Mac::ExtAddress> ExtMacAddressTlv; 155 156 /** 157 * Defines Address16 TLV constants and types. 158 * 159 */ 160 typedef UintTlvInfo<Tlv::kAddress16, uint16_t> Address16Tlv; 161 162 /** 163 * Defines Mode TLV constants and types. 164 * 165 */ 166 typedef UintTlvInfo<Tlv::kMode, uint8_t> ModeTlv; 167 168 /** 169 * Defines Timeout TLV constants and types. 170 * 171 */ 172 typedef UintTlvInfo<Tlv::kTimeout, uint32_t> TimeoutTlv; 173 174 /** 175 * Defines Network Data TLV constants and types. 176 * 177 */ 178 typedef TlvInfo<Tlv::kNetworkData> NetworkDataTlv; 179 180 /** 181 * Defines IPv6 Address List TLV constants and types. 182 * 183 */ 184 typedef TlvInfo<Tlv::kIp6AddressList> Ip6AddressListTlv; 185 186 /** 187 * Defines Battery Level TLV constants and types. 188 * 189 */ 190 typedef UintTlvInfo<Tlv::kBatteryLevel, uint8_t> BatteryLevelTlv; 191 192 /** 193 * Defines Supply Voltage TLV constants and types. 194 * 195 */ 196 typedef UintTlvInfo<Tlv::kSupplyVoltage, uint16_t> SupplyVoltageTlv; 197 198 /** 199 * Defines Child Table TLV constants and types. 200 * 201 */ 202 typedef TlvInfo<Tlv::kChildTable> ChildTableTlv; 203 204 /** 205 * Defines Max Child Timeout TLV constants and types. 206 * 207 */ 208 typedef UintTlvInfo<Tlv::kMaxChildTimeout, uint32_t> MaxChildTimeoutTlv; 209 210 /** 211 * Defines Eui64 TLV constants and types. 212 * 213 */ 214 typedef SimpleTlvInfo<Tlv::kEui64, Mac::ExtAddress> Eui64Tlv; 215 216 /** 217 * Defines Version TLV constants and types. 218 * 219 */ 220 typedef UintTlvInfo<Tlv::kVersion, uint16_t> VersionTlv; 221 222 /** 223 * Defines Vendor Name TLV constants and types. 224 * 225 */ 226 typedef StringTlvInfo<Tlv::kVendorName, Tlv::kMaxVendorNameLength> VendorNameTlv; 227 228 /** 229 * Defines Vendor Model TLV constants and types. 230 * 231 */ 232 typedef StringTlvInfo<Tlv::kVendorModel, Tlv::kMaxVendorModelLength> VendorModelTlv; 233 234 /** 235 * Defines Vendor SW Version TLV constants and types. 236 * 237 */ 238 typedef StringTlvInfo<Tlv::kVendorSwVersion, Tlv::kMaxVendorSwVersionLength> VendorSwVersionTlv; 239 240 /** 241 * Defines Thread Stack Version TLV constants and types. 242 * 243 */ 244 typedef StringTlvInfo<Tlv::kThreadStackVersion, Tlv::kMaxThreadStackVersionLength> ThreadStackVersionTlv; 245 246 /** 247 * Defines Vendor App URL TLV constants and types. 248 * 249 */ 250 typedef StringTlvInfo<Tlv::kVendorAppUrl, Tlv::kMaxVendorAppUrlLength> VendorAppUrlTlv; 251 252 /** 253 * Defines Child IPv6 Address List TLV constants and types. 254 * 255 */ 256 typedef TlvInfo<Tlv::kChildIp6AddressList> ChildIp6AddressListTlv; 257 258 /** 259 * Defines Query ID TLV constants and types. 260 * 261 */ 262 typedef UintTlvInfo<Tlv::kQueryId, uint16_t> QueryIdTlv; 263 264 typedef otNetworkDiagConnectivity Connectivity; ///< Network Diagnostic Connectivity value. 265 266 /** 267 * Implements Connectivity TLV generation and parsing. 268 * 269 */ 270 OT_TOOL_PACKED_BEGIN 271 class ConnectivityTlv : public Mle::ConnectivityTlv 272 { 273 public: 274 static constexpr uint8_t kType = ot::NetworkDiagnostic::Tlv::kConnectivity; ///< The TLV Type value. 275 276 /** 277 * Initializes the TLV. 278 * 279 */ Init(void)280 void Init(void) 281 { 282 Mle::ConnectivityTlv::Init(); 283 ot::Tlv::SetType(kType); 284 } 285 286 /** 287 * Retrieves the `Connectivity` value. 288 * 289 * @param[out] aConnectivity A reference to `Connectivity` to populate. 290 * 291 */ GetConnectivity(Connectivity & aConnectivity) const292 void GetConnectivity(Connectivity &aConnectivity) const 293 { 294 aConnectivity.mParentPriority = GetParentPriority(); 295 aConnectivity.mLinkQuality3 = GetLinkQuality3(); 296 aConnectivity.mLinkQuality2 = GetLinkQuality2(); 297 aConnectivity.mLinkQuality1 = GetLinkQuality1(); 298 aConnectivity.mLeaderCost = GetLeaderCost(); 299 aConnectivity.mIdSequence = GetIdSequence(); 300 aConnectivity.mActiveRouters = GetActiveRouters(); 301 aConnectivity.mSedBufferSize = GetSedBufferSize(); 302 aConnectivity.mSedDatagramCount = GetSedDatagramCount(); 303 } 304 305 } OT_TOOL_PACKED_END; 306 307 /** 308 * Implements Route TLV generation and parsing. 309 * 310 */ 311 OT_TOOL_PACKED_BEGIN 312 class RouteTlv : public Mle::RouteTlv 313 { 314 public: 315 static constexpr uint8_t kType = ot::NetworkDiagnostic::Tlv::kRoute; ///< The TLV Type value. 316 317 /** 318 * Initializes the TLV. 319 * 320 */ Init(void)321 void Init(void) 322 { 323 Mle::RouteTlv::Init(); 324 ot::Tlv::SetType(kType); 325 } 326 } OT_TOOL_PACKED_END; 327 328 /** 329 * Implements Leader Data TLV generation and parsing. 330 * 331 */ 332 OT_TOOL_PACKED_BEGIN 333 class LeaderDataTlv : public Mle::LeaderDataTlv 334 { 335 public: 336 static constexpr uint8_t kType = ot::NetworkDiagnostic::Tlv::kLeaderData; ///< The TLV Type value. 337 338 /** 339 * Initializes the TLV. 340 * 341 */ Init(void)342 void Init(void) 343 { 344 Mle::LeaderDataTlv::Init(); 345 ot::Tlv::SetType(kType); 346 } 347 } OT_TOOL_PACKED_END; 348 349 /** 350 * Implements Mac Counters TLV generation and parsing. 351 * 352 */ 353 OT_TOOL_PACKED_BEGIN 354 class MacCountersTlv : public Tlv, public TlvInfo<Tlv::kMacCounters> 355 { 356 public: 357 /** 358 * Initializes the TLV. 359 * 360 */ Init(void)361 void Init(void) 362 { 363 SetType(kMacCounters); 364 SetLength(sizeof(*this) - sizeof(Tlv)); 365 } 366 367 /** 368 * Indicates whether or not the TLV appears to be well-formed. 369 * 370 * @retval TRUE If the TLV appears to be well-formed. 371 * @retval FALSE If the TLV does not appear to be well-formed. 372 * 373 */ IsValid(void) const374 bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); } 375 376 /** 377 * Returns the IfInUnknownProtos counter. 378 * 379 * @returns The IfInUnknownProtos counter 380 * 381 */ GetIfInUnknownProtos(void) const382 uint32_t GetIfInUnknownProtos(void) const { return BigEndian::HostSwap32(mIfInUnknownProtos); } 383 384 /** 385 * Sets the IfInUnknownProtos counter. 386 * 387 * @param[in] aIfInUnknownProtos The IfInUnknownProtos counter 388 * 389 */ SetIfInUnknownProtos(const uint32_t aIfInUnknownProtos)390 void SetIfInUnknownProtos(const uint32_t aIfInUnknownProtos) 391 { 392 mIfInUnknownProtos = BigEndian::HostSwap32(aIfInUnknownProtos); 393 } 394 395 /** 396 * Returns the IfInErrors counter. 397 * 398 * @returns The IfInErrors counter 399 * 400 */ GetIfInErrors(void) const401 uint32_t GetIfInErrors(void) const { return BigEndian::HostSwap32(mIfInErrors); } 402 403 /** 404 * Sets the IfInErrors counter. 405 * 406 * @param[in] aIfInErrors The IfInErrors counter 407 * 408 */ SetIfInErrors(const uint32_t aIfInErrors)409 void SetIfInErrors(const uint32_t aIfInErrors) { mIfInErrors = BigEndian::HostSwap32(aIfInErrors); } 410 411 /** 412 * Returns the IfOutErrors counter. 413 * 414 * @returns The IfOutErrors counter 415 * 416 */ GetIfOutErrors(void) const417 uint32_t GetIfOutErrors(void) const { return BigEndian::HostSwap32(mIfOutErrors); } 418 419 /** 420 * Sets the IfOutErrors counter. 421 * 422 * @param[in] aIfOutErrors The IfOutErrors counter. 423 * 424 */ SetIfOutErrors(const uint32_t aIfOutErrors)425 void SetIfOutErrors(const uint32_t aIfOutErrors) { mIfOutErrors = BigEndian::HostSwap32(aIfOutErrors); } 426 427 /** 428 * Returns the IfInUcastPkts counter. 429 * 430 * @returns The IfInUcastPkts counter 431 * 432 */ GetIfInUcastPkts(void) const433 uint32_t GetIfInUcastPkts(void) const { return BigEndian::HostSwap32(mIfInUcastPkts); } 434 435 /** 436 * Sets the IfInUcastPkts counter. 437 * 438 * @param[in] aIfInUcastPkts The IfInUcastPkts counter. 439 * 440 */ SetIfInUcastPkts(const uint32_t aIfInUcastPkts)441 void SetIfInUcastPkts(const uint32_t aIfInUcastPkts) { mIfInUcastPkts = BigEndian::HostSwap32(aIfInUcastPkts); } 442 /** 443 * Returns the IfInBroadcastPkts counter. 444 * 445 * @returns The IfInBroadcastPkts counter 446 * 447 */ GetIfInBroadcastPkts(void) const448 uint32_t GetIfInBroadcastPkts(void) const { return BigEndian::HostSwap32(mIfInBroadcastPkts); } 449 450 /** 451 * Sets the IfInBroadcastPkts counter. 452 * 453 * @param[in] aIfInBroadcastPkts The IfInBroadcastPkts counter. 454 * 455 */ SetIfInBroadcastPkts(const uint32_t aIfInBroadcastPkts)456 void SetIfInBroadcastPkts(const uint32_t aIfInBroadcastPkts) 457 { 458 mIfInBroadcastPkts = BigEndian::HostSwap32(aIfInBroadcastPkts); 459 } 460 461 /** 462 * Returns the IfInDiscards counter. 463 * 464 * @returns The IfInDiscards counter 465 * 466 */ GetIfInDiscards(void) const467 uint32_t GetIfInDiscards(void) const { return BigEndian::HostSwap32(mIfInDiscards); } 468 469 /** 470 * Sets the IfInDiscards counter. 471 * 472 * @param[in] aIfInDiscards The IfInDiscards counter. 473 * 474 */ SetIfInDiscards(const uint32_t aIfInDiscards)475 void SetIfInDiscards(const uint32_t aIfInDiscards) { mIfInDiscards = BigEndian::HostSwap32(aIfInDiscards); } 476 477 /** 478 * Returns the IfOutUcastPkts counter. 479 * 480 * @returns The IfOutUcastPkts counter 481 * 482 */ GetIfOutUcastPkts(void) const483 uint32_t GetIfOutUcastPkts(void) const { return BigEndian::HostSwap32(mIfOutUcastPkts); } 484 485 /** 486 * Sets the IfOutUcastPkts counter. 487 * 488 * @param[in] aIfOutUcastPkts The IfOutUcastPkts counter. 489 * 490 */ SetIfOutUcastPkts(const uint32_t aIfOutUcastPkts)491 void SetIfOutUcastPkts(const uint32_t aIfOutUcastPkts) { mIfOutUcastPkts = BigEndian::HostSwap32(aIfOutUcastPkts); } 492 493 /** 494 * Returns the IfOutBroadcastPkts counter. 495 * 496 * @returns The IfOutBroadcastPkts counter 497 * 498 */ GetIfOutBroadcastPkts(void) const499 uint32_t GetIfOutBroadcastPkts(void) const { return BigEndian::HostSwap32(mIfOutBroadcastPkts); } 500 501 /** 502 * Sets the IfOutBroadcastPkts counter. 503 * 504 * @param[in] aIfOutBroadcastPkts The IfOutBroadcastPkts counter. 505 * 506 */ SetIfOutBroadcastPkts(const uint32_t aIfOutBroadcastPkts)507 void SetIfOutBroadcastPkts(const uint32_t aIfOutBroadcastPkts) 508 { 509 mIfOutBroadcastPkts = BigEndian::HostSwap32(aIfOutBroadcastPkts); 510 } 511 512 /** 513 * Returns the IfOutDiscards counter. 514 * 515 * @returns The IfOutDiscards counter 516 * 517 */ GetIfOutDiscards(void) const518 uint32_t GetIfOutDiscards(void) const { return BigEndian::HostSwap32(mIfOutDiscards); } 519 520 /** 521 * Sets the IfOutDiscards counter. 522 * 523 * @param[in] aIfOutDiscards The IfOutDiscards counter. 524 * 525 */ SetIfOutDiscards(const uint32_t aIfOutDiscards)526 void SetIfOutDiscards(const uint32_t aIfOutDiscards) { mIfOutDiscards = BigEndian::HostSwap32(aIfOutDiscards); } 527 528 private: 529 uint32_t mIfInUnknownProtos; 530 uint32_t mIfInErrors; 531 uint32_t mIfOutErrors; 532 uint32_t mIfInUcastPkts; 533 uint32_t mIfInBroadcastPkts; 534 uint32_t mIfInDiscards; 535 uint32_t mIfOutUcastPkts; 536 uint32_t mIfOutBroadcastPkts; 537 uint32_t mIfOutDiscards; 538 } OT_TOOL_PACKED_END; 539 540 /** 541 * Implements Child Table Entry generation and parsing. 542 * 543 */ 544 OT_TOOL_PACKED_BEGIN 545 class ChildTableEntry : public Clearable<ChildTableEntry> 546 { 547 public: 548 /** 549 * Returns the Timeout value. 550 * 551 * @returns The Timeout value. 552 * 553 */ GetTimeout(void) const554 uint8_t GetTimeout(void) const { return (GetTimeoutChildId() & kTimeoutMask) >> kTimeoutOffset; } 555 556 /** 557 * Sets the Timeout value. 558 * 559 * @param[in] aTimeout The Timeout value. 560 * 561 */ SetTimeout(uint8_t aTimeout)562 void SetTimeout(uint8_t aTimeout) 563 { 564 SetTimeoutChildId((GetTimeoutChildId() & ~kTimeoutMask) | ((aTimeout << kTimeoutOffset) & kTimeoutMask)); 565 } 566 567 /** 568 * The Link Quality value. 569 * 570 * @returns The Link Quality value. 571 * 572 */ GetLinkQuality(void) const573 LinkQuality GetLinkQuality(void) const 574 { 575 return static_cast<LinkQuality>((GetTimeoutChildId() & kLqiMask) >> kLqiOffset); 576 } 577 578 /** 579 * Set the Link Quality value. 580 * 581 * @param[in] aLinkQuality The Link Quality value. 582 * 583 */ SetLinkQuality(LinkQuality aLinkQuality)584 void SetLinkQuality(LinkQuality aLinkQuality) 585 { 586 SetTimeoutChildId((GetTimeoutChildId() & ~kLqiMask) | ((aLinkQuality << kLqiOffset) & kLqiMask)); 587 } 588 589 /** 590 * Returns the Child ID value. 591 * 592 * @returns The Child ID value. 593 * 594 */ GetChildId(void) const595 uint16_t GetChildId(void) const { return (GetTimeoutChildId() & kChildIdMask) >> kChildIdOffset; } 596 597 /** 598 * Sets the Child ID value. 599 * 600 * @param[in] aChildId The Child ID value. 601 * 602 */ SetChildId(uint16_t aChildId)603 void SetChildId(uint16_t aChildId) 604 { 605 SetTimeoutChildId((GetTimeoutChildId() & ~kChildIdMask) | ((aChildId << kChildIdOffset) & kChildIdMask)); 606 } 607 608 /** 609 * Returns the Device Mode 610 * 611 * @returns The Device Mode 612 * 613 */ GetMode(void) const614 Mle::DeviceMode GetMode(void) const { return Mle::DeviceMode(mMode); } 615 616 /** 617 * Sets the Device Mode. 618 * 619 * @param[in] aMode The Device Mode. 620 * 621 */ SetMode(Mle::DeviceMode aMode)622 void SetMode(Mle::DeviceMode aMode) { mMode = aMode.Get(); } 623 624 private: 625 // 1 0 626 // 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 627 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 628 // | Timeout |LQI| Child ID | 629 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 630 631 static constexpr uint8_t kTimeoutOffset = 11; 632 static constexpr uint8_t kLqiOffset = 9; 633 static constexpr uint8_t kChildIdOffset = 0; 634 static constexpr uint16_t kTimeoutMask = 0x1f << kTimeoutOffset; 635 static constexpr uint16_t kLqiMask = 0x3 << kLqiOffset; 636 static constexpr uint16_t kChildIdMask = 0x1ff << kChildIdOffset; 637 GetTimeoutChildId(void) const638 uint16_t GetTimeoutChildId(void) const { return BigEndian::HostSwap16(mTimeoutChildId); } SetTimeoutChildId(uint16_t aTimeoutChildIf)639 void SetTimeoutChildId(uint16_t aTimeoutChildIf) { mTimeoutChildId = BigEndian::HostSwap16(aTimeoutChildIf); } 640 641 uint16_t mTimeoutChildId; 642 uint8_t mMode; 643 } OT_TOOL_PACKED_END; 644 645 /** 646 * Implements Channel Pages TLV generation and parsing. 647 * 648 */ 649 OT_TOOL_PACKED_BEGIN 650 class ChannelPagesTlv : public Tlv, public TlvInfo<Tlv::kChannelPages> 651 { 652 public: 653 /** 654 * Initializes the TLV. 655 * 656 */ Init(void)657 void Init(void) 658 { 659 SetType(kChannelPages); 660 SetLength(sizeof(*this) - sizeof(Tlv)); 661 } 662 663 /** 664 * Indicates whether or not the TLV appears to be well-formed. 665 * 666 * @retval TRUE If the TLV appears to be well-formed. 667 * @retval FALSE If the TLV does not appear to be well-formed. 668 * 669 */ IsValid(void) const670 bool IsValid(void) const 671 { 672 // At least one channel page must be included. 673 return GetLength() >= 1; 674 } 675 676 /** 677 * Returns a pointer to the list of Channel Pages. 678 * 679 * @returns A pointer to the list of Channel Pages. 680 * 681 */ GetChannelPages(void)682 uint8_t *GetChannelPages(void) { return mChannelPages; } 683 684 private: 685 uint8_t mChannelPages[Radio::kNumChannelPages]; 686 } OT_TOOL_PACKED_END; 687 688 /** 689 * Implements IPv6 Address List TLV generation and parsing. 690 * 691 */ 692 OT_TOOL_PACKED_BEGIN 693 class TypeListTlv : public Tlv, public TlvInfo<Tlv::kTypeList> 694 { 695 public: 696 /** 697 * Initializes the TLV. 698 * 699 */ Init(void)700 void Init(void) 701 { 702 SetType(kTypeList); 703 SetLength(sizeof(*this) - sizeof(Tlv)); 704 } 705 } OT_TOOL_PACKED_END; 706 707 #if OPENTHREAD_FTD 708 709 /** 710 * Implements Child TLV generation and parsing. 711 * 712 */ 713 OT_TOOL_PACKED_BEGIN 714 class ChildTlv : public Tlv, public TlvInfo<Tlv::kChild>, public Clearable<ChildTlv> 715 { 716 public: 717 static constexpr uint8_t kFlagsRxOnWhenIdle = 1 << 7; ///< Device mode - Rx-on when idle. 718 static constexpr uint8_t kFlagsFtd = 1 << 6; ///< Device mode - Full Thread Device (FTD). 719 static constexpr uint8_t kFlagsFullNetdta = 1 << 5; ///< Device mode - Full Network Data. 720 static constexpr uint8_t kFlagsCslSync = 1 << 4; ///< Is CSL capable and CSL synchronized. 721 static constexpr uint8_t kFlagsTrackErrRate = 1 << 3; ///< Supports tracking error rates. 722 723 /** 724 * Initializes the TLV using information from a given `Child`. 725 * 726 * @param[in] aChild The child to initialize the TLV from. 727 * 728 */ 729 void InitFrom(const Child &aChild); 730 731 /** 732 * Initializes the TLV as empty (zero length). 733 * 734 */ InitAsEmpty(void)735 void InitAsEmpty(void) 736 { 737 SetType(kChild); 738 SetLength(0); 739 } 740 741 /** 742 * Returns the Flags field (`kFlags*` constants define bits in flags). 743 * 744 * @returns The Flags field. 745 * 746 */ GetFlags(void) const747 uint8_t GetFlags(void) const { return mFlags; } 748 749 /** 750 * Returns the RLOC16 field. 751 * 752 * @returns The RLOC16 of the child. 753 * 754 */ GetRloc16(void) const755 uint16_t GetRloc16(void) const { return BigEndian::HostSwap16(mRloc16); } 756 757 /** 758 * Returns the Extended Address. 759 * 760 * @returns The Extended Address of the child. 761 * 762 */ GetExtAddress(void) const763 const Mac::ExtAddress &GetExtAddress(void) const { return mExtAddress; } 764 765 /** 766 * Returns the Version field. 767 * 768 * @returns The Version of the child. 769 * 770 */ GetVersion(void) const771 uint16_t GetVersion(void) const { return BigEndian::HostSwap16(mVersion); } 772 773 /** 774 * Returns the Timeout field 775 * 776 * @returns The Timeout value in seconds. 777 * 778 */ GetTimeout(void) const779 uint32_t GetTimeout(void) const { return BigEndian::HostSwap32(mTimeout); } 780 781 /** 782 * Returns the Age field. 783 * 784 * @returns The Age field (seconds since last heard from the child). 785 * 786 */ GetAge(void) const787 uint32_t GetAge(void) const { return BigEndian::HostSwap32(mAge); } 788 789 /** 790 * Returns the Connection Time field. 791 * 792 * @returns The Connection Time field (seconds since attach). 793 * 794 */ GetConnectionTime(void) const795 uint32_t GetConnectionTime(void) const { return BigEndian::HostSwap32(mConnectionTime); } 796 797 /** 798 * Returns the Supervision Interval field 799 * 800 * @returns The Supervision Interval in seconds. Zero indicates not used. 801 * 802 */ GetSupervisionInterval(void) const803 uint16_t GetSupervisionInterval(void) const { return BigEndian::HostSwap16(mSupervisionInterval); } 804 805 /** 806 * Returns the Link Margin field. 807 * 808 * @returns The Link Margin in dB. 809 * 810 */ GetLinkMargin(void) const811 uint8_t GetLinkMargin(void) const { return mLinkMargin; } 812 813 /** 814 * Returns the Average RSSI field. 815 * 816 * @returns The Average RSSI in dBm. 127 if not available or unknown. 817 * 818 */ GetAverageRssi(void) const819 int8_t GetAverageRssi(void) const { return mAverageRssi; } 820 821 /** 822 * Returns the Last RSSI field (RSSI of last received frame from child). 823 * 824 * @returns The Last RSSI field in dBm. 127 if not available or unknown. 825 * 826 */ GetLastRssi(void) const827 int8_t GetLastRssi(void) const { return mLastRssi; } 828 829 /** 830 * Returns the Frame Error Rate field. 831 * 832 * `kFlagsTrackErrRate` from `GetFlags()` indicates whether or not the implementation supports tracking of error 833 * rates and whether or not the value in this field is valid. 834 * 835 * @returns The Frame Error Rate (0x0000->0%, 0xffff->100%). 836 * 837 */ GetFrameErrorRate(void) const838 uint16_t GetFrameErrorRate(void) const { return BigEndian::HostSwap16(mFrameErrorRate); } 839 840 /** 841 * Returns the Message Error Rate field. 842 * 843 * `kFlagsTrackErrRate` from `GetFlags()` indicates whether or not the implementation supports tracking of error 844 * rates and whether or not the value in this field is valid. 845 * 846 * @returns The Message Error Rate (0x0000->0%, 0xffff->100%). 847 * 848 */ GetMessageErrorRate(void) const849 uint16_t GetMessageErrorRate(void) const { return BigEndian::HostSwap16(mMessageErrorRate); } 850 851 /** 852 * Returns the Queued Message Count field. 853 * 854 * @returns The Queued Message Count (number of queued messages for indirect tx to child). 855 * 856 */ GetQueuedMessageCount(void) const857 uint16_t GetQueuedMessageCount(void) const { return BigEndian::HostSwap16(mQueuedMessageCount); } 858 859 /** 860 * Returns the CSL Period in unit of 10 symbols. 861 * 862 * @returns The CSL Period in unit of 10-symbols-time. Zero if CSL is not supported. 863 * 864 */ GetCslPeriod(void) const865 uint16_t GetCslPeriod(void) const { return BigEndian::HostSwap16(mCslPeriod); } 866 867 /** 868 * Returns the CSL Timeout in seconds. 869 * 870 * @returns The CSL Timeout in seconds. Zero if unknown on parent of if CSL Is not supported. 871 * 872 */ GetCslTimeout(void) const873 uint32_t GetCslTimeout(void) const { return BigEndian::HostSwap32(mCslTimeout); } 874 875 /** 876 * Returns the CSL Channel. 877 * 878 * @returns The CSL channel. 879 * 880 */ GetCslChannel(void) const881 uint8_t GetCslChannel(void) const { return mCslChannel; } 882 883 private: 884 uint8_t mFlags; // Flags (`kFlags*` constants). 885 uint16_t mRloc16; // RLOC16. 886 Mac::ExtAddress mExtAddress; // Extended Address. 887 uint16_t mVersion; // Version. 888 uint32_t mTimeout; // Timeout in seconds. 889 uint32_t mAge; // Seconds since last heard from the child. 890 uint32_t mConnectionTime; // Seconds since attach. 891 uint16_t mSupervisionInterval; // Supervision interval in seconds. Zero to indicate not used. 892 uint8_t mLinkMargin; // Link margin in dB. 893 int8_t mAverageRssi; // Average RSSI. 127 if not available or unknown 894 int8_t mLastRssi; // RSSI of last received frame. 127 if not available or unknown. 895 uint16_t mFrameErrorRate; // Frame error rate (0x0000->0%, 0xffff->100%). 896 uint16_t mMessageErrorRate; // (IPv6) msg error rate (0x0000->0%, 0xffff->100%) 897 uint16_t mQueuedMessageCount; // Number of queued messages for indirect tx to child. 898 uint16_t mCslPeriod; // CSL Period in unit of 10 symbols. 899 uint32_t mCslTimeout; // CSL Timeout in seconds. 900 uint8_t mCslChannel; // CSL channel. 901 } OT_TOOL_PACKED_END; 902 903 /** 904 * Implements Child IPv6 Address List Value generation and parsing. 905 * 906 * This TLV can use extended or normal format depending on the number of IPv6 addresses. 907 * 908 */ 909 OT_TOOL_PACKED_BEGIN 910 class ChildIp6AddressListTlvValue 911 { 912 public: 913 /** 914 * Returns the RLOC16 of the child. 915 * 916 * @returns The RLOC16 of the child. 917 * 918 */ GetRloc16(void) const919 uint16_t GetRloc16(void) const { return BigEndian::HostSwap16(mRloc16); } 920 921 /** 922 * Sets the RLOC16. 923 * 924 * @param[in] aRloc16 The RLOC16 value. 925 * 926 */ SetRloc16(uint16_t aRloc16)927 void SetRloc16(uint16_t aRloc16) { mRloc16 = BigEndian::HostSwap16(aRloc16); } 928 929 private: 930 uint16_t mRloc16; 931 // Followed by zero or more IPv6 address(es). 932 933 } OT_TOOL_PACKED_END; 934 935 /** 936 * Implements Router Neighbor TLV generation and parsing. 937 * 938 */ 939 OT_TOOL_PACKED_BEGIN 940 class RouterNeighborTlv : public Tlv, public TlvInfo<Tlv::kRouterNeighbor>, public Clearable<RouterNeighborTlv> 941 { 942 public: 943 static constexpr uint8_t kFlagsTrackErrRate = 1 << 7; ///< Supports tracking error rates. 944 945 /** 946 * Initializes the TLV using information from a given `Router`. 947 * 948 * @param[in] aRouter The router to initialize the TLV from. 949 * 950 */ 951 void InitFrom(const Router &aRouter); 952 953 /** 954 * Initializes the TLV as empty (zero length). 955 * 956 */ InitAsEmpty(void)957 void InitAsEmpty(void) 958 { 959 SetType(kRouterNeighbor); 960 SetLength(0); 961 } 962 963 /** 964 * Returns the Flags field (`kFlags*` constants define bits in flags). 965 * 966 * @returns The Flags field. 967 * 968 */ GetFlags(void) const969 uint8_t GetFlags(void) const { return mFlags; } 970 971 /** 972 * Returns the RLOC16 field. 973 * 974 * @returns The RLOC16 of the router. 975 * 976 */ GetRloc16(void) const977 uint16_t GetRloc16(void) const { return BigEndian::HostSwap16(mRloc16); } 978 979 /** 980 * Returns the Extended Address. 981 * 982 * @returns The Extended Address of the router. 983 * 984 */ GetExtAddress(void) const985 const Mac::ExtAddress &GetExtAddress(void) const { return mExtAddress; } 986 987 /** 988 * Returns the Version field. 989 * 990 * @returns The Version of the router. 991 * 992 */ GetVersion(void) const993 uint16_t GetVersion(void) const { return BigEndian::HostSwap16(mVersion); } 994 995 /** 996 * Returns the Connection Time field. 997 * 998 * @returns The Connection Time field (seconds since link establishment). 999 * 1000 */ GetConnectionTime(void) const1001 uint32_t GetConnectionTime(void) const { return BigEndian::HostSwap32(mConnectionTime); } 1002 1003 /** 1004 * Returns the Link Margin field. 1005 * 1006 * @returns The Link Margin in dB. 1007 * 1008 */ GetLinkMargin(void) const1009 uint8_t GetLinkMargin(void) const { return mLinkMargin; } 1010 1011 /** 1012 * Returns the Average RSSI field. 1013 * 1014 * @returns The Average RSSI in dBm. 127 if not available or unknown. 1015 * 1016 */ GetAverageRssi(void) const1017 int8_t GetAverageRssi(void) const { return mAverageRssi; } 1018 1019 /** 1020 * Returns the Last RSSI field (RSSI of last received frame from router). 1021 * 1022 * @returns The Last RSSI field in dBm. 127 if not available or unknown. 1023 * 1024 */ GetLastRssi(void) const1025 int8_t GetLastRssi(void) const { return mLastRssi; } 1026 1027 /** 1028 * Returns the Frame Error Rate field. 1029 * 1030 * `kFlagsTrackErrRate` from `GetFlags()` indicates whether or not the implementation supports tracking of error 1031 * rates and whether or not the value in this field is valid. 1032 * 1033 * @returns The Frame Error Rate (0x0000->0%, 0xffff->100%). 1034 * 1035 */ GetFrameErrorRate(void) const1036 uint16_t GetFrameErrorRate(void) const { return BigEndian::HostSwap16(mFrameErrorRate); } 1037 1038 /** 1039 * Returns the Message Error Rate field. 1040 * 1041 * `kFlagsTrackErrRate` from `GetFlags()` indicates whether or not the implementation supports tracking of error 1042 * rates and whether or not the value in this field is valid. 1043 * 1044 * @returns The Message Error Rate (0x0000->0%, 0xffff->100%). 1045 * 1046 */ GetMessageErrorRate(void) const1047 uint16_t GetMessageErrorRate(void) const { return BigEndian::HostSwap16(mMessageErrorRate); } 1048 1049 private: 1050 uint8_t mFlags; // Flags (`kFlags*` constants). 1051 uint16_t mRloc16; // RLOC16. 1052 Mac::ExtAddress mExtAddress; // Extended Address. 1053 uint16_t mVersion; // Version. 1054 uint32_t mConnectionTime; // Seconds since link establishment. 1055 uint8_t mLinkMargin; // Link Margin. 1056 int8_t mAverageRssi; // Average RSSI. 127 if not available or unknown 1057 int8_t mLastRssi; // RSSI of last received frame. 127 if not available or unknown. 1058 uint16_t mFrameErrorRate; // Frame error rate (0x0000->0%, 0xffff->100%). 1059 uint16_t mMessageErrorRate; // (IPv6) msg error rate (0x0000->0%, 0xffff->100%) 1060 } OT_TOOL_PACKED_END; 1061 1062 #endif // OPENTHREAD_FTD 1063 1064 /** 1065 * Implements Answer TLV generation and parsing. 1066 * 1067 */ 1068 OT_TOOL_PACKED_BEGIN 1069 class AnswerTlv : public Tlv, public TlvInfo<Tlv::kAnswer> 1070 { 1071 public: 1072 /** 1073 * Initializes the TLV. 1074 * 1075 * @param[in] aIndex The index value. 1076 * @param[in] aIsLast The "IsLast" flag value. 1077 * 1078 */ 1079 void Init(uint16_t aIndex, bool aIsLast); 1080 1081 /** 1082 * Indicates whether or not the "IsLast" flag is set 1083 * 1084 * @retval TRUE "IsLast" flag si set (this is the last answer for this query). 1085 * @retval FALSE "IsLast" flag is not set (more answer messages are expected for this query). 1086 * 1087 */ IsLast(void) const1088 bool IsLast(void) const { return GetFlagsIndex() & kIsLastFlag; } 1089 1090 /** 1091 * Gets the index. 1092 * 1093 * @returns The index. 1094 * 1095 */ GetIndex(void) const1096 uint16_t GetIndex(void) const { return GetFlagsIndex() & kIndexMask; } 1097 1098 private: 1099 static constexpr uint16_t kIsLastFlag = 1 << 15; 1100 static constexpr uint16_t kIndexMask = 0x7f; 1101 GetFlagsIndex(void) const1102 uint16_t GetFlagsIndex(void) const { return BigEndian::HostSwap16(mFlagsIndex); } SetFlagsIndex(uint16_t aFlagsIndex)1103 void SetFlagsIndex(uint16_t aFlagsIndex) { mFlagsIndex = BigEndian::HostSwap16(aFlagsIndex); } 1104 1105 uint16_t mFlagsIndex; 1106 } OT_TOOL_PACKED_END; 1107 1108 /** 1109 * Represents the MLE Counters. 1110 * 1111 */ 1112 typedef otNetworkDiagMleCounters MleCounters; 1113 1114 /** 1115 * Implements MLE Counters TLV generation and parsing. 1116 * 1117 */ 1118 OT_TOOL_PACKED_BEGIN 1119 class MleCountersTlv : public Tlv, public TlvInfo<Tlv::kMleCounters> 1120 { 1121 public: 1122 /** 1123 * Initializes the TLV. 1124 * 1125 * @param[in] aMleCounters The MLE counters to initialize the TLV with. 1126 * 1127 */ 1128 void Init(const Mle::Counters &aMleCounters); 1129 1130 /** 1131 * Indicates whether or not the TLV appears to be well-formed. 1132 * 1133 * @retval TRUE If the TLV appears to be well-formed. 1134 * @retval FALSE If the TLV does not appear to be well-formed. 1135 * 1136 */ IsValid(void) const1137 bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(Tlv); } 1138 1139 /** 1140 * 1141 * Reads the counters from TLV. 1142 * 1143 * @param[out] aDiagMleCounters A reference to `NetworkDiagnostic::MleCounters` to populate. 1144 * 1145 */ 1146 void Read(MleCounters &aDiagMleCounters) const; 1147 1148 private: 1149 uint16_t mDisabledRole; // Number of times device entered disabled role. 1150 uint16_t mDetachedRole; // Number of times device entered detached role. 1151 uint16_t mChildRole; // Number of times device entered child role. 1152 uint16_t mRouterRole; // Number of times device entered router role. 1153 uint16_t mLeaderRole; // Number of times device entered leader role. 1154 uint16_t mAttachAttempts; // Number of attach attempts while device was detached. 1155 uint16_t mPartitionIdChanges; // Number of changes to partition ID. 1156 uint16_t mBetterPartitionAttachAttempts; // Number of attempts to attach to a better partition. 1157 uint16_t mParentChanges; // Number of time device changed its parent. 1158 uint64_t mTrackedTime; // Milliseconds tracked by next counters. 1159 uint64_t mDisabledTime; // Milliseconds device has been in disabled role. 1160 uint64_t mDetachedTime; // Milliseconds device has been in detached role. 1161 uint64_t mChildTime; // Milliseconds device has been in child role. 1162 uint64_t mRouterTime; // Milliseconds device has been in router role. 1163 uint64_t mLeaderTime; // Milliseconds device has been in leader role. 1164 } OT_TOOL_PACKED_END; 1165 1166 } // namespace NetworkDiagnostic 1167 } // namespace ot 1168 1169 #endif // NETWORK_DIAGNOSTIC_TLVS_HPP_ 1170