• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2019, 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 types and constants.
32  */
33 
34 #ifndef MLE_TYPES_HPP_
35 #define MLE_TYPES_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <stdint.h>
40 #include <string.h>
41 
42 #include <openthread/thread.h>
43 #if OPENTHREAD_FTD
44 #include <openthread/thread_ftd.h>
45 #endif
46 
47 #include "common/array.hpp"
48 #include "common/as_core_type.hpp"
49 #include "common/clearable.hpp"
50 #include "common/code_utils.hpp"
51 #include "common/encoding.hpp"
52 #include "common/equatable.hpp"
53 #include "common/numeric_limits.hpp"
54 #include "common/offset_range.hpp"
55 #include "common/string.hpp"
56 #include "mac/mac_types.hpp"
57 #include "meshcop/extended_panid.hpp"
58 #include "net/ip6_address.hpp"
59 #include "thread/network_data_types.hpp"
60 
61 namespace ot {
62 
63 class Message;
64 
65 namespace Mle {
66 
67 /**
68  * @addtogroup core-mle-core
69  *
70  * @brief
71  *   This module includes definition for MLE types and constants.
72  *
73  * @{
74  */
75 
76 constexpr uint16_t kUdpPort = 19788; ///< MLE UDP Port
77 
78 constexpr uint16_t kMaxChildren     = OPENTHREAD_CONFIG_MLE_MAX_CHILDREN; ///< Maximum number of children
79 constexpr uint16_t kMinChildId      = 1;                                  ///< Minimum Child ID
80 constexpr uint16_t kMaxChildId      = 511;                                ///< Maximum Child ID
81 constexpr uint8_t  kMaxRouters      = OPENTHREAD_CONFIG_MLE_MAX_ROUTERS;  ///< Maximum number of routers
82 constexpr uint8_t  kMaxRouterId     = OT_NETWORK_MAX_ROUTER_ID;           ///< Max Router ID
83 constexpr uint8_t  kInvalidRouterId = kMaxRouterId + 1;                   ///< Value indicating invalid Router ID
84 constexpr uint8_t  kRouterIdOffset  = 10;                                 ///< Bit offset of router ID in RLOC16
85 constexpr uint16_t kInvalidRloc16   = Mac::kShortAddrInvalid;             ///< Invalid RLOC16.
86 
87 #if OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE
88 constexpr uint8_t kMaxRouteCost = 127; ///< Maximum path cost
89 #else
90 constexpr uint8_t kMaxRouteCost = 16; ///< Maximum path cost
91 #endif
92 
93 constexpr uint8_t kMeshLocalPrefixContextId = 0; ///< Reserved 6lowpan context ID for Mesh Local Prefix
94 
95 constexpr uint8_t kLinkRequestAttempts = 3; ///< Number of Link Request attempts when re-establishing link.
96 constexpr uint8_t kLinkAcceptTimeout   = 3; ///< Timeout in seconds to rx Link Accept after Link Request tx.
97 
98 /**
99  * Specifies parent reselect timeout duration in seconds used on FTD child devices.
100  *
101  * When an attach attempt to a neighboring router selected as a potential new parent fails, the same router
102  * cannot be selected again until this timeout expires.
103  */
104 constexpr uint16_t kParentReselectTimeout = OPENTHREAD_CONFIG_PARENT_SEARCH_RESELECT_TIMEOUT;
105 
106 /**
107  * Number of consecutive tx failures to child (with no-ack error) to consider child-parent link broken.
108  */
109 constexpr uint8_t kFailedChildTransmissions = OPENTHREAD_CONFIG_FAILED_CHILD_TRANSMISSIONS;
110 
111 /**
112  * Threshold to accept a router upgrade request with reason `kBorderRouterRequest` (number of BRs acting as router in
113  * Network Data).
114  */
115 constexpr uint8_t kRouterUpgradeBorderRouterRequestThreshold = 2;
116 
117 /**
118  * Represents a Thread device role.
119  */
120 enum DeviceRole : uint8_t
121 {
122     kRoleDisabled = OT_DEVICE_ROLE_DISABLED, ///< The Thread stack is disabled.
123     kRoleDetached = OT_DEVICE_ROLE_DETACHED, ///< Not currently participating in a Thread network/partition.
124     kRoleChild    = OT_DEVICE_ROLE_CHILD,    ///< The Thread Child role.
125     kRoleRouter   = OT_DEVICE_ROLE_ROUTER,   ///< The Thread Router role.
126     kRoleLeader   = OT_DEVICE_ROLE_LEADER,   ///< The Thread Leader role.
127 };
128 
129 /**
130  * Represents MLE commands.
131  */
132 enum Command : uint8_t
133 {
134     kCommandLinkRequest                   = 0,  ///< Link Request command
135     kCommandLinkAccept                    = 1,  ///< Link Accept command
136     kCommandLinkAcceptAndRequest          = 2,  ///< Link Accept And Request command
137     kCommandLinkReject                    = 3,  ///< Link Reject command
138     kCommandAdvertisement                 = 4,  ///< Advertisement command
139     kCommandUpdate                        = 5,  ///< Update command
140     kCommandUpdateRequest                 = 6,  ///< Update Request command
141     kCommandDataRequest                   = 7,  ///< Data Request command
142     kCommandDataResponse                  = 8,  ///< Data Response command
143     kCommandParentRequest                 = 9,  ///< Parent Request command
144     kCommandParentResponse                = 10, ///< Parent Response command
145     kCommandChildIdRequest                = 11, ///< Child ID Request command
146     kCommandChildIdResponse               = 12, ///< Child ID Response command
147     kCommandChildUpdateRequest            = 13, ///< Child Update Request command
148     kCommandChildUpdateResponse           = 14, ///< Child Update Response command
149     kCommandAnnounce                      = 15, ///< Announce command
150     kCommandDiscoveryRequest              = 16, ///< Discovery Request command
151     kCommandDiscoveryResponse             = 17, ///< Discovery Response command
152     kCommandLinkMetricsManagementRequest  = 18, ///< Link Metrics Management Request command
153     kCommandLinkMetricsManagementResponse = 19, ///< Link Metrics Management Response command
154     kCommandLinkProbe                     = 20, ///< Link Probe command
155     kCommandTimeSync                      = 99, ///< Time Sync command
156 };
157 
158 constexpr uint16_t kAloc16Leader                      = 0xfc00;
159 constexpr uint16_t kAloc16DhcpAgentStart              = 0xfc01;
160 constexpr uint16_t kAloc16DhcpAgentEnd                = 0xfc0f;
161 constexpr uint16_t kAloc16ServiceStart                = 0xfc10;
162 constexpr uint16_t kAloc16ServiceEnd                  = 0xfc1f;
163 constexpr uint16_t kAloc16ReservedStart               = 0xfc20;
164 constexpr uint16_t kAloc16ReservedEnd                 = 0xfc2f;
165 constexpr uint16_t kAloc16CommissionerStart           = 0xfc30;
166 constexpr uint16_t kAloc16CommissionerEnd             = 0xfc37;
167 constexpr uint16_t kAloc16BackboneRouterPrimary       = 0xfc38;
168 constexpr uint16_t kAloc16CommissionerMask            = 0x0007;
169 constexpr uint16_t kAloc16NeighborDiscoveryAgentStart = 0xfc40;
170 constexpr uint16_t kAloc16NeighborDiscoveryAgentEnd   = 0xfc4e;
171 
172 /**
173  * Specifies the leader role start mode.
174  *
175  * The start mode indicates whether device is starting normally as leader or restoring its role after reset.
176  */
177 enum LeaderStartMode : uint8_t
178 {
179     kStartingAsLeader,              ///< Starting as leader normally.
180     kRestoringLeaderRoleAfterReset, ///< Restoring leader role after reset.
181 };
182 
183 /**
184  * Represents a MLE device mode.
185  */
186 class DeviceMode : public Equatable<DeviceMode>
187 {
188 public:
189     static constexpr uint8_t kModeRxOnWhenIdle     = 1 << 3; ///< If to keep receiver on when not transmitting.
190     static constexpr uint8_t kModeReserved         = 1 << 2; ///< Set on transmission, ignore on reception.
191     static constexpr uint8_t kModeFullThreadDevice = 1 << 1; ///< If the device is an FTD.
192     static constexpr uint8_t kModeFullNetworkData  = 1 << 0; ///< If the device requires the full Network Data.
193 
194     static constexpr uint16_t kInfoStringSize = 45; ///< String buffer size used for `ToString()`.
195 
196     /**
197      * Defines the fixed-length `String` object returned from `ToString()`.
198      */
199     typedef String<kInfoStringSize> InfoString;
200 
201     /**
202      *  This structure represents an MLE Mode configuration.
203      */
204     typedef otLinkModeConfig ModeConfig;
205 
206     /**
207      * This is the default constructor for `DeviceMode` object.
208      */
209     DeviceMode(void) = default;
210 
211     /**
212      * Initializes a `DeviceMode` object from a given mode TLV bitmask.
213      *
214      * @param[in] aMode   A mode TLV bitmask to initialize the `DeviceMode` object.
215      */
DeviceMode(uint8_t aMode)216     explicit DeviceMode(uint8_t aMode) { Set(aMode); }
217 
218     /**
219      * Initializes a `DeviceMode` object from a given mode configuration structure.
220      *
221      * @param[in] aModeConfig   A mode configuration to initialize the `DeviceMode` object.
222      */
DeviceMode(ModeConfig aModeConfig)223     explicit DeviceMode(ModeConfig aModeConfig) { Set(aModeConfig); }
224 
225     /**
226      * Gets the device mode as a mode TLV bitmask.
227      *
228      * @returns The device mode as a mode TLV bitmask.
229      */
Get(void) const230     uint8_t Get(void) const { return mMode; }
231 
232     /**
233      * Sets the device mode from a given mode TLV bitmask.
234      *
235      * @param[in] aMode   A mode TLV bitmask.
236      */
Set(uint8_t aMode)237     void Set(uint8_t aMode) { mMode = aMode | kModeReserved; }
238 
239     /**
240      * Gets the device mode as a mode configuration structure.
241      *
242      * @param[out] aModeConfig   A reference to a mode configuration structure to output the device mode.
243      */
244     void Get(ModeConfig &aModeConfig) const;
245 
246     /**
247      * this method sets the device mode from a given mode configuration structure.
248      *
249      * @param[in] aModeConfig   A mode configuration structure.
250      */
251     void Set(const ModeConfig &aModeConfig);
252 
253     /**
254      * Indicates whether or not the device is rx-on-when-idle.
255      *
256      * @retval TRUE   If the device is rx-on-when-idle (non-sleepy).
257      * @retval FALSE  If the device is not rx-on-when-idle (sleepy).
258      */
IsRxOnWhenIdle(void) const259     bool IsRxOnWhenIdle(void) const { return (mMode & kModeRxOnWhenIdle) != 0; }
260 
261     /**
262      * Indicates whether or not the device is a Full Thread Device.
263      *
264      * @retval TRUE   If the device is Full Thread Device.
265      * @retval FALSE  If the device if not Full Thread Device.
266      */
IsFullThreadDevice(void) const267     bool IsFullThreadDevice(void) const { return (mMode & kModeFullThreadDevice) != 0; }
268 
269     /**
270      * Gets the Network Data type (full set or stable subset) that the device requests.
271      *
272      * @returns The Network Data type requested by this device.
273      */
GetNetworkDataType(void) const274     NetworkData::Type GetNetworkDataType(void) const
275     {
276         return (mMode & kModeFullNetworkData) ? NetworkData::kFullSet : NetworkData::kStableSubset;
277     }
278 
279     /**
280      * Indicates whether or not the device is a Minimal End Device.
281      *
282      * @retval TRUE   If the device is a Minimal End Device.
283      * @retval FALSE  If the device is not a Minimal End Device.
284      */
IsMinimalEndDevice(void) const285     bool IsMinimalEndDevice(void) const
286     {
287         return (mMode & (kModeFullThreadDevice | kModeRxOnWhenIdle)) != (kModeFullThreadDevice | kModeRxOnWhenIdle);
288     }
289 
290     /**
291      * Indicates whether or not the device mode flags are valid.
292      *
293      * An FTD which is not rx-on-when-idle (is sleepy) is considered invalid.
294      *
295      * @returns TRUE if , FALSE otherwise.
296      * @retval TRUE   If the device mode flags are valid.
297      * @retval FALSE  If the device mode flags are not valid.
298      */
IsValid(void) const299     bool IsValid(void) const { return !IsFullThreadDevice() || IsRxOnWhenIdle(); }
300 
301     /**
302      * Converts the device mode into a human-readable string.
303      *
304      * @returns An `InfoString` object representing the device mode.
305      */
306     InfoString ToString(void) const;
307 
308 private:
309     uint8_t mMode;
310 };
311 
312 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE
313 /**
314  * Represents device properties.
315  *
316  * The device properties are used for calculating the local leader weight on the device.
317  */
318 class DeviceProperties : public otDeviceProperties, public Clearable<DeviceProperties>
319 {
320 public:
321     /**
322      * Represents the device's power supply property.
323      */
324     enum PowerSupply : uint8_t
325     {
326         kPowerSupplyBattery          = OT_POWER_SUPPLY_BATTERY,           ///< Battery powered.
327         kPowerSupplyExternal         = OT_POWER_SUPPLY_EXTERNAL,          ///< External powered.
328         kPowerSupplyExternalStable   = OT_POWER_SUPPLY_EXTERNAL_STABLE,   ///< Stable external power with backup.
329         kPowerSupplyExternalUnstable = OT_POWER_SUPPLY_EXTERNAL_UNSTABLE, ///< Unstable external power.
330     };
331 
332     /**
333      * Initializes `DeviceProperties` with default values.
334      */
335     DeviceProperties(void);
336 
337     /**
338      * Clamps the `mLeaderWeightAdjustment` value to the valid range.
339      */
340     void ClampWeightAdjustment(void);
341 
342     /**
343      * Calculates the leader weight based on the device properties.
344      *
345      * @returns The calculated leader weight.
346      */
347     uint8_t CalculateLeaderWeight(void) const;
348 
349 private:
350     static constexpr int8_t  kDefaultAdjustment        = OPENTHREAD_CONFIG_MLE_DEFAULT_LEADER_WEIGHT_ADJUSTMENT;
351     static constexpr uint8_t kBaseWeight               = 64;
352     static constexpr int8_t  kBorderRouterInc          = +1;
353     static constexpr int8_t  kCcmBorderRouterInc       = +8;
354     static constexpr int8_t  kIsUnstableInc            = -4;
355     static constexpr int8_t  kPowerBatteryInc          = -8;
356     static constexpr int8_t  kPowerExternalInc         = 0;
357     static constexpr int8_t  kPowerExternalStableInc   = +4;
358     static constexpr int8_t  kPowerExternalUnstableInc = -4;
359     static constexpr int8_t  kMinAdjustment            = -16;
360     static constexpr int8_t  kMaxAdjustment            = +16;
361 
362     static_assert(kDefaultAdjustment >= kMinAdjustment, "Invalid default weight adjustment");
363     static_assert(kDefaultAdjustment <= kMaxAdjustment, "Invalid default weight adjustment");
364 };
365 
366 #endif // #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE
367 
368 /**
369  * Represents the Thread Leader Data.
370  */
371 class LeaderData : public otLeaderData, public Clearable<LeaderData>
372 {
373 public:
374     /**
375      * Returns the Partition ID value.
376      *
377      * @returns The Partition ID value.
378      */
GetPartitionId(void) const379     uint32_t GetPartitionId(void) const { return mPartitionId; }
380 
381     /**
382      * Sets the Partition ID value.
383      *
384      * @param[in]  aPartitionId  The Partition ID value.
385      */
SetPartitionId(uint32_t aPartitionId)386     void SetPartitionId(uint32_t aPartitionId) { mPartitionId = aPartitionId; }
387 
388     /**
389      * Returns the Weighting value.
390      *
391      * @returns The Weighting value.
392      */
GetWeighting(void) const393     uint8_t GetWeighting(void) const { return mWeighting; }
394 
395     /**
396      * Sets the Weighting value.
397      *
398      * @param[in]  aWeighting  The Weighting value.
399      */
SetWeighting(uint8_t aWeighting)400     void SetWeighting(uint8_t aWeighting) { mWeighting = aWeighting; }
401 
402     /**
403      * Returns the Data Version value for a type (full set or stable subset).
404      *
405      * @param[in] aType   The Network Data type (full set or stable subset).
406      *
407      * @returns The Data Version value for @p aType.
408      */
GetDataVersion(NetworkData::Type aType) const409     uint8_t GetDataVersion(NetworkData::Type aType) const
410     {
411         return (aType == NetworkData::kFullSet) ? mDataVersion : mStableDataVersion;
412     }
413 
414     /**
415      * Sets the Data Version value.
416      *
417      * @param[in]  aVersion  The Data Version value.
418      */
SetDataVersion(uint8_t aVersion)419     void SetDataVersion(uint8_t aVersion) { mDataVersion = aVersion; }
420 
421     /**
422      * Sets the Stable Data Version value.
423      *
424      * @param[in]  aVersion  The Stable Data Version value.
425      */
SetStableDataVersion(uint8_t aVersion)426     void SetStableDataVersion(uint8_t aVersion) { mStableDataVersion = aVersion; }
427 
428     /**
429      * Returns the Leader Router ID value.
430      *
431      * @returns The Leader Router ID value.
432      */
GetLeaderRouterId(void) const433     uint8_t GetLeaderRouterId(void) const { return mLeaderRouterId; }
434 
435     /**
436      * Sets the Leader Router ID value.
437      *
438      * @param[in]  aRouterId  The Leader Router ID value.
439      */
SetLeaderRouterId(uint8_t aRouterId)440     void SetLeaderRouterId(uint8_t aRouterId) { mLeaderRouterId = aRouterId; }
441 };
442 
443 OT_TOOL_PACKED_BEGIN
444 class RouterIdSet : public Equatable<RouterIdSet>, public Clearable<RouterIdSet>
445 {
446 public:
447     /**
448      * Indicates whether or not a Router ID bit is set.
449      *
450      * @param[in]  aRouterId  The Router ID.
451      *
452      * @retval TRUE   If the Router ID bit is set.
453      * @retval FALSE  If the Router ID bit is not set.
454      */
Contains(uint8_t aRouterId) const455     bool Contains(uint8_t aRouterId) const { return (mRouterIdSet[aRouterId / 8] & MaskFor(aRouterId)) != 0; }
456 
457     /**
458      * Sets a given Router ID.
459      *
460      * @param[in]  aRouterId  The Router ID to set.
461      */
Add(uint8_t aRouterId)462     void Add(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] |= MaskFor(aRouterId); }
463 
464     /**
465      * Removes a given Router ID.
466      *
467      * @param[in]  aRouterId  The Router ID to remove.
468      */
Remove(uint8_t aRouterId)469     void Remove(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] &= ~MaskFor(aRouterId); }
470 
471     /**
472      * Calculates the number of allocated Router IDs in the set.
473      *
474      * @returns The number of allocated Router IDs in the set.
475      */
476     uint8_t GetNumberOfAllocatedIds(void) const;
477 
478 private:
MaskFor(uint8_t aRouterId)479     static uint8_t MaskFor(uint8_t aRouterId) { return (0x80 >> (aRouterId % 8)); }
480 
481     uint8_t mRouterIdSet[BytesForBitSize(Mle::kMaxRouterId + 1)];
482 } OT_TOOL_PACKED_END;
483 
484 class TxChallenge;
485 
486 /**
487  * Represents a received Challenge data from an MLE message.
488  */
489 class RxChallenge
490 {
491 public:
492     static constexpr uint8_t kMinSize = 4; ///< Minimum Challenge size in bytes.
493     static constexpr uint8_t kMaxSize = 8; ///< Maximum Challenge size in bytes.
494 
495     /**
496      * Clears the challenge.
497      */
Clear(void)498     void Clear(void) { mArray.Clear(); }
499 
500     /**
501      * Indicates whether or not the challenge data is empty.
502      *
503      * @retval TRUE  The challenge is empty.
504      * @retval FALSE The challenge is not empty.
505      */
IsEmpty(void) const506     bool IsEmpty(void) const { return mArray.GetLength() == 0; }
507 
508     /**
509      * Gets a pointer to challenge data bytes.
510      *
511      * @return A pointer to the challenge data bytes.
512      */
GetBytes(void) const513     const uint8_t *GetBytes(void) const { return mArray.GetArrayBuffer(); }
514 
515     /**
516      * Gets the length of challenge data.
517      *
518      * @returns The length of challenge data in bytes.
519      */
GetLength(void) const520     uint8_t GetLength(void) const { return mArray.GetLength(); }
521 
522     /**
523      * Reads the challenge bytes from given message.
524      *
525      * If the given @p aLength is longer than `kMaxSize`, only `kMaxSize` bytes will be read.
526      *
527      * @param[in] aMessage     The message to read the challenge from.
528      * @param[in] aOffsetRange The offset range in @p aMessage to read from.
529      *
530      * @retval kErrorNone     Successfully read the challenge data from @p aMessage.
531      * @retval kErrorParse    Not enough bytes to read, or invalid length (smaller than `kMinSize`).
532      */
533     Error ReadFrom(const Message &aMessage, const OffsetRange &aOffsetRange);
534 
535     /**
536      * Compares the `RxChallenge` with a given `TxChallenge`.
537      *
538      * @param[in] aTxChallenge  The `TxChallenge` to compare with.
539      *
540      * @retval TRUE  The two challenges are equal.
541      * @retval FALSE The two challenges are not equal.
542      */
543     bool operator==(const TxChallenge &aTxChallenge) const;
544 
545 private:
546     Array<uint8_t, kMaxSize> mArray;
547 };
548 
549 /**
550  * Represents a max-sized challenge data to send in MLE message.
551  *
552  * OpenThread always uses max size challenge when sending MLE messages.
553  */
554 class TxChallenge : public Clearable<TxChallenge>
555 {
556     friend class RxChallenge;
557 
558 public:
559     /**
560      * Generates a cryptographically secure random sequence to populate the challenge data.
561      */
562     void GenerateRandom(void);
563 
564 private:
565     uint8_t m8[RxChallenge::kMaxSize];
566 };
567 
568 /**
569  * Represents a MLE Key Material
570  */
571 typedef Mac::KeyMaterial KeyMaterial;
572 
573 /**
574  * Represents a MLE Key.
575  */
576 typedef Mac::Key Key;
577 
578 /**
579  * Represents the Thread MLE counters.
580  */
581 typedef otMleCounters Counters;
582 
583 /**
584  * Derives the Child ID from a given RLOC16.
585  *
586  * @param[in]  aRloc16  The RLOC16 value.
587  *
588  * @returns The Child ID portion of an RLOC16.
589  */
ChildIdFromRloc16(uint16_t aRloc16)590 inline uint16_t ChildIdFromRloc16(uint16_t aRloc16) { return aRloc16 & kMaxChildId; }
591 
592 /**
593  * Derives the Router ID portion from a given RLOC16.
594  *
595  * @param[in]  aRloc16  The RLOC16 value.
596  *
597  * @returns The Router ID portion of an RLOC16.
598  */
RouterIdFromRloc16(uint16_t aRloc16)599 inline uint8_t RouterIdFromRloc16(uint16_t aRloc16) { return aRloc16 >> kRouterIdOffset; }
600 
601 /**
602  * Indicates whether or not a given Router ID is valid.
603  *
604  * @param[in]  aRouterId  The Router ID value to check.
605  *
606  * @retval TRUE   If @p aRouterId is in correct range [0..62].
607  * @retval FALSE  If @p aRouterId is not a valid Router ID.
608  */
IsRouterIdValid(uint8_t aRouterId)609 inline bool IsRouterIdValid(uint8_t aRouterId) { return aRouterId <= kMaxRouterId; }
610 
611 /**
612  * Returns whether the two RLOC16 have the same Router ID.
613  *
614  * @param[in]  aRloc16A  The first RLOC16 value.
615  * @param[in]  aRloc16B  The second RLOC16 value.
616  *
617  * @returns true if the two RLOC16 have the same Router ID, false otherwise.
618  */
RouterIdMatch(uint16_t aRloc16A,uint16_t aRloc16B)619 inline bool RouterIdMatch(uint16_t aRloc16A, uint16_t aRloc16B)
620 {
621     return RouterIdFromRloc16(aRloc16A) == RouterIdFromRloc16(aRloc16B);
622 }
623 
624 /**
625  * Returns the Service ID corresponding to a Service ALOC16.
626  *
627  * @param[in]  aAloc16  The Service ALOC16 value.
628  *
629  * @returns The Service ID corresponding to given ALOC16.
630  */
ServiceIdFromAloc(uint16_t aAloc16)631 inline uint8_t ServiceIdFromAloc(uint16_t aAloc16) { return static_cast<uint8_t>(aAloc16 - kAloc16ServiceStart); }
632 
633 /**
634  * Returns the Service ALOC16 corresponding to a Service ID.
635  *
636  * @param[in]  aServiceId  The Service ID value.
637  *
638  * @returns The Service ALOC16 corresponding to given ID.
639  */
ServiceAlocFromId(uint8_t aServiceId)640 inline uint16_t ServiceAlocFromId(uint8_t aServiceId)
641 {
642     return static_cast<uint16_t>(aServiceId + kAloc16ServiceStart);
643 }
644 
645 /**
646  * Returns the Commissioner Aloc corresponding to a Commissioner Session ID.
647  *
648  * @param[in]  aSessionId   The Commissioner Session ID value.
649  *
650  * @returns The Commissioner ALOC16 corresponding to given ID.
651  */
CommissionerAloc16FromId(uint16_t aSessionId)652 inline uint16_t CommissionerAloc16FromId(uint16_t aSessionId)
653 {
654     return static_cast<uint16_t>((aSessionId & kAloc16CommissionerMask) + kAloc16CommissionerStart);
655 }
656 
657 /**
658  * Derives RLOC16 from a given Router ID.
659  *
660  * @param[in]  aRouterId  The Router ID value.
661  *
662  * @returns The RLOC16 corresponding to the given Router ID.
663  */
Rloc16FromRouterId(uint8_t aRouterId)664 inline uint16_t Rloc16FromRouterId(uint8_t aRouterId) { return static_cast<uint16_t>(aRouterId << kRouterIdOffset); }
665 
666 /**
667  * Derives the router RLOC16 corresponding to the parent of a given (child) RLOC16.
668  *
669  * If @p aRloc16 itself refers to a router, then the same RLOC16 value is returned.
670  *
671  * @param[in] aRloc16   An RLOC16.
672  *
673  * @returns The router RLOC16 corresponding to the parent associated with @p aRloc16.
674  */
ParentRloc16ForRloc16(uint16_t aRloc16)675 inline uint16_t ParentRloc16ForRloc16(uint16_t aRloc16) { return Rloc16FromRouterId(RouterIdFromRloc16(aRloc16)); }
676 
677 /**
678  * Indicates whether or not @p aRloc16 refers to a router.
679  *
680  * @param[in]  aRloc16  The RLOC16 value.
681  *
682  * @retval TRUE   If @p aRloc16 refers to a router.
683  * @retval FALSE  If @p aRloc16 does not refer to a router.
684  */
IsRouterRloc16(uint16_t aRloc16)685 inline bool IsRouterRloc16(uint16_t aRloc16) { return ChildIdFromRloc16(aRloc16) == 0; }
686 
687 /**
688  * Indicates whether or not @p aRloc16 refers to a child.
689  *
690  * @param[in]  aRloc16  The RLOC16 value.
691  *
692  * @retval TRUE   If @p aRloc16 refers to a child.
693  * @retval FALSE  If @p aRloc16 does not refer to a child.
694  */
IsChildRloc16(uint16_t aRloc16)695 inline bool IsChildRloc16(uint16_t aRloc16) { return ChildIdFromRloc16(aRloc16) != 0; }
696 
697 /**
698  * Converts a device role into a human-readable string.
699  *
700  * @param[in] aRole  The device role to convert.
701  *
702  * @returns The string representation of @p aRole.
703  */
704 const char *RoleToString(DeviceRole aRole);
705 
706 /**
707  * @}
708  */
709 
710 } // namespace Mle
711 
712 DefineCoreType(otLeaderData, Mle::LeaderData);
713 DefineMapEnum(otDeviceRole, Mle::DeviceRole);
714 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE
715 DefineCoreType(otDeviceProperties, Mle::DeviceProperties);
716 DefineMapEnum(otPowerSupply, Mle::DeviceProperties::PowerSupply);
717 #endif
718 
719 } // namespace ot
720 
721 #endif // MLE_TYPES_HPP_
722