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 a Thread `Neighbor`. 32 */ 33 34 #ifndef NEIGHBOR_HPP_ 35 #define NEIGHBOR_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_types.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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * Represents diagnostic information for a neighboring node. 200 * 201 */ 202 class Info : public otNeighborInfo, public Clearable<Info> 203 { 204 public: 205 /** 206 * 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 * 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 * Sets the current state. 224 * 225 * @param[in] aState The state value. 226 * 227 */ 228 void SetState(State aState); 229 230 /** 231 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * Gets the last received fragment tag. 516 * 517 * 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 * 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 * 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 * Indicates whether the last received fragment tag is strictly after a given tag value. 542 * 543 * 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 * 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 * 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 * 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 * 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 * Gets the device MLE version. 595 * 596 */ GetVersion(void) const597 uint16_t GetVersion(void) const { return mVersion; } 598 599 /** 600 * 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 * 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 * Increments the number of consecutive link failures. 617 * 618 */ IncrementLinkFailures(void)619 void IncrementLinkFailures(void) { mLinkFailures++; } 620 621 /** 622 * Resets the number of consecutive link failures to zero. 623 * 624 */ ResetLinkFailures(void)625 void ResetLinkFailures(void) { mLinkFailures = 0; } 626 627 /** 628 * Returns the LinkQualityInfo object. 629 * 630 * @returns The LinkQualityInfo object. 631 * 632 */ GetLinkInfo(void)633 LinkQualityInfo &GetLinkInfo(void) { return mLinkInfo; } 634 635 /** 636 * 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 * 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 * Generates a new challenge value for MLE Link Request/Response exchanges. 653 * 654 */ GenerateChallenge(void)655 void GenerateChallenge(void) { mValidPending.mPending.mChallenge.GenerateRandom(); } 656 657 /** 658 * Returns the current challenge value for MLE Link Request/Response exchanges. 659 * 660 * @returns The current challenge value. 661 * 662 */ GetChallenge(void) const663 const Mle::TxChallenge &GetChallenge(void) const { return mValidPending.mPending.mChallenge; } 664 665 #if OPENTHREAD_CONFIG_UPTIME_ENABLE 666 /** 667 * Returns the connection time (in seconds) of the neighbor (seconds since entering `kStateValid`). 668 * 669 * @returns The connection time (in seconds), zero if device is not currently in `kStateValid`. 670 * 671 */ 672 uint32_t GetConnectionTime(void) const; 673 #endif 674 675 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 676 /** 677 * Indicates whether or not time sync feature is enabled. 678 * 679 * @returns TRUE if time sync feature is enabled, FALSE otherwise. 680 * 681 */ IsTimeSyncEnabled(void) const682 bool IsTimeSyncEnabled(void) const { return mTimeSyncEnabled; } 683 684 /** 685 * Sets whether or not time sync feature is enabled. 686 * 687 * @param[in] aEnable TRUE if time sync feature is enabled, FALSE otherwise. 688 * 689 */ SetTimeSyncEnabled(bool aEnabled)690 void SetTimeSyncEnabled(bool aEnabled) { mTimeSyncEnabled = aEnabled; } 691 #endif 692 693 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 694 /** 695 * Aggregates the Link Metrics data into all the series that is running for this neighbor. 696 * 697 * If a series wants to account frames of @p aFrameType, it would add count by 1 and aggregate @p aLqi and 698 * @p aRss into its averagers. 699 * 700 * @param[in] aSeriesId Series ID for Link Probe. Should be `0` if this method is not called by Link Probe. 701 * @param[in] aFrameType Type of the frame that carries Link Metrics data. 702 * @param[in] aLqi The LQI value. 703 * @param[in] aRss The Rss value. 704 * 705 */ 706 void AggregateLinkMetrics(uint8_t aSeriesId, uint8_t aFrameType, uint8_t aLqi, int8_t aRss); 707 708 /** 709 * Adds a new LinkMetrics::SeriesInfo to the neighbor's list. 710 * 711 * @param[in] aSeriesInfo A reference to the new SeriesInfo. 712 * 713 */ 714 void AddForwardTrackingSeriesInfo(LinkMetrics::SeriesInfo &aSeriesInfo); 715 716 /** 717 * Finds a specific LinkMetrics::SeriesInfo by Series ID. 718 * 719 * @param[in] aSeriesId A reference to the Series ID. 720 * 721 * @returns The pointer to the LinkMetrics::SeriesInfo. `nullptr` if not found. 722 * 723 */ 724 LinkMetrics::SeriesInfo *GetForwardTrackingSeriesInfo(const uint8_t &aSeriesId); 725 726 /** 727 * Removes a specific LinkMetrics::SeriesInfo by Series ID. 728 * 729 * @param[in] aSeriesId A reference to the Series ID to remove. 730 * 731 * @returns The pointer to the LinkMetrics::SeriesInfo. `nullptr` if not found. 732 * 733 */ 734 LinkMetrics::SeriesInfo *RemoveForwardTrackingSeriesInfo(const uint8_t &aSeriesId); 735 736 /** 737 * Removes all the Series and return the data structures to the Pool. 738 * 739 */ 740 void RemoveAllForwardTrackingSeriesInfo(void); 741 742 /** 743 * Gets the Enh-ACK Probing metrics (this `Neighbor` object is the Probing Subject). 744 * 745 * @returns Enh-ACK Probing metrics configured. 746 * 747 */ GetEnhAckProbingMetrics(void) const748 const LinkMetrics::Metrics &GetEnhAckProbingMetrics(void) const { return mEnhAckProbingMetrics; } 749 750 /** 751 * Sets the Enh-ACK Probing metrics (this `Neighbor` object is the Probing Subject). 752 * 753 * @param[in] aEnhAckProbingMetrics The metrics value to set. 754 * 755 */ SetEnhAckProbingMetrics(const LinkMetrics::Metrics & aEnhAckProbingMetrics)756 void SetEnhAckProbingMetrics(const LinkMetrics::Metrics &aEnhAckProbingMetrics) 757 { 758 mEnhAckProbingMetrics = aEnhAckProbingMetrics; 759 } 760 761 /** 762 * Indicates if Enh-ACK Probing is configured and active for this `Neighbor` object. 763 * 764 * @retval TRUE Enh-ACK Probing is configured and active for this `Neighbor`. 765 * @retval FALSE Otherwise. 766 * 767 */ IsEnhAckProbingActive(void) const768 bool IsEnhAckProbingActive(void) const 769 { 770 return (mEnhAckProbingMetrics.mLqi != 0) || (mEnhAckProbingMetrics.mLinkMargin != 0) || 771 (mEnhAckProbingMetrics.mRssi != 0); 772 } 773 #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 774 775 /** 776 * Converts a given `State` to a human-readable string. 777 * 778 * @param[in] aState A neighbor state. 779 * 780 * @returns A string representation of given state. 781 * 782 */ 783 static const char *StateToString(State aState); 784 785 protected: 786 /** 787 * Initializes the `Neighbor` object. 788 * 789 * @param[in] aInstance A reference to OpenThread instance. 790 * 791 */ 792 void Init(Instance &aInstance); 793 794 private: 795 enum : uint32_t 796 { 797 kLastRxFragmentTagTimeout = OPENTHREAD_CONFIG_MULTI_RADIO_FRAG_TAG_TIMEOUT, ///< Frag tag timeout in msec. 798 }; 799 800 Mac::ExtAddress mMacAddr; ///< The IEEE 802.15.4 Extended Address 801 TimeMilli mLastHeard; ///< Time when last heard. 802 union 803 { 804 struct 805 { 806 Mac::LinkFrameCounters mLinkFrameCounters; ///< The Link Frame Counters 807 uint32_t mMleFrameCounter; ///< The MLE Frame Counter 808 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 809 uint32_t mLinkAckFrameCounter; ///< The Link Ack Frame Counter 810 #endif 811 } mValid; 812 struct 813 { 814 Mle::TxChallenge mChallenge; ///< The challenge value 815 } mPending; 816 } mValidPending; 817 818 #if OPENTHREAD_CONFIG_MULTI_RADIO 819 uint16_t mLastRxFragmentTag; ///< Last received fragment tag 820 TimeMilli mLastRxFragmentTagTime; ///< The time last fragment tag was received and set. 821 #endif 822 823 uint32_t mKeySequence; ///< Current key sequence 824 uint16_t mRloc16; ///< The RLOC16 825 uint8_t mState : 4; ///< The link state 826 uint8_t mMode : 4; ///< The MLE device mode 827 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 828 uint8_t mLinkFailures : 7; ///< Consecutive link failure count 829 bool mTimeSyncEnabled : 1; ///< Indicates whether or not time sync feature is enabled. 830 #else 831 uint8_t mLinkFailures; ///< Consecutive link failure count 832 #endif 833 uint16_t mVersion; ///< The MLE version 834 LinkQualityInfo mLinkInfo; ///< Link quality info (contains average RSS, link margin and link quality) 835 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 836 // A list of Link Metrics Forward Tracking Series that is being 837 // tracked for this neighbor. Note that this device is the 838 // Subject and this neighbor is the Initiator. 839 LinkedList<LinkMetrics::SeriesInfo> mLinkMetricsSeriesInfoList; 840 841 // Metrics configured for Enh-ACK Based Probing at the Probing 842 // Subject (this neighbor). Note that this device is the Initiator 843 // and this neighbor is the Subject. 844 LinkMetrics::Metrics mEnhAckProbingMetrics; 845 #endif 846 #if OPENTHREAD_CONFIG_UPTIME_ENABLE 847 uint32_t mConnectionStart; 848 #endif 849 }; 850 851 DefineCoreType(otNeighborInfo, Neighbor::Info); 852 853 } // namespace ot 854 855 #endif // NEIGHBOR_HPP_ 856