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