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