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() : Mac::kShortAddrInvalid, 158 aMacAddress.IsExtended() ? &aMacAddress.GetExtended() : nullptr) 159 { 160 } 161 162 /** 163 * Initializes the `AddressMatcher` with a given state filter (it accepts any address). 164 * 165 * @param[in] aStateFilter A state filter. 166 * 167 */ AddressMatcher(StateFilter aStateFilter)168 explicit AddressMatcher(StateFilter aStateFilter) 169 : AddressMatcher(aStateFilter, Mac::kShortAddrInvalid, nullptr) 170 { 171 } 172 173 /** 174 * Indicates if a given neighbor matches the address and state filter of `AddressMatcher`. 175 * 176 * @param[in] aNeighbor A neighbor. 177 * 178 * @retval TRUE Neighbor @p aNeighbor matches the address and state filter. 179 * @retval FALSE Neighbor @p aNeighbor does not match the address or state filter. 180 * 181 */ 182 bool Matches(const Neighbor &aNeighbor) const; 183 184 private: AddressMatcher(StateFilter aStateFilter,Mac::ShortAddress aShortAddress,const Mac::ExtAddress * aExtAddress)185 AddressMatcher(StateFilter aStateFilter, Mac::ShortAddress aShortAddress, const Mac::ExtAddress *aExtAddress) 186 : mStateFilter(aStateFilter) 187 , mShortAddress(aShortAddress) 188 , mExtAddress(aExtAddress) 189 { 190 } 191 192 StateFilter mStateFilter; 193 Mac::ShortAddress mShortAddress; 194 const Mac::ExtAddress *mExtAddress; 195 }; 196 197 /** 198 * Represents diagnostic information for a neighboring node. 199 * 200 */ 201 class Info : public otNeighborInfo, public Clearable<Info> 202 { 203 public: 204 /** 205 * Sets the `Info` instance from a given `Neighbor`. 206 * 207 * @param[in] aNeighbor A neighbor. 208 * 209 */ 210 void SetFrom(const Neighbor &aNeighbor); 211 }; 212 213 /** 214 * Returns the current state. 215 * 216 * @returns The current state. 217 * 218 */ GetState(void) const219 State GetState(void) const { return static_cast<State>(mState); } 220 221 /** 222 * Sets the current state. 223 * 224 * @param[in] aState The state value. 225 * 226 */ 227 void SetState(State aState); 228 229 /** 230 * Indicates whether the neighbor is in the Invalid state. 231 * 232 * @returns TRUE if the neighbor is in the Invalid state, FALSE otherwise. 233 * 234 */ IsStateInvalid(void) const235 bool IsStateInvalid(void) const { return (mState == kStateInvalid); } 236 237 /** 238 * Indicates whether the neighbor is in the Child ID Request state. 239 * 240 * @returns TRUE if the neighbor is in the Child ID Request state, FALSE otherwise. 241 * 242 */ IsStateChildIdRequest(void) const243 bool IsStateChildIdRequest(void) const { return (mState == kStateChildIdRequest); } 244 245 /** 246 * Indicates whether the neighbor is in the Link Request state. 247 * 248 * @returns TRUE if the neighbor is in the Link Request state, FALSE otherwise. 249 * 250 */ IsStateLinkRequest(void) const251 bool IsStateLinkRequest(void) const { return (mState == kStateLinkRequest); } 252 253 /** 254 * Indicates whether the neighbor is in the Parent Response state. 255 * 256 * @returns TRUE if the neighbor is in the Parent Response state, FALSE otherwise. 257 * 258 */ IsStateParentResponse(void) const259 bool IsStateParentResponse(void) const { return (mState == kStateParentResponse); } 260 261 /** 262 * Indicates whether the neighbor is being restored. 263 * 264 * @returns TRUE if the neighbor is being restored, FALSE otherwise. 265 * 266 */ IsStateRestoring(void) const267 bool IsStateRestoring(void) const { return (mState == kStateRestored) || (mState == kStateChildUpdateRequest); } 268 269 /** 270 * Indicates whether the neighbor is in the Restored state. 271 * 272 * @returns TRUE if the neighbor is in the Restored state, FALSE otherwise. 273 * 274 */ IsStateRestored(void) const275 bool IsStateRestored(void) const { return (mState == kStateRestored); } 276 277 /** 278 * Indicates whether the neighbor is valid (frame counters are synchronized). 279 * 280 * @returns TRUE if the neighbor is valid, FALSE otherwise. 281 * 282 */ IsStateValid(void) const283 bool IsStateValid(void) const { return (mState == kStateValid); } 284 285 /** 286 * Indicates whether the neighbor is in valid state or if it is being restored. 287 * 288 * When in these states messages can be sent to and/or received from the neighbor. 289 * 290 * @returns TRUE if the neighbor is in valid, restored, or being restored states, FALSE otherwise. 291 * 292 */ IsStateValidOrRestoring(void) const293 bool IsStateValidOrRestoring(void) const { return (mState == kStateValid) || IsStateRestoring(); } 294 295 /** 296 * Indicates if the neighbor state is valid, attaching, or restored. 297 * 298 * The states `kStateRestored`, `kStateChildIdRequest`, `kStateChildUpdateRequest`, `kStateValid`, and 299 * `kStateLinkRequest` are considered as valid, attaching, or restored. 300 * 301 * @returns TRUE if the neighbor state is valid, attaching, or restored, FALSE otherwise. 302 * 303 */ 304 bool IsStateValidOrAttaching(void) const; 305 306 /** 307 * Indicates whether neighbor state matches a given state filter. 308 * 309 * @param[in] aFilter A state filter (`StateFilter` enumeration) to match against. 310 * 311 * @returns TRUE if the neighbor state matches the filter, FALSE otherwise. 312 * 313 */ 314 bool MatchesFilter(StateFilter aFilter) const; 315 316 /** 317 * Indicates whether neighbor matches a given `AddressMatcher`. 318 * 319 * @param[in] aMatcher An `AddressMatcher` to match against. 320 * 321 * @returns TRUE if the neighbor matches the address and state filter of @p aMatcher, FALSE otherwise. 322 * 323 */ Matches(const AddressMatcher & aMatcher) const324 bool Matches(const AddressMatcher &aMatcher) const { return aMatcher.Matches(*this); } 325 326 /** 327 * Gets the device mode flags. 328 * 329 * @returns The device mode flags. 330 * 331 */ GetDeviceMode(void) const332 Mle::DeviceMode GetDeviceMode(void) const { return Mle::DeviceMode(mMode); } 333 334 /** 335 * Sets the device mode flags. 336 * 337 * @param[in] aMode The device mode flags. 338 * 339 */ SetDeviceMode(Mle::DeviceMode aMode)340 void SetDeviceMode(Mle::DeviceMode aMode) { mMode = aMode.Get(); } 341 342 /** 343 * Indicates whether or not the device is rx-on-when-idle. 344 * 345 * @returns TRUE if rx-on-when-idle, FALSE otherwise. 346 * 347 */ IsRxOnWhenIdle(void) const348 bool IsRxOnWhenIdle(void) const { return GetDeviceMode().IsRxOnWhenIdle(); } 349 350 /** 351 * Indicates whether or not the device is a Full Thread Device. 352 * 353 * @returns TRUE if a Full Thread Device, FALSE otherwise. 354 * 355 */ IsFullThreadDevice(void) const356 bool IsFullThreadDevice(void) const { return GetDeviceMode().IsFullThreadDevice(); } 357 358 /** 359 * Gets the Network Data type (full set or stable subset) that the device requests. 360 * 361 * @returns The Network Data type. 362 * 363 */ GetNetworkDataType(void) const364 NetworkData::Type GetNetworkDataType(void) const { return GetDeviceMode().GetNetworkDataType(); } 365 366 /** 367 * Returns the Extended Address. 368 * 369 * @returns A const reference to the Extended Address. 370 * 371 */ GetExtAddress(void) const372 const Mac::ExtAddress &GetExtAddress(void) const { return mMacAddr; } 373 374 /** 375 * Returns the Extended Address. 376 * 377 * @returns A reference to the Extended Address. 378 * 379 */ GetExtAddress(void)380 Mac::ExtAddress &GetExtAddress(void) { return mMacAddr; } 381 382 /** 383 * Sets the Extended Address. 384 * 385 * @param[in] aAddress The Extended Address value to set. 386 * 387 */ SetExtAddress(const Mac::ExtAddress & aAddress)388 void SetExtAddress(const Mac::ExtAddress &aAddress) { mMacAddr = aAddress; } 389 390 /** 391 * Gets the key sequence value. 392 * 393 * @returns The key sequence value. 394 * 395 */ GetKeySequence(void) const396 uint32_t GetKeySequence(void) const { return mKeySequence; } 397 398 /** 399 * Sets the key sequence value. 400 * 401 * @param[in] aKeySequence The key sequence value. 402 * 403 */ SetKeySequence(uint32_t aKeySequence)404 void SetKeySequence(uint32_t aKeySequence) { mKeySequence = aKeySequence; } 405 406 /** 407 * Returns the last heard time. 408 * 409 * @returns The last heard time. 410 * 411 */ GetLastHeard(void) const412 TimeMilli GetLastHeard(void) const { return mLastHeard; } 413 414 /** 415 * Sets the last heard time. 416 * 417 * @param[in] aLastHeard The last heard time. 418 * 419 */ SetLastHeard(TimeMilli aLastHeard)420 void SetLastHeard(TimeMilli aLastHeard) { mLastHeard = aLastHeard; } 421 422 /** 423 * Gets the link frame counters. 424 * 425 * @returns A reference to `Mac::LinkFrameCounters` containing link frame counter for all supported radio links. 426 * 427 */ GetLinkFrameCounters(void)428 Mac::LinkFrameCounters &GetLinkFrameCounters(void) { return mValidPending.mValid.mLinkFrameCounters; } 429 430 /** 431 * Gets the link frame counters. 432 * 433 * @returns A reference to `Mac::LinkFrameCounters` containing link frame counter for all supported radio links. 434 * 435 */ GetLinkFrameCounters(void) const436 const Mac::LinkFrameCounters &GetLinkFrameCounters(void) const { return mValidPending.mValid.mLinkFrameCounters; } 437 438 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 439 /** 440 * Gets the link ACK frame counter value. 441 * 442 * @returns The link ACK frame counter value. 443 * 444 */ GetLinkAckFrameCounter(void) const445 uint32_t GetLinkAckFrameCounter(void) const { return mValidPending.mValid.mLinkAckFrameCounter; } 446 #endif 447 448 /** 449 * Sets the link ACK frame counter value. 450 * 451 * @param[in] aAckFrameCounter The link ACK frame counter value. 452 * 453 */ SetLinkAckFrameCounter(uint32_t aAckFrameCounter)454 void SetLinkAckFrameCounter(uint32_t aAckFrameCounter) 455 { 456 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 457 mValidPending.mValid.mLinkAckFrameCounter = aAckFrameCounter; 458 #else 459 OT_UNUSED_VARIABLE(aAckFrameCounter); 460 #endif 461 } 462 463 /** 464 * Gets the MLE frame counter value. 465 * 466 * @returns The MLE frame counter value. 467 * 468 */ GetMleFrameCounter(void) const469 uint32_t GetMleFrameCounter(void) const { return mValidPending.mValid.mMleFrameCounter; } 470 471 /** 472 * Sets the MLE frame counter value. 473 * 474 * @param[in] aFrameCounter The MLE frame counter value. 475 * 476 */ SetMleFrameCounter(uint32_t aFrameCounter)477 void SetMleFrameCounter(uint32_t aFrameCounter) { mValidPending.mValid.mMleFrameCounter = aFrameCounter; } 478 479 /** 480 * Gets the RLOC16 value. 481 * 482 * @returns The RLOC16 value. 483 * 484 */ GetRloc16(void) const485 uint16_t GetRloc16(void) const { return mRloc16; } 486 487 /** 488 * Gets the Router ID value. 489 * 490 * @returns The Router ID value. 491 * 492 */ GetRouterId(void) const493 uint8_t GetRouterId(void) const { return mRloc16 >> Mle::kRouterIdOffset; } 494 495 /** 496 * Sets the RLOC16 value. 497 * 498 * @param[in] aRloc16 The RLOC16 value. 499 * 500 */ SetRloc16(uint16_t aRloc16)501 void SetRloc16(uint16_t aRloc16) { mRloc16 = aRloc16; } 502 503 #if OPENTHREAD_CONFIG_MULTI_RADIO 504 /** 505 * Clears the last received fragment tag. 506 * 507 * The last received fragment tag is used for detect duplicate frames (received over different radios) when 508 * multi-radio feature is enabled. 509 * 510 */ ClearLastRxFragmentTag(void)511 void ClearLastRxFragmentTag(void) { mLastRxFragmentTag = 0; } 512 513 /** 514 * Gets the last received fragment tag. 515 * 516 * MUST be used only when the tag is set (and not cleared). Otherwise its behavior is undefined. 517 * 518 * @returns The last received fragment tag. 519 * 520 */ GetLastRxFragmentTag(void) const521 uint16_t GetLastRxFragmentTag(void) const { return mLastRxFragmentTag; } 522 523 /** 524 * Set the last received fragment tag. 525 * 526 * @param[in] aTag The new tag value. 527 * 528 */ 529 void SetLastRxFragmentTag(uint16_t aTag); 530 531 /** 532 * Indicates whether or not the last received fragment tag is set and valid (i.e., not yet timed out). 533 * 534 * @returns TRUE if the last received fragment tag is set and valid, FALSE otherwise. 535 * 536 */ 537 bool IsLastRxFragmentTagSet(void) const; 538 539 /** 540 * Indicates whether the last received fragment tag is strictly after a given tag value. 541 * 542 * MUST be used only when the tag is set (and not cleared). Otherwise its behavior is undefined. 543 * 544 * The tag value compassion follows the Serial Number Arithmetic logic from RFC-1982. It is semantically equivalent 545 * to `LastRxFragmentTag > aTag`. 546 * 547 * @param[in] aTag A tag value to compare against. 548 * 549 * @returns TRUE if the current last rx fragment tag is strictly after @p aTag, FALSE if they are equal or it is 550 * before @p aTag. 551 * 552 */ IsLastRxFragmentTagAfter(uint16_t aTag) const553 bool IsLastRxFragmentTagAfter(uint16_t aTag) const { return SerialNumber::IsGreater(mLastRxFragmentTag, aTag); } 554 555 #endif // OPENTHREAD_CONFIG_MULTI_RADIO 556 557 /** 558 * Indicates whether or not it is Thread 1.1. 559 * 560 * @returns TRUE if neighbors is Thread 1.1, FALSE otherwise. 561 * 562 */ IsThreadVersion1p1(void) const563 bool IsThreadVersion1p1(void) const { return mState != kStateInvalid && mVersion == kThreadVersion1p1; } 564 565 /** 566 * Indicates whether or not neighbor is Thread 1.2 or higher.. 567 * 568 * @returns TRUE if neighbor is Thread 1.2 or higher, FALSE otherwise. 569 * 570 */ IsThreadVersion1p2OrHigher(void) const571 bool IsThreadVersion1p2OrHigher(void) const { return mState != kStateInvalid && mVersion >= kThreadVersion1p2; } 572 573 /** 574 * Indicates whether Thread version supports CSL. 575 * 576 * @returns TRUE if CSL is supported, FALSE otherwise. 577 * 578 */ IsThreadVersionCslCapable(void) const579 bool IsThreadVersionCslCapable(void) const { return IsThreadVersion1p2OrHigher() && !IsRxOnWhenIdle(); } 580 581 /** 582 * Indicates whether Enhanced Keep-Alive is supported or not. 583 * 584 * @returns TRUE if Enhanced Keep-Alive is supported, FALSE otherwise. 585 * 586 */ IsEnhancedKeepAliveSupported(void) const587 bool IsEnhancedKeepAliveSupported(void) const 588 { 589 return (mState != kStateInvalid) && (mVersion >= kThreadVersion1p2); 590 } 591 592 /** 593 * Gets the device MLE version. 594 * 595 */ GetVersion(void) const596 uint16_t GetVersion(void) const { return mVersion; } 597 598 /** 599 * Sets the device MLE version. 600 * 601 * @param[in] aVersion The device MLE version. 602 * 603 */ SetVersion(uint16_t aVersion)604 void SetVersion(uint16_t aVersion) { mVersion = aVersion; } 605 606 /** 607 * Gets the number of consecutive link failures. 608 * 609 * @returns The number of consecutive link failures. 610 * 611 */ GetLinkFailures(void) const612 uint8_t GetLinkFailures(void) const { return mLinkFailures; } 613 614 /** 615 * Increments the number of consecutive link failures. 616 * 617 */ IncrementLinkFailures(void)618 void IncrementLinkFailures(void) { mLinkFailures++; } 619 620 /** 621 * Resets the number of consecutive link failures to zero. 622 * 623 */ ResetLinkFailures(void)624 void ResetLinkFailures(void) { mLinkFailures = 0; } 625 626 /** 627 * Returns the LinkQualityInfo object. 628 * 629 * @returns The LinkQualityInfo object. 630 * 631 */ GetLinkInfo(void)632 LinkQualityInfo &GetLinkInfo(void) { return mLinkInfo; } 633 634 /** 635 * Returns the LinkQualityInfo object. 636 * 637 * @returns The LinkQualityInfo object. 638 * 639 */ GetLinkInfo(void) const640 const LinkQualityInfo &GetLinkInfo(void) const { return mLinkInfo; } 641 642 /** 643 * Gets the link quality in value. 644 * 645 * @returns The link quality in value. 646 * 647 */ GetLinkQualityIn(void) const648 LinkQuality GetLinkQualityIn(void) const { return GetLinkInfo().GetLinkQuality(); } 649 650 /** 651 * Generates a new challenge value for MLE Link Request/Response exchanges. 652 * 653 */ GenerateChallenge(void)654 void GenerateChallenge(void) { mValidPending.mPending.mChallenge.GenerateRandom(); } 655 656 /** 657 * Returns the current challenge value for MLE Link Request/Response exchanges. 658 * 659 * @returns The current challenge value. 660 * 661 */ GetChallenge(void) const662 const Mle::TxChallenge &GetChallenge(void) const { return mValidPending.mPending.mChallenge; } 663 664 #if OPENTHREAD_CONFIG_UPTIME_ENABLE 665 /** 666 * Returns the connection time (in seconds) of the neighbor (seconds since entering `kStateValid`). 667 * 668 * @returns The connection time (in seconds), zero if device is not currently in `kStateValid`. 669 * 670 */ 671 uint32_t GetConnectionTime(void) const; 672 #endif 673 674 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 675 /** 676 * Indicates whether or not time sync feature is enabled. 677 * 678 * @returns TRUE if time sync feature is enabled, FALSE otherwise. 679 * 680 */ IsTimeSyncEnabled(void) const681 bool IsTimeSyncEnabled(void) const { return mTimeSyncEnabled; } 682 683 /** 684 * Sets whether or not time sync feature is enabled. 685 * 686 * @param[in] aEnable TRUE if time sync feature is enabled, FALSE otherwise. 687 * 688 */ SetTimeSyncEnabled(bool aEnabled)689 void SetTimeSyncEnabled(bool aEnabled) { mTimeSyncEnabled = aEnabled; } 690 #endif 691 692 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 693 /** 694 * Aggregates the Link Metrics data into all the series that is running for this neighbor. 695 * 696 * If a series wants to account frames of @p aFrameType, it would add count by 1 and aggregate @p aLqi and 697 * @p aRss into its averagers. 698 * 699 * @param[in] aSeriesId Series ID for Link Probe. Should be `0` if this method is not called by Link Probe. 700 * @param[in] aFrameType Type of the frame that carries Link Metrics data. 701 * @param[in] aLqi The LQI value. 702 * @param[in] aRss The Rss value. 703 * 704 */ 705 void AggregateLinkMetrics(uint8_t aSeriesId, uint8_t aFrameType, uint8_t aLqi, int8_t aRss); 706 707 /** 708 * Adds a new LinkMetrics::SeriesInfo to the neighbor's list. 709 * 710 * @param[in] aSeriesInfo A reference to the new SeriesInfo. 711 * 712 */ 713 void AddForwardTrackingSeriesInfo(LinkMetrics::SeriesInfo &aSeriesInfo); 714 715 /** 716 * Finds a specific LinkMetrics::SeriesInfo by Series ID. 717 * 718 * @param[in] aSeriesId A reference to the Series ID. 719 * 720 * @returns The pointer to the LinkMetrics::SeriesInfo. `nullptr` if not found. 721 * 722 */ 723 LinkMetrics::SeriesInfo *GetForwardTrackingSeriesInfo(const uint8_t &aSeriesId); 724 725 /** 726 * Removes a specific LinkMetrics::SeriesInfo by Series ID. 727 * 728 * @param[in] aSeriesId A reference to the Series ID to remove. 729 * 730 * @returns The pointer to the LinkMetrics::SeriesInfo. `nullptr` if not found. 731 * 732 */ 733 LinkMetrics::SeriesInfo *RemoveForwardTrackingSeriesInfo(const uint8_t &aSeriesId); 734 735 /** 736 * Removes all the Series and return the data structures to the Pool. 737 * 738 */ 739 void RemoveAllForwardTrackingSeriesInfo(void); 740 741 /** 742 * Gets the Enh-ACK Probing metrics (this `Neighbor` object is the Probing Subject). 743 * 744 * @returns Enh-ACK Probing metrics configured. 745 * 746 */ GetEnhAckProbingMetrics(void) const747 const LinkMetrics::Metrics &GetEnhAckProbingMetrics(void) const { return mEnhAckProbingMetrics; } 748 749 /** 750 * Sets the Enh-ACK Probing metrics (this `Neighbor` object is the Probing Subject). 751 * 752 * @param[in] aEnhAckProbingMetrics The metrics value to set. 753 * 754 */ SetEnhAckProbingMetrics(const LinkMetrics::Metrics & aEnhAckProbingMetrics)755 void SetEnhAckProbingMetrics(const LinkMetrics::Metrics &aEnhAckProbingMetrics) 756 { 757 mEnhAckProbingMetrics = aEnhAckProbingMetrics; 758 } 759 760 /** 761 * Indicates if Enh-ACK Probing is configured and active for this `Neighbor` object. 762 * 763 * @retval TRUE Enh-ACK Probing is configured and active for this `Neighbor`. 764 * @retval FALSE Otherwise. 765 * 766 */ IsEnhAckProbingActive(void) const767 bool IsEnhAckProbingActive(void) const 768 { 769 return (mEnhAckProbingMetrics.mLqi != 0) || (mEnhAckProbingMetrics.mLinkMargin != 0) || 770 (mEnhAckProbingMetrics.mRssi != 0); 771 } 772 #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 773 774 /** 775 * Converts a given `State` to a human-readable string. 776 * 777 * @param[in] aState A neighbor state. 778 * 779 * @returns A string representation of given state. 780 * 781 */ 782 static const char *StateToString(State aState); 783 784 protected: 785 /** 786 * Initializes the `Neighbor` object. 787 * 788 * @param[in] aInstance A reference to OpenThread instance. 789 * 790 */ 791 void Init(Instance &aInstance); 792 793 private: 794 enum : uint32_t 795 { 796 kLastRxFragmentTagTimeout = OPENTHREAD_CONFIG_MULTI_RADIO_FRAG_TAG_TIMEOUT, ///< Frag tag timeout in msec. 797 }; 798 799 Mac::ExtAddress mMacAddr; ///< The IEEE 802.15.4 Extended Address 800 TimeMilli mLastHeard; ///< Time when last heard. 801 union 802 { 803 struct 804 { 805 Mac::LinkFrameCounters mLinkFrameCounters; ///< The Link Frame Counters 806 uint32_t mMleFrameCounter; ///< The MLE Frame Counter 807 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 808 uint32_t mLinkAckFrameCounter; ///< The Link Ack Frame Counter 809 #endif 810 } mValid; 811 struct 812 { 813 Mle::TxChallenge mChallenge; ///< The challenge value 814 } mPending; 815 } mValidPending; 816 817 #if OPENTHREAD_CONFIG_MULTI_RADIO 818 uint16_t mLastRxFragmentTag; ///< Last received fragment tag 819 TimeMilli mLastRxFragmentTagTime; ///< The time last fragment tag was received and set. 820 #endif 821 822 uint32_t mKeySequence; ///< Current key sequence 823 uint16_t mRloc16; ///< The RLOC16 824 uint8_t mState : 4; ///< The link state 825 uint8_t mMode : 4; ///< The MLE device mode 826 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 827 uint8_t mLinkFailures : 7; ///< Consecutive link failure count 828 bool mTimeSyncEnabled : 1; ///< Indicates whether or not time sync feature is enabled. 829 #else 830 uint8_t mLinkFailures; ///< Consecutive link failure count 831 #endif 832 uint16_t mVersion; ///< The MLE version 833 LinkQualityInfo mLinkInfo; ///< Link quality info (contains average RSS, link margin and link quality) 834 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 835 // A list of Link Metrics Forward Tracking Series that is being 836 // tracked for this neighbor. Note that this device is the 837 // Subject and this neighbor is the Initiator. 838 LinkedList<LinkMetrics::SeriesInfo> mLinkMetricsSeriesInfoList; 839 840 // Metrics configured for Enh-ACK Based Probing at the Probing 841 // Subject (this neighbor). Note that this device is the Initiator 842 // and this neighbor is the Subject. 843 LinkMetrics::Metrics mEnhAckProbingMetrics; 844 #endif 845 #if OPENTHREAD_CONFIG_UPTIME_ENABLE 846 uint32_t mConnectionStart; 847 #endif 848 }; 849 850 DefineCoreType(otNeighborInfo, Neighbor::Info); 851 852 } // namespace ot 853 854 #endif // NEIGHBOR_HPP_ 855