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