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/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.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  * This class 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      * This enumeration 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      * This class 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          * This constructor 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          * This constructor 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          * This constructor initializes the `AddressMatcher` with a given MAC address and state filter.
150          *
151          * @param[in]  aMacAddress     A MAC address.
152          * @param[in]  aStateFilter    A state filter.
153          *
154          */
AddressMatcher(const Mac::Address & aMacAddress,StateFilter aStateFilter)155         AddressMatcher(const Mac::Address &aMacAddress, StateFilter aStateFilter)
156             : AddressMatcher(aStateFilter,
157                              aMacAddress.IsShort() ? aMacAddress.GetShort()
158                                                    : static_cast<Mac::ShortAddress>(Mac::kShortAddrInvalid),
159                              aMacAddress.IsExtended() ? &aMacAddress.GetExtended() : nullptr)
160         {
161         }
162 
163         /**
164          * This constructor initializes the `AddressMatcher` with a given state filter (it accepts any address).
165          *
166          * @param[in]  aStateFilter    A state filter.
167          *
168          */
AddressMatcher(StateFilter aStateFilter)169         explicit AddressMatcher(StateFilter aStateFilter)
170             : AddressMatcher(aStateFilter, Mac::kShortAddrInvalid, nullptr)
171         {
172         }
173 
174         /**
175          * This method indicates if a given neighbor matches the address and state filter of `AddressMatcher`.
176          *
177          * @param[in] aNeighbor   A neighbor.
178          *
179          * @retval TRUE   Neighbor @p aNeighbor matches the address and state filter.
180          * @retval FALSE  Neighbor @p aNeighbor does not match the address or state filter.
181          *
182          */
183         bool Matches(const Neighbor &aNeighbor) const;
184 
185     private:
AddressMatcher(StateFilter aStateFilter,Mac::ShortAddress aShortAddress,const Mac::ExtAddress * aExtAddress)186         AddressMatcher(StateFilter aStateFilter, Mac::ShortAddress aShortAddress, const Mac::ExtAddress *aExtAddress)
187             : mStateFilter(aStateFilter)
188             , mShortAddress(aShortAddress)
189             , mExtAddress(aExtAddress)
190         {
191         }
192 
193         StateFilter            mStateFilter;
194         Mac::ShortAddress      mShortAddress;
195         const Mac::ExtAddress *mExtAddress;
196     };
197 
198     /**
199      * This type represents diagnostic information for a neighboring node.
200      *
201      */
202     class Info : public otNeighborInfo, public Clearable<Info>
203     {
204     public:
205         /**
206          * This method sets the `Info` instance from a given `Neighbor`.
207          *
208          * @param[in] aNeighbor   A neighbor.
209          *
210          */
211         void SetFrom(const Neighbor &aNeighbor);
212     };
213 
214     /**
215      * This method returns the current state.
216      *
217      * @returns The current state.
218      *
219      */
GetState(void) const220     State GetState(void) const { return static_cast<State>(mState); }
221 
222     /**
223      * This method sets the current state.
224      *
225      * @param[in]  aState  The state value.
226      *
227      */
228     void SetState(State aState);
229 
230     /**
231      * This method indicates whether the neighbor is in the Invalid state.
232      *
233      * @returns TRUE if the neighbor is in the Invalid state, FALSE otherwise.
234      *
235      */
IsStateInvalid(void) const236     bool IsStateInvalid(void) const { return (mState == kStateInvalid); }
237 
238     /**
239      * This method indicates whether the neighbor is in the Child ID Request state.
240      *
241      * @returns TRUE if the neighbor is in the Child ID Request state, FALSE otherwise.
242      *
243      */
IsStateChildIdRequest(void) const244     bool IsStateChildIdRequest(void) const { return (mState == kStateChildIdRequest); }
245 
246     /**
247      * This method indicates whether the neighbor is in the Link Request state.
248      *
249      * @returns TRUE if the neighbor is in the Link Request state, FALSE otherwise.
250      *
251      */
IsStateLinkRequest(void) const252     bool IsStateLinkRequest(void) const { return (mState == kStateLinkRequest); }
253 
254     /**
255      * This method indicates whether the neighbor is in the Parent Response state.
256      *
257      * @returns TRUE if the neighbor is in the Parent Response state, FALSE otherwise.
258      *
259      */
IsStateParentResponse(void) const260     bool IsStateParentResponse(void) const { return (mState == kStateParentResponse); }
261 
262     /**
263      * This method indicates whether the neighbor is being restored.
264      *
265      * @returns TRUE if the neighbor is being restored, FALSE otherwise.
266      *
267      */
IsStateRestoring(void) const268     bool IsStateRestoring(void) const { return (mState == kStateRestored) || (mState == kStateChildUpdateRequest); }
269 
270     /**
271      * This method indicates whether the neighbor is in the Restored state.
272      *
273      * @returns TRUE if the neighbor is in the Restored state, FALSE otherwise.
274      *
275      */
IsStateRestored(void) const276     bool IsStateRestored(void) const { return (mState == kStateRestored); }
277 
278     /**
279      * This method indicates whether the neighbor is valid (frame counters are synchronized).
280      *
281      * @returns TRUE if the neighbor is valid, FALSE otherwise.
282      *
283      */
IsStateValid(void) const284     bool IsStateValid(void) const { return (mState == kStateValid); }
285 
286     /**
287      * This method indicates whether the neighbor is in valid state or if it is being restored.
288      *
289      * When in these states messages can be sent to and/or received from the neighbor.
290      *
291      * @returns TRUE if the neighbor is in valid, restored, or being restored states, FALSE otherwise.
292      *
293      */
IsStateValidOrRestoring(void) const294     bool IsStateValidOrRestoring(void) const { return (mState == kStateValid) || IsStateRestoring(); }
295 
296     /**
297      * This method indicates if the neighbor state is valid, attaching, or restored.
298      *
299      * The states `kStateRestored`, `kStateChildIdRequest`, `kStateChildUpdateRequest`, `kStateValid`, and
300      * `kStateLinkRequest` are considered as valid, attaching, or restored.
301      *
302      * @returns TRUE if the neighbor state is valid, attaching, or restored, FALSE otherwise.
303      *
304      */
305     bool IsStateValidOrAttaching(void) const;
306 
307     /**
308      * This method indicates whether neighbor state matches a given state filter.
309      *
310      * @param[in] aFilter   A state filter (`StateFilter` enumeration) to match against.
311      *
312      * @returns TRUE if the neighbor state matches the filter, FALSE otherwise.
313      *
314      */
315     bool MatchesFilter(StateFilter aFilter) const;
316 
317     /**
318      * This method indicates whether neighbor matches a given `AddressMatcher`.
319      *
320      * @param[in]  aMatcher   An `AddressMatcher` to match against.
321      *
322      * @returns TRUE if the neighbor matches the address and state filter of @p aMatcher, FALSE otherwise.
323      *
324      */
Matches(const AddressMatcher & aMatcher) const325     bool Matches(const AddressMatcher &aMatcher) const { return aMatcher.Matches(*this); }
326 
327     /**
328      * This method gets the device mode flags.
329      *
330      * @returns The device mode flags.
331      *
332      */
GetDeviceMode(void) const333     Mle::DeviceMode GetDeviceMode(void) const { return Mle::DeviceMode(mMode); }
334 
335     /**
336      * This method sets the device mode flags.
337      *
338      * @param[in]  aMode  The device mode flags.
339      *
340      */
SetDeviceMode(Mle::DeviceMode aMode)341     void SetDeviceMode(Mle::DeviceMode aMode) { mMode = aMode.Get(); }
342 
343     /**
344      * This method indicates whether or not the device is rx-on-when-idle.
345      *
346      * @returns TRUE if rx-on-when-idle, FALSE otherwise.
347      *
348      */
IsRxOnWhenIdle(void) const349     bool IsRxOnWhenIdle(void) const { return GetDeviceMode().IsRxOnWhenIdle(); }
350 
351     /**
352      * This method indicates whether or not the device is a Full Thread Device.
353      *
354      * @returns TRUE if a Full Thread Device, FALSE otherwise.
355      *
356      */
IsFullThreadDevice(void) const357     bool IsFullThreadDevice(void) const { return GetDeviceMode().IsFullThreadDevice(); }
358 
359     /**
360      * This method gets the Network Data type (full set or stable subset) that the device requests.
361      *
362      * @returns The Network Data type.
363      *
364      */
GetNetworkDataType(void) const365     NetworkData::Type GetNetworkDataType(void) const { return GetDeviceMode().GetNetworkDataType(); }
366 
367     /**
368      * This method returns the Extended Address.
369      *
370      * @returns A const reference to the Extended Address.
371      *
372      */
GetExtAddress(void) const373     const Mac::ExtAddress &GetExtAddress(void) const { return mMacAddr; }
374 
375     /**
376      * This method returns the Extended Address.
377      *
378      * @returns A reference to the Extended Address.
379      *
380      */
GetExtAddress(void)381     Mac::ExtAddress &GetExtAddress(void) { return mMacAddr; }
382 
383     /**
384      * This method sets the Extended Address.
385      *
386      * @param[in]  aAddress  The Extended Address value to set.
387      *
388      */
SetExtAddress(const Mac::ExtAddress & aAddress)389     void SetExtAddress(const Mac::ExtAddress &aAddress) { mMacAddr = aAddress; }
390 
391     /**
392      * This method gets the key sequence value.
393      *
394      * @returns The key sequence value.
395      *
396      */
GetKeySequence(void) const397     uint32_t GetKeySequence(void) const { return mKeySequence; }
398 
399     /**
400      * This method sets the key sequence value.
401      *
402      * @param[in]  aKeySequence  The key sequence value.
403      *
404      */
SetKeySequence(uint32_t aKeySequence)405     void SetKeySequence(uint32_t aKeySequence) { mKeySequence = aKeySequence; }
406 
407     /**
408      * This method returns the last heard time.
409      *
410      * @returns The last heard time.
411      *
412      */
GetLastHeard(void) const413     TimeMilli GetLastHeard(void) const { return mLastHeard; }
414 
415     /**
416      * This method sets the last heard time.
417      *
418      * @param[in]  aLastHeard  The last heard time.
419      *
420      */
SetLastHeard(TimeMilli aLastHeard)421     void SetLastHeard(TimeMilli aLastHeard) { mLastHeard = aLastHeard; }
422 
423     /**
424      * This method gets the link frame counters.
425      *
426      * @returns A reference to `Mac::LinkFrameCounters` containing link frame counter for all supported radio links.
427      *
428      */
GetLinkFrameCounters(void)429     Mac::LinkFrameCounters &GetLinkFrameCounters(void) { return mValidPending.mValid.mLinkFrameCounters; }
430 
431     /**
432      * This method gets the link frame counters.
433      *
434      * @returns A reference to `Mac::LinkFrameCounters` containing link frame counter for all supported radio links.
435      *
436      */
GetLinkFrameCounters(void) const437     const Mac::LinkFrameCounters &GetLinkFrameCounters(void) const { return mValidPending.mValid.mLinkFrameCounters; }
438 
439 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
440     /**
441      * This method gets the link ACK frame counter value.
442      *
443      * @returns The link ACK frame counter value.
444      *
445      */
GetLinkAckFrameCounter(void) const446     uint32_t GetLinkAckFrameCounter(void) const { return mValidPending.mValid.mLinkAckFrameCounter; }
447 #endif
448 
449     /**
450      * This method sets the link ACK frame counter value.
451      *
452      * @param[in]  aAckFrameCounter  The link ACK frame counter value.
453      *
454      */
SetLinkAckFrameCounter(uint32_t aAckFrameCounter)455     void SetLinkAckFrameCounter(uint32_t aAckFrameCounter)
456     {
457 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
458         mValidPending.mValid.mLinkAckFrameCounter = aAckFrameCounter;
459 #else
460         OT_UNUSED_VARIABLE(aAckFrameCounter);
461 #endif
462     }
463 
464     /**
465      * This method gets the MLE frame counter value.
466      *
467      * @returns The MLE frame counter value.
468      *
469      */
GetMleFrameCounter(void) const470     uint32_t GetMleFrameCounter(void) const { return mValidPending.mValid.mMleFrameCounter; }
471 
472     /**
473      * This method sets the MLE frame counter value.
474      *
475      * @param[in]  aFrameCounter  The MLE frame counter value.
476      *
477      */
SetMleFrameCounter(uint32_t aFrameCounter)478     void SetMleFrameCounter(uint32_t aFrameCounter) { mValidPending.mValid.mMleFrameCounter = aFrameCounter; }
479 
480     /**
481      * This method gets the RLOC16 value.
482      *
483      * @returns The RLOC16 value.
484      *
485      */
GetRloc16(void) const486     uint16_t GetRloc16(void) const { return mRloc16; }
487 
488     /**
489      * This method gets the Router ID value.
490      *
491      * @returns The Router ID value.
492      *
493      */
GetRouterId(void) const494     uint8_t GetRouterId(void) const { return mRloc16 >> Mle::kRouterIdOffset; }
495 
496     /**
497      * This method sets the RLOC16 value.
498      *
499      * @param[in]  aRloc16  The RLOC16 value.
500      *
501      */
SetRloc16(uint16_t aRloc16)502     void SetRloc16(uint16_t aRloc16) { mRloc16 = aRloc16; }
503 
504 #if OPENTHREAD_CONFIG_MULTI_RADIO
505     /**
506      * This method clears the last received fragment tag.
507      *
508      * The last received fragment tag is used for detect duplicate frames (received over different radios) when
509      * multi-radio feature is enabled.
510      *
511      */
ClearLastRxFragmentTag(void)512     void ClearLastRxFragmentTag(void) { mLastRxFragmentTag = 0; }
513 
514     /**
515      * This method gets the last received fragment tag.
516      *
517      * This method MUST be used only when the tag is set (and not cleared). Otherwise its behavior is undefined.
518      *
519      * @returns The last received fragment tag.
520      *
521      */
GetLastRxFragmentTag(void) const522     uint16_t GetLastRxFragmentTag(void) const { return mLastRxFragmentTag; }
523 
524     /**
525      * This method set the last received fragment tag.
526      *
527      * @param[in] aTag   The new tag value.
528      *
529      */
530     void SetLastRxFragmentTag(uint16_t aTag);
531 
532     /**
533      * This method indicates whether or not the last received fragment tag is set and valid (i.e., not yet timed out).
534      *
535      * @returns TRUE if the last received fragment tag is set and valid, FALSE otherwise.
536      *
537      */
538     bool IsLastRxFragmentTagSet(void) const;
539 
540     /**
541      * This method indicates whether the last received fragment tag is strictly after a given tag value.
542      *
543      * This method MUST be used only when the tag is set (and not cleared). Otherwise its behavior is undefined.
544      *
545      * The tag value compassion follows the Serial Number Arithmetic logic from RFC-1982. It is semantically equivalent
546      * to `LastRxFragmentTag > aTag`.
547      *
548      * @param[in] aTag   A tag value to compare against.
549      *
550      * @returns TRUE if the current last rx fragment tag is strictly after @p aTag, FALSE if they are equal or it is
551      * before @p aTag.
552      *
553      */
IsLastRxFragmentTagAfter(uint16_t aTag) const554     bool IsLastRxFragmentTagAfter(uint16_t aTag) const { return SerialNumber::IsGreater(mLastRxFragmentTag, aTag); }
555 
556 #endif // OPENTHREAD_CONFIG_MULTI_RADIO
557 
558     /**
559      * This method indicates whether or not it is Thread 1.1.
560      *
561      * @returns TRUE if neighbors is Thread 1.1, FALSE otherwise.
562      *
563      */
IsThreadVersion1p1(void) const564     bool IsThreadVersion1p1(void) const { return mState != kStateInvalid && mVersion == kThreadVersion1p1; }
565 
566     /**
567      * This method indicates whether or not neighbor is Thread 1.2 or higher..
568      *
569      * @returns TRUE if neighbor is Thread 1.2 or higher, FALSE otherwise.
570      *
571      */
IsThreadVersion1p2OrHigher(void) const572     bool IsThreadVersion1p2OrHigher(void) const { return mState != kStateInvalid && mVersion >= kThreadVersion1p2; }
573 
574     /**
575      * This method indicates whether Thread version supports CSL.
576      *
577      * @returns TRUE if CSL is supported, FALSE otherwise.
578      *
579      */
IsThreadVersionCslCapable(void) const580     bool IsThreadVersionCslCapable(void) const { return IsThreadVersion1p2OrHigher() && !IsRxOnWhenIdle(); }
581 
582     /**
583      * This method indicates whether Enhanced Keep-Alive is supported or not.
584      *
585      * @returns TRUE if Enhanced Keep-Alive is supported, FALSE otherwise.
586      *
587      */
IsEnhancedKeepAliveSupported(void) const588     bool IsEnhancedKeepAliveSupported(void) const
589     {
590         return (mState != kStateInvalid) && (mVersion >= kThreadVersion1p2);
591     }
592 
593     /**
594      * This method gets the device MLE version.
595      *
596      */
GetVersion(void) const597     uint16_t GetVersion(void) const { return mVersion; }
598 
599     /**
600      * This method sets the device MLE version.
601      *
602      * @param[in]  aVersion  The device MLE version.
603      *
604      */
SetVersion(uint16_t aVersion)605     void SetVersion(uint16_t aVersion) { mVersion = aVersion; }
606 
607     /**
608      * This method gets the number of consecutive link failures.
609      *
610      * @returns The number of consecutive link failures.
611      *
612      */
GetLinkFailures(void) const613     uint8_t GetLinkFailures(void) const { return mLinkFailures; }
614 
615     /**
616      * This method increments the number of consecutive link failures.
617      *
618      */
IncrementLinkFailures(void)619     void IncrementLinkFailures(void) { mLinkFailures++; }
620 
621     /**
622      * This method resets the number of consecutive link failures to zero.
623      *
624      */
ResetLinkFailures(void)625     void ResetLinkFailures(void) { mLinkFailures = 0; }
626 
627     /**
628      * This method returns the LinkQualityInfo object.
629      *
630      * @returns The LinkQualityInfo object.
631      *
632      */
GetLinkInfo(void)633     LinkQualityInfo &GetLinkInfo(void) { return mLinkInfo; }
634 
635     /**
636      * This method returns the LinkQualityInfo object.
637      *
638      * @returns The LinkQualityInfo object.
639      *
640      */
GetLinkInfo(void) const641     const LinkQualityInfo &GetLinkInfo(void) const { return mLinkInfo; }
642 
643     /**
644      * This method gets the link quality in value.
645      *
646      * @returns The link quality in value.
647      *
648      */
GetLinkQualityIn(void) const649     LinkQuality GetLinkQualityIn(void) const { return GetLinkInfo().GetLinkQuality(); }
650 
651     /**
652      * This method generates a new challenge value for MLE Link Request/Response exchanges.
653      *
654      */
655     void GenerateChallenge(void);
656 
657     /**
658      * This method returns the current challenge value for MLE Link Request/Response exchanges.
659      *
660      * @returns The current challenge value.
661      *
662      */
GetChallenge(void) const663     const uint8_t *GetChallenge(void) const { return mValidPending.mPending.mChallenge; }
664 
665     /**
666      * This method returns the size (bytes) of the challenge value for MLE Link Request/Response exchanges.
667      *
668      * @returns The size (bytes) of the challenge value for MLE Link Request/Response exchanges.
669      *
670      */
GetChallengeSize(void) const671     uint8_t GetChallengeSize(void) const { return sizeof(mValidPending.mPending.mChallenge); }
672 
673 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
674     /**
675      * This method returns the connection time (in seconds) of the neighbor (seconds since entering `kStateValid`).
676      *
677      * @returns The connection time (in seconds), zero if device is not currently in `kStateValid`.
678      *
679      */
680     uint32_t GetConnectionTime(void) const;
681 #endif
682 
683 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
684     /**
685      * This method indicates whether or not time sync feature is enabled.
686      *
687      * @returns TRUE if time sync feature is enabled, FALSE otherwise.
688      *
689      */
IsTimeSyncEnabled(void) const690     bool IsTimeSyncEnabled(void) const { return mTimeSyncEnabled; }
691 
692     /**
693      * This method sets whether or not time sync feature is enabled.
694      *
695      * @param[in]  aEnable    TRUE if time sync feature is enabled, FALSE otherwise.
696      *
697      */
SetTimeSyncEnabled(bool aEnabled)698     void SetTimeSyncEnabled(bool aEnabled) { mTimeSyncEnabled = aEnabled; }
699 #endif
700 
701 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
702     /**
703      * This method aggregates the Link Metrics data into all the series that is running for this neighbor.
704      *
705      * If a series wants to account frames of @p aFrameType, it would add count by 1 and aggregate @p aLqi and
706      * @p aRss into its averagers.
707      *
708      * @param[in] aSeriesId     Series ID for Link Probe. Should be `0` if this method is not called by Link Probe.
709      * @param[in] aFrameType    Type of the frame that carries Link Metrics data.
710      * @param[in] aLqi          The LQI value.
711      * @param[in] aRss          The Rss value.
712      *
713      */
714     void AggregateLinkMetrics(uint8_t aSeriesId, uint8_t aFrameType, uint8_t aLqi, int8_t aRss);
715 
716     /**
717      * This method adds a new LinkMetrics::SeriesInfo to the neighbor's list.
718      *
719      * @param[in]  aSeriesInfo  A reference to the new SeriesInfo.
720      *
721      */
722     void AddForwardTrackingSeriesInfo(LinkMetrics::SeriesInfo &aSeriesInfo);
723 
724     /**
725      * This method finds a specific LinkMetrics::SeriesInfo by Series ID.
726      *
727      * @param[in] aSeriesId    A reference to the Series ID.
728      *
729      * @returns The pointer to the LinkMetrics::SeriesInfo. `nullptr` if not found.
730      *
731      */
732     LinkMetrics::SeriesInfo *GetForwardTrackingSeriesInfo(const uint8_t &aSeriesId);
733 
734     /**
735      * This method removes a specific LinkMetrics::SeriesInfo by Series ID.
736      *
737      * @param[in] aSeriesId    A reference to the Series ID to remove.
738      *
739      * @returns The pointer to the LinkMetrics::SeriesInfo. `nullptr` if not found.
740      *
741      */
742     LinkMetrics::SeriesInfo *RemoveForwardTrackingSeriesInfo(const uint8_t &aSeriesId);
743 
744     /**
745      * This method removes all the Series and return the data structures to the Pool.
746      *
747      */
748     void RemoveAllForwardTrackingSeriesInfo(void);
749 
750     /**
751      * This method gets the Enh-ACK Probing metrics (this `Neighbor` object is the Probing Subject).
752      *
753      * @returns Enh-ACK Probing metrics configured.
754      *
755      */
GetEnhAckProbingMetrics(void) const756     const LinkMetrics::Metrics &GetEnhAckProbingMetrics(void) const { return mEnhAckProbingMetrics; }
757 
758     /**
759      * This method sets the Enh-ACK Probing metrics (this `Neighbor` object is the Probing Subject).
760      *
761      * @param[in]  aEnhAckProbingMetrics  The metrics value to set.
762      *
763      */
SetEnhAckProbingMetrics(const LinkMetrics::Metrics & aEnhAckProbingMetrics)764     void SetEnhAckProbingMetrics(const LinkMetrics::Metrics &aEnhAckProbingMetrics)
765     {
766         mEnhAckProbingMetrics = aEnhAckProbingMetrics;
767     }
768 
769     /**
770      * This method indicates if Enh-ACK Probing is configured and active for this `Neighbor` object.
771      *
772      * @retval TRUE   Enh-ACK Probing is configured and active for this `Neighbor`.
773      * @retval FALSE  Otherwise.
774      *
775      */
IsEnhAckProbingActive(void) const776     bool IsEnhAckProbingActive(void) const
777     {
778         return (mEnhAckProbingMetrics.mLqi != 0) || (mEnhAckProbingMetrics.mLinkMargin != 0) ||
779                (mEnhAckProbingMetrics.mRssi != 0);
780     }
781 #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
782 
783     /**
784      * This method converts a given `State` to a human-readable string.
785      *
786      * @param[in] aState   A neighbor state.
787      *
788      * @returns A string representation of given state.
789      *
790      */
791     static const char *StateToString(State aState);
792 
793 protected:
794     /**
795      * This method initializes the `Neighbor` object.
796      *
797      * @param[in] aInstance  A reference to OpenThread instance.
798      *
799      */
800     void Init(Instance &aInstance);
801 
802 private:
803     enum : uint32_t
804     {
805         kLastRxFragmentTagTimeout = OPENTHREAD_CONFIG_MULTI_RADIO_FRAG_TAG_TIMEOUT, ///< Frag tag timeout in msec.
806     };
807 
808     Mac::ExtAddress mMacAddr;   ///< The IEEE 802.15.4 Extended Address
809     TimeMilli       mLastHeard; ///< Time when last heard.
810     union
811     {
812         struct
813         {
814             Mac::LinkFrameCounters mLinkFrameCounters; ///< The Link Frame Counters
815             uint32_t               mMleFrameCounter;   ///< The MLE Frame Counter
816 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
817             uint32_t mLinkAckFrameCounter; ///< The Link Ack Frame Counter
818 #endif
819         } mValid;
820         struct
821         {
822             uint8_t mChallenge[Mle::kMaxChallengeSize]; ///< The challenge value
823         } mPending;
824     } mValidPending;
825 
826 #if OPENTHREAD_CONFIG_MULTI_RADIO
827     uint16_t  mLastRxFragmentTag;     ///< Last received fragment tag
828     TimeMilli mLastRxFragmentTagTime; ///< The time last fragment tag was received and set.
829 #endif
830 
831     uint32_t mKeySequence; ///< Current key sequence
832     uint16_t mRloc16;      ///< The RLOC16
833     uint8_t  mState : 4;   ///< The link state
834     uint8_t  mMode : 4;    ///< The MLE device mode
835 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
836     uint8_t mLinkFailures : 7;    ///< Consecutive link failure count
837     bool    mTimeSyncEnabled : 1; ///< Indicates whether or not time sync feature is enabled.
838 #else
839     uint8_t mLinkFailures; ///< Consecutive link failure count
840 #endif
841     uint16_t        mVersion;  ///< The MLE version
842     LinkQualityInfo mLinkInfo; ///< Link quality info (contains average RSS, link margin and link quality)
843 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
844     // A list of Link Metrics Forward Tracking Series that is being
845     // tracked for this neighbor. Note that this device is the
846     // Subject and this neighbor is the Initiator.
847     LinkedList<LinkMetrics::SeriesInfo> mLinkMetricsSeriesInfoList;
848 
849     // Metrics configured for Enh-ACK Based Probing at the Probing
850     // Subject (this neighbor). Note that this device is the Initiator
851     // and this neighbor is the Subject.
852     LinkMetrics::Metrics mEnhAckProbingMetrics;
853 #endif
854 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
855     uint32_t mConnectionStart;
856 #endif
857 };
858 
859 #if OPENTHREAD_FTD
860 
861 /**
862  * This class represents a Thread Child.
863  *
864  */
865 class Child : public Neighbor,
866               public IndirectSender::ChildInfo,
867               public DataPollHandler::ChildInfo
868 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
869     ,
870               public CslTxScheduler::ChildInfo
871 #endif
872 {
873     class AddressIteratorBuilder;
874 
875 public:
876     static constexpr uint8_t kMaxRequestTlvs = 6;
877 
878     /**
879      * This class represents diagnostic information for a Thread Child.
880      *
881      */
882     class Info : public otChildInfo, public Clearable<Info>
883     {
884     public:
885         /**
886          * This method sets the `Info` instance from a given `Child`.
887          *
888          * @param[in] aChild   A neighbor.
889          *
890          */
891         void SetFrom(const Child &aChild);
892     };
893 
894     /**
895      * This class defines an iterator used to go through IPv6 address entries of a child.
896      *
897      */
898     class AddressIterator : public Unequatable<AddressIterator>
899     {
900         friend class AddressIteratorBuilder;
901 
902     public:
903         /**
904          * This type represents an index indicating the current IPv6 address entry to which the iterator is pointing.
905          *
906          */
907         typedef otChildIp6AddressIterator Index;
908 
909         /**
910          * This constructor initializes the iterator associated with a given `Child` starting from beginning of the
911          * IPv6 address list.
912          *
913          * @param[in] aChild    A reference to a child entry.
914          * @param[in] aFilter   An IPv6 address type filter restricting iterator to certain type of addresses.
915          *
916          */
AddressIterator(const Child & aChild,Ip6::Address::TypeFilter aFilter=Ip6::Address::kTypeAny)917         explicit AddressIterator(const Child &aChild, Ip6::Address::TypeFilter aFilter = Ip6::Address::kTypeAny)
918             : AddressIterator(aChild, 0, aFilter)
919         {
920         }
921 
922         /**
923          * This constructor initializes the iterator associated with a given `Child` starting from a given index
924          *
925          * @param[in]  aChild   A reference to the child entry.
926          * @param[in]  aIndex   An index (`Index`) with which to initialize the iterator.
927          * @param[in]  aFilter  An IPv6 address type filter restricting iterator to certain type of addresses.
928          *
929          */
AddressIterator(const Child & aChild,Index aIndex,Ip6::Address::TypeFilter aFilter=Ip6::Address::kTypeAny)930         AddressIterator(const Child &aChild, Index aIndex, Ip6::Address::TypeFilter aFilter = Ip6::Address::kTypeAny)
931             : mChild(aChild)
932             , mFilter(aFilter)
933             , mIndex(aIndex)
934         {
935             Update();
936         }
937 
938         /**
939          * This method converts the iterator into an index.
940          *
941          * @returns An index corresponding to the iterator.
942          *
943          */
GetAsIndex(void) const944         Index GetAsIndex(void) const { return mIndex; }
945 
946         /**
947          * This method gets the iterator's associated `Child` entry.
948          *
949          * @returns The associated child entry.
950          *
951          */
GetChild(void) const952         const Child &GetChild(void) const { return mChild; }
953 
954         /**
955          * This method gets the current `Child` IPv6 Address to which the iterator is pointing.
956          *
957          * @returns  A pointer to the associated IPv6 Address, or `nullptr` if iterator is done.
958          *
959          */
960         const Ip6::Address *GetAddress(void) const;
961 
962         /**
963          * This method indicates whether the iterator has reached end of the list.
964          *
965          * @retval TRUE   There are no more entries in the list (reached end of the list).
966          * @retval FALSE  The current entry is valid.
967          *
968          */
IsDone(void) const969         bool IsDone(void) const { return (mIndex >= kMaxIndex); }
970 
971         /**
972          * This method overloads `++` operator (pre-increment) to advance the iterator.
973          *
974          * The iterator is moved to point to the next `Address` entry.  If there are no more `Ip6::Address` entries
975          * `IsDone()` returns `true`.
976          *
977          */
operator ++(void)978         void operator++(void) { mIndex++, Update(); }
979 
980         /**
981          * This method overloads `++` operator (post-increment) to advance the iterator.
982          *
983          * The iterator is moved to point to the next `Address` entry.  If there are no more `Ip6::Address` entries
984          *  `IsDone()` returns `true`.
985          *
986          */
operator ++(int)987         void operator++(int) { mIndex++, Update(); }
988 
989         /**
990          * This method overloads the `*` dereference operator and gets a reference to `Ip6::Address` to which the
991          * iterator is currently pointing.
992          *
993          * This method MUST be used when the iterator is not done (i.e., `IsDone()` returns `false`).
994          *
995          * @returns A reference to the `Ip6::Address` entry currently pointed by the iterator.
996          *
997          */
operator *(void) const998         const Ip6::Address &operator*(void) const { return *GetAddress(); }
999 
1000         /**
1001          * This method overloads operator `==` to evaluate whether or not two `Iterator` instances are equal.
1002          *
1003          * This method MUST be used when the two iterators are associated with the same `Child` entry.
1004          *
1005          * @param[in]  aOther  The other `Iterator` to compare with.
1006          *
1007          * @retval TRUE   If the two `Iterator` objects are equal.
1008          * @retval FALSE  If the two `Iterator` objects are not equal.
1009          *
1010          */
operator ==(const AddressIterator & aOther) const1011         bool operator==(const AddressIterator &aOther) const { return (mIndex == aOther.mIndex); }
1012 
1013     private:
1014         enum IteratorType : uint8_t
1015         {
1016             kEndIterator,
1017         };
1018 
1019         static constexpr uint16_t kMaxIndex = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD;
1020 
AddressIterator(const Child & aChild,IteratorType)1021         AddressIterator(const Child &aChild, IteratorType)
1022             : mChild(aChild)
1023             , mIndex(kMaxIndex)
1024         {
1025         }
1026 
1027         void Update(void);
1028 
1029         const Child             &mChild;
1030         Ip6::Address::TypeFilter mFilter;
1031         Index                    mIndex;
1032         Ip6::Address             mMeshLocalAddress;
1033     };
1034 
1035     /**
1036      * This method initializes the `Child` object.
1037      *
1038      * @param[in] aInstance  A reference to OpenThread instance.
1039      *
1040      */
Init(Instance & aInstance)1041     void Init(Instance &aInstance) { Neighbor::Init(aInstance); }
1042 
1043     /**
1044      * This method clears the child entry.
1045      *
1046      */
1047     void Clear(void);
1048 
1049     /**
1050      * This method clears the IPv6 address list for the child.
1051      *
1052      */
1053     void ClearIp6Addresses(void);
1054 
1055     /**
1056      * This method sets the device mode flags.
1057      *
1058      * @param[in]  aMode  The device mode flags.
1059      *
1060      */
1061     void SetDeviceMode(Mle::DeviceMode aMode);
1062 
1063     /**
1064      * This method gets the mesh-local IPv6 address.
1065      *
1066      * @param[out]   aAddress            A reference to an IPv6 address to provide address (if any).
1067      *
1068      * @retval kErrorNone      Successfully found the mesh-local address and updated @p aAddress.
1069      * @retval kErrorNotFound  No mesh-local IPv6 address in the IPv6 address list.
1070      *
1071      */
1072     Error GetMeshLocalIp6Address(Ip6::Address &aAddress) const;
1073 
1074     /**
1075      * This method returns the Mesh Local Interface Identifier.
1076      *
1077      * @returns The Mesh Local Interface Identifier.
1078      *
1079      */
GetMeshLocalIid(void) const1080     const Ip6::InterfaceIdentifier &GetMeshLocalIid(void) const { return mMeshLocalIid; }
1081 
1082     /**
1083      * This method enables range-based `for` loop iteration over all (or a subset of) IPv6 addresses.
1084      *
1085      * This method should be used as follows: to iterate over all addresses
1086      *
1087      *     for (const Ip6::Address &address : child.IterateIp6Addresses()) { ... }
1088      *
1089      * or to iterate over a subset of IPv6 addresses determined by a given address type filter
1090      *
1091      *     for (const Ip6::Address &address : child.IterateIp6Addresses(Ip6::Address::kTypeMulticast)) { ... }
1092      *
1093      * @param[in] aFilter  An IPv6 address type filter restricting iteration to certain type of addresses (default is
1094      *                     to accept any address type).
1095      *
1096      * @returns An IteratorBuilder instance.
1097      *
1098      */
IterateIp6Addresses(Ip6::Address::TypeFilter aFilter=Ip6::Address::kTypeAny) const1099     AddressIteratorBuilder IterateIp6Addresses(Ip6::Address::TypeFilter aFilter = Ip6::Address::kTypeAny) const
1100     {
1101         return AddressIteratorBuilder(*this, aFilter);
1102     }
1103 
1104     /**
1105      * This method adds an IPv6 address to the list.
1106      *
1107      * @param[in]  aAddress           A reference to IPv6 address to be added.
1108      *
1109      * @retval kErrorNone          Successfully added the new address.
1110      * @retval kErrorAlready       Address is already in the list.
1111      * @retval kErrorNoBufs        Already at maximum number of addresses. No entry available to add the new address.
1112      * @retval kErrorInvalidArgs   Address is invalid (it is the Unspecified Address).
1113      *
1114      */
1115     Error AddIp6Address(const Ip6::Address &aAddress);
1116 
1117     /**
1118      * This method removes an IPv6 address from the list.
1119      *
1120      * @param[in]  aAddress               A reference to IPv6 address to be removed.
1121      *
1122      * @retval kErrorNone             Successfully removed the address.
1123      * @retval kErrorNotFound         Address was not found in the list.
1124      * @retval kErrorInvalidArgs      Address is invalid (it is the Unspecified Address).
1125      *
1126      */
1127     Error RemoveIp6Address(const Ip6::Address &aAddress);
1128 
1129     /**
1130      * This method indicates whether an IPv6 address is in the list of IPv6 addresses of the child.
1131      *
1132      * @param[in]  aAddress   A reference to IPv6 address.
1133      *
1134      * @retval TRUE           The address exists on the list.
1135      * @retval FALSE          Address was not found in the list.
1136      *
1137      */
1138     bool HasIp6Address(const Ip6::Address &aAddress) const;
1139 
1140 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE
1141     /**
1142      * This method retrieves the Domain Unicast Address registered by the child.
1143      *
1144      * @returns A pointer to Domain Unicast Address registered by the child if there is.
1145      *
1146      */
1147     const Ip6::Address *GetDomainUnicastAddress(void) const;
1148 #endif
1149 
1150     /**
1151      * This method gets the child timeout.
1152      *
1153      * @returns The child timeout.
1154      *
1155      */
GetTimeout(void) const1156     uint32_t GetTimeout(void) const { return mTimeout; }
1157 
1158     /**
1159      * This method sets the child timeout.
1160      *
1161      * @param[in]  aTimeout  The child timeout.
1162      *
1163      */
SetTimeout(uint32_t aTimeout)1164     void SetTimeout(uint32_t aTimeout) { mTimeout = aTimeout; }
1165 
1166     /**
1167      * This method gets the network data version.
1168      *
1169      * @returns The network data version.
1170      *
1171      */
GetNetworkDataVersion(void) const1172     uint8_t GetNetworkDataVersion(void) const { return mNetworkDataVersion; }
1173 
1174     /**
1175      * This method sets the network data version.
1176      *
1177      * @param[in]  aVersion  The network data version.
1178      *
1179      */
SetNetworkDataVersion(uint8_t aVersion)1180     void SetNetworkDataVersion(uint8_t aVersion) { mNetworkDataVersion = aVersion; }
1181 
1182     /**
1183      * This method generates a new challenge value to use during a child attach.
1184      *
1185      */
1186     void GenerateChallenge(void);
1187 
1188     /**
1189      * This method gets the current challenge value used during attach.
1190      *
1191      * @returns The current challenge value.
1192      *
1193      */
GetChallenge(void) const1194     const uint8_t *GetChallenge(void) const { return mAttachChallenge; }
1195 
1196     /**
1197      * This method gets the challenge size (bytes) used during attach.
1198      *
1199      * @returns The challenge size (bytes).
1200      *
1201      */
GetChallengeSize(void) const1202     uint8_t GetChallengeSize(void) const { return sizeof(mAttachChallenge); }
1203 
1204     /**
1205      * This method clears the requested TLV list.
1206      *
1207      */
ClearRequestTlvs(void)1208     void ClearRequestTlvs(void) { memset(mRequestTlvs, Mle::Tlv::kInvalid, sizeof(mRequestTlvs)); }
1209 
1210     /**
1211      * This method returns the requested TLV at index @p aIndex.
1212      *
1213      * @param[in]  aIndex  The index into the requested TLV list.
1214      *
1215      * @returns The requested TLV at index @p aIndex.
1216      *
1217      */
GetRequestTlv(uint8_t aIndex) const1218     uint8_t GetRequestTlv(uint8_t aIndex) const { return mRequestTlvs[aIndex]; }
1219 
1220     /**
1221      * This method sets the requested TLV at index @p aIndex.
1222      *
1223      * @param[in]  aIndex  The index into the requested TLV list.
1224      * @param[in]  aType   The TLV type.
1225      *
1226      */
SetRequestTlv(uint8_t aIndex,uint8_t aType)1227     void SetRequestTlv(uint8_t aIndex, uint8_t aType) { mRequestTlvs[aIndex] = aType; }
1228 
1229     /**
1230      * This method returns the supervision interval (in seconds).
1231      *
1232      * @returns The supervision interval (in seconds).
1233      *
1234      */
GetSupervisionInterval(void) const1235     uint16_t GetSupervisionInterval(void) const { return mSupervisionInterval; }
1236 
1237     /**
1238      * This method sets the supervision interval.
1239      *
1240      * @param[in] aInterval  The supervision interval (in seconds).
1241      *
1242      */
SetSupervisionInterval(uint16_t aInterval)1243     void SetSupervisionInterval(uint16_t aInterval) { mSupervisionInterval = aInterval; }
1244 
1245     /**
1246      * This method increments the number of seconds since last supervision of the child.
1247      *
1248      */
IncrementSecondsSinceLastSupervision(void)1249     void IncrementSecondsSinceLastSupervision(void) { mSecondsSinceSupervision++; }
1250 
1251     /**
1252      * This method returns the number of seconds since last supervision of the child (last message to the child)
1253      *
1254      * @returns Number of seconds since last supervision of the child.
1255      *
1256      */
GetSecondsSinceLastSupervision(void) const1257     uint16_t GetSecondsSinceLastSupervision(void) const { return mSecondsSinceSupervision; }
1258 
1259     /**
1260      * This method resets the number of seconds since last supervision of the child to zero.
1261      *
1262      */
ResetSecondsSinceLastSupervision(void)1263     void ResetSecondsSinceLastSupervision(void) { mSecondsSinceSupervision = 0; }
1264 
1265 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
1266     /**
1267      * This method returns MLR state of an IPv6 multicast address.
1268      *
1269      * @note The @p aAddress reference MUST be from `IterateIp6Addresses()` or `AddressIterator`.
1270      *
1271      * @param[in] aAddress  The IPv6 multicast address.
1272      *
1273      * @returns MLR state of the IPv6 multicast address.
1274      *
1275      */
1276     MlrState GetAddressMlrState(const Ip6::Address &aAddress) const;
1277 
1278     /**
1279      * This method sets MLR state of an IPv6 multicast address.
1280      *
1281      * @note The @p aAddress reference MUST be from `IterateIp6Addresses()` or `AddressIterator`.
1282      *
1283      * @param[in] aAddress  The IPv6 multicast address.
1284      * @param[in] aState    The target MLR state.
1285      *
1286      */
1287     void SetAddressMlrState(const Ip6::Address &aAddress, MlrState aState);
1288 
1289     /**
1290      * This method returns if the Child has IPv6 address @p aAddress of MLR state `kMlrStateRegistered`.
1291      *
1292      * @param[in] aAddress  The IPv6 address.
1293      *
1294      * @retval true   If the Child has IPv6 address @p aAddress of MLR state `kMlrStateRegistered`.
1295      * @retval false  If the Child does not have IPv6 address @p aAddress of MLR state `kMlrStateRegistered`.
1296      *
1297      */
1298     bool HasMlrRegisteredAddress(const Ip6::Address &aAddress) const;
1299 
1300     /**
1301      * This method returns if the Child has any IPv6 address of MLR state `kMlrStateRegistered`.
1302      *
1303      * @retval true   If the Child has any IPv6 address of MLR state `kMlrStateRegistered`.
1304      * @retval false  If the Child does not have any IPv6 address of MLR state `kMlrStateRegistered`.
1305      *
1306      */
HasAnyMlrRegisteredAddress(void) const1307     bool HasAnyMlrRegisteredAddress(void) const { return mMlrRegisteredMask.HasAny(); }
1308 
1309     /**
1310      * This method returns if the Child has any IPv6 address of MLR state `kMlrStateToRegister`.
1311      *
1312      * @retval true   If the Child has any IPv6 address of MLR state `kMlrStateToRegister`.
1313      * @retval false  If the Child does not have any IPv6 address of MLR state `kMlrStateToRegister`.
1314      *
1315      */
HasAnyMlrToRegisterAddress(void) const1316     bool HasAnyMlrToRegisterAddress(void) const { return mMlrToRegisterMask.HasAny(); }
1317 #endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
1318 
1319 private:
1320 #if OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD < 2
1321 #error OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD should be at least set to 2.
1322 #endif
1323 
1324     static constexpr uint16_t kNumIp6Addresses = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD - 1;
1325 
1326     typedef BitVector<kNumIp6Addresses> ChildIp6AddressMask;
1327 
1328     class AddressIteratorBuilder
1329     {
1330     public:
AddressIteratorBuilder(const Child & aChild,Ip6::Address::TypeFilter aFilter)1331         AddressIteratorBuilder(const Child &aChild, Ip6::Address::TypeFilter aFilter)
1332             : mChild(aChild)
1333             , mFilter(aFilter)
1334         {
1335         }
1336 
begin(void)1337         AddressIterator begin(void) { return AddressIterator(mChild, mFilter); }
end(void)1338         AddressIterator end(void) { return AddressIterator(mChild, AddressIterator::kEndIterator); }
1339 
1340     private:
1341         const Child             &mChild;
1342         Ip6::Address::TypeFilter mFilter;
1343     };
1344 
1345     Ip6::InterfaceIdentifier mMeshLocalIid;                 ///< IPv6 address IID for mesh-local address
1346     Ip6::Address             mIp6Address[kNumIp6Addresses]; ///< Registered IPv6 addresses
1347     uint32_t                 mTimeout;                      ///< Child timeout
1348 
1349 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE
1350     ChildIp6AddressMask mMlrToRegisterMask;
1351     ChildIp6AddressMask mMlrRegisteredMask;
1352 #endif
1353 
1354     uint8_t mNetworkDataVersion; ///< Current Network Data version
1355 
1356     union
1357     {
1358         uint8_t mRequestTlvs[kMaxRequestTlvs];            ///< Requested MLE TLVs
1359         uint8_t mAttachChallenge[Mle::kMaxChallengeSize]; ///< The challenge value
1360     };
1361 
1362     uint16_t mSupervisionInterval;     // Supervision interval for the child (in sec).
1363     uint16_t mSecondsSinceSupervision; // Number of seconds since last supervision of the child.
1364 
1365     static_assert(OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS < 8192, "mQueuedMessageCount cannot fit max required!");
1366 };
1367 
1368 #endif // OPENTHREAD_FTD
1369 
1370 class Parent;
1371 
1372 /**
1373  * This class represents a Thread Router
1374  *
1375  */
1376 class Router : public Neighbor
1377 {
1378 public:
1379     /**
1380      * This class represents diagnostic information for a Thread Router.
1381      *
1382      */
1383     class Info : public otRouterInfo, public Clearable<Info>
1384     {
1385     public:
1386         /**
1387          * This method sets the `Info` instance from a given `Router`.
1388          *
1389          * @param[in] aRouter   A router.
1390          *
1391          */
1392         void SetFrom(const Router &aRouter);
1393 
1394         /**
1395          * This method sets the `Info` instance from a given `Parent`.
1396          *
1397          * @param[in] aParent   A parent.
1398          *
1399          */
1400         void SetFrom(const Parent &aParent);
1401     };
1402 
1403     /**
1404      * This method initializes the `Router` object.
1405      *
1406      * @param[in] aInstance  A reference to OpenThread instance.
1407      *
1408      */
Init(Instance & aInstance)1409     void Init(Instance &aInstance) { Neighbor::Init(aInstance); }
1410 
1411     /**
1412      * This method clears the router entry.
1413      *
1414      */
1415     void Clear(void);
1416 
1417     /**
1418      * This method sets the `Router` entry from a `Parent`
1419      *
1420      */
1421     void SetFrom(const Parent &aParent);
1422 
1423     /**
1424      * This method gets the router ID of the next hop to this router.
1425      *
1426      * @returns The router ID of the next hop to this router.
1427      *
1428      */
GetNextHop(void) const1429     uint8_t GetNextHop(void) const { return mNextHop; }
1430 
1431     /**
1432      * This method gets the link quality out value for this router.
1433      *
1434      * @returns The link quality out value for this router.
1435      *
1436      */
GetLinkQualityOut(void) const1437     LinkQuality GetLinkQualityOut(void) const { return static_cast<LinkQuality>(mLinkQualityOut); }
1438 
1439     /**
1440      * This method sets the link quality out value for this router.
1441      *
1442      * @param[in]  aLinkQuality  The link quality out value for this router.
1443      *
1444      */
SetLinkQualityOut(LinkQuality aLinkQuality)1445     void SetLinkQualityOut(LinkQuality aLinkQuality) { mLinkQualityOut = aLinkQuality; }
1446 
1447     /**
1448      * This method gets the two-way link quality value (minimum of link quality in and out).
1449      *
1450      * @returns The two-way link quality value.
1451      *
1452      */
1453     LinkQuality GetTwoWayLinkQuality(void) const;
1454 
1455     /**
1456      * This method get the route cost to this router.
1457      *
1458      * @returns The route cost to this router.
1459      *
1460      */
GetCost(void) const1461     uint8_t GetCost(void) const { return mCost; }
1462 
1463     /**
1464      * This method sets the next hop and cost to this router.
1465      *
1466      * @param[in]  aNextHop  The Router ID of the next hop to this router.
1467      * @param[in]  aCost     The cost to this router.
1468      *
1469      * @retval TRUE   If there was a change, i.e., @p aNextHop or @p aCost were different from their previous values.
1470      * @retval FALSE  If no change to next hop and cost values (new values are the same as before).
1471      *
1472      */
1473     bool SetNextHopAndCost(uint8_t aNextHop, uint8_t aCost);
1474 
1475     /**
1476      * This method sets the next hop to this router as invalid and clears the cost.
1477      *
1478      * @retval TRUE   If there was a change (next hop was valid before).
1479      * @retval FALSE  No change to next hop (next hop was invalid before).
1480      *
1481      */
1482     bool SetNextHopToInvalid(void);
1483 
1484 private:
1485     uint8_t mNextHop;            ///< The next hop towards this router
1486     uint8_t mLinkQualityOut : 2; ///< The link quality out for this router
1487 
1488 #if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
1489     uint8_t mCost; ///< The cost to this router via neighbor router
1490 #else
1491     uint8_t mCost : 4;     ///< The cost to this router via neighbor router
1492 #endif
1493 };
1494 
1495 /**
1496  * This class represent parent of a child node.
1497  *
1498  */
1499 class Parent : public Router
1500 {
1501 public:
1502     /**
1503      * This method initializes the `Parent`.
1504      *
1505      * @param[in] aInstance  A reference to OpenThread instance.
1506      *
1507      */
Init(Instance & aInstance)1508     void Init(Instance &aInstance)
1509     {
1510         Neighbor::Init(aInstance);
1511 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1512         mCslAccuracy.Init();
1513 #endif
1514     }
1515 
1516     /**
1517      * This method clears the parent entry.
1518      *
1519      */
1520     void Clear(void);
1521 
1522     /**
1523      * This method gets route cost from parent to leader.
1524      *
1525      * @returns The route cost from parent to leader
1526      *
1527      */
GetLeaderCost(void) const1528     uint8_t GetLeaderCost(void) const { return mLeaderCost; }
1529 
1530     /**
1531      * This method sets route cost from parent to leader.
1532      *
1533      * @param[in] aLaderConst  The route cost.
1534      *
1535      */
SetLeaderCost(uint8_t aLeaderCost)1536     void SetLeaderCost(uint8_t aLeaderCost) { mLeaderCost = aLeaderCost; }
1537 
1538 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1539     /**
1540      * This method gets the CSL accuracy (clock accuracy and uncertainty).
1541      *
1542      * @returns The CSL accuracy.
1543      *
1544      */
GetCslAccuracy(void) const1545     const Mac::CslAccuracy &GetCslAccuracy(void) const { return mCslAccuracy; }
1546 
1547     /**
1548      * This method sets CSL accuracy.
1549      *
1550      * @param[in] aCslAccuracy  The CSL accuracy.
1551      *
1552      */
SetCslAccuracy(const Mac::CslAccuracy & aCslAccuracy)1553     void SetCslAccuracy(const Mac::CslAccuracy &aCslAccuracy) { mCslAccuracy = aCslAccuracy; }
1554 #endif
1555 
1556 private:
1557     uint8_t mLeaderCost;
1558 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1559     Mac::CslAccuracy mCslAccuracy; // CSL accuracy (clock accuracy in ppm and uncertainty).
1560 #endif
1561 };
1562 
1563 DefineCoreType(otNeighborInfo, Neighbor::Info);
1564 #if OPENTHREAD_FTD
1565 DefineCoreType(otChildInfo, Child::Info);
1566 #endif
1567 DefineCoreType(otRouterInfo, Router::Info);
1568 
1569 } // namespace ot
1570 
1571 #endif // TOPOLOGY_HPP_
1572