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