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 maintaining Thread network topologies.
32  */
33 
34 #ifndef TOPOLOGY_HPP_
35 #define TOPOLOGY_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <openthread/thread_ftd.h>
40 
41 #include "common/clearable.hpp"
42 #include "common/equatable.hpp"
43 #include "common/linked_list.hpp"
44 #include "common/locator.hpp"
45 #include "common/message.hpp"
46 #include "common/random.hpp"
47 #include "common/timer.hpp"
48 #include "mac/mac_types.hpp"
49 #include "net/ip6.hpp"
50 #include "radio/radio.hpp"
51 #include "radio/trel_link.hpp"
52 #include "thread/csl_tx_scheduler.hpp"
53 #include "thread/indirect_sender.hpp"
54 #include "thread/link_metrics.hpp"
55 #include "thread/link_quality.hpp"
56 #include "thread/mle_tlvs.hpp"
57 #include "thread/mle_types.hpp"
58 #include "thread/radio_selector.hpp"
59 
60 namespace ot {
61 
62 /**
63  * This class represents a Thread neighbor.
64  *
65  */
66 class Neighbor : public InstanceLocatorInit
67 #if OPENTHREAD_CONFIG_MULTI_RADIO
68     ,
69                  public RadioSelector::NeighborInfo
70 #endif
71 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
72     ,
73                  public Trel::NeighborInfo
74 #endif
75 {
76 public:
77     /**
78      * Neighbor link states.
79      *
80      */
81     enum State : uint8_t
82     {
83         kStateInvalid,            ///< Neighbor link is invalid
84         kStateRestored,           ///< Neighbor is restored from non-volatile memory
85         kStateParentRequest,      ///< Received an MLE Parent Request message
86         kStateParentResponse,     ///< Received an MLE Parent Response message
87         kStateChildIdRequest,     ///< Received an MLE Child ID Request message
88         kStateLinkRequest,        ///< Sent an MLE Link Request message
89         kStateChildUpdateRequest, ///< Sent an MLE Child Update Request message (trying to restore the child)
90         kStateValid,              ///< Link is valid
91     };
92 
93     /**
94      * This enumeration defines state filters used for finding a neighbor or iterating through the child/neighbor table.
95      *
96      * Each filter definition accepts a subset of `State` values.
97      *
98      */
99     enum StateFilter : uint8_t
100     {
101         kInStateValid,                     ///< Accept neighbor only in `kStateValid`.
102         kInStateValidOrRestoring,          ///< Accept neighbor with `IsStateValidOrRestoring()` being `true`.
103         kInStateChildIdRequest,            ///< Accept neighbor only in `Child:kStateChildIdRequest`.
104         kInStateValidOrAttaching,          ///< Accept neighbor with `IsStateValidOrAttaching()` being `true`.
105         kInStateInvalid,                   ///< Accept neighbor only in `kStateInvalid`.
106         kInStateAnyExceptInvalid,          ///< Accept neighbor in any state except `kStateInvalid`.
107         kInStateAnyExceptValidOrRestoring, ///< Accept neighbor in any state except `IsStateValidOrRestoring()`.
108         kInStateAny,                       ///< Accept neighbor in any state.
109     };
110 
111     /**
112      * This class represents an Address Matcher used to find a neighbor (child/router) with a given MAC address also
113      * matching a given state filter.
114      *
115      */
116     class AddressMatcher
117     {
118     public:
119         /**
120          * This constructor initializes the `AddressMatcher` with a given MAC short address (RCOC16) and state filter.
121          *
122          * @param[in]  aShortAddress   A MAC short address (RLOC16).
123          * @param[in]  aStateFilter    A state filter.
124          *
125          */
AddressMatcher(Mac::ShortAddress aShortAddress,StateFilter aStateFilter)126         AddressMatcher(Mac::ShortAddress aShortAddress, StateFilter aStateFilter)
127             : AddressMatcher(aStateFilter, aShortAddress, nullptr)
128         {
129         }
130 
131         /**
132          * This constructor 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          *
137          */
AddressMatcher(const Mac::ExtAddress & aExtAddress,StateFilter aStateFilter)138         AddressMatcher(const Mac::ExtAddress &aExtAddress, StateFilter aStateFilter)
139             : AddressMatcher(aStateFilter, Mac::kShortAddrInvalid, &aExtAddress)
140         {
141         }
142 
143         /**
144          * This constructor initializes the `AddressMatcher` with a given MAC address and state filter.
145          *
146          * @param[in]  aMacAddress     A MAC address.
147          * @param[in]  aStateFilter    A state filter.
148          *
149          */
AddressMatcher(const Mac::Address & aMacAddress,StateFilter aStateFilter)150         AddressMatcher(const Mac::Address &aMacAddress, StateFilter aStateFilter)
151             : AddressMatcher(aStateFilter,
152                              aMacAddress.IsShort() ? aMacAddress.GetShort()
153                                                    : static_cast<Mac::ShortAddress>(Mac::kShortAddrInvalid),
154                              aMacAddress.IsExtended() ? &aMacAddress.GetExtended() : nullptr)
155         {
156         }
157 
158         /**
159          * This constructor initializes the `AddressMatcher` with a given state filter (it accepts any address).
160          *
161          * @param[in]  aStateFilter    A state filter.
162          *
163          */
AddressMatcher(StateFilter aStateFilter)164         explicit AddressMatcher(StateFilter aStateFilter)
165             : AddressMatcher(aStateFilter, Mac::kShortAddrInvalid, nullptr)
166         {
167         }
168 
169         /**
170          * This method indicates if a given neighbor matches the address and state filter of `AddressMatcher`.
171          *
172          * @param[in] aNeighbor   A neighbor.
173          *
174          * @retval TRUE   Neighbor @p aNeighbor matches the address and state filter.
175          * @retval FALSE  Neighbor @p aNeighbor does not match the address or state filter.
176          *
177          */
178         bool Matches(const Neighbor &aNeighbor) const;
179 
180     private:
AddressMatcher(StateFilter aStateFilter,Mac::ShortAddress aShortAddress,const Mac::ExtAddress * aExtAddress)181         AddressMatcher(StateFilter aStateFilter, Mac::ShortAddress aShortAddress, const Mac::ExtAddress *aExtAddress)
182             : mStateFilter(aStateFilter)
183             , mShortAddress(aShortAddress)
184             , mExtAddress(aExtAddress)
185         {
186         }
187 
188         StateFilter            mStateFilter;
189         Mac::ShortAddress      mShortAddress;
190         const Mac::ExtAddress *mExtAddress;
191     };
192 
193     /**
194      * This type represents diagnostic information for a neighboring node.
195      *
196      */
197     class Info : public otNeighborInfo, public Clearable<Info>
198     {
199     public:
200         /**
201          * This method sets the `Info` instance from a given `Neighbor`.
202          *
203          * @param[in] aNeighbor   A neighbor.
204          *
205          */
206         void SetFrom(const Neighbor &aNeighbor);
207     };
208 
209     /**
210      * This method returns the current state.
211      *
212      * @returns The current state.
213      *
214      */
GetState(void) const215     State GetState(void) const { return static_cast<State>(mState); }
216 
217     /**
218      * This method sets the current state.
219      *
220      * @param[in]  aState  The state value.
221      *
222      */
SetState(State aState)223     void SetState(State aState) { mState = static_cast<uint8_t>(aState); }
224 
225     /**
226      * This method indicates whether the neighbor is in the Invalid state.
227      *
228      * @returns TRUE if the neighbor is in the Invalid state, FALSE otherwise.
229      *
230      */
IsStateInvalid(void) const231     bool IsStateInvalid(void) const { return (mState == kStateInvalid); }
232 
233     /**
234      * This method indicates whether the neighbor is in the Child ID Request state.
235      *
236      * @returns TRUE if the neighbor is in the Child ID Request state, FALSE otherwise.
237      *
238      */
IsStateChildIdRequest(void) const239     bool IsStateChildIdRequest(void) const { return (mState == kStateChildIdRequest); }
240 
241     /**
242      * This method indicates whether the neighbor is in the Link Request state.
243      *
244      * @returns TRUE if the neighbor is in the Link Request state, FALSE otherwise.
245      *
246      */
IsStateLinkRequest(void) const247     bool IsStateLinkRequest(void) const { return (mState == kStateLinkRequest); }
248 
249     /**
250      * This method indicates whether the neighbor is in the Parent Response state.
251      *
252      * @returns TRUE if the neighbor is in the Parent Response state, FALSE otherwise.
253      *
254      */
IsStateParentResponse(void) const255     bool IsStateParentResponse(void) const { return (mState == kStateParentResponse); }
256 
257     /**
258      * This method indicates whether the neighbor is being restored.
259      *
260      * @returns TRUE if the neighbor is being restored, FALSE otherwise.
261      *
262      */
IsStateRestoring(void) const263     bool IsStateRestoring(void) const { return (mState == kStateRestored) || (mState == kStateChildUpdateRequest); }
264 
265     /**
266      * This method indicates whether the neighbor is in the Restored state.
267      *
268      * @returns TRUE if the neighbor is in the Restored state, FALSE otherwise.
269      *
270      */
IsStateRestored(void) const271     bool IsStateRestored(void) const { return (mState == kStateRestored); }
272 
273     /**
274      * This method indicates whether the neighbor is valid (frame counters are synchronized).
275      *
276      * @returns TRUE if the neighbor is valid, FALSE otherwise.
277      *
278      */
IsStateValid(void) const279     bool IsStateValid(void) const { return (mState == kStateValid); }
280 
281     /**
282      * This method indicates whether the neighbor is in valid state or if it is being restored.
283      *
284      * When in these states messages can be sent to and/or received from the neighbor.
285      *
286      * @returns TRUE if the neighbor is in valid, restored, or being restored states, FALSE otherwise.
287      *
288      */
IsStateValidOrRestoring(void) const289     bool IsStateValidOrRestoring(void) const { return (mState == kStateValid) || IsStateRestoring(); }
290 
291     /**
292      * This method indicates if the neighbor state is valid, attaching, or restored.
293      *
294      * The states `kStateRestored`, `kStateChildIdRequest`, `kStateChildUpdateRequest`, `kStateValid`, and
295      * `kStateLinkRequest` are considered as valid, attaching, or restored.
296      *
297      * @returns TRUE if the neighbor state is valid, attaching, or restored, FALSE otherwise.
298      *
299      */
300     bool IsStateValidOrAttaching(void) const;
301 
302     /**
303      * This method indicates whether neighbor state matches a given state filter.
304      *
305      * @param[in] aFilter   A state filter (`StateFilter` enumeration) to match against.
306      *
307      * @returns TRUE if the neighbor state matches the filter, FALSE otherwise.
308      *
309      */
310     bool MatchesFilter(StateFilter aFilter) const;
311 
312     /**
313      * This method indicates whether neighbor matches a given `AddressMatcher`.
314      *
315      * @param[in]  aMatcher   An `AddressMatcher` to match against.
316      *
317      * @returns TRUE if the neighbor matches the address and state filter of @p aMatcher, FALSE otherwise.
318      *
319      */
Matches(const AddressMatcher & aMatcher) const320     bool Matches(const AddressMatcher &aMatcher) const { return aMatcher.Matches(*this); }
321 
322     /**
323      * This method gets the device mode flags.
324      *
325      * @returns The device mode flags.
326      *
327      */
GetDeviceMode(void) const328     Mle::DeviceMode GetDeviceMode(void) const { return Mle::DeviceMode(mMode); }
329 
330     /**
331      * This method sets the device mode flags.
332      *
333      * @param[in]  aMode  The device mode flags.
334      *
335      */
SetDeviceMode(Mle::DeviceMode aMode)336     void SetDeviceMode(Mle::DeviceMode aMode) { mMode = aMode.Get(); }
337 
338     /**
339      * This method indicates whether or not the device is rx-on-when-idle.
340      *
341      * @returns TRUE if rx-on-when-idle, FALSE otherwise.
342      *
343      */
IsRxOnWhenIdle(void) const344     bool IsRxOnWhenIdle(void) const { return GetDeviceMode().IsRxOnWhenIdle(); }
345 
346     /**
347      * This method indicates whether or not the device is a Full Thread Device.
348      *
349      * @returns TRUE if a Full Thread Device, FALSE otherwise.
350      *
351      */
IsFullThreadDevice(void) const352     bool IsFullThreadDevice(void) const { return GetDeviceMode().IsFullThreadDevice(); }
353 
354     /**
355      * This method indicates whether or not the device requests Full Network Data.
356      *
357      * @returns TRUE if requests Full Network Data, FALSE otherwise.
358      *
359      */
IsFullNetworkData(void) const360     bool IsFullNetworkData(void) const { return GetDeviceMode().IsFullNetworkData(); }
361 
362     /**
363      * This method sets all bytes of the Extended Address to zero.
364      *
365      */
ClearExtAddress(void)366     void ClearExtAddress(void) { memset(&mMacAddr, 0, sizeof(mMacAddr)); }
367 
368     /**
369      * This method returns the Extended Address.
370      *
371      * @returns A reference to the Extended Address.
372      *
373      */
GetExtAddress(void) const374     const Mac::ExtAddress &GetExtAddress(void) const { return mMacAddr; }
375 
376     /**
377      * This method sets the Extended Address.
378      *
379      * @param[in]  aAddress  The Extended Address value to set.
380      *
381      */
SetExtAddress(const Mac::ExtAddress & aAddress)382     void SetExtAddress(const Mac::ExtAddress &aAddress) { mMacAddr = aAddress; }
383 
384     /**
385      * This method gets the key sequence value.
386      *
387      * @returns The key sequence value.
388      *
389      */
GetKeySequence(void) const390     uint32_t GetKeySequence(void) const { return mKeySequence; }
391 
392     /**
393      * This method sets the key sequence value.
394      *
395      * @param[in]  aKeySequence  The key sequence value.
396      *
397      */
SetKeySequence(uint32_t aKeySequence)398     void SetKeySequence(uint32_t aKeySequence) { mKeySequence = aKeySequence; }
399 
400     /**
401      * This method returns the last heard time.
402      *
403      * @returns The last heard time.
404      *
405      */
GetLastHeard(void) const406     TimeMilli GetLastHeard(void) const { return mLastHeard; }
407 
408     /**
409      * This method sets the last heard time.
410      *
411      * @param[in]  aLastHeard  The last heard time.
412      *
413      */
SetLastHeard(TimeMilli aLastHeard)414     void SetLastHeard(TimeMilli aLastHeard) { mLastHeard = aLastHeard; }
415 
416     /**
417      * This method gets the link frame counters.
418      *
419      * @returns A reference to `Mac::LinkFrameCounters` containing link frame counter for all supported radio links.
420      *
421      */
GetLinkFrameCounters(void)422     Mac::LinkFrameCounters &GetLinkFrameCounters(void) { return mValidPending.mValid.mLinkFrameCounters; }
423 
424     /**
425      * This method gets the link frame counters.
426      *
427      * @returns A reference to `Mac::LinkFrameCounters` containing link frame counter for all supported radio links.
428      *
429      */
GetLinkFrameCounters(void) const430     const Mac::LinkFrameCounters &GetLinkFrameCounters(void) const { return mValidPending.mValid.mLinkFrameCounters; }
431 
432 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
433     /**
434      * This method gets the link ACK frame counter value.
435      *
436      * @returns The link ACK frame counter value.
437      *
438      */
GetLinkAckFrameCounter(void) const439     uint32_t GetLinkAckFrameCounter(void) const { return mValidPending.mValid.mLinkAckFrameCounter; }
440 #endif
441 
442     /**
443      * This method sets the link ACK frame counter value.
444      *
445      * @param[in]  aAckFrameCounter  The link ACK frame counter value.
446      *
447      */
SetLinkAckFrameCounter(uint32_t aAckFrameCounter)448     void SetLinkAckFrameCounter(uint32_t aAckFrameCounter)
449     {
450 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
451         mValidPending.mValid.mLinkAckFrameCounter = aAckFrameCounter;
452 #else
453         OT_UNUSED_VARIABLE(aAckFrameCounter);
454 #endif
455     }
456 
457     /**
458      * This method gets the MLE frame counter value.
459      *
460      * @returns The MLE frame counter value.
461      *
462      */
GetMleFrameCounter(void) const463     uint32_t GetMleFrameCounter(void) const { return mValidPending.mValid.mMleFrameCounter; }
464 
465     /**
466      * This method sets the MLE frame counter value.
467      *
468      * @param[in]  aFrameCounter  The MLE frame counter value.
469      *
470      */
SetMleFrameCounter(uint32_t aFrameCounter)471     void SetMleFrameCounter(uint32_t aFrameCounter) { mValidPending.mValid.mMleFrameCounter = aFrameCounter; }
472 
473     /**
474      * This method gets the RLOC16 value.
475      *
476      * @returns The RLOC16 value.
477      *
478      */
GetRloc16(void) const479     uint16_t GetRloc16(void) const { return mRloc16; }
480 
481     /**
482      * This method gets the Router ID value.
483      *
484      * @returns The Router ID value.
485      *
486      */
GetRouterId(void) const487     uint8_t GetRouterId(void) const { return mRloc16 >> Mle::kRouterIdOffset; }
488 
489     /**
490      * This method sets the RLOC16 value.
491      *
492      * @param[in]  aRloc16  The RLOC16 value.
493      *
494      */
SetRloc16(uint16_t aRloc16)495     void SetRloc16(uint16_t aRloc16) { mRloc16 = aRloc16; }
496 
497 #if OPENTHREAD_CONFIG_MULTI_RADIO
498     /**
499      * This method clears the last received fragment tag.
500      *
501      * The last received fragment tag is used for detect duplicate frames (receievd over different radios) when
502      * multi-radio feature is enabled.
503      *
504      */
ClearLastRxFragmentTag(void)505     void ClearLastRxFragmentTag(void) { mLastRxFragmentTag = 0; }
506 
507     /**
508      * This method gets the last received fragment tag.
509      *
510      * This method MUST be used only when the tag is set (and not cleared). Otherwise its behavior is undefined.
511      *
512      * @returns The last received fragment tag.
513      *
514      */
GetLastRxFragmentTag(void) const515     uint16_t GetLastRxFragmentTag(void) const { return mLastRxFragmentTag; }
516 
517     /**
518      * This method set the last received fragment tag.
519      *
520      * @param[in] aTag   The new tag value.
521      *
522      */
SetLastRxFragmentTag(uint16_t aTag)523     void SetLastRxFragmentTag(uint16_t aTag) { mLastRxFragmentTag = (aTag == 0) ? 0xffff : aTag; }
524 
525     /**
526      * This method indicates whether the last received fragment tag is set or not.
527      *
528      * @returns TRUE if the last received fragment tag is set, FALSE otherwise.
529      *
530      */
IsLastRxFragmentTagSet(void) const531     bool IsLastRxFragmentTagSet(void) const { return (mLastRxFragmentTag != 0); }
532 
533     /**
534      * This method indicates whether the last received fragment tag is strictly after a given tag value.
535      *
536      * This method MUST be used only when the tag is set (and not cleared). Otherwise its behavior is undefined.
537      *
538      * The tag value compassion follows the Serial Number Arithmetic logic from RFC-1982. It is semantically equivalent
539      * to `LastRxFragementTag > aTag`.
540      *
541      * @param[in] aTag   A tag value to compare against.
542      *
543      * @returns TRUE if the current last rx fragment tag is strictly after @p aTag, FALSE if they are equal or it is
544      * before @p aTag.
545      *
546      */
IsLastRxFragmentTagAfter(uint16_t aTag) const547     bool IsLastRxFragmentTagAfter(uint16_t aTag) const { return ((aTag - mLastRxFragmentTag) & (1U << 15)) != 0; }
548 
549 #endif // OPENTHREAD_CONFIG_MULTI_RADIO
550 
551     /**
552      * This method indicates whether or not it is a valid Thread 1.1 neighbor.
553      *
554      * @returns TRUE if it is a valid Thread 1.1 neighbor, FALSE otherwise.
555      *
556      */
IsThreadVersion1p1(void) const557     bool IsThreadVersion1p1(void) const { return mState != kStateInvalid && mVersion == OT_THREAD_VERSION_1_1; }
558 
559     /**
560      * This method indicates whether or not it is a valid Thread 1.2 neighbor.
561      *
562      * @returns TRUE if it is a valid Thread 1.2 neighbor, FALSE otherwise.
563      *
564      */
IsThreadVersion1p2(void) const565     bool IsThreadVersion1p2(void) const { return mState != kStateInvalid && mVersion == OT_THREAD_VERSION_1_2; }
566 
567     /**
568      * This method indicates whether Enhanced Keep-Alive is supported or not.
569      *
570      * @returns TRUE if Enhanced Keep-Alive is supported, FALSE otherwise.
571      *
572      */
IsEnhancedKeepAliveSupported(void) const573     bool IsEnhancedKeepAliveSupported(void) const
574     {
575         return mState != kStateInvalid && mVersion >= OT_THREAD_VERSION_1_2;
576     }
577 
578     /**
579      * This method gets the device MLE version.
580      *
581      */
GetVersion(void) const582     uint8_t GetVersion(void) const { return mVersion; }
583 
584     /**
585      * This method sets the device MLE version.
586      *
587      * @param[in]  aVersion  The device MLE version.
588      *
589      */
SetVersion(uint8_t aVersion)590     void SetVersion(uint8_t aVersion) { mVersion = aVersion; }
591 
592     /**
593      * This method gets the number of consecutive link failures.
594      *
595      * @returns The number of consecutive link failures.
596      *
597      */
GetLinkFailures(void) const598     uint8_t GetLinkFailures(void) const { return mLinkFailures; }
599 
600     /**
601      * This method increments the number of consecutive link failures.
602      *
603      */
IncrementLinkFailures(void)604     void IncrementLinkFailures(void) { mLinkFailures++; }
605 
606     /**
607      * This method resets the number of consecutive link failures to zero.
608      *
609      */
ResetLinkFailures(void)610     void ResetLinkFailures(void) { mLinkFailures = 0; }
611 
612     /**
613      * This method returns the LinkQualityInfo object.
614      *
615      * @returns The LinkQualityInfo object.
616      *
617      */
GetLinkInfo(void)618     LinkQualityInfo &GetLinkInfo(void) { return mLinkInfo; }
619 
620     /**
621      * This method returns the LinkQualityInfo object.
622      *
623      * @returns The LinkQualityInfo object.
624      *
625      */
GetLinkInfo(void) const626     const LinkQualityInfo &GetLinkInfo(void) const { return mLinkInfo; }
627 
628     /**
629      * This method generates a new challenge value for MLE Link Request/Response exchanges.
630      *
631      */
632     void GenerateChallenge(void);
633 
634     /**
635      * This method returns the current challenge value for MLE Link Request/Response exchanges.
636      *
637      * @returns The current challenge value.
638      *
639      */
GetChallenge(void) const640     const uint8_t *GetChallenge(void) const { return mValidPending.mPending.mChallenge; }
641 
642     /**
643      * This method returns the size (bytes) of the challenge value for MLE Link Request/Response exchanges.
644      *
645      * @returns The size (bytes) of the challenge value for MLE Link Request/Response exchanges.
646      *
647      */
GetChallengeSize(void) const648     uint8_t GetChallengeSize(void) const { return sizeof(mValidPending.mPending.mChallenge); }
649 
650 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
651     /**
652      * This method indicates whether or not time sync feature is enabled.
653      *
654      * @returns TRUE if time sync feature is enabled, FALSE otherwise.
655      *
656      */
IsTimeSyncEnabled(void) const657     bool IsTimeSyncEnabled(void) const { return mTimeSyncEnabled; }
658 
659     /**
660      * This method sets whether or not time sync feature is enabled.
661      *
662      * @param[in]  aEnable    TRUE if time sync feature is enabled, FALSE otherwise.
663      *
664      */
SetTimeSyncEnabled(bool aEnabled)665     void SetTimeSyncEnabled(bool aEnabled) { mTimeSyncEnabled = aEnabled; }
666 #endif
667 
668 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
669     /**
670      * This method aggregates the Link Metrics data into all the series that is running for this neighbor.
671      *
672      * If a series wants to account frames of @p aFrameType, it would add count by 1 and aggregate @p aLqi and
673      * @p aRss into its averagers.
674      *
675      * @param[in] aSeriesId     Series ID for Link Probe. Should be `0` if this method is not called by Link Probe.
676      * @param[in] aFrameType    Type of the frame that carries Link Metrics data.
677      * @param[in] aLqi          The LQI value.
678      * @param[in] aRss          The Rss value.
679      *
680      */
681     void AggregateLinkMetrics(uint8_t aSeriesId, uint8_t aFrameType, uint8_t aLqi, int8_t aRss);
682 
683     /**
684      * This method adds a new LinkMetrics::SeriesInfo to the neighbor's list.
685      *
686      * @param[in]    A reference to the new SeriesInfo.
687      *
688      */
689     void AddForwardTrackingSeriesInfo(LinkMetrics::SeriesInfo &aSeriesInfo);
690 
691     /**
692      * This method finds a specific LinkMetrics::SeriesInfo by Series ID.
693      *
694      * @param[in] aSeriesId    A reference to the Series ID.
695      *
696      * @returns The pointer to the LinkMetrics::SeriesInfo. `nullptr` if not found.
697      *
698      */
699     LinkMetrics::SeriesInfo *GetForwardTrackingSeriesInfo(const uint8_t &aSeriesId);
700 
701     /**
702      * This method removes a specific LinkMetrics::SeriesInfo by Series ID.
703      *
704      * @param[in] aSeriesId    A reference to the Series ID to remove.
705      *
706      * @returns The pointer to the LinkMetrics::SeriesInfo. `nullptr` if not found.
707      *
708      */
709     LinkMetrics::SeriesInfo *RemoveForwardTrackingSeriesInfo(const uint8_t &aSeriesId);
710 
711     /**
712      * This method removes all the Series and return the data structures to the Pool.
713      *
714      */
715     void RemoveAllForwardTrackingSeriesInfo(void);
716 
717     /**
718      * This method gets the Enh-ACK Probing metrics (this `Neighbor` object is the Probing Subject).
719      *
720      * @returns Enh-ACK Probing metrics configured.
721      *
722      */
GetEnhAckProbingMetrics(void) const723     const LinkMetrics::Metrics &GetEnhAckProbingMetrics(void) const { return mEnhAckProbingMetrics; }
724 
725     /**
726      * This method sets the Enh-ACK Probing metrics (this `Neighbor` object is the Probing Subject).
727      *
728      * @param[in]  aEnhAckProbingMetrics  The metrics value to set.
729      *
730      */
SetEnhAckProbingMetrics(const LinkMetrics::Metrics & aEnhAckProbingMetrics)731     void SetEnhAckProbingMetrics(const LinkMetrics::Metrics &aEnhAckProbingMetrics)
732     {
733         mEnhAckProbingMetrics = aEnhAckProbingMetrics;
734     }
735 
736     /**
737      * This method indicates if Enh-ACK Probing is configured and active for this `Neighbor` object.
738      *
739      * @retval TRUE   Enh-ACK Probing is configured and active for this `Neighbor`.
740      * @retval FALSE  Otherwise.
741      *
742      */
IsEnhAckProbingActive(void) const743     bool IsEnhAckProbingActive(void) const
744     {
745         return (mEnhAckProbingMetrics.mLqi != 0) || (mEnhAckProbingMetrics.mLinkMargin != 0) ||
746                (mEnhAckProbingMetrics.mRssi != 0);
747     }
748 #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
749 
750     /**
751      * This method converts a given `State` to a human-readable string.
752      *
753      * @param[in] aState   A neighbor state.
754      *
755      * @returns A string representation of given state.
756      *
757      */
758     static const char *StateToString(State aState);
759 
760 protected:
761     /**
762      * This method initializes the `Neighbor` object.
763      *
764      * @param[in] aInstance  A reference to OpenThread instance.
765      *
766      */
767     void Init(Instance &aInstance);
768 
769 private:
770     Mac::ExtAddress mMacAddr;   ///< The IEEE 802.15.4 Extended Address
771     TimeMilli       mLastHeard; ///< Time when last heard.
772     union
773     {
774         struct
775         {
776             Mac::LinkFrameCounters mLinkFrameCounters; ///< The Link Frame Counters
777             uint32_t               mMleFrameCounter;   ///< The MLE Frame Counter
778 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
779             uint32_t mLinkAckFrameCounter; ///< The Link Ack Frame Counter
780 #endif
781         } mValid;
782         struct
783         {
784             uint8_t mChallenge[Mle::kMaxChallengeSize]; ///< The challenge value
785         } mPending;
786     } mValidPending;
787 
788 #if OPENTHREAD_CONFIG_MULTI_RADIO
789     uint16_t mLastRxFragmentTag; ///< Last received fragment tag
790 #endif
791 
792     uint32_t mKeySequence; ///< Current key sequence
793     uint16_t mRloc16;      ///< The RLOC16
794     uint8_t  mState : 4;   ///< The link state
795     uint8_t  mMode : 4;    ///< The MLE device mode
796 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
797     uint8_t mLinkFailures : 7;    ///< Consecutive link failure count
798     bool    mTimeSyncEnabled : 1; ///< Indicates whether or not time sync feature is enabled.
799 #else
800     uint8_t mLinkFailures; ///< Consecutive link failure count
801 #endif
802     uint8_t         mVersion;  ///< The MLE version
803     LinkQualityInfo mLinkInfo; ///< Link quality info (contains average RSS, link margin and link quality)
804 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
805     // A list of Link Metrics Forward Tracking Series that is being
806     // tracked for this neighbor. Note that this device is the
807     // Subject and this neighbor is the Initiator.
808     LinkedList<LinkMetrics::SeriesInfo> mLinkMetricsSeriesInfoList;
809 
810     // Metrics configured for Enh-ACK Based Probing at the Probing
811     // Subject (this neighbor). Note that this device is the Initiator
812     // and this neighbor is the Subject.
813     LinkMetrics::Metrics mEnhAckProbingMetrics;
814 #endif
815 };
816 
817 #if OPENTHREAD_FTD
818 
819 /**
820  * This class represents a Thread Child.
821  *
822  */
823 class Child : public Neighbor,
824               public IndirectSender::ChildInfo,
825               public DataPollHandler::ChildInfo
826 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
827     ,
828               public CslTxScheduler::ChildInfo
829 #endif
830 {
831     class AddressIteratorBuilder;
832 
833 public:
834     static constexpr uint8_t kMaxRequestTlvs = 5;
835 
836     /**
837      * This class represents diagnostic information for a Thread Child.
838      *
839      */
840     class Info : public otChildInfo, public Clearable<Info>
841     {
842     public:
843         /**
844          * This method sets the `Info` instance from a given `Child`.
845          *
846          * @param[in] aChild   A neighbor.
847          *
848          */
849         void SetFrom(const Child &aChild);
850     };
851 
852     /**
853      * This class defines an iterator used to go through IPv6 address entries of a child.
854      *
855      */
856     class AddressIterator : public Unequatable<AddressIterator>
857     {
858         friend class AddressIteratorBuilder;
859 
860     public:
861         /**
862          * This type represents an index indicating the current IPv6 address entry to which the iterator is pointing.
863          *
864          */
865         typedef otChildIp6AddressIterator Index;
866 
867         /**
868          * This constructor initializes the iterator associated with a given `Child` starting from beginning of the
869          * IPv6 address list.
870          *
871          * @param[in] aChild    A reference to a child entry.
872          * @param[in] aFilter   An IPv6 address type filter restricting iterator to certain type of addresses.
873          *
874          */
AddressIterator(const Child & aChild,Ip6::Address::TypeFilter aFilter=Ip6::Address::kTypeAny)875         explicit AddressIterator(const Child &aChild, Ip6::Address::TypeFilter aFilter = Ip6::Address::kTypeAny)
876             : AddressIterator(aChild, 0, aFilter)
877         {
878         }
879 
880         /**
881          * This constructor initializes the iterator associated with a given `Child` starting from a given index
882          *
883          * @param[in]  aChild   A reference to the child entry.
884          * @param[in]  aIndex   An index (`Index`) with which to initialize the iterator.
885          * @param[in]  aFilter  An IPv6 address type filter restricting iterator to certain type of addresses.
886          *
887          */
AddressIterator(const Child & aChild,Index aIndex,Ip6::Address::TypeFilter aFilter=Ip6::Address::kTypeAny)888         AddressIterator(const Child &aChild, Index aIndex, Ip6::Address::TypeFilter aFilter = Ip6::Address::kTypeAny)
889             : mChild(aChild)
890             , mFilter(aFilter)
891             , mIndex(aIndex)
892         {
893             Update();
894         }
895 
896         /**
897          * This method converts the iterator into an index.
898          *
899          * @returns An index corresponding to the iterator.
900          *
901          */
GetAsIndex(void) const902         Index GetAsIndex(void) const { return mIndex; }
903 
904         /**
905          * This method gets the iterator's associated `Child` entry.
906          *
907          * @returns The associated child entry.
908          *
909          */
GetChild(void) const910         const Child &GetChild(void) const { return mChild; }
911 
912         /**
913          * This method gets the current `Child` IPv6 Address to which the iterator is pointing.
914          *
915          * @returns  A pointer to the associated IPv6 Address, or nullptr if iterator is done.
916          *
917          */
918         const Ip6::Address *GetAddress(void) const;
919 
920         /**
921          * This method indicates whether the iterator has reached end of the list.
922          *
923          * @retval TRUE   There are no more entries in the list (reached end of the list).
924          * @retval FALSE  The current entry is valid.
925          *
926          */
IsDone(void) const927         bool IsDone(void) const { return (mIndex >= kMaxIndex); }
928 
929         /**
930          * This method overloads `++` operator (pre-increment) to advance the iterator.
931          *
932          * The iterator is moved to point to the next `Address` entry.  If there are no more `Ip6::Address` entries
933          * `IsDone()` returns `true`.
934          *
935          */
operator ++(void)936         void operator++(void) { mIndex++, Update(); }
937 
938         /**
939          * This method overloads `++` operator (post-increment) to advance the iterator.
940          *
941          * The iterator is moved to point to the next `Address` entry.  If there are no more `Ip6::Address` entries
942          *  `IsDone()` returns `true`.
943          *
944          */
operator ++(int)945         void operator++(int) { mIndex++, Update(); }
946 
947         /**
948          * This method overloads the `*` dereference operator and gets a reference to `Ip6::Address` to which the
949          * iterator is currently pointing.
950          *
951          * This method MUST be used when the iterator is not done (i.e., `IsDone()` returns `false`).
952          *
953          * @returns A reference to the `Ip6::Address` entry currently pointed by the iterator.
954          *
955          */
operator *(void) const956         const Ip6::Address &operator*(void)const { return *GetAddress(); }
957 
958         /**
959          * This method overloads operator `==` to evaluate whether or not two `Iterator` instances are equal.
960          *
961          * This method MUST be used when the two iterators are associated with the same `Child` entry.
962          *
963          * @param[in]  aOther  The other `Iterator` to compare with.
964          *
965          * @retval TRUE   If the two `Iterator` objects are equal.
966          * @retval FALSE  If the two `Iterator` objects are not equal.
967          *
968          */
operator ==(const AddressIterator & aOther) const969         bool operator==(const AddressIterator &aOther) const { return (mIndex == aOther.mIndex); }
970 
971     private:
972         enum IteratorType : uint8_t
973         {
974             kEndIterator,
975         };
976 
977         static constexpr uint16_t kMaxIndex = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD;
978 
AddressIterator(const Child & aChild,IteratorType)979         AddressIterator(const Child &aChild, IteratorType)
980             : mChild(aChild)
981             , mIndex(kMaxIndex)
982         {
983         }
984 
985         void Update(void);
986 
987         const Child &            mChild;
988         Ip6::Address::TypeFilter mFilter;
989         Index                    mIndex;
990         Ip6::Address             mMeshLocalAddress;
991     };
992 
993     /**
994      * This method initializes the `Child` object.
995      *
996      * @param[in] aInstance  A reference to OpenThread instance.
997      *
998      */
Init(Instance & aInstance)999     void Init(Instance &aInstance) { Neighbor::Init(aInstance); }
1000 
1001     /**
1002      * This method clears the child entry.
1003      *
1004      */
1005     void Clear(void);
1006 
1007     /**
1008      * This method clears the IPv6 address list for the child.
1009      *
1010      */
1011     void ClearIp6Addresses(void);
1012 
1013     /**
1014      * This method sets the device mode flags.
1015      *
1016      * @param[in]  aMode  The device mode flags.
1017      *
1018      */
1019     void SetDeviceMode(Mle::DeviceMode aMode);
1020 
1021     /**
1022      * This method gets the mesh-local IPv6 address.
1023      *
1024      * @param[out]   aAddress            A reference to an IPv6 address to provide address (if any).
1025      *
1026      * @retval kErrorNone      Successfully found the mesh-local address and updated @p aAddress.
1027      * @retval kErrorNotFound  No mesh-local IPv6 address in the IPv6 address list.
1028      *
1029      */
1030     Error GetMeshLocalIp6Address(Ip6::Address &aAddress) const;
1031 
1032     /**
1033      * This method returns the Mesh Local Interface Identifier.
1034      *
1035      * @returns The Mesh Local Interface Identifier.
1036      *
1037      */
GetMeshLocalIid(void) const1038     const Ip6::InterfaceIdentifier &GetMeshLocalIid(void) const { return mMeshLocalIid; }
1039 
1040     /**
1041      * This method enables range-based `for` loop iteration over all (or a subset of) IPv6 addresses.
1042      *
1043      * This method should be used as follows: to iterate over all addresses
1044      *
1045      *     for (const Ip6::Address &address : child.IterateIp6Addresses()) { ... }
1046      *
1047      * or to iterate over a subset of IPv6 addresses determined by a given address type filter
1048      *
1049      *     for (const Ip6::Address &address : child.IterateIp6Addresses(Ip6::Address::kTypeMulticast)) { ... }
1050      *
1051      * @param[in] aFilter  An IPv6 address type filter restricting iteration to certain type of addresses (default is
1052      *                     to accept any address type).
1053      *
1054      * @returns An IteratorBuilder instance.
1055      *
1056      */
IterateIp6Addresses(Ip6::Address::TypeFilter aFilter=Ip6::Address::kTypeAny) const1057     AddressIteratorBuilder IterateIp6Addresses(Ip6::Address::TypeFilter aFilter = Ip6::Address::kTypeAny) const
1058     {
1059         return AddressIteratorBuilder(*this, aFilter);
1060     }
1061 
1062     /**
1063      * This method adds an IPv6 address to the list.
1064      *
1065      * @param[in]  aAddress           A reference to IPv6 address to be added.
1066      *
1067      * @retval kErrorNone          Successfully added the new address.
1068      * @retval kErrorAlready       Address is already in the list.
1069      * @retval kErrorNoBufs        Already at maximum number of addresses. No entry available to add the new address.
1070      * @retval kErrorInvalidArgs   Address is invalid (it is the Unspecified Address).
1071      *
1072      */
1073     Error AddIp6Address(const Ip6::Address &aAddress);
1074 
1075     /**
1076      * This method removes an IPv6 address from the list.
1077      *
1078      * @param[in]  aAddress               A reference to IPv6 address to be removed.
1079      *
1080      * @retval kErrorNone             Successfully removed the address.
1081      * @retval kErrorNotFound         Address was not found in the list.
1082      * @retval kErrorInvalidArgs      Address is invalid (it is the Unspecified Address).
1083      *
1084      */
1085     Error RemoveIp6Address(const Ip6::Address &aAddress);
1086 
1087     /**
1088      * This method indicates whether an IPv6 address is in the list of IPv6 addresses of the child.
1089      *
1090      * @param[in]  aAddress   A reference to IPv6 address.
1091      *
1092      * @retval TRUE           The address exists on the list.
1093      * @retval FALSE          Address was not found in the list.
1094      *
1095      */
1096     bool HasIp6Address(const Ip6::Address &aAddress) const;
1097 
1098 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE
1099     /**
1100      * This method retrieves the Domain Unicast Address registered by the child.
1101      *
1102      * @returns A pointer to Domain Unicast Address registered by the child if there is.
1103      *
1104      */
1105     const Ip6::Address *GetDomainUnicastAddress(void) const;
1106 #endif
1107 
1108     /**
1109      * This method gets the child timeout.
1110      *
1111      * @returns The child timeout.
1112      *
1113      */
GetTimeout(void) const1114     uint32_t GetTimeout(void) const { return mTimeout; }
1115 
1116     /**
1117      * This method sets the child timeout.
1118      *
1119      * @param[in]  aTimeout  The child timeout.
1120      *
1121      */
SetTimeout(uint32_t aTimeout)1122     void SetTimeout(uint32_t aTimeout) { mTimeout = aTimeout; }
1123 
1124     /**
1125      * This method gets the network data version.
1126      *
1127      * @returns The network data version.
1128      *
1129      */
GetNetworkDataVersion(void) const1130     uint8_t GetNetworkDataVersion(void) const { return mNetworkDataVersion; }
1131 
1132     /**
1133      * This method sets the network data version.
1134      *
1135      * @param[in]  aVersion  The network data version.
1136      *
1137      */
SetNetworkDataVersion(uint8_t aVersion)1138     void SetNetworkDataVersion(uint8_t aVersion) { mNetworkDataVersion = aVersion; }
1139 
1140     /**
1141      * This method generates a new challenge value to use during a child attach.
1142      *
1143      */
1144     void GenerateChallenge(void);
1145 
1146     /**
1147      * This method gets the current challenge value used during attach.
1148      *
1149      * @returns The current challenge value.
1150      *
1151      */
GetChallenge(void) const1152     const uint8_t *GetChallenge(void) const { return mAttachChallenge; }
1153 
1154     /**
1155      * This method gets the challenge size (bytes) used during attach.
1156      *
1157      * @returns The challenge size (bytes).
1158      *
1159      */
GetChallengeSize(void) const1160     uint8_t GetChallengeSize(void) const { return sizeof(mAttachChallenge); }
1161 
1162     /**
1163      * This method clears the requested TLV list.
1164      *
1165      */
ClearRequestTlvs(void)1166     void ClearRequestTlvs(void) { memset(mRequestTlvs, Mle::Tlv::kInvalid, sizeof(mRequestTlvs)); }
1167 
1168     /**
1169      * This method returns the requested TLV at index @p aIndex.
1170      *
1171      * @param[in]  aIndex  The index into the requested TLV list.
1172      *
1173      * @returns The requested TLV at index @p aIndex.
1174      *
1175      */
GetRequestTlv(uint8_t aIndex) const1176     uint8_t GetRequestTlv(uint8_t aIndex) const { return mRequestTlvs[aIndex]; }
1177 
1178     /**
1179      * This method sets the requested TLV at index @p aIndex.
1180      *
1181      * @param[in]  aIndex  The index into the requested TLV list.
1182      * @param[in]  aType   The TLV type.
1183      *
1184      */
SetRequestTlv(uint8_t aIndex,uint8_t aType)1185     void SetRequestTlv(uint8_t aIndex, uint8_t aType) { mRequestTlvs[aIndex] = aType; }
1186 
1187 #if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE
1188 
1189     /**
1190      * This method increments the number of seconds since last supervision of the child.
1191      *
1192      */
IncrementSecondsSinceLastSupervision(void)1193     void IncrementSecondsSinceLastSupervision(void) { mSecondsSinceSupervision++; }
1194 
1195     /**
1196      * This method returns the number of seconds since last supervision of the child (last message to the child)
1197      *
1198      * @returns Number of seconds since last supervision of the child.
1199      *
1200      */
GetSecondsSinceLastSupervision(void) const1201     uint16_t GetSecondsSinceLastSupervision(void) const { return mSecondsSinceSupervision; }
1202 
1203     /**
1204      * This method resets the number of seconds since last supervision of the child to zero.
1205      *
1206      */
ResetSecondsSinceLastSupervision(void)1207     void ResetSecondsSinceLastSupervision(void) { mSecondsSinceSupervision = 0; }
1208 
1209 #endif // #if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE
1210 
1211 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
1212     /**
1213      * This method returns MLR state of an IPv6 multicast address.
1214      *
1215      * @note The @p aAdddress reference MUST be from `IterateIp6Addresses()` or `AddressIterator`.
1216      *
1217      * @param[in] aAddress  The IPv6 multicast address.
1218      *
1219      * @returns MLR state of the IPv6 multicast address.
1220      *
1221      */
1222     MlrState GetAddressMlrState(const Ip6::Address &aAddress) const;
1223 
1224     /**
1225      * This method sets MLR state of an IPv6 multicast address.
1226      *
1227      * @note The @p aAdddress reference MUST be from `IterateIp6Addresses()` or `AddressIterator`.
1228      *
1229      * @param[in] aAddress  The IPv6 multicast address.
1230      * @param[in] aState    The target MLR state.
1231      *
1232      */
1233     void SetAddressMlrState(const Ip6::Address &aAddress, MlrState aState);
1234 
1235     /**
1236      * This method returns if the Child has IPv6 address @p aAddress of MLR state `kMlrStateRegistered`.
1237      *
1238      * @param[in] aAddress  The IPv6 address.
1239      *
1240      * @retval true   If the Child has IPv6 address @p aAddress of MLR state `kMlrStateRegistered`.
1241      * @retval false  If the Child does not have IPv6 address @p aAddress of MLR state `kMlrStateRegistered`.
1242      *
1243      */
1244     bool HasMlrRegisteredAddress(const Ip6::Address &aAddress) const;
1245 
1246     /**
1247      * This method returns if the Child has any IPv6 address of MLR state `kMlrStateRegistered`.
1248      *
1249      * @retval true   If the Child has any IPv6 address of MLR state `kMlrStateRegistered`.
1250      * @retval false  If the Child does not have any IPv6 address of MLR state `kMlrStateRegistered`.
1251      *
1252      */
HasAnyMlrRegisteredAddress(void) const1253     bool HasAnyMlrRegisteredAddress(void) const { return mMlrRegisteredMask.HasAny(); }
1254 
1255     /**
1256      * This method returns if the Child has any IPv6 address of MLR state `kMlrStateToRegister`.
1257      *
1258      * @retval true   If the Child has any IPv6 address of MLR state `kMlrStateToRegister`.
1259      * @retval false  If the Child does not have any IPv6 address of MLR state `kMlrStateToRegister`.
1260      *
1261      */
HasAnyMlrToRegisterAddress(void) const1262     bool HasAnyMlrToRegisterAddress(void) const { return mMlrToRegisterMask.HasAny(); }
1263 #endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
1264 
1265 private:
1266 #if OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD < 2
1267 #error OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD should be at least set to 2.
1268 #endif
1269 
1270     static constexpr uint16_t kNumIp6Addresses = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD - 1;
1271 
1272     typedef BitVector<kNumIp6Addresses> ChildIp6AddressMask;
1273 
1274     class AddressIteratorBuilder
1275     {
1276     public:
AddressIteratorBuilder(const Child & aChild,Ip6::Address::TypeFilter aFilter)1277         AddressIteratorBuilder(const Child &aChild, Ip6::Address::TypeFilter aFilter)
1278             : mChild(aChild)
1279             , mFilter(aFilter)
1280         {
1281         }
1282 
begin(void)1283         AddressIterator begin(void) { return AddressIterator(mChild, mFilter); }
end(void)1284         AddressIterator end(void) { return AddressIterator(mChild, AddressIterator::kEndIterator); }
1285 
1286     private:
1287         const Child &            mChild;
1288         Ip6::Address::TypeFilter mFilter;
1289     };
1290 
1291     Ip6::InterfaceIdentifier mMeshLocalIid;                 ///< IPv6 address IID for mesh-local address
1292     Ip6::Address             mIp6Address[kNumIp6Addresses]; ///< Registered IPv6 addresses
1293     uint32_t                 mTimeout;                      ///< Child timeout
1294 
1295 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
1296     ChildIp6AddressMask mMlrToRegisterMask;
1297     ChildIp6AddressMask mMlrRegisteredMask;
1298 #endif
1299 
1300     uint8_t mNetworkDataVersion; ///< Current Network Data version
1301 
1302     union
1303     {
1304         uint8_t mRequestTlvs[kMaxRequestTlvs];            ///< Requested MLE TLVs
1305         uint8_t mAttachChallenge[Mle::kMaxChallengeSize]; ///< The challenge value
1306     };
1307 
1308 #if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE
1309     uint16_t mSecondsSinceSupervision; ///< Number of seconds since last supervision of the child.
1310 #endif
1311 
1312     static_assert(OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS < 8192, "mQueuedMessageCount cannot fit max required!");
1313 };
1314 
1315 #endif // OPENTHREAD_FTD
1316 
1317 /**
1318  * This class represents a Thread Router
1319  *
1320  */
1321 class Router : public Neighbor
1322 {
1323 public:
1324     /**
1325      * This class represents diagnostic information for a Thread Router.
1326      *
1327      */
1328     class Info : public otRouterInfo, public Clearable<Info>
1329     {
1330     public:
1331         /**
1332          * This method sets the `Info` instance from a given `Router`.
1333          *
1334          * @param[in] aRouter   A router.
1335          *
1336          */
1337         void SetFrom(const Router &aRouter);
1338     };
1339 
1340     /**
1341      * This method initializes the `Router` object.
1342      *
1343      * @param[in] aInstance  A reference to OpenThread instance.
1344      *
1345      */
Init(Instance & aInstance)1346     void Init(Instance &aInstance)
1347     {
1348         Neighbor::Init(aInstance);
1349 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1350         SetCslClockAccuracy(kCslWorstCrystalPpm);
1351         SetCslClockUncertainty(kCslWorstUncertainty);
1352 #endif
1353     }
1354 
1355     /**
1356      * This method clears the router entry.
1357      *
1358      */
1359     void Clear(void);
1360 
1361     /**
1362      * This method gets the router ID of the next hop to this router.
1363      *
1364      * @returns The router ID of the next hop to this router.
1365      *
1366      */
GetNextHop(void) const1367     uint8_t GetNextHop(void) const { return mNextHop; }
1368 
1369     /**
1370      * This method sets the router ID of the next hop to this router.
1371      *
1372      * @param[in]  aRouterId  The router ID of the next hop to this router.
1373      *
1374      */
SetNextHop(uint8_t aRouterId)1375     void SetNextHop(uint8_t aRouterId) { mNextHop = aRouterId; }
1376 
1377     /**
1378      * This method gets the link quality out value for this router.
1379      *
1380      * @returns The link quality out value for this router.
1381      *
1382      */
GetLinkQualityOut(void) const1383     uint8_t GetLinkQualityOut(void) const { return mLinkQualityOut; }
1384 
1385     /**
1386      * This method sets the link quality out value for this router.
1387      *
1388      * @param[in]  aLinkQuality  The link quality out value for this router.
1389      *
1390      */
SetLinkQualityOut(uint8_t aLinkQuality)1391     void SetLinkQualityOut(uint8_t aLinkQuality) { mLinkQualityOut = aLinkQuality; }
1392 
1393     /**
1394      * This method get the route cost to this router.
1395      *
1396      * @returns The route cost to this router.
1397      *
1398      */
GetCost(void) const1399     uint8_t GetCost(void) const { return mCost; }
1400 
1401     /**
1402      * This method sets the router cost to this router.
1403      *
1404      * @param[in]  aCost  The router cost to this router.
1405      *
1406      */
SetCost(uint8_t aCost)1407     void SetCost(uint8_t aCost) { mCost = aCost; }
1408 
1409 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1410     /**
1411      * This method get the CSL clock accuracy of this router.
1412      *
1413      * @returns The CSL clock accuracy of this router.
1414      *
1415      */
GetCslClockAccuracy(void) const1416     uint8_t GetCslClockAccuracy(void) const { return mCslClockAccuracy; }
1417 
1418     /**
1419      * This method sets the CSL clock accuracy of this router.
1420      *
1421      * @param[in]  aCost  The CSL clock accuracy of this router.
1422      *
1423      */
SetCslClockAccuracy(uint8_t aCslClockAccuracy)1424     void SetCslClockAccuracy(uint8_t aCslClockAccuracy) { mCslClockAccuracy = aCslClockAccuracy; }
1425 
1426     /**
1427      * This method get the CSL clock uncertainty of this router.
1428      *
1429      * @returns The CSL clock uncertainty of this router.
1430      *
1431      */
GetCslClockUncertainty(void) const1432     uint8_t GetCslClockUncertainty(void) const { return mCslClockUncertainty; }
1433 
1434     /**
1435      * This method sets the CSL clock uncertainty of this router.
1436      *
1437      * @param[in]  aCost  The CSL clock uncertainty of this router.
1438      *
1439      */
SetCslClockUncertainty(uint8_t aCslClockUncertainty)1440     void SetCslClockUncertainty(uint8_t aCslClockUncertainty) { mCslClockUncertainty = aCslClockUncertainty; }
1441 #endif
1442 
1443 private:
1444     uint8_t mNextHop;            ///< The next hop towards this router
1445     uint8_t mLinkQualityOut : 2; ///< The link quality out for this router
1446 
1447 #if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
1448     uint8_t mCost; ///< The cost to this router via neighbor router
1449 #else
1450     uint8_t mCost : 4;     ///< The cost to this router via neighbor router
1451 #endif
1452 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1453     uint8_t mCslClockAccuracy;    ///< Crystal accuracy, in units of ± ppm.
1454     uint8_t mCslClockUncertainty; ///< Scheduling uncertainty, in units of 10 us.
1455 #endif
1456 };
1457 
1458 } // namespace ot
1459 
1460 #endif // TOPOLOGY_HPP_
1461