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