• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2016-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 MAC types.
32  */
33 
34 #ifndef MAC_TYPES_HPP_
35 #define MAC_TYPES_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <stdint.h>
40 #include <string.h>
41 
42 #include <openthread/link.h>
43 #include <openthread/thread.h>
44 
45 #include "common/as_core_type.hpp"
46 #include "common/clearable.hpp"
47 #include "common/data.hpp"
48 #include "common/equatable.hpp"
49 #include "common/string.hpp"
50 #include "crypto/storage.hpp"
51 
52 namespace ot {
53 namespace Mac {
54 
55 /**
56  * @addtogroup core-mac
57  *
58  * @{
59  */
60 
61 /**
62  * Represents the IEEE 802.15.4 PAN ID.
63  */
64 typedef otPanId PanId;
65 
66 constexpr PanId kPanIdBroadcast = 0xffff; ///< Broadcast PAN ID.
67 
68 /**
69  * Represents the IEEE 802.15.4 Short Address.
70  */
71 typedef otShortAddress ShortAddress;
72 
73 constexpr ShortAddress kShortAddrBroadcast = OT_RADIO_BROADCAST_SHORT_ADDR; ///< Broadcast Short Address.
74 constexpr ShortAddress kShortAddrInvalid   = OT_RADIO_INVALID_SHORT_ADDR;   ///< Invalid Short Address.
75 
76 /**
77  * Generates a random IEEE 802.15.4 PAN ID.
78  *
79  * @returns A randomly generated IEEE 802.15.4 PAN ID (excluding `kPanIdBroadcast`).
80  */
81 PanId GenerateRandomPanId(void);
82 
83 /**
84  * Represents an IEEE 802.15.4 Extended Address.
85  */
86 OT_TOOL_PACKED_BEGIN
87 class ExtAddress : public otExtAddress, public Equatable<ExtAddress>, public Clearable<ExtAddress>
88 {
89 public:
90     static constexpr uint16_t kInfoStringSize = 17; ///< Max chars for the info string (`ToString()`).
91 
92     /**
93      * Defines the fixed-length `String` object returned from `ToString()`.
94      */
95     typedef String<kInfoStringSize> InfoString;
96 
97     /**
98      * Type specifies the copy byte order when Extended Address is being copied to/from a buffer.
99      */
100     enum CopyByteOrder : uint8_t
101     {
102         kNormalByteOrder,  ///< Copy address bytes in normal order (as provided in array buffer).
103         kReverseByteOrder, ///< Copy address bytes in reverse byte order.
104     };
105 
106     /**
107      * Fills all bytes of address with a given byte value.
108      *
109      * @param[in] aByte A byte value to fill address with.
110      */
Fill(uint8_t aByte)111     void Fill(uint8_t aByte) { memset(this, aByte, sizeof(*this)); }
112 
113 #if OPENTHREAD_FTD || OPENTHREAD_MTD
114     /**
115      * Generates a random IEEE 802.15.4 Extended Address.
116      */
117     void GenerateRandom(void);
118 #endif
119 
120     /**
121      * Sets the Extended Address from a given byte array.
122      *
123      * @param[in] aBuffer    Pointer to an array containing the Extended Address. `OT_EXT_ADDRESS_SIZE` bytes from
124      *                       buffer are copied to form the Extended Address.
125      * @param[in] aByteOrder The byte order to use when copying the address.
126      */
Set(const uint8_t * aBuffer,CopyByteOrder aByteOrder=kNormalByteOrder)127     void Set(const uint8_t *aBuffer, CopyByteOrder aByteOrder = kNormalByteOrder)
128     {
129         CopyAddress(m8, aBuffer, aByteOrder);
130     }
131 
132     /**
133      * Indicates whether or not the Group bit is set.
134      *
135      * @retval TRUE   If the group bit is set.
136      * @retval FALSE  If the group bit is not set.
137      */
IsGroup(void) const138     bool IsGroup(void) const { return (m8[0] & kGroupFlag) != 0; }
139 
140     /**
141      * Sets the Group bit.
142      *
143      * @param[in]  aGroup  TRUE if group address, FALSE otherwise.
144      */
SetGroup(bool aGroup)145     void SetGroup(bool aGroup)
146     {
147         if (aGroup)
148         {
149             m8[0] |= kGroupFlag;
150         }
151         else
152         {
153             m8[0] &= ~kGroupFlag;
154         }
155     }
156 
157     /**
158      * Toggles the Group bit.
159      */
ToggleGroup(void)160     void ToggleGroup(void) { m8[0] ^= kGroupFlag; }
161 
162     /**
163      * Indicates whether or not the Local bit is set.
164      *
165      * @retval TRUE   If the local bit is set.
166      * @retval FALSE  If the local bit is not set.
167      */
IsLocal(void) const168     bool IsLocal(void) const { return (m8[0] & kLocalFlag) != 0; }
169 
170     /**
171      * Sets the Local bit.
172      *
173      * @param[in]  aLocal  TRUE if locally administered, FALSE otherwise.
174      */
SetLocal(bool aLocal)175     void SetLocal(bool aLocal)
176     {
177         if (aLocal)
178         {
179             m8[0] |= kLocalFlag;
180         }
181         else
182         {
183             m8[0] &= ~kLocalFlag;
184         }
185     }
186 
187     /**
188      * Toggles the Local bit.
189      */
ToggleLocal(void)190     void ToggleLocal(void) { m8[0] ^= kLocalFlag; }
191 
192     /**
193      * Copies the Extended Address into a given buffer.
194      *
195      * @param[out] aBuffer     A pointer to a buffer to copy the Extended Address into.
196      * @param[in]  aByteOrder  The byte order to copy the address.
197      */
CopyTo(uint8_t * aBuffer,CopyByteOrder aByteOrder=kNormalByteOrder) const198     void CopyTo(uint8_t *aBuffer, CopyByteOrder aByteOrder = kNormalByteOrder) const
199     {
200         CopyAddress(aBuffer, m8, aByteOrder);
201     }
202 
203     /**
204      * Overloads operator `==` to evaluate whether or not two `ExtAddress` instances are equal.
205      *
206      * @param[in]  aOther  The other `ExtAddress` instance to compare with.
207      *
208      * @retval TRUE   If the two `ExtAddress` instances are equal.
209      * @retval FALSE  If the two `ExtAddress` instances are not equal.
210      */
211     bool operator==(const ExtAddress &aOther) const;
212 
213     /**
214      * Converts an address to a string.
215      *
216      * @returns An `InfoString` containing the string representation of the Extended Address.
217      */
218     InfoString ToString(void) const;
219 
220 private:
221     static constexpr uint8_t kGroupFlag = (1 << 0);
222     static constexpr uint8_t kLocalFlag = (1 << 1);
223 
224     static void CopyAddress(uint8_t *aDst, const uint8_t *aSrc, CopyByteOrder aByteOrder);
225 } OT_TOOL_PACKED_END;
226 
227 /**
228  * Represents an IEEE 802.15.4 Short or Extended Address.
229  */
230 class Address
231 {
232 public:
233     /**
234      * Defines the fixed-length `String` object returned from `ToString()`.
235      */
236     typedef ExtAddress::InfoString InfoString;
237 
238     /**
239      * Specifies the IEEE 802.15.4 Address type.
240      */
241     enum Type : uint8_t
242     {
243         kTypeNone,     ///< No address.
244         kTypeShort,    ///< IEEE 802.15.4 Short Address.
245         kTypeExtended, ///< IEEE 802.15.4 Extended Address.
246     };
247 
248     /**
249      * Initializes an Address.
250      */
Address(void)251     Address(void)
252         : mType(kTypeNone)
253     {
254     }
255 
256     /**
257      * Gets the address type (Short Address, Extended Address, or none).
258      *
259      * @returns The address type.
260      */
GetType(void) const261     Type GetType(void) const { return mType; }
262 
263     /**
264      * Indicates whether or not there is an address.
265      *
266      * @returns TRUE if there is no address (i.e. address type is `kTypeNone`), FALSE otherwise.
267      */
IsNone(void) const268     bool IsNone(void) const { return (mType == kTypeNone); }
269 
270     /**
271      * Indicates whether or not the Address is a Short Address.
272      *
273      * @returns TRUE if it is a Short Address, FALSE otherwise.
274      */
IsShort(void) const275     bool IsShort(void) const { return (mType == kTypeShort); }
276 
277     /**
278      * Indicates whether or not the Address is an Extended Address.
279      *
280      * @returns TRUE if it is an Extended Address, FALSE otherwise.
281      */
IsExtended(void) const282     bool IsExtended(void) const { return (mType == kTypeExtended); }
283 
284     /**
285      * Gets the address as a Short Address.
286      *
287      * MUST be used only if the address type is Short Address.
288      *
289      * @returns The Short Address.
290      */
GetShort(void) const291     ShortAddress GetShort(void) const { return mShared.mShortAddress; }
292 
293     /**
294      * Gets the address as an Extended Address.
295      *
296      * MUST be used only if the address type is Extended Address.
297      *
298      * @returns A constant reference to the Extended Address.
299      */
GetExtended(void) const300     const ExtAddress &GetExtended(void) const { return mShared.mExtAddress; }
301 
302     /**
303      * Gets the address as an Extended Address.
304      *
305      * MUST be used only if the address type is Extended Address.
306      *
307      * @returns A reference to the Extended Address.
308      */
GetExtended(void)309     ExtAddress &GetExtended(void) { return mShared.mExtAddress; }
310 
311     /**
312      * Sets the address to none (i.e., clears the address).
313      *
314      * Address type will be updated to `kTypeNone`.
315      */
SetNone(void)316     void SetNone(void) { mType = kTypeNone; }
317 
318     /**
319      * Sets the address with a Short Address.
320      *
321      * The type is also updated to indicate that address is Short.
322      *
323      * @param[in]  aShortAddress  A Short Address
324      */
SetShort(ShortAddress aShortAddress)325     void SetShort(ShortAddress aShortAddress)
326     {
327         mShared.mShortAddress = aShortAddress;
328         mType                 = kTypeShort;
329     }
330 
331     /**
332      * Sets the address with an Extended Address.
333      *
334      * The type is also updated to indicate that the address is Extended.
335      *
336      * @param[in]  aExtAddress  An Extended Address
337      */
SetExtended(const ExtAddress & aExtAddress)338     void SetExtended(const ExtAddress &aExtAddress)
339     {
340         mShared.mExtAddress = aExtAddress;
341         mType               = kTypeExtended;
342     }
343 
344     /**
345      * Sets the address with an Extended Address given as a byte array.
346      *
347      * The type is also updated to indicate that the address is Extended.
348      *
349      * @param[in] aBuffer    Pointer to an array containing the Extended Address. `OT_EXT_ADDRESS_SIZE` bytes from
350      *                       buffer are copied to form the Extended Address.
351      * @param[in] aByteOrder The byte order to copy the address from @p aBuffer.
352      */
SetExtended(const uint8_t * aBuffer,ExtAddress::CopyByteOrder aByteOrder=ExtAddress::kNormalByteOrder)353     void SetExtended(const uint8_t *aBuffer, ExtAddress::CopyByteOrder aByteOrder = ExtAddress::kNormalByteOrder)
354     {
355         mShared.mExtAddress.Set(aBuffer, aByteOrder);
356         mType = kTypeExtended;
357     }
358 
359     /**
360      * Indicates whether or not the address is a Short Broadcast Address.
361      *
362      * @returns TRUE if address is Short Broadcast Address, FALSE otherwise.
363      */
IsBroadcast(void) const364     bool IsBroadcast(void) const { return ((mType == kTypeShort) && (GetShort() == kShortAddrBroadcast)); }
365 
366     /**
367      * Indicates whether or not the address is a Short Invalid Address.
368      *
369      * @returns TRUE if address is Short Invalid Address, FALSE otherwise.
370      */
IsShortAddrInvalid(void) const371     bool IsShortAddrInvalid(void) const { return ((mType == kTypeShort) && (GetShort() == kShortAddrInvalid)); }
372 
373     /**
374      * Overloads operator `==` to evaluate whether or not two `Address` instances are equal.
375      *
376      * @param[in]  aOther  The other `Address` instance to compare with.
377      *
378      * @retval TRUE   If the two `Address` instances are equal.
379      * @retval FALSE  If the two `Address` instances are not equal.
380      */
381     bool operator==(const Address &aOther) const;
382 
383     /**
384      * Converts an address to a null-terminated string
385      *
386      * @returns A `String` representing the address.
387      */
388     InfoString ToString(void) const;
389 
390 private:
391     union
392     {
393         ShortAddress mShortAddress; ///< The IEEE 802.15.4 Short Address.
394         ExtAddress   mExtAddress;   ///< The IEEE 802.15.4 Extended Address.
395     } mShared;
396 
397     Type mType; ///< The address type (Short, Extended, or none).
398 };
399 
400 /**
401  * Represents two MAC addresses corresponding to source and destination.
402  */
403 struct Addresses
404 {
405     Address mSource;      ///< Source address.
406     Address mDestination; ///< Destination address.
407 };
408 
409 /**
410  * Represents two PAN IDs corresponding to source and destination.
411  */
412 class PanIds : public Clearable<PanIds>
413 {
414 public:
415     /**
416      * Initializes PAN IDs as empty (no source or destination PAN ID).
417      */
PanIds(void)418     PanIds(void) { Clear(); }
419 
420     /**
421      * Indicates whether or not source PAN ID is present.
422      *
423      * @retval TRUE   The source PAN ID is present.
424      * @retval FALSE  The source PAN ID is not present.
425      */
IsSourcePresent(void) const426     bool IsSourcePresent(void) const { return mIsSourcePresent; }
427 
428     /**
429      * Gets the source PAN ID when it is present.
430      *
431      * @returns The source PAN ID.
432      */
GetSource(void) const433     PanId GetSource(void) const { return mSource; }
434 
435     /**
436      * Indicates whether or not destination PAN ID is present.
437      *
438      * @retval TRUE   The destination PAN ID is present.
439      * @retval FALSE  The destination PAN ID is not present.
440      */
IsDestinationPresent(void) const441     bool IsDestinationPresent(void) const { return mIsDestinationPresent; }
442 
443     /**
444      * Gets the destination PAN ID when it is present.
445      *
446      * @returns The destination PAN ID.
447      */
GetDestination(void) const448     PanId GetDestination(void) const { return mDestination; }
449 
450     /**
451      * Sets the source PAN ID.
452      *
453      * @param[in] aPanId  The source PAN ID.
454      */
455     void SetSource(PanId aPanId);
456 
457     /**
458      * Sets the destination PAN ID.
459      *
460      * @param[in] aPanId  The source PAN ID.
461      */
462     void SetDestination(PanId aPanId);
463 
464     /**
465      * Sets both source and destination PAN IDs to the same value.
466      *
467      * @param[in] aPanId  The PAN ID.
468      */
469     void SetBothSourceDestination(PanId aPanId);
470 
471 private:
472     PanId mSource;
473     PanId mDestination;
474     bool  mIsSourcePresent;
475     bool  mIsDestinationPresent;
476 };
477 
478 /**
479  * Represents a MAC key.
480  */
481 OT_TOOL_PACKED_BEGIN
482 class Key : public otMacKey, public Equatable<Key>, public Clearable<Key>
483 {
484 public:
485     static constexpr uint16_t kSize = OT_MAC_KEY_SIZE; ///< Key size in bytes.
486 
487     /**
488      * Gets a pointer to the bytes array containing the key
489      *
490      * @returns A pointer to the byte array containing the key.
491      */
GetBytes(void) const492     const uint8_t *GetBytes(void) const { return m8; }
493 
494 } OT_TOOL_PACKED_END;
495 
496 /**
497  * Represents a MAC Key Ref used by PSA.
498  */
499 typedef otMacKeyRef KeyRef;
500 
501 /**
502  * Represents a MAC Key Material.
503  */
504 class KeyMaterial : public otMacKeyMaterial, public Unequatable<KeyMaterial>
505 {
506 public:
507     /**
508      * Initializes a `KeyMaterial`.
509      */
KeyMaterial(void)510     KeyMaterial(void)
511     {
512         GetKey().Clear();
513 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
514         SetKeyRef(kInvalidKeyRef);
515 #endif
516     }
517 
518 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
519     /**
520      * Overload `=` operator to assign the `KeyMaterial` from another one.
521      *
522      * If the `KeyMaterial` currently stores a valid and different `KeyRef`, the assignment of new value will ensure to
523      * delete the previous one before using the new `KeyRef` from @p aOther.
524      *
525      * @param[in] aOther  aOther  The other `KeyMaterial` instance to assign from.
526      *
527      * @returns A reference to the current `KeyMaterial`
528      */
529     KeyMaterial &operator=(const KeyMaterial &aOther);
530 
531     KeyMaterial(const KeyMaterial &) = delete;
532 #endif
533 
534     /**
535      *  This method clears the `KeyMaterial`.
536      *
537      * Under `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE`, if the `KeyMaterial` currently stores a valid previous
538      * `KeyRef`, the `Clear()` call will ensure to delete the previous `KeyRef` and set it to `kInvalidKeyRef`.
539      */
540     void Clear(void);
541 
542 #if !OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
543     /**
544      * Gets the literal `Key`.
545      *
546      * @returns The literal `Key`
547      */
GetKey(void) const548     const Key &GetKey(void) const { return static_cast<const Key &>(mKeyMaterial.mKey); }
549 
550 #else
551     /**
552      * Gets the stored `KeyRef`
553      *
554      * @returns The `KeyRef`
555      */
GetKeyRef(void) const556     KeyRef GetKeyRef(void) const { return mKeyMaterial.mKeyRef; }
557 #endif
558 
559     /**
560      * Sets the `KeyMaterial` from a given Key.
561      *
562      * If the `KeyMaterial` currently stores a valid `KeyRef`, the `SetFrom()` call will ensure to delete the previous
563      * one before creating and using a new `KeyRef` associated with the new `Key`.
564      *
565      * @param[in] aKey           A reference to the new key.
566      * @param[in] aIsExportable  Boolean indicating if the key is exportable (this is only applicable under
567      *                           `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` config).
568      */
569     void SetFrom(const Key &aKey, bool aIsExportable = false);
570 
571     /**
572      * Extracts the literal key from `KeyMaterial`
573      *
574      * @param[out] aKey  A reference to the output the key.
575      */
576     void ExtractKey(Key &aKey) const;
577 
578     /**
579      * Converts `KeyMaterial` to a `Crypto::Key`.
580      *
581      * @param[out]  aCryptoKey  A reference to a `Crypto::Key` to populate.
582      */
583     void ConvertToCryptoKey(Crypto::Key &aCryptoKey) const;
584 
585     /**
586      * Overloads operator `==` to evaluate whether or not two `KeyMaterial` instances are equal.
587      *
588      * @param[in]  aOther  The other `KeyMaterial` instance to compare with.
589      *
590      * @retval TRUE   If the two `KeyMaterial` instances are equal.
591      * @retval FALSE  If the two `KeyMaterial` instances are not equal.
592      */
593     bool operator==(const KeyMaterial &aOther) const;
594 
595 private:
596 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
597     static constexpr KeyRef kInvalidKeyRef = Crypto::Storage::kInvalidKeyRef;
598 
599     void DestroyKey(void);
SetKeyRef(KeyRef aKeyRef)600     void SetKeyRef(KeyRef aKeyRef) { mKeyMaterial.mKeyRef = aKeyRef; }
601 #endif
GetKey(void)602     Key &GetKey(void) { return static_cast<Key &>(mKeyMaterial.mKey); }
SetKey(const Key & aKey)603     void SetKey(const Key &aKey) { mKeyMaterial.mKey = aKey; }
604 };
605 
606 #if OPENTHREAD_CONFIG_MULTI_RADIO
607 
608 /**
609  * Defines the radio link types.
610  */
611 enum RadioType : uint8_t
612 {
613 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
614     kRadioTypeIeee802154, ///< IEEE 802.15.4 (2.4GHz) link type.
615 #endif
616 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
617     kRadioTypeTrel, ///< Thread Radio Encapsulation link type.
618 #endif
619 };
620 
621 /**
622  * This constant specifies the number of supported radio link types.
623  */
624 constexpr uint8_t kNumRadioTypes = (((OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE) ? 1 : 0) +
625                                     ((OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE) ? 1 : 0));
626 
627 /**
628  * Represents a set of radio links.
629  */
630 class RadioTypes
631 {
632 public:
633     static constexpr uint16_t kInfoStringSize = 32; ///< Max chars for the info string (`ToString()`).
634 
635     /**
636      * Defines the fixed-length `String` object returned from `ToString()`.
637      */
638     typedef String<kInfoStringSize> InfoString;
639 
640     /**
641      * This static class variable defines an array containing all supported radio link types.
642      */
643     static const RadioType kAllRadioTypes[kNumRadioTypes];
644 
645     /**
646      * Initializes a `RadioTypes` object as empty set
647      */
RadioTypes(void)648     RadioTypes(void)
649         : mBitMask(0)
650     {
651     }
652 
653     /**
654      * Initializes a `RadioTypes` object with a given bit-mask.
655      *
656      * @param[in] aMask   A bit-mask representing the radio types (the first bit corresponds to radio type 0, and so on)
657      */
RadioTypes(uint8_t aMask)658     explicit RadioTypes(uint8_t aMask)
659         : mBitMask(aMask)
660     {
661     }
662 
663     /**
664      * Clears the set.
665      */
Clear(void)666     void Clear(void) { mBitMask = 0; }
667 
668     /**
669      * Indicates whether the set is empty or not
670      *
671      * @returns TRUE if the set is empty, FALSE otherwise.
672      */
IsEmpty(void) const673     bool IsEmpty(void) const { return (mBitMask == 0); }
674 
675     /**
676      *  This method indicates whether the set contains only a single radio type.
677      *
678      * @returns TRUE if the set contains a single radio type, FALSE otherwise.
679      */
ContainsSingleRadio(void) const680     bool ContainsSingleRadio(void) const { return !IsEmpty() && ((mBitMask & (mBitMask - 1)) == 0); }
681 
682     /**
683      * Indicates whether or not the set contains a given radio type.
684      *
685      * @param[in] aType  A radio link type.
686      *
687      * @returns TRUE if the set contains @p aType, FALSE otherwise.
688      */
Contains(RadioType aType) const689     bool Contains(RadioType aType) const { return ((mBitMask & BitFlag(aType)) != 0); }
690 
691     /**
692      * Adds a radio type to the set.
693      *
694      * @param[in] aType  A radio link type.
695      */
Add(RadioType aType)696     void Add(RadioType aType) { mBitMask |= BitFlag(aType); }
697 
698     /**
699      * Adds another radio types set to the current one.
700      *
701      * @param[in] aTypes   A radio link type set to add.
702      */
Add(RadioTypes aTypes)703     void Add(RadioTypes aTypes) { mBitMask |= aTypes.mBitMask; }
704 
705     /**
706      * Adds all radio types supported by device to the set.
707      */
708     void AddAll(void);
709 
710     /**
711      * Removes a given radio type from the set.
712      *
713      * @param[in] aType  A radio link type.
714      */
Remove(RadioType aType)715     void Remove(RadioType aType) { mBitMask &= ~BitFlag(aType); }
716 
717     /**
718      * Gets the radio type set as a bitmask.
719      *
720      * The first bit in the mask corresponds to first radio type (radio type with value zero), and so on.
721      *
722      * @returns A bitmask representing the set of radio types.
723      */
GetAsBitMask(void) const724     uint8_t GetAsBitMask(void) const { return mBitMask; }
725 
726     /**
727      * Overloads operator `-` to return a new set which is the set difference between current set and
728      * a given set.
729      *
730      * @param[in] aOther  Another radio type set.
731      *
732      * @returns A new set which is set difference between current one and @p aOther.
733      */
operator -(const RadioTypes & aOther) const734     RadioTypes operator-(const RadioTypes &aOther) const { return RadioTypes(mBitMask & ~aOther.mBitMask); }
735 
736     /**
737      * Converts the radio set to human-readable string.
738      *
739      * @return A string representation of the set of radio types.
740      */
741     InfoString ToString(void) const;
742 
743 private:
BitFlag(RadioType aType)744     static uint8_t BitFlag(RadioType aType) { return static_cast<uint8_t>(1U << static_cast<uint8_t>(aType)); }
745 
746     uint8_t mBitMask;
747 };
748 
749 /**
750  * Converts a link type to a string
751  *
752  * @param[in] aRadioType  A link type value.
753  *
754  * @returns A string representation of the link type.
755  */
756 const char *RadioTypeToString(RadioType aRadioType);
757 
758 #endif // OPENTHREAD_CONFIG_MULTI_RADIO
759 
760 /**
761  * Represents Link Frame Counters for all supported radio links.
762  */
763 class LinkFrameCounters
764 {
765 public:
766     /**
767      * Resets all counters (set them all to zero).
768      */
Reset(void)769     void Reset(void) { SetAll(0); }
770 
771 #if OPENTHREAD_CONFIG_MULTI_RADIO
772 
773     /**
774      * Gets the link Frame Counter for a given radio link.
775      *
776      * @param[in] aRadioType  A radio link type.
777      *
778      * @returns The Link Frame Counter for radio link @p aRadioType.
779      */
780     uint32_t Get(RadioType aRadioType) const;
781 
782     /**
783      * Sets the Link Frame Counter for a given radio link.
784      *
785      * @param[in] aRadioType  A radio link type.
786      * @param[in] aCounter    The new counter value.
787      */
788     void Set(RadioType aRadioType, uint32_t aCounter);
789 
790 #else
791 
792     /**
793      * Gets the Link Frame Counter value.
794      *
795      * @return The Link Frame Counter value.
796      */
Get(void) const797     uint32_t Get(void) const
798 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
799     {
800         return m154Counter;
801     }
802 #elif OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
803     {
804         return mTrelCounter;
805     }
806 #endif
807 
808     /**
809      * Sets the Link Frame Counter for a given radio link.
810      *
811      * @param[in] aCounter    The new counter value.
812      */
Set(uint32_t aCounter)813     void Set(uint32_t aCounter)
814 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
815     {
816         m154Counter = aCounter;
817     }
818 #elif OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
819     {
820         mTrelCounter = aCounter;
821     }
822 #endif
823 
824 #endif // OPENTHREAD_CONFIG_MULTI_RADIO
825 
826 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
827     /**
828      * Gets the Link Frame Counter for 802.15.4 radio link.
829      *
830      * @returns The Link Frame Counter for 802.15.4 radio link.
831      */
Get154(void) const832     uint32_t Get154(void) const { return m154Counter; }
833 
834     /**
835      * Sets the Link Frame Counter for 802.15.4 radio link.
836      *
837      * @param[in] aCounter   The new counter value.
838      */
Set154(uint32_t aCounter)839     void Set154(uint32_t aCounter) { m154Counter = aCounter; }
840 #endif
841 
842 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
843     /**
844      * Gets the Link Frame Counter for TREL radio link.
845      *
846      * @returns The Link Frame Counter for TREL radio link.
847      */
GetTrel(void) const848     uint32_t GetTrel(void) const { return mTrelCounter; }
849 
850     /**
851      * Increments the Link Frame Counter for TREL radio link.
852      */
IncrementTrel(void)853     void IncrementTrel(void) { mTrelCounter++; }
854 #endif
855 
856     /**
857      * Gets the maximum Link Frame Counter among all supported radio links.
858      *
859      * @return The maximum Link frame Counter among all supported radio links.
860      */
861     uint32_t GetMaximum(void) const;
862 
863     /**
864      * Sets the Link Frame Counter value for all radio links.
865      *
866      * @param[in]  aCounter  The Link Frame Counter value.
867      */
868     void SetAll(uint32_t aCounter);
869 
870 private:
871 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
872     uint32_t m154Counter;
873 #endif
874 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
875     uint32_t mTrelCounter;
876 #endif
877 };
878 
879 /**
880  * Represents CSL accuracy.
881  */
882 class CslAccuracy
883 {
884 public:
885     static constexpr uint8_t kWorstClockAccuracy = 255; ///< Worst possible crystal accuracy, in units of ± ppm.
886     static constexpr uint8_t kWorstUncertainty   = 255; ///< Worst possible uncertainty, in units of 10 microseconds.
887 
888     /**
889      * Initializes the CSL accuracy using `kWorstClockAccuracy` and `kWorstUncertainty` values.
890      */
Init(void)891     void Init(void)
892     {
893         mClockAccuracy = kWorstClockAccuracy;
894         mUncertainty   = kWorstUncertainty;
895     }
896 
897     /**
898      * Returns the CSL clock accuracy.
899      *
900      * @returns The CSL clock accuracy in ± ppm.
901      */
GetClockAccuracy(void) const902     uint8_t GetClockAccuracy(void) const { return mClockAccuracy; }
903 
904     /**
905      * Sets the CSL clock accuracy.
906      *
907      * @param[in]  aClockAccuracy  The CSL clock accuracy in ± ppm.
908      */
SetClockAccuracy(uint8_t aClockAccuracy)909     void SetClockAccuracy(uint8_t aClockAccuracy) { mClockAccuracy = aClockAccuracy; }
910 
911     /**
912      * Returns the CSL uncertainty.
913      *
914      * @returns The uncertainty in units 10 microseconds.
915      */
GetUncertainty(void) const916     uint8_t GetUncertainty(void) const { return mUncertainty; }
917 
918     /**
919      * Gets the CLS uncertainty in microseconds.
920      *
921      * @returns the CLS uncertainty in microseconds.
922      */
GetUncertaintyInMicrosec(void) const923     uint16_t GetUncertaintyInMicrosec(void) const { return static_cast<uint16_t>(mUncertainty) * kUsPerUncertUnit; }
924 
925     /**
926      * Sets the CSL uncertainty.
927      *
928      * @param[in]  aUncertainty  The CSL uncertainty in units 10 microseconds.
929      */
SetUncertainty(uint8_t aUncertainty)930     void SetUncertainty(uint8_t aUncertainty) { mUncertainty = aUncertainty; }
931 
932 private:
933     static constexpr uint8_t kUsPerUncertUnit = 10;
934 
935     uint8_t mClockAccuracy;
936     uint8_t mUncertainty;
937 };
938 
939 /**
940  * @}
941  */
942 
943 } // namespace Mac
944 
945 DefineCoreType(otExtAddress, Mac::ExtAddress);
946 DefineCoreType(otMacKey, Mac::Key);
947 
948 } // namespace ot
949 
950 #endif // MAC_TYPES_HPP_
951