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/callback.hpp"
40 #include "common/encoding.hpp"
41 #include "common/locator.hpp"
42 #include "common/log.hpp"
43 #include "common/non_copyable.hpp"
44 #include "common/notifier.hpp"
45 #include "common/timer.hpp"
46 #include "crypto/aes_ccm.hpp"
47 #include "mac/mac.hpp"
48 #include "meshcop/joiner_router.hpp"
49 #include "meshcop/meshcop.hpp"
50 #include "net/udp6.hpp"
51 #include "thread/link_metrics.hpp"
52 #include "thread/link_metrics_tlvs.hpp"
53 #include "thread/mle_tlvs.hpp"
54 #include "thread/mle_types.hpp"
55 #include "thread/neighbor_table.hpp"
56 #include "thread/network_data_types.hpp"
57 #include "thread/topology.hpp"
58 
59 namespace ot {
60 
61 /**
62  * @addtogroup core-mle MLE
63  *
64  * @brief
65  *   This module includes definitions for the MLE protocol.
66  *
67  * @{
68  *
69  * @defgroup core-mle-core Core
70  * @defgroup core-mle-router Router
71  * @defgroup core-mle-tlvs TLVs
72  *
73  * @}
74  */
75 
76 class SupervisionListener;
77 
78 /**
79  * @namespace ot::Mle
80  *
81  * @brief
82  *   This namespace includes definitions for the MLE protocol.
83  */
84 
85 namespace Mle {
86 
87 /**
88  * @addtogroup core-mle-core
89  *
90  * @brief
91  *   This module includes definitions for MLE functionality required by the Thread Child, Router, and Leader roles.
92  *
93  * @{
94  *
95  */
96 
97 /**
98  * This class implements MLE functionality required by the Thread EndDevices, Router, and Leader roles.
99  *
100  */
101 class Mle : public InstanceLocator, private NonCopyable
102 {
103     friend class DiscoverScanner;
104     friend class ot::Notifier;
105     friend class ot::SupervisionListener;
106 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
107     friend class ot::LinkMetrics::Initiator;
108 #endif
109 
110 public:
111     /**
112      * This constructor initializes the MLE object.
113      *
114      * @param[in]  aInstance     A reference to the OpenThread instance.
115      *
116      */
117     explicit Mle(Instance &aInstance);
118 
119     /**
120      * This method enables MLE.
121      *
122      * @retval kErrorNone     Successfully enabled MLE.
123      * @retval kErrorAlready  MLE was already enabled.
124      *
125      */
126     Error Enable(void);
127 
128     /**
129      * This method disables MLE.
130      *
131      * @retval kErrorNone     Successfully disabled MLE.
132      *
133      */
134     Error Disable(void);
135 
136     /**
137      * This method starts the MLE protocol operation.
138      *
139      * @retval kErrorNone           Successfully started the protocol operation.
140      * @retval kErrorInvalidState   IPv6 interface is down or device is in raw-link mode.
141      *
142      */
Start(void)143     Error Start(void) { return Start(kNormalAttach); }
144 
145     /**
146      * This method stops the MLE protocol operation.
147      *
148      */
Stop(void)149     void Stop(void) { Stop(kUpdateNetworkDatasets); }
150 
151     /**
152      * This method restores network information from non-volatile memory (if any).
153      *
154      */
155     void Restore(void);
156 
157     /**
158      * This method stores network information into non-volatile memory.
159      *
160      * @retval kErrorNone      Successfully store the network information.
161      * @retval kErrorNoBufs    Could not store the network information due to insufficient memory space.
162      *
163      */
164     Error Store(void);
165 
166     /**
167      * This method generates an MLE Announce message.
168      *
169      * @param[in]  aChannel        The channel to use when transmitting.
170      *
171      */
SendAnnounce(uint8_t aChannel)172     void SendAnnounce(uint8_t aChannel) { SendAnnounce(aChannel, kNormalAnnounce); }
173 
174     /**
175      * This method causes the Thread interface to detach from the Thread network.
176      *
177      * @retval kErrorNone          Successfully detached from the Thread network.
178      * @retval kErrorInvalidState  MLE is Disabled.
179      *
180      */
181     Error BecomeDetached(void);
182 
183     /**
184      * This method causes the Thread interface to attempt an MLE attach.
185      *
186      * @retval kErrorNone          Successfully began the attach process.
187      * @retval kErrorInvalidState  MLE is Disabled.
188      * @retval kErrorBusy          An attach process is in progress.
189      *
190      */
191     Error BecomeChild(void);
192 
193     /**
194      * This function notifies other nodes in the network (if any) and then stops Thread protocol operation.
195      *
196      * It sends an Address Release if it's a router, or sets its child timeout to 0 if it's a child.
197      *
198      * @param[in] aCallback A pointer to a function that is called upon finishing detaching.
199      * @param[in] aContext  A pointer to callback application-specific context.
200      *
201      * @retval kErrorNone   Successfully started detaching.
202      * @retval kErrorBusy   Detaching is already in progress.
203      *
204      */
205     Error DetachGracefully(otDetachGracefullyCallback aCallback, void *aContext);
206 
207     /**
208      * This method indicates whether or not the Thread device is attached to a Thread network.
209      *
210      * @retval TRUE   Attached to a Thread network.
211      * @retval FALSE  Not attached to a Thread network.
212      *
213      */
214     bool IsAttached(void) const;
215 
216     /**
217      * This method indicates whether device is currently attaching or not.
218      *
219      * Note that an already attached device may also be in attaching state. Examples of this include a leader/router
220      * trying to attach to a better partition, or a child trying to find a better parent (when feature
221      * `OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE` is enabled).
222      *
223      * @retval TRUE   Device is currently trying to attach.
224      * @retval FALSE  Device is not in middle of attach process.
225      *
226      */
IsAttaching(void) const227     bool IsAttaching(void) const { return (mAttachState != kAttachStateIdle); }
228 
229     /**
230      * This method returns the current Thread device role.
231      *
232      * @returns The current Thread device role.
233      *
234      */
GetRole(void) const235     DeviceRole GetRole(void) const { return mRole; }
236 
237     /**
238      * This method indicates whether device role is disabled.
239      *
240      * @retval TRUE   Device role is disabled.
241      * @retval FALSE  Device role is not disabled.
242      *
243      */
IsDisabled(void) const244     bool IsDisabled(void) const { return (mRole == kRoleDisabled); }
245 
246     /**
247      * This method indicates whether device role is detached.
248      *
249      * @retval TRUE   Device role is detached.
250      * @retval FALSE  Device role is not detached.
251      *
252      */
IsDetached(void) const253     bool IsDetached(void) const { return (mRole == kRoleDetached); }
254 
255     /**
256      * This method indicates whether device role is child.
257      *
258      * @retval TRUE   Device role is child.
259      * @retval FALSE  Device role is not child.
260      *
261      */
IsChild(void) const262     bool IsChild(void) const { return (mRole == kRoleChild); }
263 
264     /**
265      * This method indicates whether device role is router.
266      *
267      * @retval TRUE   Device role is router.
268      * @retval FALSE  Device role is not router.
269      *
270      */
IsRouter(void) const271     bool IsRouter(void) const { return (mRole == kRoleRouter); }
272 
273     /**
274      * This method indicates whether device role is leader.
275      *
276      * @retval TRUE   Device role is leader.
277      * @retval FALSE  Device role is not leader.
278      *
279      */
IsLeader(void) const280     bool IsLeader(void) const { return (mRole == kRoleLeader); }
281 
282     /**
283      * This method indicates whether device role is either router or leader.
284      *
285      * @retval TRUE   Device role is either router or leader.
286      * @retval FALSE  Device role is neither router nor leader.
287      *
288      */
289     bool IsRouterOrLeader(void) const;
290 
291     /**
292      * This method returns the Device Mode as reported in the Mode TLV.
293      *
294      * @returns The Device Mode as reported in the Mode TLV.
295      *
296      */
GetDeviceMode(void) const297     DeviceMode GetDeviceMode(void) const { return mDeviceMode; }
298 
299     /**
300      * This method sets the Device Mode as reported in the Mode TLV.
301      *
302      * @param[in]  aDeviceMode  The device mode to set.
303      *
304      * @retval kErrorNone         Successfully set the Mode TLV.
305      * @retval kErrorInvalidArgs  The mode combination specified in @p aMode is invalid.
306      *
307      */
308     Error SetDeviceMode(DeviceMode aDeviceMode);
309 
310     /**
311      * This method indicates whether or not the device is rx-on-when-idle.
312      *
313      * @returns TRUE if rx-on-when-idle, FALSE otherwise.
314      *
315      */
IsRxOnWhenIdle(void) const316     bool IsRxOnWhenIdle(void) const { return mDeviceMode.IsRxOnWhenIdle(); }
317 
318     /**
319      * This method indicates whether or not the device is a Full Thread Device.
320      *
321      * @returns TRUE if a Full Thread Device, FALSE otherwise.
322      *
323      */
IsFullThreadDevice(void) const324     bool IsFullThreadDevice(void) const { return mDeviceMode.IsFullThreadDevice(); }
325 
326     /**
327      * This method indicates whether or not the device is a Minimal End Device.
328      *
329      * @returns TRUE if the device is a Minimal End Device, FALSE otherwise.
330      *
331      */
IsMinimalEndDevice(void) const332     bool IsMinimalEndDevice(void) const { return mDeviceMode.IsMinimalEndDevice(); }
333 
334     /**
335      * This method gets the Network Data type (full set or stable subset) that this device requests.
336      *
337      * @returns The Network Data type requested by this device.
338      *
339      */
GetNetworkDataType(void) const340     NetworkData::Type GetNetworkDataType(void) const { return mDeviceMode.GetNetworkDataType(); }
341 
342     /**
343      * This method returns a pointer to the Mesh Local Prefix.
344      *
345      * @returns A reference to the Mesh Local Prefix.
346      *
347      */
GetMeshLocalPrefix(void) const348     const Ip6::NetworkPrefix &GetMeshLocalPrefix(void) const { return mMeshLocal16.GetAddress().GetPrefix(); }
349 
350     /**
351      * This method sets the Mesh Local Prefix.
352      *
353      * @param[in]  aMeshLocalPrefix  A reference to the Mesh Local Prefix.
354      *
355      */
356     void SetMeshLocalPrefix(const Ip6::NetworkPrefix &aMeshLocalPrefix);
357 
358 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
359     /**
360      * This method sets the Mesh Local IID.
361      *
362      * Available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled.
363      *
364      * @param[in] aMlIid  The Mesh Local IID.
365      *
366      * @retval kErrorNone           Successfully configured Mesh Local IID.
367      * @retval kErrorInvalidState   If the Thread stack is already enabled.
368      *
369      */
370     Error SetMeshLocalIid(const Ip6::InterfaceIdentifier &aMlIid);
371 #endif
372 
373     /**
374      * This method applies the Mesh Local Prefix.
375      *
376      */
377     void ApplyMeshLocalPrefix(void);
378 
379     /**
380      * This method returns a reference to the Thread link-local address.
381      *
382      * The Thread link local address is derived using IEEE802.15.4 Extended Address as Interface Identifier.
383      *
384      * @returns A reference to the Thread link local address.
385      *
386      */
GetLinkLocalAddress(void) const387     const Ip6::Address &GetLinkLocalAddress(void) const { return mLinkLocal64.GetAddress(); }
388 
389     /**
390      * This method updates the link local address.
391      *
392      * Call this method when the IEEE 802.15.4 Extended Address has changed.
393      *
394      */
395     void UpdateLinkLocalAddress(void);
396 
397     /**
398      * This method returns a reference to the link-local all Thread nodes multicast address.
399      *
400      * @returns A reference to the link-local all Thread nodes multicast address.
401      *
402      */
GetLinkLocalAllThreadNodesAddress(void) const403     const Ip6::Address &GetLinkLocalAllThreadNodesAddress(void) const { return mLinkLocalAllThreadNodes.GetAddress(); }
404 
405     /**
406      * This method returns a reference to the realm-local all Thread nodes multicast address.
407      *
408      * @returns A reference to the realm-local all Thread nodes multicast address.
409      *
410      */
GetRealmLocalAllThreadNodesAddress(void) const411     const Ip6::Address &GetRealmLocalAllThreadNodesAddress(void) const
412     {
413         return mRealmLocalAllThreadNodes.GetAddress();
414     }
415 
416     /**
417      * This method gets the parent when operating in End Device mode.
418      *
419      * @returns A reference to the parent.
420      *
421      */
GetParent(void)422     Parent &GetParent(void) { return mParent; }
423 
424     /**
425      * This method gets the parent when operating in End Device mode.
426      *
427      * @returns A reference to the parent.
428      *
429      */
GetParent(void) const430     const Parent &GetParent(void) const { return mParent; }
431 
432     /**
433      * The method retrieves information about the parent.
434      *
435      * @param[out] aParentInfo     Reference to a parent information structure.
436      *
437      * @retval kErrorNone          Successfully retrieved the parent info and updated @p aParentInfo.
438      * @retval kErrorInvalidState  Device role is not child.
439      *
440      */
441     Error GetParentInfo(Router::Info &aParentInfo) const;
442 
443     /**
444      * This method get the parent candidate.
445      *
446      * The parent candidate is valid when attempting to attach to a new parent.
447      *
448      */
GetParentCandidate(void)449     Parent &GetParentCandidate(void) { return mParentCandidate; }
450 
451     /**
452      * This method starts the process for child to search for a better parent while staying attached to its current
453      * parent
454      *
455      * @retval kErrorNone          Successfully started the process to search for a better parent.
456      * @retval kErrorInvalidState  Device role is not child.
457      *
458      */
459     Error SearchForBetterParent(void);
460 
461     /**
462      * This method indicates whether or not an IPv6 address is an RLOC.
463      *
464      * @retval TRUE   If @p aAddress is an RLOC.
465      * @retval FALSE  If @p aAddress is not an RLOC.
466      *
467      */
468     bool IsRoutingLocator(const Ip6::Address &aAddress) const;
469 
470     /**
471      * This method indicates whether or not an IPv6 address is an ALOC.
472      *
473      * @retval TRUE   If @p aAddress is an ALOC.
474      * @retval FALSE  If @p aAddress is not an ALOC.
475      *
476      */
477     bool IsAnycastLocator(const Ip6::Address &aAddress) const;
478 
479     /**
480      * This method indicates whether or not an IPv6 address is a Mesh Local Address.
481      *
482      * @retval TRUE   If @p aAddress is a Mesh Local Address.
483      * @retval FALSE  If @p aAddress is not a Mesh Local Address.
484      *
485      */
486     bool IsMeshLocalAddress(const Ip6::Address &aAddress) const;
487 
488     /**
489      * This method returns the MLE Timeout value.
490      *
491      * @returns The MLE Timeout value in seconds.
492      *
493      */
GetTimeout(void) const494     uint32_t GetTimeout(void) const { return mTimeout; }
495 
496     /**
497      * This method sets the MLE Timeout value.
498      *
499      * @param[in]  aTimeout  The Timeout value in seconds.
500      *
501      */
502     void SetTimeout(uint32_t aTimeout);
503 
504     /**
505      * This method returns the RLOC16 assigned to the Thread interface.
506      *
507      * @returns The RLOC16 assigned to the Thread interface.
508      *
509      */
GetRloc16(void) const510     uint16_t GetRloc16(void) const { return mRloc16; }
511 
512     /**
513      * This method returns a reference to the RLOC assigned to the Thread interface.
514      *
515      * @returns A reference to the RLOC assigned to the Thread interface.
516      *
517      */
GetMeshLocal16(void) const518     const Ip6::Address &GetMeshLocal16(void) const { return mMeshLocal16.GetAddress(); }
519 
520     /**
521      * This method returns a reference to the ML-EID assigned to the Thread interface.
522      *
523      * @returns A reference to the ML-EID assigned to the Thread interface.
524      *
525      */
GetMeshLocal64(void) const526     const Ip6::Address &GetMeshLocal64(void) const { return mMeshLocal64.GetAddress(); }
527 
528     /**
529      * This method returns the Router ID of the Leader.
530      *
531      * @returns The Router ID of the Leader.
532      *
533      */
GetLeaderId(void) const534     uint8_t GetLeaderId(void) const { return mLeaderData.GetLeaderRouterId(); }
535 
536     /**
537      * This method retrieves the Leader's RLOC.
538      *
539      * @param[out]  aAddress  A reference to the Leader's RLOC.
540      *
541      * @retval kErrorNone      Successfully retrieved the Leader's RLOC.
542      * @retval kErrorDetached  The Thread interface is not currently attached to a Thread Partition.
543      *
544      */
545     Error GetLeaderAddress(Ip6::Address &aAddress) const;
546 
547     /**
548      * This method retrieves the Leader's ALOC.
549      *
550      * @param[out]  aAddress  A reference to the Leader's ALOC.
551      *
552      * @retval kErrorNone      Successfully retrieved the Leader's ALOC.
553      * @retval kErrorDetached  The Thread interface is not currently attached to a Thread Partition.
554      *
555      */
GetLeaderAloc(Ip6::Address & aAddress) const556     Error GetLeaderAloc(Ip6::Address &aAddress) const { return GetLocatorAddress(aAddress, kAloc16Leader); }
557 
558     /**
559      * This method computes the Commissioner's ALOC.
560      *
561      * @param[out]  aAddress        A reference to the Commissioner's ALOC.
562      * @param[in]   aSessionId      Commissioner session id.
563      *
564      * @retval kErrorNone      Successfully retrieved the Commissioner's ALOC.
565      * @retval kErrorDetached  The Thread interface is not currently attached to a Thread Partition.
566      *
567      */
GetCommissionerAloc(Ip6::Address & aAddress,uint16_t aSessionId) const568     Error GetCommissionerAloc(Ip6::Address &aAddress, uint16_t aSessionId) const
569     {
570         return GetLocatorAddress(aAddress, CommissionerAloc16FromId(aSessionId));
571     }
572 
573     /**
574      * This method retrieves the Service ALOC for given Service ID.
575      *
576      * @param[in]   aServiceId Service ID to get ALOC for.
577      * @param[out]  aAddress   A reference to the Service ALOC.
578      *
579      * @retval kErrorNone      Successfully retrieved the Service ALOC.
580      * @retval kErrorDetached  The Thread interface is not currently attached to a Thread Partition.
581      *
582      */
583     Error GetServiceAloc(uint8_t aServiceId, Ip6::Address &aAddress) const;
584 
585     /**
586      * This method returns the most recently received Leader Data.
587      *
588      * @returns  A reference to the most recently received Leader Data.
589      *
590      */
591     const LeaderData &GetLeaderData(void);
592 
593     /**
594      * This method returns a reference to the send queue.
595      *
596      * @returns A reference to the send queue.
597      *
598      */
GetMessageQueue(void) const599     const MessageQueue &GetMessageQueue(void) const { return mDelayedResponses; }
600 
601     /**
602      * This method frees multicast MLE Data Response from Delayed Message Queue if any.
603      *
604      */
605     void RemoveDelayedDataResponseMessage(void);
606 
607     /**
608      * This method gets the MLE counters.
609      *
610      * @returns A reference to the MLE counters.
611      *
612      */
GetCounters(void)613     const Counters &GetCounters(void)
614     {
615 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
616         UpdateRoleTimeCounters(mRole);
617 #endif
618         return mCounters;
619     }
620 
621     /**
622      * This method resets the MLE counters.
623      *
624      */
625     void ResetCounters(void);
626 
627 #if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE
628     /**
629      * This function registers the client callback that is called when processing an MLE Parent Response message.
630      *
631      * @param[in]  aCallback A pointer to a function that is called to deliver MLE Parent Response data.
632      * @param[in]  aContext  A pointer to application-specific context.
633      *
634      */
RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCallback,void * aContext)635     void RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCallback, void *aContext)
636     {
637         mParentResponseCallback.Set(aCallback, aContext);
638     }
639 #endif
640 
641     /**
642      * This method requests MLE layer to prepare and send a shorter version of Child ID Request message by only
643      * including the mesh-local IPv6 address in the Address Registration TLV.
644      *
645      * This method should be called when a previous MLE Child ID Request message would require fragmentation at 6LoWPAN
646      * layer.
647      *
648      */
649     void RequestShorterChildIdRequest(void);
650 
651     /**
652      * This method gets the RLOC or ALOC of a given RLOC16 or ALOC16.
653      *
654      * @param[out]  aAddress  A reference to the RLOC or ALOC.
655      * @param[in]   aLocator  RLOC16 or ALOC16.
656      *
657      * @retval kErrorNone      If got the RLOC or ALOC successfully.
658      * @retval kErrorDetached  If device is detached.
659      *
660      */
661     Error GetLocatorAddress(Ip6::Address &aAddress, uint16_t aLocator) const;
662 
663     /**
664      * This method schedules a Child Update Request.
665      *
666      */
667     void ScheduleChildUpdateRequest(void);
668 
669     /*
670      * This method indicates whether or not the device has restored the network information from
671      * non-volatile settings after boot.
672      *
673      * @retval true  Successfully restored the network information.
674      * @retval false No valid network information was found.
675      *
676      */
HasRestored(void) const677     bool HasRestored(void) const { return mHasRestored; }
678 
679 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
680     /**
681      * This method gets the CSL timeout.
682      *
683      * @returns CSL timeout
684      *
685      */
GetCslTimeout(void) const686     uint32_t GetCslTimeout(void) const { return mCslTimeout; }
687 
688     /**
689      * This method sets the CSL timeout.
690      *
691      * @param[in]  aTimeout  The CSL timeout in seconds.
692      *
693      */
694     void SetCslTimeout(uint32_t aTimeout);
695 
696     /**
697      * This method calculates CSL metric of parent.
698      *
699      * @param[in] aCslAccuracy The CSL accuracy.
700      *
701      * @returns CSL metric.
702      *
703      */
704     uint64_t CalcParentCslMetric(const Mac::CslAccuracy &aCslAccuracy) const;
705 
706 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
707 
708 protected:
709     /**
710      * MLE Command Types.
711      *
712      */
713     enum Command : uint8_t
714     {
715         kCommandLinkRequest                   = 0,  ///< Link Request
716         kCommandLinkAccept                    = 1,  ///< Link Accept
717         kCommandLinkAcceptAndRequest          = 2,  ///< Link Accept and Reject
718         kCommandLinkReject                    = 3,  ///< Link Reject
719         kCommandAdvertisement                 = 4,  ///< Advertisement
720         kCommandUpdate                        = 5,  ///< Update
721         kCommandUpdateRequest                 = 6,  ///< Update Request
722         kCommandDataRequest                   = 7,  ///< Data Request
723         kCommandDataResponse                  = 8,  ///< Data Response
724         kCommandParentRequest                 = 9,  ///< Parent Request
725         kCommandParentResponse                = 10, ///< Parent Response
726         kCommandChildIdRequest                = 11, ///< Child ID Request
727         kCommandChildIdResponse               = 12, ///< Child ID Response
728         kCommandChildUpdateRequest            = 13, ///< Child Update Request
729         kCommandChildUpdateResponse           = 14, ///< Child Update Response
730         kCommandAnnounce                      = 15, ///< Announce
731         kCommandDiscoveryRequest              = 16, ///< Discovery Request
732         kCommandDiscoveryResponse             = 17, ///< Discovery Response
733         kCommandLinkMetricsManagementRequest  = 18, ///< Link Metrics Management Request
734         kCommandLinkMetricsManagementResponse = 19, ///< Link Metrics Management Response
735         kCommandLinkProbe                     = 20, ///< Link Probe
736         kCommandTimeSync                      = 99, ///< Time Sync (when OPENTHREAD_CONFIG_TIME_SYNC_ENABLE enabled)
737     };
738 
739     /**
740      * Attach mode.
741      *
742      */
743     enum AttachMode : uint8_t
744     {
745         kAnyPartition,       ///< Attach to any Thread partition.
746         kSamePartition,      ///< Attach to the same Thread partition (attempt 1 when losing connectivity).
747         kSamePartitionRetry, ///< Attach to the same Thread partition (attempt 2 when losing connectivity).
748         kBetterPartition,    ///< Attach to a better (i.e. higher weight/partition id) Thread partition.
749         kDowngradeToReed,    ///< Attach to the same Thread partition during downgrade process.
750         kBetterParent,       ///< Attach to a better parent.
751     };
752 
753     /**
754      * States during attach (when searching for a parent).
755      *
756      */
757     enum AttachState : uint8_t
758     {
759         kAttachStateIdle,            ///< Not currently searching for a parent.
760         kAttachStateProcessAnnounce, ///< Waiting to process a received Announce (to switch channel/pan-id).
761         kAttachStateStart,           ///< Starting to look for a parent.
762         kAttachStateParentRequest,   ///< Send Parent Request (current number tracked by `mParentRequestCounter`).
763         kAttachStateAnnounce,        ///< Send Announce messages
764         kAttachStateChildIdRequest,  ///< Sending a Child ID Request message.
765     };
766 
767     /**
768      * States when reattaching network using stored dataset
769      *
770      */
771     enum ReattachState : uint8_t
772     {
773         kReattachStop,    ///< Reattach process is disabled or finished
774         kReattachStart,   ///< Start reattach process
775         kReattachActive,  ///< Reattach using stored Active Dataset
776         kReattachPending, ///< Reattach using stored Pending Dataset
777     };
778 
779     static constexpr uint16_t kMleMaxResponseDelay = 1000u; ///< Max delay before responding to a multicast request.
780 
781     /**
782      * This enumeration type is used in `AppendAddressRegistrationTlv()` to determine which addresses to include in the
783      * appended Address Registration TLV.
784      *
785      */
786     enum AddressRegistrationMode : uint8_t
787     {
788         kAppendAllAddresses,  ///< Append all addresses (unicast/multicast) in Address Registration TLV.
789         kAppendMeshLocalOnly, ///< Only append the Mesh Local (ML-EID) address in Address Registration TLV.
790     };
791 
792     /**
793      * This enumeration represents the message actions used in `Log()` methods.
794      *
795      */
796     enum MessageAction : uint8_t
797     {
798         kMessageSend,
799         kMessageReceive,
800         kMessageDelay,
801         kMessageRemoveDelayed,
802     };
803 
804     /**
805      * This enumeration represents message types used in `Log()` methods.
806      *
807      */
808     enum MessageType : uint8_t
809     {
810         kTypeAdvertisement,
811         kTypeAnnounce,
812         kTypeChildIdRequest,
813         kTypeChildIdRequestShort,
814         kTypeChildIdResponse,
815         kTypeChildUpdateRequestOfParent,
816         kTypeChildUpdateResponseOfParent,
817         kTypeDataRequest,
818         kTypeDataResponse,
819         kTypeDiscoveryRequest,
820         kTypeDiscoveryResponse,
821         kTypeGenericDelayed,
822         kTypeGenericUdp,
823         kTypeParentRequestToRouters,
824         kTypeParentRequestToRoutersReeds,
825         kTypeParentResponse,
826 #if OPENTHREAD_FTD
827         kTypeAddressRelease,
828         kTypeAddressReleaseReply,
829         kTypeAddressReply,
830         kTypeAddressSolicit,
831         kTypeChildUpdateRequestOfChild,
832         kTypeChildUpdateResponseOfChild,
833         kTypeChildUpdateResponseOfUnknownChild,
834         kTypeLinkAccept,
835         kTypeLinkAcceptAndRequest,
836         kTypeLinkReject,
837         kTypeLinkRequest,
838         kTypeParentRequest,
839 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
840         kTypeTimeSync,
841 #endif
842 #endif
843 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
844         kTypeLinkMetricsManagementRequest,
845         kTypeLinkMetricsManagementResponse,
846         kTypeLinkProbe,
847 #endif
848     };
849 
850     static constexpr uint8_t kMaxTlvListSize = 32; ///< Maximum number of TLVs in a `TlvList`.
851 
852     /**
853      * This type represents a list of TLVs (array of TLV types).
854      *
855      */
856     class TlvList : public Array<uint8_t, kMaxTlvListSize>
857     {
858     public:
859         /**
860          * This constructor initializes the `TlvList` as empty.
861          *
862          */
863         TlvList(void) = default;
864 
865         /**
866          * This method checks if a given TLV type is not already present in the list and adds it in the list.
867          *
868          * If the list is full, this method logs it as a warning.
869          *
870          * @param[in] aTlvType   The TLV type to add to the list.
871          *
872          */
873         void Add(uint8_t aTlvType);
874 
875         /**
876          * This method adds elements from a given list to this TLV list (if not already present in the list).
877          *
878          * @param[in] aTlvList   The TLV list to add elements from.
879          *
880          */
881         void AddElementsFrom(const TlvList &aTlvList);
882     };
883 
884     /**
885      * This type represents a Challenge (or Response) data.
886      *
887      */
888     struct Challenge
889     {
890         uint8_t mBuffer[kMaxChallengeSize]; ///< Buffer containing the challenge/response byte sequence.
891         uint8_t mLength;                    ///< Challenge length (in bytes).
892 
893         /**
894          * This method generates a cryptographically secure random sequence to populate the challenge data.
895          *
896          */
897         void GenerateRandom(void);
898 
899         /**
900          * This method indicates whether the Challenge matches a given buffer.
901          *
902          * @param[in] aBuffer   A pointer to a buffer to compare with the Challenge.
903          * @param[in] aLength   Length of @p aBuffer (in bytes).
904          *
905          * @retval TRUE  If the Challenge matches the given buffer.
906          * @retval FALSE If the Challenge does not match the given buffer.
907          *
908          */
909         bool Matches(const uint8_t *aBuffer, uint8_t aLength) const;
910 
911         /**
912          * This method indicates whether two Challenge data byte sequences are equal or not.
913          *
914          * @param[in] aOther   Another Challenge data to compare.
915          *
916          * @retval TRUE  If the two Challenges match.
917          * @retval FALSE If the two Challenges do not match.
918          *
919          */
operator ==ot::Mle::Mle::Challenge920         bool operator==(const Challenge &aOther) const { return Matches(aOther.mBuffer, aOther.mLength); }
921     };
922 
923     /**
924      * This class represents an MLE Tx message.
925      *
926      */
927     class TxMessage : public Message
928     {
929     public:
930         /**
931          * This method appends a Source Address TLV to the message.
932          *
933          * @retval kErrorNone    Successfully appended the Source Address TLV.
934          * @retval kErrorNoBufs  Insufficient buffers available to append the Source Address TLV.
935          *
936          */
937         Error AppendSourceAddressTlv(void);
938 
939         /**
940          * This method appends a Mode TLV to the message.
941          *
942          * @param[in]  aMode     The Device Mode.
943          *
944          * @retval kErrorNone    Successfully appended the Mode TLV.
945          * @retval kErrorNoBufs  Insufficient buffers available to append the Mode TLV.
946          *
947          */
948         Error AppendModeTlv(DeviceMode aMode);
949 
950         /**
951          * This method appends a Timeout TLV to the message.
952          *
953          * @param[in]  aTimeout  The Timeout value.
954          *
955          * @retval kErrorNone    Successfully appended the Timeout TLV.
956          * @retval kErrorNoBufs  Insufficient buffers available to append the Timeout TLV.
957          *
958          */
959         Error AppendTimeoutTlv(uint32_t aTimeout);
960 
961         /**
962          * This method appends a Challenge TLV to the message.
963          *
964          * @param[in]  aChallenge        A pointer to the Challenge value.
965          * @param[in]  aChallengeLength  The length of the Challenge value in bytes.
966          *
967          * @retval kErrorNone    Successfully appended the Challenge TLV.
968          * @retval kErrorNoBufs  Insufficient buffers available to append the Challenge TLV.
969          *
970          */
971         Error AppendChallengeTlv(const uint8_t *aChallenge, uint8_t aChallengeLength);
972 
973         /**
974          * This method appends a Challenge TLV to the message.
975          *
976          * @param[in] aChallenge A reference to the Challenge data.
977          *
978          * @retval kErrorNone    Successfully appended the Challenge TLV.
979          * @retval kErrorNoBufs  Insufficient buffers available to append the Challenge TLV.
980          *
981          */
982         Error AppendChallengeTlv(const Challenge &aChallenge);
983 
984         /**
985          * This method appends a Response TLV to the message.
986          *
987          * @param[in] aResponse  A reference to the Response data.
988          *
989          * @retval kErrorNone    Successfully appended the Response TLV.
990          * @retval kErrorNoBufs  Insufficient buffers available to append the Response TLV.
991          *
992          */
993         Error AppendResponseTlv(const Challenge &aResponse);
994 
995         /**
996          * This method appends a Link Frame Counter TLV to the message.
997          *
998          * @retval kErrorNone     Successfully appended the Link Frame Counter TLV.
999          * @retval kErrorNoBufs   Insufficient buffers available to append the Link Frame Counter TLV.
1000          *
1001          */
1002         Error AppendLinkFrameCounterTlv(void);
1003 
1004         /**
1005          * This method appends an MLE Frame Counter TLV to the message.
1006          *
1007          * @retval kErrorNone     Successfully appended the Frame Counter TLV.
1008          * @retval kErrorNoBufs   Insufficient buffers available to append the MLE Frame Counter TLV.
1009          *
1010          */
1011         Error AppendMleFrameCounterTlv(void);
1012 
1013         /**
1014          * This method appends an Address16 TLV to the message.
1015          *
1016          * @param[in]  aRloc16    The RLOC16 value.
1017          *
1018          * @retval kErrorNone     Successfully appended the Address16 TLV.
1019          * @retval kErrorNoBufs   Insufficient buffers available to append the Address16 TLV.
1020          *
1021          */
1022         Error AppendAddress16Tlv(uint16_t aRloc16);
1023 
1024         /**
1025          * This method appends a Network Data TLV to the message.
1026          *
1027          * @param[in]  aType      The Network Data type to append, full set or stable subset.
1028          *
1029          * @retval kErrorNone     Successfully appended the Network Data TLV.
1030          * @retval kErrorNoBufs   Insufficient buffers available to append the Network Data TLV.
1031          *
1032          */
1033         Error AppendNetworkDataTlv(NetworkData::Type aType);
1034 
1035         /**
1036          * This method appends a TLV Request TLV to the message.
1037          *
1038          * @param[in]  aTlvs        A pointer to the list of TLV types.
1039          * @param[in]  aTlvsLength  The number of TLV types in @p aTlvs
1040          *
1041          * @retval kErrorNone     Successfully appended the TLV Request TLV.
1042          * @retval kErrorNoBufs   Insufficient buffers available to append the TLV Request TLV.
1043          *
1044          */
1045         Error AppendTlvRequestTlv(const uint8_t *aTlvs, uint8_t aTlvsLength);
1046 
1047         /**
1048          * This method appends a TLV Request TLV to the message.
1049          *
1050          * @tparam kArrayLength     The TLV array length.
1051          *
1052          * @param[in]  aTlvArray    A reference to an array of TLV types of @p kArrayLength length.
1053          *
1054          * @retval kErrorNone     Successfully appended the TLV Request TLV.
1055          * @retval kErrorNoBufs   Insufficient buffers available to append the TLV Request TLV.
1056          *
1057          */
AppendTlvRequestTlv(const uint8_t (& aTlvArray)[kArrayLength])1058         template <uint8_t kArrayLength> Error AppendTlvRequestTlv(const uint8_t (&aTlvArray)[kArrayLength])
1059         {
1060             return AppendTlvRequestTlv(aTlvArray, kArrayLength);
1061         }
1062 
1063         /**
1064          * This method appends a Leader Data TLV to the message.
1065          *
1066          * @retval kErrorNone     Successfully appended the Leader Data TLV.
1067          * @retval kErrorNoBufs   Insufficient buffers available to append the Leader Data TLV.
1068          *
1069          */
1070         Error AppendLeaderDataTlv(void);
1071 
1072         /**
1073          * This method appends a Scan Mask TLV to th message.
1074          *
1075          * @param[in]  aScanMask  The Scan Mask value.
1076          *
1077          * @retval kErrorNone     Successfully appended the Scan Mask TLV.
1078          * @retval kErrorNoBufs   Insufficient buffers available to append the Scan Mask TLV.
1079          *
1080          */
1081         Error AppendScanMaskTlv(uint8_t aScanMask);
1082 
1083         /**
1084          * This method appends a Status TLV to the message.
1085          *
1086          * @param[in] aStatus     The Status value.
1087          *
1088          * @retval kErrorNone     Successfully appended the Status TLV.
1089          * @retval kErrorNoBufs   Insufficient buffers available to append the Status TLV.
1090          *
1091          */
1092         Error AppendStatusTlv(StatusTlv::Status aStatus);
1093 
1094         /**
1095          * This method appends a Link Margin TLV to the message.
1096          *
1097          * @param[in] aLinkMargin The Link Margin value.
1098          *
1099          * @retval kErrorNone     Successfully appended the Link Margin TLV.
1100          * @retval kErrorNoBufs   Insufficient buffers available to append the Link Margin TLV.
1101          *
1102          */
1103         Error AppendLinkMarginTlv(uint8_t aLinkMargin);
1104 
1105         /**
1106          * This method appends a Version TLV to the message.
1107          *
1108          * @retval kErrorNone     Successfully appended the Version TLV.
1109          * @retval kErrorNoBufs   Insufficient buffers available to append the Version TLV.
1110          *
1111          */
1112         Error AppendVersionTlv(void);
1113 
1114         /**
1115          * This method appends an Address Registration TLV to the message.
1116          *
1117          * @param[in]  aMode      Determines which addresses to include in the TLV (see `AddressRegistrationMode`).
1118          *
1119          * @retval kErrorNone     Successfully appended the Address Registration TLV.
1120          * @retval kErrorNoBufs   Insufficient buffers available to append the Address Registration TLV.
1121          *
1122          */
1123         Error AppendAddressRegistrationTlv(AddressRegistrationMode aMode = kAppendAllAddresses);
1124 
1125         /**
1126          * This method appends a Supervision Interval TLV to the message.
1127          *
1128          * @param[in]  aInterval  The interval value.
1129          *
1130          * @retval kErrorNone    Successfully appended the Supervision Interval TLV.
1131          * @retval kErrorNoBufs  Insufficient buffers available to append the Supervision Interval TLV.
1132          *
1133          */
1134         Error AppendSupervisionIntervalTlv(uint16_t aInterval);
1135 
1136 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1137         /**
1138          * This method appends a Time Request TLV to the message.
1139          *
1140          * @retval kErrorNone     Successfully appended the Time Request TLV.
1141          * @retval kErrorNoBufs   Insufficient buffers available to append the Time Request TLV.
1142          *
1143          */
1144         Error AppendTimeRequestTlv(void);
1145 
1146         /**
1147          * This method appends a Time Parameter TLV to the message.
1148          *
1149          * @retval kErrorNone     Successfully appended the Time Parameter TLV.
1150          * @retval kErrorNoBufs   Insufficient buffers available to append the Time Parameter TLV.
1151          *
1152          */
1153         Error AppendTimeParameterTlv(void);
1154 #endif
1155         /**
1156          * This method appends a XTAL Accuracy TLV to the message.
1157          *
1158          * @retval kErrorNone     Successfully appended the XTAL Accuracy TLV.
1159          * @retval kErrorNoBufs   Insufficient buffers available to append the XTAl Accuracy TLV.
1160          *
1161          */
1162         Error AppendXtalAccuracyTlv(void);
1163 
1164 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1165         /**
1166          * This method appends a CSL Channel TLV to the message.
1167          *
1168          * @retval kErrorNone     Successfully appended the CSL Channel TLV.
1169          * @retval kErrorNoBufs   Insufficient buffers available to append the CSL Channel TLV.
1170          *
1171          */
1172         Error AppendCslChannelTlv(void);
1173 
1174         /**
1175          * This method appends a CSL Sync Timeout TLV to the message.
1176          *
1177          * @retval kErrorNone     Successfully appended the CSL Timeout TLV.
1178          * @retval kErrorNoBufs   Insufficient buffers available to append the CSL Timeout TLV.
1179          *
1180          */
1181         Error AppendCslTimeoutTlv(void);
1182 #endif
1183 
1184 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
1185         /**
1186          * This method appends a CSL Clock Accuracy TLV to the message.
1187          *
1188          * @retval kErrorNone     Successfully appended the CSL Accuracy TLV.
1189          * @retval kErrorNoBufs   Insufficient buffers available to append the CSL Accuracy TLV.
1190          *
1191          */
1192         Error AppendCslClockAccuracyTlv(void);
1193 #endif
1194 
1195         /**
1196          * This method appends a Active Timestamp TLV to the message.
1197          *
1198          * @retval kErrorNone     Successfully appended the Active Timestamp TLV.
1199          * @retval kErrorNoBufs   Insufficient buffers available to append the Active Timestamp TLV.
1200          *
1201          */
1202         Error AppendActiveTimestampTlv(void);
1203 
1204         /**
1205          * This method appends a Pending Timestamp TLV to the message.
1206          *
1207          * @retval kErrorNone     Successfully appended the Pending Timestamp TLV.
1208          * @retval kErrorNoBufs   Insufficient buffers available to append the Pending Timestamp TLV.
1209          *
1210          */
1211         Error AppendPendingTimestampTlv(void);
1212 
1213 #if OPENTHREAD_FTD
1214         /**
1215          * This method appends a Route TLV to the message.
1216          *
1217          * @param[in] aNeighbor   A pointer to the intended destination  (can be `nullptr`).
1218          *
1219          * @retval kErrorNone     Successfully appended the Route TLV.
1220          * @retval kErrorNoBufs   Insufficient buffers available to append the Route TLV.
1221          *
1222          */
1223         Error AppendRouteTlv(Neighbor *aNeighbor = nullptr);
1224 
1225         /**
1226          * This method appends a Active Dataset TLV to the message.
1227          *
1228          * @retval kErrorNone     Successfully appended the Active Dataset TLV.
1229          * @retval kErrorNoBufs   Insufficient buffers available to append the Active Dataset TLV.
1230          *
1231          */
1232         Error AppendActiveDatasetTlv(void);
1233 
1234         /**
1235          * This method appends a Pending Dataset TLV to the message.
1236          *
1237          * @retval kErrorNone     Successfully appended the Pending Dataset TLV.
1238          * @retval kErrorNoBufs   Insufficient buffers available to append the Pending Dataset TLV.
1239          *
1240          */
1241         Error AppendPendingDatasetTlv(void);
1242 
1243         /**
1244          * This method appends a Connectivity TLV to the message.
1245          *
1246          * @retval kErrorNone     Successfully appended the Connectivity TLV.
1247          * @retval kErrorNoBufs   Insufficient buffers available to append the Connectivity TLV.
1248          *
1249          */
1250         Error AppendConnectivityTlv(void);
1251 
1252         /**
1253          * This method appends a Address Registration TLV to the message with addresses from a given child.
1254          *
1255          * @param[in] aChild  The child to include its list of addresses in the Address Registration TLV.
1256          *
1257          * @retval kErrorNone     Successfully appended the Connectivity TLV.
1258          * @retval kErrorNoBufs   Insufficient buffers available to append the Connectivity TLV.
1259          *
1260          */
1261         Error AppendAddressRegistrationTlv(Child &aChild);
1262 #endif // OPENTHREAD_FTD
1263 
1264         /**
1265          * This method submits the MLE message to the UDP socket to be sent.
1266          *
1267          * @param[in]  aDestination  A reference to the IPv6 address of the destination.
1268          *
1269          * @retval kErrorNone     Successfully submitted the MLE message.
1270          * @retval kErrorNoBufs   Insufficient buffers to form the rest of the MLE message.
1271          *
1272          */
1273         Error SendTo(const Ip6::Address &aDestination);
1274 
1275         /**
1276          * This method enqueues the message to be sent after a given delay.
1277          *
1278          * @param[in]  aDestination         The IPv6 address of the recipient of the message.
1279          * @param[in]  aDelay               The delay in milliseconds before transmission of the message.
1280          *
1281          * @retval kErrorNone     Successfully queued the message to transmit after the delay.
1282          * @retval kErrorNoBufs   Insufficient buffers to queue the message.
1283          *
1284          */
1285         Error SendAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay);
1286 
1287     private:
1288         Error AppendCompressedAddressEntry(uint8_t aContextId, const Ip6::Address &aAddress);
1289         Error AppendAddressEntry(const Ip6::Address &aAddress);
1290     };
1291 
1292     /**
1293      * This class represents an MLE Rx message.
1294      *
1295      */
1296     class RxMessage : public Message
1297     {
1298     public:
1299         /**
1300          * This method reads Challenge TLV from the message.
1301          *
1302          * @param[out] aChallenge        A reference to the Challenge data where to output the read value.
1303          *
1304          * @retval kErrorNone       Successfully read the Challenge TLV.
1305          * @retval kErrorNotFound   Challenge TLV was not found in the message.
1306          * @retval kErrorParse      Challenge TLV was found but could not be parsed.
1307          *
1308          */
1309         Error ReadChallengeTlv(Challenge &aChallenge) const;
1310 
1311         /**
1312          * This method reads Response TLV from the message.
1313          *
1314          * @param[out] aResponse        A reference to the Response data where to output the read value.
1315          *
1316          * @retval kErrorNone       Successfully read the Response TLV.
1317          * @retval kErrorNotFound   Response TLV was not found in the message.
1318          * @retval kErrorParse      Response TLV was found but could not be parsed.
1319          *
1320          */
1321         Error ReadResponseTlv(Challenge &aResponse) const;
1322 
1323         /**
1324          * This method reads Link and MLE Frame Counters from the message.
1325          *
1326          * Link Frame Counter TLV must be present in the message and its value is read into @p aLinkFrameCounter. If MLE
1327          * Frame Counter TLV is present in the message, its value is read into @p aMleFrameCounter. If the MLE Frame
1328          * Counter TLV is not present in the message, then @p aMleFrameCounter is set to the same value as
1329          * @p aLinkFrameCounter.
1330          *
1331          * @param[out] aLinkFrameCounter  A reference to an `uint32_t` to output the Link Frame Counter.
1332          * @param[out] aMleFrameCounter   A reference to an `uint32_t` to output the MLE Frame Counter.
1333          *
1334          * @retval kErrorNone       Successfully read the counters.
1335          * @retval kErrorNotFound   Link Frame Counter TLV was not found in the message.
1336          * @retval kErrorParse      TLVs are not well-formed.
1337          *
1338          */
1339         Error ReadFrameCounterTlvs(uint32_t &aLinkFrameCounter, uint32_t &aMleFrameCounter) const;
1340 
1341         /**
1342          * This method reads TLV Request TLV from the message.
1343          *
1344          * @param[out] aTlvList     A reference to output the read list of requested TLVs.
1345          *
1346          * @retval kErrorNone       Successfully read the TLV.
1347          * @retval kErrorNotFound   TLV was not found in the message.
1348          * @retval kErrorParse      TLV was found but could not be parsed.
1349          *
1350          */
1351         Error ReadTlvRequestTlv(TlvList &aTlvList) const;
1352 
1353         /**
1354          * This method reads Leader Data TLV from a message.
1355          *
1356          * @param[out] aLeaderData     A reference to output the Leader Data.
1357          *
1358          * @retval kErrorNone       Successfully read the TLV.
1359          * @retval kErrorNotFound   TLV was not found in the message.
1360          * @retval kErrorParse      TLV was found but could not be parsed.
1361          *
1362          */
1363         Error ReadLeaderDataTlv(LeaderData &aLeaderData) const;
1364 
1365 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1366         /**
1367          * This method reads CSL Clock Accuracy TLV from a message.
1368          *
1369          * @param[out] aCslAccuracy A reference to output the CSL accuracy.
1370          *
1371          * @retval kErrorNone       Successfully read the TLV.
1372          * @retval kErrorNotFound   TLV was not found in the message.
1373          * @retval kErrorParse      TLV was found but could not be parsed.
1374          *
1375          */
1376         Error ReadCslClockAccuracyTlv(Mac::CslAccuracy &aCslAccuracy) const;
1377 #endif
1378 
1379 #if OPENTHREAD_FTD
1380         /**
1381          * This method reads and validates Route TLV from a message.
1382          *
1383          * @param[out] aRouteTlv    A reference to output the read Route TLV.
1384          *
1385          * @retval kErrorNone       Successfully read and validated the Route TLV.
1386          * @retval kErrorNotFound   TLV was not found in the message.
1387          * @retval kErrorParse      TLV was found but could not be parsed or is not valid.
1388          *
1389          */
1390         Error ReadRouteTlv(RouteTlv &aRouteTlv) const;
1391 #endif
1392 
1393     private:
1394         Error ReadChallengeOrResponse(uint8_t aTlvType, Challenge &aBuffer) const;
1395     };
1396 
1397     /**
1398      * This structure represents a received MLE message containing additional information about the message (e.g.
1399      * key sequence, neighbor from which it was received).
1400      *
1401      */
1402     struct RxInfo
1403     {
1404         /**
1405          * This enumeration represents a received MLE message class.
1406          *
1407          */
1408         enum Class : uint8_t
1409         {
1410             kUnknown,              ///< Unknown (default value, also indicates MLE message parse error).
1411             kAuthoritativeMessage, ///< Authoritative message (larger received key seq MUST be adopted).
1412             kPeerMessage,          ///< Peer message (adopt only if from a known neighbor and is greater by one).
1413         };
1414 
1415         /**
1416          * This constructor initializes the `RxInfo`.
1417          *
1418          * @param[in] aMessage       The received MLE message.
1419          * @param[in] aMessageInfo   The `Ip6::MessageInfo` associated with message.
1420          *
1421          */
RxInfoot::Mle::Mle::RxInfo1422         RxInfo(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
1423             : mMessage(static_cast<RxMessage &>(aMessage))
1424             , mMessageInfo(aMessageInfo)
1425             , mFrameCounter(0)
1426             , mKeySequence(0)
1427             , mNeighbor(nullptr)
1428             , mClass(kUnknown)
1429         {
1430         }
1431 
1432         /**
1433          * This method indicates whether the `mNeighbor` (neighbor from which message was received) is non-null and
1434          * in valid state.
1435          *
1436          * @retval TRUE  If `mNeighbor` is non-null and in valid state.
1437          * @retval FALSE If `mNeighbor` is `nullptr` or not in valid state.
1438          *
1439          */
IsNeighborStateValidot::Mle::Mle::RxInfo1440         bool IsNeighborStateValid(void) const { return (mNeighbor != nullptr) && mNeighbor->IsStateValid(); }
1441 
1442         RxMessage              &mMessage;      ///< The MLE message.
1443         const Ip6::MessageInfo &mMessageInfo;  ///< The `MessageInfo` associated with the message.
1444         uint32_t                mFrameCounter; ///< The frame counter from aux security header.
1445         uint32_t                mKeySequence;  ///< The key sequence from aux security header.
1446         Neighbor               *mNeighbor;     ///< Neighbor from which message was received (can be `nullptr`).
1447         Class                   mClass;        ///< The message class (authoritative, peer, or unknown).
1448     };
1449 
1450     /**
1451      * This method allocates and initializes new MLE message for a given command.
1452      *
1453      * @param[in] aCommand   The MLE command.
1454      *
1455      * @returns A pointer to the message or `nullptr` if insufficient message buffers are available.
1456      *
1457      */
1458     TxMessage *NewMleMessage(Command aCommand);
1459 
1460     /**
1461      * This method sets the device role.
1462      *
1463      * @param[in] aRole A device role.
1464      *
1465      */
1466     void SetRole(DeviceRole aRole);
1467 
1468     /**
1469      * This method causes the Thread interface to attempt an MLE attach.
1470      *
1471      * @param[in]  aMode  Indicates what partitions to attach to.
1472      *
1473      */
1474     void Attach(AttachMode aMode);
1475 
1476     /**
1477      * This method sets the attach state
1478      *
1479      * @param[in] aState An attach state
1480      *
1481      */
1482     void SetAttachState(AttachState aState);
1483 
1484     /**
1485      * This method initializes a given @p aNeighbor with information from @p aRxInfo.
1486      *
1487      * This method updates the following properties on @p aNeighbor from @p aRxInfo:
1488      *
1489      * - Sets the Extended MAC address from `MessageInfo` peer IPv6 address IID.
1490      * - Clears the `GetLinkInfo()` and adds RSS from the `GetThreadLinkInfo()`.
1491      * - Resets the link failure counter (`ResetLinkFailures()`).
1492      * - Sets the "last heard" time to now (`SetLastHeard()`).
1493      *
1494      * @param[in,out] aNeighbor   The `Neighbor` to initialize.
1495      * @param[in]     aRxInfo     The `RxtInfo` to use for initialization.
1496      *
1497      */
1498     void InitNeighbor(Neighbor &aNeighbor, const RxInfo &aRxInfo);
1499 
1500     /**
1501      * This method clears the parent candidate.
1502      *
1503      */
ClearParentCandidate(void)1504     void ClearParentCandidate(void) { mParentCandidate.Clear(); }
1505 
1506     /**
1507      * This method checks if the destination is reachable.
1508      *
1509      * @param[in]  aMeshDest   The RLOC16 of the destination.
1510      * @param[in]  aIp6Header  The IPv6 header of the message.
1511      *
1512      * @retval kErrorNone      The destination is reachable.
1513      * @retval kErrorNoRoute   The destination is not reachable and the message should be dropped.
1514      *
1515      */
1516     Error CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6Header);
1517 
1518     /**
1519      * This method returns the next hop towards an RLOC16 destination.
1520      *
1521      * @param[in]  aDestination  The RLOC16 of the destination.
1522      *
1523      * @returns A RLOC16 of the next hop if a route is known, kInvalidRloc16 otherwise.
1524      *
1525      */
1526     Mac::ShortAddress GetNextHop(uint16_t aDestination) const;
1527 
1528     /**
1529      * This method generates an MLE Data Request message.
1530      *
1531      * @param[in]  aDestination      The IPv6 destination address.
1532      *
1533      * @retval kErrorNone     Successfully generated an MLE Data Request message.
1534      * @retval kErrorNoBufs   Insufficient buffers to generate the MLE Data Request message.
1535      *
1536      */
1537     Error SendDataRequest(const Ip6::Address &aDestination);
1538 
1539 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
1540     /**
1541      * This method generates an MLE Data Request message which request Link Metrics Report TLV.
1542      *
1543      * @param[in]  aDestination      A reference to the IPv6 address of the destination.
1544      * @param[in]  aQueryInfo        A Link Metrics query info.
1545      *
1546      * @retval kErrorNone     Successfully generated an MLE Data Request message.
1547      * @retval kErrorNoBufs   Insufficient buffers to generate the MLE Data Request message.
1548      *
1549      */
1550     Error SendDataRequestForLinkMetricsReport(const Ip6::Address                      &aDestination,
1551                                               const LinkMetrics::Initiator::QueryInfo &aQueryInfo);
1552 #endif
1553 
1554     /**
1555      * This method generates an MLE Child Update Request message.
1556      *
1557      * @retval kErrorNone    Successfully generated an MLE Child Update Request message.
1558      * @retval kErrorNoBufs  Insufficient buffers to generate the MLE Child Update Request message.
1559      *
1560      */
1561     Error SendChildUpdateRequest(void);
1562 
1563     /**
1564      * This method generates an MLE Child Update Response message.
1565      *
1566      * @param[in]  aTlvList      A list of requested TLV types.
1567      * @param[in]  aChallenge    The Challenge for the response.
1568      *
1569      * @retval kErrorNone     Successfully generated an MLE Child Update Response message.
1570      * @retval kErrorNoBufs   Insufficient buffers to generate the MLE Child Update Response message.
1571      *
1572      */
1573     Error SendChildUpdateResponse(const TlvList &aTlvList, const Challenge &aChallenge);
1574 
1575     /**
1576      * This method sets the RLOC16 assigned to the Thread interface.
1577      *
1578      * @param[in]  aRloc16  The RLOC16 to set.
1579      *
1580      */
1581     void SetRloc16(uint16_t aRloc16);
1582 
1583     /**
1584      * This method sets the Device State to Detached.
1585      *
1586      */
1587     void SetStateDetached(void);
1588 
1589     /**
1590      * This method sets the Device State to Child.
1591      *
1592      */
1593     void SetStateChild(uint16_t aRloc16);
1594 
1595     /**
1596      * This method sets the Leader's Partition ID, Weighting, and Router ID values.
1597      *
1598      * @param[in]  aPartitionId     The Leader's Partition ID value.
1599      * @param[in]  aWeighting       The Leader's Weighting value.
1600      * @param[in]  aLeaderRouterId  The Leader's Router ID value.
1601      *
1602      */
1603     void SetLeaderData(uint32_t aPartitionId, uint8_t aWeighting, uint8_t aLeaderRouterId);
1604 
1605 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
1606     /**
1607      * This static method emits a log message with an IPv6 address.
1608      *
1609      * @param[in]  aAction     The message action (send/receive/delay, etc).
1610      * @param[in]  aType       The message type.
1611      * @param[in]  aAddress    The IPv6 address of the peer.
1612      *
1613      */
1614     static void Log(MessageAction aAction, MessageType aType, const Ip6::Address &aAddress);
1615 
1616     /**
1617      * This static method emits a log message with an IPv6 address and RLOC16.
1618      *
1619      * @param[in]  aAction     The message action (send/receive/delay, etc).
1620      * @param[in]  aType       The message type.
1621      * @param[in]  aAddress    The IPv6 address of the peer.
1622      * @param[in]  aRloc       The RLOC16.
1623      *
1624      */
1625     static void Log(MessageAction aAction, MessageType aType, const Ip6::Address &aAddress, uint16_t aRloc);
1626 #else
Log(MessageAction,MessageType,const Ip6::Address &)1627     static void Log(MessageAction, MessageType, const Ip6::Address &) {}
Log(MessageAction,MessageType,const Ip6::Address &,uint16_t)1628     static void Log(MessageAction, MessageType, const Ip6::Address &, uint16_t) {}
1629 #endif // #if OT_SHOULD_LOG_AT( OT_LOG_LEVEL_INFO)
1630 
1631 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
1632     /**
1633      * This static method emits a log message indicating an error in processing of a message.
1634      *
1635      * Note that log message is emitted only if there is an error, i.e., @p aError is not `kErrorNone`. The log
1636      * message will have the format "Failed to process {aMessageString} : {ErrorString}".
1637      *
1638      * @param[in]  aType      The message type.
1639      * @param[in]  aError     The error in processing of the message.
1640      *
1641      */
1642     static void LogProcessError(MessageType aType, Error aError);
1643 
1644     /**
1645      * This static method emits a log message indicating an error when sending a message.
1646      *
1647      * Note that log message is emitted only if there is an error, i.e. @p aError is not `kErrorNone`. The log
1648      * message will have the format "Failed to send {Message Type} : {ErrorString}".
1649      *
1650      * @param[in]  aType    The message type.
1651      * @param[in]  aError   The error in sending the message.
1652      *
1653      */
1654     static void LogSendError(MessageType aType, Error aError);
1655 #else
LogProcessError(MessageType,Error)1656     static void LogProcessError(MessageType, Error) {}
LogSendError(MessageType,Error)1657     static void LogSendError(MessageType, Error) {}
1658 #endif // #if OT_SHOULD_LOG_AT( OT_LOG_LEVEL_WARN)
1659 
1660     /**
1661      * This method triggers MLE Announce on previous channel after the Thread device successfully
1662      * attaches and receives the new Active Commissioning Dataset if needed.
1663      *
1664      * MTD would send Announce immediately after attached.
1665      * FTD would delay to send Announce after tried to become Router or decided to stay in REED role.
1666      *
1667      */
1668     void InformPreviousChannel(void);
1669 
1670     /**
1671      * This method indicates whether or not in announce attach process.
1672      *
1673      * @retval true if attaching/attached on the announced parameters, false otherwise.
1674      *
1675      */
IsAnnounceAttach(void) const1676     bool IsAnnounceAttach(void) const { return mAlternatePanId != Mac::kPanIdBroadcast; }
1677 
1678 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE)
1679     /**
1680      * This method converts an `AttachMode` enumeration value into a human-readable string.
1681      *
1682      * @param[in] aMode An attach mode
1683      *
1684      * @returns A human-readable string corresponding to the attach mode.
1685      *
1686      */
1687     static const char *AttachModeToString(AttachMode aMode);
1688 
1689     /**
1690      * This method converts an `AttachState` enumeration value into a human-readable string.
1691      *
1692      * @param[in] aState An attach state
1693      *
1694      * @returns A human-readable string corresponding to the attach state.
1695      *
1696      */
1697     static const char *AttachStateToString(AttachState aState);
1698 
1699     /**
1700      * This method converts a `ReattachState` enumeration value into a human-readable string.
1701      *
1702      * @param[in] aState A reattach state
1703      *
1704      * @returns A human-readable string corresponding to the reattach state.
1705      *
1706      */
1707     static const char *ReattachStateToString(ReattachState aState);
1708 #endif
1709 
1710 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
1711     /**
1712      * This method sends a Link Metrics Management Request message.
1713      *
1714      * @param[in]  aDestination  A reference to the IPv6 address of the destination.
1715      * @param[in]  aSubTlv       A reference to the sub-TLV to include.
1716      *
1717      * @retval kErrorNone     Successfully sent a Link Metrics Management Request.
1718      * @retval kErrorNoBufs   Insufficient buffers to generate the MLE Link Metrics Management Request message.
1719      *
1720      */
1721     Error SendLinkMetricsManagementRequest(const Ip6::Address &aDestination, const ot::Tlv &aSubTlv);
1722 
1723     /**
1724      * This method sends an MLE Link Probe message.
1725      *
1726      * @param[in]  aDestination  A reference to the IPv6 address of the destination.
1727      * @param[in]  aSeriesId     The Series ID [1, 254] which the Probe message targets at.
1728      * @param[in]  aBuf          A pointer to the data payload.
1729      * @param[in]  aLength       The length of the data payload in Link Probe TLV, [0, 64].
1730      *
1731      * @retval kErrorNone         Successfully sent a Link Metrics Management Request.
1732      * @retval kErrorNoBufs       Insufficient buffers to generate the MLE Link Metrics Management Request message.
1733      * @retval kErrorInvalidArgs  Series ID is not a valid value, not within range [1, 254].
1734      *
1735      */
1736     Error SendLinkProbe(const Ip6::Address &aDestination, uint8_t aSeriesId, uint8_t *aBuf, uint8_t aLength);
1737 
1738 #endif
1739 
1740     void ScheduleMessageTransmissionTimer(void);
1741 
1742 private:
1743     // Declare early so we can use in as `TimerMilli` callbacks.
1744     void HandleAttachTimer(void);
1745     void HandleDelayedResponseTimer(void);
1746     void HandleMessageTransmissionTimer(void);
1747 
1748 protected:
1749     using AttachTimer = TimerMilliIn<Mle, &Mle::HandleAttachTimer>;
1750     using DelayTimer  = TimerMilliIn<Mle, &Mle::HandleDelayedResponseTimer>;
1751     using MsgTxTimer  = TimerMilliIn<Mle, &Mle::HandleMessageTransmissionTimer>;
1752 
1753     Ip6::Netif::UnicastAddress mLeaderAloc; ///< Leader anycast locator
1754 
1755     LeaderData    mLeaderData;                 ///< Last received Leader Data TLV.
1756     bool          mRetrieveNewNetworkData : 1; ///< Indicating new Network Data is needed if set.
1757     bool          mRequestRouteTlv : 1;        ///< Request Route TLV when sending Data Request.
1758     DeviceRole    mRole;                       ///< Current Thread role.
1759     Parent        mParent;                     ///< Parent information.
1760     NeighborTable mNeighborTable;              ///< The neighbor table.
1761     DeviceMode    mDeviceMode;                 ///< Device mode setting.
1762     AttachState   mAttachState;                ///< The attach state.
1763     uint8_t       mParentRequestCounter;       ///< Number of parent requests while in `kAttachStateParentRequest`.
1764     ReattachState mReattachState;              ///< Reattach state
1765     uint16_t      mAttachCounter;              ///< Attach attempt counter.
1766     uint16_t      mAnnounceDelay;              ///< Delay in between sending Announce messages during attach.
1767     AttachTimer   mAttachTimer;                ///< The timer for driving the attach process.
1768     DelayTimer    mDelayedResponseTimer;       ///< The timer to delay MLE responses.
1769     MsgTxTimer    mMessageTransmissionTimer;   ///< The timer for (re-)sending of MLE messages (e.g. Child Update).
1770 #if OPENTHREAD_FTD
1771     uint8_t mLinkRequestAttempts; ///< Number of remaining link requests to send after reset.
1772     bool    mWasLeader;           ///< Indicating if device was leader before reset.
1773 #endif
1774 
1775 private:
1776     static constexpr uint8_t kMleHopLimit        = 255;
1777     static constexpr uint8_t kMleSecurityTagSize = 4; // Security tag size in bytes.
1778 
1779     // Parameters for "attach backoff" feature (CONFIG_ENABLE_ATTACH_BACKOFF) - Intervals are in milliseconds.
1780     static constexpr uint32_t kAttachBackoffMinInterval = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MINIMUM_INTERVAL;
1781     static constexpr uint32_t kAttachBackoffMaxInterval = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MAXIMUM_INTERVAL;
1782     static constexpr uint32_t kAttachBackoffJitter      = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_JITTER_INTERVAL;
1783     static constexpr uint32_t kAttachBackoffDelayToResetCounter =
1784         OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_DELAY_TO_RESET_BACKOFF_INTERVAL;
1785 
1786 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_3
1787     // First attach cycle includes two Parent Requests to routers, followed by four to routers and REEDs.
1788     static constexpr uint8_t kFirstAttachCycleTotalParentRequests       = 6;
1789     static constexpr uint8_t kFirstAttachCycleNumParentRequestToRouters = 2;
1790 #else
1791     // First attach cycle in Thread 1.1/1.2 includes a Parent Requests to routers, followed by one to routers and REEDs.
1792     static constexpr uint8_t kFirstAttachCycleTotalParentRequests       = 2;
1793     static constexpr uint8_t kFirstAttachCycleNumParentRequestToRouters = 1;
1794 #endif
1795 
1796     // Next attach cycles includes one Parent Request to routers, followed by one to routers and REEDs.
1797     static constexpr uint8_t kNextAttachCycleTotalParentRequests       = 2;
1798     static constexpr uint8_t kNextAttachCycleNumParentRequestToRouters = 1;
1799 
1800     static constexpr uint32_t kDetachGracefullyTimeout = 1000;
1801 
1802     static constexpr uint32_t kStoreFrameCounterAhead   = OPENTHREAD_CONFIG_STORE_FRAME_COUNTER_AHEAD;
1803     static constexpr uint8_t  kMaxIpAddressesToRegister = OPENTHREAD_CONFIG_MLE_IP_ADDRS_TO_REGISTER;
1804     static constexpr uint32_t kDefaultCslTimeout        = OPENTHREAD_CONFIG_CSL_TIMEOUT;
1805 
1806     enum StartMode : uint8_t // Used in `Start()`.
1807     {
1808         kNormalAttach,
1809         kAnnounceAttach, // Try to attach on the announced thread network with newer active timestamp.
1810     };
1811 
1812     enum StopMode : uint8_t // Used in `Stop()`.
1813     {
1814         kKeepNetworkDatasets,
1815         kUpdateNetworkDatasets,
1816     };
1817 
1818     enum AnnounceMode : uint8_t // Used in `SendAnnounce()`
1819     {
1820         kNormalAnnounce,
1821         kOrphanAnnounce,
1822     };
1823 
1824     enum ParentRequestType : uint8_t
1825     {
1826         kToRouters,         // Parent Request to routers only.
1827         kToRoutersAndReeds, // Parent Request to all routers and REEDs.
1828     };
1829 
1830     enum ChildUpdateRequestState : uint8_t
1831     {
1832         kChildUpdateRequestNone,    // No pending or active Child Update Request.
1833         kChildUpdateRequestPending, // Pending Child Update Request due to relative OT_CHANGED event.
1834         kChildUpdateRequestActive,  // Child Update Request has been sent and Child Update Response is expected.
1835     };
1836 
1837     enum ChildUpdateRequestMode : uint8_t // Used in `SendChildUpdateRequest()`
1838     {
1839         kNormalChildUpdateRequest, // Normal Child Update Request.
1840         kAppendChallengeTlv,       // Append Challenge TLV to Child Update Request even if currently attached.
1841         kAppendZeroTimeout,        // Use zero timeout when appending Timeout TLV (used for graceful detach).
1842     };
1843 
1844     enum DataRequestState : uint8_t
1845     {
1846         kDataRequestNone,   // Not waiting for a Data Response.
1847         kDataRequestActive, // Data Request has been sent, Data Response is expected.
1848     };
1849 
1850     enum SecuritySuite : uint8_t
1851     {
1852         k154Security = 0,   // Security suite value indicating that MLE message is not secured.
1853         kNoSecurity  = 255, // Security suite value indicating that MLE message is secured.
1854     };
1855 
1856     struct DelayedResponseMetadata
1857     {
AppendToot::Mle::Mle::DelayedResponseMetadata1858         Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); }
1859         void  ReadFrom(const Message &aMessage);
1860         void  RemoveFrom(Message &aMessage) const;
1861 
1862         Ip6::Address mDestination; // IPv6 address of the message destination.
1863         TimeMilli    mSendTime;    // Time when the message shall be sent.
1864     };
1865 
1866     OT_TOOL_PACKED_BEGIN
1867     class SecurityHeader
1868     {
1869     public:
InitSecurityControl(void)1870         void InitSecurityControl(void) { mSecurityControl = kKeyIdMode2Mic32; }
IsSecurityControlValid(void) const1871         bool IsSecurityControlValid(void) const { return (mSecurityControl == kKeyIdMode2Mic32); }
1872 
GetFrameCounter(void) const1873         uint32_t GetFrameCounter(void) const { return Encoding::LittleEndian::HostSwap32(mFrameCounter); }
SetFrameCounter(uint32_t aCounter)1874         void     SetFrameCounter(uint32_t aCounter) { mFrameCounter = Encoding::LittleEndian::HostSwap32(aCounter); }
1875 
GetKeyId(void) const1876         uint32_t GetKeyId(void) const { return Encoding::BigEndian::HostSwap32(mKeySource); }
SetKeyId(uint32_t aKeySequence)1877         void     SetKeyId(uint32_t aKeySequence)
1878         {
1879             mKeySource = Encoding::BigEndian::HostSwap32(aKeySequence);
1880             mKeyIndex  = (aKeySequence & 0x7f) + 1;
1881         }
1882 
1883     private:
1884         static constexpr uint8_t kKeyIdMode2Mic32 =
1885             static_cast<uint8_t>(Mac::Frame::kKeyIdMode2) | static_cast<uint8_t>(Mac::Frame::kSecurityEncMic32);
1886 
1887         uint8_t  mSecurityControl;
1888         uint32_t mFrameCounter;
1889         uint32_t mKeySource;
1890         uint8_t  mKeyIndex;
1891     } OT_TOOL_PACKED_END;
1892 
1893     class ParentCandidate : public Parent
1894     {
1895     public:
Init(Instance & aInstance)1896         void Init(Instance &aInstance) { Parent::Init(aInstance); }
1897         void Clear(void);
1898         void CopyTo(Parent &aParent) const;
1899 
1900         Challenge  mChallenge;
1901         int8_t     mPriority;
1902         uint8_t    mLinkQuality3;
1903         uint8_t    mLinkQuality2;
1904         uint8_t    mLinkQuality1;
1905         uint16_t   mSedBufferSize;
1906         uint8_t    mSedDatagramCount;
1907         uint8_t    mLinkMargin;
1908         LeaderData mLeaderData;
1909         bool       mIsSingleton;
1910     };
1911 
1912 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
1913     class ServiceAloc : public Ip6::Netif::UnicastAddress
1914     {
1915     public:
1916         static constexpr uint16_t kNotInUse = Mac::kShortAddrInvalid;
1917 
1918         ServiceAloc(void);
1919 
IsInUse(void) const1920         bool     IsInUse(void) const { return GetAloc16() != kNotInUse; }
MarkAsNotInUse(void)1921         void     MarkAsNotInUse(void) { SetAloc16(kNotInUse); }
GetAloc16(void) const1922         uint16_t GetAloc16(void) const { return GetAddress().GetIid().GetLocator(); }
SetAloc16(uint16_t aAloc16)1923         void     SetAloc16(uint16_t aAloc16) { GetAddress().GetIid().SetLocator(aAloc16); }
ApplyMeshLocalPrefix(const Ip6::NetworkPrefix & aPrefix)1924         void     ApplyMeshLocalPrefix(const Ip6::NetworkPrefix &aPrefix) { GetAddress().SetPrefix(aPrefix); }
1925     };
1926 #endif
1927 
1928 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
HandleParentSearchTimer(void)1929     void HandleParentSearchTimer(void) { mParentSearch.HandleTimer(); }
1930 
1931     class ParentSearch : public InstanceLocator
1932     {
1933     public:
ParentSearch(Instance & aInstance)1934         explicit ParentSearch(Instance &aInstance)
1935             : InstanceLocator(aInstance)
1936             , mIsInBackoff(false)
1937             , mBackoffWasCanceled(false)
1938             , mRecentlyDetached(false)
1939             , mBackoffCancelTime(0)
1940             , mTimer(aInstance)
1941         {
1942         }
1943 
1944         void StartTimer(void);
1945         void UpdateState(void);
SetRecentlyDetached(void)1946         void SetRecentlyDetached(void) { mRecentlyDetached = true; }
1947         void HandleTimer(void);
1948 
1949     private:
1950         // All timer intervals are converted to milliseconds.
1951         static constexpr uint32_t kCheckInterval   = (OPENTHREAD_CONFIG_PARENT_SEARCH_CHECK_INTERVAL * 1000u);
1952         static constexpr uint32_t kBackoffInterval = (OPENTHREAD_CONFIG_PARENT_SEARCH_BACKOFF_INTERVAL * 1000u);
1953         static constexpr uint32_t kJitterInterval  = (15 * 1000u);
1954         static constexpr int8_t   kRssThreshold    = OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_THRESHOLD;
1955 
1956         using SearchTimer = TimerMilliIn<Mle, &Mle::HandleParentSearchTimer>;
1957 
1958         bool        mIsInBackoff : 1;
1959         bool        mBackoffWasCanceled : 1;
1960         bool        mRecentlyDetached : 1;
1961         TimeMilli   mBackoffCancelTime;
1962         SearchTimer mTimer;
1963     };
1964 #endif // OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
1965 
1966     Error       Start(StartMode aMode);
1967     void        Stop(StopMode aMode);
1968     void        HandleNotifierEvents(Events aEvents);
1969     void        SendDelayedResponse(TxMessage &aMessage, const DelayedResponseMetadata &aMetadata);
1970     static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
1971     void        HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
1972     void        ReestablishLinkWithNeighbor(Neighbor &aNeighbor);
1973     static void HandleDetachGracefullyTimer(Timer &aTimer);
1974     void        HandleDetachGracefullyTimer(void);
IsDetachingGracefully(void)1975     bool        IsDetachingGracefully(void) { return mDetachGracefullyTimer.IsRunning(); }
1976     Error       SendChildUpdateRequest(ChildUpdateRequestMode aMode);
1977     Error       SendDataRequestAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay);
1978 
1979 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
1980     Error SendDataRequest(const Ip6::Address                      &aDestination,
1981                           const uint8_t                           *aTlvs,
1982                           uint8_t                                  aTlvsLength,
1983                           uint16_t                                 aDelay,
1984                           const LinkMetrics::Initiator::QueryInfo *aQueryInfo = nullptr);
1985 #else
1986     Error SendDataRequest(const Ip6::Address &aDestination, const uint8_t *aTlvs, uint8_t aTlvsLength, uint16_t aDelay);
1987 #endif
1988 
1989 #if OPENTHREAD_FTD
1990     static void HandleDetachGracefullyAddressReleaseResponse(void                *aContext,
1991                                                              otMessage           *aMessage,
1992                                                              const otMessageInfo *aMessageInfo,
1993                                                              Error                aResult);
1994     void        HandleDetachGracefullyAddressReleaseResponse(void);
1995 #endif
1996 
1997     void HandleAdvertisement(RxInfo &aRxInfo);
1998     void HandleChildIdResponse(RxInfo &aRxInfo);
1999     void HandleChildUpdateRequest(RxInfo &aRxInfo);
2000     void HandleChildUpdateResponse(RxInfo &aRxInfo);
2001     void HandleDataResponse(RxInfo &aRxInfo);
2002     void HandleParentResponse(RxInfo &aRxInfo);
2003     void HandleAnnounce(RxInfo &aRxInfo);
2004 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
2005     void HandleLinkMetricsManagementRequest(RxInfo &aRxInfo);
2006     void HandleLinkProbe(RxInfo &aRxInfo);
2007 #endif
2008 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
2009     void HandleLinkMetricsManagementResponse(RxInfo &aRxInfo);
2010 #endif
2011     Error HandleLeaderData(RxInfo &aRxInfo);
2012     void  ProcessAnnounce(void);
2013     bool  HasUnregisteredAddress(void);
2014 
2015     uint32_t GetAttachStartDelay(void) const;
2016     void     SendParentRequest(ParentRequestType aType);
2017     Error    SendChildIdRequest(void);
2018     Error    GetNextAnnounceChannel(uint8_t &aChannel) const;
2019     bool     HasMoreChannelsToAnnounce(void) const;
2020     bool     PrepareAnnounceState(void);
2021     void     SendAnnounce(uint8_t aChannel, AnnounceMode aMode);
2022     void     SendAnnounce(uint8_t aChannel, const Ip6::Address &aDestination, AnnounceMode aMode = kNormalAnnounce);
2023     void RemoveDelayedMessage(Message::SubType aSubType, MessageType aMessageType, const Ip6::Address *aDestination);
2024     void RemoveDelayedDataRequestMessage(const Ip6::Address &aDestination);
2025 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
2026     Error SendLinkMetricsManagementResponse(const Ip6::Address &aDestination, LinkMetrics::Status aStatus);
2027 #endif
2028     uint32_t Reattach(void);
2029     bool     HasAcceptableParentCandidate(void) const;
2030     Error    DetermineParentRequestType(ParentRequestType &aType) const;
2031 
2032     bool IsBetterParent(uint16_t                aRloc16,
2033                         LinkQuality             aLinkQuality,
2034                         uint8_t                 aLinkMargin,
2035                         const ConnectivityTlv  &aConnectivityTlv,
2036                         uint16_t                aVersion,
2037                         const Mac::CslAccuracy &aCslAccuracy);
2038     bool IsNetworkDataNewer(const LeaderData &aLeaderData);
2039 
2040     Error ProcessMessageSecurity(Crypto::AesCcm::Mode    aMode,
2041                                  Message                &aMessage,
2042                                  const Ip6::MessageInfo &aMessageInfo,
2043                                  uint16_t                aCmdOffset,
2044                                  const SecurityHeader   &aHeader);
2045 
2046 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
2047     ServiceAloc *FindInServiceAlocs(uint16_t aAloc16);
2048     void         UpdateServiceAlocs(void);
2049 #endif
2050 
2051 #if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH
2052     void InformPreviousParent(void);
2053 #endif
2054 
2055 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
2056     static void        LogError(MessageAction aAction, MessageType aType, Error aError);
2057     static const char *MessageActionToString(MessageAction aAction);
2058     static const char *MessageTypeToString(MessageType aType);
2059     static const char *MessageTypeActionToSuffixString(MessageType aType, MessageAction aAction);
2060 #endif
2061 
2062 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
2063     void UpdateRoleTimeCounters(DeviceRole aRole);
2064 #endif
2065 
2066     using DetachGracefullyTimer = TimerMilliIn<Mle, &Mle::HandleDetachGracefullyTimer>;
2067 
2068     MessageQueue mDelayedResponses;
2069 
2070     Challenge mParentRequestChallenge;
2071 
2072     AttachMode      mAttachMode;
2073     ParentCandidate mParentCandidate;
2074 
2075     uint8_t                 mChildUpdateAttempts;
2076     ChildUpdateRequestState mChildUpdateRequestState;
2077     uint8_t                 mDataRequestAttempts;
2078     DataRequestState        mDataRequestState;
2079 
2080     AddressRegistrationMode mAddressRegistrationMode;
2081 
2082     bool mHasRestored;
2083     bool mReceivedResponseFromParent;
2084     bool mInitiallyAttachedAsSleepy;
2085 
2086     Ip6::Udp::Socket mSocket;
2087     uint32_t         mTimeout;
2088 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
2089     uint32_t mCslTimeout;
2090 #endif
2091 
2092     uint16_t mRloc16;
2093     uint16_t mPreviousParentRloc;
2094 
2095 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
2096     ParentSearch mParentSearch;
2097 #endif
2098 
2099     uint8_t  mAnnounceChannel;
2100     uint8_t  mAlternateChannel;
2101     uint16_t mAlternatePanId;
2102     uint64_t mAlternateTimestamp;
2103 
2104 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
2105     ServiceAloc mServiceAlocs[kMaxServiceAlocs];
2106 #endif
2107 
2108     Counters mCounters;
2109 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
2110     uint64_t mLastUpdatedTimestamp;
2111 #endif
2112 
2113     static const otMeshLocalPrefix sMeshLocalPrefixInit;
2114 
2115     Ip6::Netif::UnicastAddress   mLinkLocal64;
2116     Ip6::Netif::UnicastAddress   mMeshLocal64;
2117     Ip6::Netif::UnicastAddress   mMeshLocal16;
2118     Ip6::Netif::MulticastAddress mLinkLocalAllThreadNodes;
2119     Ip6::Netif::MulticastAddress mRealmLocalAllThreadNodes;
2120 
2121     DetachGracefullyTimer                mDetachGracefullyTimer;
2122     Callback<otDetachGracefullyCallback> mDetachGracefullyCallback;
2123 
2124 #if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE
2125     Callback<otThreadParentResponseCallback> mParentResponseCallback;
2126 #endif
2127 };
2128 
2129 } // namespace Mle
2130 
2131 /**
2132  * @}
2133  *
2134  */
2135 
2136 } // namespace ot
2137 
2138 #endif // MLE_HPP_
2139