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/dataset.hpp"
49 #include "meshcop/joiner_router.hpp"
50 #include "meshcop/meshcop.hpp"
51 #include "net/udp6.hpp"
52 #include "thread/child.hpp"
53 #include "thread/link_metrics.hpp"
54 #include "thread/link_metrics_tlvs.hpp"
55 #include "thread/mle_tlvs.hpp"
56 #include "thread/mle_types.hpp"
57 #include "thread/neighbor_table.hpp"
58 #include "thread/network_data_types.hpp"
59 #include "thread/router.hpp"
60 
61 namespace ot {
62 
63 /**
64  * @addtogroup core-mle MLE
65  *
66  * @brief
67  *   This module includes definitions for the MLE protocol.
68  *
69  * @{
70  *
71  * @defgroup core-mle-core Core
72  * @defgroup core-mle-router Router
73  * @defgroup core-mle-tlvs TLVs
74  *
75  * @}
76  */
77 
78 class SupervisionListener;
79 class UnitTester;
80 
81 /**
82  * @namespace ot::Mle
83  *
84  * @brief
85  *   This namespace includes definitions for the MLE protocol.
86  */
87 
88 namespace Mle {
89 
90 /**
91  * @addtogroup core-mle-core
92  *
93  * @brief
94  *   This module includes definitions for MLE functionality required by the Thread Child, Router, and Leader roles.
95  *
96  * @{
97  *
98  */
99 
100 #if OPENTHREAD_FTD
101 class MleRouter;
102 #endif
103 
104 /**
105  * Implements MLE functionality required by the Thread EndDevices, Router, and Leader roles.
106  *
107  */
108 class Mle : public InstanceLocator, private NonCopyable
109 {
110 #if OPENTHREAD_FTD
111     friend class MleRouter;
112 #endif
113     friend class DiscoverScanner;
114     friend class ot::Instance;
115     friend class ot::Notifier;
116     friend class ot::SupervisionListener;
117 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
118     friend class ot::LinkMetrics::Initiator;
119 #endif
120     friend class ot::UnitTester;
121 
122 public:
123     /**
124      * Initializes the MLE object.
125      *
126      * @param[in]  aInstance     A reference to the OpenThread instance.
127      *
128      */
129     explicit Mle(Instance &aInstance);
130 
131     /**
132      * Enables MLE.
133      *
134      * @retval kErrorNone     Successfully enabled MLE.
135      * @retval kErrorAlready  MLE was already enabled.
136      *
137      */
138     Error Enable(void);
139 
140     /**
141      * Disables MLE.
142      *
143      * @retval kErrorNone     Successfully disabled MLE.
144      *
145      */
146     Error Disable(void);
147 
148     /**
149      * Starts the MLE protocol operation.
150      *
151      * @retval kErrorNone           Successfully started the protocol operation.
152      * @retval kErrorInvalidState   IPv6 interface is down or device is in raw-link mode.
153      *
154      */
Start(void)155     Error Start(void) { return Start(kNormalAttach); }
156 
157     /**
158      * Stops the MLE protocol operation.
159      *
160      */
Stop(void)161     void Stop(void) { Stop(kUpdateNetworkDatasets); }
162 
163     /**
164      * Restores network information from non-volatile memory (if any).
165      *
166      */
167     void Restore(void);
168 
169     /**
170      * Stores network information into non-volatile memory.
171      *
172      * @retval kErrorNone      Successfully store the network information.
173      * @retval kErrorNoBufs    Could not store the network information due to insufficient memory space.
174      *
175      */
176     Error Store(void);
177 
178     /**
179      * Generates an MLE Announce message.
180      *
181      * @param[in]  aChannel        The channel to use when transmitting.
182      *
183      */
SendAnnounce(uint8_t aChannel)184     void SendAnnounce(uint8_t aChannel) { SendAnnounce(aChannel, kNormalAnnounce); }
185 
186     /**
187      * Causes the Thread interface to detach from the Thread network.
188      *
189      * @retval kErrorNone          Successfully detached from the Thread network.
190      * @retval kErrorInvalidState  MLE is Disabled.
191      *
192      */
193     Error BecomeDetached(void);
194 
195     /**
196      * Causes the Thread interface to attempt an MLE attach.
197      *
198      * @retval kErrorNone          Successfully began the attach process.
199      * @retval kErrorInvalidState  MLE is Disabled.
200      * @retval kErrorBusy          An attach process is in progress.
201      *
202      */
203     Error BecomeChild(void);
204 
205     /**
206      * Notifies other nodes in the network (if any) and then stops Thread protocol operation.
207      *
208      * It sends an Address Release if it's a router, or sets its child timeout to 0 if it's a child.
209      *
210      * @param[in] aCallback A pointer to a function that is called upon finishing detaching.
211      * @param[in] aContext  A pointer to callback application-specific context.
212      *
213      * @retval kErrorNone   Successfully started detaching.
214      * @retval kErrorBusy   Detaching is already in progress.
215      *
216      */
217     Error DetachGracefully(otDetachGracefullyCallback aCallback, void *aContext);
218 
219     /**
220      * Indicates whether or not the Thread device is attached to a Thread network.
221      *
222      * @retval TRUE   Attached to a Thread network.
223      * @retval FALSE  Not attached to a Thread network.
224      *
225      */
226     bool IsAttached(void) const;
227 
228     /**
229      * Indicates whether device is currently attaching or not.
230      *
231      * Note that an already attached device may also be in attaching state. Examples of this include a leader/router
232      * trying to attach to a better partition, or a child trying to find a better parent (when feature
233      * `OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE` is enabled).
234      *
235      * @retval TRUE   Device is currently trying to attach.
236      * @retval FALSE  Device is not in middle of attach process.
237      *
238      */
IsAttaching(void) const239     bool IsAttaching(void) const { return (mAttachState != kAttachStateIdle); }
240 
241     /**
242      * Returns the current Thread device role.
243      *
244      * @returns The current Thread device role.
245      *
246      */
GetRole(void) const247     DeviceRole GetRole(void) const { return mRole; }
248 
249     /**
250      * Indicates whether device role is disabled.
251      *
252      * @retval TRUE   Device role is disabled.
253      * @retval FALSE  Device role is not disabled.
254      *
255      */
IsDisabled(void) const256     bool IsDisabled(void) const { return (mRole == kRoleDisabled); }
257 
258     /**
259      * Indicates whether device role is detached.
260      *
261      * @retval TRUE   Device role is detached.
262      * @retval FALSE  Device role is not detached.
263      *
264      */
IsDetached(void) const265     bool IsDetached(void) const { return (mRole == kRoleDetached); }
266 
267     /**
268      * Indicates whether device role is child.
269      *
270      * @retval TRUE   Device role is child.
271      * @retval FALSE  Device role is not child.
272      *
273      */
IsChild(void) const274     bool IsChild(void) const { return (mRole == kRoleChild); }
275 
276     /**
277      * Indicates whether device role is router.
278      *
279      * @retval TRUE   Device role is router.
280      * @retval FALSE  Device role is not router.
281      *
282      */
IsRouter(void) const283     bool IsRouter(void) const { return (mRole == kRoleRouter); }
284 
285     /**
286      * Indicates whether device role is leader.
287      *
288      * @retval TRUE   Device role is leader.
289      * @retval FALSE  Device role is not leader.
290      *
291      */
IsLeader(void) const292     bool IsLeader(void) const { return (mRole == kRoleLeader); }
293 
294     /**
295      * Indicates whether device role is either router or leader.
296      *
297      * @retval TRUE   Device role is either router or leader.
298      * @retval FALSE  Device role is neither router nor leader.
299      *
300      */
301     bool IsRouterOrLeader(void) const;
302 
303     /**
304      * Returns the Device Mode as reported in the Mode TLV.
305      *
306      * @returns The Device Mode as reported in the Mode TLV.
307      *
308      */
GetDeviceMode(void) const309     DeviceMode GetDeviceMode(void) const { return mDeviceMode; }
310 
311     /**
312      * Sets the Device Mode as reported in the Mode TLV.
313      *
314      * @param[in]  aDeviceMode  The device mode to set.
315      *
316      * @retval kErrorNone         Successfully set the Mode TLV.
317      * @retval kErrorInvalidArgs  The mode combination specified in @p aMode is invalid.
318      *
319      */
320     Error SetDeviceMode(DeviceMode aDeviceMode);
321 
322     /**
323      * Indicates whether or not the device is rx-on-when-idle.
324      *
325      * @returns TRUE if rx-on-when-idle, FALSE otherwise.
326      *
327      */
IsRxOnWhenIdle(void) const328     bool IsRxOnWhenIdle(void) const { return mDeviceMode.IsRxOnWhenIdle(); }
329 
330     /**
331      * Indicates whether or not the device is a Full Thread Device.
332      *
333      * @returns TRUE if a Full Thread Device, FALSE otherwise.
334      *
335      */
IsFullThreadDevice(void) const336     bool IsFullThreadDevice(void) const { return mDeviceMode.IsFullThreadDevice(); }
337 
338     /**
339      * Indicates whether or not the device is a Minimal End Device.
340      *
341      * @returns TRUE if the device is a Minimal End Device, FALSE otherwise.
342      *
343      */
IsMinimalEndDevice(void) const344     bool IsMinimalEndDevice(void) const { return mDeviceMode.IsMinimalEndDevice(); }
345 
346     /**
347      * Gets the Network Data type (full set or stable subset) that this device requests.
348      *
349      * @returns The Network Data type requested by this device.
350      *
351      */
GetNetworkDataType(void) const352     NetworkData::Type GetNetworkDataType(void) const { return mDeviceMode.GetNetworkDataType(); }
353 
354     /**
355      * Returns a pointer to the Mesh Local Prefix.
356      *
357      * @returns A reference to the Mesh Local Prefix.
358      *
359      */
GetMeshLocalPrefix(void) const360     const Ip6::NetworkPrefix &GetMeshLocalPrefix(void) const { return mMeshLocalPrefix; }
361 
362     /**
363      * Sets the Mesh Local Prefix.
364      *
365      * @param[in]  aMeshLocalPrefix  A reference to the Mesh Local Prefix.
366      *
367      */
368     void SetMeshLocalPrefix(const Ip6::NetworkPrefix &aMeshLocalPrefix);
369 
370 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
371     /**
372      * Sets the Mesh Local IID.
373      *
374      * Available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled.
375      *
376      * @param[in] aMlIid  The Mesh Local IID.
377      *
378      * @retval kErrorNone           Successfully configured Mesh Local IID.
379      * @retval kErrorInvalidState   If the Thread stack is already enabled.
380      *
381      */
382     Error SetMeshLocalIid(const Ip6::InterfaceIdentifier &aMlIid);
383 #endif
384 
385     /**
386      * Returns a reference to the Thread link-local address.
387      *
388      * The Thread link local address is derived using IEEE802.15.4 Extended Address as Interface Identifier.
389      *
390      * @returns A reference to the Thread link local address.
391      *
392      */
GetLinkLocalAddress(void) const393     const Ip6::Address &GetLinkLocalAddress(void) const { return mLinkLocalAddress.GetAddress(); }
394 
395     /**
396      * Updates the link local address.
397      *
398      * Call this method when the IEEE 802.15.4 Extended Address has changed.
399      *
400      */
401     void UpdateLinkLocalAddress(void);
402 
403     /**
404      * Returns a reference to the link-local all Thread nodes multicast address.
405      *
406      * @returns A reference to the link-local all Thread nodes multicast address.
407      *
408      */
GetLinkLocalAllThreadNodesAddress(void) const409     const Ip6::Address &GetLinkLocalAllThreadNodesAddress(void) const { return mLinkLocalAllThreadNodes.GetAddress(); }
410 
411     /**
412      * Returns a reference to the realm-local all Thread nodes multicast address.
413      *
414      * @returns A reference to the realm-local all Thread nodes multicast address.
415      *
416      */
GetRealmLocalAllThreadNodesAddress(void) const417     const Ip6::Address &GetRealmLocalAllThreadNodesAddress(void) const
418     {
419         return mRealmLocalAllThreadNodes.GetAddress();
420     }
421 
422     /**
423      * Gets the parent's RLOC16.
424      *
425      * @returns  The parent's RLOC16, or `kInvalidRloc16` if parent's state is not valid.
426      *
427      */
428     uint16_t GetParentRloc16(void) const;
429 
430     /**
431      * Gets the parent when operating in End Device mode.
432      *
433      * @returns A reference to the parent.
434      *
435      */
GetParent(void)436     Parent &GetParent(void) { return mParent; }
437 
438     /**
439      * Gets the parent when operating in End Device mode.
440      *
441      * @returns A reference to the parent.
442      *
443      */
GetParent(void) const444     const Parent &GetParent(void) const { return mParent; }
445 
446     /**
447      * The method retrieves information about the parent.
448      *
449      * @param[out] aParentInfo     Reference to a parent information structure.
450      *
451      * @retval kErrorNone          Successfully retrieved the parent info and updated @p aParentInfo.
452      * @retval kErrorInvalidState  Device role is not child.
453      *
454      */
455     Error GetParentInfo(Router::Info &aParentInfo) const;
456 
457     /**
458      * Get the parent candidate.
459      *
460      * The parent candidate is valid when attempting to attach to a new parent.
461      *
462      */
GetParentCandidate(void)463     Parent &GetParentCandidate(void) { return mParentCandidate; }
464 
465     /**
466      * Starts the process for child to search for a better parent while staying attached to its current
467      * parent
468      *
469      * @retval kErrorNone          Successfully started the process to search for a better parent.
470      * @retval kErrorInvalidState  Device role is not child.
471      *
472      */
473     Error SearchForBetterParent(void);
474 
475     /**
476      * Indicates whether or not an IPv6 address is an RLOC.
477      *
478      * @retval TRUE   If @p aAddress is an RLOC.
479      * @retval FALSE  If @p aAddress is not an RLOC.
480      *
481      */
482     bool IsRoutingLocator(const Ip6::Address &aAddress) const;
483 
484     /**
485      * Indicates whether or not an IPv6 address is an ALOC.
486      *
487      * @retval TRUE   If @p aAddress is an ALOC.
488      * @retval FALSE  If @p aAddress is not an ALOC.
489      *
490      */
491     bool IsAnycastLocator(const Ip6::Address &aAddress) const;
492 
493     /**
494      * Indicates whether or not an IPv6 address is a Mesh Local Address.
495      *
496      * @retval TRUE   If @p aAddress is a Mesh Local Address.
497      * @retval FALSE  If @p aAddress is not a Mesh Local Address.
498      *
499      */
500     bool IsMeshLocalAddress(const Ip6::Address &aAddress) const;
501 
502     /**
503      * Returns the MLE Timeout value.
504      *
505      * @returns The MLE Timeout value in seconds.
506      *
507      */
GetTimeout(void) const508     uint32_t GetTimeout(void) const { return mTimeout; }
509 
510     /**
511      * Sets the MLE Timeout value.
512      *
513      * @param[in]  aTimeout  The Timeout value in seconds.
514      *
515      */
516     void SetTimeout(uint32_t aTimeout);
517 
518     /**
519      * Returns the RLOC16 assigned to the Thread interface.
520      *
521      * @returns The RLOC16 assigned to the Thread interface.
522      *
523      */
GetRloc16(void) const524     uint16_t GetRloc16(void) const { return mRloc16; }
525 
526     /**
527      * Indicates whether or not this device is using a given RLOC16.
528      *
529      * @param[in] aRloc16   The RLOC16 to check.
530      *
531      * @retval TRUE   This device is using @p aRloc16.
532      * @retval FALSE  This device is not using @p aRloc16.
533      *
534      */
HasRloc16(uint16_t aRloc16) const535     bool HasRloc16(uint16_t aRloc16) const { return mRloc16 == aRloc16; }
536 
537     /**
538      * Indicates whether or not this device RLOC16 matches a given Router ID.
539      *
540      * @param[in] aRouterId   The Router ID to check.
541      *
542      * @retval TRUE   This device's RLOC16 matches the @p aRouterId.
543      * @retval FALSE  This device's RLOC16 does not match the @p aRouterId.
544      *
545      */
MatchesRouterId(uint8_t aRouterId) const546     bool MatchesRouterId(uint8_t aRouterId) const { return RouterIdFromRloc16(mRloc16) == aRouterId; }
547 
548     /**
549      * Indicates whether or not this device's RLOC16 shares the same Router ID with a given RLOC16.
550      *
551      * A shared Router ID implies that this device and the @ aRloc16 are either directly related as parent and child,
552      * or are children of the same parent within the Thread network.
553      *
554      * @param[in] aRloc16   The RLOC16 to check.
555      *
556      * @retval TRUE   This device and @p aRloc16 have a matching router ID.
557      * @retval FALSE  This device and @p aRloc16 do not have a matching router ID.
558      *
559      */
HasMatchingRouterIdWith(uint16_t aRloc16) const560     bool HasMatchingRouterIdWith(uint16_t aRloc16) const { return RouterIdMatch(mRloc16, aRloc16); }
561 
562     /**
563      * Returns the mesh local RLOC IPv6 address assigned to the Thread interface.
564      *
565      * @returns The mesh local RLOC IPv6 address.
566      *
567      */
GetMeshLocalRloc(void) const568     const Ip6::Address &GetMeshLocalRloc(void) const { return mMeshLocalRloc.GetAddress(); }
569 
570     /**
571      * Returns the mesh local endpoint identifier (ML-EID) IPv6 address assigned to the Thread interface.
572      *
573      * @returns The ML-EID address.
574      *
575      */
GetMeshLocalEid(void) const576     const Ip6::Address &GetMeshLocalEid(void) const { return mMeshLocalEid.GetAddress(); }
577 
578     /**
579      * Returns a reference to the ML-EID as a `Netif::UnicastAddress`.
580      *
581      * @returns A reference to the ML-EID.
582      *
583      */
GetMeshLocalEidUnicastAddress(void)584     Ip6::Netif::UnicastAddress &GetMeshLocalEidUnicastAddress(void) { return mMeshLocalEid; }
585 
586     /**
587      * Returns the Router ID of the Leader.
588      *
589      * @returns The Router ID of the Leader.
590      *
591      */
GetLeaderId(void) const592     uint8_t GetLeaderId(void) const { return mLeaderData.GetLeaderRouterId(); }
593 
594     /**
595      * Returns the RLOC16 of the Leader.
596      *
597      * @returns The RLOC16 of the Leader.
598      *
599      */
GetLeaderRloc16(void) const600     uint16_t GetLeaderRloc16(void) const { return Rloc16FromRouterId(GetLeaderId()); }
601 
602     /**
603      * Retrieves the Leader's RLOC.
604      *
605      * @param[out]  aAddress  A reference to an address to return the Leader's RLOC.
606      *
607      */
608     void GetLeaderRloc(Ip6::Address &aAddress) const;
609 
610     /**
611      * Retrieves the Leader's ALOC.
612      *
613      * @param[out]  aAddress  A reference to an address to return the Leader's ALOC.
614      *
615      */
616     void GetLeaderAloc(Ip6::Address &aAddress) const;
617 
618     /**
619      * Retrieves the Commissioner's ALOC for a given session ID.
620      *
621      * @param[in]   aSessionId      Commissioner session id.
622      * @param[out]  aAddress        A reference to an address to return the Commissioner's ALOC.
623      *
624      */
625     void GetCommissionerAloc(uint16_t aSessionId, Ip6::Address &aAddress) const;
626 
627     /**
628      * Retrieves the Service ALOC for given Service ID.
629      *
630      * @param[in]   aServiceId Service ID to get ALOC for.
631      * @param[out]  aAddress   A reference to an address to return the Service ALOC.
632      *
633      */
634     void GetServiceAloc(uint8_t aServiceId, Ip6::Address &aAddress) const;
635 
636     /**
637      * Returns the most recently received Leader Data.
638      *
639      * @returns  A reference to the most recently received Leader Data.
640      *
641      */
642     const LeaderData &GetLeaderData(void);
643 
644     /**
645      * Returns a reference to the send queue.
646      *
647      * @returns A reference to the send queue.
648      *
649      */
GetMessageQueue(void) const650     const MessageQueue &GetMessageQueue(void) const { return mDelayedResponses; }
651 
652     /**
653      * Frees multicast MLE Data Response from Delayed Message Queue if any.
654      *
655      */
656     void RemoveDelayedDataResponseMessage(void);
657 
658     /**
659      * Gets the MLE counters.
660      *
661      * @returns A reference to the MLE counters.
662      *
663      */
GetCounters(void)664     const Counters &GetCounters(void)
665     {
666 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
667         UpdateRoleTimeCounters(mRole);
668 #endif
669         return mCounters;
670     }
671 
672     /**
673      * Resets the MLE counters.
674      *
675      */
676     void ResetCounters(void);
677 
678 #if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE
679     /**
680      * Registers the client callback that is called when processing an MLE Parent Response message.
681      *
682      * @param[in]  aCallback A pointer to a function that is called to deliver MLE Parent Response data.
683      * @param[in]  aContext  A pointer to application-specific context.
684      *
685      */
RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCallback,void * aContext)686     void RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCallback, void *aContext)
687     {
688         mParentResponseCallback.Set(aCallback, aContext);
689     }
690 #endif
691     /**
692      * Notifies MLE whether the Child ID Request message was transmitted successfully.
693      *
694      * @param[in]  aMessage  The transmitted message.
695      *
696      */
697     void HandleChildIdRequestTxDone(Message &aMessage);
698 
699     /**
700      * Requests MLE layer to prepare and send a shorter version of Child ID Request message by only
701      * including the mesh-local IPv6 address in the Address Registration TLV.
702      *
703      * Should be called when a previous MLE Child ID Request message would require fragmentation at 6LoWPAN
704      * layer.
705      *
706      */
707     void RequestShorterChildIdRequest(void);
708 
709     /**
710      * Schedules a Child Update Request.
711      *
712      */
713     void ScheduleChildUpdateRequest(void);
714 
715     /*
716      * Indicates whether or not the device has restored the network information from
717      * non-volatile settings after boot.
718      *
719      * @retval true  Successfully restored the network information.
720      * @retval false No valid network information was found.
721      *
722      */
HasRestored(void) const723     bool HasRestored(void) const { return mHasRestored; }
724 
725     /**
726      * Indicates whether or not a given netif multicast address instance is a prefix-based address added by MLE and
727      * uses the mesh local prefix.
728      *
729      * @param[in] aAddress   A `Netif::MulticastAddress` address instance.
730      *
731      * @retval TRUE   If @p aAddress is a prefix-based address which uses the mesh local prefix.
732      * @retval FALSE  If @p aAddress is not a prefix-based address which uses the mesh local prefix.
733      *
734      */
IsMulticastAddressMeshLocalPrefixBased(const Ip6::Netif::MulticastAddress & aAddress) const735     bool IsMulticastAddressMeshLocalPrefixBased(const Ip6::Netif::MulticastAddress &aAddress) const
736     {
737         return (&aAddress == &mLinkLocalAllThreadNodes) || (&aAddress == &mRealmLocalAllThreadNodes);
738     }
739 
740 #if OPENTHREAD_CONFIG_DYNAMIC_STORE_FRAME_AHEAD_COUNTER_ENABLE
741     /**
742      * Sets the store frame counter ahead.
743      *
744      * @param[in]  aStoreFrameCounterAhead  The store frame counter ahead to set.
745      *
746      */
SetStoreFrameCounterAhead(uint32_t aStoreFrameCounterAhead)747     void SetStoreFrameCounterAhead(uint32_t aStoreFrameCounterAhead)
748     {
749         mStoreFrameCounterAhead = aStoreFrameCounterAhead;
750     }
751 
752     /**
753      * Gets the current store frame counter ahead.
754      *
755      * @returns The current store frame counter ahead.
756      *
757      */
GetStoreFrameCounterAhead(void)758     uint32_t GetStoreFrameCounterAhead(void) { return mStoreFrameCounterAhead; }
759 #endif // OPENTHREAD_CONFIG_DYNAMIC_STORE_FRAME_AHEAD_COUNTER_ENABLE
760 
761 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
762     /**
763      * Gets the CSL timeout.
764      *
765      * @returns CSL timeout
766      *
767      */
GetCslTimeout(void) const768     uint32_t GetCslTimeout(void) const { return mCslTimeout; }
769 
770     /**
771      * Sets the CSL timeout.
772      *
773      * @param[in]  aTimeout  The CSL timeout in seconds.
774      *
775      */
776     void SetCslTimeout(uint32_t aTimeout);
777 
778     /**
779      * Calculates CSL metric of parent.
780      *
781      * @param[in] aCslAccuracy The CSL accuracy.
782      *
783      * @returns CSL metric.
784      *
785      */
786     uint64_t CalcParentCslMetric(const Mac::CslAccuracy &aCslAccuracy) const;
787 
788 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
789 
790 private:
791     //------------------------------------------------------------------------------------------------------------------
792     // Constants
793 
794     // All time intervals are in milliseconds
795     static constexpr uint32_t kParentRequestRouterTimeout     = 750;  // Wait time after tx of Parent Req to routers
796     static constexpr uint32_t kParentRequestReedTimeout       = 1250; // Wait timer after tx of Parent Req to REEDs
797     static constexpr uint32_t kParentRequestDuplicateMargin   = 50;   // Margin to detect duplicate received Parent Req
798     static constexpr uint32_t kChildIdResponseTimeout         = 1250; // Wait time to receive Child ID Response
799     static constexpr uint32_t kAttachStartJitter              = 50;   // Max jitter time added to start of attach
800     static constexpr uint32_t kAnnounceProcessTimeout         = 250;  // Delay after Announce rx before processing
801     static constexpr uint32_t kAnnounceTimeout                = 1400; // Total timeout for sending Announce messages
802     static constexpr uint16_t kMinAnnounceDelay               = 80;   // Min delay between Announcement messages
803     static constexpr uint32_t kParentResponseMaxDelayRouters  = 500;  // Max response delay for Parent Req to routers
804     static constexpr uint32_t kParentResponseMaxDelayAll      = 1000; // Max response delay for Parent Req to all
805     static constexpr uint32_t kChildUpdateRequestPendingDelay = 100;  // Delay for aggregating Child Update Req
806     static constexpr uint32_t kMaxLinkAcceptDelay             = 1000; // Max delay to tx Link Accept for multicast Req
807     static constexpr uint32_t kChildIdRequestTimeout          = 5000; // Max delay to rx a Child ID Req after Parent Res
808     static constexpr uint32_t kLinkRequestTimeout             = 2000; // Max delay to rx a Link Accept
809     static constexpr uint32_t kDetachGracefullyTimeout        = 1000; // Timeout for graceful detach
810     static constexpr uint32_t kUnicastRetxDelay               = 1000; // Base delay for MLE unicast retx
811     static constexpr uint32_t kMulticastRetxDelay             = 5000; // Base delay for MLE multicast retx
812     static constexpr uint32_t kMulticastRetxDelayMin          = kMulticastRetxDelay * 9 / 10;  // 0.9 * base delay
813     static constexpr uint32_t kMulticastRetxDelayMax          = kMulticastRetxDelay * 11 / 10; // 1.1 * base delay
814     static constexpr uint32_t kAnnounceBackoffForPendingDataset = 60000; // Max delay left to block Announce processing.
815 
816     static constexpr uint8_t kMaxTxCount                = 3; // Max tx count for MLE message
817     static constexpr uint8_t kMaxCriticalTxCount        = 6; // Max tx count for critical MLE message
818     static constexpr uint8_t kMaxChildKeepAliveAttempts = 4; // Max keep alive attempts before reattach
819 
820     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
821     // Attach backoff feature (CONFIG_ENABLE_ATTACH_BACKOFF) - Intervals are in milliseconds.
822 
823     static constexpr uint32_t kAttachBackoffMinInterval = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MINIMUM_INTERVAL;
824     static constexpr uint32_t kAttachBackoffMaxInterval = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MAXIMUM_INTERVAL;
825     static constexpr uint32_t kAttachBackoffJitter      = OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_JITTER_INTERVAL;
826     static constexpr uint32_t kAttachBackoffDelayToResetCounter =
827         OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_DELAY_TO_RESET_BACKOFF_INTERVAL;
828 
829     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
830     // Number of Parent Requests in first and next attach cycles
831 
832 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_3
833     // First attach cycle includes two Parent Requests to routers, followed by four to routers and REEDs.
834     static constexpr uint8_t kFirstAttachCycleTotalParentRequests       = 6;
835     static constexpr uint8_t kFirstAttachCycleNumParentRequestToRouters = 2;
836 #else
837     // First attach cycle in Thread 1.1/1.2 includes a Parent Requests to routers, followed by one to routers and REEDs.
838     static constexpr uint8_t kFirstAttachCycleTotalParentRequests       = 2;
839     static constexpr uint8_t kFirstAttachCycleNumParentRequestToRouters = 1;
840 #endif
841 
842     // Next attach cycles includes one Parent Request to routers, followed by one to routers and REEDs.
843     static constexpr uint8_t kNextAttachCycleTotalParentRequests       = 2;
844     static constexpr uint8_t kNextAttachCycleNumParentRequestToRouters = 1;
845 
846     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
847 
848 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
849     static constexpr uint8_t kMaxServiceAlocs = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS + 1;
850 #else
851     static constexpr uint8_t kMaxServiceAlocs = OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_MAX_ALOCS;
852 #endif
853 
854     static constexpr uint8_t  kMleHopLimit                   = 255;
855     static constexpr uint8_t  kMleSecurityTagSize            = 4;
856     static constexpr uint32_t kDefaultStoreFrameCounterAhead = OPENTHREAD_CONFIG_STORE_FRAME_COUNTER_AHEAD;
857     static constexpr uint8_t  kMaxIpAddressesToRegister      = OPENTHREAD_CONFIG_MLE_IP_ADDRS_TO_REGISTER;
858     static constexpr uint32_t kDefaultChildTimeout           = OPENTHREAD_CONFIG_MLE_CHILD_TIMEOUT_DEFAULT;
859     static constexpr uint32_t kDefaultCslTimeout             = OPENTHREAD_CONFIG_CSL_TIMEOUT;
860 
861     //------------------------------------------------------------------------------------------------------------------
862     // Enumerations
863 
864     enum Command : uint8_t
865     {
866         kCommandLinkRequest                   = 0,
867         kCommandLinkAccept                    = 1,
868         kCommandLinkAcceptAndRequest          = 2,
869         kCommandLinkReject                    = 3,
870         kCommandAdvertisement                 = 4,
871         kCommandUpdate                        = 5,
872         kCommandUpdateRequest                 = 6,
873         kCommandDataRequest                   = 7,
874         kCommandDataResponse                  = 8,
875         kCommandParentRequest                 = 9,
876         kCommandParentResponse                = 10,
877         kCommandChildIdRequest                = 11,
878         kCommandChildIdResponse               = 12,
879         kCommandChildUpdateRequest            = 13,
880         kCommandChildUpdateResponse           = 14,
881         kCommandAnnounce                      = 15,
882         kCommandDiscoveryRequest              = 16,
883         kCommandDiscoveryResponse             = 17,
884         kCommandLinkMetricsManagementRequest  = 18,
885         kCommandLinkMetricsManagementResponse = 19,
886         kCommandLinkProbe                     = 20,
887         kCommandTimeSync                      = 99,
888     };
889 
890     enum AttachMode : uint8_t
891     {
892         kAnyPartition,    // Attach to any Thread partition.
893         kSamePartition,   // Attach to the same Thread partition (when losing connectivity).
894         kBetterPartition, // Attach to a better (i.e. higher weight/partition id) Thread partition.
895         kDowngradeToReed, // Attach to the same Thread partition during downgrade process.
896         kBetterParent,    // Attach to a better parent.
897     };
898 
899     enum AttachState : uint8_t
900     {
901         kAttachStateIdle,            // Not currently searching for a parent.
902         kAttachStateProcessAnnounce, // Waiting to process a received Announce (to switch channel/pan-id).
903         kAttachStateStart,           // Starting to look for a parent.
904         kAttachStateParentRequest,   // Send Parent Request (current number tracked by `mParentRequestCounter`).
905         kAttachStateAnnounce,        // Send Announce messages
906         kAttachStateChildIdRequest,  // Sending a Child ID Request message.
907     };
908 
909     enum ReattachState : uint8_t
910     {
911         kReattachStop,    // Reattach process is disabled or finished
912         kReattachStart,   // Start reattach process
913         kReattachActive,  // Reattach using stored Active Dataset
914         kReattachPending, // Reattach using stored Pending Dataset
915     };
916 
917     static constexpr uint16_t kMleMaxResponseDelay = 1000u; // Max delay before responding to a multicast request.
918 
919     enum AddressRegistrationMode : uint8_t // Used by `AppendAddressRegistrationTlv()`
920     {
921         kAppendAllAddresses,  // Append all addresses (unicast/multicast) in Address Registration TLV.
922         kAppendMeshLocalOnly, // Only append the Mesh Local (ML-EID) address in Address Registration TLV.
923     };
924 
925     enum StartMode : uint8_t // Used in `Start()`.
926     {
927         kNormalAttach,
928         kAnnounceAttach, // Try to attach on the announced thread network with newer active timestamp.
929     };
930 
931     enum StopMode : uint8_t // Used in `Stop()`.
932     {
933         kKeepNetworkDatasets,
934         kUpdateNetworkDatasets,
935     };
936 
937     enum AnnounceMode : uint8_t // Used in `SendAnnounce()`
938     {
939         kNormalAnnounce,
940         kOrphanAnnounce,
941     };
942 
943     enum ParentRequestType : uint8_t
944     {
945         kToRouters,         // Parent Request to routers only.
946         kToRoutersAndReeds, // Parent Request to all routers and REEDs.
947     };
948 
949     enum ChildUpdateRequestState : uint8_t
950     {
951         kChildUpdateRequestNone,    // No pending or active Child Update Request.
952         kChildUpdateRequestPending, // Pending Child Update Request due to relative OT_CHANGED event.
953         kChildUpdateRequestActive,  // Child Update Request has been sent and Child Update Response is expected.
954     };
955 
956     enum ChildUpdateRequestMode : uint8_t // Used in `SendChildUpdateRequest()`
957     {
958         kNormalChildUpdateRequest, // Normal Child Update Request.
959         kAppendChallengeTlv,       // Append Challenge TLV to Child Update Request even if currently attached.
960         kAppendZeroTimeout,        // Use zero timeout when appending Timeout TLV (used for graceful detach).
961     };
962 
963     enum DataRequestState : uint8_t
964     {
965         kDataRequestNone,   // Not waiting for a Data Response.
966         kDataRequestActive, // Data Request has been sent, Data Response is expected.
967     };
968 
969     enum SecuritySuite : uint8_t
970     {
971         k154Security = 0,   // Security suite value indicating that MLE message is not secured.
972         kNoSecurity  = 255, // Security suite value indicating that MLE message is secured.
973     };
974 
975     enum MessageAction : uint8_t
976     {
977         kMessageSend,
978         kMessageReceive,
979         kMessageDelay,
980         kMessageRemoveDelayed,
981     };
982 
983     enum MessageType : uint8_t
984     {
985         kTypeAdvertisement,
986         kTypeAnnounce,
987         kTypeChildIdRequest,
988         kTypeChildIdRequestShort,
989         kTypeChildIdResponse,
990         kTypeChildUpdateRequestAsChild,
991         kTypeChildUpdateResponseAsChild,
992         kTypeDataRequest,
993         kTypeDataResponse,
994         kTypeDiscoveryRequest,
995         kTypeDiscoveryResponse,
996         kTypeGenericDelayed,
997         kTypeGenericUdp,
998         kTypeParentRequestToRouters,
999         kTypeParentRequestToRoutersReeds,
1000         kTypeParentResponse,
1001 #if OPENTHREAD_FTD
1002         kTypeAddressRelease,
1003         kTypeAddressReleaseReply,
1004         kTypeAddressReply,
1005         kTypeAddressSolicit,
1006         kTypeChildUpdateRequestOfChild,
1007         kTypeChildUpdateResponseOfChild,
1008         kTypeChildUpdateResponseOfUnknownChild,
1009         kTypeLinkAccept,
1010         kTypeLinkAcceptAndRequest,
1011         kTypeLinkReject,
1012         kTypeLinkRequest,
1013         kTypeParentRequest,
1014 #endif
1015 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
1016         kTypeLinkMetricsManagementRequest,
1017         kTypeLinkMetricsManagementResponse,
1018         kTypeLinkProbe,
1019 #endif
1020 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1021         kTypeTimeSync,
1022 #endif
1023     };
1024 
1025     //------------------------------------------------------------------------------------------------------------------
1026     // Nested types
1027 
1028     static constexpr uint8_t kMaxTlvListSize = 32; // Maximum number of TLVs in a `TlvList`.
1029 
1030     class TlvList : public Array<uint8_t, kMaxTlvListSize>
1031     {
1032     public:
1033         TlvList(void) = default;
1034 
1035         void Add(uint8_t aTlvType);
1036         void AddElementsFrom(const TlvList &aTlvList);
1037     };
1038 
1039     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1040 
1041     class TxMessage : public Message
1042     {
1043     public:
1044         Error AppendSourceAddressTlv(void);
1045         Error AppendModeTlv(DeviceMode aMode);
1046         Error AppendTimeoutTlv(uint32_t aTimeout);
1047         Error AppendChallengeTlv(const TxChallenge &aChallenge);
1048         Error AppendResponseTlv(const RxChallenge &aResponse);
1049         Error AppendLinkFrameCounterTlv(void);
1050         Error AppendMleFrameCounterTlv(void);
1051         Error AppendLinkAndMleFrameCounterTlvs(void);
1052         Error AppendAddress16Tlv(uint16_t aRloc16);
1053         Error AppendNetworkDataTlv(NetworkData::Type aType);
1054         Error AppendTlvRequestTlv(const uint8_t *aTlvs, uint8_t aTlvsLength);
1055         Error AppendLeaderDataTlv(void);
1056         Error AppendScanMaskTlv(uint8_t aScanMask);
1057         Error AppendStatusTlv(StatusTlv::Status aStatus);
1058         Error AppendLinkMarginTlv(uint8_t aLinkMargin);
1059         Error AppendVersionTlv(void);
1060         Error AppendAddressRegistrationTlv(AddressRegistrationMode aMode = kAppendAllAddresses);
1061         Error AppendSupervisionIntervalTlvIfSleepyChild(void);
1062         Error AppendSupervisionIntervalTlv(uint16_t aInterval);
1063         Error AppendXtalAccuracyTlv(void);
1064         Error AppendActiveTimestampTlv(void);
1065         Error AppendPendingTimestampTlv(void);
1066         Error AppendActiveAndPendingTimestampTlvs(void);
1067 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1068         Error AppendTimeRequestTlv(void);
1069         Error AppendTimeParameterTlv(void);
1070 #endif
1071 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1072         Error AppendCslChannelTlv(void);
1073         Error AppendCslTimeoutTlv(void);
1074 #endif
1075 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
1076         Error AppendCslClockAccuracyTlv(void);
1077 #endif
1078 #if OPENTHREAD_FTD
1079         Error AppendRouteTlv(Neighbor *aNeighbor = nullptr);
1080         Error AppendActiveDatasetTlv(void);
1081         Error AppendPendingDatasetTlv(void);
1082         Error AppendConnectivityTlv(void);
1083         Error AppendSteeringDataTlv(void);
1084         Error AppendAddressRegistrationTlv(Child &aChild);
1085 #endif
AppendTlvRequestTlv(const uint8_t (& aTlvArray)[kArrayLength])1086         template <uint8_t kArrayLength> Error AppendTlvRequestTlv(const uint8_t (&aTlvArray)[kArrayLength])
1087         {
1088             return AppendTlvRequestTlv(aTlvArray, kArrayLength);
1089         }
1090 
1091         Error SendTo(const Ip6::Address &aDestination);
1092         Error SendAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay);
1093 
1094     private:
1095         Error AppendCompressedAddressEntry(uint8_t aContextId, const Ip6::Address &aAddress);
1096         Error AppendAddressEntry(const Ip6::Address &aAddress);
1097         Error AppendDatasetTlv(MeshCoP::Dataset::Type aDatasetType);
1098     };
1099 
1100     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1101 
1102     class RxMessage : public Message
1103     {
1104     public:
1105         bool  ContainsTlv(Tlv::Type aTlvType) const;
1106         Error ReadModeTlv(DeviceMode &aMode) const;
1107         Error ReadVersionTlv(uint16_t &aVersion) const;
1108         Error ReadChallengeTlv(RxChallenge &aChallenge) const;
1109         Error ReadResponseTlv(RxChallenge &aResponse) const;
1110         Error ReadAndMatchResponseTlvWith(const TxChallenge &aChallenge) const;
1111         Error ReadFrameCounterTlvs(uint32_t &aLinkFrameCounter, uint32_t &aMleFrameCounter) const;
1112         Error ReadTlvRequestTlv(TlvList &aTlvList) const;
1113         Error ReadLeaderDataTlv(LeaderData &aLeaderData) const;
1114         Error ReadAndSetNetworkDataTlv(const LeaderData &aLeaderData) const;
1115         Error ReadAndSaveActiveDataset(const MeshCoP::Timestamp &aActiveTimestamp) const;
1116         Error ReadAndSavePendingDataset(const MeshCoP::Timestamp &aPendingTimestamp) const;
1117 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1118         Error ReadCslClockAccuracyTlv(Mac::CslAccuracy &aCslAccuracy) const;
1119 #endif
1120 #if OPENTHREAD_FTD
1121         Error ReadRouteTlv(RouteTlv &aRouteTlv) const;
1122 #endif
1123 
1124     private:
1125         Error ReadChallengeOrResponse(uint8_t aTlvType, RxChallenge &aRxChallenge) const;
1126         Error ReadAndSaveDataset(MeshCoP::Dataset::Type aDatasetType, const MeshCoP::Timestamp &aTimestamp) const;
1127     };
1128 
1129     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1130 
1131     struct RxInfo
1132     {
1133         enum Class : uint8_t
1134         {
1135             kUnknown,              // Unknown (default value, also indicates MLE message parse error).
1136             kAuthoritativeMessage, // Authoritative message (larger received key seq MUST be adopted).
1137             kPeerMessage,          // Peer message (adopt only if from a known neighbor and is greater by one).
1138         };
1139 
RxInfoot::Mle::Mle::RxInfo1140         RxInfo(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
1141             : mMessage(static_cast<RxMessage &>(aMessage))
1142             , mMessageInfo(aMessageInfo)
1143             , mFrameCounter(0)
1144             , mKeySequence(0)
1145             , mNeighbor(nullptr)
1146             , mClass(kUnknown)
1147         {
1148         }
1149 
IsNeighborStateValidot::Mle::Mle::RxInfo1150         bool IsNeighborStateValid(void) const { return (mNeighbor != nullptr) && mNeighbor->IsStateValid(); }
1151 
1152         RxMessage              &mMessage;      // The MLE message.
1153         const Ip6::MessageInfo &mMessageInfo;  // The `MessageInfo` associated with the message.
1154         uint32_t                mFrameCounter; // The frame counter from aux security header.
1155         uint32_t                mKeySequence;  // The key sequence from aux security header.
1156         Neighbor               *mNeighbor;     // Neighbor from which message was received (can be `nullptr`).
1157         Class                   mClass;        // The message class (authoritative, peer, or unknown).
1158     };
1159 
1160     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1161 
1162     struct DelayedResponseMetadata
1163     {
AppendToot::Mle::Mle::DelayedResponseMetadata1164         Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); }
1165         void  ReadFrom(const Message &aMessage);
1166         void  RemoveFrom(Message &aMessage) const;
1167 
1168         Ip6::Address mDestination; // IPv6 address of the message destination.
1169         TimeMilli    mSendTime;    // Time when the message shall be sent.
1170     };
1171 
1172     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1173 
1174     OT_TOOL_PACKED_BEGIN
1175     class SecurityHeader
1176     {
1177     public:
InitSecurityControl(void)1178         void InitSecurityControl(void) { mSecurityControl = kKeyIdMode2Mic32; }
IsSecurityControlValid(void) const1179         bool IsSecurityControlValid(void) const { return (mSecurityControl == kKeyIdMode2Mic32); }
1180 
GetFrameCounter(void) const1181         uint32_t GetFrameCounter(void) const { return LittleEndian::HostSwap32(mFrameCounter); }
SetFrameCounter(uint32_t aCounter)1182         void     SetFrameCounter(uint32_t aCounter) { mFrameCounter = LittleEndian::HostSwap32(aCounter); }
1183 
GetKeyId(void) const1184         uint32_t GetKeyId(void) const { return BigEndian::HostSwap32(mKeySource); }
SetKeyId(uint32_t aKeySequence)1185         void     SetKeyId(uint32_t aKeySequence)
1186         {
1187             mKeySource = BigEndian::HostSwap32(aKeySequence);
1188             mKeyIndex  = (aKeySequence & 0x7f) + 1;
1189         }
1190 
1191     private:
1192         static constexpr uint8_t kKeyIdMode2Mic32 =
1193             static_cast<uint8_t>(Mac::Frame::kKeyIdMode2) | static_cast<uint8_t>(Mac::Frame::kSecurityEncMic32);
1194 
1195         uint8_t  mSecurityControl;
1196         uint32_t mFrameCounter;
1197         uint32_t mKeySource;
1198         uint8_t  mKeyIndex;
1199     } OT_TOOL_PACKED_END;
1200 
1201     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1202 
1203     class ParentCandidate : public Parent
1204     {
1205     public:
Init(Instance & aInstance)1206         void Init(Instance &aInstance) { Parent::Init(aInstance); }
1207         void Clear(void);
1208         void CopyTo(Parent &aParent) const;
1209 
1210         RxChallenge mRxChallenge;
1211         int8_t      mPriority;
1212         uint8_t     mLinkQuality3;
1213         uint8_t     mLinkQuality2;
1214         uint8_t     mLinkQuality1;
1215         uint16_t    mSedBufferSize;
1216         uint8_t     mSedDatagramCount;
1217         uint8_t     mLinkMargin;
1218         LeaderData  mLeaderData;
1219         bool        mIsSingleton;
1220     };
1221 
1222     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1223 
1224 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
1225     class ServiceAloc : public Ip6::Netif::UnicastAddress
1226     {
1227     public:
1228         static constexpr uint16_t kNotInUse = kInvalidRloc16;
1229 
1230         ServiceAloc(void);
1231 
IsInUse(void) const1232         bool     IsInUse(void) const { return GetAloc16() != kNotInUse; }
MarkAsNotInUse(void)1233         void     MarkAsNotInUse(void) { SetAloc16(kNotInUse); }
GetAloc16(void) const1234         uint16_t GetAloc16(void) const { return GetAddress().GetIid().GetLocator(); }
SetAloc16(uint16_t aAloc16)1235         void     SetAloc16(uint16_t aAloc16) { GetAddress().GetIid().SetLocator(aAloc16); }
1236     };
1237 #endif
1238 
1239     //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1240 
1241 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
HandleParentSearchTimer(void)1242     void HandleParentSearchTimer(void) { mParentSearch.HandleTimer(); }
1243 
1244     class ParentSearch : public InstanceLocator
1245     {
1246     public:
ParentSearch(Instance & aInstance)1247         explicit ParentSearch(Instance &aInstance)
1248             : InstanceLocator(aInstance)
1249             , mIsInBackoff(false)
1250             , mBackoffWasCanceled(false)
1251             , mRecentlyDetached(false)
1252             , mBackoffCancelTime(0)
1253             , mTimer(aInstance)
1254         {
1255         }
1256 
1257         void StartTimer(void);
1258         void UpdateState(void);
SetRecentlyDetached(void)1259         void SetRecentlyDetached(void) { mRecentlyDetached = true; }
1260         void HandleTimer(void);
1261 
1262     private:
1263         // All timer intervals are converted to milliseconds.
1264         static constexpr uint32_t kCheckInterval   = (OPENTHREAD_CONFIG_PARENT_SEARCH_CHECK_INTERVAL * 1000u);
1265         static constexpr uint32_t kBackoffInterval = (OPENTHREAD_CONFIG_PARENT_SEARCH_BACKOFF_INTERVAL * 1000u);
1266         static constexpr uint32_t kJitterInterval  = (15 * 1000u);
1267         static constexpr int8_t   kRssThreshold    = OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_THRESHOLD;
1268 
1269         using SearchTimer = TimerMilliIn<Mle, &Mle::HandleParentSearchTimer>;
1270 
1271         bool        mIsInBackoff : 1;
1272         bool        mBackoffWasCanceled : 1;
1273         bool        mRecentlyDetached : 1;
1274         TimeMilli   mBackoffCancelTime;
1275         SearchTimer mTimer;
1276     };
1277 #endif // OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
1278 
1279     //------------------------------------------------------------------------------------------------------------------
1280     // Methods
1281 
1282     Error      Start(StartMode aMode);
1283     void       Stop(StopMode aMode);
1284     TxMessage *NewMleMessage(Command aCommand);
1285     void       SetRole(DeviceRole aRole);
1286     void       Attach(AttachMode aMode);
1287     void       SetAttachState(AttachState aState);
1288     void       InitNeighbor(Neighbor &aNeighbor, const RxInfo &aRxInfo);
ClearParentCandidate(void)1289     void       ClearParentCandidate(void) { mParentCandidate.Clear(); }
1290     Error      SendDataRequest(const Ip6::Address &aDestination);
1291     void       HandleNotifierEvents(Events aEvents);
1292     void       SendDelayedResponse(TxMessage &aMessage, const DelayedResponseMetadata &aMetadata);
1293     void       HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
1294     void       ReestablishLinkWithNeighbor(Neighbor &aNeighbor);
1295     void       HandleDetachGracefullyTimer(void);
IsDetachingGracefully(void)1296     bool       IsDetachingGracefully(void) { return mDetachGracefullyTimer.IsRunning(); }
1297     Error      SendChildUpdateRequest(ChildUpdateRequestMode aMode);
1298     Error      SendDataRequestAfterDelay(const Ip6::Address &aDestination, uint16_t aDelay);
1299     Error      SendChildUpdateRequest(void);
1300     Error      SendChildUpdateResponse(const TlvList      &aTlvList,
1301                                        const RxChallenge  &aChallenge,
1302                                        const Ip6::Address &aDestination);
1303     void       SetRloc16(uint16_t aRloc16);
1304     void       SetStateDetached(void);
1305     void       SetStateChild(uint16_t aRloc16);
1306     void       SetLeaderData(uint32_t aPartitionId, uint8_t aWeighting, uint8_t aLeaderRouterId);
1307     void       SetLeaderData(const LeaderData &aLeaderData);
1308     void       InformPreviousChannel(void);
IsAnnounceAttach(void) const1309     bool       IsAnnounceAttach(void) const { return mAlternatePanId != Mac::kPanIdBroadcast; }
1310     void       ScheduleMessageTransmissionTimer(void);
1311     void       HandleAttachTimer(void);
1312     void       HandleDelayedResponseTimer(void);
1313     void       HandleMessageTransmissionTimer(void);
1314     void       ProcessKeySequence(RxInfo &aRxInfo);
1315     void       HandleAdvertisement(RxInfo &aRxInfo);
1316     void       HandleChildIdResponse(RxInfo &aRxInfo);
1317     void       HandleChildUpdateRequest(RxInfo &aRxInfo);
1318     void       HandleChildUpdateResponse(RxInfo &aRxInfo);
1319     void       HandleDataResponse(RxInfo &aRxInfo);
1320     void       HandleParentResponse(RxInfo &aRxInfo);
1321     void       HandleAnnounce(RxInfo &aRxInfo);
1322     Error      HandleLeaderData(RxInfo &aRxInfo);
1323     void       ProcessAnnounce(void);
1324     bool       HasUnregisteredAddress(void);
1325     uint32_t   GetAttachStartDelay(void) const;
1326     void       SendParentRequest(ParentRequestType aType);
1327     Error      SendChildIdRequest(void);
1328     Error      GetNextAnnounceChannel(uint8_t &aChannel) const;
1329     bool       HasMoreChannelsToAnnounce(void) const;
1330     bool       PrepareAnnounceState(void);
1331     void       SendAnnounce(uint8_t aChannel, AnnounceMode aMode);
1332     void       SendAnnounce(uint8_t aChannel, const Ip6::Address &aDestination, AnnounceMode aMode = kNormalAnnounce);
1333     uint32_t   Reattach(void);
1334     bool       HasAcceptableParentCandidate(void) const;
1335     Error      DetermineParentRequestType(ParentRequestType &aType) const;
1336     bool       IsBetterParent(uint16_t                aRloc16,
1337                               uint8_t                 aTwoWayLinkMargin,
1338                               const ConnectivityTlv  &aConnectivityTlv,
1339                               uint16_t                aVersion,
1340                               const Mac::CslAccuracy &aCslAccuracy);
1341     bool       IsNetworkDataNewer(const LeaderData &aLeaderData);
1342     Error      ProcessMessageSecurity(Crypto::AesCcm::Mode    aMode,
1343                                       Message                &aMessage,
1344                                       const Ip6::MessageInfo &aMessageInfo,
1345                                       uint16_t                aCmdOffset,
1346                                       const SecurityHeader   &aHeader);
1347     void RemoveDelayedMessage(Message::SubType aSubType, MessageType aMessageType, const Ip6::Address *aDestination);
1348     void RemoveDelayedDataRequestMessage(const Ip6::Address &aDestination);
1349 
1350 #if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH
1351     void InformPreviousParent(void);
1352 #endif
1353 
1354 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
1355     void UpdateRoleTimeCounters(DeviceRole aRole);
1356 #endif
1357 
1358 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
1359     ServiceAloc *FindInServiceAlocs(uint16_t aAloc16);
1360     void         UpdateServiceAlocs(void);
1361 #endif
1362 
1363 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1364     void HandleTimeSync(RxInfo &aRxInfo);
1365 #endif
1366 
1367 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
1368     void  HandleLinkMetricsManagementRequest(RxInfo &aRxInfo);
1369     void  HandleLinkProbe(RxInfo &aRxInfo);
1370     Error SendLinkMetricsManagementResponse(const Ip6::Address &aDestination, LinkMetrics::Status aStatus);
1371 #endif
1372 
1373 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
1374     void  HandleLinkMetricsManagementResponse(RxInfo &aRxInfo);
1375     Error SendDataRequestForLinkMetricsReport(const Ip6::Address                      &aDestination,
1376                                               const LinkMetrics::Initiator::QueryInfo &aQueryInfo);
1377     Error SendLinkMetricsManagementRequest(const Ip6::Address &aDestination, const ot::Tlv &aSubTlv);
1378     Error SendLinkProbe(const Ip6::Address &aDestination, uint8_t aSeriesId, uint8_t *aBuf, uint8_t aLength);
1379     Error SendDataRequest(const Ip6::Address                      &aDestination,
1380                           const uint8_t                           *aTlvs,
1381                           uint8_t                                  aTlvsLength,
1382                           uint16_t                                 aDelay,
1383                           const LinkMetrics::Initiator::QueryInfo *aQueryInfo = nullptr);
1384 #else
1385     Error SendDataRequest(const Ip6::Address &aDestination, const uint8_t *aTlvs, uint8_t aTlvsLength, uint16_t aDelay);
1386 #endif
1387 
1388 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
1389     static void Log(MessageAction aAction, MessageType aType, const Ip6::Address &aAddress);
1390     static void Log(MessageAction aAction, MessageType aType, const Ip6::Address &aAddress, uint16_t aRloc);
1391 #else
Log(MessageAction,MessageType,const Ip6::Address &)1392     static void Log(MessageAction, MessageType, const Ip6::Address &) {}
Log(MessageAction,MessageType,const Ip6::Address &,uint16_t)1393     static void Log(MessageAction, MessageType, const Ip6::Address &, uint16_t) {}
1394 #endif
1395 
1396 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_NOTE)
1397     static const char *AttachModeToString(AttachMode aMode);
1398     static const char *AttachStateToString(AttachState aState);
1399     static const char *ReattachStateToString(ReattachState aState);
1400 #endif
1401 
1402 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
1403     static void        LogError(MessageAction aAction, MessageType aType, Error aError);
1404     static const char *MessageActionToString(MessageAction aAction);
1405     static const char *MessageTypeToString(MessageType aType);
1406     static const char *MessageTypeActionToSuffixString(MessageType aType, MessageAction aAction);
1407     static void        LogProcessError(MessageType aType, Error aError);
1408     static void        LogSendError(MessageType aType, Error aError);
1409 #else
LogProcessError(MessageType,Error)1410     static void LogProcessError(MessageType, Error) {}
LogSendError(MessageType,Error)1411     static void LogSendError(MessageType, Error) {}
1412 #endif
1413 
1414     //------------------------------------------------------------------------------------------------------------------
1415     // Variables
1416 
1417     using DetachGracefullyTimer = TimerMilliIn<Mle, &Mle::HandleDetachGracefullyTimer>;
1418     using AttachTimer           = TimerMilliIn<Mle, &Mle::HandleAttachTimer>;
1419     using DelayTimer            = TimerMilliIn<Mle, &Mle::HandleDelayedResponseTimer>;
1420     using MsgTxTimer            = TimerMilliIn<Mle, &Mle::HandleMessageTransmissionTimer>;
1421     using MleSocket             = Ip6::Udp::SocketIn<Mle, &Mle::HandleUdpReceive>;
1422 
1423     static const otMeshLocalPrefix kMeshLocalPrefixInit;
1424 
1425     bool mRetrieveNewNetworkData : 1;
1426     bool mRequestRouteTlv : 1;
1427     bool mHasRestored : 1;
1428     bool mReceivedResponseFromParent : 1;
1429     bool mInitiallyAttachedAsSleepy : 1;
1430 #if OPENTHREAD_FTD
1431     bool mWasLeader : 1;
1432 #endif
1433 
1434     DeviceRole              mRole;
1435     DeviceMode              mDeviceMode;
1436     AttachState             mAttachState;
1437     ReattachState           mReattachState;
1438     AttachMode              mAttachMode;
1439     DataRequestState        mDataRequestState;
1440     AddressRegistrationMode mAddressRegistrationMode;
1441     ChildUpdateRequestState mChildUpdateRequestState;
1442 
1443     uint8_t mParentRequestCounter;
1444     uint8_t mChildUpdateAttempts;
1445     uint8_t mDataRequestAttempts;
1446     uint8_t mAnnounceChannel;
1447     uint8_t mAlternateChannel;
1448 #if OPENTHREAD_FTD
1449     uint8_t mLinkRequestAttempts;
1450 #endif
1451     uint16_t mRloc16;
1452     uint16_t mPreviousParentRloc;
1453     uint16_t mAttachCounter;
1454     uint16_t mAnnounceDelay;
1455     uint16_t mAlternatePanId;
1456     uint32_t mStoreFrameCounterAhead;
1457     uint32_t mTimeout;
1458 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1459     uint32_t mCslTimeout;
1460 #endif
1461     uint64_t mAlternateTimestamp;
1462 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
1463     uint64_t mLastUpdatedTimestamp;
1464 #endif
1465 
1466     LeaderData      mLeaderData;
1467     Parent          mParent;
1468     NeighborTable   mNeighborTable;
1469     MessageQueue    mDelayedResponses;
1470     TxChallenge     mParentRequestChallenge;
1471     ParentCandidate mParentCandidate;
1472     MleSocket       mSocket;
1473     Counters        mCounters;
1474 #if OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE
1475     ParentSearch mParentSearch;
1476 #endif
1477 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
1478     ServiceAloc mServiceAlocs[kMaxServiceAlocs];
1479 #endif
1480     Callback<otDetachGracefullyCallback> mDetachGracefullyCallback;
1481 #if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE
1482     Callback<otThreadParentResponseCallback> mParentResponseCallback;
1483 #endif
1484     AttachTimer                  mAttachTimer;
1485     DelayTimer                   mDelayedResponseTimer;
1486     MsgTxTimer                   mMessageTransmissionTimer;
1487     DetachGracefullyTimer        mDetachGracefullyTimer;
1488     Ip6::NetworkPrefix           mMeshLocalPrefix;
1489     Ip6::Netif::UnicastAddress   mLinkLocalAddress;
1490     Ip6::Netif::UnicastAddress   mMeshLocalEid;
1491     Ip6::Netif::UnicastAddress   mMeshLocalRloc;
1492     Ip6::Netif::MulticastAddress mLinkLocalAllThreadNodes;
1493     Ip6::Netif::MulticastAddress mRealmLocalAllThreadNodes;
1494 };
1495 
1496 } // namespace Mle
1497 
1498 /**
1499  * @}
1500  *
1501  */
1502 
1503 } // namespace ot
1504 
1505 #endif // MLE_HPP_
1506