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