• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2016, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *   This file includes definitions for MLE functionality required by the Thread Router and Leader roles.
32  */
33 
34 #ifndef MLE_ROUTER_HPP_
35 #define MLE_ROUTER_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <openthread/thread_ftd.h>
40 
41 #include "coap/coap.hpp"
42 #include "coap/coap_message.hpp"
43 #include "common/time_ticker.hpp"
44 #include "common/timer.hpp"
45 #include "common/trickle_timer.hpp"
46 #include "mac/mac_types.hpp"
47 #include "meshcop/meshcop_tlvs.hpp"
48 #include "net/icmp6.hpp"
49 #include "net/udp6.hpp"
50 #include "thread/child_table.hpp"
51 #include "thread/mle.hpp"
52 #include "thread/mle_tlvs.hpp"
53 #include "thread/router_table.hpp"
54 #include "thread/thread_tlvs.hpp"
55 #include "thread/topology.hpp"
56 
57 namespace ot {
58 namespace Mle {
59 
60 /**
61  * @addtogroup core-mle-router
62  *
63  * @brief
64  *   This module includes definitions for MLE functionality required by the Thread Router and Leader roles.
65  *
66  * @{
67  */
68 
69 #if OPENTHREAD_FTD
70 
71 /**
72  * This class implements MLE functionality required by the Thread Router and Leader roles.
73  *
74  */
75 class MleRouter : public Mle
76 {
77     friend class Mle;
78     friend class ot::Instance;
79     friend class ot::TimeTicker;
80 
81 public:
82     /**
83      * This constructor initializes the object.
84      *
85      * @param[in]  aInstance     A reference to the OpenThread instance.
86      *
87      */
88     explicit MleRouter(Instance &aInstance);
89 
90     /**
91      * This method indicates whether or not the device is router-eligible.
92      *
93      * @retval true   If device is router-eligible.
94      * @retval false  If device is not router-eligible.
95      *
96      */
97     bool IsRouterEligible(void) const;
98 
99     /**
100      * This method sets whether or not the device is router-eligible.
101      *
102      * If @p aEligible is false and the device is currently operating as a router, this call will cause the device to
103      * detach and attempt to reattach as a child.
104      *
105      * @param[in]  aEligible  TRUE to configure device router-eligible, FALSE otherwise.
106      *
107      * @retval kErrorNone         Successfully set the router-eligible configuration.
108      * @retval kErrorNotCapable   The device is not capable of becoming a router.
109      *
110      */
111     Error SetRouterEligible(bool aEligible);
112 
113     /**
114      * This method indicates whether a node is the only router on the network.
115      *
116      * @retval TRUE   It is the only router in the network.
117      * @retval FALSE  It is a child or is not a single router in the network.
118      *
119      */
120     bool IsSingleton(void);
121 
122     /**
123      * This method generates an Address Solicit request for a Router ID.
124      *
125      * @param[in]  aStatus  The reason for requesting a Router ID.
126      *
127      * @retval kErrorNone           Successfully generated an Address Solicit message.
128      * @retval kErrorNotCapable     Device is not capable of becoming a router
129      * @retval kErrorInvalidState   Thread is not enabled
130      *
131      */
132     Error BecomeRouter(ThreadStatusTlv::Status aStatus);
133 
134     /**
135      * This method causes the Thread interface to become a Leader and start a new partition.
136      *
137      * @retval kErrorNone           Successfully become a Leader and started a new partition.
138      * @retval kErrorNotCapable     Device is not capable of becoming a leader
139      * @retval kErrorInvalidState   Thread is not enabled
140      *
141      */
142     Error BecomeLeader(void);
143 
144     /**
145      * This method returns the Leader Weighting value for this Thread interface.
146      *
147      * @returns The Leader Weighting value for this Thread interface.
148      *
149      */
GetLeaderWeight(void) const150     uint8_t GetLeaderWeight(void) const { return mLeaderWeight; }
151 
152     /**
153      * This method sets the Leader Weighting value for this Thread interface.
154      *
155      * @param[in]  aWeight  The Leader Weighting value.
156      *
157      */
SetLeaderWeight(uint8_t aWeight)158     void SetLeaderWeight(uint8_t aWeight) { mLeaderWeight = aWeight; }
159 
160 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
161 
162     /**
163      * This method returns the preferred Partition Id when operating in the Leader role for certification testing.
164      *
165      * @returns The preferred Partition Id value.
166      *
167      */
GetPreferredLeaderPartitionId(void) const168     uint32_t GetPreferredLeaderPartitionId(void) const { return mPreferredLeaderPartitionId; }
169 
170     /**
171      * This method sets the preferred Partition Id when operating in the Leader role for certification testing.
172      *
173      * @param[in]  aPartitionId  The preferred Leader Partition Id.
174      *
175      */
SetPreferredLeaderPartitionId(uint32_t aPartitionId)176     void SetPreferredLeaderPartitionId(uint32_t aPartitionId) { mPreferredLeaderPartitionId = aPartitionId; }
177 #endif
178 
179     /**
180      * This method sets the preferred Router Id. Upon becoming a router/leader the node
181      * attempts to use this Router Id. If the preferred Router Id is not set or if it
182      * can not be used, a randomly generated router Id is picked.
183      * This property can be set when he device role is detached or disabled.
184      *
185      * @param[in]  aRouterId             The preferred Router Id.
186      *
187      * @retval kErrorNone          Successfully set the preferred Router Id.
188      * @retval kErrorInvalidState  Could not set (role is other than detached and disabled)
189      *
190      */
191     Error SetPreferredRouterId(uint8_t aRouterId);
192 
193     /**
194      * This method gets the Partition Id which the device joined successfully once.
195      *
196      */
GetPreviousPartitionId(void) const197     uint32_t GetPreviousPartitionId(void) const { return mPreviousPartitionId; }
198 
199     /**
200      * This method sets the Partition Id which the device joins successfully.
201      *
202      * @param[in]  aPartitionId   The Partition Id.
203      *
204      */
SetPreviousPartitionId(uint32_t aPartitionId)205     void SetPreviousPartitionId(uint32_t aPartitionId) { mPreviousPartitionId = aPartitionId; }
206 
207     /**
208      * This method sets the Router Id.
209      *
210      * @param[in]  aRouterId   The Router Id.
211      *
212      */
213     void SetRouterId(uint8_t aRouterId);
214 
215     /**
216      * This method returns the next hop towards an RLOC16 destination.
217      *
218      * @param[in]  aDestination  The RLOC16 of the destination.
219      *
220      * @returns A RLOC16 of the next hop if a route is known, kInvalidRloc16 otherwise.
221      *
222      */
223     uint16_t GetNextHop(uint16_t aDestination);
224 
225     /**
226      * This method returns the NETWORK_ID_TIMEOUT value.
227      *
228      * @returns The NETWORK_ID_TIMEOUT value.
229      *
230      */
GetNetworkIdTimeout(void) const231     uint8_t GetNetworkIdTimeout(void) const { return mNetworkIdTimeout; }
232 
233     /**
234      * This method sets the NETWORK_ID_TIMEOUT value.
235      *
236      * @param[in]  aTimeout  The NETWORK_ID_TIMEOUT value.
237      *
238      */
SetNetworkIdTimeout(uint8_t aTimeout)239     void SetNetworkIdTimeout(uint8_t aTimeout) { mNetworkIdTimeout = aTimeout; }
240 
241     /**
242      * This method returns the route cost to a RLOC16.
243      *
244      * @param[in]  aRloc16  The RLOC16 of the destination.
245      *
246      * @returns The route cost to a RLOC16.
247      *
248      */
249     uint8_t GetRouteCost(uint16_t aRloc16) const;
250 
251     /**
252      * This method returns the link cost to the given Router.
253      *
254      * @param[in]  aRouterId  The Router ID.
255      *
256      * @returns The link cost to the Router.
257      *
258      */
259     uint8_t GetLinkCost(uint8_t aRouterId);
260 
261     /**
262      * This method returns the minimum cost to the given router.
263      *
264      * @param[in]  aRloc16  The short address of the given router.
265      *
266      * @returns The minimum cost to the given router (via direct link or forwarding).
267      *
268      */
269     uint8_t GetCost(uint16_t aRloc16);
270 
271     /**
272      * This method returns the ROUTER_SELECTION_JITTER value.
273      *
274      * @returns The ROUTER_SELECTION_JITTER value.
275      *
276      */
GetRouterSelectionJitter(void) const277     uint8_t GetRouterSelectionJitter(void) const { return mRouterSelectionJitter; }
278 
279     /**
280      * This method sets the ROUTER_SELECTION_JITTER value.
281      *
282      * @returns The ROUTER_SELECTION_JITTER value.
283      *
284      */
285     Error SetRouterSelectionJitter(uint8_t aRouterJitter);
286 
287     /**
288      * This method returns the current router selection jitter timeout value.
289      *
290      * @returns The current router selection jitter timeout value.
291      *
292      */
GetRouterSelectionJitterTimeout(void) const293     uint8_t GetRouterSelectionJitterTimeout(void) const { return mRouterSelectionJitterTimeout; }
294 
295     /**
296      * This method returns the ROUTER_UPGRADE_THRESHOLD value.
297      *
298      * @returns The ROUTER_UPGRADE_THRESHOLD value.
299      *
300      */
GetRouterUpgradeThreshold(void) const301     uint8_t GetRouterUpgradeThreshold(void) const { return mRouterUpgradeThreshold; }
302 
303     /**
304      * This method sets the ROUTER_UPGRADE_THRESHOLD value.
305      *
306      * @param[in]  aThreshold  The ROUTER_UPGRADE_THRESHOLD value.
307      *
308      */
SetRouterUpgradeThreshold(uint8_t aThreshold)309     void SetRouterUpgradeThreshold(uint8_t aThreshold) { mRouterUpgradeThreshold = aThreshold; }
310 
311     /**
312      * This method returns the ROUTER_DOWNGRADE_THRESHOLD value.
313      *
314      * @returns The ROUTER_DOWNGRADE_THRESHOLD value.
315      *
316      */
GetRouterDowngradeThreshold(void) const317     uint8_t GetRouterDowngradeThreshold(void) const { return mRouterDowngradeThreshold; }
318 
319     /**
320      * This method sets the ROUTER_DOWNGRADE_THRESHOLD value.
321      *
322      * @param[in]  aThreshold  The ROUTER_DOWNGRADE_THRESHOLD value.
323      *
324      */
SetRouterDowngradeThreshold(uint8_t aThreshold)325     void SetRouterDowngradeThreshold(uint8_t aThreshold) { mRouterDowngradeThreshold = aThreshold; }
326 
327     /**
328      * This method returns if the REED is expected to become Router soon.
329      *
330      * @retval TRUE   If the REED is going to become a Router soon.
331      * @retval FALSE  If the REED is not going to become a Router soon.
332      *
333      */
334     bool IsExpectedToBecomeRouterSoon(void) const;
335 
336     /**
337      * This method removes a link to a neighbor.
338      *
339      * @param[in]  aNeighbor  A reference to the neighbor object.
340      *
341      */
342     void RemoveNeighbor(Neighbor &aNeighbor);
343 
344     /**
345      * This method invalidates a direct link to a neighboring router (due to failed link-layer acks).
346      *
347      * @param[in]  aRouter  A reference to the router object.
348      *
349      */
350     void RemoveRouterLink(Router &aRouter);
351 
352     /**
353      * This method indicates whether or not the RLOC16 is an MTD child of this device.
354      *
355      * @param[in]  aRloc16  The RLOC16.
356      *
357      * @retval TRUE if @p aRloc16 is an MTD child of this device.
358      * @retval FALSE if @p aRloc16 is not an MTD child of this device.
359      *
360      */
361     bool IsMinimalChild(uint16_t aRloc16);
362 
363     /**
364      * This method indicates whether or not the given Thread partition attributes are preferred.
365      *
366      * @param[in]  aSingletonA   Whether or not the Thread Partition A has a single router.
367      * @param[in]  aLeaderDataA  A reference to Thread Partition A's Leader Data.
368      * @param[in]  aSingletonB   Whether or not the Thread Partition B has a single router.
369      * @param[in]  aLeaderDataB  A reference to Thread Partition B's Leader Data.
370      *
371      * @retval 1   If partition A is preferred.
372      * @retval 0   If partition A and B have equal preference.
373      * @retval -1  If partition B is preferred.
374      *
375      */
376     static int ComparePartitions(bool              aSingletonA,
377                                  const LeaderData &aLeaderDataA,
378                                  bool              aSingletonB,
379                                  const LeaderData &aLeaderDataB);
380 
381     /**
382      * This method checks if the destination is reachable.
383      *
384      * @param[in]  aMeshDest   The RLOC16 of the destination.
385      * @param[in]  aIp6Header  A reference to the IPv6 header of the message.
386      *
387      * @retval kErrorNone      The destination is reachable.
388      * @retval kErrorNoRoute   The destination is not reachable and the message should be dropped.
389      *
390      */
391     Error CheckReachability(uint16_t aMeshDest, const Ip6::Header &aIp6Header);
392 
393     /**
394      * This method resolves 2-hop routing loops.
395      *
396      * @param[in]  aSourceMac   The RLOC16 of the previous hop.
397      * @param[in]  aDestRloc16  The RLOC16 of the final destination.
398      *
399      */
400     void ResolveRoutingLoops(uint16_t aSourceMac, uint16_t aDestRloc16);
401 
402     /**
403      * This method checks if a given Router ID has correct value.
404      *
405      * @param[in]  aRouterId  The Router ID value.
406      *
407      * @retval TRUE   If @p aRouterId is in correct range [0..62].
408      * @retval FALSE  If @p aRouterId is not a valid Router ID.
409      *
410      */
IsRouterIdValid(uint8_t aRouterId)411     static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; }
412 
413     /**
414      * This method fills an ConnectivityTlv.
415      *
416      * @param[out]  aTlv  A reference to the tlv to be filled.
417      *
418      */
419     void FillConnectivityTlv(ConnectivityTlv &aTlv);
420 
421     /**
422      * This method fills an RouteTlv.
423      *
424      * @param[out]  aTlv  A reference to the tlv to be filled.
425      *
426      */
427     void FillRouteTlv(RouteTlv &aTlv, Neighbor *aNeighbor = nullptr);
428 
429     /**
430      * This method generates an MLE Child Update Request message to be sent to the parent.
431      *
432      * @retval kErrorNone     Successfully generated an MLE Child Update Request message.
433      * @retval kErrorNoBufs   Insufficient buffers to generate the MLE Child Update Request message.
434      *
435      */
SendChildUpdateRequest(void)436     Error SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); }
437 
438     Error SendLinkRequest(Neighbor *aNeighbor);
439 
440 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
441     /**
442      * This method sets steering data out of band
443      *
444      * @param[in]  aExtAddress  Value used to set steering data
445      *                          All zeros clears steering data
446      *                          All 0xFFs sets steering data to 0xFF
447      *                          Anything else is used to compute the bloom filter
448      *
449      */
450     void SetSteeringData(const Mac::ExtAddress *aExtAddress);
451 #endif
452 
453     /**
454      * This method gets the assigned parent priority.
455      *
456      * @returns The assigned parent priority value, -2 means not assigned.
457      *
458      */
GetAssignParentPriority(void) const459     int8_t GetAssignParentPriority(void) const { return mParentPriority; }
460 
461     /**
462      * This method sets the parent priority.
463      *
464      * @param[in]  aParentPriority  The parent priority value.
465      *
466      * @retval kErrorNone           Successfully set the parent priority.
467      * @retval kErrorInvalidArgs    If the parent priority value is not among 1, 0, -1 and -2.
468      *
469      */
470     Error SetAssignParentPriority(int8_t aParentPriority);
471 
472     /**
473      * This method gets the longest MLE Timeout TLV for all active MTD children.
474      *
475      * @param[out]  aTimeout  A reference to where the information is placed.
476      *
477      * @retval kErrorNone           Successfully get the max child timeout
478      * @retval kErrorInvalidState   Not an active router
479      * @retval kErrorNotFound       NO MTD child
480      *
481      */
482     Error GetMaxChildTimeout(uint32_t &aTimeout) const;
483 
484     /**
485      * This function sets the callback that is called when processing an MLE Discovery Request message.
486      *
487      * @param[in]  aCallback A pointer to a function that is called to deliver MLE Discovery Request data.
488      * @param[in]  aContext  A pointer to application-specific context.
489      *
490      */
SetDiscoveryRequestCallback(otThreadDiscoveryRequestCallback aCallback,void * aContext)491     void SetDiscoveryRequestCallback(otThreadDiscoveryRequestCallback aCallback, void *aContext)
492     {
493         mDiscoveryRequestCallback        = aCallback;
494         mDiscoveryRequestCallbackContext = aContext;
495     }
496 
497     /**
498      * This method resets the MLE Advertisement Trickle timer interval.
499      *
500      */
501     void ResetAdvertiseInterval(void);
502 
503     /**
504      * This static method converts link quality to route cost.
505      *
506      * @param[in]  aLinkQuality  The link quality.
507      *
508      * @returns The link cost corresponding to @p aLinkQuality.
509      *
510      */
511     static uint8_t LinkQualityToCost(uint8_t aLinkQuality);
512 
513 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
514     /**
515      * This method generates an MLE Time Synchronization message.
516      *
517      * @retval kErrorNone     Successfully sent an MLE Time Synchronization message.
518      * @retval kErrorNoBufs   Insufficient buffers to generate the MLE Time Synchronization message.
519      *
520      */
521     Error SendTimeSync(void);
522 #endif
523 
524 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
525     /**
526      * This method sets the delay before registering Backbone Router service.
527      *
528      * @param[in]  aDelay  The delay before registering Backbone Router service.
529      *
530      */
SetBackboneRouterRegistrationDelay(uint8_t aDelay)531     void SetBackboneRouterRegistrationDelay(uint8_t aDelay) { mBackboneRouterRegistrationDelay = aDelay; }
532 #endif
533 
534     /**
535      * This method gets the maximum number of IP addresses that each MTD child may register with this device as parent.
536      *
537      * @returns The maximum number of IP addresses that each MTD child may register with this device as parent.
538      *
539      */
540     uint8_t GetMaxChildIpAddresses(void) const;
541 
542 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
543     /**
544      * This method sets/restores the maximum number of IP addresses that each MTD child may register with this
545      * device as parent.
546      *
547      * @param[in]  aMaxIpAddresses  The maximum number of IP addresses that each MTD child may register with this
548      *                              device as parent. 0 to clear the setting and restore the default.
549      *
550      * @retval kErrorNone           Successfully set/cleared the number.
551      * @retval kErrorInvalidArgs    If exceeds the allowed maximum number.
552      *
553      */
554     Error SetMaxChildIpAddresses(uint8_t aMaxIpAddresses);
555 
556     /**
557      * This method sets whether the device was commissioned using CCM.
558      *
559      * @param[in]  aEnabled  TRUE if the device was commissioned using CCM, FALSE otherwise.
560      *
561      */
SetCcmEnabled(bool aEnabled)562     void SetCcmEnabled(bool aEnabled) { mCcmEnabled = aEnabled; }
563 
564     /**
565      * This function sets whether the Security Policy TLV version-threshold for routing (VR field) is enabled.
566      *
567      * @param[in]  aEnabled  TRUE to enable Security Policy TLV version-threshold for routing, FALSE otherwise.
568      *
569      */
SetThreadVersionCheckEnabled(bool aEnabled)570     void SetThreadVersionCheckEnabled(bool aEnabled) { mThreadVersionCheckEnabled = aEnabled; }
571 #endif
572 
573     /**
574      * This function sends an Address Release.
575      *
576      * @param[in] aResponseHandler        A pointer to a function that is called upon response reception or time-out.
577      * @param[in] aResponseHandlerContext A pointer to callback application-specific context.
578      *
579      */
580     void SendAddressRelease(Coap::ResponseHandler aResponseHandler = nullptr, void *aResponseHandlerContext = nullptr);
581 
582 private:
583     static constexpr uint16_t kDiscoveryMaxJitter            = 250;  // Max jitter delay Discovery Responses (in msec).
584     static constexpr uint32_t kStateUpdatePeriod             = 1000; // State update period (in msec).
585     static constexpr uint16_t kUnsolicitedDataResponseJitter = 500;  // Max delay for unsol Data Response (in msec).
586 
587     // Threshold to accept a router upgrade request with reason
588     // `kBorderRouterRequest` (number of BRs acting as router in
589     // Network Data).
590     static constexpr uint8_t kRouterUpgradeBorderRouterRequestThreshold = 2;
591 
592     void  HandleDetachStart(void);
593     void  HandleChildStart(AttachMode aMode);
594     void  HandleLinkRequest(RxInfo &aRxInfo);
595     void  HandleLinkAccept(RxInfo &aRxInfo);
596     Error HandleLinkAccept(RxInfo &aRxInfo, bool aRequest);
597     void  HandleLinkAcceptAndRequest(RxInfo &aRxInfo);
598     Error HandleAdvertisement(RxInfo &aRxInfo);
599     void  HandleParentRequest(RxInfo &aRxInfo);
600     void  HandleChildIdRequest(RxInfo &aRxInfo);
601     void  HandleChildUpdateRequest(RxInfo &aRxInfo);
602     void  HandleChildUpdateResponse(RxInfo &aRxInfo);
603     void  HandleDataRequest(RxInfo &aRxInfo);
604     void  HandleNetworkDataUpdateRouter(void);
605     void  HandleDiscoveryRequest(RxInfo &aRxInfo);
606 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
607     void HandleTimeSync(RxInfo &aRxInfo);
608 #endif
609 
610     Error ProcessRouteTlv(RxInfo &aRxInfo);
611     Error ProcessRouteTlv(RxInfo &aRxInfo, RouteTlv &aRouteTlv);
612     void  StopAdvertiseTrickleTimer(void);
613     Error SendAddressSolicit(ThreadStatusTlv::Status aStatus);
614     void  SendAddressSolicitResponse(const Coap::Message &   aRequest,
615                                      ThreadStatusTlv::Status aResponseStatus,
616                                      const Router *          aRouter,
617                                      const Ip6::MessageInfo &aMessageInfo);
618     void  SendAdvertisement(void);
619     Error SendLinkAccept(const Ip6::MessageInfo &aMessageInfo,
620                          Neighbor *              aNeighbor,
621                          const RequestedTlvs &   aRequestedTlvs,
622                          const Challenge &       aChallenge);
623     void  SendParentResponse(Child *aChild, const Challenge &aChallenge, bool aRoutersOnlyRequest);
624     Error SendChildIdResponse(Child &aChild);
625     Error SendChildUpdateRequest(Child &aChild);
626     void  SendChildUpdateResponse(Child *                 aChild,
627                                   const Ip6::MessageInfo &aMessageInfo,
628                                   const uint8_t *         aTlvs,
629                                   uint8_t                 aTlvsLength,
630                                   const Challenge &       aChallenge);
631     void  SendDataResponse(const Ip6::Address &aDestination,
632                            const uint8_t *     aTlvs,
633                            uint8_t             aTlvsLength,
634                            uint16_t            aDelay,
635                            const Message *     aRequestMessage = nullptr);
636     Error SendDiscoveryResponse(const Ip6::Address &aDestination, const Message &aDiscoverRequestMessage);
637     void  SetStateRouter(uint16_t aRloc16);
638     void  SetStateLeader(uint16_t aRloc16, LeaderStartMode aStartMode);
639     void  StopLeader(void);
640     void  SynchronizeChildNetworkData(void);
641     Error UpdateChildAddresses(const Message &aMessage, uint16_t aOffset, Child &aChild);
642     void  UpdateRoutes(const RouteTlv &aRoute, uint8_t aRouterId);
643     bool  UpdateLinkQualityOut(const RouteTlv &aRoute, Router &aNeighbor, bool &aResetAdvInterval);
644     bool  HasNeighborWithGoodLinkQuality(void) const;
645 
646     static void HandleAddressSolicitResponse(void *               aContext,
647                                              otMessage *          aMessage,
648                                              const otMessageInfo *aMessageInfo,
649                                              Error                aResult);
650     void HandleAddressSolicitResponse(Coap::Message *aMessage, const Ip6::MessageInfo *aMessageInfo, Error aResult);
651     static void HandleAddressRelease(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
652     void        HandleAddressRelease(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
653     static void HandleAddressSolicit(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
654     void        HandleAddressSolicit(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
655 
656     static bool IsSingleton(const RouteTlv &aRouteTlv);
657 
658     void HandlePartitionChange(void);
659 
660     void SetChildStateToValid(Child &aChild);
661     bool HasChildren(void);
662     void RemoveChildren(void);
663     bool HasMinDowngradeNeighborRouters(void);
664     bool HasOneNeighborWithComparableConnectivity(const RouteTlv &aRoute, uint8_t aRouterId);
665     bool HasSmallNumberOfChildren(void);
666 
667     static void HandleAdvertiseTrickleTimer(TrickleTimer &aTimer);
668     void        HandleAdvertiseTrickleTimer(void);
669     void        HandleTimeTick(void);
670 
671     TrickleTimer mAdvertiseTrickleTimer;
672 
673     Coap::Resource mAddressSolicit;
674     Coap::Resource mAddressRelease;
675 
676     ChildTable  mChildTable;
677     RouterTable mRouterTable;
678 
679     uint8_t   mChallengeTimeout;
680     Challenge mChallenge;
681 
682     uint16_t mNextChildId;
683     uint8_t  mNetworkIdTimeout;
684     uint8_t  mRouterUpgradeThreshold;
685     uint8_t  mRouterDowngradeThreshold;
686     uint8_t  mLeaderWeight;
687 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
688     uint32_t mPreferredLeaderPartitionId; ///< only for certification testing
689     bool     mCcmEnabled : 1;
690     bool     mThreadVersionCheckEnabled : 1;
691 #endif
692     bool mRouterEligible : 1;
693     bool mAddressSolicitPending : 1;
694     bool mAddressSolicitRejected : 1;
695 
696     uint8_t mRouterId;
697     uint8_t mPreviousRouterId;
698 
699     uint32_t mPreviousPartitionIdRouter;         ///< The partition ID when last operating as a router
700     uint32_t mPreviousPartitionId;               ///< The partition ID when last attached
701     uint8_t  mPreviousPartitionRouterIdSequence; ///< The router ID sequence when last attached
702     uint8_t  mPreviousPartitionIdTimeout;        ///< The partition ID timeout when last attached
703 
704     uint8_t mRouterSelectionJitter;        ///< The variable to save the assigned jitter value.
705     uint8_t mRouterSelectionJitterTimeout; ///< The Timeout prior to request/release Router ID.
706 
707     uint8_t mLinkRequestDelay;
708 
709     int8_t mParentPriority; ///< The assigned parent priority value, -2 means not assigned.
710 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
711     uint8_t mBackboneRouterRegistrationDelay; ///< Delay before registering Backbone Router service.
712 #endif
713 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
714     uint8_t mMaxChildIpAddresses;
715 #endif
716 
717 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
718     MeshCoP::SteeringData mSteeringData;
719 #endif
720 
721     otThreadDiscoveryRequestCallback mDiscoveryRequestCallback;
722     void *                           mDiscoveryRequestCallbackContext;
723 };
724 
725 #endif // OPENTHREAD_FTD
726 
727 #if OPENTHREAD_MTD
728 
729 class MleRouter : public Mle
730 {
731     friend class Mle;
732     friend class ot::Instance;
733 
734 public:
MleRouter(Instance & aInstance)735     explicit MleRouter(Instance &aInstance)
736         : Mle(aInstance)
737     {
738     }
739 
IsSingleton(void) const740     bool IsSingleton(void) const { return false; }
741 
GetNextHop(uint16_t aDestination) const742     uint16_t GetNextHop(uint16_t aDestination) const { return Mle::GetNextHop(aDestination); }
743 
GetCost(uint16_t)744     uint8_t GetCost(uint16_t) { return 0; }
745 
RemoveNeighbor(Neighbor &)746     Error RemoveNeighbor(Neighbor &) { return BecomeDetached(); }
RemoveRouterLink(Router &)747     void  RemoveRouterLink(Router &) { IgnoreError(BecomeDetached()); }
748 
IsRouterIdValid(uint8_t aRouterId)749     static bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; }
750 
SendChildUpdateRequest(void)751     Error SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); }
752 
CheckReachability(uint16_t aMeshDest,Ip6::Header & aIp6Header)753     Error CheckReachability(uint16_t aMeshDest, Ip6::Header &aIp6Header)
754     {
755         return Mle::CheckReachability(aMeshDest, aIp6Header);
756     }
757 };
758 
759 #endif // OPENTHREAD_MTD
760 
761 } // namespace Mle
762 
763 /**
764  * @}
765  */
766 
767 } // namespace ot
768 
769 #endif // MLE_ROUTER_HPP_
770