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 maintaining Thread network topologies. 32 */ 33 34 #ifndef TOPOLOGY_HPP_ 35 #define TOPOLOGY_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <openthread/thread_ftd.h> 40 41 #include "common/as_core_type.hpp" 42 #include "common/clearable.hpp" 43 #include "common/equatable.hpp" 44 #include "common/linked_list.hpp" 45 #include "common/locator.hpp" 46 #include "common/message.hpp" 47 #include "common/random.hpp" 48 #include "common/serial_number.hpp" 49 #include "common/timer.hpp" 50 #include "mac/mac_types.hpp" 51 #include "net/ip6.hpp" 52 #include "radio/radio.hpp" 53 #include "radio/trel_link.hpp" 54 #include "thread/csl_tx_scheduler.hpp" 55 #include "thread/indirect_sender.hpp" 56 #include "thread/link_metrics.hpp" 57 #include "thread/link_quality.hpp" 58 #include "thread/mle_tlvs.hpp" 59 #include "thread/mle_types.hpp" 60 #include "thread/network_data_types.hpp" 61 #include "thread/radio_selector.hpp" 62 63 namespace ot { 64 65 /** 66 * This class represents a Thread neighbor. 67 * 68 */ 69 class Neighbor : public InstanceLocatorInit 70 #if OPENTHREAD_CONFIG_MULTI_RADIO 71 , 72 public RadioSelector::NeighborInfo 73 #endif 74 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE 75 , 76 public Trel::NeighborInfo 77 #endif 78 { 79 public: 80 /** 81 * Neighbor link states. 82 * 83 */ 84 enum State : uint8_t 85 { 86 kStateInvalid, ///< Neighbor link is invalid 87 kStateRestored, ///< Neighbor is restored from non-volatile memory 88 kStateParentRequest, ///< Received an MLE Parent Request message 89 kStateParentResponse, ///< Received an MLE Parent Response message 90 kStateChildIdRequest, ///< Received an MLE Child ID Request message 91 kStateLinkRequest, ///< Sent an MLE Link Request message 92 kStateChildUpdateRequest, ///< Sent an MLE Child Update Request message (trying to restore the child) 93 kStateValid, ///< Link is valid 94 }; 95 96 /** 97 * This enumeration defines state filters used for finding a neighbor or iterating through the child/neighbor table. 98 * 99 * Each filter definition accepts a subset of `State` values. 100 * 101 */ 102 enum StateFilter : uint8_t 103 { 104 kInStateValid, ///< Accept neighbor only in `kStateValid`. 105 kInStateValidOrRestoring, ///< Accept neighbor with `IsStateValidOrRestoring()` being `true`. 106 kInStateChildIdRequest, ///< Accept neighbor only in `Child:kStateChildIdRequest`. 107 kInStateValidOrAttaching, ///< Accept neighbor with `IsStateValidOrAttaching()` being `true`. 108 kInStateInvalid, ///< Accept neighbor only in `kStateInvalid`. 109 kInStateAnyExceptInvalid, ///< Accept neighbor in any state except `kStateInvalid`. 110 kInStateAnyExceptValidOrRestoring, ///< Accept neighbor in any state except `IsStateValidOrRestoring()`. 111 kInStateAny, ///< Accept neighbor in any state. 112 }; 113 114 /** 115 * This class represents an Address Matcher used to find a neighbor (child/router) with a given MAC address also 116 * matching a given state filter. 117 * 118 */ 119 class AddressMatcher 120 { 121 public: 122 /** 123 * This constructor initializes the `AddressMatcher` with a given MAC short address (RCOC16) and state filter. 124 * 125 * @param[in] aShortAddress A MAC short address (RLOC16). 126 * @param[in] aStateFilter A state filter. 127 * 128 */ AddressMatcher(Mac::ShortAddress aShortAddress,StateFilter aStateFilter)129 AddressMatcher(Mac::ShortAddress aShortAddress, StateFilter aStateFilter) 130 : AddressMatcher(aStateFilter, aShortAddress, nullptr) 131 { 132 } 133 134 /** 135 * This constructor initializes the `AddressMatcher` with a given MAC extended address and state filter. 136 * 137 * @param[in] aExtAddress A MAC extended address. 138 * @param[in] aStateFilter A state filter. 139 * 140 */ AddressMatcher(const Mac::ExtAddress & aExtAddress,StateFilter aStateFilter)141 AddressMatcher(const Mac::ExtAddress &aExtAddress, StateFilter aStateFilter) 142 : AddressMatcher(aStateFilter, Mac::kShortAddrInvalid, &aExtAddress) 143 { 144 } 145 146 /** 147 * This constructor initializes the `AddressMatcher` with a given MAC address and state filter. 148 * 149 * @param[in] aMacAddress A MAC address. 150 * @param[in] aStateFilter A state filter. 151 * 152 */ AddressMatcher(const Mac::Address & aMacAddress,StateFilter aStateFilter)153 AddressMatcher(const Mac::Address &aMacAddress, StateFilter aStateFilter) 154 : AddressMatcher(aStateFilter, 155 aMacAddress.IsShort() ? aMacAddress.GetShort() 156 : static_cast<Mac::ShortAddress>(Mac::kShortAddrInvalid), 157 aMacAddress.IsExtended() ? &aMacAddress.GetExtended() : nullptr) 158 { 159 } 160 161 /** 162 * This constructor initializes the `AddressMatcher` with a given state filter (it accepts any address). 163 * 164 * @param[in] aStateFilter A state filter. 165 * 166 */ AddressMatcher(StateFilter aStateFilter)167 explicit AddressMatcher(StateFilter aStateFilter) 168 : AddressMatcher(aStateFilter, Mac::kShortAddrInvalid, nullptr) 169 { 170 } 171 172 /** 173 * This method indicates if a given neighbor matches the address and state filter of `AddressMatcher`. 174 * 175 * @param[in] aNeighbor A neighbor. 176 * 177 * @retval TRUE Neighbor @p aNeighbor matches the address and state filter. 178 * @retval FALSE Neighbor @p aNeighbor does not match the address or state filter. 179 * 180 */ 181 bool Matches(const Neighbor &aNeighbor) const; 182 183 private: AddressMatcher(StateFilter aStateFilter,Mac::ShortAddress aShortAddress,const Mac::ExtAddress * aExtAddress)184 AddressMatcher(StateFilter aStateFilter, Mac::ShortAddress aShortAddress, const Mac::ExtAddress *aExtAddress) 185 : mStateFilter(aStateFilter) 186 , mShortAddress(aShortAddress) 187 , mExtAddress(aExtAddress) 188 { 189 } 190 191 StateFilter mStateFilter; 192 Mac::ShortAddress mShortAddress; 193 const Mac::ExtAddress *mExtAddress; 194 }; 195 196 /** 197 * This type represents diagnostic information for a neighboring node. 198 * 199 */ 200 class Info : public otNeighborInfo, public Clearable<Info> 201 { 202 public: 203 /** 204 * This method sets the `Info` instance from a given `Neighbor`. 205 * 206 * @param[in] aNeighbor A neighbor. 207 * 208 */ 209 void SetFrom(const Neighbor &aNeighbor); 210 }; 211 212 /** 213 * This method returns the current state. 214 * 215 * @returns The current state. 216 * 217 */ GetState(void) const218 State GetState(void) const { return static_cast<State>(mState); } 219 220 /** 221 * This method sets the current state. 222 * 223 * @param[in] aState The state value. 224 * 225 */ SetState(State aState)226 void SetState(State aState) { mState = static_cast<uint8_t>(aState); } 227 228 /** 229 * This method indicates whether the neighbor is in the Invalid state. 230 * 231 * @returns TRUE if the neighbor is in the Invalid state, FALSE otherwise. 232 * 233 */ IsStateInvalid(void) const234 bool IsStateInvalid(void) const { return (mState == kStateInvalid); } 235 236 /** 237 * This method indicates whether the neighbor is in the Child ID Request state. 238 * 239 * @returns TRUE if the neighbor is in the Child ID Request state, FALSE otherwise. 240 * 241 */ IsStateChildIdRequest(void) const242 bool IsStateChildIdRequest(void) const { return (mState == kStateChildIdRequest); } 243 244 /** 245 * This method indicates whether the neighbor is in the Link Request state. 246 * 247 * @returns TRUE if the neighbor is in the Link Request state, FALSE otherwise. 248 * 249 */ IsStateLinkRequest(void) const250 bool IsStateLinkRequest(void) const { return (mState == kStateLinkRequest); } 251 252 /** 253 * This method indicates whether the neighbor is in the Parent Response state. 254 * 255 * @returns TRUE if the neighbor is in the Parent Response state, FALSE otherwise. 256 * 257 */ IsStateParentResponse(void) const258 bool IsStateParentResponse(void) const { return (mState == kStateParentResponse); } 259 260 /** 261 * This method indicates whether the neighbor is being restored. 262 * 263 * @returns TRUE if the neighbor is being restored, FALSE otherwise. 264 * 265 */ IsStateRestoring(void) const266 bool IsStateRestoring(void) const { return (mState == kStateRestored) || (mState == kStateChildUpdateRequest); } 267 268 /** 269 * This method indicates whether the neighbor is in the Restored state. 270 * 271 * @returns TRUE if the neighbor is in the Restored state, FALSE otherwise. 272 * 273 */ IsStateRestored(void) const274 bool IsStateRestored(void) const { return (mState == kStateRestored); } 275 276 /** 277 * This method indicates whether the neighbor is valid (frame counters are synchronized). 278 * 279 * @returns TRUE if the neighbor is valid, FALSE otherwise. 280 * 281 */ IsStateValid(void) const282 bool IsStateValid(void) const { return (mState == kStateValid); } 283 284 /** 285 * This method indicates whether the neighbor is in valid state or if it is being restored. 286 * 287 * When in these states messages can be sent to and/or received from the neighbor. 288 * 289 * @returns TRUE if the neighbor is in valid, restored, or being restored states, FALSE otherwise. 290 * 291 */ IsStateValidOrRestoring(void) const292 bool IsStateValidOrRestoring(void) const { return (mState == kStateValid) || IsStateRestoring(); } 293 294 /** 295 * This method indicates if the neighbor state is valid, attaching, or restored. 296 * 297 * The states `kStateRestored`, `kStateChildIdRequest`, `kStateChildUpdateRequest`, `kStateValid`, and 298 * `kStateLinkRequest` are considered as valid, attaching, or restored. 299 * 300 * @returns TRUE if the neighbor state is valid, attaching, or restored, FALSE otherwise. 301 * 302 */ 303 bool IsStateValidOrAttaching(void) const; 304 305 /** 306 * This method indicates whether neighbor state matches a given state filter. 307 * 308 * @param[in] aFilter A state filter (`StateFilter` enumeration) to match against. 309 * 310 * @returns TRUE if the neighbor state matches the filter, FALSE otherwise. 311 * 312 */ 313 bool MatchesFilter(StateFilter aFilter) const; 314 315 /** 316 * This method indicates whether neighbor matches a given `AddressMatcher`. 317 * 318 * @param[in] aMatcher An `AddressMatcher` to match against. 319 * 320 * @returns TRUE if the neighbor matches the address and state filter of @p aMatcher, FALSE otherwise. 321 * 322 */ Matches(const AddressMatcher & aMatcher) const323 bool Matches(const AddressMatcher &aMatcher) const { return aMatcher.Matches(*this); } 324 325 /** 326 * This method gets the device mode flags. 327 * 328 * @returns The device mode flags. 329 * 330 */ GetDeviceMode(void) const331 Mle::DeviceMode GetDeviceMode(void) const { return Mle::DeviceMode(mMode); } 332 333 /** 334 * This method sets the device mode flags. 335 * 336 * @param[in] aMode The device mode flags. 337 * 338 */ SetDeviceMode(Mle::DeviceMode aMode)339 void SetDeviceMode(Mle::DeviceMode aMode) { mMode = aMode.Get(); } 340 341 /** 342 * This method indicates whether or not the device is rx-on-when-idle. 343 * 344 * @returns TRUE if rx-on-when-idle, FALSE otherwise. 345 * 346 */ IsRxOnWhenIdle(void) const347 bool IsRxOnWhenIdle(void) const { return GetDeviceMode().IsRxOnWhenIdle(); } 348 349 /** 350 * This method indicates whether or not the device is a Full Thread Device. 351 * 352 * @returns TRUE if a Full Thread Device, FALSE otherwise. 353 * 354 */ IsFullThreadDevice(void) const355 bool IsFullThreadDevice(void) const { return GetDeviceMode().IsFullThreadDevice(); } 356 357 /** 358 * This method gets the Network Data type (full set or stable subset) that the device requests. 359 * 360 * @returns The Network Data type. 361 * 362 */ GetNetworkDataType(void) const363 NetworkData::Type GetNetworkDataType(void) const { return GetDeviceMode().GetNetworkDataType(); } 364 365 /** 366 * This method sets all bytes of the Extended Address to zero. 367 * 368 */ ClearExtAddress(void)369 void ClearExtAddress(void) { memset(&mMacAddr, 0, sizeof(mMacAddr)); } 370 371 /** 372 * This method returns the Extended Address. 373 * 374 * @returns A reference to the Extended Address. 375 * 376 */ GetExtAddress(void) const377 const Mac::ExtAddress &GetExtAddress(void) const { return mMacAddr; } 378 379 /** 380 * This method sets the Extended Address. 381 * 382 * @param[in] aAddress The Extended Address value to set. 383 * 384 */ SetExtAddress(const Mac::ExtAddress & aAddress)385 void SetExtAddress(const Mac::ExtAddress &aAddress) { mMacAddr = aAddress; } 386 387 /** 388 * This method gets the key sequence value. 389 * 390 * @returns The key sequence value. 391 * 392 */ GetKeySequence(void) const393 uint32_t GetKeySequence(void) const { return mKeySequence; } 394 395 /** 396 * This method sets the key sequence value. 397 * 398 * @param[in] aKeySequence The key sequence value. 399 * 400 */ SetKeySequence(uint32_t aKeySequence)401 void SetKeySequence(uint32_t aKeySequence) { mKeySequence = aKeySequence; } 402 403 /** 404 * This method returns the last heard time. 405 * 406 * @returns The last heard time. 407 * 408 */ GetLastHeard(void) const409 TimeMilli GetLastHeard(void) const { return mLastHeard; } 410 411 /** 412 * This method sets the last heard time. 413 * 414 * @param[in] aLastHeard The last heard time. 415 * 416 */ SetLastHeard(TimeMilli aLastHeard)417 void SetLastHeard(TimeMilli aLastHeard) { mLastHeard = aLastHeard; } 418 419 /** 420 * This method gets the link frame counters. 421 * 422 * @returns A reference to `Mac::LinkFrameCounters` containing link frame counter for all supported radio links. 423 * 424 */ GetLinkFrameCounters(void)425 Mac::LinkFrameCounters &GetLinkFrameCounters(void) { return mValidPending.mValid.mLinkFrameCounters; } 426 427 /** 428 * This method gets the link frame counters. 429 * 430 * @returns A reference to `Mac::LinkFrameCounters` containing link frame counter for all supported radio links. 431 * 432 */ GetLinkFrameCounters(void) const433 const Mac::LinkFrameCounters &GetLinkFrameCounters(void) const { return mValidPending.mValid.mLinkFrameCounters; } 434 435 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 436 /** 437 * This method gets the link ACK frame counter value. 438 * 439 * @returns The link ACK frame counter value. 440 * 441 */ GetLinkAckFrameCounter(void) const442 uint32_t GetLinkAckFrameCounter(void) const { return mValidPending.mValid.mLinkAckFrameCounter; } 443 #endif 444 445 /** 446 * This method sets the link ACK frame counter value. 447 * 448 * @param[in] aAckFrameCounter The link ACK frame counter value. 449 * 450 */ SetLinkAckFrameCounter(uint32_t aAckFrameCounter)451 void SetLinkAckFrameCounter(uint32_t aAckFrameCounter) 452 { 453 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 454 mValidPending.mValid.mLinkAckFrameCounter = aAckFrameCounter; 455 #else 456 OT_UNUSED_VARIABLE(aAckFrameCounter); 457 #endif 458 } 459 460 /** 461 * This method gets the MLE frame counter value. 462 * 463 * @returns The MLE frame counter value. 464 * 465 */ GetMleFrameCounter(void) const466 uint32_t GetMleFrameCounter(void) const { return mValidPending.mValid.mMleFrameCounter; } 467 468 /** 469 * This method sets the MLE frame counter value. 470 * 471 * @param[in] aFrameCounter The MLE frame counter value. 472 * 473 */ SetMleFrameCounter(uint32_t aFrameCounter)474 void SetMleFrameCounter(uint32_t aFrameCounter) { mValidPending.mValid.mMleFrameCounter = aFrameCounter; } 475 476 /** 477 * This method gets the RLOC16 value. 478 * 479 * @returns The RLOC16 value. 480 * 481 */ GetRloc16(void) const482 uint16_t GetRloc16(void) const { return mRloc16; } 483 484 /** 485 * This method gets the Router ID value. 486 * 487 * @returns The Router ID value. 488 * 489 */ GetRouterId(void) const490 uint8_t GetRouterId(void) const { return mRloc16 >> Mle::kRouterIdOffset; } 491 492 /** 493 * This method sets the RLOC16 value. 494 * 495 * @param[in] aRloc16 The RLOC16 value. 496 * 497 */ SetRloc16(uint16_t aRloc16)498 void SetRloc16(uint16_t aRloc16) { mRloc16 = aRloc16; } 499 500 #if OPENTHREAD_CONFIG_MULTI_RADIO 501 /** 502 * This method clears the last received fragment tag. 503 * 504 * The last received fragment tag is used for detect duplicate frames (received over different radios) when 505 * multi-radio feature is enabled. 506 * 507 */ ClearLastRxFragmentTag(void)508 void ClearLastRxFragmentTag(void) { mLastRxFragmentTag = 0; } 509 510 /** 511 * This method gets the last received fragment tag. 512 * 513 * This method MUST be used only when the tag is set (and not cleared). Otherwise its behavior is undefined. 514 * 515 * @returns The last received fragment tag. 516 * 517 */ GetLastRxFragmentTag(void) const518 uint16_t GetLastRxFragmentTag(void) const { return mLastRxFragmentTag; } 519 520 /** 521 * This method set the last received fragment tag. 522 * 523 * @param[in] aTag The new tag value. 524 * 525 */ 526 void SetLastRxFragmentTag(uint16_t aTag); 527 528 /** 529 * This method indicates whether or not the last received fragment tag is set and valid (i.e., not yet timed out). 530 * 531 * @returns TRUE if the last received fragment tag is set and valid, FALSE otherwise. 532 * 533 */ 534 bool IsLastRxFragmentTagSet(void) const; 535 536 /** 537 * This method indicates whether the last received fragment tag is strictly after a given tag value. 538 * 539 * This method MUST be used only when the tag is set (and not cleared). Otherwise its behavior is undefined. 540 * 541 * The tag value compassion follows the Serial Number Arithmetic logic from RFC-1982. It is semantically equivalent 542 * to `LastRxFragementTag > aTag`. 543 * 544 * @param[in] aTag A tag value to compare against. 545 * 546 * @returns TRUE if the current last rx fragment tag is strictly after @p aTag, FALSE if they are equal or it is 547 * before @p aTag. 548 * 549 */ IsLastRxFragmentTagAfter(uint16_t aTag) const550 bool IsLastRxFragmentTagAfter(uint16_t aTag) const { return SerialNumber::IsGreater(mLastRxFragmentTag, aTag); } 551 552 #endif // OPENTHREAD_CONFIG_MULTI_RADIO 553 554 /** 555 * This method indicates whether or not it is Thread 1.1. 556 * 557 * @returns TRUE if neighbors is Thread 1.1, FALSE otherwise. 558 * 559 */ IsThreadVersion1p1(void) const560 bool IsThreadVersion1p1(void) const { return mState != kStateInvalid && mVersion == OT_THREAD_VERSION_1_1; } 561 562 /** 563 * This method indicates whether or not neighbor is Thread 1.2 or higher.. 564 * 565 * @returns TRUE if neighbor is Thread 1.2 or higher, FALSE otherwise. 566 * 567 */ IsThreadVersion1p2OrHigher(void) const568 bool IsThreadVersion1p2OrHigher(void) const { return mState != kStateInvalid && mVersion >= OT_THREAD_VERSION_1_2; } 569 570 /** 571 * This method indicates whether Thread version supports CSL. 572 * 573 * @returns TRUE if CSL is supported, FALSE otherwise. 574 * 575 */ IsThreadVersionCslCapable(void) const576 bool IsThreadVersionCslCapable(void) const { return IsThreadVersion1p2OrHigher() && !IsRxOnWhenIdle(); } 577 578 /** 579 * This method indicates whether Enhanced Keep-Alive is supported or not. 580 * 581 * @returns TRUE if Enhanced Keep-Alive is supported, FALSE otherwise. 582 * 583 */ IsEnhancedKeepAliveSupported(void) const584 bool IsEnhancedKeepAliveSupported(void) const 585 { 586 return mState != kStateInvalid && mVersion >= OT_THREAD_VERSION_1_2; 587 } 588 589 /** 590 * This method gets the device MLE version. 591 * 592 */ GetVersion(void) const593 uint8_t GetVersion(void) const { return mVersion; } 594 595 /** 596 * This method sets the device MLE version. 597 * 598 * @param[in] aVersion The device MLE version. 599 * 600 */ SetVersion(uint8_t aVersion)601 void SetVersion(uint8_t aVersion) { mVersion = aVersion; } 602 603 /** 604 * This method gets the number of consecutive link failures. 605 * 606 * @returns The number of consecutive link failures. 607 * 608 */ GetLinkFailures(void) const609 uint8_t GetLinkFailures(void) const { return mLinkFailures; } 610 611 /** 612 * This method increments the number of consecutive link failures. 613 * 614 */ IncrementLinkFailures(void)615 void IncrementLinkFailures(void) { mLinkFailures++; } 616 617 /** 618 * This method resets the number of consecutive link failures to zero. 619 * 620 */ ResetLinkFailures(void)621 void ResetLinkFailures(void) { mLinkFailures = 0; } 622 623 /** 624 * This method returns the LinkQualityInfo object. 625 * 626 * @returns The LinkQualityInfo object. 627 * 628 */ GetLinkInfo(void)629 LinkQualityInfo &GetLinkInfo(void) { return mLinkInfo; } 630 631 /** 632 * This method returns the LinkQualityInfo object. 633 * 634 * @returns The LinkQualityInfo object. 635 * 636 */ GetLinkInfo(void) const637 const LinkQualityInfo &GetLinkInfo(void) const { return mLinkInfo; } 638 639 /** 640 * This method generates a new challenge value for MLE Link Request/Response exchanges. 641 * 642 */ 643 void GenerateChallenge(void); 644 645 /** 646 * This method returns the current challenge value for MLE Link Request/Response exchanges. 647 * 648 * @returns The current challenge value. 649 * 650 */ GetChallenge(void) const651 const uint8_t *GetChallenge(void) const { return mValidPending.mPending.mChallenge; } 652 653 /** 654 * This method returns the size (bytes) of the challenge value for MLE Link Request/Response exchanges. 655 * 656 * @returns The size (bytes) of the challenge value for MLE Link Request/Response exchanges. 657 * 658 */ GetChallengeSize(void) const659 uint8_t GetChallengeSize(void) const { return sizeof(mValidPending.mPending.mChallenge); } 660 661 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 662 /** 663 * This method indicates whether or not time sync feature is enabled. 664 * 665 * @returns TRUE if time sync feature is enabled, FALSE otherwise. 666 * 667 */ IsTimeSyncEnabled(void) const668 bool IsTimeSyncEnabled(void) const { return mTimeSyncEnabled; } 669 670 /** 671 * This method sets whether or not time sync feature is enabled. 672 * 673 * @param[in] aEnable TRUE if time sync feature is enabled, FALSE otherwise. 674 * 675 */ SetTimeSyncEnabled(bool aEnabled)676 void SetTimeSyncEnabled(bool aEnabled) { mTimeSyncEnabled = aEnabled; } 677 #endif 678 679 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 680 /** 681 * This method aggregates the Link Metrics data into all the series that is running for this neighbor. 682 * 683 * If a series wants to account frames of @p aFrameType, it would add count by 1 and aggregate @p aLqi and 684 * @p aRss into its averagers. 685 * 686 * @param[in] aSeriesId Series ID for Link Probe. Should be `0` if this method is not called by Link Probe. 687 * @param[in] aFrameType Type of the frame that carries Link Metrics data. 688 * @param[in] aLqi The LQI value. 689 * @param[in] aRss The Rss value. 690 * 691 */ 692 void AggregateLinkMetrics(uint8_t aSeriesId, uint8_t aFrameType, uint8_t aLqi, int8_t aRss); 693 694 /** 695 * This method adds a new LinkMetrics::SeriesInfo to the neighbor's list. 696 * 697 * @param[in] aSeriesInfo A reference to the new SeriesInfo. 698 * 699 */ 700 void AddForwardTrackingSeriesInfo(LinkMetrics::SeriesInfo &aSeriesInfo); 701 702 /** 703 * This method finds a specific LinkMetrics::SeriesInfo by Series ID. 704 * 705 * @param[in] aSeriesId A reference to the Series ID. 706 * 707 * @returns The pointer to the LinkMetrics::SeriesInfo. `nullptr` if not found. 708 * 709 */ 710 LinkMetrics::SeriesInfo *GetForwardTrackingSeriesInfo(const uint8_t &aSeriesId); 711 712 /** 713 * This method removes a specific LinkMetrics::SeriesInfo by Series ID. 714 * 715 * @param[in] aSeriesId A reference to the Series ID to remove. 716 * 717 * @returns The pointer to the LinkMetrics::SeriesInfo. `nullptr` if not found. 718 * 719 */ 720 LinkMetrics::SeriesInfo *RemoveForwardTrackingSeriesInfo(const uint8_t &aSeriesId); 721 722 /** 723 * This method removes all the Series and return the data structures to the Pool. 724 * 725 */ 726 void RemoveAllForwardTrackingSeriesInfo(void); 727 728 /** 729 * This method gets the Enh-ACK Probing metrics (this `Neighbor` object is the Probing Subject). 730 * 731 * @returns Enh-ACK Probing metrics configured. 732 * 733 */ GetEnhAckProbingMetrics(void) const734 const LinkMetrics::Metrics &GetEnhAckProbingMetrics(void) const { return mEnhAckProbingMetrics; } 735 736 /** 737 * This method sets the Enh-ACK Probing metrics (this `Neighbor` object is the Probing Subject). 738 * 739 * @param[in] aEnhAckProbingMetrics The metrics value to set. 740 * 741 */ SetEnhAckProbingMetrics(const LinkMetrics::Metrics & aEnhAckProbingMetrics)742 void SetEnhAckProbingMetrics(const LinkMetrics::Metrics &aEnhAckProbingMetrics) 743 { 744 mEnhAckProbingMetrics = aEnhAckProbingMetrics; 745 } 746 747 /** 748 * This method indicates if Enh-ACK Probing is configured and active for this `Neighbor` object. 749 * 750 * @retval TRUE Enh-ACK Probing is configured and active for this `Neighbor`. 751 * @retval FALSE Otherwise. 752 * 753 */ IsEnhAckProbingActive(void) const754 bool IsEnhAckProbingActive(void) const 755 { 756 return (mEnhAckProbingMetrics.mLqi != 0) || (mEnhAckProbingMetrics.mLinkMargin != 0) || 757 (mEnhAckProbingMetrics.mRssi != 0); 758 } 759 #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 760 761 /** 762 * This method converts a given `State` to a human-readable string. 763 * 764 * @param[in] aState A neighbor state. 765 * 766 * @returns A string representation of given state. 767 * 768 */ 769 static const char *StateToString(State aState); 770 771 protected: 772 /** 773 * This method initializes the `Neighbor` object. 774 * 775 * @param[in] aInstance A reference to OpenThread instance. 776 * 777 */ 778 void Init(Instance &aInstance); 779 780 private: 781 enum : uint32_t 782 { 783 kLastRxFragmentTagTimeout = OPENTHREAD_CONFIG_MULTI_RADIO_FRAG_TAG_TIMEOUT, ///< Frag tag timeout in msec. 784 }; 785 786 Mac::ExtAddress mMacAddr; ///< The IEEE 802.15.4 Extended Address 787 TimeMilli mLastHeard; ///< Time when last heard. 788 union 789 { 790 struct 791 { 792 Mac::LinkFrameCounters mLinkFrameCounters; ///< The Link Frame Counters 793 uint32_t mMleFrameCounter; ///< The MLE Frame Counter 794 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 795 uint32_t mLinkAckFrameCounter; ///< The Link Ack Frame Counter 796 #endif 797 } mValid; 798 struct 799 { 800 uint8_t mChallenge[Mle::kMaxChallengeSize]; ///< The challenge value 801 } mPending; 802 } mValidPending; 803 804 #if OPENTHREAD_CONFIG_MULTI_RADIO 805 uint16_t mLastRxFragmentTag; ///< Last received fragment tag 806 TimeMilli mLastRxFragmentTagTime; ///< The time last fragment tag was received and set. 807 #endif 808 809 uint32_t mKeySequence; ///< Current key sequence 810 uint16_t mRloc16; ///< The RLOC16 811 uint8_t mState : 4; ///< The link state 812 uint8_t mMode : 4; ///< The MLE device mode 813 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 814 uint8_t mLinkFailures : 7; ///< Consecutive link failure count 815 bool mTimeSyncEnabled : 1; ///< Indicates whether or not time sync feature is enabled. 816 #else 817 uint8_t mLinkFailures; ///< Consecutive link failure count 818 #endif 819 uint8_t mVersion; ///< The MLE version 820 LinkQualityInfo mLinkInfo; ///< Link quality info (contains average RSS, link margin and link quality) 821 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 822 // A list of Link Metrics Forward Tracking Series that is being 823 // tracked for this neighbor. Note that this device is the 824 // Subject and this neighbor is the Initiator. 825 LinkedList<LinkMetrics::SeriesInfo> mLinkMetricsSeriesInfoList; 826 827 // Metrics configured for Enh-ACK Based Probing at the Probing 828 // Subject (this neighbor). Note that this device is the Initiator 829 // and this neighbor is the Subject. 830 LinkMetrics::Metrics mEnhAckProbingMetrics; 831 #endif 832 }; 833 834 #if OPENTHREAD_FTD 835 836 /** 837 * This class represents a Thread Child. 838 * 839 */ 840 class Child : public Neighbor, 841 public IndirectSender::ChildInfo, 842 public DataPollHandler::ChildInfo 843 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE 844 , 845 public CslTxScheduler::ChildInfo 846 #endif 847 { 848 class AddressIteratorBuilder; 849 850 public: 851 static constexpr uint8_t kMaxRequestTlvs = 5; 852 853 /** 854 * This class represents diagnostic information for a Thread Child. 855 * 856 */ 857 class Info : public otChildInfo, public Clearable<Info> 858 { 859 public: 860 /** 861 * This method sets the `Info` instance from a given `Child`. 862 * 863 * @param[in] aChild A neighbor. 864 * 865 */ 866 void SetFrom(const Child &aChild); 867 }; 868 869 /** 870 * This class defines an iterator used to go through IPv6 address entries of a child. 871 * 872 */ 873 class AddressIterator : public Unequatable<AddressIterator> 874 { 875 friend class AddressIteratorBuilder; 876 877 public: 878 /** 879 * This type represents an index indicating the current IPv6 address entry to which the iterator is pointing. 880 * 881 */ 882 typedef otChildIp6AddressIterator Index; 883 884 /** 885 * This constructor initializes the iterator associated with a given `Child` starting from beginning of the 886 * IPv6 address list. 887 * 888 * @param[in] aChild A reference to a child entry. 889 * @param[in] aFilter An IPv6 address type filter restricting iterator to certain type of addresses. 890 * 891 */ AddressIterator(const Child & aChild,Ip6::Address::TypeFilter aFilter=Ip6::Address::kTypeAny)892 explicit AddressIterator(const Child &aChild, Ip6::Address::TypeFilter aFilter = Ip6::Address::kTypeAny) 893 : AddressIterator(aChild, 0, aFilter) 894 { 895 } 896 897 /** 898 * This constructor initializes the iterator associated with a given `Child` starting from a given index 899 * 900 * @param[in] aChild A reference to the child entry. 901 * @param[in] aIndex An index (`Index`) with which to initialize the iterator. 902 * @param[in] aFilter An IPv6 address type filter restricting iterator to certain type of addresses. 903 * 904 */ AddressIterator(const Child & aChild,Index aIndex,Ip6::Address::TypeFilter aFilter=Ip6::Address::kTypeAny)905 AddressIterator(const Child &aChild, Index aIndex, Ip6::Address::TypeFilter aFilter = Ip6::Address::kTypeAny) 906 : mChild(aChild) 907 , mFilter(aFilter) 908 , mIndex(aIndex) 909 { 910 Update(); 911 } 912 913 /** 914 * This method converts the iterator into an index. 915 * 916 * @returns An index corresponding to the iterator. 917 * 918 */ GetAsIndex(void) const919 Index GetAsIndex(void) const { return mIndex; } 920 921 /** 922 * This method gets the iterator's associated `Child` entry. 923 * 924 * @returns The associated child entry. 925 * 926 */ GetChild(void) const927 const Child &GetChild(void) const { return mChild; } 928 929 /** 930 * This method gets the current `Child` IPv6 Address to which the iterator is pointing. 931 * 932 * @returns A pointer to the associated IPv6 Address, or `nullptr` if iterator is done. 933 * 934 */ 935 const Ip6::Address *GetAddress(void) const; 936 937 /** 938 * This method indicates whether the iterator has reached end of the list. 939 * 940 * @retval TRUE There are no more entries in the list (reached end of the list). 941 * @retval FALSE The current entry is valid. 942 * 943 */ IsDone(void) const944 bool IsDone(void) const { return (mIndex >= kMaxIndex); } 945 946 /** 947 * This method overloads `++` operator (pre-increment) to advance the iterator. 948 * 949 * The iterator is moved to point to the next `Address` entry. If there are no more `Ip6::Address` entries 950 * `IsDone()` returns `true`. 951 * 952 */ operator ++(void)953 void operator++(void) { mIndex++, Update(); } 954 955 /** 956 * This method overloads `++` operator (post-increment) to advance the iterator. 957 * 958 * The iterator is moved to point to the next `Address` entry. If there are no more `Ip6::Address` entries 959 * `IsDone()` returns `true`. 960 * 961 */ operator ++(int)962 void operator++(int) { mIndex++, Update(); } 963 964 /** 965 * This method overloads the `*` dereference operator and gets a reference to `Ip6::Address` to which the 966 * iterator is currently pointing. 967 * 968 * This method MUST be used when the iterator is not done (i.e., `IsDone()` returns `false`). 969 * 970 * @returns A reference to the `Ip6::Address` entry currently pointed by the iterator. 971 * 972 */ operator *(void) const973 const Ip6::Address &operator*(void)const { return *GetAddress(); } 974 975 /** 976 * This method overloads operator `==` to evaluate whether or not two `Iterator` instances are equal. 977 * 978 * This method MUST be used when the two iterators are associated with the same `Child` entry. 979 * 980 * @param[in] aOther The other `Iterator` to compare with. 981 * 982 * @retval TRUE If the two `Iterator` objects are equal. 983 * @retval FALSE If the two `Iterator` objects are not equal. 984 * 985 */ operator ==(const AddressIterator & aOther) const986 bool operator==(const AddressIterator &aOther) const { return (mIndex == aOther.mIndex); } 987 988 private: 989 enum IteratorType : uint8_t 990 { 991 kEndIterator, 992 }; 993 994 static constexpr uint16_t kMaxIndex = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD; 995 AddressIterator(const Child & aChild,IteratorType)996 AddressIterator(const Child &aChild, IteratorType) 997 : mChild(aChild) 998 , mIndex(kMaxIndex) 999 { 1000 } 1001 1002 void Update(void); 1003 1004 const Child & mChild; 1005 Ip6::Address::TypeFilter mFilter; 1006 Index mIndex; 1007 Ip6::Address mMeshLocalAddress; 1008 }; 1009 1010 /** 1011 * This method initializes the `Child` object. 1012 * 1013 * @param[in] aInstance A reference to OpenThread instance. 1014 * 1015 */ Init(Instance & aInstance)1016 void Init(Instance &aInstance) { Neighbor::Init(aInstance); } 1017 1018 /** 1019 * This method clears the child entry. 1020 * 1021 */ 1022 void Clear(void); 1023 1024 /** 1025 * This method clears the IPv6 address list for the child. 1026 * 1027 */ 1028 void ClearIp6Addresses(void); 1029 1030 /** 1031 * This method sets the device mode flags. 1032 * 1033 * @param[in] aMode The device mode flags. 1034 * 1035 */ 1036 void SetDeviceMode(Mle::DeviceMode aMode); 1037 1038 /** 1039 * This method gets the mesh-local IPv6 address. 1040 * 1041 * @param[out] aAddress A reference to an IPv6 address to provide address (if any). 1042 * 1043 * @retval kErrorNone Successfully found the mesh-local address and updated @p aAddress. 1044 * @retval kErrorNotFound No mesh-local IPv6 address in the IPv6 address list. 1045 * 1046 */ 1047 Error GetMeshLocalIp6Address(Ip6::Address &aAddress) const; 1048 1049 /** 1050 * This method returns the Mesh Local Interface Identifier. 1051 * 1052 * @returns The Mesh Local Interface Identifier. 1053 * 1054 */ GetMeshLocalIid(void) const1055 const Ip6::InterfaceIdentifier &GetMeshLocalIid(void) const { return mMeshLocalIid; } 1056 1057 /** 1058 * This method enables range-based `for` loop iteration over all (or a subset of) IPv6 addresses. 1059 * 1060 * This method should be used as follows: to iterate over all addresses 1061 * 1062 * for (const Ip6::Address &address : child.IterateIp6Addresses()) { ... } 1063 * 1064 * or to iterate over a subset of IPv6 addresses determined by a given address type filter 1065 * 1066 * for (const Ip6::Address &address : child.IterateIp6Addresses(Ip6::Address::kTypeMulticast)) { ... } 1067 * 1068 * @param[in] aFilter An IPv6 address type filter restricting iteration to certain type of addresses (default is 1069 * to accept any address type). 1070 * 1071 * @returns An IteratorBuilder instance. 1072 * 1073 */ IterateIp6Addresses(Ip6::Address::TypeFilter aFilter=Ip6::Address::kTypeAny) const1074 AddressIteratorBuilder IterateIp6Addresses(Ip6::Address::TypeFilter aFilter = Ip6::Address::kTypeAny) const 1075 { 1076 return AddressIteratorBuilder(*this, aFilter); 1077 } 1078 1079 /** 1080 * This method adds an IPv6 address to the list. 1081 * 1082 * @param[in] aAddress A reference to IPv6 address to be added. 1083 * 1084 * @retval kErrorNone Successfully added the new address. 1085 * @retval kErrorAlready Address is already in the list. 1086 * @retval kErrorNoBufs Already at maximum number of addresses. No entry available to add the new address. 1087 * @retval kErrorInvalidArgs Address is invalid (it is the Unspecified Address). 1088 * 1089 */ 1090 Error AddIp6Address(const Ip6::Address &aAddress); 1091 1092 /** 1093 * This method removes an IPv6 address from the list. 1094 * 1095 * @param[in] aAddress A reference to IPv6 address to be removed. 1096 * 1097 * @retval kErrorNone Successfully removed the address. 1098 * @retval kErrorNotFound Address was not found in the list. 1099 * @retval kErrorInvalidArgs Address is invalid (it is the Unspecified Address). 1100 * 1101 */ 1102 Error RemoveIp6Address(const Ip6::Address &aAddress); 1103 1104 /** 1105 * This method indicates whether an IPv6 address is in the list of IPv6 addresses of the child. 1106 * 1107 * @param[in] aAddress A reference to IPv6 address. 1108 * 1109 * @retval TRUE The address exists on the list. 1110 * @retval FALSE Address was not found in the list. 1111 * 1112 */ 1113 bool HasIp6Address(const Ip6::Address &aAddress) const; 1114 1115 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE 1116 /** 1117 * This method retrieves the Domain Unicast Address registered by the child. 1118 * 1119 * @returns A pointer to Domain Unicast Address registered by the child if there is. 1120 * 1121 */ 1122 const Ip6::Address *GetDomainUnicastAddress(void) const; 1123 #endif 1124 1125 /** 1126 * This method gets the child timeout. 1127 * 1128 * @returns The child timeout. 1129 * 1130 */ GetTimeout(void) const1131 uint32_t GetTimeout(void) const { return mTimeout; } 1132 1133 /** 1134 * This method sets the child timeout. 1135 * 1136 * @param[in] aTimeout The child timeout. 1137 * 1138 */ SetTimeout(uint32_t aTimeout)1139 void SetTimeout(uint32_t aTimeout) { mTimeout = aTimeout; } 1140 1141 /** 1142 * This method gets the network data version. 1143 * 1144 * @returns The network data version. 1145 * 1146 */ GetNetworkDataVersion(void) const1147 uint8_t GetNetworkDataVersion(void) const { return mNetworkDataVersion; } 1148 1149 /** 1150 * This method sets the network data version. 1151 * 1152 * @param[in] aVersion The network data version. 1153 * 1154 */ SetNetworkDataVersion(uint8_t aVersion)1155 void SetNetworkDataVersion(uint8_t aVersion) { mNetworkDataVersion = aVersion; } 1156 1157 /** 1158 * This method generates a new challenge value to use during a child attach. 1159 * 1160 */ 1161 void GenerateChallenge(void); 1162 1163 /** 1164 * This method gets the current challenge value used during attach. 1165 * 1166 * @returns The current challenge value. 1167 * 1168 */ GetChallenge(void) const1169 const uint8_t *GetChallenge(void) const { return mAttachChallenge; } 1170 1171 /** 1172 * This method gets the challenge size (bytes) used during attach. 1173 * 1174 * @returns The challenge size (bytes). 1175 * 1176 */ GetChallengeSize(void) const1177 uint8_t GetChallengeSize(void) const { return sizeof(mAttachChallenge); } 1178 1179 /** 1180 * This method clears the requested TLV list. 1181 * 1182 */ ClearRequestTlvs(void)1183 void ClearRequestTlvs(void) { memset(mRequestTlvs, Mle::Tlv::kInvalid, sizeof(mRequestTlvs)); } 1184 1185 /** 1186 * This method returns the requested TLV at index @p aIndex. 1187 * 1188 * @param[in] aIndex The index into the requested TLV list. 1189 * 1190 * @returns The requested TLV at index @p aIndex. 1191 * 1192 */ GetRequestTlv(uint8_t aIndex) const1193 uint8_t GetRequestTlv(uint8_t aIndex) const { return mRequestTlvs[aIndex]; } 1194 1195 /** 1196 * This method sets the requested TLV at index @p aIndex. 1197 * 1198 * @param[in] aIndex The index into the requested TLV list. 1199 * @param[in] aType The TLV type. 1200 * 1201 */ SetRequestTlv(uint8_t aIndex,uint8_t aType)1202 void SetRequestTlv(uint8_t aIndex, uint8_t aType) { mRequestTlvs[aIndex] = aType; } 1203 1204 #if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE 1205 1206 /** 1207 * This method increments the number of seconds since last supervision of the child. 1208 * 1209 */ IncrementSecondsSinceLastSupervision(void)1210 void IncrementSecondsSinceLastSupervision(void) { mSecondsSinceSupervision++; } 1211 1212 /** 1213 * This method returns the number of seconds since last supervision of the child (last message to the child) 1214 * 1215 * @returns Number of seconds since last supervision of the child. 1216 * 1217 */ GetSecondsSinceLastSupervision(void) const1218 uint16_t GetSecondsSinceLastSupervision(void) const { return mSecondsSinceSupervision; } 1219 1220 /** 1221 * This method resets the number of seconds since last supervision of the child to zero. 1222 * 1223 */ ResetSecondsSinceLastSupervision(void)1224 void ResetSecondsSinceLastSupervision(void) { mSecondsSinceSupervision = 0; } 1225 1226 #endif // #if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE 1227 1228 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE 1229 /** 1230 * This method returns MLR state of an IPv6 multicast address. 1231 * 1232 * @note The @p aAdddress reference MUST be from `IterateIp6Addresses()` or `AddressIterator`. 1233 * 1234 * @param[in] aAddress The IPv6 multicast address. 1235 * 1236 * @returns MLR state of the IPv6 multicast address. 1237 * 1238 */ 1239 MlrState GetAddressMlrState(const Ip6::Address &aAddress) const; 1240 1241 /** 1242 * This method sets MLR state of an IPv6 multicast address. 1243 * 1244 * @note The @p aAdddress reference MUST be from `IterateIp6Addresses()` or `AddressIterator`. 1245 * 1246 * @param[in] aAddress The IPv6 multicast address. 1247 * @param[in] aState The target MLR state. 1248 * 1249 */ 1250 void SetAddressMlrState(const Ip6::Address &aAddress, MlrState aState); 1251 1252 /** 1253 * This method returns if the Child has IPv6 address @p aAddress of MLR state `kMlrStateRegistered`. 1254 * 1255 * @param[in] aAddress The IPv6 address. 1256 * 1257 * @retval true If the Child has IPv6 address @p aAddress of MLR state `kMlrStateRegistered`. 1258 * @retval false If the Child does not have IPv6 address @p aAddress of MLR state `kMlrStateRegistered`. 1259 * 1260 */ 1261 bool HasMlrRegisteredAddress(const Ip6::Address &aAddress) const; 1262 1263 /** 1264 * This method returns if the Child has any IPv6 address of MLR state `kMlrStateRegistered`. 1265 * 1266 * @retval true If the Child has any IPv6 address of MLR state `kMlrStateRegistered`. 1267 * @retval false If the Child does not have any IPv6 address of MLR state `kMlrStateRegistered`. 1268 * 1269 */ HasAnyMlrRegisteredAddress(void) const1270 bool HasAnyMlrRegisteredAddress(void) const { return mMlrRegisteredMask.HasAny(); } 1271 1272 /** 1273 * This method returns if the Child has any IPv6 address of MLR state `kMlrStateToRegister`. 1274 * 1275 * @retval true If the Child has any IPv6 address of MLR state `kMlrStateToRegister`. 1276 * @retval false If the Child does not have any IPv6 address of MLR state `kMlrStateToRegister`. 1277 * 1278 */ HasAnyMlrToRegisterAddress(void) const1279 bool HasAnyMlrToRegisterAddress(void) const { return mMlrToRegisterMask.HasAny(); } 1280 #endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE 1281 1282 private: 1283 #if OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD < 2 1284 #error OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD should be at least set to 2. 1285 #endif 1286 1287 static constexpr uint16_t kNumIp6Addresses = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD - 1; 1288 1289 typedef BitVector<kNumIp6Addresses> ChildIp6AddressMask; 1290 1291 class AddressIteratorBuilder 1292 { 1293 public: AddressIteratorBuilder(const Child & aChild,Ip6::Address::TypeFilter aFilter)1294 AddressIteratorBuilder(const Child &aChild, Ip6::Address::TypeFilter aFilter) 1295 : mChild(aChild) 1296 , mFilter(aFilter) 1297 { 1298 } 1299 begin(void)1300 AddressIterator begin(void) { return AddressIterator(mChild, mFilter); } end(void)1301 AddressIterator end(void) { return AddressIterator(mChild, AddressIterator::kEndIterator); } 1302 1303 private: 1304 const Child & mChild; 1305 Ip6::Address::TypeFilter mFilter; 1306 }; 1307 1308 Ip6::InterfaceIdentifier mMeshLocalIid; ///< IPv6 address IID for mesh-local address 1309 Ip6::Address mIp6Address[kNumIp6Addresses]; ///< Registered IPv6 addresses 1310 uint32_t mTimeout; ///< Child timeout 1311 1312 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE 1313 ChildIp6AddressMask mMlrToRegisterMask; 1314 ChildIp6AddressMask mMlrRegisteredMask; 1315 #endif 1316 1317 uint8_t mNetworkDataVersion; ///< Current Network Data version 1318 1319 union 1320 { 1321 uint8_t mRequestTlvs[kMaxRequestTlvs]; ///< Requested MLE TLVs 1322 uint8_t mAttachChallenge[Mle::kMaxChallengeSize]; ///< The challenge value 1323 }; 1324 1325 #if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE 1326 uint16_t mSecondsSinceSupervision; ///< Number of seconds since last supervision of the child. 1327 #endif 1328 1329 static_assert(OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS < 8192, "mQueuedMessageCount cannot fit max required!"); 1330 }; 1331 1332 #endif // OPENTHREAD_FTD 1333 1334 /** 1335 * This class represents a Thread Router 1336 * 1337 */ 1338 class Router : public Neighbor 1339 { 1340 public: 1341 /** 1342 * This class represents diagnostic information for a Thread Router. 1343 * 1344 */ 1345 class Info : public otRouterInfo, public Clearable<Info> 1346 { 1347 public: 1348 /** 1349 * This method sets the `Info` instance from a given `Router`. 1350 * 1351 * @param[in] aRouter A router. 1352 * 1353 */ 1354 void SetFrom(const Router &aRouter); 1355 }; 1356 1357 /** 1358 * This method initializes the `Router` object. 1359 * 1360 * @param[in] aInstance A reference to OpenThread instance. 1361 * 1362 */ Init(Instance & aInstance)1363 void Init(Instance &aInstance) 1364 { 1365 Neighbor::Init(aInstance); 1366 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1367 SetCslClockAccuracy(kCslWorstCrystalPpm); 1368 SetCslUncertainty(kCslWorstUncertainty); 1369 #endif 1370 } 1371 1372 /** 1373 * This method clears the router entry. 1374 * 1375 */ 1376 void Clear(void); 1377 1378 /** 1379 * This method gets the router ID of the next hop to this router. 1380 * 1381 * @returns The router ID of the next hop to this router. 1382 * 1383 */ GetNextHop(void) const1384 uint8_t GetNextHop(void) const { return mNextHop; } 1385 1386 /** 1387 * This method sets the router ID of the next hop to this router. 1388 * 1389 * @param[in] aRouterId The router ID of the next hop to this router. 1390 * 1391 */ SetNextHop(uint8_t aRouterId)1392 void SetNextHop(uint8_t aRouterId) { mNextHop = aRouterId; } 1393 1394 /** 1395 * This method gets the link quality out value for this router. 1396 * 1397 * @returns The link quality out value for this router. 1398 * 1399 */ GetLinkQualityOut(void) const1400 LinkQuality GetLinkQualityOut(void) const { return static_cast<LinkQuality>(mLinkQualityOut); } 1401 1402 /** 1403 * This method sets the link quality out value for this router. 1404 * 1405 * @param[in] aLinkQuality The link quality out value for this router. 1406 * 1407 */ SetLinkQualityOut(LinkQuality aLinkQuality)1408 void SetLinkQualityOut(LinkQuality aLinkQuality) { mLinkQualityOut = aLinkQuality; } 1409 1410 /** 1411 * This method get the route cost to this router. 1412 * 1413 * @returns The route cost to this router. 1414 * 1415 */ GetCost(void) const1416 uint8_t GetCost(void) const { return mCost; } 1417 1418 /** 1419 * This method sets the router cost to this router. 1420 * 1421 * @param[in] aCost The router cost to this router. 1422 * 1423 */ SetCost(uint8_t aCost)1424 void SetCost(uint8_t aCost) { mCost = aCost; } 1425 1426 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1427 /** 1428 * This method get the CSL clock accuracy of this router. 1429 * 1430 * @returns The CSL clock accuracy of this router. 1431 * 1432 */ GetCslClockAccuracy(void) const1433 uint8_t GetCslClockAccuracy(void) const { return mCslClockAccuracy; } 1434 1435 /** 1436 * This method sets the CSL clock accuracy of this router. 1437 * 1438 * @param[in] aCslClockAccuracy The CSL clock accuracy of this router. 1439 * 1440 */ SetCslClockAccuracy(uint8_t aCslClockAccuracy)1441 void SetCslClockAccuracy(uint8_t aCslClockAccuracy) { mCslClockAccuracy = aCslClockAccuracy; } 1442 1443 /** 1444 * This method get the CSL clock uncertainty of this router. 1445 * 1446 * @returns The CSL clock uncertainty of this router. 1447 * 1448 */ GetCslUncertainty(void) const1449 uint8_t GetCslUncertainty(void) const { return mCslUncertainty; } 1450 1451 /** 1452 * This method sets the CSL clock uncertainty of this router. 1453 * 1454 * @param[in] aCslUncertainty The CSL clock uncertainty of this router. 1455 * 1456 */ SetCslUncertainty(uint8_t aCslUncertainty)1457 void SetCslUncertainty(uint8_t aCslUncertainty) { mCslUncertainty = aCslUncertainty; } 1458 #endif 1459 1460 private: 1461 uint8_t mNextHop; ///< The next hop towards this router 1462 uint8_t mLinkQualityOut : 2; ///< The link quality out for this router 1463 1464 #if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE 1465 uint8_t mCost; ///< The cost to this router via neighbor router 1466 #else 1467 uint8_t mCost : 4; ///< The cost to this router via neighbor router 1468 #endif 1469 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1470 uint8_t mCslClockAccuracy; ///< Crystal accuracy, in units of ± ppm. 1471 uint8_t mCslUncertainty; ///< Scheduling uncertainty, in units of 10 us. 1472 #endif 1473 }; 1474 1475 DefineCoreType(otNeighborInfo, Neighbor::Info); 1476 #if OPENTHREAD_FTD 1477 DefineCoreType(otChildInfo, Child::Info); 1478 #endif 1479 DefineCoreType(otRouterInfo, Router::Info); 1480 1481 } // namespace ot 1482 1483 #endif // TOPOLOGY_HPP_ 1484