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