• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <limits.h>
40 #include <stdint.h>
41 
42 #include "common/as_core_type.hpp"
43 #include "common/const_cast.hpp"
44 #include "common/encoding.hpp"
45 #include "mac/mac_types.hpp"
46 #include "meshcop/network_name.hpp"
47 
48 namespace ot {
49 namespace Mac {
50 
51 using ot::Encoding::LittleEndian::HostSwap16;
52 using ot::Encoding::LittleEndian::HostSwap64;
53 using ot::Encoding::LittleEndian::ReadUint24;
54 using ot::Encoding::LittleEndian::WriteUint24;
55 
56 /**
57  * @addtogroup core-mac
58  *
59  * @{
60  *
61  */
62 
63 /**
64  * This class implements IEEE 802.15.4 IE (Information Element) header generation and parsing.
65  *
66  */
67 OT_TOOL_PACKED_BEGIN
68 class HeaderIe
69 {
70 public:
71     /**
72      * This method initializes the Header IE.
73      *
74      */
Init(void)75     void Init(void) { mFields.m16 = 0; }
76 
77     /**
78      * This method initializes the Header IE with Id and Length.
79      *
80      * @param[in]  aId   The IE Element Id.
81      * @param[in]  aLen  The IE content length.
82      *
83      */
84     void Init(uint16_t aId, uint8_t aLen);
85 
86     /**
87      * This method returns the IE Element Id.
88      *
89      * @returns the IE Element Id.
90      *
91      */
GetId(void) const92     uint16_t GetId(void) const { return (HostSwap16(mFields.m16) & kIdMask) >> kIdOffset; }
93 
94     /**
95      * This method sets the IE Element Id.
96      *
97      * @param[in]  aId  The IE Element Id.
98      *
99      */
SetId(uint16_t aId)100     void SetId(uint16_t aId)
101     {
102         mFields.m16 = HostSwap16((HostSwap16(mFields.m16) & ~kIdMask) | ((aId << kIdOffset) & kIdMask));
103     }
104 
105     /**
106      * This method returns the IE content length.
107      *
108      * @returns the IE content length.
109      *
110      */
GetLength(void) const111     uint8_t GetLength(void) const { return mFields.m8[0] & kLengthMask; }
112 
113     /**
114      * This method sets the IE content length.
115      *
116      * @param[in]  aLength  The IE content length.
117      *
118      */
SetLength(uint8_t aLength)119     void SetLength(uint8_t aLength) { mFields.m8[0] = (mFields.m8[0] & ~kLengthMask) | (aLength & kLengthMask); }
120 
121 private:
122     // Header IE format:
123     //
124     // +-----------+------------+--------+
125     // | Bits: 0-6 |    7-14    |   15   |
126     // +-----------+------------+--------+
127     // | Length    | Element ID | Type=0 |
128     // +-----------+------------+--------+
129 
130     static constexpr uint8_t  kSize       = 2;
131     static constexpr uint8_t  kIdOffset   = 7;
132     static constexpr uint8_t  kLengthMask = 0x7f;
133     static constexpr uint16_t kIdMask     = 0x00ff << kIdOffset;
134 
135     union OT_TOOL_PACKED_FIELD
136     {
137         uint8_t  m8[kSize];
138         uint16_t m16;
139     } mFields;
140 
141 } OT_TOOL_PACKED_END;
142 
143 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || \
144     OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
145 /**
146  * This class implements vendor specific Header IE generation and parsing.
147  *
148  */
149 OT_TOOL_PACKED_BEGIN
150 class VendorIeHeader
151 {
152 public:
153     static constexpr uint8_t kHeaderIeId    = 0x00;
154     static constexpr uint8_t kIeContentSize = sizeof(uint8_t) * 4;
155 
156     /**
157      * This method returns the Vendor OUI.
158      *
159      * @returns The Vendor OUI.
160      *
161      */
GetVendorOui(void) const162     uint32_t GetVendorOui(void) const { return ReadUint24(mOui); }
163 
164     /**
165      * This method sets the Vendor OUI.
166      *
167      * @param[in]  aVendorOui  A Vendor OUI.
168      *
169      */
SetVendorOui(uint32_t aVendorOui)170     void SetVendorOui(uint32_t aVendorOui) { WriteUint24(aVendorOui, mOui); }
171 
172     /**
173      * This method returns the Vendor IE sub-type.
174      *
175      * @returns The Vendor IE sub-type.
176      *
177      */
GetSubType(void) const178     uint8_t GetSubType(void) const { return mSubType; }
179 
180     /**
181      * This method sets the Vendor IE sub-type.
182      *
183      * @param[in]  aSubType  The Vendor IE sub-type.
184      *
185      */
SetSubType(uint8_t aSubType)186     void SetSubType(uint8_t aSubType) { mSubType = aSubType; }
187 
188 private:
189     static constexpr uint8_t kOuiSize = 3;
190 
191     uint8_t mOui[kOuiSize];
192     uint8_t mSubType;
193 } OT_TOOL_PACKED_END;
194 
195 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
196 /**
197  * This class implements Time Header IE generation and parsing.
198  *
199  */
200 OT_TOOL_PACKED_BEGIN
201 class TimeIe : public VendorIeHeader
202 {
203 public:
204     static constexpr uint32_t kVendorOuiNest = 0x18b430;
205     static constexpr uint8_t  kVendorIeTime  = 0x01;
206     static constexpr uint8_t  kHeaderIeId    = VendorIeHeader::kHeaderIeId;
207     static constexpr uint8_t  kIeContentSize = VendorIeHeader::kIeContentSize + sizeof(uint8_t) + sizeof(uint64_t);
208 
209     /**
210      * This method initializes the time IE.
211      *
212      */
Init(void)213     void Init(void)
214     {
215         SetVendorOui(kVendorOuiNest);
216         SetSubType(kVendorIeTime);
217     }
218 
219     /**
220      * This method returns the time sync sequence.
221      *
222      * @returns the time sync sequence.
223      *
224      */
GetSequence(void) const225     uint8_t GetSequence(void) const { return mSequence; }
226 
227     /**
228      * This method sets the tine sync sequence.
229      *
230      * @param[in]  aSequence The time sync sequence.
231      *
232      */
SetSequence(uint8_t aSequence)233     void SetSequence(uint8_t aSequence) { mSequence = aSequence; }
234 
235     /**
236      * This method returns the network time.
237      *
238      * @returns the network time, in microseconds.
239      *
240      */
GetTime(void) const241     uint64_t GetTime(void) const { return HostSwap64(mTime); }
242 
243     /**
244      * This method sets the network time.
245      *
246      * @param[in]  aTime  The network time.
247      *
248      */
SetTime(uint64_t aTime)249     void SetTime(uint64_t aTime) { mTime = HostSwap64(aTime); }
250 
251 private:
252     uint8_t  mSequence;
253     uint64_t mTime;
254 } OT_TOOL_PACKED_END;
255 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
256 
257 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
258 class ThreadIe
259 {
260 public:
261     static constexpr uint8_t  kHeaderIeId               = VendorIeHeader::kHeaderIeId;
262     static constexpr uint8_t  kIeContentSize            = VendorIeHeader::kIeContentSize;
263     static constexpr uint32_t kVendorOuiThreadCompanyId = 0xeab89b;
264     static constexpr uint8_t  kEnhAckProbingIe          = 0x00;
265 };
266 #endif
267 
268 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE ||
269        // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
270 
271 /**
272  * This class implements IEEE 802.15.4 MAC frame generation and parsing.
273  *
274  */
275 class Frame : public otRadioFrame
276 {
277 public:
278     static constexpr uint8_t kFcfSize             = sizeof(uint16_t);
279     static constexpr uint8_t kDsnSize             = sizeof(uint8_t);
280     static constexpr uint8_t kSecurityControlSize = sizeof(uint8_t);
281     static constexpr uint8_t kFrameCounterSize    = sizeof(uint32_t);
282     static constexpr uint8_t kCommandIdSize       = sizeof(uint8_t);
283     static constexpr uint8_t k154FcsSize          = sizeof(uint16_t);
284 
285     static constexpr uint16_t kFcfFrameBeacon      = 0 << 0;
286     static constexpr uint16_t kFcfFrameData        = 1 << 0;
287     static constexpr uint16_t kFcfFrameAck         = 2 << 0;
288     static constexpr uint16_t kFcfFrameMacCmd      = 3 << 0;
289     static constexpr uint16_t kFcfFrameTypeMask    = 7 << 0;
290     static constexpr uint16_t kFcfSecurityEnabled  = 1 << 3;
291     static constexpr uint16_t kFcfFramePending     = 1 << 4;
292     static constexpr uint16_t kFcfAckRequest       = 1 << 5;
293     static constexpr uint16_t kFcfPanidCompression = 1 << 6;
294     static constexpr uint16_t kFcfIePresent        = 1 << 9;
295     static constexpr uint16_t kFcfDstAddrNone      = 0 << 10;
296     static constexpr uint16_t kFcfDstAddrShort     = 2 << 10;
297     static constexpr uint16_t kFcfDstAddrExt       = 3 << 10;
298     static constexpr uint16_t kFcfDstAddrMask      = 3 << 10;
299     static constexpr uint16_t kFcfFrameVersion2006 = 1 << 12;
300     static constexpr uint16_t kFcfFrameVersion2015 = 2 << 12;
301     static constexpr uint16_t kFcfFrameVersionMask = 3 << 12;
302     static constexpr uint16_t kFcfSrcAddrNone      = 0 << 14;
303     static constexpr uint16_t kFcfSrcAddrShort     = 2 << 14;
304     static constexpr uint16_t kFcfSrcAddrExt       = 3 << 14;
305     static constexpr uint16_t kFcfSrcAddrMask      = 3 << 14;
306 
307     static constexpr uint8_t kSecNone      = 0 << 0;
308     static constexpr uint8_t kSecMic32     = 1 << 0;
309     static constexpr uint8_t kSecMic64     = 2 << 0;
310     static constexpr uint8_t kSecMic128    = 3 << 0;
311     static constexpr uint8_t kSecEnc       = 4 << 0;
312     static constexpr uint8_t kSecEncMic32  = 5 << 0;
313     static constexpr uint8_t kSecEncMic64  = 6 << 0;
314     static constexpr uint8_t kSecEncMic128 = 7 << 0;
315     static constexpr uint8_t kSecLevelMask = 7 << 0;
316 
317     static constexpr uint8_t kMic0Size   = 0;
318     static constexpr uint8_t kMic32Size  = 32 / CHAR_BIT;
319     static constexpr uint8_t kMic64Size  = 64 / CHAR_BIT;
320     static constexpr uint8_t kMic128Size = 128 / CHAR_BIT;
321     static constexpr uint8_t kMaxMicSize = kMic128Size;
322 
323     static constexpr uint8_t kKeyIdMode0    = 0 << 3;
324     static constexpr uint8_t kKeyIdMode1    = 1 << 3;
325     static constexpr uint8_t kKeyIdMode2    = 2 << 3;
326     static constexpr uint8_t kKeyIdMode3    = 3 << 3;
327     static constexpr uint8_t kKeyIdModeMask = 3 << 3;
328 
329     static constexpr uint8_t kKeySourceSizeMode0 = 0;
330     static constexpr uint8_t kKeySourceSizeMode1 = 0;
331     static constexpr uint8_t kKeySourceSizeMode2 = 4;
332     static constexpr uint8_t kKeySourceSizeMode3 = 8;
333 
334     static constexpr uint8_t kKeyIndexSize = sizeof(uint8_t);
335 
336     static constexpr uint8_t kMacCmdAssociationRequest         = 1;
337     static constexpr uint8_t kMacCmdAssociationResponse        = 2;
338     static constexpr uint8_t kMacCmdDisassociationNotification = 3;
339     static constexpr uint8_t kMacCmdDataRequest                = 4;
340     static constexpr uint8_t kMacCmdPanidConflictNotification  = 5;
341     static constexpr uint8_t kMacCmdOrphanNotification         = 6;
342     static constexpr uint8_t kMacCmdBeaconRequest              = 7;
343     static constexpr uint8_t kMacCmdCoordinatorRealignment     = 8;
344     static constexpr uint8_t kMacCmdGtsRequest                 = 9;
345 
346     static constexpr uint8_t kImmAckLength = kFcfSize + kDsnSize + k154FcsSize;
347 
348     static constexpr uint16_t kInfoStringSize = 128; ///< Max chars for `InfoString` (ToInfoString()).
349 
350     /**
351      * This type defines the fixed-length `String` object returned from `ToInfoString()` method.
352      *
353      */
354     typedef String<kInfoStringSize> InfoString;
355 
356     /**
357      * This method indicates whether the frame is empty (no payload).
358      *
359      * @retval TRUE   The frame is empty (no PSDU payload).
360      * @retval FALSE  The frame is not empty.
361      *
362      */
IsEmpty(void) const363     bool IsEmpty(void) const { return (mLength == 0); }
364 
365     /**
366      * This method initializes the MAC header.
367      *
368      * @param[in]  aFcf              The Frame Control field.
369      * @param[in]  aSecurityControl  The Security Control field.
370      *
371      */
372     void InitMacHeader(uint16_t aFcf, uint8_t aSecurityControl);
373 
374     /**
375      * This method validates the frame.
376      *
377      * @retval kErrorNone    Successfully parsed the MAC header.
378      * @retval kErrorParse   Failed to parse through the MAC header.
379      *
380      */
381     Error ValidatePsdu(void) const;
382 
383     /**
384      * This method returns the IEEE 802.15.4 Frame Type.
385      *
386      * @returns The IEEE 802.15.4 Frame Type.
387      *
388      */
GetType(void) const389     uint8_t GetType(void) const { return GetPsdu()[0] & kFcfFrameTypeMask; }
390 
391     /**
392      * This method returns whether the frame is an Ack frame.
393      *
394      * @retval TRUE   If this is an Ack.
395      * @retval FALSE  If this is not an Ack.
396      *
397      */
IsAck(void) const398     bool IsAck(void) const { return GetType() == kFcfFrameAck; }
399 
400     /**
401      * This method returns the IEEE 802.15.4 Frame Version.
402      *
403      * @returns The IEEE 802.15.4 Frame Version.
404      *
405      */
GetVersion(void) const406     uint16_t GetVersion(void) const { return GetFrameControlField() & kFcfFrameVersionMask; }
407 
408     /**
409      * This method returns if this IEEE 802.15.4 frame's version is 2015.
410      *
411      * @returns TRUE if version is 2015, FALSE otherwise.
412      *
413      */
IsVersion2015(void) const414     bool IsVersion2015(void) const { return IsVersion2015(GetFrameControlField()); }
415 
416     /**
417      * This method indicates whether or not security is enabled.
418      *
419      * @retval TRUE   If security is enabled.
420      * @retval FALSE  If security is not enabled.
421      *
422      */
GetSecurityEnabled(void) const423     bool GetSecurityEnabled(void) const { return (GetPsdu()[0] & kFcfSecurityEnabled) != 0; }
424 
425     /**
426      * This method indicates whether or not the Frame Pending bit is set.
427      *
428      * @retval TRUE   If the Frame Pending bit is set.
429      * @retval FALSE  If the Frame Pending bit is not set.
430      *
431      */
GetFramePending(void) const432     bool GetFramePending(void) const { return (GetPsdu()[0] & kFcfFramePending) != 0; }
433 
434     /**
435      * This method sets the Frame Pending bit.
436      *
437      * @param[in]  aFramePending  The Frame Pending bit.
438      *
439      */
440     void SetFramePending(bool aFramePending);
441 
442     /**
443      * This method indicates whether or not the Ack Request bit is set.
444      *
445      * @retval TRUE   If the Ack Request bit is set.
446      * @retval FALSE  If the Ack Request bit is not set.
447      *
448      */
GetAckRequest(void) const449     bool GetAckRequest(void) const { return (GetPsdu()[0] & kFcfAckRequest) != 0; }
450 
451     /**
452      * This method sets the Ack Request bit.
453      *
454      * @param[in]  aAckRequest  The Ack Request bit.
455      *
456      */
457     void SetAckRequest(bool aAckRequest);
458 
459     /**
460      * This method indicates whether or not the PanId Compression bit is set.
461      *
462      * @retval TRUE   If the PanId Compression bit is set.
463      * @retval FALSE  If the PanId Compression bit is not set.
464      *
465      */
IsPanIdCompressed(void) const466     bool IsPanIdCompressed(void) const { return (GetFrameControlField() & kFcfPanidCompression) != 0; }
467 
468     /**
469      * This method indicates whether or not IEs present.
470      *
471      * @retval TRUE   If IEs present.
472      * @retval FALSE  If no IE present.
473      *
474      */
IsIePresent(void) const475     bool IsIePresent(void) const { return (GetFrameControlField() & kFcfIePresent) != 0; }
476 
477     /**
478      * This method returns the Sequence Number value.
479      *
480      * @returns The Sequence Number value.
481      *
482      */
GetSequence(void) const483     uint8_t GetSequence(void) const { return GetPsdu()[kSequenceIndex]; }
484 
485     /**
486      * This method sets the Sequence Number value.
487      *
488      * @param[in]  aSequence  The Sequence Number value.
489      *
490      */
SetSequence(uint8_t aSequence)491     void SetSequence(uint8_t aSequence) { GetPsdu()[kSequenceIndex] = aSequence; }
492 
493     /**
494      * This method indicates whether or not the Destination PAN ID is present.
495      *
496      * @returns TRUE if the Destination PAN ID is present, FALSE otherwise.
497      *
498      */
IsDstPanIdPresent(void) const499     bool IsDstPanIdPresent(void) const { return IsDstPanIdPresent(GetFrameControlField()); }
500 
501     /**
502      * This method gets the Destination PAN Identifier.
503      *
504      * @param[out]  aPanId  The Destination PAN Identifier.
505      *
506      * @retval kErrorNone   Successfully retrieved the Destination PAN Identifier.
507      * @retval kErrorParse  Failed to parse the PAN Identifier.
508      *
509      */
510     Error GetDstPanId(PanId &aPanId) const;
511 
512     /**
513      * This method sets the Destination PAN Identifier.
514      *
515      * @param[in]  aPanId  The Destination PAN Identifier.
516      *
517      */
518     void SetDstPanId(PanId aPanId);
519 
520     /**
521      * This method indicates whether or not the Destination Address is present for this object.
522      *
523      * @retval TRUE   If the Destination Address is present.
524      * @retval FALSE  If the Destination Address is not present.
525      *
526      */
IsDstAddrPresent() const527     bool IsDstAddrPresent() const { return IsDstAddrPresent(GetFrameControlField()); }
528 
529     /**
530      * This method gets the Destination Address.
531      *
532      * @param[out]  aAddress  The Destination Address.
533      *
534      * @retval kErrorNone  Successfully retrieved the Destination Address.
535      *
536      */
537     Error GetDstAddr(Address &aAddress) const;
538 
539     /**
540      * This method sets the Destination Address.
541      *
542      * @param[in]  aShortAddress  The Destination Address.
543      *
544      */
545     void SetDstAddr(ShortAddress aShortAddress);
546 
547     /**
548      * This method sets the Destination Address.
549      *
550      * @param[in]  aExtAddress  The Destination Address.
551      *
552      */
553     void SetDstAddr(const ExtAddress &aExtAddress);
554 
555     /**
556      * This method sets the Destination Address.
557      *
558      * @param[in]  aAddress  The Destination Address.
559      *
560      */
561     void SetDstAddr(const Address &aAddress);
562 
563     /**
564      * This method indicates whether or not the Source Address is present for this object.
565      *
566      * @retval TRUE   If the Source Address is present.
567      * @retval FALSE  If the Source Address is not present.
568      *
569      */
IsSrcPanIdPresent(void) const570     bool IsSrcPanIdPresent(void) const { return IsSrcPanIdPresent(GetFrameControlField()); }
571 
572     /**
573      * This method gets the Source PAN Identifier.
574      *
575      * @param[out]  aPanId  The Source PAN Identifier.
576      *
577      * @retval kErrorNone   Successfully retrieved the Source PAN Identifier.
578      *
579      */
580     Error GetSrcPanId(PanId &aPanId) const;
581 
582     /**
583      * This method sets the Source PAN Identifier.
584      *
585      * @param[in]  aPanId  The Source PAN Identifier.
586      *
587      * @retval kErrorNone   Successfully set the Source PAN Identifier.
588      *
589      */
590     Error SetSrcPanId(PanId aPanId);
591 
592     /**
593      * This method indicates whether or not the Source Address is present for this object.
594      *
595      * @retval TRUE   If the Source Address is present.
596      * @retval FALSE  If the Source Address is not present.
597      *
598      */
IsSrcAddrPresent(void) const599     bool IsSrcAddrPresent(void) const { return IsSrcAddrPresent(GetFrameControlField()); }
600 
601     /**
602      * This method gets the Source Address.
603      *
604      * @param[out]  aAddress  The Source Address.
605      *
606      * @retval kErrorNone  Successfully retrieved the Source Address.
607      *
608      */
609     Error GetSrcAddr(Address &aAddress) const;
610 
611     /**
612      * This method sets the Source Address.
613      *
614      * @param[in]  aShortAddress  The Source Address.
615      *
616      */
617     void SetSrcAddr(ShortAddress aShortAddress);
618 
619     /**
620      * This method sets the Source Address.
621      *
622      * @param[in]  aExtAddress  The Source Address.
623      *
624      */
625     void SetSrcAddr(const ExtAddress &aExtAddress);
626 
627     /**
628      * This method sets the Source Address.
629      *
630      * @param[in]  aAddress  The Source Address.
631      *
632      */
633     void SetSrcAddr(const Address &aAddress);
634 
635     /**
636      * This method gets the Security Control Field.
637      *
638      * @param[out]  aSecurityControlField  The Security Control Field.
639      *
640      * @retval kErrorNone   Successfully retrieved the Security Level Identifier.
641      * @retval kErrorParse  Failed to find the security control field in the frame.
642      *
643      */
644     Error GetSecurityControlField(uint8_t &aSecurityControlField) const;
645 
646     /**
647      * This method sets the Security Control Field.
648      *
649      * @param[in]  aSecurityControlField  The Security Control Field.
650      *
651      */
652     void SetSecurityControlField(uint8_t aSecurityControlField);
653 
654     /**
655      * This method gets the Security Level Identifier.
656      *
657      * @param[out]  aSecurityLevel  The Security Level Identifier.
658      *
659      * @retval kErrorNone  Successfully retrieved the Security Level Identifier.
660      *
661      */
662     Error GetSecurityLevel(uint8_t &aSecurityLevel) const;
663 
664     /**
665      * This method gets the Key Identifier Mode.
666      *
667      * @param[out]  aKeyIdMode  The Key Identifier Mode.
668      *
669      * @retval kErrorNone  Successfully retrieved the Key Identifier Mode.
670      *
671      */
672     Error GetKeyIdMode(uint8_t &aKeyIdMode) const;
673 
674     /**
675      * This method gets the Frame Counter.
676      *
677      * @param[out]  aFrameCounter  The Frame Counter.
678      *
679      * @retval kErrorNone  Successfully retrieved the Frame Counter.
680      *
681      */
682     Error GetFrameCounter(uint32_t &aFrameCounter) const;
683 
684     /**
685      * This method sets the Frame Counter.
686      *
687      * @param[in]  aFrameCounter  The Frame Counter.
688      *
689      */
690     void SetFrameCounter(uint32_t aFrameCounter);
691 
692     /**
693      * This method returns a pointer to the Key Source.
694      *
695      * @returns A pointer to the Key Source.
696      *
697      */
698     const uint8_t *GetKeySource(void) const;
699 
700     /**
701      * This method sets the Key Source.
702      *
703      * @param[in]  aKeySource  A pointer to the Key Source value.
704      *
705      */
706     void SetKeySource(const uint8_t *aKeySource);
707 
708     /**
709      * This method gets the Key Identifier.
710      *
711      * @param[out]  aKeyId  The Key Identifier.
712      *
713      * @retval kErrorNone  Successfully retrieved the Key Identifier.
714      *
715      */
716     Error GetKeyId(uint8_t &aKeyId) const;
717 
718     /**
719      * This method sets the Key Identifier.
720      *
721      * @param[in]  aKeyId  The Key Identifier.
722      *
723      */
724     void SetKeyId(uint8_t aKeyId);
725 
726     /**
727      * This method gets the Command ID.
728      *
729      * @param[out]  aCommandId  The Command ID.
730      *
731      * @retval kErrorNone  Successfully retrieved the Command ID.
732      *
733      */
734     Error GetCommandId(uint8_t &aCommandId) const;
735 
736     /**
737      * This method sets the Command ID.
738      *
739      * @param[in]  aCommandId  The Command ID.
740      *
741      * @retval kErrorNone  Successfully set the Command ID.
742      *
743      */
744     Error SetCommandId(uint8_t aCommandId);
745 
746     /**
747      * This method indicates whether the frame is a MAC Data Request command (data poll).
748      *
749      * For 802.15.4-2015 and above frame, the frame should be already decrypted.
750      *
751      * @returns TRUE if frame is a MAC Data Request command, FALSE otherwise.
752      *
753      */
754     bool IsDataRequestCommand(void) const;
755 
756     /**
757      * This method returns the MAC Frame Length.
758      *
759      * @returns The MAC Frame Length.
760      *
761      */
GetLength(void) const762     uint16_t GetLength(void) const { return mLength; }
763 
764     /**
765      * This method sets the MAC Frame Length.
766      *
767      * @param[in]  aLength  The MAC Frame Length.
768      *
769      */
SetLength(uint16_t aLength)770     void SetLength(uint16_t aLength) { mLength = aLength; }
771 
772     /**
773      * This method returns the MAC header size.
774      *
775      * @returns The MAC header size.
776      *
777      */
778     uint8_t GetHeaderLength(void) const;
779 
780     /**
781      * This method returns the MAC footer size.
782      *
783      * @returns The MAC footer size.
784      *
785      */
786     uint8_t GetFooterLength(void) const;
787 
788     /**
789      * This method returns the current MAC Payload length.
790      *
791      * @returns The current MAC Payload length.
792      *
793      */
794     uint16_t GetPayloadLength(void) const;
795 
796     /**
797      * This method returns the maximum MAC Payload length for the given MAC header and footer.
798      *
799      * @returns The maximum MAC Payload length for the given MAC header and footer.
800      *
801      */
802     uint16_t GetMaxPayloadLength(void) const;
803 
804     /**
805      * This method sets the MAC Payload length.
806      *
807      */
808     void SetPayloadLength(uint16_t aLength);
809 
810     /**
811      * This method returns the IEEE 802.15.4 channel used for transmission or reception.
812      *
813      * @returns The IEEE 802.15.4 channel used for transmission or reception.
814      *
815      */
GetChannel(void) const816     uint8_t GetChannel(void) const { return mChannel; }
817 
818     /**
819      * This method sets the IEEE 802.15.4 channel used for transmission or reception.
820      *
821      * @param[in]  aChannel  The IEEE 802.15.4 channel used for transmission or reception.
822      *
823      */
SetChannel(uint8_t aChannel)824     void SetChannel(uint8_t aChannel) { mChannel = aChannel; }
825 
826     /**
827      * This method returns the IEEE 802.15.4 PSDU length.
828      *
829      * @returns The IEEE 802.15.4 PSDU length.
830      *
831      */
GetPsduLength(void) const832     uint16_t GetPsduLength(void) const { return mLength; }
833 
834     /**
835      * This method returns a pointer to the PSDU.
836      *
837      * @returns A pointer to the PSDU.
838      *
839      */
GetPsdu(void)840     uint8_t *GetPsdu(void) { return mPsdu; }
841 
842     /**
843      * This const method returns a pointer to the PSDU.
844      *
845      * @returns A pointer to the PSDU.
846      *
847      */
GetPsdu(void) const848     const uint8_t *GetPsdu(void) const { return mPsdu; }
849 
850     /**
851      * This method returns a pointer to the MAC Header.
852      *
853      * @returns A pointer to the MAC Header.
854      *
855      */
GetHeader(void)856     uint8_t *GetHeader(void) { return GetPsdu(); }
857 
858     /**
859      * This const method returns a pointer to the MAC Header.
860      *
861      * @returns A pointer to the MAC Header.
862      *
863      */
GetHeader(void) const864     const uint8_t *GetHeader(void) const { return GetPsdu(); }
865 
866     /**
867      * This method returns a pointer to the MAC Payload.
868      *
869      * @returns A pointer to the MAC Payload.
870      *
871      */
GetPayload(void)872     uint8_t *GetPayload(void) { return AsNonConst(AsConst(this)->GetPayload()); }
873 
874     /**
875      * This const method returns a pointer to the MAC Payload.
876      *
877      * @returns A pointer to the MAC Payload.
878      *
879      */
880     const uint8_t *GetPayload(void) const;
881 
882     /**
883      * This method returns a pointer to the MAC Footer.
884      *
885      * @returns A pointer to the MAC Footer.
886      *
887      */
GetFooter(void)888     uint8_t *GetFooter(void) { return AsNonConst(AsConst(this)->GetFooter()); }
889 
890     /**
891      * This const method returns a pointer to the MAC Footer.
892      *
893      * @returns A pointer to the MAC Footer.
894      *
895      */
896     const uint8_t *GetFooter(void) const;
897 
898 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
899 
900     /**
901      * This method returns a pointer to the vendor specific Time IE.
902      *
903      * @returns A pointer to the Time IE, `nullptr` if not found.
904      *
905      */
GetTimeIe(void)906     TimeIe *GetTimeIe(void) { return AsNonConst(AsConst(this)->GetTimeIe()); }
907 
908     /**
909      * This method returns a pointer to the vendor specific Time IE.
910      *
911      * @returns A pointer to the Time IE, `nullptr` if not found.
912      *
913      */
914     const TimeIe *GetTimeIe(void) const;
915 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
916 
917 #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
918     /**
919      * This template method appends an Header IE at specified index in this frame.
920      *
921      * @param[in,out]   aIndex  The index to append IE. If `aIndex` is `0` on input, this method finds the index
922      *                          for the first IE and appends the IE at that position. If the position is not found
923      *                          successfully, `aIndex` will be set to `kInvalidIndex`. Otherwise the IE will be
924      *                          appended at `aIndex` on input. And on output, `aIndex` will be set to the end of the
925      *                          IE just appended.
926      *
927      * @tparam  IeType  The Header IE type, it MUST contain a constant `kHeaderIeId` equal to the IE's Id
928      *                  and a constant `kIeContentSize` indicating the IE body's size.
929      *
930      * @retval kErrorNone      Successfully appended the Header IE.
931      * @retval kErrorNotFound  The position for first IE is not found.
932      *
933      */
934     template <typename IeType> Error AppendHeaderIeAt(uint8_t &aIndex);
935 
936     /**
937      * This method returns a pointer to the Header IE.
938      *
939      * @param[in] aIeId  The Element Id of the Header IE.
940      *
941      * @returns A pointer to the Header IE, `nullptr` if not found.
942      *
943      */
GetHeaderIe(uint8_t aIeId)944     uint8_t *GetHeaderIe(uint8_t aIeId) { return AsNonConst(AsConst(this)->GetHeaderIe(aIeId)); }
945 
946     /**
947      * This method returns a pointer to the Header IE.
948      *
949      * @param[in] aIeId  The Element Id of the Header IE.
950      *
951      * @returns A pointer to the Header IE, `nullptr` if not found.
952      *
953      */
954     const uint8_t *GetHeaderIe(uint8_t aIeId) const;
955 
956     /**
957      * This method returns a pointer to a specific Thread IE.
958      *
959      * A Thread IE is a vendor specific IE with Vendor OUI as `kVendorOuiThreadCompanyId`.
960      *
961      * @param[in] aSubType  The sub type of the Thread IE.
962      *
963      * @returns A pointer to the Thread IE, `nullptr` if not found.
964      *
965      */
GetThreadIe(uint8_t aSubType)966     uint8_t *GetThreadIe(uint8_t aSubType) { return AsNonConst(AsConst(this)->GetThreadIe(aSubType)); }
967 
968     /**
969      * This method returns a pointer to a specific Thread IE.
970      *
971      * A Thread IE is a vendor specific IE with Vendor OUI as `kVendorOuiThreadCompanyId`.
972      *
973      * @param[in] aSubType  The sub type of the Thread IE.
974      *
975      * @returns A pointer to the Thread IE, `nullptr` if not found.
976      *
977      */
978     const uint8_t *GetThreadIe(uint8_t aSubType) const;
979 
980 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
981     /**
982      * This method finds CSL IE in the frame and modify its content.
983      *
984      * @param[in] aCslPeriod  CSL Period in CSL IE.
985      * @param[in] aCslPhase   CSL Phase in CSL IE.
986      *
987      */
988     void SetCslIe(uint16_t aCslPeriod, uint16_t aCslPhase);
989 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
990 
991 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
992     /**
993      * This method finds Enhanced ACK Probing (Vendor Specific) IE and set its value.
994      *
995      * @param[in] aValue  A pointer to the value to set.
996      * @param[in] aLen    The length of @p aValue.
997      *
998      */
999     void SetEnhAckProbingIe(const uint8_t *aValue, uint8_t aLen);
1000 #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
1001 
1002 #endif // OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
1003 
1004 #if OPENTHREAD_CONFIG_MULTI_RADIO
1005     /**
1006      * This method gets the radio link type of the frame.
1007      *
1008      * @returns Frame's radio link type.
1009      *
1010      */
GetRadioType(void) const1011     RadioType GetRadioType(void) const { return static_cast<RadioType>(mRadioType); }
1012 
1013     /**
1014      * This method sets the radio link type of the frame.
1015      *
1016      * @param[in] aRadioType  A radio link type.
1017      *
1018      */
SetRadioType(RadioType aRadioType)1019     void SetRadioType(RadioType aRadioType) { mRadioType = static_cast<uint8_t>(aRadioType); }
1020 #endif
1021 
1022     /**
1023      * This method returns the maximum transmission unit size (MTU).
1024      *
1025      * @returns The maximum transmission unit (MTU).
1026      *
1027      */
GetMtu(void) const1028     uint16_t GetMtu(void) const
1029 #if !OPENTHREAD_CONFIG_MULTI_RADIO && OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
1030     {
1031         return OT_RADIO_FRAME_MAX_SIZE;
1032     }
1033 #else
1034         ;
1035 #endif
1036 
1037     /**
1038      * This method returns the FCS size.
1039      *
1040      * @returns This method returns the FCS size.
1041      *
1042      */
GetFcsSize(void) const1043     uint8_t GetFcsSize(void) const
1044 #if !OPENTHREAD_CONFIG_MULTI_RADIO && OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
1045     {
1046         return k154FcsSize;
1047     }
1048 #else
1049         ;
1050 #endif
1051 
1052     /**
1053      * This method returns information about the frame object as an `InfoString` object.
1054      *
1055      * @returns An `InfoString` containing info about the frame.
1056      *
1057      */
1058     InfoString ToInfoString(void) const;
1059 
1060     /**
1061      * This method returns the Frame Control field of the frame.
1062      *
1063      * @returns The Frame Control field.
1064      *
1065      */
1066     uint16_t GetFrameControlField(void) const;
1067 
1068 protected:
1069     static constexpr uint8_t kInvalidIndex  = 0xff;
1070     static constexpr uint8_t kInvalidSize   = kInvalidIndex;
1071     static constexpr uint8_t kMaxPsduSize   = kInvalidSize - 1;
1072     static constexpr uint8_t kSequenceIndex = kFcfSize;
1073 
1074     uint8_t FindDstPanIdIndex(void) const;
1075     uint8_t FindDstAddrIndex(void) const;
1076     uint8_t FindSrcPanIdIndex(void) const;
1077     uint8_t FindSrcAddrIndex(void) const;
1078     uint8_t SkipAddrFieldIndex(void) const;
1079     uint8_t FindSecurityHeaderIndex(void) const;
1080     uint8_t SkipSecurityHeaderIndex(void) const;
1081     uint8_t FindPayloadIndex(void) const;
1082 #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
1083     uint8_t FindHeaderIeIndex(void) const;
1084 
1085     Error                           InitIeHeaderAt(uint8_t &aIndex, uint8_t ieId, uint8_t ieContentSize);
1086     template <typename IeType> void InitIeContentAt(uint8_t &aIndex);
1087 #endif
1088 
1089     static uint8_t GetKeySourceLength(uint8_t aKeyIdMode);
1090 
IsDstAddrPresent(uint16_t aFcf)1091     static bool IsDstAddrPresent(uint16_t aFcf) { return (aFcf & kFcfDstAddrMask) != kFcfDstAddrNone; }
1092     static bool IsDstPanIdPresent(uint16_t aFcf);
IsSrcAddrPresent(uint16_t aFcf)1093     static bool IsSrcAddrPresent(uint16_t aFcf) { return (aFcf & kFcfSrcAddrMask) != kFcfSrcAddrNone; }
1094     static bool IsSrcPanIdPresent(uint16_t aFcf);
IsVersion2015(uint16_t aFcf)1095     static bool IsVersion2015(uint16_t aFcf) { return (aFcf & kFcfFrameVersionMask) == kFcfFrameVersion2015; }
1096 
1097     static uint8_t CalculateAddrFieldSize(uint16_t aFcf);
1098     static uint8_t CalculateSecurityHeaderSize(uint8_t aSecurityControl);
1099     static uint8_t CalculateMicSize(uint8_t aSecurityControl);
1100 };
1101 
1102 /**
1103  * This class supports received IEEE 802.15.4 MAC frame processing.
1104  *
1105  */
1106 class RxFrame : public Frame
1107 {
1108 public:
1109     friend class TxFrame;
1110 
1111     /**
1112      * This method returns the RSSI in dBm used for reception.
1113      *
1114      * @returns The RSSI in dBm used for reception.
1115      *
1116      */
GetRssi(void) const1117     int8_t GetRssi(void) const { return mInfo.mRxInfo.mRssi; }
1118 
1119     /**
1120      * This method sets the RSSI in dBm used for reception.
1121      *
1122      * @param[in]  aRssi  The RSSI in dBm used for reception.
1123      *
1124      */
SetRssi(int8_t aRssi)1125     void SetRssi(int8_t aRssi) { mInfo.mRxInfo.mRssi = aRssi; }
1126 
1127     /**
1128      * This method returns the receive Link Quality Indicator.
1129      *
1130      * @returns The receive Link Quality Indicator.
1131      *
1132      */
GetLqi(void) const1133     uint8_t GetLqi(void) const { return mInfo.mRxInfo.mLqi; }
1134 
1135     /**
1136      * This method sets the receive Link Quality Indicator.
1137      *
1138      * @param[in]  aLqi  The receive Link Quality Indicator.
1139      *
1140      */
SetLqi(uint8_t aLqi)1141     void SetLqi(uint8_t aLqi) { mInfo.mRxInfo.mLqi = aLqi; }
1142 
1143     /**
1144      * This method indicates whether or not the received frame is acknowledged with frame pending set.
1145      *
1146      * @retval TRUE   This frame is acknowledged with frame pending set.
1147      * @retval FALSE  This frame is acknowledged with frame pending not set.
1148      *
1149      */
IsAckedWithFramePending(void) const1150     bool IsAckedWithFramePending(void) const { return mInfo.mRxInfo.mAckedWithFramePending; }
1151 
1152     /**
1153      * This method returns the timestamp when the frame was received.
1154      *
1155      * @returns The timestamp when the frame was received, in microseconds.
1156      *
1157      */
GetTimestamp(void) const1158     const uint64_t &GetTimestamp(void) const { return mInfo.mRxInfo.mTimestamp; }
1159 
1160     /**
1161      * This method performs AES CCM on the frame which is received.
1162      *
1163      * @param[in]  aExtAddress  A reference to the extended address, which will be used to generate nonce
1164      *                          for AES CCM computation.
1165      * @param[in]  aMacKey      A reference to the MAC key to decrypt the received frame.
1166      *
1167      * @retval kErrorNone      Process of received frame AES CCM succeeded.
1168      * @retval kErrorSecurity  Received frame MIC check failed.
1169      *
1170      */
1171     Error ProcessReceiveAesCcm(const ExtAddress &aExtAddress, const KeyMaterial &aMacKey);
1172 
1173 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1174     /**
1175      * This method gets the offset to network time.
1176      *
1177      * @returns  The offset to network time.
1178      *
1179      */
ComputeNetworkTimeOffset(void) const1180     int64_t ComputeNetworkTimeOffset(void) const
1181     {
1182         return static_cast<int64_t>(GetTimeIe()->GetTime() - GetTimestamp());
1183     }
1184 
1185     /**
1186      * This method gets the time sync sequence.
1187      *
1188      * @returns  The time sync sequence.
1189      *
1190      */
ReadTimeSyncSeq(void) const1191     uint8_t ReadTimeSyncSeq(void) const { return GetTimeIe()->GetSequence(); }
1192 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1193 };
1194 
1195 /**
1196  * This class supports IEEE 802.15.4 MAC frame generation for transmission.
1197  *
1198  */
1199 class TxFrame : public Frame
1200 {
1201 public:
1202     /**
1203      * This method returns the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring a channel
1204      * access failure.
1205      *
1206      * Equivalent to macMaxCSMABackoffs in IEEE 802.15.4-2006.
1207      *
1208      * @returns The maximum number of backoffs the CSMA-CA algorithm will attempt before declaring a channel access
1209      *          failure.
1210      *
1211      */
GetMaxCsmaBackoffs(void) const1212     uint8_t GetMaxCsmaBackoffs(void) const { return mInfo.mTxInfo.mMaxCsmaBackoffs; }
1213 
1214     /**
1215      * This method sets the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring a channel
1216      * access failure.
1217      *
1218      * Equivalent to macMaxCSMABackoffs in IEEE 802.15.4-2006.
1219      *
1220      * @param[in]  aMaxCsmaBackoffs  The maximum number of backoffs the CSMA-CA algorithm will attempt before declaring
1221      *                               a channel access failure.
1222      *
1223      */
SetMaxCsmaBackoffs(uint8_t aMaxCsmaBackoffs)1224     void SetMaxCsmaBackoffs(uint8_t aMaxCsmaBackoffs) { mInfo.mTxInfo.mMaxCsmaBackoffs = aMaxCsmaBackoffs; }
1225 
1226     /**
1227      * This method returns the maximum number of retries allowed after a transmission failure.
1228      *
1229      * Equivalent to macMaxFrameRetries in IEEE 802.15.4-2006.
1230      *
1231      * @returns The maximum number of retries allowed after a transmission failure.
1232      *
1233      */
GetMaxFrameRetries(void) const1234     uint8_t GetMaxFrameRetries(void) const { return mInfo.mTxInfo.mMaxFrameRetries; }
1235 
1236     /**
1237      * This method sets the maximum number of retries allowed after a transmission failure.
1238      *
1239      * Equivalent to macMaxFrameRetries in IEEE 802.15.4-2006.
1240      *
1241      * @param[in]  aMaxFrameRetries  The maximum number of retries allowed after a transmission failure.
1242      *
1243      */
SetMaxFrameRetries(uint8_t aMaxFrameRetries)1244     void SetMaxFrameRetries(uint8_t aMaxFrameRetries) { mInfo.mTxInfo.mMaxFrameRetries = aMaxFrameRetries; }
1245 
1246     /**
1247      * This method indicates whether or not the frame is a retransmission.
1248      *
1249      * @retval TRUE   Frame is a retransmission
1250      * @retval FALSE  This is a new frame and not a retransmission of an earlier frame.
1251      *
1252      */
IsARetransmission(void) const1253     bool IsARetransmission(void) const { return mInfo.mTxInfo.mIsARetx; }
1254 
1255     /**
1256      * This method sets the retransmission flag attribute.
1257      *
1258      * @param[in]  aIsARetx  TRUE if frame is a retransmission of an earlier frame, FALSE otherwise.
1259      *
1260      */
SetIsARetransmission(bool aIsARetx)1261     void SetIsARetransmission(bool aIsARetx) { mInfo.mTxInfo.mIsARetx = aIsARetx; }
1262 
1263     /**
1264      * This method indicates whether or not CSMA-CA is enabled.
1265      *
1266      * @retval TRUE   CSMA-CA is enabled.
1267      * @retval FALSE  CSMA-CA is not enabled is not enabled.
1268      *
1269      */
IsCsmaCaEnabled(void) const1270     bool IsCsmaCaEnabled(void) const { return mInfo.mTxInfo.mCsmaCaEnabled; }
1271 
1272     /**
1273      * This method sets the CSMA-CA enabled attribute.
1274      *
1275      * @param[in]  aCsmaCaEnabled  TRUE if CSMA-CA must be enabled for this packet, FALSE otherwise.
1276      *
1277      */
SetCsmaCaEnabled(bool aCsmaCaEnabled)1278     void SetCsmaCaEnabled(bool aCsmaCaEnabled) { mInfo.mTxInfo.mCsmaCaEnabled = aCsmaCaEnabled; }
1279 
1280     /**
1281      * This method returns the key used for frame encryption and authentication (AES CCM).
1282      *
1283      * @returns The pointer to the key.
1284      *
1285      */
GetAesKey(void) const1286     const Mac::KeyMaterial &GetAesKey(void) const
1287     {
1288         return *static_cast<const Mac::KeyMaterial *>(mInfo.mTxInfo.mAesKey);
1289     }
1290 
1291     /**
1292      * This method sets the key used for frame encryption and authentication (AES CCM).
1293      *
1294      * @param[in]  aAesKey  The pointer to the key.
1295      *
1296      */
SetAesKey(const Mac::KeyMaterial & aAesKey)1297     void SetAesKey(const Mac::KeyMaterial &aAesKey) { mInfo.mTxInfo.mAesKey = &aAesKey; }
1298 
1299     /**
1300      * This method copies the PSDU and all attributes (except for frame link type) from another frame.
1301      *
1302      * @note This method performs a deep copy meaning the content of PSDU buffer from the given frame is copied into
1303      * the PSDU buffer of the current frame.
1304 
1305      * @param[in] aFromFrame  The frame to copy from.
1306      *
1307      */
1308     void CopyFrom(const TxFrame &aFromFrame);
1309 
1310     /**
1311      * This method performs AES CCM on the frame which is going to be sent.
1312      *
1313      * @param[in]  aExtAddress  A reference to the extended address, which will be used to generate nonce
1314      *                          for AES CCM computation.
1315      *
1316      */
1317     void ProcessTransmitAesCcm(const ExtAddress &aExtAddress);
1318 
1319     /**
1320      * This method indicates whether or not the frame has security processed.
1321      *
1322      * @retval TRUE   The frame already has security processed.
1323      * @retval FALSE  The frame does not have security processed.
1324      *
1325      */
IsSecurityProcessed(void) const1326     bool IsSecurityProcessed(void) const { return mInfo.mTxInfo.mIsSecurityProcessed; }
1327 
1328     /**
1329      * This method sets the security processed flag attribute.
1330      *
1331      * @param[in]  aIsSecurityProcessed  TRUE if the frame already has security processed.
1332      *
1333      */
SetIsSecurityProcessed(bool aIsSecurityProcessed)1334     void SetIsSecurityProcessed(bool aIsSecurityProcessed)
1335     {
1336         mInfo.mTxInfo.mIsSecurityProcessed = aIsSecurityProcessed;
1337     }
1338 
1339     /**
1340      * This method indicates whether or not the frame header is updated.
1341      *
1342      * @retval TRUE   The frame already has the header updated.
1343      * @retval FALSE  The frame does not have the header updated.
1344      *
1345      */
IsHeaderUpdated(void) const1346     bool IsHeaderUpdated(void) const { return mInfo.mTxInfo.mIsHeaderUpdated; }
1347 
1348     /**
1349      * This method sets the header updated flag attribute.
1350      *
1351      * @param[in]  aIsHeaderUpdated  TRUE if the frame header is updated.
1352      *
1353      */
SetIsHeaderUpdated(bool aIsHeaderUpdated)1354     void SetIsHeaderUpdated(bool aIsHeaderUpdated) { mInfo.mTxInfo.mIsHeaderUpdated = aIsHeaderUpdated; }
1355 
1356 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1357     /**
1358      * This method sets the Time IE offset.
1359      *
1360      * @param[in]  aOffset  The Time IE offset, 0 means no Time IE.
1361      *
1362      */
SetTimeIeOffset(uint8_t aOffset)1363     void SetTimeIeOffset(uint8_t aOffset) { mInfo.mTxInfo.mIeInfo->mTimeIeOffset = aOffset; }
1364 
1365     /**
1366      * This method gets the Time IE offset.
1367      *
1368      * @returns The Time IE offset, 0 means no Time IE.
1369      *
1370      */
GetTimeIeOffset(void) const1371     uint8_t GetTimeIeOffset(void) const { return mInfo.mTxInfo.mIeInfo->mTimeIeOffset; }
1372 
1373     /**
1374      * This method sets the offset to network time.
1375      *
1376      * @param[in]  aNetworkTimeOffset  The offset to network time.
1377      *
1378      */
SetNetworkTimeOffset(int64_t aNetworkTimeOffset)1379     void SetNetworkTimeOffset(int64_t aNetworkTimeOffset)
1380     {
1381         mInfo.mTxInfo.mIeInfo->mNetworkTimeOffset = aNetworkTimeOffset;
1382     }
1383 
1384     /**
1385      * This method sets the time sync sequence.
1386      *
1387      * @param[in]  aTimeSyncSeq  The time sync sequence.
1388      *
1389      */
SetTimeSyncSeq(uint8_t aTimeSyncSeq)1390     void SetTimeSyncSeq(uint8_t aTimeSyncSeq) { mInfo.mTxInfo.mIeInfo->mTimeSyncSeq = aTimeSyncSeq; }
1391 #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
1392 
1393     /**
1394      * Generate Imm-Ack in this frame object.
1395      *
1396      * @param[in]    aFrame             A reference to the frame received.
1397      * @param[in]    aIsFramePending    Value of the ACK's frame pending bit.
1398      *
1399      */
1400     void GenerateImmAck(const RxFrame &aFrame, bool aIsFramePending);
1401 
1402     /**
1403      * Generate Enh-Ack in this frame object.
1404      *
1405      * @param[in]    aFrame             A reference to the frame received.
1406      * @param[in]    aIsFramePending    Value of the ACK's frame pending bit.
1407      * @param[in]    aIeData            A pointer to the IE data portion of the ACK to be sent.
1408      * @param[in]    aIeLength          The length of IE data portion of the ACK to be sent.
1409      *
1410      * @retval  kErrorNone           Successfully generated Enh Ack.
1411      * @retval  kErrorParse          @p aFrame has incorrect format.
1412      *
1413      */
1414     Error GenerateEnhAck(const RxFrame &aFrame, bool aIsFramePending, const uint8_t *aIeData, uint8_t aIeLength);
1415 
1416 #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
1417     /**
1418      * Set TX delay field for the frame.
1419      *
1420      * @param[in]    aTxDelay    The delay time for the TX frame.
1421      *
1422      */
SetTxDelay(uint32_t aTxDelay)1423     void SetTxDelay(uint32_t aTxDelay) { mInfo.mTxInfo.mTxDelay = aTxDelay; }
1424 
1425     /**
1426      * Set TX delay base time field for the frame.
1427      *
1428      * @param[in]    aTxDelayBaseTime    The delay base time for the TX frame.
1429      *
1430      */
SetTxDelayBaseTime(uint32_t aTxDelayBaseTime)1431     void SetTxDelayBaseTime(uint32_t aTxDelayBaseTime) { mInfo.mTxInfo.mTxDelayBaseTime = aTxDelayBaseTime; }
1432 #endif
1433 };
1434 
1435 OT_TOOL_PACKED_BEGIN
1436 class Beacon
1437 {
1438 public:
1439     static constexpr uint16_t kSuperFrameSpec = 0x0fff; ///< Superframe Specification value.
1440 
1441     /**
1442      * This method initializes the Beacon message.
1443      *
1444      */
Init(void)1445     void Init(void)
1446     {
1447         mSuperframeSpec     = HostSwap16(kSuperFrameSpec);
1448         mGtsSpec            = 0;
1449         mPendingAddressSpec = 0;
1450     }
1451 
1452     /**
1453      * This method indicates whether or not the beacon appears to be a valid Thread Beacon message.
1454      *
1455      * @retval TRUE   If the beacon appears to be a valid Thread Beacon message.
1456      * @retval FALSE  If the beacon does not appear to be a valid Thread Beacon message.
1457      *
1458      */
IsValid(void) const1459     bool IsValid(void) const
1460     {
1461         return (mSuperframeSpec == HostSwap16(kSuperFrameSpec)) && (mGtsSpec == 0) && (mPendingAddressSpec == 0);
1462     }
1463 
1464     /**
1465      * This method returns the pointer to the beacon payload.
1466      *
1467      * @returns A pointer to the beacon payload.
1468      *
1469      */
GetPayload(void)1470     uint8_t *GetPayload(void) { return reinterpret_cast<uint8_t *>(this) + sizeof(*this); }
1471 
1472     /**
1473      * This method returns the pointer to the beacon payload.
1474      *
1475      * @returns A pointer to the beacon payload.
1476      *
1477      */
GetPayload(void) const1478     const uint8_t *GetPayload(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }
1479 
1480 private:
1481     uint16_t mSuperframeSpec;
1482     uint8_t  mGtsSpec;
1483     uint8_t  mPendingAddressSpec;
1484 } OT_TOOL_PACKED_END;
1485 
1486 /**
1487  * This class implements IEEE 802.15.4 Beacon Payload generation and parsing.
1488  *
1489  */
1490 OT_TOOL_PACKED_BEGIN
1491 class BeaconPayload
1492 {
1493 public:
1494     static constexpr uint8_t kProtocolId      = 3;                     ///< Thread Protocol ID.
1495     static constexpr uint8_t kProtocolVersion = 2;                     ///< Thread Protocol version.
1496     static constexpr uint8_t kVersionOffset   = 4;                     ///< Version field bit offset.
1497     static constexpr uint8_t kVersionMask     = 0xf << kVersionOffset; ///< Version field mask.
1498     static constexpr uint8_t kNativeFlag      = 1 << 3;                ///< Native Commissioner flag.
1499     static constexpr uint8_t kJoiningFlag     = 1 << 0;                ///< Joining Permitted flag.
1500 
1501     /**
1502      * This method initializes the Beacon Payload.
1503      *
1504      */
Init(void)1505     void Init(void)
1506     {
1507         mProtocolId = kProtocolId;
1508         mFlags      = kProtocolVersion << kVersionOffset;
1509     }
1510 
1511     /**
1512      * This method indicates whether or not the beacon appears to be a valid Thread Beacon Payload.
1513      *
1514      * @retval TRUE   If the beacon appears to be a valid Thread Beacon Payload.
1515      * @retval FALSE  If the beacon does not appear to be a valid Thread Beacon Payload.
1516      *
1517      */
IsValid(void) const1518     bool IsValid(void) const { return (mProtocolId == kProtocolId); }
1519 
1520     /**
1521      * This method returns the Protocol ID value.
1522      *
1523      * @returns the Protocol ID value.
1524      *
1525      */
GetProtocolId(void) const1526     uint8_t GetProtocolId(void) const { return mProtocolId; }
1527 
1528     /**
1529      * This method returns the Protocol Version value.
1530      *
1531      * @returns The Protocol Version value.
1532      *
1533      */
GetProtocolVersion(void) const1534     uint8_t GetProtocolVersion(void) const { return mFlags >> kVersionOffset; }
1535 
1536     /**
1537      * This method indicates whether or not the Native Commissioner flag is set.
1538      *
1539      * @retval TRUE   If the Native Commissioner flag is set.
1540      * @retval FALSE  If the Native Commissioner flag is not set.
1541      *
1542      */
IsNative(void) const1543     bool IsNative(void) const { return (mFlags & kNativeFlag) != 0; }
1544 
1545     /**
1546      * This method clears the Native Commissioner flag.
1547      *
1548      */
ClearNative(void)1549     void ClearNative(void) { mFlags &= ~kNativeFlag; }
1550 
1551     /**
1552      * This method sets the Native Commissioner flag.
1553      *
1554      */
SetNative(void)1555     void SetNative(void) { mFlags |= kNativeFlag; }
1556 
1557     /**
1558      * This method indicates whether or not the Joining Permitted flag is set.
1559      *
1560      * @retval TRUE   If the Joining Permitted flag is set.
1561      * @retval FALSE  If the Joining Permitted flag is not set.
1562      *
1563      */
IsJoiningPermitted(void) const1564     bool IsJoiningPermitted(void) const { return (mFlags & kJoiningFlag) != 0; }
1565 
1566     /**
1567      * This method clears the Joining Permitted flag.
1568      *
1569      */
ClearJoiningPermitted(void)1570     void ClearJoiningPermitted(void) { mFlags &= ~kJoiningFlag; }
1571 
1572     /**
1573      * This method sets the Joining Permitted flag.
1574      *
1575      */
SetJoiningPermitted(void)1576     void SetJoiningPermitted(void)
1577     {
1578         mFlags |= kJoiningFlag;
1579 
1580 #if OPENTHREAD_CONFIG_MAC_JOIN_BEACON_VERSION != 2 // check against kProtocolVersion
1581         mFlags &= ~kVersionMask;
1582         mFlags |= OPENTHREAD_CONFIG_MAC_JOIN_BEACON_VERSION << kVersionOffset;
1583 #endif
1584     }
1585 
1586     /**
1587      * This method gets the Network Name field.
1588      *
1589      * @returns The Network Name field as `NameData`.
1590      *
1591      */
GetNetworkName(void) const1592     MeshCoP::NameData GetNetworkName(void) const { return MeshCoP::NameData(mNetworkName, sizeof(mNetworkName)); }
1593 
1594     /**
1595      * This method sets the Network Name field.
1596      *
1597      * @param[in]  aNameData  The Network Name (as a `NameData`).
1598      *
1599      */
SetNetworkName(const MeshCoP::NameData & aNameData)1600     void SetNetworkName(const MeshCoP::NameData &aNameData) { aNameData.CopyTo(mNetworkName, sizeof(mNetworkName)); }
1601 
1602     /**
1603      * This method returns the Extended PAN ID field.
1604      *
1605      * @returns The Extended PAN ID field.
1606      *
1607      */
GetExtendedPanId(void) const1608     const otExtendedPanId &GetExtendedPanId(void) const { return mExtendedPanId; }
1609 
1610     /**
1611      * This method sets the Extended PAN ID field.
1612      *
1613      * @param[in]  aExtPanId  An Extended PAN ID.
1614      *
1615      */
SetExtendedPanId(const otExtendedPanId & aExtPanId)1616     void SetExtendedPanId(const otExtendedPanId &aExtPanId) { mExtendedPanId = aExtPanId; }
1617 
1618 private:
1619     uint8_t         mProtocolId;
1620     uint8_t         mFlags;
1621     char            mNetworkName[MeshCoP::NetworkName::kMaxSize];
1622     otExtendedPanId mExtendedPanId;
1623 } OT_TOOL_PACKED_END;
1624 
1625 /**
1626  * This class implements CSL IE data structure.
1627  *
1628  */
1629 OT_TOOL_PACKED_BEGIN
1630 class CslIe
1631 {
1632 public:
1633     static constexpr uint8_t kHeaderIeId    = 0x1a;
1634     static constexpr uint8_t kIeContentSize = sizeof(uint16_t) * 2;
1635 
1636     /**
1637      * This method returns the CSL Period.
1638      *
1639      * @returns the CSL Period.
1640      *
1641      */
GetPeriod(void) const1642     uint16_t GetPeriod(void) const { return HostSwap16(mPeriod); }
1643 
1644     /**
1645      * This method sets the CSL Period.
1646      *
1647      * @param[in]  aPeriod  The CSL Period.
1648      *
1649      */
SetPeriod(uint16_t aPeriod)1650     void SetPeriod(uint16_t aPeriod) { mPeriod = HostSwap16(aPeriod); }
1651 
1652     /**
1653      * This method returns the CSL Phase.
1654      *
1655      * @returns the CSL Phase.
1656      *
1657      */
GetPhase(void) const1658     uint16_t GetPhase(void) const { return HostSwap16(mPhase); }
1659 
1660     /**
1661      * This method sets the CSL Phase.
1662      *
1663      * @param[in]  aPhase  The CSL Phase.
1664      *
1665      */
SetPhase(uint16_t aPhase)1666     void SetPhase(uint16_t aPhase) { mPhase = HostSwap16(aPhase); }
1667 
1668 private:
1669     uint16_t mPhase;
1670     uint16_t mPeriod;
1671 } OT_TOOL_PACKED_END;
1672 
1673 /**
1674  * This class implements Termination2 IE.
1675  *
1676  * This class is empty for template specialization.
1677  *
1678  */
1679 class Termination2Ie
1680 {
1681 public:
1682     static constexpr uint8_t kHeaderIeId    = 0x7f;
1683     static constexpr uint8_t kIeContentSize = 0;
1684 };
1685 
1686 /**
1687  * @}
1688  *
1689  */
1690 
1691 } // namespace Mac
1692 } // namespace ot
1693 
1694 #endif // MAC_FRAME_HPP_
1695