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