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 MLE functionality required by the Thread Child, Router, and Leader roles.
32  */
33 
34 #ifndef MLE_HPP_
35 #define MLE_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "common/encoding.hpp"
40 #include "common/locator.hpp"
41 #include "common/non_copyable.hpp"
42 #include "common/notifier.hpp"
43 #include "common/timer.hpp"
44 #include "mac/mac.hpp"
45 #include "meshcop/joiner_router.hpp"
46 #include "meshcop/meshcop.hpp"
47 #include "net/udp6.hpp"
48 #include "thread/link_metrics.hpp"
49 #include "thread/link_metrics_tlvs.hpp"
50 #include "thread/mle_tlvs.hpp"
51 #include "thread/mle_types.hpp"
52 #include "thread/neighbor_table.hpp"
53 #include "thread/topology.hpp"
54 
55 namespace ot {
56 
57 /**
58  * @addtogroup core-mle MLE
59  *
60  * @brief
61  *   This module includes definitions for the MLE protocol.
62  *
63  * @{
64  *
65  * @defgroup core-mle-core Core
66  * @defgroup core-mle-router Router
67  * @defgroup core-mle-tlvs TLVs
68  *
69  * @}
70  */
71 
72 /**
73  * @namespace ot::Mle
74  *
75  * @brief
76  *   This namespace includes definitions for the MLE protocol.
77  */
78 
79 namespace Mle {
80 
81 /**
82  * @addtogroup core-mle-core
83  *
84  * @brief
85  *   This module includes definitions for MLE functionality required by the Thread Child, Router, and Leader roles.
86  *
87  * @{
88  *
89  */
90 
91 /**
92  * This class implements MLE functionality required by the Thread EndDevices, Router, and Leader roles.
93  *
94  */
95 class Mle : public InstanceLocator, private NonCopyable
96 {
97     friend class DiscoverScanner;
98     friend class ot::Notifier;
99 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
100     friend class ot::LinkMetrics::LinkMetrics;
101 #endif
102 
103 public:
104     /**
105      * This constructor initializes the MLE object.
106      *
107      * @param[in]  aInstance     A reference to the OpenThread instance.
108      *
109      */
110     explicit Mle(Instance &aInstance);
111 
112     /**
113      * This method enables MLE.
114      *
115      * @retval kErrorNone     Successfully enabled MLE.
116      * @retval kErrorAlready  MLE was already enabled.
117      *
118      */
119     Error Enable(void);
120 
121     /**
122      * This method disables MLE.
123      *
124      * @retval kErrorNone     Successfully disabled MLE.
125      *
126      */
127     Error Disable(void);
128 
129     /**
130      * This method starts the MLE protocol operation.
131      *
132      * @param[in]  aAnnounceAttach True if attach on the announced thread network with newer active timestamp,
133      *                             or False if not.
134      *
135      * @retval kErrorNone           Successfully started the protocol operation.
136      * @retval kErrorInvalidState   IPv6 interface is down or device is in raw-link mode.
137      *
138      */
139     Error Start(bool aAnnounceAttach);
140 
141     /**
142      * This method stops the MLE protocol operation.
143      *
144      * @param[in]  aClearNetworkDatasets  True to clear network datasets, False not.
145      *
146      */
147     void Stop(bool aClearNetworkDatasets);
148 
149     /**
150      * This method restores network information from non-volatile memory.
151      *
152      * @retval kErrorNone      Successfully restore the network information.
153      * @retval kErrorNotFound  There is no valid network information stored in non-volatile memory.
154      *
155      */
156     Error Restore(void);
157 
158     /**
159      * This method stores network information into non-volatile memory.
160      *
161      * @retval kErrorNone      Successfully store the network information.
162      * @retval kErrorNoBufs    Could not store the network information due to insufficient memory space.
163      *
164      */
165     Error Store(void);
166 
167     /**
168      * This method generates an MLE Announce message.
169      *
170      * @param[in]  aChannel        The channel to use when transmitting.
171      * @param[in]  aOrphanAnnounce To indicate if MLE Announce is sent from an orphan end device.
172      *
173      */
174     void SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce);
175 
176     /**
177      * This method causes the Thread interface to detach from the Thread network.
178      *
179      * @retval kErrorNone          Successfully detached from the Thread network.
180      * @retval kErrorInvalidState  MLE is Disabled.
181      *
182      */
183     Error BecomeDetached(void);
184 
185     /**
186      * This method causes the Thread interface to attempt an MLE attach.
187      *
188      * @param[in]  aMode  Indicates what partitions to attach to.
189      *
190      * @retval kErrorNone          Successfully began the attach process.
191      * @retval kErrorInvalidState  MLE is Disabled.
192      * @retval kErrorBusy          An attach process is in progress.
193      *
194      */
195     Error BecomeChild(AttachMode aMode);
196 
197     /**
198      * This method indicates whether or not the Thread device is attached to a Thread network.
199      *
200      * @retval TRUE   Attached to a Thread network.
201      * @retval FALSE  Not attached to a Thread network.
202      *
203      */
204     bool IsAttached(void) const;
205 
206     /**
207      * This method indicates whether device is currently attaching or not.
208      *
209      * Note that an already attached device may also be in attaching state. Examples of this include a leader/router
210      * trying to attach to a better partition, or a child trying to find a better parent (when feature
211      * `OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE` is enabled).
212      *
213      * @retval TRUE   Device is currently trying to attach.
214      * @retval FALSE  Device is not in middle of attach process.
215      *
216      */
IsAttaching(void) const217     bool IsAttaching(void) const { return (mAttachState != kAttachStateIdle); }
218 
219     /**
220      * This method returns the current Thread device role.
221      *
222      * @returns The current Thread device role.
223      *
224      */
GetRole(void) const225     DeviceRole GetRole(void) const { return mRole; }
226 
227     /**
228      * This method indicates whether device role is disabled.
229      *
230      * @retval TRUE   Device role is disabled.
231      * @retval FALSE  Device role is not disabled.
232      *
233      */
IsDisabled(void) const234     bool IsDisabled(void) const { return (mRole == kRoleDisabled); }
235 
236     /**
237      * This method indicates whether device role is detached.
238      *
239      * @retval TRUE   Device role is detached.
240      * @retval FALSE  Device role is not detached.
241      *
242      */
IsDetached(void) const243     bool IsDetached(void) const { return (mRole == kRoleDetached); }
244 
245     /**
246      * This method indicates whether device role is child.
247      *
248      * @retval TRUE   Device role is child.
249      * @retval FALSE  Device role is not child.
250      *
251      */
IsChild(void) const252     bool IsChild(void) const { return (mRole == kRoleChild); }
253 
254     /**
255      * This method indicates whether device role is router.
256      *
257      * @retval TRUE   Device role is router.
258      * @retval FALSE  Device role is not router.
259      *
260      */
IsRouter(void) const261     bool IsRouter(void) const { return (mRole == kRoleRouter); }
262 
263     /**
264      * This method indicates whether device role is leader.
265      *
266      * @retval TRUE   Device role is leader.
267      * @retval FALSE  Device role is not leader.
268      *
269      */
IsLeader(void) const270     bool IsLeader(void) const { return (mRole == kRoleLeader); }
271 
272     /**
273      * This method indicates whether device role is either router or leader.
274      *
275      * @retval TRUE   Device role is either router or leader.
276      * @retval FALSE  Device role is neither router nor leader.
277      *
278      */
279     bool IsRouterOrLeader(void) const;
280 
281     /**
282      * This method returns the Device Mode as reported in the Mode TLV.
283      *
284      * @returns The Device Mode as reported in the Mode TLV.
285      *
286      */
GetDeviceMode(void) const287     DeviceMode GetDeviceMode(void) const { return mDeviceMode; }
288 
289     /**
290      * This method sets the Device Mode as reported in the Mode TLV.
291      *
292      * @param[in]  aDeviceMode  The device mode to set.
293      *
294      * @retval kErrorNone         Successfully set the Mode TLV.
295      * @retval kErrorInvalidArgs  The mode combination specified in @p aMode is invalid.
296      *
297      */
298     Error SetDeviceMode(DeviceMode aDeviceMode);
299 
300     /**
301      * This method indicates whether or not the device is rx-on-when-idle.
302      *
303      * @returns TRUE if rx-on-when-idle, FALSE otherwise.
304      *
305      */
IsRxOnWhenIdle(void) const306     bool IsRxOnWhenIdle(void) const { return mDeviceMode.IsRxOnWhenIdle(); }
307 
308     /**
309      * This method indicates whether or not the device is a Full Thread Device.
310      *
311      * @returns TRUE if a Full Thread Device, FALSE otherwise.
312      *
313      */
IsFullThreadDevice(void) const314     bool IsFullThreadDevice(void) const { return mDeviceMode.IsFullThreadDevice(); }
315 
316     /**
317      * This method indicates whether or not the device requests Full Network Data.
318      *
319      * @returns TRUE if requests Full Network Data, FALSE otherwise.
320      *
321      */
IsFullNetworkData(void) const322     bool IsFullNetworkData(void) const { return mDeviceMode.IsFullNetworkData(); }
323 
324     /**
325      * This method indicates whether or not the device is a Minimal End Device.
326      *
327      * @returns TRUE if the device is a Minimal End Device, FALSE otherwise.
328      *
329      */
IsMinimalEndDevice(void) const330     bool IsMinimalEndDevice(void) const { return mDeviceMode.IsMinimalEndDevice(); }
331 
332     /**
333      * This method returns a pointer to the Mesh Local Prefix.
334      *
335      * @returns A reference to the Mesh Local Prefix.
336      *
337      */
GetMeshLocalPrefix(void) const338     const MeshLocalPrefix &GetMeshLocalPrefix(void) const
339     {
340         return static_cast<const MeshLocalPrefix &>(mMeshLocal16.GetAddress().GetPrefix());
341     }
342 
343     /**
344      * This method sets the Mesh Local Prefix.
345      *
346      * @param[in]  aMeshLocalPrefix  A reference to the Mesh Local Prefix.
347      *
348      */
349     void SetMeshLocalPrefix(const MeshLocalPrefix &aMeshLocalPrefix);
350 
351 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
352     /**
353      * This method sets the Mesh Local IID.
354      *
355      * Available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled.
356      *
357      * @param[in] aMlIid  The Mesh Local IID.
358      *
359      * @retval kErrorNone           Successfully configured Mesh Local IID.
360      * @retval kErrorInvalidState   If the Thread stack is already enabled.
361      *
362      */
363     Error SetMeshLocalIid(const Ip6::InterfaceIdentifier &aMlIid);
364 #endif
365 
366     /**
367      * This method applies the Mesh Local Prefix.
368      *
369      */
370     void ApplyMeshLocalPrefix(void);
371 
372     /**
373      * This method returns a reference to the Thread link-local address.
374      *
375      * The Thread link local address is derived using IEEE802.15.4 Extended Address as Interface Identifier.
376      *
377      * @returns A reference to the Thread link local address.
378      *
379      */
GetLinkLocalAddress(void) const380     const Ip6::Address &GetLinkLocalAddress(void) const { return mLinkLocal64.GetAddress(); }
381 
382     /**
383      * This method updates the link local address.
384      *
385      * Call this method when the IEEE 802.15.4 Extended Address has changed.
386      *
387      */
388     void UpdateLinkLocalAddress(void);
389 
390     /**
391      * This method returns a reference to the link-local all Thread nodes multicast address.
392      *
393      * @returns A reference to the link-local all Thread nodes multicast address.
394      *
395      */
GetLinkLocalAllThreadNodesAddress(void) const396     const Ip6::Address &GetLinkLocalAllThreadNodesAddress(void) const { return mLinkLocalAllThreadNodes.GetAddress(); }
397 
398     /**
399      * This method returns a reference to the realm-local all Thread nodes multicast address.
400      *
401      * @returns A reference to the realm-local all Thread nodes multicast address.
402      *
403      */
GetRealmLocalAllThreadNodesAddress(void) const404     const Ip6::Address &GetRealmLocalAllThreadNodesAddress(void) const
405     {
406         return mRealmLocalAllThreadNodes.GetAddress();
407     }
408 
409     /**
410      * This method gets the parent when operating in End Device mode.
411      *
412      * @returns A reference to the parent.
413      *
414      */
GetParent(void)415     Router &GetParent(void) { return mParent; }
416 
417     /**
418      * This method get the parent candidate.
419      *
420      * The parent candidate is valid when attempting to attach to a new parent.
421      *
422      */
GetParentCandidate(void)423     Router &GetParentCandidate(void) { return mParentCandidate; }
424 
425     /**
426      * This method indicates whether or not an IPv6 address is an RLOC.
427      *
428      * @retval TRUE   If @p aAddress is an RLOC.
429      * @retval FALSE  If @p aAddress is not an RLOC.
430      *
431      */
432     bool IsRoutingLocator(const Ip6::Address &aAddress) const;
433 
434     /**
435      * This method indicates whether or not an IPv6 address is an ALOC.
436      *
437      * @retval TRUE   If @p aAddress is an ALOC.
438      * @retval FALSE  If @p aAddress is not an ALOC.
439      *
440      */
441     bool IsAnycastLocator(const Ip6::Address &aAddress) const;
442 
443     /**
444      * This method indicates whether or not an IPv6 address is a Mesh Local Address.
445      *
446      * @retval TRUE   If @p aAddress is a Mesh Local Address.
447      * @retval FALSE  If @p aAddress is not a Mesh Local Address.
448      *
449      */
450     bool IsMeshLocalAddress(const Ip6::Address &aAddress) const;
451 
452     /**
453      * This method returns the MLE Timeout value.
454      *
455      * @returns The MLE Timeout value in seconds.
456      *
457      */
GetTimeout(void) const458     uint32_t GetTimeout(void) const { return mTimeout; }
459 
460     /**
461      * This method sets the MLE Timeout value.
462      *
463      * @param[in]  aTimeout  The Timeout value in seconds.
464      *
465      */
466     void SetTimeout(uint32_t aTimeout);
467 
468     /**
469      * This method returns the RLOC16 assigned to the Thread interface.
470      *
471      * @returns The RLOC16 assigned to the Thread interface.
472      *
473      */
474     uint16_t GetRloc16(void) const;
475 
476     /**
477      * This method returns a reference to the RLOC assigned to the Thread interface.
478      *
479      * @returns A reference to the RLOC assigned to the Thread interface.
480      *
481      */
GetMeshLocal16(void) const482     const Ip6::Address &GetMeshLocal16(void) const { return mMeshLocal16.GetAddress(); }
483 
484     /**
485      * This method returns a reference to the ML-EID assigned to the Thread interface.
486      *
487      * @returns A reference to the ML-EID assigned to the Thread interface.
488      *
489      */
GetMeshLocal64(void) const490     const Ip6::Address &GetMeshLocal64(void) const { return mMeshLocal64.GetAddress(); }
491 
492     /**
493      * This method returns the Router ID of the Leader.
494      *
495      * @returns The Router ID of the Leader.
496      *
497      */
GetLeaderId(void) const498     uint8_t GetLeaderId(void) const { return mLeaderData.GetLeaderRouterId(); }
499 
500     /**
501      * This method retrieves the Leader's RLOC.
502      *
503      * @param[out]  aAddress  A reference to the Leader's RLOC.
504      *
505      * @retval kErrorNone      Successfully retrieved the Leader's RLOC.
506      * @retval kErrorDetached  The Thread interface is not currently attached to a Thread Partition.
507      *
508      */
509     Error GetLeaderAddress(Ip6::Address &aAddress) const;
510 
511     /**
512      * This method retrieves the Leader's ALOC.
513      *
514      * @param[out]  aAddress  A reference to the Leader's ALOC.
515      *
516      * @retval kErrorNone      Successfully retrieved the Leader's ALOC.
517      * @retval kErrorDetached  The Thread interface is not currently attached to a Thread Partition.
518      *
519      */
GetLeaderAloc(Ip6::Address & aAddress) const520     Error GetLeaderAloc(Ip6::Address &aAddress) const { return GetLocatorAddress(aAddress, kAloc16Leader); }
521 
522     /**
523      * This method computes the Commissioner's ALOC.
524      *
525      * @param[out]  aAddress        A reference to the Commissioner's ALOC.
526      * @param[in]   aSessionId      Commissioner session id.
527      *
528      * @retval kErrorNone      Successfully retrieved the Commissioner's ALOC.
529      * @retval kErrorDetached  The Thread interface is not currently attached to a Thread Partition.
530      *
531      */
GetCommissionerAloc(Ip6::Address & aAddress,uint16_t aSessionId) const532     Error GetCommissionerAloc(Ip6::Address &aAddress, uint16_t aSessionId) const
533     {
534         return GetLocatorAddress(aAddress, CommissionerAloc16FromId(aSessionId));
535     }
536 
537     /**
538      * This method retrieves the Service ALOC for given Service ID.
539      *
540      * @param[in]   aServiceId Service ID to get ALOC for.
541      * @param[out]  aAddress   A reference to the Service ALOC.
542      *
543      * @retval kErrorNone      Successfully retrieved the Service ALOC.
544      * @retval kErrorDetached  The Thread interface is not currently attached to a Thread Partition.
545      *
546      */
547     Error GetServiceAloc(uint8_t aServiceId, Ip6::Address &aAddress) const;
548 
549     /**
550      * This method returns the most recently received Leader Data.
551      *
552      * @returns  A reference to the most recently received Leader Data.
553      *
554      */
555     const LeaderData &GetLeaderData(void);
556 
557     /**
558      * This method derives the Child ID from a given RLOC16.
559      *
560      * @param[in]  aRloc16  The RLOC16 value.
561      *
562      * @returns The Child ID portion of an RLOC16.
563      *
564      */
ChildIdFromRloc16(uint16_t aRloc16)565     static uint16_t ChildIdFromRloc16(uint16_t aRloc16) { return aRloc16 & kMaxChildId; }
566 
567     /**
568      * This method derives the Router ID portion from a given RLOC16.
569      *
570      * @param[in]  aRloc16  The RLOC16 value.
571      *
572      * @returns The Router ID portion of an RLOC16.
573      *
574      */
RouterIdFromRloc16(uint16_t aRloc16)575     static uint8_t RouterIdFromRloc16(uint16_t aRloc16) { return aRloc16 >> kRouterIdOffset; }
576 
577     /**
578      * This method returns whether the two RLOC16 have the same Router ID.
579      *
580      * @param[in]  aRloc16A  The first RLOC16 value.
581      * @param[in]  aRloc16B  The second RLOC16 value.
582      *
583      * @returns true if the two RLOC16 have the same Router ID, false otherwise.
584      *
585      */
RouterIdMatch(uint16_t aRloc16A,uint16_t aRloc16B)586     static bool RouterIdMatch(uint16_t aRloc16A, uint16_t aRloc16B)
587     {
588         return RouterIdFromRloc16(aRloc16A) == RouterIdFromRloc16(aRloc16B);
589     }
590 
591     /**
592      * This method returns the Service ID corresponding to a Service ALOC16.
593      *
594      * @param[in]  aAloc16  The Servicer ALOC16 value.
595      *
596      * @returns The Service ID corresponding to given ALOC16.
597      *
598      */
ServiceIdFromAloc(uint16_t aAloc16)599     static uint8_t ServiceIdFromAloc(uint16_t aAloc16) { return static_cast<uint8_t>(aAloc16 - kAloc16ServiceStart); }
600 
601     /**
602      * This method returns the Service Aloc corresponding to a Service ID.
603      *
604      * @param[in]  aServiceId  The Service ID value.
605      *
606      * @returns The Service ALOC16 corresponding to given ID.
607      *
608      */
ServiceAlocFromId(uint8_t aServiceId)609     static uint16_t ServiceAlocFromId(uint8_t aServiceId)
610     {
611         return static_cast<uint16_t>(aServiceId + kAloc16ServiceStart);
612     }
613 
614     /**
615      * This method returns the Commissioner Aloc corresponding to a Commissioner Session ID.
616      *
617      * @param[in]  aSessionId   The Commissioner Session ID value.
618      *
619      * @returns The Commissioner ALOC16 corresponding to given ID.
620      *
621      */
CommissionerAloc16FromId(uint16_t aSessionId)622     static uint16_t CommissionerAloc16FromId(uint16_t aSessionId)
623     {
624         return static_cast<uint16_t>((aSessionId & kAloc16CommissionerMask) + kAloc16CommissionerStart);
625     }
626 
627     /**
628      * This method derives RLOC16 from a given Router ID.
629      *
630      * @param[in]  aRouterId  The Router ID value.
631      *
632      * @returns The RLOC16 corresponding to the given Router ID.
633      *
634      */
Rloc16FromRouterId(uint8_t aRouterId)635     static uint16_t Rloc16FromRouterId(uint8_t aRouterId)
636     {
637         return static_cast<uint16_t>(aRouterId << kRouterIdOffset);
638     }
639 
640     /**
641      * This method indicates whether or not @p aRloc16 refers to an active router.
642      *
643      * @param[in]  aRloc16  The RLOC16 value.
644      *
645      * @retval TRUE   If @p aRloc16 refers to an active router.
646      * @retval FALSE  If @p aRloc16 does not refer to an active router.
647      *
648      */
IsActiveRouter(uint16_t aRloc16)649     static bool IsActiveRouter(uint16_t aRloc16) { return ChildIdFromRloc16(aRloc16) == 0; }
650 
651     /**
652      * This method returns a reference to the send queue.
653      *
654      * @returns A reference to the send queue.
655      *
656      */
GetMessageQueue(void) const657     const MessageQueue &GetMessageQueue(void) const { return mDelayedResponses; }
658 
659     /**
660      * This method frees multicast MLE Data Response from Delayed Message Queue if any.
661      *
662      */
663     void RemoveDelayedDataResponseMessage(void);
664 
665     /**
666      * This method converts a device role into a human-readable string.
667      *
668      */
669     static const char *RoleToString(DeviceRole aRole);
670 
671     /**
672      * This method gets the MLE counters.
673      *
674      * @returns A reference to the MLE counters.
675      *
676      */
GetCounters(void) const677     const otMleCounters &GetCounters(void) const { return mCounters; }
678 
679     /**
680      * This method resets the MLE counters.
681      *
682      */
ResetCounters(void)683     void ResetCounters(void) { memset(&mCounters, 0, sizeof(mCounters)); }
684 
685     /**
686      * This function registers the client callback that is called when processing an MLE Parent Response message.
687      *
688      * @param[in]  aCallback A pointer to a function that is called to deliver MLE Parent Response data.
689      * @param[in]  aContext  A pointer to application-specific context.
690      *
691      */
692     void RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCallback, void *aContext);
693 
694     /**
695      * This method requests MLE layer to prepare and send a shorter version of Child ID Request message by only
696      * including the mesh-local IPv6 address in the Address Registration TLV.
697      *
698      * This method should be called when a previous MLE Child ID Request message would require fragmentation at 6LoWPAN
699      * layer.
700      *
701      */
702     void RequestShorterChildIdRequest(void);
703 
704     /**
705      * This method gets the RLOC or ALOC of a given RLOC16 or ALOC16.
706      *
707      * @param[out]  aAddress  A reference to the RLOC or ALOC.
708      * @param[in]   aLocator  RLOC16 or ALOC16.
709      *
710      * @retval kErrorNone      If got the RLOC or ALOC successfully.
711      * @retval kErrorDetached  If device is detached.
712      *
713      */
714     Error GetLocatorAddress(Ip6::Address &aAddress, uint16_t aLocator) const;
715 
716     /**
717      * This method schedules a Child Update Request.
718      *
719      */
720     void ScheduleChildUpdateRequest(void);
721 
722     /*
723      * This method indicates whether or not the device has restored the network information from
724      * non-volatile settings after boot.
725      *
726      * @retval true  Successfully restored the network information.
727      * @retval false No valid network information was found.
728      *
729      */
HasRestored(void) const730     bool HasRestored(void) const { return mHasRestored; }
731 
732 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
733     /**
734      * This method gets the CSL timeout.
735      *
736      * @returns CSL timeout
737      *
738      */
GetCslTimeout(void) const739     uint32_t GetCslTimeout(void) const { return mCslTimeout; }
740 
741     /**
742      * This method sets the CSL timeout.
743      *
744      * @param[in]  aTimeout  The CSL timeout in seconds.
745      *
746      */
747     void SetCslTimeout(uint32_t aTimeout);
748 
749     /**
750      * This method calculates CSL metric of parent.
751      *
752      * @param[in] aCslClockAccuracy The CSL Clock Accuracy.
753      * @param[in] aCslUncertainty The CSL Uncertainty.
754      *
755      * @returns CSL metric.
756      */
757     uint64_t CalcParentCslMetric(uint8_t aCslClockAccuracy, uint8_t aCslUncertainty);
758 
759 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
760 
761 protected:
762     /**
763      * MLE Command Types.
764      *
765      */
766     enum Command : uint8_t
767     {
768         kCommandLinkRequest                   = 0,  ///< Link Request
769         kCommandLinkAccept                    = 1,  ///< Link Accept
770         kCommandLinkAcceptAndRequest          = 2,  ///< Link Accept and Reject
771         kCommandLinkReject                    = 3,  ///< Link Reject
772         kCommandAdvertisement                 = 4,  ///< Advertisement
773         kCommandUpdate                        = 5,  ///< Update
774         kCommandUpdateRequest                 = 6,  ///< Update Request
775         kCommandDataRequest                   = 7,  ///< Data Request
776         kCommandDataResponse                  = 8,  ///< Data Response
777         kCommandParentRequest                 = 9,  ///< Parent Request
778         kCommandParentResponse                = 10, ///< Parent Response
779         kCommandChildIdRequest                = 11, ///< Child ID Request
780         kCommandChildIdResponse               = 12, ///< Child ID Response
781         kCommandChildUpdateRequest            = 13, ///< Child Update Request
782         kCommandChildUpdateResponse           = 14, ///< Child Update Response
783         kCommandAnnounce                      = 15, ///< Announce
784         kCommandDiscoveryRequest              = 16, ///< Discovery Request
785         kCommandDiscoveryResponse             = 17, ///< Discovery Response
786         kCommandLinkMetricsManagementRequest  = 18, ///< Link Metrics Management Request
787         kCommandLinkMetricsManagementResponse = 19, ///< Link Metrics Management Response
788         kCommandLinkProbe                     = 20, ///< Link Probe
789         kCommandTimeSync                      = 99, ///< Time Sync (when OPENTHREAD_CONFIG_TIME_SYNC_ENABLE enabled)
790     };
791 
792     /**
793      * States during attach (when searching for a parent).
794      *
795      */
796     enum AttachState : uint8_t
797     {
798         kAttachStateIdle,                ///< Not currently searching for a parent.
799         kAttachStateProcessAnnounce,     ///< Waiting to process a received Announce (to switch channel/pan-id).
800         kAttachStateStart,               ///< Starting to look for a parent.
801         kAttachStateParentRequestRouter, ///< Searching for a Router to attach to.
802         kAttachStateParentRequestReed,   ///< Searching for Routers or REEDs to attach to.
803         kAttachStateAnnounce,            ///< Send Announce messages
804         kAttachStateChildIdRequest,      ///< Sending a Child ID Request message.
805     };
806 
807     /**
808      * States when reattaching network using stored dataset
809      *
810      */
811     enum ReattachState : uint8_t
812     {
813         kReattachStop    = 0, ///< Reattach process is disabled or finished
814         kReattachStart   = 1, ///< Start reattach process
815         kReattachActive  = 2, ///< Reattach using stored Active Dataset
816         kReattachPending = 3, ///< Reattach using stored Pending Dataset
817     };
818 
819     static constexpr uint16_t kMleMaxResponseDelay = 1000u; ///< Max delay before responding to a multicast request.
820 
821     /**
822      * This enumeration type is used in `AppendAddressRegistration()` to determine which addresses to include in the
823      * appended Address Registration TLV.
824      *
825      */
826     enum AddressRegistrationMode : uint8_t
827     {
828         kAppendAllAddresses,  ///< Append all addresses (unicast/multicast) in Address Registration TLV.
829         kAppendMeshLocalOnly, ///< Only append the Mesh Local (ML-EID) address in Address Registration TLV.
830     };
831 
832     /**
833      * This enumeration represents the message actions used in `Log()` methods.
834      *
835      */
836     enum MessageAction : uint8_t
837     {
838         kMessageSend,
839         kMessageReceive,
840         kMessageDelay,
841         kMessageRemoveDelayed,
842     };
843 
844     /**
845      * This enumeration represents message types used in `Log()` methods.
846      *
847      */
848     enum MessageType : uint8_t
849     {
850         kTypeAdvertisement,
851         kTypeAnnounce,
852         kTypeChildIdRequest,
853         kTypeChildIdRequestShort,
854         kTypeChildIdResponse,
855         kTypeChildUpdateRequestOfParent,
856         kTypeChildUpdateResponseOfParent,
857         kTypeDataRequest,
858         kTypeDataResponse,
859         kTypeDiscoveryRequest,
860         kTypeDiscoveryResponse,
861         kTypeGenericDelayed,
862         kTypeGenericUdp,
863         kTypeParentRequestToRouters,
864         kTypeParentRequestToRoutersReeds,
865         kTypeParentResponse,
866 #if OPENTHREAD_FTD
867         kTypeAddressRelease,
868         kTypeAddressReleaseReply,
869         kTypeAddressReply,
870         kTypeAddressSolicit,
871         kTypeChildUpdateRequestOfChild,
872         kTypeChildUpdateResponseOfChild,
873         kTypeChildUpdateResponseOfUnknownChild,
874         kTypeLinkAccept,
875         kTypeLinkAcceptAndRequest,
876         kTypeLinkReject,
877         kTypeLinkRequest,
878         kTypeParentRequest,
879 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
880         kTypeTimeSync,
881 #endif
882 #endif
883 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
884         kTypeLinkMetricsManagementRequest,
885         kTypeLinkMetricsManagementResponse,
886         kTypeLinkProbe,
887 #endif
888     };
889 
890     /**
891      * This type represents a Challenge (or Response) data.
892      *
893      */
894     struct Challenge
895     {
896         uint8_t mBuffer[kMaxChallengeSize]; ///< Buffer containing the challenge/response byte sequence.
897         uint8_t mLength;                    ///< Challenge length (in bytes).
898 
899         /**
900          * This method generates a cryptographically secure random sequence to populate the challenge data.
901          *
902          */
903         void GenerateRandom(void);
904 
905         /**
906          * This method indicates whether the Challenge matches a given buffer.
907          *
908          * @param[in] aBuffer   A pointer to a buffer to compare with the Challenge.
909          * @param[in] aLength   Length of @p aBuffer (in bytes).
910          *
911          * @retval TRUE  If the Challenge matches the given buffer.
912          * @retval FALSE If the Challenge does not match the given buffer.
913          *
914          */
915         bool Matches(const uint8_t *aBuffer, uint8_t aLength) const;
916 
917         /**
918          * This method indicates whether two Challenge data byte sequences are equal or not.
919          *
920          * @param[in] aOther   Another Challenge data to compare.
921          *
922          * @retval TRUE  If the two Challenges match.
923          * @retval FALSE If the two Challenges do not match.
924          *
925          */
operator ==ot::Mle::Mle::Challenge926         bool operator==(const Challenge &aOther) const { return Matches(aOther.mBuffer, aOther.mLength); }
927     };
928 
929     /**
930      * This type represents list of requested TLVs in a TLV Request TLV.
931      *
932      */
933     struct RequestedTlvs
934     {
935         static constexpr uint8_t kMaxNumTlvs = 16; ///< Maximum number of TLVs in request array.
936 
937         uint8_t mTlvs[kMaxNumTlvs]; ///< Array of requested TLVs.
938         uint8_t mNumTlvs;           ///< Number of TLVs in the array.
939     };
940 
941     /**
942      * This method allocates a new message buffer for preparing an MLE message.
943      *
944      * @returns A pointer to the message or nullptr if insufficient message buffers are available.
945      *
946      */
947     Message *NewMleMessage(void);
948 
949     /**
950      * This method sets the device role.
951      *
952      * @param[in] aRole A device role.
953      *
954      */
955     void SetRole(DeviceRole aRole);
956 
957     /**
958      * This method sets the attach state
959      *
960      * @param[in] aState An attach state
961      *
962      */
963     void SetAttachState(AttachState aState);
964 
965     /**
966      * This method appends an MLE header to a message.
967      *
968      * @param[in]  aMessage  A reference to the message.
969      * @param[in]  aCommand  The MLE Command Type.
970      *
971      * @retval kErrorNone    Successfully appended the header.
972      * @retval kErrorNoBufs  Insufficient buffers available to append the header.
973      *
974      */
975     Error AppendHeader(Message &aMessage, Command aCommand);
976 
977     /**
978      * This method appends a Source Address TLV to a message.
979      *
980      * @param[in]  aMessage  A reference to the message.
981      *
982      * @retval kErrorNone    Successfully appended the Source Address TLV.
983      * @retval kErrorNoBufs  Insufficient buffers available to append the Source Address TLV.
984      *
985      */
986     Error AppendSourceAddress(Message &aMessage) const;
987 
988     /**
989      * This method appends a Mode TLV to a message.
990      *
991      * @param[in]  aMessage  A reference to the message.
992      * @param[in]  aMode     The Device Mode.
993      *
994      * @retval kErrorNone    Successfully appended the Mode TLV.
995      * @retval kErrorNoBufs  Insufficient buffers available to append the Mode TLV.
996      *
997      */
998     Error AppendMode(Message &aMessage, DeviceMode aMode);
999 
1000     /**
1001      * This method appends a Timeout TLV to a message.
1002      *
1003      * @param[in]  aMessage  A reference to the message.
1004      * @param[in]  aTimeout  The Timeout value.
1005      *
1006      * @retval kErrorNone    Successfully appended the Timeout TLV.
1007      * @retval kErrorNoBufs  Insufficient buffers available to append the Timeout TLV.
1008      *
1009      */
1010     Error AppendTimeout(Message &aMessage, uint32_t aTimeout);
1011 
1012     /**
1013      * This method appends a Challenge TLV to a message.
1014      *
1015      * @param[in]  aMessage          A reference to the message.
1016      * @param[in]  aChallenge        A pointer to the Challenge value.
1017      * @param[in]  aChallengeLength  The length of the Challenge value in bytes.
1018      *
1019      * @retval kErrorNone    Successfully appended the Challenge TLV.
1020      * @retval kErrorNoBufs  Insufficient buffers available to append the Challenge TLV.
1021      *
1022      */
1023     Error AppendChallenge(Message &aMessage, const uint8_t *aChallenge, uint8_t aChallengeLength);
1024 
1025     /**
1026      * This method appends a Challenge TLV to a message.
1027      *
1028      * @param[in]  aMessage          A reference to the message.
1029      * @param[in]  aChallenge        A reference to the Challenge data.
1030      *
1031      * @retval kErrorNone    Successfully appended the Challenge TLV.
1032      * @retval kErrorNoBufs  Insufficient buffers available to append the Challenge TLV.
1033      *
1034      */
1035     Error AppendChallenge(Message &aMessage, const Challenge &aChallenge);
1036 
1037     /**
1038      * This method reads Challenge TLV from a message.
1039      *
1040      * @param[in]  aMessage          A reference to the message.
1041      * @param[out] aChallenge        A reference to the Challenge data where to output the read value.
1042      *
1043      * @retval kErrorNone       Successfully read the Challenge TLV.
1044      * @retval kErrorNotFound   Challenge TLV was not found in the message.
1045      * @retval kErrorParse      Challenge TLV was found but could not be parsed.
1046      *
1047      */
1048     Error ReadChallenge(const Message &aMessage, Challenge &aChallenge);
1049 
1050     /**
1051      * This method appends a Response TLV to a message.
1052      *
1053      * @param[in]  aMessage         A reference to the message.
1054      * @param[in]  aResponse        A reference to the Response data.
1055      *
1056      * @retval kErrorNone    Successfully appended the Response TLV.
1057      * @retval kErrorNoBufs  Insufficient buffers available to append the Response TLV.
1058      *
1059      */
1060     Error AppendResponse(Message &aMessage, const Challenge &aResponse);
1061 
1062     /**
1063      * This method reads Response TLV from a message.
1064      *
1065      * @param[in]  aMessage         A reference to the message.
1066      * @param[out] aResponse        A reference to the Response data where to output the read value.
1067      *
1068      * @retval kErrorNone       Successfully read the Response TLV.
1069      * @retval kErrorNotFound   Response TLV was not found in the message.
1070      * @retval kErrorParse      Response TLV was found but could not be parsed.
1071      *
1072      */
1073     Error ReadResponse(const Message &aMessage, Challenge &aResponse);
1074 
1075     /**
1076      * This method appends a Link Frame Counter TLV to a message.
1077      *
1078      * @param[in]  aMessage  A reference to the message.
1079      *
1080      * @retval kErrorNone     Successfully appended the Link Frame Counter TLV.
1081      * @retval kErrorNoBufs   Insufficient buffers available to append the Link Frame Counter TLV.
1082      *
1083      */
1084     Error AppendLinkFrameCounter(Message &aMessage);
1085 
1086     /**
1087      * This method reads Link and MLE Frame Counters from a message.
1088      *
1089      * Link Frame Counter TLV must be present in the message and its value is read into @p aLinkFrameCounter. If MLE
1090      * Frame Counter TLV is present in the message, its value is read into @p aMleFrameCounter. If the MLE Frame
1091      * Counter TLV is not present in the message, then @p aMleFrameCounter is set to same value as @p aLinkFrameCounter.
1092      *
1093      * @param[in]  aMesssage           A reference to the message to read from.
1094      * @param[out] aLinkFrameCounter   A reference to an `uint32_t` to output the Link Frame Counter.
1095      * @param[out] aMleFrameCounter    A reference to an `uint32_t` to output the MLE Frame Counter.
1096      *
1097      * @retval kErrorNone       Successfully read the counters.
1098      * @retval kErrorNotFound   Link Frame Counter TLV was not found in the message.
1099      * @retval kErrorParse      TLVs are not well-formed.
1100      *
1101      */
1102     Error ReadFrameCounters(const Message &aMessage, uint32_t &aLinkFrameCounter, uint32_t &aMleFrameCounter) const;
1103 
1104     /**
1105      * This method appends an MLE Frame Counter TLV to a message.
1106      *
1107      * @param[in]  aMessage  A reference to the message.
1108      *
1109      * @retval kErrorNone     Successfully appended the Frame Counter TLV.
1110      * @retval kErrorNoBufs   Insufficient buffers available to append the MLE Frame Counter TLV.
1111      *
1112      */
1113     Error AppendMleFrameCounter(Message &aMessage);
1114 
1115     /**
1116      * This method appends an Address16 TLV to a message.
1117      *
1118      * @param[in]  aMessage  A reference to the message.
1119      * @param[in]  aRloc16   The RLOC16 value.
1120      *
1121      * @retval kErrorNone     Successfully appended the Address16 TLV.
1122      * @retval kErrorNoBufs   Insufficient buffers available to append the Address16 TLV.
1123      *
1124      */
1125     Error AppendAddress16(Message &aMessage, uint16_t aRloc16);
1126 
1127     /**
1128      * This method appends a Network Data TLV to the message.
1129      *
1130      * @param[in]  aMessage     A reference to the message.
1131      * @param[in]  aStableOnly  TRUE to append stable data, FALSE otherwise.
1132      *
1133      * @retval kErrorNone     Successfully appended the Network Data TLV.
1134      * @retval kErrorNoBufs   Insufficient buffers available to append the Network Data TLV.
1135      *
1136      */
1137     Error AppendNetworkData(Message &aMessage, bool aStableOnly);
1138 
1139     /**
1140      * This method appends a TLV Request TLV to a message.
1141      *
1142      * @param[in]  aMessage     A reference to the message.
1143      * @param[in]  aTlvs        A pointer to the list of TLV types.
1144      * @param[in]  aTlvsLength  The number of TLV types in @p aTlvs
1145      *
1146      * @retval kErrorNone     Successfully appended the TLV Request TLV.
1147      * @retval kErrorNoBufs   Insufficient buffers available to append the TLV Request TLV.
1148      *
1149      */
1150     Error AppendTlvRequest(Message &aMessage, const uint8_t *aTlvs, uint8_t aTlvsLength);
1151 
1152     /**
1153      * This method reads TLV Request TLV from a message.
1154      *
1155      * @param[in]  aMessage         A reference to the message.
1156      * @param[out] aRequestedTlvs   A reference to output the read list of requested TLVs.
1157      *
1158      * @retval kErrorNone       Successfully read the TLV.
1159      * @retval kErrorNotFound   TLV was not found in the message.
1160      * @retval kErrorParse      TLV was found but could not be parsed.
1161      *
1162      */
1163     Error FindTlvRequest(const Message &aMessage, RequestedTlvs &aRequestedTlvs);
1164 
1165     /**
1166      * This method appends a Leader Data TLV to a message.
1167      *
1168      * @param[in]  aMessage  A reference to the message.
1169      *
1170      * @retval kErrorNone     Successfully appended the Leader Data TLV.
1171      * @retval kErrorNoBufs   Insufficient buffers available to append the Leader Data TLV.
1172      *
1173      */
1174     Error AppendLeaderData(Message &aMessage);
1175 
1176     /**
1177      * This method reads Leader Data TLV from a message.
1178      *
1179      * @param[in]  aMessage        A reference to the message.
1180      * @param[out] aLeaderData     A reference to output the Leader Data.
1181      *
1182      * @retval kErrorNone       Successfully read the TLV.
1183      * @retval kErrorNotFound   TLV was not found in the message.
1184      * @retval kErrorParse      TLV was found but could not be parsed.
1185      *
1186      */
1187     Error ReadLeaderData(const Message &aMessage, LeaderData &aLeaderData);
1188 
1189     /**
1190      * This method appends a Scan Mask TLV to a message.
1191      *
1192      * @param[in]  aMessage   A reference to the message.
1193      * @param[in]  aScanMask  The Scan Mask value.
1194      *
1195      * @retval kErrorNone     Successfully appended the Scan Mask TLV.
1196      * @retval kErrorNoBufs   Insufficient buffers available to append the Scan Mask TLV.
1197      *
1198      */
1199     Error AppendScanMask(Message &aMessage, uint8_t aScanMask);
1200 
1201     /**
1202      * This method appends a Status TLV to a message.
1203      *
1204      * @param[in]  aMessage  A reference to the message.
1205      * @param[in]  aStatus   The Status value.
1206      *
1207      * @retval kErrorNone     Successfully appended the Status TLV.
1208      * @retval kErrorNoBufs   Insufficient buffers available to append the Status TLV.
1209      *
1210      */
1211     Error AppendStatus(Message &aMessage, StatusTlv::Status aStatus);
1212 
1213     /**
1214      * This method appends a Link Margin TLV to a message.
1215      *
1216      * @param[in]  aMessage     A reference to the message.
1217      * @param[in]  aLinkMargin  The Link Margin value.
1218      *
1219      * @retval kErrorNone     Successfully appended the Link Margin TLV.
1220      * @retval kErrorNoBufs   Insufficient buffers available to append the Link Margin TLV.
1221      *
1222      */
1223     Error AppendLinkMargin(Message &aMessage, uint8_t aLinkMargin);
1224 
1225     /**
1226      * This method appends a Version TLV to a message.
1227      *
1228      * @param[in]  aMessage  A reference to the message.
1229      *
1230      * @retval kErrorNone     Successfully appended the Version TLV.
1231      * @retval kErrorNoBufs   Insufficient buffers available to append the Version TLV.
1232      *
1233      */
1234     Error AppendVersion(Message &aMessage);
1235 
1236     /**
1237      * This method appends an Address Registration TLV to a message.
1238      *
1239      * @param[in]  aMessage  A reference to the message.
1240      * @param[in]  aMode     Determines which addresses to include in the TLV (see `AddressRegistrationMode`).
1241      *
1242      * @retval kErrorNone     Successfully appended the Address Registration TLV.
1243      * @retval kErrorNoBufs   Insufficient buffers available to append the Address Registration TLV.
1244      *
1245      */
1246     Error AppendAddressRegistration(Message &aMessage, AddressRegistrationMode aMode = kAppendAllAddresses);
1247 
1248 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1249     /**
1250      * This method appends a Time Request TLV to a message.
1251      *
1252      * @param[in]  aMessage  A reference to the message.
1253      *
1254      * @retval kErrorNone     Successfully appended the Time Request TLV.
1255      * @retval kErrorNoBufs   Insufficient buffers available to append the Time Request TLV.
1256      *
1257      */
1258     Error AppendTimeRequest(Message &aMessage);
1259 
1260     /**
1261      * This method appends a Time Parameter TLV to a message.
1262      *
1263      * @param[in]  aMessage  A reference to the message.
1264      *
1265      * @retval kErrorNone     Successfully appended the Time Parameter TLV.
1266      * @retval kErrorNoBufs   Insufficient buffers available to append the Time Parameter TLV.
1267      *
1268      */
1269     Error AppendTimeParameter(Message &aMessage);
1270 
1271     /**
1272      * This method appends a XTAL Accuracy TLV to a message.
1273      *
1274      * @param[in]  aMessage  A reference to the message.
1275      *
1276      * @retval kErrorNone     Successfully appended the XTAL Accuracy TLV.
1277      * @retval kErrorNoBufs   Insufficient buffers available to append the XTAl Accuracy TLV.
1278      *
1279      */
1280     Error AppendXtalAccuracy(Message &aMessage);
1281 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1282 
1283 #if (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE) || OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1284     /**
1285      * This method appends a CSL Channel TLV to a message.
1286      *
1287      * @param[in]  aMessage  A reference to the message.
1288      *
1289      * @retval kErrorNone     Successfully appended the CSL Channel TLV.
1290      * @retval kErrorNoBufs   Insufficient buffers available to append the CSL Channel TLV.
1291      *
1292      */
1293     Error AppendCslChannel(Message &aMessage);
1294 
1295     /**
1296      * This method appends a CSL Sync Timeout TLV to a message.
1297      *
1298      * @param[in]  aMessage  A reference to the message.
1299      *
1300      * @retval kErrorNone     Successfully appended the CSL Timeout TLV.
1301      * @retval kErrorNoBufs   Insufficient buffers available to append the CSL Timeout TLV.
1302      *
1303      */
1304     Error AppendCslTimeout(Message &aMessage);
1305 #endif // (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE) || OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1306 
1307 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
1308     /**
1309      * This method appends a CSL Clock Accuracy TLV to a message.
1310      *
1311      * @param[in]  aMessage  A reference to the message.
1312      *
1313      * @retval kErrorNone     Successfully appended the CSL Accuracy TLV.
1314      * @retval kErrorNoBufs   Insufficient buffers available to append the CSL Accuracy TLV.
1315      */
1316     Error AppendCslClockAccuracy(Message &aMessage);
1317 #endif
1318 
1319     /**
1320      * This method appends a Active Timestamp TLV to a message.
1321      *
1322      * @param[in]  aMessage  A reference to the message.
1323      *
1324      * @retval kErrorNone     Successfully appended the Active Timestamp TLV.
1325      * @retval kErrorNoBufs   Insufficient buffers available to append the Active Timestamp TLV.
1326      *
1327      */
1328     Error AppendActiveTimestamp(Message &aMessage);
1329 
1330     /**
1331      * This method appends a Pending Timestamp TLV to a message.
1332      *
1333      * @param[in]  aMessage  A reference to the message.
1334      *
1335      * @retval kErrorNone     Successfully appended the Pending Timestamp TLV.
1336      * @retval kErrorNoBufs   Insufficient buffers available to append the Pending Timestamp TLV.
1337      *
1338      */
1339     Error AppendPendingTimestamp(Message &aMessage);
1340 
1341     /**
1342      * This method checks if the destination is reachable.
1343      *
1344      * @param[in]  aMeshDest   The RLOC16 of the destination.
1345      * @param[in]  aIp6Header  The IPv6 header of the message.
1346      *
1347      * @retval kErrorNone      The destination is reachable.
1348      * @retval kErrorNoRoute   The destination is not reachable and the message should be dropped.
1349      *
1350      */
1351     Error CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header);
1352 
1353     /**
1354      * This method returns the next hop towards an RLOC16 destination.
1355      *
1356      * @param[in]  aDestination  The RLOC16 of the destination.
1357      *
1358      * @returns A RLOC16 of the next hop if a route is known, kInvalidRloc16 otherwise.
1359      *
1360      */
1361     Mac::ShortAddress GetNextHop(uint16_t aDestination) const;
1362 
1363     /**
1364      * This method generates an MLE Data Request message.
1365      *
1366      * @param[in]  aDestination      A reference to the IPv6 address of the destination.
1367      * @param[in]  aTlvs             A pointer to requested TLV types.
1368      * @param[in]  aTlvsLength       The number of TLV types in @p aTlvs.
1369      * @param[in]  aDelay            Delay in milliseconds before the Data Request message is sent.
1370      * @param[in]  aExtraTlvs        A pointer to extra TLVs.
1371      * @param[in]  aExtraTlvsLength  Length of extra TLVs.
1372      *
1373      * @retval kErrorNone     Successfully generated an MLE Data Request message.
1374      * @retval kErrorNoBufs   Insufficient buffers to generate the MLE Data Request message.
1375      *
1376      */
1377     Error SendDataRequest(const Ip6::Address &aDestination,
1378                           const uint8_t *     aTlvs,
1379                           uint8_t             aTlvsLength,
1380                           uint16_t            aDelay,
1381                           const uint8_t *     aExtraTlvs       = nullptr,
1382                           uint8_t             aExtraTlvsLength = 0);
1383 
1384     /**
1385      * This method generates an MLE Child Update Request message.
1386      *
1387      * @retval kErrorNone    Successfully generated an MLE Child Update Request message.
1388      * @retval kErrorNoBufs  Insufficient buffers to generate the MLE Child Update Request message.
1389      *
1390      */
1391     Error SendChildUpdateRequest(void);
1392 
1393     /**
1394      * This method generates an MLE Child Update Response message.
1395      *
1396      * @param[in]  aTlvs         A pointer to requested TLV types.
1397      * @param[in]  aNumTlvs      The number of TLV types in @p aTlvs.
1398      * @param[in]  aChallenge    The Challenge for the response.
1399      *
1400      * @retval kErrorNone     Successfully generated an MLE Child Update Response message.
1401      * @retval kErrorNoBufs   Insufficient buffers to generate the MLE Child Update Response message.
1402      *
1403      */
1404     Error SendChildUpdateResponse(const uint8_t *aTlvs, uint8_t aNumTlvs, const Challenge &aChallenge);
1405 
1406     /**
1407      * This method submits an MLE message to the UDP socket.
1408      *
1409      * @param[in]  aMessage      A reference to the message.
1410      * @param[in]  aDestination  A reference to the IPv6 address of the destination.
1411      *
1412      * @retval kErrorNone     Successfully submitted the MLE message.
1413      * @retval kErrorNoBufs   Insufficient buffers to form the rest of the MLE message.
1414      *
1415      */
1416     Error SendMessage(Message &aMessage, const Ip6::Address &aDestination);
1417 
1418     /**
1419      * This method sets the RLOC16 assigned to the Thread interface.
1420      *
1421      * @param[in]  aRloc16  The RLOC16 to set.
1422      *
1423      */
1424     void SetRloc16(uint16_t aRloc16);
1425 
1426     /**
1427      * This method sets the Device State to Detached.
1428      *
1429      */
1430     void SetStateDetached(void);
1431 
1432     /**
1433      * This method sets the Device State to Child.
1434      *
1435      */
1436     void SetStateChild(uint16_t aRloc16);
1437 
1438     /**
1439      * This method sets the Leader's Partition ID, Weighting, and Router ID values.
1440      *
1441      * @param[in]  aPartitionId     The Leader's Partition ID value.
1442      * @param[in]  aWeighting       The Leader's Weighting value.
1443      * @param[in]  aLeaderRouterId  The Leader's Router ID value.
1444      *
1445      */
1446     void SetLeaderData(uint32_t aPartitionId, uint8_t aWeighting, uint8_t aLeaderRouterId);
1447 
1448     /**
1449      * This method adds a message to the message queue. The queued message will be transmitted after given delay.
1450      *
1451      * @param[in]  aMessage      The message to transmit after given delay.
1452      * @param[in]  aDestination  The IPv6 address of the recipient of the message.
1453      * @param[in]  aDelay        The delay in milliseconds before transmission of the message.
1454      *
1455      * @retval kErrorNone     Successfully queued the message to transmit after the delay.
1456      * @retval kErrorNoBufs   Insufficient buffers to queue the message.
1457      *
1458      */
1459     Error AddDelayedResponse(Message &aMessage, const Ip6::Address &aDestination, uint16_t aDelay);
1460 
1461 #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_MLE == 1)
1462     /**
1463      * This static method emits a log message with an IPv6 address.
1464      *
1465      * @param[in]  aAction     The message action (send/receive/delay, etc).
1466      * @param[in]  aType       The message type.
1467      * @param[in]  aAddress    The IPv6 address of the peer.
1468      *
1469      */
1470     static void Log(MessageAction aAction, MessageType aType, const Ip6::Address &aAddress);
1471 
1472     /**
1473      * This static method emits a log message with an IPv6 address and RLOC16.
1474      *
1475      * @param[in]  aAction     The message action (send/receive/delay, etc).
1476      * @param[in]  aType       The message type.
1477      * @param[in]  aAddress    The IPv6 address of the peer.
1478      * @param[in]  aRloc       The RLOC16.
1479      *
1480      */
1481     static void Log(MessageAction aAction, MessageType aType, const Ip6::Address &aAddress, uint16_t aRloc);
1482 #else
Log(MessageAction,MessageType,const Ip6::Address &)1483     static void Log(MessageAction, MessageType, const Ip6::Address &) {}
Log(MessageAction,MessageType,const Ip6::Address &,uint16_t)1484     static void Log(MessageAction, MessageType, const Ip6::Address &, uint16_t) {}
1485 #endif // #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_MLE == 1)
1486 
1487 #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_WARN) && (OPENTHREAD_CONFIG_LOG_MLE == 1)
1488     /**
1489      * This static method emits a log message indicating an error in processing of a message.
1490      *
1491      * Note that log message is emitted only if there is an error, i.e., @p aError is not `kErrorNone`. The log
1492      * message will have the format "Failed to process {aMessageString} : {ErrorString}".
1493      *
1494      * @param[in]  aType      The message type.
1495      * @param[in]  aError     The error in processing of the message.
1496      *
1497      */
1498     static void LogProcessError(MessageType aType, Error aError);
1499 
1500     /**
1501      * This static method emits a log message indicating an error when sending a message.
1502      *
1503      * Note that log message is emitted only if there is an error, i.e. @p aError is not `kErrorNone`. The log
1504      * message will have the format "Failed to send {Message Type} : {ErrorString}".
1505      *
1506      * @param[in]  aType    The message type.
1507      * @param[in]  aError   The error in sending the message.
1508      *
1509      */
1510     static void LogSendError(MessageType aType, Error aError);
1511 #else
LogProcessError(MessageType,Error)1512     static void LogProcessError(MessageType, Error) {}
LogSendError(MessageType,Error)1513     static void LogSendError(MessageType, Error) {}
1514 #endif // #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_WARN) && (OPENTHREAD_CONFIG_LOG_MLE == 1)
1515 
1516     /**
1517      * This method triggers MLE Announce on previous channel after the Thread device successfully
1518      * attaches and receives the new Active Commissioning Dataset if needed.
1519      *
1520      * MTD would send Announce immediately after attached.
1521      * FTD would delay to send Announce after tried to become Router or decided to stay in REED role.
1522      *
1523      */
1524     void InformPreviousChannel(void);
1525 
1526     /**
1527      * This method indicates whether or not in announce attach process.
1528      *
1529      * @retval true if attaching/attached on the announced parameters, false otherwise.
1530      *
1531      */
IsAnnounceAttach(void) const1532     bool IsAnnounceAttach(void) const { return mAlternatePanId != Mac::kPanIdBroadcast; }
1533 
1534 #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_NOTE) && (OPENTHREAD_CONFIG_LOG_MLE == 1)
1535     /**
1536      * This method converts an `AttachMode` enumeration value into a human-readable string.
1537      *
1538      * @param[in] aMode An attach mode
1539      *
1540      * @returns A human-readable string corresponding to the attach mode.
1541      *
1542      */
1543     static const char *AttachModeToString(AttachMode aMode);
1544 
1545     /**
1546      * This method converts an `AttachState` enumeration value into a human-readable string.
1547      *
1548      * @param[in] aState An attach state
1549      *
1550      * @returns A human-readable string corresponding to the attach state.
1551      *
1552      */
1553     static const char *AttachStateToString(AttachState aState);
1554 
1555     /**
1556      * This method converts a `ReattachState` enumeration value into a human-readable string.
1557      *
1558      * @param[in] aState A reattach state
1559      *
1560      * @returns A human-readable string corresponding to the reattach state.
1561      *
1562      */
1563     static const char *ReattachStateToString(ReattachState aState);
1564 #endif
1565 
1566 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
1567     /**
1568      * This method sends a Link Metrics Management Request message.
1569      *
1570      * @param[in]  aDestination  A reference to the IPv6 address of the destination.
1571      * @param[in]  aSubTlvs      A pointer to the buffer of the sub-TLVs in the message.
1572      * @param[in]  aLength       The overall length of @p aSubTlvs.
1573      *
1574      * @retval kErrorNone     Successfully sent a Link Metrics Management Request.
1575      * @retval kErrorNoBufs   Insufficient buffers to generate the MLE Link Metrics Management Request message.
1576      *
1577      */
1578     Error SendLinkMetricsManagementRequest(const Ip6::Address &aDestination, const uint8_t *aSubTlvs, uint8_t aLength);
1579 
1580     /**
1581      * This method sends an MLE Link Probe message.
1582      *
1583      * @param[in]  aDestination  A reference to the IPv6 address of the destination.
1584      * @param[in]  aSeriesId     The Series ID [1, 254] which the Probe message targets at.
1585      * @param[in]  aBuf          A pointer to the data payload.
1586      * @param[in]  aLength       The length of the data payload in Link Probe TLV, [0, 64].
1587      *
1588      * @retval kErrorNone         Successfully sent a Link Metrics Management Request.
1589      * @retval kErrorNoBufs       Insufficient buffers to generate the MLE Link Metrics Management Request message.
1590      * @retval kErrorInvalidArgs  Series ID is not a valid value, not within range [1, 254].
1591      *
1592      */
1593     Error SendLinkProbe(const Ip6::Address &aDestination, uint8_t aSeriesId, uint8_t *aBuf, uint8_t aLength);
1594 
1595 #endif
1596 
1597     Ip6::Netif::UnicastAddress mLeaderAloc; ///< Leader anycast locator
1598 
1599     LeaderData    mLeaderData;               ///< Last received Leader Data TLV.
1600     bool          mRetrieveNewNetworkData;   ///< Indicating new Network Data is needed if set.
1601     DeviceRole    mRole;                     ///< Current Thread role.
1602     Router        mParent;                   ///< Parent information.
1603     Router        mParentCandidate;          ///< Parent candidate information.
1604     NeighborTable mNeighborTable;            ///< The neighbor table.
1605     DeviceMode    mDeviceMode;               ///< Device mode setting.
1606     AttachState   mAttachState;              ///< The parent request state.
1607     ReattachState mReattachState;            ///< Reattach state
1608     uint16_t      mAttachCounter;            ///< Attach attempt counter.
1609     uint16_t      mAnnounceDelay;            ///< Delay in between sending Announce messages during attach.
1610     TimerMilli    mAttachTimer;              ///< The timer for driving the attach process.
1611     TimerMilli    mDelayedResponseTimer;     ///< The timer to delay MLE responses.
1612     TimerMilli    mMessageTransmissionTimer; ///< The timer for (re-)sending of MLE messages (e.g. Child Update).
1613     uint8_t       mParentLeaderCost;
1614 
1615 private:
1616     static constexpr uint8_t kMleHopLimit        = 255;
1617     static constexpr uint8_t kMleSecurityTagSize = 4; // Security tag size in bytes.
1618 
1619     // Parameters related to "periodic parent search" feature (CONFIG_ENABLE_PERIODIC_PARENT_SEARCH).
1620     // All timer intervals are converted to milliseconds.
1621     static constexpr uint32_t kParentSearchCheckInterval   = (OPENTHREAD_CONFIG_PARENT_SEARCH_CHECK_INTERVAL * 1000u);
1622     static constexpr uint32_t kParentSearchBackoffInterval = (OPENTHREAD_CONFIG_PARENT_SEARCH_BACKOFF_INTERVAL * 1000u);
1623     static constexpr uint32_t kParentSearchJitterInterval  = (15 * 1000u);
1624     static constexpr int8_t   kParentSearchRssThreadhold   = OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_THRESHOLD;
1625 
1626     // Parameters for "attach backoff" feature (CONFIG_ENABLE_ATTACH_BACKOFF) - Intervals are in milliseconds.
1627     static constexpr uint32_t kAttachBackoffMinInterval = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MINIMUM_INTERVAL;
1628     static constexpr uint32_t kAttachBackoffMaxInterval = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MAXIMUM_INTERVAL;
1629     static constexpr uint32_t kAttachBackoffJitter      = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_JITTER_INTERVAL;
1630     static constexpr uint32_t kAttachBackoffDelayToResetCounter =
1631         OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_DELAY_TO_RESET_BACKOFF_INTERVAL;
1632 
1633     enum ParentRequestType : uint8_t
1634     {
1635         kParentRequestTypeRouters,         // Parent Request to all routers.
1636         kParentRequestTypeRoutersAndReeds, // Parent Request to all routers and REEDs.
1637     };
1638 
1639     enum ChildUpdateRequestState : uint8_t
1640     {
1641         kChildUpdateRequestNone,    // No pending or active Child Update Request.
1642         kChildUpdateRequestPending, // Pending Child Update Request due to relative OT_CHANGED event.
1643         kChildUpdateRequestActive,  // Child Update Request has been sent and Child Update Response is expected.
1644     };
1645 
1646     enum DataRequestState : uint8_t
1647     {
1648         kDataRequestNone,   // Not waiting for a Data Response.
1649         kDataRequestActive, // Data Request has been sent, Data Response is expected.
1650     };
1651 
1652     struct DelayedResponseMetadata
1653     {
AppendToot::Mle::Mle::DelayedResponseMetadata1654         Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); }
1655         void  ReadFrom(const Message &aMessage);
1656         void  RemoveFrom(Message &aMessage) const;
1657 
1658         Ip6::Address mDestination; // IPv6 address of the message destination.
1659         TimeMilli    mSendTime;    // Time when the message shall be sent.
1660     };
1661 
1662     OT_TOOL_PACKED_BEGIN
1663     class Header
1664     {
1665     public:
1666         enum SecuritySuite : uint8_t
1667         {
1668             k154Security = 0,
1669             kNoSecurity  = 255,
1670         };
1671 
Init(void)1672         void Init(void)
1673         {
1674             mSecuritySuite   = k154Security;
1675             mSecurityControl = Mac::Frame::kSecEncMic32;
1676         }
1677 
IsValid(void) const1678         bool IsValid(void) const
1679         {
1680             return (mSecuritySuite == kNoSecurity) ||
1681                    (mSecuritySuite == k154Security &&
1682                     mSecurityControl == (Mac::Frame::kKeyIdMode2 | Mac::Frame::kSecEncMic32));
1683         }
1684 
GetLength(void) const1685         uint8_t GetLength(void) const
1686         {
1687             return sizeof(mSecuritySuite) + sizeof(mCommand) +
1688                    ((mSecuritySuite == k154Security)
1689                         ? sizeof(mSecurityControl) + sizeof(mFrameCounter) + sizeof(mKeySource) + sizeof(mKeyIndex)
1690                         : 0);
1691         }
1692 
GetSecuritySuite(void) const1693         SecuritySuite GetSecuritySuite(void) const { return static_cast<SecuritySuite>(mSecuritySuite); }
SetSecuritySuite(SecuritySuite aSecuritySuite)1694         void SetSecuritySuite(SecuritySuite aSecuritySuite) { mSecuritySuite = static_cast<uint8_t>(aSecuritySuite); }
1695 
GetHeaderLength(void) const1696         uint8_t GetHeaderLength(void) const
1697         {
1698             return sizeof(mSecurityControl) + sizeof(mFrameCounter) + sizeof(mKeySource) + sizeof(mKeyIndex);
1699         }
1700 
GetBytes(void) const1701         const uint8_t *GetBytes(void) const { return reinterpret_cast<const uint8_t *>(&mSecuritySuite); }
GetSecurityControl(void) const1702         uint8_t        GetSecurityControl(void) const { return mSecurityControl; }
1703 
IsKeyIdMode2(void) const1704         bool IsKeyIdMode2(void) const
1705         {
1706             return (mSecurityControl & Mac::Frame::kKeyIdModeMask) == Mac::Frame::kKeyIdMode2;
1707         }
1708 
SetKeyIdMode2(void)1709         void SetKeyIdMode2(void)
1710         {
1711             mSecurityControl = (mSecurityControl & ~Mac::Frame::kKeyIdModeMask) | Mac::Frame::kKeyIdMode2;
1712         }
1713 
GetKeyId(void) const1714         uint32_t GetKeyId(void) const { return Encoding::BigEndian::HostSwap32(mKeySource); }
1715 
SetKeyId(uint32_t aKeySequence)1716         void SetKeyId(uint32_t aKeySequence)
1717         {
1718             mKeySource = Encoding::BigEndian::HostSwap32(aKeySequence);
1719             mKeyIndex  = (aKeySequence & 0x7f) + 1;
1720         }
1721 
GetFrameCounter(void) const1722         uint32_t GetFrameCounter(void) const { return Encoding::LittleEndian::HostSwap32(mFrameCounter); }
SetFrameCounter(uint32_t aFrameCounter)1723         void     SetFrameCounter(uint32_t aFrameCounter)
1724         {
1725             mFrameCounter = Encoding::LittleEndian::HostSwap32(aFrameCounter);
1726         }
1727 
GetCommand(void) const1728         Command GetCommand(void) const
1729         {
1730             return static_cast<Command>((mSecuritySuite == kNoSecurity) ? mSecurityControl : mCommand);
1731         }
1732 
SetCommand(Command aCommand)1733         void SetCommand(Command aCommand)
1734         {
1735             if (mSecuritySuite == kNoSecurity)
1736             {
1737                 mSecurityControl = static_cast<uint8_t>(aCommand);
1738             }
1739             else
1740             {
1741                 mCommand = static_cast<uint8_t>(aCommand);
1742             }
1743         }
1744 
1745     private:
1746         uint8_t  mSecuritySuite;
1747         uint8_t  mSecurityControl;
1748         uint32_t mFrameCounter;
1749         uint32_t mKeySource;
1750         uint8_t  mKeyIndex;
1751         uint8_t  mCommand;
1752     } OT_TOOL_PACKED_END;
1753 
1754     void        HandleNotifierEvents(Events aEvents);
1755     static void HandleAttachTimer(Timer &aTimer);
1756     void        HandleAttachTimer(void);
1757     static void HandleDelayedResponseTimer(Timer &aTimer);
1758     void        HandleDelayedResponseTimer(void);
1759     static void HandleMessageTransmissionTimer(Timer &aTimer);
1760     void        HandleMessageTransmissionTimer(void);
1761     static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
1762     void        HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
1763     void        ScheduleMessageTransmissionTimer(void);
1764     Error       ReadChallengeOrResponse(const Message &aMessage, uint8_t aTlvType, Challenge &aBuffer);
1765 
1766     void HandleAdvertisement(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *aNeighbor);
1767     void HandleChildIdResponse(const Message &         aMessage,
1768                                const Ip6::MessageInfo &aMessageInfo,
1769                                const Neighbor *        aNeighbor);
1770     void HandleChildUpdateRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *aNeighbor);
1771     void HandleChildUpdateResponse(const Message &         aMessage,
1772                                    const Ip6::MessageInfo &aMessageInfo,
1773                                    const Neighbor *        aNeighbor);
1774     void HandleDataResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const Neighbor *aNeighbor);
1775     void HandleParentResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, uint32_t aKeySequence);
1776     void HandleAnnounce(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
1777 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
1778     void HandleLinkMetricsManagementRequest(const Message &         aMessage,
1779                                             const Ip6::MessageInfo &aMessageInfo,
1780                                             Neighbor *              aNeighbor);
1781 #endif
1782 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
1783     void HandleLinkMetricsManagementResponse(const Message &         aMessage,
1784                                              const Ip6::MessageInfo &aMessageInfo,
1785                                              Neighbor *              aNeighbor);
1786 #endif
1787 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
1788     void HandleLinkProbe(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, Neighbor *aNeighbor);
1789 #endif
1790     Error HandleLeaderData(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
1791     void  ProcessAnnounce(void);
1792     bool  HasUnregisteredAddress(void);
1793 
1794     uint32_t GetAttachStartDelay(void) const;
1795     Error    SendParentRequest(ParentRequestType aType);
1796     Error    SendChildIdRequest(void);
1797     Error    GetNextAnnouceChannel(uint8_t &aChannel) const;
1798     bool     HasMoreChannelsToAnnouce(void) const;
1799     bool     PrepareAnnounceState(void);
1800     void     SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce, const Ip6::Address &aDestination);
1801 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
1802     Error SendLinkMetricsManagementResponse(const Ip6::Address &aDestination, LinkMetrics::Status aStatus);
1803 #endif
1804     uint32_t Reattach(void);
1805 
1806     bool IsBetterParent(uint16_t               aRloc16,
1807                         uint8_t                aLinkQuality,
1808                         uint8_t                aLinkMargin,
1809                         const ConnectivityTlv &aConnectivityTlv,
1810                         uint8_t                aVersion,
1811                         uint8_t                aCslClockAccuracy,
1812                         uint8_t                aCslUncertainty);
1813     bool IsNetworkDataNewer(const LeaderData &aLeaderData);
1814 
1815 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
1816     /**
1817      * This method scans for network data from the leader and updates IP addresses assigned to this
1818      * interface to make sure that all Service ALOCs (0xfc10-0xfc1f) are properly set.
1819      */
1820     void UpdateServiceAlocs(void);
1821 #endif
1822 
1823 #if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH
1824     void InformPreviousParent(void);
1825 #endif
1826 
1827 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
1828     static void HandleParentSearchTimer(Timer &aTimer);
1829     void        HandleParentSearchTimer(void);
1830     void        StartParentSearchTimer(void);
1831     void        UpdateParentSearchState(void);
1832 #endif
1833 
1834 #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_WARN) && (OPENTHREAD_CONFIG_LOG_MLE == 1)
1835     static void        LogError(MessageAction aAction, MessageType aType, Error aError);
1836     static const char *MessageActionToString(MessageAction aAction);
1837     static const char *MessageTypeToString(MessageType aType);
1838     static const char *MessageTypeActionToSuffixString(MessageType aType, MessageAction aAction);
1839 #endif
1840 
1841     MessageQueue mDelayedResponses;
1842 
1843     Challenge mParentRequestChallenge;
1844 
1845     AttachMode mParentRequestMode;
1846     int8_t     mParentPriority;
1847     uint8_t    mParentLinkQuality3;
1848     uint8_t    mParentLinkQuality2;
1849     uint8_t    mParentLinkQuality1;
1850     uint16_t   mParentSedBufferSize;
1851     uint8_t    mParentSedDatagramCount;
1852 
1853     uint8_t                 mChildUpdateAttempts;
1854     ChildUpdateRequestState mChildUpdateRequestState;
1855     uint8_t                 mDataRequestAttempts;
1856     DataRequestState        mDataRequestState;
1857 
1858     AddressRegistrationMode mAddressRegistrationMode;
1859 
1860     bool       mHasRestored;
1861     uint8_t    mParentLinkMargin;
1862     bool       mParentIsSingleton;
1863     bool       mReceivedResponseFromParent;
1864     LeaderData mParentLeaderData;
1865 
1866     Challenge mParentCandidateChallenge;
1867 
1868     Ip6::Udp::Socket mSocket;
1869     uint32_t         mTimeout;
1870 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1871     uint32_t mCslTimeout;
1872 #endif
1873 
1874 #if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH
1875     uint16_t mPreviousParentRloc;
1876 #endif
1877 
1878 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
1879     bool       mParentSearchIsInBackoff : 1;
1880     bool       mParentSearchBackoffWasCanceled : 1;
1881     bool       mParentSearchRecentlyDetached : 1;
1882     TimeMilli  mParentSearchBackoffCancelTime;
1883     TimerMilli mParentSearchTimer;
1884 #endif
1885 
1886     uint8_t  mAnnounceChannel;
1887     uint8_t  mAlternateChannel;
1888     uint16_t mAlternatePanId;
1889     uint64_t mAlternateTimestamp;
1890 
1891 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
1892     Ip6::Netif::UnicastAddress mServiceAlocs[kMaxServiceAlocs];
1893 #endif
1894 
1895     otMleCounters mCounters;
1896 
1897     Ip6::Netif::UnicastAddress   mLinkLocal64;
1898     Ip6::Netif::UnicastAddress   mMeshLocal64;
1899     Ip6::Netif::UnicastAddress   mMeshLocal16;
1900     Ip6::Netif::MulticastAddress mLinkLocalAllThreadNodes;
1901     Ip6::Netif::MulticastAddress mRealmLocalAllThreadNodes;
1902 
1903     otThreadParentResponseCallback mParentResponseCb;
1904     void *                         mParentResponseCbContext;
1905 };
1906 
1907 } // namespace Mle
1908 
1909 /**
1910  * @}
1911  *
1912  */
1913 
1914 } // namespace ot
1915 
1916 #endif // MLE_HPP_
1917