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