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