xref: /aosp_15_r20/external/openthread/src/core/mac/mac_frame.hpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1 /*
2  *  Copyright (c) 2016, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *   This file includes definitions for generating and processing IEEE 802.15.4 MAC frames.
32  */
33 
34 #ifndef MAC_FRAME_HPP_
35 #define MAC_FRAME_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "common/as_core_type.hpp"
40 #include "common/const_cast.hpp"
41 #include "common/encoding.hpp"
42 #include "common/numeric_limits.hpp"
43 #include "mac/mac_types.hpp"
44 #include "meshcop/network_name.hpp"
45 
46 namespace ot {
47 namespace Mac {
48 
49 /**
50  * @addtogroup core-mac
51  *
52  * @{
53  *
54  */
55 
56 /**
57  * Implements IEEE 802.15.4 IE (Information Element) header generation and parsing.
58  *
59  */
60 OT_TOOL_PACKED_BEGIN
61 class HeaderIe
62 {
63 public:
64     /**
65      * Initializes the Header IE.
66      *
67      */
Init(void)68     void Init(void) { mFields.m16 = 0; }
69 
70     /**
71      * Initializes the Header IE with Id and Length.
72      *
73      * @param[in]  aId   The IE Element Id.
74      * @param[in]  aLen  The IE content length.
75      *
76      */
77     void Init(uint16_t aId, uint8_t aLen);
78 
79     /**
80      * Returns the IE Element Id.
81      *
82      * @returns the IE Element Id.
83      *
84      */
GetId(void) const85     uint16_t GetId(void) const { return (LittleEndian::HostSwap16(mFields.m16) & kIdMask) >> kIdOffset; }
86 
87     /**
88      * Sets the IE Element Id.
89      *
90      * @param[in]  aId  The IE Element Id.
91      *
92      */
SetId(uint16_t aId)93     void SetId(uint16_t aId)
94     {
95         mFields.m16 = LittleEndian::HostSwap16((LittleEndian::HostSwap16(mFields.m16) & ~kIdMask) |
96                                                ((aId << kIdOffset) & kIdMask));
97     }
98 
99     /**
100      * Returns the IE content length.
101      *
102      * @returns the IE content length.
103      *
104      */
GetLength(void) const105     uint8_t GetLength(void) const { return mFields.m8[0] & kLengthMask; }
106 
107     /**
108      * Sets the IE content length.
109      *
110      * @param[in]  aLength  The IE content length.
111      *
112      */
SetLength(uint8_t aLength)113     void SetLength(uint8_t aLength) { mFields.m8[0] = (mFields.m8[0] & ~kLengthMask) | (aLength & kLengthMask); }
114 
115 private:
116     // Header IE format:
117     //
118     // +-----------+------------+--------+
119     // | Bits: 0-6 |    7-14    |   15   |
120     // +-----------+------------+--------+
121     // | Length    | Element ID | Type=0 |
122     // +-----------+------------+--------+
123 
124     static constexpr uint8_t  kSize       = 2;
125     static constexpr uint8_t  kIdOffset   = 7;
126     static constexpr uint8_t  kLengthMask = 0x7f;
127     static constexpr uint16_t kIdMask     = 0x00ff << kIdOffset;
128 
129     union OT_TOOL_PACKED_FIELD
130     {
131         uint8_t  m8[kSize];
132         uint16_t m16;
133     } mFields;
134 
135 } OT_TOOL_PACKED_END;
136 
137 /**
138  * Implements CSL IE data structure.
139  *
140  */
141 OT_TOOL_PACKED_BEGIN
142 class CslIe
143 {
144 public:
145     static constexpr uint8_t kHeaderIeId    = 0x1a;
146     static constexpr uint8_t kIeContentSize = sizeof(uint16_t) * 2;
147 
148     /**
149      * Returns the CSL Period.
150      *
151      * @returns the CSL Period.
152      *
153      */
GetPeriod(void) const154     uint16_t GetPeriod(void) const { return LittleEndian::HostSwap16(mPeriod); }
155 
156     /**
157      * Sets the CSL Period.
158      *
159      * @param[in]  aPeriod  The CSL Period.
160      *
161      */
SetPeriod(uint16_t aPeriod)162     void SetPeriod(uint16_t aPeriod) { mPeriod = LittleEndian::HostSwap16(aPeriod); }
163 
164     /**
165      * Returns the CSL Phase.
166      *
167      * @returns the CSL Phase.
168      *
169      */
GetPhase(void) const170     uint16_t GetPhase(void) const { return LittleEndian::HostSwap16(mPhase); }
171 
172     /**
173      * Sets the CSL Phase.
174      *
175      * @param[in]  aPhase  The CSL Phase.
176      *
177      */
SetPhase(uint16_t aPhase)178     void SetPhase(uint16_t aPhase) { mPhase = LittleEndian::HostSwap16(aPhase); }
179 
180 private:
181     uint16_t mPhase;
182     uint16_t mPeriod;
183 } OT_TOOL_PACKED_END;
184 
185 /**
186  * Implements Termination2 IE.
187  *
188  * Is empty for template specialization.
189  *
190  */
191 class Termination2Ie
192 {
193 public:
194     static constexpr uint8_t kHeaderIeId    = 0x7f;
195     static constexpr uint8_t kIeContentSize = 0;
196 };
197 
198 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || \
199     OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
200 /**
201  * Implements vendor specific Header IE generation and parsing.
202  *
203  */
204 OT_TOOL_PACKED_BEGIN
205 class VendorIeHeader
206 {
207 public:
208     static constexpr uint8_t kHeaderIeId    = 0x00;
209     static constexpr uint8_t kIeContentSize = sizeof(uint8_t) * 4;
210 
211     /**
212      * Returns the Vendor OUI.
213      *
214      * @returns The Vendor OUI.
215      *
216      */
GetVendorOui(void) const217     uint32_t GetVendorOui(void) const { return LittleEndian::ReadUint24(mOui); }
218 
219     /**
220      * Sets the Vendor OUI.
221      *
222      * @param[in]  aVendorOui  A Vendor OUI.
223      *
224      */
SetVendorOui(uint32_t aVendorOui)225     void SetVendorOui(uint32_t aVendorOui) { LittleEndian::WriteUint24(aVendorOui, mOui); }
226 
227     /**
228      * Returns the Vendor IE sub-type.
229      *
230      * @returns The Vendor IE sub-type.
231      *
232      */
GetSubType(void) const233     uint8_t GetSubType(void) const { return mSubType; }
234 
235     /**
236      * Sets the Vendor IE sub-type.
237      *
238      * @param[in]  aSubType  The Vendor IE sub-type.
239      *
240      */
SetSubType(uint8_t aSubType)241     void SetSubType(uint8_t aSubType) { mSubType = aSubType; }
242 
243 private:
244     static constexpr uint8_t kOuiSize = 3;
245 
246     uint8_t mOui[kOuiSize];
247     uint8_t mSubType;
248 } OT_TOOL_PACKED_END;
249 
250 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
251 /**
252  * Implements Time Header IE generation and parsing.
253  *
254  */
255 OT_TOOL_PACKED_BEGIN
256 class TimeIe : public VendorIeHeader
257 {
258 public:
259     static constexpr uint32_t kVendorOuiNest = 0x18b430;
260     static constexpr uint8_t  kVendorIeTime  = 0x01;
261     static constexpr uint8_t  kHeaderIeId    = VendorIeHeader::kHeaderIeId;
262     static constexpr uint8_t  kIeContentSize = VendorIeHeader::kIeContentSize + sizeof(uint8_t) + sizeof(uint64_t);
263 
264     /**
265      * Initializes the time IE.
266      *
267      */
Init(void)268     void Init(void)
269     {
270         SetVendorOui(kVendorOuiNest);
271         SetSubType(kVendorIeTime);
272     }
273 
274     /**
275      * Returns the time sync sequence.
276      *
277      * @returns the time sync sequence.
278      *
279      */
GetSequence(void) const280     uint8_t GetSequence(void) const { return mSequence; }
281 
282     /**
283      * Sets the tine sync sequence.
284      *
285      * @param[in]  aSequence The time sync sequence.
286      *
287      */
SetSequence(uint8_t aSequence)288     void SetSequence(uint8_t aSequence) { mSequence = aSequence; }
289 
290     /**
291      * Returns the network time.
292      *
293      * @returns the network time, in microseconds.
294      *
295      */
GetTime(void) const296     uint64_t GetTime(void) const { return LittleEndian::HostSwap64(mTime); }
297 
298     /**
299      * Sets the network time.
300      *
301      * @param[in]  aTime  The network time.
302      *
303      */
SetTime(uint64_t aTime)304     void SetTime(uint64_t aTime) { mTime = LittleEndian::HostSwap64(aTime); }
305 
306 private:
307     uint8_t  mSequence;
308     uint64_t mTime;
309 } OT_TOOL_PACKED_END;
310 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
311 
312 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
313 class ThreadIe
314 {
315 public:
316     static constexpr uint8_t  kHeaderIeId               = VendorIeHeader::kHeaderIeId;
317     static constexpr uint8_t  kIeContentSize            = VendorIeHeader::kIeContentSize;
318     static constexpr uint32_t kVendorOuiThreadCompanyId = 0xeab89b;
319     static constexpr uint8_t  kEnhAckProbingIe          = 0x00;
320 };
321 #endif
322 
323 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE ||
324        // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
325 
326 /**
327  * Implements IEEE 802.15.4 MAC frame generation and parsing.
328  *
329  */
330 class Frame : public otRadioFrame
331 {
332 public:
333     /**
334      * Represents the MAC frame type.
335      *
336      * Values match the Frame Type field in Frame Control Field (FCF)  as an `uint16_t`.
337      *
338      */
339     enum Type : uint16_t
340     {
341         kTypeBeacon = 0, ///< Beacon Frame Type.
342         kTypeData   = 1, ///< Data Frame Type.
343         kTypeAck    = 2, ///< Ack Frame Type.
344         kTypeMacCmd = 3, ///< MAC Command Frame Type.
345     };
346 
347     /**
348      * Represents the MAC frame version.
349      *
350      * Values match the Version field in Frame Control Field (FCF) as an `uint16_t`.
351      *
352      */
353     enum Version : uint16_t
354     {
355         kVersion2003 = 0 << 12, ///< 2003 Frame Version.
356         kVersion2006 = 1 << 12, ///< 2006 Frame Version.
357         kVersion2015 = 2 << 12, ///< 2015 Frame Version.
358     };
359 
360     /**
361      * Represents the MAC frame security level.
362      *
363      * Values match the Security Level field in Security Control Field as an `uint8_t`.
364      *
365      */
366     enum SecurityLevel : uint8_t
367     {
368         kSecurityNone      = 0, ///< No security.
369         kSecurityMic32     = 1, ///< No encryption, MIC-32 authentication.
370         kSecurityMic64     = 2, ///< No encryption, MIC-64 authentication.
371         kSecurityMic128    = 3, ///< No encryption, MIC-128 authentication.
372         kSecurityEnc       = 4, ///< Encryption, no authentication
373         kSecurityEncMic32  = 5, ///< Encryption with MIC-32 authentication.
374         kSecurityEncMic64  = 6, ///< Encryption with MIC-64 authentication.
375         kSecurityEncMic128 = 7, ///< Encryption with MIC-128 authentication.
376     };
377 
378     /**
379      * Represents the MAC frame security key identifier mode.
380      *
381      * Values match the Key Identifier Mode field in Security Control Field as an `uint8_t`.
382      *
383      */
384     enum KeyIdMode : uint8_t
385     {
386         kKeyIdMode0 = 0 << 3, ///< Key ID Mode 0 - Key is determined implicitly.
387         kKeyIdMode1 = 1 << 3, ///< Key ID Mode 1 - Key is determined from Key Index field.
388         kKeyIdMode2 = 2 << 3, ///< Key ID Mode 2 - Key is determined from 4-bytes Key Source and Index fields.
389         kKeyIdMode3 = 3 << 3, ///< Key ID Mode 3 - Key is determined from 8-bytes Key Source and Index fields.
390     };
391 
392     /**
393      * Represents a subset of MAC Command Identifiers.
394      *
395      */
396     enum CommandId : uint8_t
397     {
398         kMacCmdAssociationRequest         = 1,
399         kMacCmdAssociationResponse        = 2,
400         kMacCmdDisassociationNotification = 3,
401         kMacCmdDataRequest                = 4,
402         kMacCmdPanidConflictNotification  = 5,
403         kMacCmdOrphanNotification         = 6,
404         kMacCmdBeaconRequest              = 7,
405         kMacCmdCoordinatorRealignment     = 8,
406         kMacCmdGtsRequest                 = 9,
407     };
408 
409     static constexpr uint16_t kInfoStringSize = 128; ///< Max chars for `InfoString` (ToInfoString()).
410 
411     static constexpr uint8_t kPreambleSize  = 4;
412     static constexpr uint8_t kSfdSize       = 1;
413     static constexpr uint8_t kPhrSize       = 1;
414     static constexpr uint8_t kPhyHeaderSize = kPreambleSize + kSfdSize + kPhrSize;
415     static constexpr uint8_t kFcfSize       = sizeof(uint16_t);
416     static constexpr uint8_t kDsnSize       = sizeof(uint8_t);
417     static constexpr uint8_t k154FcsSize    = sizeof(uint16_t);
418     static constexpr uint8_t kImmAckLength  = kFcfSize + kDsnSize + k154FcsSize;
419 
420     /**
421      * Defines the fixed-length `String` object returned from `ToInfoString()` method.
422      *
423      */
424     typedef String<kInfoStringSize> InfoString;
425 
426     /**
427      * Indicates whether the frame is empty (no payload).
428      *
429      * @retval TRUE   The frame is empty (no PSDU payload).
430      * @retval FALSE  The frame is not empty.
431      *
432      */
IsEmpty(void) const433     bool IsEmpty(void) const { return (mLength == 0); }
434 
435     /**
436      * Initializes the MAC header.
437      *
438      * Determines and writes the Frame Control Field (FCF) and Security Control in the frame along with
439      * given source and destination addresses and PAN IDs.
440      *
441      * The Ack Request bit in FCF is set if there is destination and it is not broadcast and frame type @p aType is not
442      * ACK. The Frame Pending and IE Present bits are not set.
443      *
444      * @param[in] aType          Frame type.
445      * @param[in] aVersion       Frame version.
446      * @param[in] aAddrs         Frame source and destination addresses (each can be none, short, or extended).
447      * @param[in] aPanIds        Source and destination PAN IDs.
448      * @param[in] aSecurityLevel Frame security level.
449      * @param[in] aKeyIdMode     Frame security key ID mode.
450      * @param[in] aSuppressSequence     Whether to suppress sequence number.
451      *
452      */
453     void InitMacHeader(Type             aType,
454                        Version          aVersion,
455                        const Addresses &aAddrs,
456                        const PanIds    &aPanIds,
457                        SecurityLevel    aSecurityLevel,
458                        KeyIdMode        aKeyIdMode        = kKeyIdMode0,
459                        bool             aSuppressSequence = false);
460 
461     /**
462      * Validates the frame.
463      *
464      * @retval kErrorNone    Successfully parsed the MAC header.
465      * @retval kErrorParse   Failed to parse through the MAC header.
466      *
467      */
468     Error ValidatePsdu(void) const;
469 
470     /**
471      * Returns the IEEE 802.15.4 Frame Type.
472      *
473      * @returns The IEEE 802.15.4 Frame Type.
474      *
475      */
GetType(void) const476     uint8_t GetType(void) const { return GetPsdu()[0] & kFcfFrameTypeMask; }
477 
478     /**
479      * Returns whether the frame is an Ack frame.
480      *
481      * @retval TRUE   If this is an Ack.
482      * @retval FALSE  If this is not an Ack.
483      *
484      */
IsAck(void) const485     bool IsAck(void) const { return GetType() == kTypeAck; }
486 
487     /**
488      * Returns the IEEE 802.15.4 Frame Version.
489      *
490      * @returns The IEEE 802.15.4 Frame Version.
491      *
492      */
GetVersion(void) const493     uint16_t GetVersion(void) const { return GetFrameControlField() & kFcfFrameVersionMask; }
494 
495     /**
496      * Returns if this IEEE 802.15.4 frame's version is 2015.
497      *
498      * @returns TRUE if version is 2015, FALSE otherwise.
499      *
500      */
IsVersion2015(void) const501     bool IsVersion2015(void) const { return IsVersion2015(GetFrameControlField()); }
502 
503     /**
504      * Indicates whether or not security is enabled.
505      *
506      * @retval TRUE   If security is enabled.
507      * @retval FALSE  If security is not enabled.
508      *
509      */
GetSecurityEnabled(void) const510     bool GetSecurityEnabled(void) const { return (GetPsdu()[0] & kFcfSecurityEnabled) != 0; }
511 
512     /**
513      * Indicates whether or not the Frame Pending bit is set.
514      *
515      * @retval TRUE   If the Frame Pending bit is set.
516      * @retval FALSE  If the Frame Pending bit is not set.
517      *
518      */
GetFramePending(void) const519     bool GetFramePending(void) const { return (GetPsdu()[0] & kFcfFramePending) != 0; }
520 
521     /**
522      * Sets the Frame Pending bit.
523      *
524      * @param[in]  aFramePending  The Frame Pending bit.
525      *
526      */
527     void SetFramePending(bool aFramePending);
528 
529     /**
530      * Indicates whether or not the Ack Request bit is set.
531      *
532      * @retval TRUE   If the Ack Request bit is set.
533      * @retval FALSE  If the Ack Request bit is not set.
534      *
535      */
GetAckRequest(void) const536     bool GetAckRequest(void) const { return (GetPsdu()[0] & kFcfAckRequest) != 0; }
537 
538     /**
539      * Sets the Ack Request bit.
540      *
541      * @param[in]  aAckRequest  The Ack Request bit.
542      *
543      */
544     void SetAckRequest(bool aAckRequest);
545 
546     /**
547      * Indicates whether or not the PanId Compression bit is set.
548      *
549      * @retval TRUE   If the PanId Compression bit is set.
550      * @retval FALSE  If the PanId Compression bit is not set.
551      *
552      */
IsPanIdCompressed(void) const553     bool IsPanIdCompressed(void) const { return (GetFrameControlField() & kFcfPanidCompression) != 0; }
554 
555     /**
556      * Indicates whether or not IEs present.
557      *
558      * @retval TRUE   If IEs present.
559      * @retval FALSE  If no IE present.
560      *
561      */
IsIePresent(void) const562     bool IsIePresent(void) const { return (GetFrameControlField() & kFcfIePresent) != 0; }
563 
564     /**
565      * Sets the IE Present bit.
566      *
567      * @param[in]  aIePresent   The IE Present bit.
568      *
569      */
570     void SetIePresent(bool aIePresent);
571 
572     /**
573      * Returns the Sequence Number value.
574      *
575      * @returns The Sequence Number value.
576      *
577      */
578     uint8_t GetSequence(void) const;
579 
580     /**
581      * Sets the Sequence Number value.
582      *
583      * @param[in]  aSequence  The Sequence Number value.
584      *
585      */
586     void SetSequence(uint8_t aSequence);
587 
588     /**
589      * Indicates whether or not the Sequence Number is present.
590      *
591      * @returns TRUE if the Sequence Number is present, FALSE otherwise.
592      *
593      */
IsSequencePresent(void) const594     uint8_t IsSequencePresent(void) const { return !IsSequenceSuppressed(GetFrameControlField()); }
595 
596     /**
597      * Get the size of the sequence number.
598      *
599      * @retval      0       The size of sequence number is 0, indicating it's not present.
600      * @retval      1       The size of sequence number is 1, indicating it's present.
601      *
602      */
GetSeqNumSize(void) const603     uint8_t GetSeqNumSize(void) const { return GetSeqNumSize(GetFrameControlField()); }
604 
605     /**
606      * Indicates whether or not the Destination PAN ID is present.
607      *
608      * @returns TRUE if the Destination PAN ID is present, FALSE otherwise.
609      *
610      */
IsDstPanIdPresent(void) const611     bool IsDstPanIdPresent(void) const { return IsDstPanIdPresent(GetFrameControlField()); }
612 
613     /**
614      * Gets the Destination PAN Identifier.
615      *
616      * @param[out]  aPanId  The Destination PAN Identifier.
617      *
618      * @retval kErrorNone   Successfully retrieved the Destination PAN Identifier.
619      * @retval kErrorParse  Failed to parse the PAN Identifier.
620      *
621      */
622     Error GetDstPanId(PanId &aPanId) const;
623 
624     /**
625      * Sets the Destination PAN Identifier.
626      *
627      * @param[in]  aPanId  The Destination PAN Identifier.
628      *
629      */
630     void SetDstPanId(PanId aPanId);
631 
632     /**
633      * Indicates whether or not the Destination Address is present for this object.
634      *
635      * @retval TRUE   If the Destination Address is present.
636      * @retval FALSE  If the Destination Address is not present.
637      *
638      */
IsDstAddrPresent() const639     bool IsDstAddrPresent() const { return IsDstAddrPresent(GetFrameControlField()); }
640 
641     /**
642      * Gets the Destination Address.
643      *
644      * @param[out]  aAddress  The Destination Address.
645      *
646      * @retval kErrorNone  Successfully retrieved the Destination Address.
647      *
648      */
649     Error GetDstAddr(Address &aAddress) const;
650 
651     /**
652      * Sets the Destination Address.
653      *
654      * @param[in]  aShortAddress  The Destination Address.
655      *
656      */
657     void SetDstAddr(ShortAddress aShortAddress);
658 
659     /**
660      * Sets the Destination Address.
661      *
662      * @param[in]  aExtAddress  The Destination Address.
663      *
664      */
665     void SetDstAddr(const ExtAddress &aExtAddress);
666 
667     /**
668      * Sets the Destination Address.
669      *
670      * @param[in]  aAddress  The Destination Address.
671      *
672      */
673     void SetDstAddr(const Address &aAddress);
674 
675     /**
676      * Indicates whether or not the Source Address is present for this object.
677      *
678      * @retval TRUE   If the Source Address is present.
679      * @retval FALSE  If the Source Address is not present.
680      *
681      */
IsSrcPanIdPresent(void) const682     bool IsSrcPanIdPresent(void) const { return IsSrcPanIdPresent(GetFrameControlField()); }
683 
684     /**
685      * Gets the Source PAN Identifier.
686      *
687      * @param[out]  aPanId  The Source PAN Identifier.
688      *
689      * @retval kErrorNone   Successfully retrieved the Source PAN Identifier.
690      *
691      */
692     Error GetSrcPanId(PanId &aPanId) const;
693 
694     /**
695      * Sets the Source PAN Identifier.
696      *
697      * @param[in]  aPanId  The Source PAN Identifier.
698      *
699      * @retval kErrorNone   Successfully set the Source PAN Identifier.
700      *
701      */
702     Error SetSrcPanId(PanId aPanId);
703 
704     /**
705      * Indicates whether or not the Source Address is present for this object.
706      *
707      * @retval TRUE   If the Source Address is present.
708      * @retval FALSE  If the Source Address is not present.
709      *
710      */
IsSrcAddrPresent(void) const711     bool IsSrcAddrPresent(void) const { return IsSrcAddrPresent(GetFrameControlField()); }
712 
713     /**
714      * Gets the Source Address.
715      *
716      * @param[out]  aAddress  The Source Address.
717      *
718      * @retval kErrorNone  Successfully retrieved the Source Address.
719      *
720      */
721     Error GetSrcAddr(Address &aAddress) const;
722 
723     /**
724      * Sets the Source Address.
725      *
726      * @param[in]  aShortAddress  The Source Address.
727      *
728      */
729     void SetSrcAddr(ShortAddress aShortAddress);
730 
731     /**
732      * Sets the Source Address.
733      *
734      * @param[in]  aExtAddress  The Source Address.
735      *
736      */
737     void SetSrcAddr(const ExtAddress &aExtAddress);
738 
739     /**
740      * Sets the Source Address.
741      *
742      * @param[in]  aAddress  The Source Address.
743      *
744      */
745     void SetSrcAddr(const Address &aAddress);
746 
747     /**
748      * Gets the Security Control Field.
749      *
750      * @param[out]  aSecurityControlField  The Security Control Field.
751      *
752      * @retval kErrorNone   Successfully retrieved the Security Level Identifier.
753      * @retval kErrorParse  Failed to find the security control field in the frame.
754      *
755      */
756     Error GetSecurityControlField(uint8_t &aSecurityControlField) const;
757 
758     /**
759      * Sets the Security Control Field.
760      *
761      * @param[in]  aSecurityControlField  The Security Control Field.
762      *
763      */
764     void SetSecurityControlField(uint8_t aSecurityControlField);
765 
766     /**
767      * Gets the Security Level Identifier.
768      *
769      * @param[out]  aSecurityLevel  The Security Level Identifier.
770      *
771      * @retval kErrorNone  Successfully retrieved the Security Level Identifier.
772      *
773      */
774     Error GetSecurityLevel(uint8_t &aSecurityLevel) const;
775 
776     /**
777      * Gets the Key Identifier Mode.
778      *
779      * @param[out]  aKeyIdMode  The Key Identifier Mode.
780      *
781      * @retval kErrorNone  Successfully retrieved the Key Identifier Mode.
782      *
783      */
784     Error GetKeyIdMode(uint8_t &aKeyIdMode) const;
785 
786     /**
787      * Gets the Frame Counter.
788      *
789      * @param[out]  aFrameCounter  The Frame Counter.
790      *
791      * @retval kErrorNone  Successfully retrieved the Frame Counter.
792      *
793      */
794     Error GetFrameCounter(uint32_t &aFrameCounter) const;
795 
796     /**
797      * Sets the Frame Counter.
798      *
799      * @param[in]  aFrameCounter  The Frame Counter.
800      *
801      */
802     void SetFrameCounter(uint32_t aFrameCounter);
803 
804     /**
805      * Returns a pointer to the Key Source.
806      *
807      * @returns A pointer to the Key Source.
808      *
809      */
810     const uint8_t *GetKeySource(void) const;
811 
812     /**
813      * Sets the Key Source.
814      *
815      * @param[in]  aKeySource  A pointer to the Key Source value.
816      *
817      */
818     void SetKeySource(const uint8_t *aKeySource);
819 
820     /**
821      * Gets the Key Identifier.
822      *
823      * @param[out]  aKeyId  The Key Identifier.
824      *
825      * @retval kErrorNone  Successfully retrieved the Key Identifier.
826      *
827      */
828     Error GetKeyId(uint8_t &aKeyId) const;
829 
830     /**
831      * Sets the Key Identifier.
832      *
833      * @param[in]  aKeyId  The Key Identifier.
834      *
835      */
836     void SetKeyId(uint8_t aKeyId);
837 
838     /**
839      * Gets the Command ID.
840      *
841      * @param[out]  aCommandId  The Command ID.
842      *
843      * @retval kErrorNone  Successfully retrieved the Command ID.
844      *
845      */
846     Error GetCommandId(uint8_t &aCommandId) const;
847 
848     /**
849      * Sets the Command ID.
850      *
851      * @param[in]  aCommandId  The Command ID.
852      *
853      * @retval kErrorNone  Successfully set the Command ID.
854      *
855      */
856     Error SetCommandId(uint8_t aCommandId);
857 
858     /**
859      * Indicates whether the frame is a MAC Data Request command (data poll).
860      *
861      * For 802.15.4-2015 and above frame, the frame should be already decrypted.
862      *
863      * @returns TRUE if frame is a MAC Data Request command, FALSE otherwise.
864      *
865      */
866     bool IsDataRequestCommand(void) const;
867 
868     /**
869      * Returns the MAC Frame Length, namely the IEEE 802.15.4 PSDU length.
870      *
871      * @returns The MAC Frame Length.
872      *
873      */
GetLength(void) const874     uint16_t GetLength(void) const { return mLength; }
875 
876     /**
877      * Sets the MAC Frame Length.
878      *
879      * @param[in]  aLength  The MAC Frame Length.
880      *
881      */
SetLength(uint16_t aLength)882     void SetLength(uint16_t aLength) { mLength = aLength; }
883 
884     /**
885      * Returns the MAC header size.
886      *
887      * @returns The MAC header size.
888      *
889      */
890     uint8_t GetHeaderLength(void) const;
891 
892     /**
893      * Returns the MAC footer size.
894      *
895      * @returns The MAC footer size.
896      *
897      */
898     uint8_t GetFooterLength(void) const;
899 
900     /**
901      * Returns the current MAC Payload length.
902      *
903      * @returns The current MAC Payload length.
904      *
905      */
906     uint16_t GetPayloadLength(void) const;
907 
908     /**
909      * Returns the maximum MAC Payload length for the given MAC header and footer.
910      *
911      * @returns The maximum MAC Payload length for the given MAC header and footer.
912      *
913      */
914     uint16_t GetMaxPayloadLength(void) const;
915 
916     /**
917      * Sets the MAC Payload length.
918      *
919      */
920     void SetPayloadLength(uint16_t aLength);
921 
922     /**
923      * Returns the IEEE 802.15.4 channel used for transmission or reception.
924      *
925      * @returns The IEEE 802.15.4 channel used for transmission or reception.
926      *
927      */
GetChannel(void) const928     uint8_t GetChannel(void) const { return mChannel; }
929 
930     /**
931      * Returns a pointer to the PSDU.
932      *
933      * @returns A pointer to the PSDU.
934      *
935      */
GetPsdu(void)936     uint8_t *GetPsdu(void) { return mPsdu; }
937 
938     /**
939      * Returns a pointer to the PSDU.
940      *
941      * @returns A pointer to the PSDU.
942      *
943      */
GetPsdu(void) const944     const uint8_t *GetPsdu(void) const { return mPsdu; }
945 
946     /**
947      * Returns a pointer to the MAC Header.
948      *
949      * @returns A pointer to the MAC Header.
950      *
951      */
GetHeader(void)952     uint8_t *GetHeader(void) { return GetPsdu(); }
953 
954     /**
955      * Returns a pointer to the MAC Header.
956      *
957      * @returns A pointer to the MAC Header.
958      *
959      */
GetHeader(void) const960     const uint8_t *GetHeader(void) const { return GetPsdu(); }
961 
962     /**
963      * Returns a pointer to the MAC Payload.
964      *
965      * @returns A pointer to the MAC Payload.
966      *
967      */
GetPayload(void)968     uint8_t *GetPayload(void) { return AsNonConst(AsConst(this)->GetPayload()); }
969 
970     /**
971      * Returns a pointer to the MAC Payload.
972      *
973      * @returns A pointer to the MAC Payload.
974      *
975      */
976     const uint8_t *GetPayload(void) const;
977 
978     /**
979      * Returns a pointer to the MAC Footer.
980      *
981      * @returns A pointer to the MAC Footer.
982      *
983      */
GetFooter(void)984     uint8_t *GetFooter(void) { return AsNonConst(AsConst(this)->GetFooter()); }
985 
986     /**
987      * Returns a pointer to the MAC Footer.
988      *
989      * @returns A pointer to the MAC Footer.
990      *
991      */
992     const uint8_t *GetFooter(void) const;
993 
994 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
995 
996     /**
997      * Returns a pointer to the vendor specific Time IE.
998      *
999      * @returns A pointer to the Time IE, `nullptr` if not found.
1000      *
1001      */
GetTimeIe(void)1002     TimeIe *GetTimeIe(void) { return AsNonConst(AsConst(this)->GetTimeIe()); }
1003 
1004     /**
1005      * Returns a pointer to the vendor specific Time IE.
1006      *
1007      * @returns A pointer to the Time IE, `nullptr` if not found.
1008      *
1009      */
1010     const TimeIe *GetTimeIe(void) const;
1011 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1012 
1013 #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
1014     /**
1015      * Appends an Header IE at specified index in this frame.
1016      *
1017      * Also sets the IE present bit in the Frame Control Field (FCF).
1018      *
1019      * @param[in,out]   aIndex  The index to append IE. If `aIndex` is `0` on input, this method finds the index
1020      *                          for the first IE and appends the IE at that position. If the position is not found
1021      *                          successfully, `aIndex` will be set to `kInvalidIndex`. Otherwise the IE will be
1022      *                          appended at `aIndex` on input. And on output, `aIndex` will be set to the end of the
1023      *                          IE just appended.
1024      *
1025      * @tparam  IeType  The Header IE type, it MUST contain a constant `kHeaderIeId` equal to the IE's Id
1026      *                  and a constant `kIeContentSize` indicating the IE body's size.
1027      *
1028      * @retval kErrorNone      Successfully appended the Header IE.
1029      * @retval kErrorNotFound  The position for first IE is not found.
1030      *
1031      */
1032     template <typename IeType> Error AppendHeaderIeAt(uint8_t &aIndex);
1033 
1034     /**
1035      * Returns a pointer to the Header IE.
1036      *
1037      * @param[in] aIeId  The Element Id of the Header IE.
1038      *
1039      * @returns A pointer to the Header IE, `nullptr` if not found.
1040      *
1041      */
GetHeaderIe(uint8_t aIeId)1042     uint8_t *GetHeaderIe(uint8_t aIeId) { return AsNonConst(AsConst(this)->GetHeaderIe(aIeId)); }
1043 
1044     /**
1045      * Returns a pointer to the Header IE.
1046      *
1047      * @param[in] aIeId  The Element Id of the Header IE.
1048      *
1049      * @returns A pointer to the Header IE, `nullptr` if not found.
1050      *
1051      */
1052     const uint8_t *GetHeaderIe(uint8_t aIeId) const;
1053 
1054     /**
1055      * Returns a pointer to a specific Thread IE.
1056      *
1057      * A Thread IE is a vendor specific IE with Vendor OUI as `kVendorOuiThreadCompanyId`.
1058      *
1059      * @param[in] aSubType  The sub type of the Thread IE.
1060      *
1061      * @returns A pointer to the Thread IE, `nullptr` if not found.
1062      *
1063      */
GetThreadIe(uint8_t aSubType)1064     uint8_t *GetThreadIe(uint8_t aSubType) { return AsNonConst(AsConst(this)->GetThreadIe(aSubType)); }
1065 
1066     /**
1067      * Returns a pointer to a specific Thread IE.
1068      *
1069      * A Thread IE is a vendor specific IE with Vendor OUI as `kVendorOuiThreadCompanyId`.
1070      *
1071      * @param[in] aSubType  The sub type of the Thread IE.
1072      *
1073      * @returns A pointer to the Thread IE, `nullptr` if not found.
1074      *
1075      */
1076     const uint8_t *GetThreadIe(uint8_t aSubType) const;
1077 
1078 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1079     /**
1080      * Finds CSL IE in the frame and modify its content.
1081      *
1082      * @param[in] aCslPeriod  CSL Period in CSL IE.
1083      * @param[in] aCslPhase   CSL Phase in CSL IE.
1084      *
1085      */
1086     void SetCslIe(uint16_t aCslPeriod, uint16_t aCslPhase);
1087 
1088     /**
1089      * Indicates whether or not the frame contains CSL IE.
1090      *
1091      * @retval TRUE   If the frame contains CSL IE.
1092      * @retval FALSE  If the frame doesn't contain CSL IE.
1093      *
1094      */
1095     bool HasCslIe(void) const;
1096 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
1097 
1098 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE)
1099     /**
1100      * Returns a pointer to a CSL IE.
1101      *
1102      * @returns A pointer to the CSL IE, `nullptr` if not found.
1103      *
1104      */
1105     const CslIe *GetCslIe(void) const;
1106 
1107     /**
1108      * Returns a pointer to a CSL IE.
1109      *
1110      * @returns A pointer to the CSL IE, `nullptr` if not found.
1111      *
1112      */
GetCslIe(void)1113     CslIe *GetCslIe(void) { return AsNonConst(AsConst(this)->GetCslIe()); }
1114 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE)
1115 
1116 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
1117     /**
1118      * Finds Enhanced ACK Probing (Vendor Specific) IE and set its value.
1119      *
1120      * @param[in] aValue  A pointer to the value to set.
1121      * @param[in] aLen    The length of @p aValue.
1122      *
1123      */
1124     void SetEnhAckProbingIe(const uint8_t *aValue, uint8_t aLen);
1125 #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
1126 
1127 #endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
1128 
1129 #if OPENTHREAD_CONFIG_MULTI_RADIO
1130     /**
1131      * Gets the radio link type of the frame.
1132      *
1133      * @returns Frame's radio link type.
1134      *
1135      */
GetRadioType(void) const1136     RadioType GetRadioType(void) const { return static_cast<RadioType>(mRadioType); }
1137 
1138     /**
1139      * Sets the radio link type of the frame.
1140      *
1141      * @param[in] aRadioType  A radio link type.
1142      *
1143      */
SetRadioType(RadioType aRadioType)1144     void SetRadioType(RadioType aRadioType) { mRadioType = static_cast<uint8_t>(aRadioType); }
1145 #endif
1146 
1147     /**
1148      * Returns the maximum transmission unit size (MTU).
1149      *
1150      * @returns The maximum transmission unit (MTU).
1151      *
1152      */
GetMtu(void) const1153     uint16_t GetMtu(void) const
1154 #if !OPENTHREAD_CONFIG_MULTI_RADIO && OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
1155     {
1156         return OT_RADIO_FRAME_MAX_SIZE;
1157     }
1158 #else
1159         ;
1160 #endif
1161 
1162     /**
1163      * Returns the FCS size.
1164      *
1165      * @returns This method returns the FCS size.
1166      *
1167      */
GetFcsSize(void) const1168     uint8_t GetFcsSize(void) const
1169 #if !OPENTHREAD_CONFIG_MULTI_RADIO && OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
1170     {
1171         return k154FcsSize;
1172     }
1173 #else
1174         ;
1175 #endif
1176 
1177     /**
1178      * Returns information about the frame object as an `InfoString` object.
1179      *
1180      * @returns An `InfoString` containing info about the frame.
1181      *
1182      */
1183     InfoString ToInfoString(void) const;
1184 
1185     /**
1186      * Returns the Frame Control field of the frame.
1187      *
1188      * @returns The Frame Control field.
1189      *
1190      */
1191     uint16_t GetFrameControlField(void) const;
1192 
1193 protected:
1194     static constexpr uint8_t kSecurityControlSize = sizeof(uint8_t);
1195     static constexpr uint8_t kFrameCounterSize    = sizeof(uint32_t);
1196     static constexpr uint8_t kCommandIdSize       = sizeof(uint8_t);
1197     static constexpr uint8_t kKeyIndexSize        = sizeof(uint8_t);
1198 
1199     static constexpr uint16_t kFcfFrameTypeMask      = 7 << 0;
1200     static constexpr uint16_t kFcfSecurityEnabled    = 1 << 3;
1201     static constexpr uint16_t kFcfFramePending       = 1 << 4;
1202     static constexpr uint16_t kFcfAckRequest         = 1 << 5;
1203     static constexpr uint16_t kFcfPanidCompression   = 1 << 6;
1204     static constexpr uint16_t kFcfSequenceSupression = 1 << 8;
1205     static constexpr uint16_t kFcfIePresent          = 1 << 9;
1206     static constexpr uint16_t kFcfDstAddrNone        = 0 << 10;
1207     static constexpr uint16_t kFcfDstAddrShort       = 2 << 10;
1208     static constexpr uint16_t kFcfDstAddrExt         = 3 << 10;
1209     static constexpr uint16_t kFcfDstAddrMask        = 3 << 10;
1210     static constexpr uint16_t kFcfFrameVersionMask   = 3 << 12;
1211     static constexpr uint16_t kFcfSrcAddrNone        = 0 << 14;
1212     static constexpr uint16_t kFcfSrcAddrShort       = 2 << 14;
1213     static constexpr uint16_t kFcfSrcAddrExt         = 3 << 14;
1214     static constexpr uint16_t kFcfSrcAddrMask        = 3 << 14;
1215 
1216     static constexpr uint8_t kSecLevelMask  = 7 << 0;
1217     static constexpr uint8_t kKeyIdModeMask = 3 << 3;
1218 
1219     static constexpr uint8_t kMic0Size   = 0;
1220     static constexpr uint8_t kMic32Size  = 32 / kBitsPerByte;
1221     static constexpr uint8_t kMic64Size  = 64 / kBitsPerByte;
1222     static constexpr uint8_t kMic128Size = 128 / kBitsPerByte;
1223     static constexpr uint8_t kMaxMicSize = kMic128Size;
1224 
1225     static constexpr uint8_t kKeySourceSizeMode0 = 0;
1226     static constexpr uint8_t kKeySourceSizeMode1 = 0;
1227     static constexpr uint8_t kKeySourceSizeMode2 = 4;
1228     static constexpr uint8_t kKeySourceSizeMode3 = 8;
1229 
1230     static constexpr uint8_t kInvalidIndex  = 0xff;
1231     static constexpr uint8_t kInvalidSize   = kInvalidIndex;
1232     static constexpr uint8_t kMaxPsduSize   = kInvalidSize - 1;
1233     static constexpr uint8_t kSequenceIndex = kFcfSize;
1234 
1235     void    SetFrameControlField(uint16_t aFcf);
1236     uint8_t FindDstPanIdIndex(void) const;
1237     uint8_t FindDstAddrIndex(void) const;
1238     uint8_t FindSrcPanIdIndex(void) const;
1239     uint8_t FindSrcAddrIndex(void) const;
1240     uint8_t SkipAddrFieldIndex(void) const;
1241     uint8_t FindSecurityHeaderIndex(void) const;
1242     uint8_t SkipSecurityHeaderIndex(void) const;
1243     uint8_t FindPayloadIndex(void) const;
1244 #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
1245     uint8_t FindHeaderIeIndex(void) const;
1246 
1247     Error                           InitIeHeaderAt(uint8_t &aIndex, uint8_t ieId, uint8_t ieContentSize);
1248     template <typename IeType> void InitIeContentAt(uint8_t &aIndex);
1249 #endif
1250 
1251     static uint8_t GetKeySourceLength(uint8_t aKeyIdMode);
1252 
IsDstAddrPresent(uint16_t aFcf)1253     static bool IsDstAddrPresent(uint16_t aFcf) { return (aFcf & kFcfDstAddrMask) != kFcfDstAddrNone; }
1254     static bool IsDstPanIdPresent(uint16_t aFcf);
IsSequenceSuppressed(uint16_t aFcf)1255     static bool IsSequenceSuppressed(uint16_t aFcf)
1256     {
1257         return (aFcf & (kFcfSequenceSupression | kFcfFrameVersionMask)) == (kFcfSequenceSupression | kVersion2015);
1258     }
GetSeqNumSize(uint16_t aFcf)1259     static uint8_t GetSeqNumSize(uint16_t aFcf) { return !IsSequenceSuppressed(aFcf) ? kDsnSize : 0; }
1260 
IsSrcAddrPresent(uint16_t aFcf)1261     static bool IsSrcAddrPresent(uint16_t aFcf) { return (aFcf & kFcfSrcAddrMask) != kFcfSrcAddrNone; }
1262     static bool IsSrcPanIdPresent(uint16_t aFcf);
IsVersion2015(uint16_t aFcf)1263     static bool IsVersion2015(uint16_t aFcf) { return (aFcf & kFcfFrameVersionMask) == kVersion2015; }
1264 
1265     static uint8_t CalculateAddrFieldSize(uint16_t aFcf);
1266     static uint8_t CalculateSecurityHeaderSize(uint8_t aSecurityControl);
1267     static uint8_t CalculateMicSize(uint8_t aSecurityControl);
1268 };
1269 
1270 /**
1271  * Supports received IEEE 802.15.4 MAC frame processing.
1272  *
1273  */
1274 class RxFrame : public Frame
1275 {
1276 public:
1277     friend class TxFrame;
1278 
1279     /**
1280      * Returns the RSSI in dBm used for reception.
1281      *
1282      * @returns The RSSI in dBm used for reception.
1283      *
1284      */
GetRssi(void) const1285     int8_t GetRssi(void) const { return mInfo.mRxInfo.mRssi; }
1286 
1287     /**
1288      * Sets the RSSI in dBm used for reception.
1289      *
1290      * @param[in]  aRssi  The RSSI in dBm used for reception.
1291      *
1292      */
SetRssi(int8_t aRssi)1293     void SetRssi(int8_t aRssi) { mInfo.mRxInfo.mRssi = aRssi; }
1294 
1295     /**
1296      * Returns the receive Link Quality Indicator.
1297      *
1298      * @returns The receive Link Quality Indicator.
1299      *
1300      */
GetLqi(void) const1301     uint8_t GetLqi(void) const { return mInfo.mRxInfo.mLqi; }
1302 
1303     /**
1304      * Sets the receive Link Quality Indicator.
1305      *
1306      * @param[in]  aLqi  The receive Link Quality Indicator.
1307      *
1308      */
SetLqi(uint8_t aLqi)1309     void SetLqi(uint8_t aLqi) { mInfo.mRxInfo.mLqi = aLqi; }
1310 
1311     /**
1312      * Indicates whether or not the received frame is acknowledged with frame pending set.
1313      *
1314      * @retval TRUE   This frame is acknowledged with frame pending set.
1315      * @retval FALSE  This frame is acknowledged with frame pending not set.
1316      *
1317      */
IsAckedWithFramePending(void) const1318     bool IsAckedWithFramePending(void) const { return mInfo.mRxInfo.mAckedWithFramePending; }
1319 
1320     /**
1321      * Returns the timestamp when the frame was received.
1322      *
1323      * The value SHALL be the time of the local radio clock in
1324      * microseconds when the end of the SFD (or equivalently: the start
1325      * of the first symbol of the PHR) was present at the local antenna,
1326      * see the definition of a "symbol boundary" in IEEE 802.15.4-2020,
1327      * section 6.5.2 or equivalently the RMARKER definition in section
1328      * 6.9.1 (albeit both unrelated to OT).
1329      *
1330      * The time is relative to the local radio clock as defined by
1331      * `otPlatRadioGetNow`.
1332      *
1333      * @returns The timestamp in microseconds.
1334      */
GetTimestamp(void) const1335     const uint64_t &GetTimestamp(void) const { return mInfo.mRxInfo.mTimestamp; }
1336 
1337     /**
1338      * Performs AES CCM on the frame which is received.
1339      *
1340      * @param[in]  aExtAddress  A reference to the extended address, which will be used to generate nonce
1341      *                          for AES CCM computation.
1342      * @param[in]  aMacKey      A reference to the MAC key to decrypt the received frame.
1343      *
1344      * @retval kErrorNone      Process of received frame AES CCM succeeded.
1345      * @retval kErrorSecurity  Received frame MIC check failed.
1346      *
1347      */
1348     Error ProcessReceiveAesCcm(const ExtAddress &aExtAddress, const KeyMaterial &aMacKey);
1349 
1350 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1351     /**
1352      * Gets the offset to network time.
1353      *
1354      * @returns  The offset to network time.
1355      *
1356      */
ComputeNetworkTimeOffset(void) const1357     int64_t ComputeNetworkTimeOffset(void) const
1358     {
1359         return static_cast<int64_t>(GetTimeIe()->GetTime() - GetTimestamp());
1360     }
1361 
1362     /**
1363      * Gets the time sync sequence.
1364      *
1365      * @returns  The time sync sequence.
1366      *
1367      */
ReadTimeSyncSeq(void) const1368     uint8_t ReadTimeSyncSeq(void) const { return GetTimeIe()->GetSequence(); }
1369 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1370 };
1371 
1372 /**
1373  * Supports IEEE 802.15.4 MAC frame generation for transmission.
1374  *
1375  */
1376 class TxFrame : public Frame
1377 {
1378 public:
1379     /**
1380      * Sets the channel on which to send the frame.
1381      *
1382      * It also sets the `RxChannelAfterTxDone` to the same channel.
1383      *
1384      * @param[in]  aChannel  The channel used for transmission.
1385      *
1386      */
SetChannel(uint8_t aChannel)1387     void SetChannel(uint8_t aChannel)
1388     {
1389         mChannel = aChannel;
1390         SetRxChannelAfterTxDone(aChannel);
1391     }
1392 
1393     /**
1394      * Sets TX power to send the frame.
1395      *
1396      * @param[in]  aTxPower  The tx power used for transmission.
1397      *
1398      */
SetTxPower(int8_t aTxPower)1399     void SetTxPower(int8_t aTxPower) { mInfo.mTxInfo.mTxPower = aTxPower; }
1400 
1401     /**
1402      * Gets the RX channel after frame TX is done.
1403      *
1404      * @returns The RX channel after frame TX is done.
1405      *
1406      */
GetRxChannelAfterTxDone(void) const1407     uint8_t GetRxChannelAfterTxDone(void) const { return mInfo.mTxInfo.mRxChannelAfterTxDone; }
1408 
1409     /**
1410      * Sets the RX channel after frame TX is done.
1411      *
1412      * @param[in] aChannel   The RX channel after frame TX is done.
1413      *
1414      */
SetRxChannelAfterTxDone(uint8_t aChannel)1415     void SetRxChannelAfterTxDone(uint8_t aChannel) { mInfo.mTxInfo.mRxChannelAfterTxDone = aChannel; }
1416 
1417     /**
1418      * Returns the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring a channel
1419      * access failure.
1420      *
1421      * Equivalent to macMaxCSMABackoffs in IEEE 802.15.4-2006.
1422      *
1423      * @returns The maximum number of backoffs the CSMA-CA algorithm will attempt before declaring a channel access
1424      *          failure.
1425      *
1426      */
GetMaxCsmaBackoffs(void) const1427     uint8_t GetMaxCsmaBackoffs(void) const { return mInfo.mTxInfo.mMaxCsmaBackoffs; }
1428 
1429     /**
1430      * Sets the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring a channel
1431      * access failure.
1432      *
1433      * Equivalent to macMaxCSMABackoffs in IEEE 802.15.4-2006.
1434      *
1435      * @param[in]  aMaxCsmaBackoffs  The maximum number of backoffs the CSMA-CA algorithm will attempt before declaring
1436      *                               a channel access failure.
1437      *
1438      */
SetMaxCsmaBackoffs(uint8_t aMaxCsmaBackoffs)1439     void SetMaxCsmaBackoffs(uint8_t aMaxCsmaBackoffs) { mInfo.mTxInfo.mMaxCsmaBackoffs = aMaxCsmaBackoffs; }
1440 
1441     /**
1442      * Returns the maximum number of retries allowed after a transmission failure.
1443      *
1444      * Equivalent to macMaxFrameRetries in IEEE 802.15.4-2006.
1445      *
1446      * @returns The maximum number of retries allowed after a transmission failure.
1447      *
1448      */
GetMaxFrameRetries(void) const1449     uint8_t GetMaxFrameRetries(void) const { return mInfo.mTxInfo.mMaxFrameRetries; }
1450 
1451     /**
1452      * Sets the maximum number of retries allowed after a transmission failure.
1453      *
1454      * Equivalent to macMaxFrameRetries in IEEE 802.15.4-2006.
1455      *
1456      * @param[in]  aMaxFrameRetries  The maximum number of retries allowed after a transmission failure.
1457      *
1458      */
SetMaxFrameRetries(uint8_t aMaxFrameRetries)1459     void SetMaxFrameRetries(uint8_t aMaxFrameRetries) { mInfo.mTxInfo.mMaxFrameRetries = aMaxFrameRetries; }
1460 
1461     /**
1462      * Indicates whether or not the frame is a retransmission.
1463      *
1464      * @retval TRUE   Frame is a retransmission
1465      * @retval FALSE  This is a new frame and not a retransmission of an earlier frame.
1466      *
1467      */
IsARetransmission(void) const1468     bool IsARetransmission(void) const { return mInfo.mTxInfo.mIsARetx; }
1469 
1470     /**
1471      * Sets the retransmission flag attribute.
1472      *
1473      * @param[in]  aIsARetx  TRUE if frame is a retransmission of an earlier frame, FALSE otherwise.
1474      *
1475      */
SetIsARetransmission(bool aIsARetx)1476     void SetIsARetransmission(bool aIsARetx) { mInfo.mTxInfo.mIsARetx = aIsARetx; }
1477 
1478     /**
1479      * Indicates whether or not CSMA-CA is enabled.
1480      *
1481      * @retval TRUE   CSMA-CA is enabled.
1482      * @retval FALSE  CSMA-CA is not enabled is not enabled.
1483      *
1484      */
IsCsmaCaEnabled(void) const1485     bool IsCsmaCaEnabled(void) const { return mInfo.mTxInfo.mCsmaCaEnabled; }
1486 
1487     /**
1488      * Sets the CSMA-CA enabled attribute.
1489      *
1490      * @param[in]  aCsmaCaEnabled  TRUE if CSMA-CA must be enabled for this packet, FALSE otherwise.
1491      *
1492      */
SetCsmaCaEnabled(bool aCsmaCaEnabled)1493     void SetCsmaCaEnabled(bool aCsmaCaEnabled) { mInfo.mTxInfo.mCsmaCaEnabled = aCsmaCaEnabled; }
1494 
1495     /**
1496      * Returns the key used for frame encryption and authentication (AES CCM).
1497      *
1498      * @returns The pointer to the key.
1499      *
1500      */
GetAesKey(void) const1501     const Mac::KeyMaterial &GetAesKey(void) const
1502     {
1503         return *static_cast<const Mac::KeyMaterial *>(mInfo.mTxInfo.mAesKey);
1504     }
1505 
1506     /**
1507      * Sets the key used for frame encryption and authentication (AES CCM).
1508      *
1509      * @param[in]  aAesKey  The pointer to the key.
1510      *
1511      */
SetAesKey(const Mac::KeyMaterial & aAesKey)1512     void SetAesKey(const Mac::KeyMaterial &aAesKey) { mInfo.mTxInfo.mAesKey = &aAesKey; }
1513 
1514     /**
1515      * Copies the PSDU and all attributes (except for frame link type) from another frame.
1516      *
1517      * @note This method performs a deep copy meaning the content of PSDU buffer from the given frame is copied into
1518      * the PSDU buffer of the current frame.
1519 
1520      * @param[in] aFromFrame  The frame to copy from.
1521      *
1522      */
1523     void CopyFrom(const TxFrame &aFromFrame);
1524 
1525     /**
1526      * Performs AES CCM on the frame which is going to be sent.
1527      *
1528      * @param[in]  aExtAddress  A reference to the extended address, which will be used to generate nonce
1529      *                          for AES CCM computation.
1530      *
1531      */
1532     void ProcessTransmitAesCcm(const ExtAddress &aExtAddress);
1533 
1534     /**
1535      * Indicates whether or not the frame has security processed.
1536      *
1537      * @retval TRUE   The frame already has security processed.
1538      * @retval FALSE  The frame does not have security processed.
1539      *
1540      */
IsSecurityProcessed(void) const1541     bool IsSecurityProcessed(void) const { return mInfo.mTxInfo.mIsSecurityProcessed; }
1542 
1543     /**
1544      * Sets the security processed flag attribute.
1545      *
1546      * @param[in]  aIsSecurityProcessed  TRUE if the frame already has security processed.
1547      *
1548      */
SetIsSecurityProcessed(bool aIsSecurityProcessed)1549     void SetIsSecurityProcessed(bool aIsSecurityProcessed)
1550     {
1551         mInfo.mTxInfo.mIsSecurityProcessed = aIsSecurityProcessed;
1552     }
1553 
1554     /**
1555      * Indicates whether or not the frame contains the CSL IE.
1556      *
1557      * @retval TRUE   The frame contains the CSL IE.
1558      * @retval FALSE  The frame does not contain the CSL IE.
1559      *
1560      */
IsCslIePresent(void) const1561     bool IsCslIePresent(void) const { return mInfo.mTxInfo.mCslPresent; }
1562 
1563     /**
1564      * Sets the CSL IE present flag.
1565      *
1566      * @param[in]  aCslPresent  TRUE if the frame contains the CSL IE.
1567      */
SetCslIePresent(bool aCslPresent)1568     void SetCslIePresent(bool aCslPresent) { mInfo.mTxInfo.mCslPresent = aCslPresent; }
1569 
1570     /**
1571      * Indicates whether or not the frame header is updated.
1572      *
1573      * @retval TRUE   The frame already has the header updated.
1574      * @retval FALSE  The frame does not have the header updated.
1575      *
1576      */
IsHeaderUpdated(void) const1577     bool IsHeaderUpdated(void) const { return mInfo.mTxInfo.mIsHeaderUpdated; }
1578 
1579     /**
1580      * Sets the header updated flag attribute.
1581      *
1582      * @param[in]  aIsHeaderUpdated  TRUE if the frame header is updated.
1583      *
1584      */
SetIsHeaderUpdated(bool aIsHeaderUpdated)1585     void SetIsHeaderUpdated(bool aIsHeaderUpdated) { mInfo.mTxInfo.mIsHeaderUpdated = aIsHeaderUpdated; }
1586 
1587 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1588     /**
1589      * Sets the Time IE offset.
1590      *
1591      * @param[in]  aOffset  The Time IE offset, 0 means no Time IE.
1592      *
1593      */
SetTimeIeOffset(uint8_t aOffset)1594     void SetTimeIeOffset(uint8_t aOffset) { mInfo.mTxInfo.mIeInfo->mTimeIeOffset = aOffset; }
1595 
1596     /**
1597      * Gets the Time IE offset.
1598      *
1599      * @returns The Time IE offset, 0 means no Time IE.
1600      *
1601      */
GetTimeIeOffset(void) const1602     uint8_t GetTimeIeOffset(void) const { return mInfo.mTxInfo.mIeInfo->mTimeIeOffset; }
1603 
1604     /**
1605      * Sets the offset to network time.
1606      *
1607      * @param[in]  aNetworkTimeOffset  The offset to network time.
1608      *
1609      */
SetNetworkTimeOffset(int64_t aNetworkTimeOffset)1610     void SetNetworkTimeOffset(int64_t aNetworkTimeOffset)
1611     {
1612         mInfo.mTxInfo.mIeInfo->mNetworkTimeOffset = aNetworkTimeOffset;
1613     }
1614 
1615     /**
1616      * Sets the time sync sequence.
1617      *
1618      * @param[in]  aTimeSyncSeq  The time sync sequence.
1619      *
1620      */
SetTimeSyncSeq(uint8_t aTimeSyncSeq)1621     void SetTimeSyncSeq(uint8_t aTimeSyncSeq) { mInfo.mTxInfo.mIeInfo->mTimeSyncSeq = aTimeSyncSeq; }
1622 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1623 
1624     /**
1625      * Generate Imm-Ack in this frame object.
1626      *
1627      * @param[in]    aFrame             A reference to the frame received.
1628      * @param[in]    aIsFramePending    Value of the ACK's frame pending bit.
1629      *
1630      */
1631     void GenerateImmAck(const RxFrame &aFrame, bool aIsFramePending);
1632 
1633     /**
1634      * Generate Enh-Ack in this frame object.
1635      *
1636      * @param[in]    aRxFrame           A reference to the received frame.
1637      * @param[in]    aIsFramePending    Value of the ACK's frame pending bit.
1638      * @param[in]    aIeData            A pointer to the IE data portion of the ACK to be sent.
1639      * @param[in]    aIeLength          The length of IE data portion of the ACK to be sent.
1640      *
1641      * @retval  kErrorNone           Successfully generated Enh Ack.
1642      * @retval  kErrorParse          @p aRxFrame has incorrect format.
1643      *
1644      */
1645     Error GenerateEnhAck(const RxFrame &aRxFrame, bool aIsFramePending, const uint8_t *aIeData, uint8_t aIeLength);
1646 
1647 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
1648     /**
1649      * Set TX delay field for the frame.
1650      *
1651      * @param[in]    aTxDelay    The delay time for the TX frame.
1652      *
1653      */
SetTxDelay(uint32_t aTxDelay)1654     void SetTxDelay(uint32_t aTxDelay) { mInfo.mTxInfo.mTxDelay = aTxDelay; }
1655 
1656     /**
1657      * Set TX delay base time field for the frame.
1658      *
1659      * @param[in]    aTxDelayBaseTime    The delay base time for the TX frame.
1660      *
1661      */
SetTxDelayBaseTime(uint32_t aTxDelayBaseTime)1662     void SetTxDelayBaseTime(uint32_t aTxDelayBaseTime) { mInfo.mTxInfo.mTxDelayBaseTime = aTxDelayBaseTime; }
1663 #endif
1664 };
1665 
1666 OT_TOOL_PACKED_BEGIN
1667 class Beacon
1668 {
1669 public:
1670     static constexpr uint16_t kSuperFrameSpec = 0x0fff; ///< Superframe Specification value.
1671 
1672     /**
1673      * Initializes the Beacon message.
1674      *
1675      */
Init(void)1676     void Init(void)
1677     {
1678         mSuperframeSpec     = LittleEndian::HostSwap16(kSuperFrameSpec);
1679         mGtsSpec            = 0;
1680         mPendingAddressSpec = 0;
1681     }
1682 
1683     /**
1684      * Indicates whether or not the beacon appears to be a valid Thread Beacon message.
1685      *
1686      * @retval TRUE   If the beacon appears to be a valid Thread Beacon message.
1687      * @retval FALSE  If the beacon does not appear to be a valid Thread Beacon message.
1688      *
1689      */
IsValid(void) const1690     bool IsValid(void) const
1691     {
1692         return (mSuperframeSpec == LittleEndian::HostSwap16(kSuperFrameSpec)) && (mGtsSpec == 0) &&
1693                (mPendingAddressSpec == 0);
1694     }
1695 
1696     /**
1697      * Returns the pointer to the beacon payload.
1698      *
1699      * @returns A pointer to the beacon payload.
1700      *
1701      */
GetPayload(void)1702     uint8_t *GetPayload(void) { return reinterpret_cast<uint8_t *>(this) + sizeof(*this); }
1703 
1704     /**
1705      * Returns the pointer to the beacon payload.
1706      *
1707      * @returns A pointer to the beacon payload.
1708      *
1709      */
GetPayload(void) const1710     const uint8_t *GetPayload(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }
1711 
1712 private:
1713     uint16_t mSuperframeSpec;
1714     uint8_t  mGtsSpec;
1715     uint8_t  mPendingAddressSpec;
1716 } OT_TOOL_PACKED_END;
1717 
1718 /**
1719  * Implements IEEE 802.15.4 Beacon Payload generation and parsing.
1720  *
1721  */
1722 OT_TOOL_PACKED_BEGIN
1723 class BeaconPayload
1724 {
1725 public:
1726     static constexpr uint8_t kProtocolId      = 3;                     ///< Thread Protocol ID.
1727     static constexpr uint8_t kProtocolVersion = 2;                     ///< Thread Protocol version.
1728     static constexpr uint8_t kVersionOffset   = 4;                     ///< Version field bit offset.
1729     static constexpr uint8_t kVersionMask     = 0xf << kVersionOffset; ///< Version field mask.
1730     static constexpr uint8_t kNativeFlag      = 1 << 3;                ///< Native Commissioner flag.
1731     static constexpr uint8_t kJoiningFlag     = 1 << 0;                ///< Joining Permitted flag.
1732 
1733     /**
1734      * Initializes the Beacon Payload.
1735      *
1736      */
Init(void)1737     void Init(void)
1738     {
1739         mProtocolId = kProtocolId;
1740         mFlags      = kProtocolVersion << kVersionOffset;
1741     }
1742 
1743     /**
1744      * Indicates whether or not the beacon appears to be a valid Thread Beacon Payload.
1745      *
1746      * @retval TRUE   If the beacon appears to be a valid Thread Beacon Payload.
1747      * @retval FALSE  If the beacon does not appear to be a valid Thread Beacon Payload.
1748      *
1749      */
IsValid(void) const1750     bool IsValid(void) const { return (mProtocolId == kProtocolId); }
1751 
1752     /**
1753      * Returns the Protocol ID value.
1754      *
1755      * @returns the Protocol ID value.
1756      *
1757      */
GetProtocolId(void) const1758     uint8_t GetProtocolId(void) const { return mProtocolId; }
1759 
1760     /**
1761      * Returns the Protocol Version value.
1762      *
1763      * @returns The Protocol Version value.
1764      *
1765      */
GetProtocolVersion(void) const1766     uint8_t GetProtocolVersion(void) const { return mFlags >> kVersionOffset; }
1767 
1768     /**
1769      * Indicates whether or not the Native Commissioner flag is set.
1770      *
1771      * @retval TRUE   If the Native Commissioner flag is set.
1772      * @retval FALSE  If the Native Commissioner flag is not set.
1773      *
1774      */
IsNative(void) const1775     bool IsNative(void) const { return (mFlags & kNativeFlag) != 0; }
1776 
1777     /**
1778      * Clears the Native Commissioner flag.
1779      *
1780      */
ClearNative(void)1781     void ClearNative(void) { mFlags &= ~kNativeFlag; }
1782 
1783     /**
1784      * Sets the Native Commissioner flag.
1785      *
1786      */
SetNative(void)1787     void SetNative(void) { mFlags |= kNativeFlag; }
1788 
1789     /**
1790      * Indicates whether or not the Joining Permitted flag is set.
1791      *
1792      * @retval TRUE   If the Joining Permitted flag is set.
1793      * @retval FALSE  If the Joining Permitted flag is not set.
1794      *
1795      */
IsJoiningPermitted(void) const1796     bool IsJoiningPermitted(void) const { return (mFlags & kJoiningFlag) != 0; }
1797 
1798     /**
1799      * Clears the Joining Permitted flag.
1800      *
1801      */
ClearJoiningPermitted(void)1802     void ClearJoiningPermitted(void) { mFlags &= ~kJoiningFlag; }
1803 
1804     /**
1805      * Sets the Joining Permitted flag.
1806      *
1807      */
SetJoiningPermitted(void)1808     void SetJoiningPermitted(void)
1809     {
1810         mFlags |= kJoiningFlag;
1811 
1812 #if OPENTHREAD_CONFIG_MAC_JOIN_BEACON_VERSION != 2 // check against kProtocolVersion
1813         mFlags &= ~kVersionMask;
1814         mFlags |= OPENTHREAD_CONFIG_MAC_JOIN_BEACON_VERSION << kVersionOffset;
1815 #endif
1816     }
1817 
1818     /**
1819      * Gets the Network Name field.
1820      *
1821      * @returns The Network Name field as `NameData`.
1822      *
1823      */
GetNetworkName(void) const1824     MeshCoP::NameData GetNetworkName(void) const { return MeshCoP::NameData(mNetworkName, sizeof(mNetworkName)); }
1825 
1826     /**
1827      * Sets the Network Name field.
1828      *
1829      * @param[in]  aNameData  The Network Name (as a `NameData`).
1830      *
1831      */
SetNetworkName(const MeshCoP::NameData & aNameData)1832     void SetNetworkName(const MeshCoP::NameData &aNameData) { aNameData.CopyTo(mNetworkName, sizeof(mNetworkName)); }
1833 
1834     /**
1835      * Returns the Extended PAN ID field.
1836      *
1837      * @returns The Extended PAN ID field.
1838      *
1839      */
GetExtendedPanId(void) const1840     const otExtendedPanId &GetExtendedPanId(void) const { return mExtendedPanId; }
1841 
1842     /**
1843      * Sets the Extended PAN ID field.
1844      *
1845      * @param[in]  aExtPanId  An Extended PAN ID.
1846      *
1847      */
SetExtendedPanId(const otExtendedPanId & aExtPanId)1848     void SetExtendedPanId(const otExtendedPanId &aExtPanId) { mExtendedPanId = aExtPanId; }
1849 
1850 private:
1851     uint8_t         mProtocolId;
1852     uint8_t         mFlags;
1853     char            mNetworkName[MeshCoP::NetworkName::kMaxSize];
1854     otExtendedPanId mExtendedPanId;
1855 } OT_TOOL_PACKED_END;
1856 
1857 /**
1858  * @}
1859  *
1860  */
1861 
1862 } // namespace Mac
1863 } // namespace ot
1864 
1865 #endif // MAC_FRAME_HPP_
1866