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 class Neighbor : public InstanceLocatorInit
71 #if OPENTHREAD_CONFIG_MULTI_RADIO
72     ,
73                  public RadioSelector::NeighborInfo
74 #endif
75 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
76     ,
77                  public Trel::NeighborInfo
78 #endif
79 {
80 public:
81     /**
82      * Neighbor link states.
83      */
84     enum State : uint8_t
85     {
86         kStateInvalid,            ///< Neighbor link is invalid
87         kStateRestored,           ///< Neighbor is restored from non-volatile memory
88         kStateParentRequest,      ///< Received an MLE Parent Request message
89         kStateParentResponse,     ///< Received an MLE Parent Response message
90         kStateChildIdRequest,     ///< Received an MLE Child ID Request message
91         kStateLinkRequest,        ///< Sent an MLE Link Request message
92         kStateChildUpdateRequest, ///< Sent an MLE Child Update Request message (trying to restore the child)
93         kStateValid,              ///< Link is valid
94     };
95 
96     /**
97      * Defines state filters used for finding a neighbor or iterating through the child/neighbor table.
98      *
99      * Each filter definition accepts a subset of `State` values.
100      */
101     enum StateFilter : uint8_t
102     {
103         kInStateValid,                     ///< Accept neighbor only in `kStateValid`.
104         kInStateValidOrRestoring,          ///< Accept neighbor with `IsStateValidOrRestoring()` being `true`.
105         kInStateChildIdRequest,            ///< Accept neighbor only in `Child:kStateChildIdRequest`.
106         kInStateValidOrAttaching,          ///< Accept neighbor with `IsStateValidOrAttaching()` being `true`.
107         kInStateInvalid,                   ///< Accept neighbor only in `kStateInvalid`.
108         kInStateAnyExceptInvalid,          ///< Accept neighbor in any state except `kStateInvalid`.
109         kInStateAnyExceptValidOrRestoring, ///< Accept neighbor in any state except `IsStateValidOrRestoring()`.
110         kInStateAny,                       ///< Accept neighbor in any state.
111     };
112 
113     /**
114      * Represents an Address Matcher used to find a neighbor (child/router) with a given MAC address also
115      * matching a given state filter.
116      */
117     class AddressMatcher
118     {
119     public:
120         /**
121          * Initializes the `AddressMatcher` with a given MAC short address (RCOC16) and state filter.
122          *
123          * @param[in]  aShortAddress   A MAC short address (RLOC16).
124          * @param[in]  aStateFilter    A state filter.
125          */
AddressMatcher(Mac::ShortAddress aShortAddress,StateFilter aStateFilter)126         AddressMatcher(Mac::ShortAddress aShortAddress, StateFilter aStateFilter)
127             : AddressMatcher(aStateFilter, aShortAddress, nullptr)
128         {
129         }
130 
131         /**
132          * Initializes the `AddressMatcher` with a given MAC extended address and state filter.
133          *
134          * @param[in]  aExtAddress     A MAC extended address.
135          * @param[in]  aStateFilter    A state filter.
136          */
AddressMatcher(const Mac::ExtAddress & aExtAddress,StateFilter aStateFilter)137         AddressMatcher(const Mac::ExtAddress &aExtAddress, StateFilter aStateFilter)
138             : AddressMatcher(aStateFilter, Mac::kShortAddrInvalid, &aExtAddress)
139         {
140         }
141 
142         /**
143          * Initializes the `AddressMatcher` with a given MAC address and state filter.
144          *
145          * @param[in]  aMacAddress     A MAC address.
146          * @param[in]  aStateFilter    A state filter.
147          */
AddressMatcher(const Mac::Address & aMacAddress,StateFilter aStateFilter)148         AddressMatcher(const Mac::Address &aMacAddress, StateFilter aStateFilter)
149             : AddressMatcher(aStateFilter,
150                              aMacAddress.IsShort() ? aMacAddress.GetShort() : Mac::kShortAddrInvalid,
151                              aMacAddress.IsExtended() ? &aMacAddress.GetExtended() : nullptr)
152         {
153         }
154 
155         /**
156          * Initializes the `AddressMatcher` with a given state filter (it accepts any address).
157          *
158          * @param[in]  aStateFilter    A state filter.
159          */
AddressMatcher(StateFilter aStateFilter)160         explicit AddressMatcher(StateFilter aStateFilter)
161             : AddressMatcher(aStateFilter, Mac::kShortAddrInvalid, nullptr)
162         {
163         }
164 
165         /**
166          * Indicates if a given neighbor matches the address and state filter of `AddressMatcher`.
167          *
168          * @param[in] aNeighbor   A neighbor.
169          *
170          * @retval TRUE   Neighbor @p aNeighbor matches the address and state filter.
171          * @retval FALSE  Neighbor @p aNeighbor does not match the address or state filter.
172          */
173         bool Matches(const Neighbor &aNeighbor) const;
174 
175     private:
AddressMatcher(StateFilter aStateFilter,Mac::ShortAddress aShortAddress,const Mac::ExtAddress * aExtAddress)176         AddressMatcher(StateFilter aStateFilter, Mac::ShortAddress aShortAddress, const Mac::ExtAddress *aExtAddress)
177             : mStateFilter(aStateFilter)
178             , mShortAddress(aShortAddress)
179             , mExtAddress(aExtAddress)
180         {
181         }
182 
183         StateFilter            mStateFilter;
184         Mac::ShortAddress      mShortAddress;
185         const Mac::ExtAddress *mExtAddress;
186     };
187 
188     /**
189      * Represents diagnostic information for a neighboring node.
190      */
191     class Info : public otNeighborInfo, public Clearable<Info>
192     {
193     public:
194         /**
195          * Sets the `Info` instance from a given `Neighbor`.
196          *
197          * @param[in] aNeighbor   A neighbor.
198          */
199         void SetFrom(const Neighbor &aNeighbor);
200     };
201 
202     /**
203      * Returns the current state.
204      *
205      * @returns The current state.
206      */
GetState(void) const207     State GetState(void) const { return static_cast<State>(mState); }
208 
209     /**
210      * Sets the current state.
211      *
212      * @param[in]  aState  The state value.
213      */
214     void SetState(State aState);
215 
216     /**
217      * Indicates whether the neighbor is in the Invalid state.
218      *
219      * @returns TRUE if the neighbor is in the Invalid state, FALSE otherwise.
220      */
IsStateInvalid(void) const221     bool IsStateInvalid(void) const { return (mState == kStateInvalid); }
222 
223     /**
224      * Indicates whether the neighbor is in the Child ID Request state.
225      *
226      * @returns TRUE if the neighbor is in the Child ID Request state, FALSE otherwise.
227      */
IsStateChildIdRequest(void) const228     bool IsStateChildIdRequest(void) const { return (mState == kStateChildIdRequest); }
229 
230     /**
231      * Indicates whether the neighbor is in the Link Request state.
232      *
233      * @returns TRUE if the neighbor is in the Link Request state, FALSE otherwise.
234      */
IsStateLinkRequest(void) const235     bool IsStateLinkRequest(void) const { return (mState == kStateLinkRequest); }
236 
237     /**
238      * Indicates whether the neighbor is in the Parent Response state.
239      *
240      * @returns TRUE if the neighbor is in the Parent Response state, FALSE otherwise.
241      */
IsStateParentResponse(void) const242     bool IsStateParentResponse(void) const { return (mState == kStateParentResponse); }
243 
244     /**
245      * Indicates whether the neighbor is being restored.
246      *
247      * @returns TRUE if the neighbor is being restored, FALSE otherwise.
248      */
IsStateRestoring(void) const249     bool IsStateRestoring(void) const { return (mState == kStateRestored) || (mState == kStateChildUpdateRequest); }
250 
251     /**
252      * Indicates whether the neighbor is in the Restored state.
253      *
254      * @returns TRUE if the neighbor is in the Restored state, FALSE otherwise.
255      */
IsStateRestored(void) const256     bool IsStateRestored(void) const { return (mState == kStateRestored); }
257 
258     /**
259      * Indicates whether the neighbor is valid (frame counters are synchronized).
260      *
261      * @returns TRUE if the neighbor is valid, FALSE otherwise.
262      */
IsStateValid(void) const263     bool IsStateValid(void) const { return (mState == kStateValid); }
264 
265     /**
266      * Indicates whether the neighbor is in valid state or if it is being restored.
267      *
268      * When in these states messages can be sent to and/or received from the neighbor.
269      *
270      * @returns TRUE if the neighbor is in valid, restored, or being restored states, FALSE otherwise.
271      */
IsStateValidOrRestoring(void) const272     bool IsStateValidOrRestoring(void) const { return (mState == kStateValid) || IsStateRestoring(); }
273 
274     /**
275      * Indicates if the neighbor state is valid, attaching, or restored.
276      *
277      * The states `kStateRestored`, `kStateChildIdRequest`, `kStateChildUpdateRequest`, `kStateValid`, and
278      * `kStateLinkRequest` are considered as valid, attaching, or restored.
279      *
280      * @returns TRUE if the neighbor state is valid, attaching, or restored, FALSE otherwise.
281      */
282     bool IsStateValidOrAttaching(void) const;
283 
284     /**
285      * Indicates whether neighbor state matches a given state filter.
286      *
287      * @param[in] aFilter   A state filter (`StateFilter` enumeration) to match against.
288      *
289      * @returns TRUE if the neighbor state matches the filter, FALSE otherwise.
290      */
291     bool MatchesFilter(StateFilter aFilter) const;
292 
293     /**
294      * Indicates whether neighbor matches a given `AddressMatcher`.
295      *
296      * @param[in]  aMatcher   An `AddressMatcher` to match against.
297      *
298      * @returns TRUE if the neighbor matches the address and state filter of @p aMatcher, FALSE otherwise.
299      */
Matches(const AddressMatcher & aMatcher) const300     bool Matches(const AddressMatcher &aMatcher) const { return aMatcher.Matches(*this); }
301 
302     /**
303      * Gets the device mode flags.
304      *
305      * @returns The device mode flags.
306      */
GetDeviceMode(void) const307     Mle::DeviceMode GetDeviceMode(void) const { return Mle::DeviceMode(mMode); }
308 
309     /**
310      * Sets the device mode flags.
311      *
312      * @param[in]  aMode  The device mode flags.
313      */
SetDeviceMode(Mle::DeviceMode aMode)314     void SetDeviceMode(Mle::DeviceMode aMode) { mMode = aMode.Get(); }
315 
316     /**
317      * Indicates whether or not the device is rx-on-when-idle.
318      *
319      * @returns TRUE if rx-on-when-idle, FALSE otherwise.
320      */
IsRxOnWhenIdle(void) const321     bool IsRxOnWhenIdle(void) const { return GetDeviceMode().IsRxOnWhenIdle(); }
322 
323     /**
324      * Indicates whether or not the device is a Full Thread Device.
325      *
326      * @returns TRUE if a Full Thread Device, FALSE otherwise.
327      */
IsFullThreadDevice(void) const328     bool IsFullThreadDevice(void) const { return GetDeviceMode().IsFullThreadDevice(); }
329 
330     /**
331      * Gets the Network Data type (full set or stable subset) that the device requests.
332      *
333      * @returns The Network Data type.
334      */
GetNetworkDataType(void) const335     NetworkData::Type GetNetworkDataType(void) const { return GetDeviceMode().GetNetworkDataType(); }
336 
337     /**
338      * Returns the Extended Address.
339      *
340      * @returns A const reference to the Extended Address.
341      */
GetExtAddress(void) const342     const Mac::ExtAddress &GetExtAddress(void) const { return mMacAddr; }
343 
344     /**
345      * Returns the Extended Address.
346      *
347      * @returns A reference to the Extended Address.
348      */
GetExtAddress(void)349     Mac::ExtAddress &GetExtAddress(void) { return mMacAddr; }
350 
351     /**
352      * Sets the Extended Address.
353      *
354      * @param[in]  aAddress  The Extended Address value to set.
355      */
SetExtAddress(const Mac::ExtAddress & aAddress)356     void SetExtAddress(const Mac::ExtAddress &aAddress) { mMacAddr = aAddress; }
357 
358     /**
359      * Gets the key sequence value.
360      *
361      * @returns The key sequence value.
362      */
GetKeySequence(void) const363     uint32_t GetKeySequence(void) const { return mKeySequence; }
364 
365     /**
366      * Sets the key sequence value.
367      *
368      * @param[in]  aKeySequence  The key sequence value.
369      */
SetKeySequence(uint32_t aKeySequence)370     void SetKeySequence(uint32_t aKeySequence) { mKeySequence = aKeySequence; }
371 
372     /**
373      * Returns the last heard time.
374      *
375      * @returns The last heard time.
376      */
GetLastHeard(void) const377     TimeMilli GetLastHeard(void) const { return mLastHeard; }
378 
379     /**
380      * Sets the last heard time.
381      *
382      * @param[in]  aLastHeard  The last heard time.
383      */
SetLastHeard(TimeMilli aLastHeard)384     void SetLastHeard(TimeMilli aLastHeard) { mLastHeard = aLastHeard; }
385 
386     /**
387      * Gets the link frame counters.
388      *
389      * @returns A reference to `Mac::LinkFrameCounters` containing link frame counter for all supported radio links.
390      */
GetLinkFrameCounters(void)391     Mac::LinkFrameCounters &GetLinkFrameCounters(void) { return mValidPending.mValid.mLinkFrameCounters; }
392 
393     /**
394      * Gets the link frame counters.
395      *
396      * @returns A reference to `Mac::LinkFrameCounters` containing link frame counter for all supported radio links.
397      */
GetLinkFrameCounters(void) const398     const Mac::LinkFrameCounters &GetLinkFrameCounters(void) const { return mValidPending.mValid.mLinkFrameCounters; }
399 
400 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
401     /**
402      * Gets the link ACK frame counter value.
403      *
404      * @returns The link ACK frame counter value.
405      */
GetLinkAckFrameCounter(void) const406     uint32_t GetLinkAckFrameCounter(void) const { return mValidPending.mValid.mLinkAckFrameCounter; }
407 #endif
408 
409     /**
410      * Sets the link ACK frame counter value.
411      *
412      * @param[in]  aAckFrameCounter  The link ACK frame counter value.
413      */
SetLinkAckFrameCounter(uint32_t aAckFrameCounter)414     void SetLinkAckFrameCounter(uint32_t aAckFrameCounter)
415     {
416 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
417         mValidPending.mValid.mLinkAckFrameCounter = aAckFrameCounter;
418 #else
419         OT_UNUSED_VARIABLE(aAckFrameCounter);
420 #endif
421     }
422 
423     /**
424      * Gets the MLE frame counter value.
425      *
426      * @returns The MLE frame counter value.
427      */
GetMleFrameCounter(void) const428     uint32_t GetMleFrameCounter(void) const { return mValidPending.mValid.mMleFrameCounter; }
429 
430     /**
431      * Sets the MLE frame counter value.
432      *
433      * @param[in]  aFrameCounter  The MLE frame counter value.
434      */
SetMleFrameCounter(uint32_t aFrameCounter)435     void SetMleFrameCounter(uint32_t aFrameCounter) { mValidPending.mValid.mMleFrameCounter = aFrameCounter; }
436 
437     /**
438      * Gets the RLOC16 value.
439      *
440      * @returns The RLOC16 value.
441      */
GetRloc16(void) const442     uint16_t GetRloc16(void) const { return mRloc16; }
443 
444     /**
445      * Gets the Router ID value.
446      *
447      * @returns The Router ID value.
448      */
GetRouterId(void) const449     uint8_t GetRouterId(void) const { return mRloc16 >> Mle::kRouterIdOffset; }
450 
451     /**
452      * Sets the RLOC16 value.
453      *
454      * @param[in]  aRloc16  The RLOC16 value.
455      */
SetRloc16(uint16_t aRloc16)456     void SetRloc16(uint16_t aRloc16) { mRloc16 = aRloc16; }
457 
458 #if OPENTHREAD_CONFIG_MULTI_RADIO
459     /**
460      * Clears the last received fragment tag.
461      *
462      * The last received fragment tag is used for detect duplicate frames (received over different radios) when
463      * multi-radio feature is enabled.
464      */
ClearLastRxFragmentTag(void)465     void ClearLastRxFragmentTag(void) { mLastRxFragmentTag = 0; }
466 
467     /**
468      * Gets the last received fragment tag.
469      *
470      * MUST be used only when the tag is set (and not cleared). Otherwise its behavior is undefined.
471      *
472      * @returns The last received fragment tag.
473      */
GetLastRxFragmentTag(void) const474     uint16_t GetLastRxFragmentTag(void) const { return mLastRxFragmentTag; }
475 
476     /**
477      * Set the last received fragment tag.
478      *
479      * @param[in] aTag   The new tag value.
480      */
481     void SetLastRxFragmentTag(uint16_t aTag);
482 
483     /**
484      * Indicates whether or not the last received fragment tag is set and valid (i.e., not yet timed out).
485      *
486      * @returns TRUE if the last received fragment tag is set and valid, FALSE otherwise.
487      */
488     bool IsLastRxFragmentTagSet(void) const;
489 
490     /**
491      * Indicates whether the last received fragment tag is strictly after a given tag value.
492      *
493      * MUST be used only when the tag is set (and not cleared). Otherwise its behavior is undefined.
494      *
495      * The tag value compassion follows the Serial Number Arithmetic logic from RFC-1982. It is semantically equivalent
496      * to `LastRxFragmentTag > aTag`.
497      *
498      * @param[in] aTag   A tag value to compare against.
499      *
500      * @returns TRUE if the current last rx fragment tag is strictly after @p aTag, FALSE if they are equal or it is
501      * before @p aTag.
502      */
IsLastRxFragmentTagAfter(uint16_t aTag) const503     bool IsLastRxFragmentTagAfter(uint16_t aTag) const { return SerialNumber::IsGreater(mLastRxFragmentTag, aTag); }
504 
505 #endif // OPENTHREAD_CONFIG_MULTI_RADIO
506 
507     /**
508      * Indicates whether or not it is Thread 1.1.
509      *
510      * @returns TRUE if neighbors is Thread 1.1, FALSE otherwise.
511      */
IsThreadVersion1p1(void) const512     bool IsThreadVersion1p1(void) const { return mState != kStateInvalid && mVersion == kThreadVersion1p1; }
513 
514     /**
515      * Indicates whether or not neighbor is Thread 1.2 or higher..
516      *
517      * @returns TRUE if neighbor is Thread 1.2 or higher, FALSE otherwise.
518      */
IsThreadVersion1p2OrHigher(void) const519     bool IsThreadVersion1p2OrHigher(void) const { return mState != kStateInvalid && mVersion >= kThreadVersion1p2; }
520 
521     /**
522      * Indicates whether Thread version supports CSL.
523      *
524      * @returns TRUE if CSL is supported, FALSE otherwise.
525      */
IsThreadVersionCslCapable(void) const526     bool IsThreadVersionCslCapable(void) const { return IsThreadVersion1p2OrHigher() && !IsRxOnWhenIdle(); }
527 
528     /**
529      * Indicates whether Enhanced Keep-Alive is supported or not.
530      *
531      * @returns TRUE if Enhanced Keep-Alive is supported, FALSE otherwise.
532      */
IsEnhancedKeepAliveSupported(void) const533     bool IsEnhancedKeepAliveSupported(void) const
534     {
535         return (mState != kStateInvalid) && (mVersion >= kThreadVersion1p2);
536     }
537 
538     /**
539      * Gets the device MLE version.
540      */
GetVersion(void) const541     uint16_t GetVersion(void) const { return mVersion; }
542 
543     /**
544      * Sets the device MLE version.
545      *
546      * @param[in]  aVersion  The device MLE version.
547      */
SetVersion(uint16_t aVersion)548     void SetVersion(uint16_t aVersion) { mVersion = aVersion; }
549 
550     /**
551      * Gets the number of consecutive link failures.
552      *
553      * @returns The number of consecutive link failures.
554      */
GetLinkFailures(void) const555     uint8_t GetLinkFailures(void) const { return mLinkFailures; }
556 
557     /**
558      * Increments the number of consecutive link failures.
559      */
IncrementLinkFailures(void)560     void IncrementLinkFailures(void) { mLinkFailures++; }
561 
562     /**
563      * Resets the number of consecutive link failures to zero.
564      */
ResetLinkFailures(void)565     void ResetLinkFailures(void) { mLinkFailures = 0; }
566 
567     /**
568      * Returns the LinkQualityInfo object.
569      *
570      * @returns The LinkQualityInfo object.
571      */
GetLinkInfo(void)572     LinkQualityInfo &GetLinkInfo(void) { return mLinkInfo; }
573 
574     /**
575      * Returns the LinkQualityInfo object.
576      *
577      * @returns The LinkQualityInfo object.
578      */
GetLinkInfo(void) const579     const LinkQualityInfo &GetLinkInfo(void) const { return mLinkInfo; }
580 
581     /**
582      * Gets the link quality in value.
583      *
584      * @returns The link quality in value.
585      */
GetLinkQualityIn(void) const586     LinkQuality GetLinkQualityIn(void) const { return GetLinkInfo().GetLinkQuality(); }
587 
588     /**
589      * Generates a new challenge value for MLE Link Request/Response exchanges.
590      */
GenerateChallenge(void)591     void GenerateChallenge(void) { mValidPending.mPending.mChallenge.GenerateRandom(); }
592 
593     /**
594      * Returns the current challenge value for MLE Link Request/Response exchanges.
595      *
596      * @returns The current challenge value.
597      */
GetChallenge(void) const598     const Mle::TxChallenge &GetChallenge(void) const { return mValidPending.mPending.mChallenge; }
599 
600 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
601     /**
602      * Returns the connection time (in seconds) of the neighbor (seconds since entering `kStateValid`).
603      *
604      * @returns The connection time (in seconds), zero if device is not currently in `kStateValid`.
605      */
606     uint32_t GetConnectionTime(void) const;
607 #endif
608 
609 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
610     /**
611      * Indicates whether or not time sync feature is enabled.
612      *
613      * @returns TRUE if time sync feature is enabled, FALSE otherwise.
614      */
IsTimeSyncEnabled(void) const615     bool IsTimeSyncEnabled(void) const { return mTimeSyncEnabled; }
616 
617     /**
618      * Sets whether or not time sync feature is enabled.
619      *
620      * @param[in]  aEnable    TRUE if time sync feature is enabled, FALSE otherwise.
621      */
SetTimeSyncEnabled(bool aEnabled)622     void SetTimeSyncEnabled(bool aEnabled) { mTimeSyncEnabled = aEnabled; }
623 #endif
624 
625 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
626     /**
627      * Aggregates the Link Metrics data into all the series that is running for this neighbor.
628      *
629      * If a series wants to account frames of @p aFrameType, it would add count by 1 and aggregate @p aLqi and
630      * @p aRss into its averagers.
631      *
632      * @param[in] aSeriesId     Series ID for Link Probe. Should be `0` if this method is not called by Link Probe.
633      * @param[in] aFrameType    Type of the frame that carries Link Metrics data.
634      * @param[in] aLqi          The LQI value.
635      * @param[in] aRss          The Rss value.
636      */
637     void AggregateLinkMetrics(uint8_t aSeriesId, uint8_t aFrameType, uint8_t aLqi, int8_t aRss);
638 
639     /**
640      * Adds a new LinkMetrics::SeriesInfo to the neighbor's list.
641      *
642      * @param[in]  aSeriesInfo  A reference to the new SeriesInfo.
643      */
644     void AddForwardTrackingSeriesInfo(LinkMetrics::SeriesInfo &aSeriesInfo);
645 
646     /**
647      * Finds a specific LinkMetrics::SeriesInfo by Series ID.
648      *
649      * @param[in] aSeriesId    A reference to the Series ID.
650      *
651      * @returns The pointer to the LinkMetrics::SeriesInfo. `nullptr` if not found.
652      */
653     LinkMetrics::SeriesInfo *GetForwardTrackingSeriesInfo(const uint8_t &aSeriesId);
654 
655     /**
656      * Removes a specific LinkMetrics::SeriesInfo by Series ID.
657      *
658      * @param[in] aSeriesId    A reference to the Series ID to remove.
659      *
660      * @returns The pointer to the LinkMetrics::SeriesInfo. `nullptr` if not found.
661      */
662     LinkMetrics::SeriesInfo *RemoveForwardTrackingSeriesInfo(const uint8_t &aSeriesId);
663 
664     /**
665      * Removes all the Series and return the data structures to the Pool.
666      */
667     void RemoveAllForwardTrackingSeriesInfo(void);
668 
669     /**
670      * Gets the Enh-ACK Probing metrics (this `Neighbor` object is the Probing Subject).
671      *
672      * @returns Enh-ACK Probing metrics configured.
673      */
GetEnhAckProbingMetrics(void) const674     const LinkMetrics::Metrics &GetEnhAckProbingMetrics(void) const { return mEnhAckProbingMetrics; }
675 
676     /**
677      * Sets the Enh-ACK Probing metrics (this `Neighbor` object is the Probing Subject).
678      *
679      * @param[in]  aEnhAckProbingMetrics  The metrics value to set.
680      */
SetEnhAckProbingMetrics(const LinkMetrics::Metrics & aEnhAckProbingMetrics)681     void SetEnhAckProbingMetrics(const LinkMetrics::Metrics &aEnhAckProbingMetrics)
682     {
683         mEnhAckProbingMetrics = aEnhAckProbingMetrics;
684     }
685 
686     /**
687      * Indicates if Enh-ACK Probing is configured and active for this `Neighbor` object.
688      *
689      * @retval TRUE   Enh-ACK Probing is configured and active for this `Neighbor`.
690      * @retval FALSE  Otherwise.
691      */
IsEnhAckProbingActive(void) const692     bool IsEnhAckProbingActive(void) const
693     {
694         return (mEnhAckProbingMetrics.mLqi != 0) || (mEnhAckProbingMetrics.mLinkMargin != 0) ||
695                (mEnhAckProbingMetrics.mRssi != 0);
696     }
697 #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
698 
699     /**
700      * Converts a given `State` to a human-readable string.
701      *
702      * @param[in] aState   A neighbor state.
703      *
704      * @returns A string representation of given state.
705      */
706     static const char *StateToString(State aState);
707 
708 protected:
709     /**
710      * Initializes the `Neighbor` object.
711      *
712      * @param[in] aInstance  A reference to OpenThread instance.
713      */
714     void Init(Instance &aInstance);
715 
716 private:
717     static constexpr uint32_t kLastRxFragmentTagTimeout = OPENTHREAD_CONFIG_MULTI_RADIO_FRAG_TAG_TIMEOUT; // in msec
718 
719     Mac::ExtAddress mMacAddr;
720     TimeMilli       mLastHeard;
721     union
722     {
723         struct
724         {
725             Mac::LinkFrameCounters mLinkFrameCounters;
726             uint32_t               mMleFrameCounter;
727 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
728             uint32_t mLinkAckFrameCounter;
729 #endif
730         } mValid;
731         struct
732         {
733             Mle::TxChallenge mChallenge;
734         } mPending;
735     } mValidPending;
736 
737 #if OPENTHREAD_CONFIG_MULTI_RADIO
738     uint16_t  mLastRxFragmentTag;
739     TimeMilli mLastRxFragmentTagTime;
740 #endif
741 
742     uint32_t mKeySequence;
743     uint16_t mRloc16;
744     uint8_t  mState : 4;
745     uint8_t  mMode : 4;
746 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
747     uint8_t mLinkFailures : 7;
748     bool    mTimeSyncEnabled : 1;
749 #else
750     uint8_t mLinkFailures;
751 #endif
752     uint16_t        mVersion;
753     LinkQualityInfo mLinkInfo;
754 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
755     // A list of Link Metrics Forward Tracking Series that is being
756     // tracked for this neighbor. Note that this device is the
757     // Subject and this neighbor is the Initiator.
758     LinkedList<LinkMetrics::SeriesInfo> mLinkMetricsSeriesInfoList;
759 
760     // Metrics configured for Enh-ACK Based Probing at the Probing
761     // Subject (this neighbor). Note that this device is the Initiator
762     // and this neighbor is the Subject.
763     LinkMetrics::Metrics mEnhAckProbingMetrics;
764 #endif
765 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
766     uint32_t mConnectionStart;
767 #endif
768 };
769 
770 DefineCoreType(otNeighborInfo, Neighbor::Info);
771 
772 /**
773  * Represents a CSL neighbor.
774  */
775 class CslNeighbor : public Neighbor
776 #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
777     ,
778                     public IndirectSender::NeighborInfo,
779                     public DataPollHandler::NeighborInfo
780 #endif
781 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
782     ,
783                     public CslTxScheduler::NeighborInfo
784 #endif
785 {
786 };
787 
788 } // namespace ot
789 
790 #endif // NEIGHBOR_HPP_
791