1 /*
2  *  Copyright (c) 2016-2018, 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 the IEEE 802.15.4 MAC layer (sub-MAC).
32  */
33 
34 #ifndef SUB_MAC_HPP_
35 #define SUB_MAC_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <openthread/link.h>
40 
41 #include "common/locator.hpp"
42 #include "common/non_copyable.hpp"
43 #include "common/timer.hpp"
44 #include "mac/mac_frame.hpp"
45 #include "radio/radio.hpp"
46 
47 namespace ot {
48 
49 /**
50  * @addtogroup core-mac
51  *
52  * @brief
53  *   This module includes definitions for the IEEE 802.15.4 MAC (sub-MAC).
54  *
55  * @{
56  *
57  */
58 
59 namespace Mac {
60 
61 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE && (OPENTHREAD_CONFIG_THREAD_VERSION < OT_THREAD_VERSION_1_2)
62 #error "Thread 1.2 or higher version is required for OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE."
63 #endif
64 
65 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
66 
67 #if (OPENTHREAD_CONFIG_THREAD_VERSION < OT_THREAD_VERSION_1_2)
68 #error "Thread 1.2 or higher version is required for OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE."
69 #endif
70 
71 #if !OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
72 #error "Microsecond timer OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE is required for "\
73     "OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE"
74 #endif
75 
76 #endif
77 
78 #if OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE && !OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
79 #error "OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE is required for OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE."
80 #endif
81 
82 /**
83  * This class implements the IEEE 802.15.4 MAC (sub-MAC).
84  *
85  * Sub-MAC layer implements a subset of IEEE802.15.4 MAC primitives which are shared by both MAC layer (in FTD/MTD
86  * modes) and Raw Link (Radio only mode).
87 
88  * The sub-MAC layer handles the following (if not provided by radio platform):
89  *
90  *    - Ack timeout for frame transmission,
91  *    - CSMA backoff logic,
92  *    - Frame re-transmissions,
93  *    - Energy scan on a single channel and RSSI sampling.
94  *
95  * It also act as the interface (to radio platform) for setting/getting radio configurations such as short or extended
96  * addresses and PAN Id.
97  *
98  */
99 class SubMac : public InstanceLocator, private NonCopyable
100 {
101     friend class Radio::Callbacks;
102 
103 public:
104     static constexpr int8_t kInvalidRssiValue = 127; ///< Invalid Received Signal Strength Indicator (RSSI) value.
105 
106     /**
107      * This class defines the callbacks notifying `SubMac` user of changes and events.
108      *
109      */
110     class Callbacks : public InstanceLocator
111     {
112     public:
113         /**
114          * This constructor initializes the `Callbacks` object.
115          *
116          * @param[in]  aInstance  A reference to the OpenThread instance.
117          *
118          */
119         explicit Callbacks(Instance &aInstance);
120 
121         /**
122          * This method notifies user of `SubMac` of a received frame.
123          *
124          * @param[in]  aFrame    A pointer to the received frame or nullptr if the receive operation failed.
125          * @param[in]  aError    kErrorNone when successfully received a frame,
126          *                       kErrorAbort when reception was aborted and a frame was not received,
127          *                       kErrorNoBufs when a frame could not be received due to lack of rx buffer space.
128          *
129          */
130         void ReceiveDone(RxFrame *aFrame, Error aError);
131 
132         /**
133          * This method notifies user of `SubMac` of CCA status (success/failure) for a frame transmission attempt.
134          *
135          * This is intended for updating counters, logging, and/or tracking CCA failure rate statistics.
136          *
137          * @param[in] aCcaSuccess   TRUE if the CCA succeeded, FALSE otherwise.
138          * @param[in] aChannel      The channel on which CCA was performed.
139          *
140          */
141         void RecordCcaStatus(bool aCcaSuccess, uint8_t aChannel);
142 
143         /**
144          * This method notifies user of `SubMac` of the status of a frame transmission attempt.
145          *
146          * This is intended for updating counters, logging, and/or collecting statistics.
147          *
148          * @note Unlike `TransmitDone` which is invoked after all re-transmission attempts to indicate the final status
149          * of a frame transmission, this method is invoked on all frame transmission attempts.
150          *
151          * @param[in] aFrame      The transmitted frame.
152          * @param[in] aAckFrame   A pointer to the ACK frame, or nullptr if no ACK was received.
153          * @param[in] aError      kErrorNone when the frame was transmitted successfully,
154          *                        kErrorNoAck when the frame was transmitted but no ACK was received,
155          *                        kErrorChannelAccessFailure tx failed due to activity on the channel,
156          *                        kErrorAbort when transmission was aborted for other reasons.
157          * @param[in] aRetryCount Current retry count. This is valid only when sub-mac handles frame re-transmissions.
158          * @param[in] aWillRetx   Indicates whether frame will be retransmitted or not. This is applicable only
159          *                        when there was an error in current transmission attempt.
160          *
161          */
162         void RecordFrameTransmitStatus(const TxFrame &aFrame,
163                                        const RxFrame *aAckFrame,
164                                        Error          aError,
165                                        uint8_t        aRetryCount,
166                                        bool           aWillRetx);
167 
168         /**
169          * The method notifies user of `SubMac` that the transmit operation has completed, providing, if applicable,
170          * the received ACK frame.
171          *
172          * @param[in]  aFrame     The transmitted frame.
173          * @param[in]  aAckFrame  A pointer to the ACK frame, nullptr if no ACK was received.
174          * @param[in]  aError     kErrorNone when the frame was transmitted,
175          *                        kErrorNoAck when the frame was transmitted but no ACK was received,
176          *                        kErrorChannelAccessFailure tx failed due to activity on the channel,
177          *                        kErrorAbort when transmission was aborted for other reasons.
178          *
179          */
180         void TransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError);
181 
182         /**
183          * This method notifies user of `SubMac` that energy scan is complete.
184          *
185          * @param[in]  aMaxRssi  Maximum RSSI seen on the channel, or `SubMac::kInvalidRssiValue` if failed.
186          *
187          */
188         void EnergyScanDone(int8_t aMaxRssi);
189 
190         /**
191          * This method notifies user of `SubMac` that MAC frame counter is updated.
192          *
193          * @param[in]  aFrameCounter  The MAC frame counter value.
194          *
195          */
196         void FrameCounterUpdated(uint32_t aFrameCounter);
197     };
198 
199     /**
200      * This constructor initializes the `SubMac` object.
201      *
202      * @param[in]  aInstance  A reference to the OpenThread instance.
203      *
204      */
205     explicit SubMac(Instance &aInstance);
206 
207     /**
208      * This method gets the capabilities provided by platform radio.
209      *
210      * @returns The capability bit vector (see `OT_RADIO_CAP_*` definitions).
211      *
212      */
GetRadioCaps(void) const213     otRadioCaps GetRadioCaps(void) const { return mRadioCaps; }
214 
215     /**
216      * This method gets the capabilities provided by `SubMac` layer.
217      *
218      * @returns The capability bit vector (see `OT_RADIO_CAP_*` definitions).
219      *
220      */
221     otRadioCaps GetCaps(void) const;
222 
223     /**
224      * This method sets the PAN ID.
225      *
226      * @param[in] aPanId  The PAN ID.
227      *
228      */
229     void SetPanId(PanId aPanId);
230 
231     /**
232      * This method gets the short address.
233      *
234      * @returns The short address.
235      *
236      */
GetShortAddress(void) const237     ShortAddress GetShortAddress(void) const { return mShortAddress; }
238 
239     /**
240      * This method sets the short address.
241      *
242      * @param[in] aShortAddress   The short address.
243      *
244      */
245     void SetShortAddress(ShortAddress aShortAddress);
246 
247     /**
248      * This function gets the extended address.
249      *
250      * @returns A reference to the extended address.
251      *
252      */
GetExtAddress(void) const253     const ExtAddress &GetExtAddress(void) const { return mExtAddress; }
254 
255     /**
256      * This method sets extended address.
257      *
258      * @param[in] aExtAddress  The extended address.
259      *
260      */
261     void SetExtAddress(const ExtAddress &aExtAddress);
262 
263     /**
264      * This method registers a callback to provide received packet capture for IEEE 802.15.4 frames.
265      *
266      * @param[in]  aPcapCallback     A pointer to a function that is called when receiving an IEEE 802.15.4 link frame
267      *                                or nullptr to disable the callback.
268      * @param[in]  aCallbackContext  A pointer to application-specific context.
269      *
270      */
271     void SetPcapCallback(otLinkPcapCallback aPcapCallback, void *aCallbackContext);
272 
273     /**
274      * This method indicates whether radio should stay in Receive or Sleep during CSMA backoff.
275      *
276      * @param[in]  aRxOnWhenBackoff  TRUE to keep radio in Receive, FALSE to put to Sleep during CSMA backoff.
277      *
278      */
SetRxOnWhenBackoff(bool aRxOnWhenBackoff)279     void SetRxOnWhenBackoff(bool aRxOnWhenBackoff) { mRxOnWhenBackoff = aRxOnWhenBackoff; }
280 
281     /**
282      * This method enables the radio.
283      *
284      * @retval kErrorNone     Successfully enabled.
285      * @retval kErrorFailed   The radio could not be enabled.
286      *
287      */
288     Error Enable(void);
289 
290     /**
291      * This method disables the radio.
292      *
293      * @retval kErrorNone     Successfully disabled the radio.
294      *
295      */
296     Error Disable(void);
297 
298     /**
299      * This method transitions the radio to Sleep.
300      *
301      * @retval kErrorNone          Successfully transitioned to Sleep.
302      * @retval kErrorBusy          The radio was transmitting.
303      * @retval kErrorInvalidState  The radio was disabled.
304      *
305      */
306     Error Sleep(void);
307 
308     /**
309      * This method indicates whether the sub-mac is busy transmitting or scanning.
310      *
311      * @retval TRUE if the sub-mac is busy transmitting or scanning.
312      * @retval FALSE if the sub-mac is not busy transmitting or scanning.
313      *
314      */
IsTransmittingOrScanning(void) const315     bool IsTransmittingOrScanning(void) const { return (mState == kStateTransmit) || (mState == kStateEnergyScan); }
316 
317     /**
318      * This method transitions the radio to Receive.
319      *
320      * @param[in]  aChannel   The channel to use for receiving.
321      *
322      * @retval kErrorNone          Successfully transitioned to Receive.
323      * @retval kErrorInvalidState  The radio was disabled or transmitting.
324      *
325      */
326     Error Receive(uint8_t aChannel);
327 
328     /**
329      * This method gets the radio transmit frame.
330      *
331      * @returns The transmit frame.
332      *
333      */
GetTransmitFrame(void)334     TxFrame &GetTransmitFrame(void) { return mTransmitFrame; }
335 
336     /**
337      * This method sends a prepared frame.
338      *
339      * The frame should be placed in `GetTransmitFrame()` frame.
340      *
341      * The `SubMac` layer handles Ack timeout, CSMA backoff, and frame retransmission.
342      *
343      * @retval kErrorNone          Successfully started the frame transmission
344      * @retval kErrorInvalidState  The radio was disabled or transmitting.
345      *
346      */
347     Error Send(void);
348 
349     /**
350      * This method gets the number of transmit retries of last transmitted frame.
351      *
352      * @returns Number of transmit retries.
353      *
354      */
GetTransmitRetries(void) const355     uint8_t GetTransmitRetries(void) const { return mTransmitRetries; }
356 
357     /**
358      * This method gets the most recent RSSI measurement.
359      *
360      * @returns The RSSI in dBm when it is valid. `kInvalidRssiValue` when RSSI is invalid.
361      *
362      */
363     int8_t GetRssi(void) const;
364 
365     /**
366      * This method begins energy scan.
367      *
368      * @param[in] aScanChannel   The channel to perform the energy scan on.
369      * @param[in] aScanDuration  The duration, in milliseconds, for the channel to be scanned.
370      *
371      * @retval kErrorNone            Successfully started scanning the channel.
372      * @retval kErrorInvalidState    The radio was disabled or transmitting.
373      * @retval kErrorNotImplemented  Energy scan is not supported (applicable in link-raw/radio mode only).
374      *
375      */
376     Error EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration);
377 
378     /**
379      * This method returns the noise floor value (currently use the radio receive sensitivity value).
380      *
381      * @returns The noise floor value in dBm.
382      *
383      */
384     int8_t GetNoiseFloor(void);
385 
386 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
387 
388     /**
389      * This method lets `SubMac` start CSL sample.
390      *
391      * `SubMac` would switch the radio state between `Receive` and `Sleep` according the CSL timer. When CslSample is
392      * started, `mState` will become `kStateCslSample`. But it could be doing `Sleep` or `Receive` at this moment
393      * (depending on `mCslState`).
394      *
395      * @param[in]  aPanChannel  The current phy channel used by the device. This param will only take effect when CSL
396      *                          channel hasn't been explicitly specified.
397      *
398      * @retval kErrorNone          Successfully entered CSL operation (sleep or receive according to CSL timer).
399      * @retval kErrorBusy          The radio was transmitting.
400      * @retval kErrorInvalidState  The radio was disabled.
401      *
402      */
403     Error CslSample(uint8_t aPanChannel);
404 
405     /**
406      * This method gets the CSL channel.
407      *
408      * @returns CSL channel.
409      *
410      */
GetCslChannel(void) const411     uint8_t GetCslChannel(void) const { return mCslChannel; }
412 
413     /**
414      * This method sets the CSL channel.
415      *
416      * @param[in]  aChannel  The CSL channel. `0` to set CSL Channel unspecified.
417      *
418      */
419     void SetCslChannel(uint8_t aChannel);
420 
421     /**
422      * This method indicates if CSL channel has been explicitly specified by the upper layer.
423      *
424      * @returns If CSL channel has been specified.
425      *
426      */
IsCslChannelSpecified(void) const427     bool IsCslChannelSpecified(void) const { return mIsCslChannelSpecified; }
428 
429     /**
430      * This method sets the flag representing if CSL channel has been specified.
431      *
432      */
SetCslChannelSpecified(bool aIsSpecified)433     void SetCslChannelSpecified(bool aIsSpecified) { mIsCslChannelSpecified = aIsSpecified; }
434 
435     /**
436      * This method gets the CSL period.
437      *
438      * @returns CSL period.
439      *
440      */
GetCslPeriod(void) const441     uint16_t GetCslPeriod(void) const { return mCslPeriod; }
442 
443     /**
444      * This method sets the CSL period.
445      *
446      * @param[in]  aPeriod  The CSL period in 10 symbols.
447      *
448      */
449     void SetCslPeriod(uint16_t aPeriod);
450 
451     /**
452      * This method returns CSL parent clock accuracy, in ± ppm.
453      *
454      * @retval CSL parent clock accuracy.
455      *
456      */
GetCslParentClockAccuracy(void) const457     uint8_t GetCslParentClockAccuracy(void) const { return mCslParentAccuracy; }
458 
459     /**
460      * This method sets CSL parent clock accuracy, in ± ppm.
461      *
462      * @param[in] aCslParentAccuracy CSL parent clock accuracy, in ± ppm.
463      *
464      */
SetCslParentClockAccuracy(uint8_t aCslParentAccuracy)465     void SetCslParentClockAccuracy(uint8_t aCslParentAccuracy) { mCslParentAccuracy = aCslParentAccuracy; }
466 
467     /**
468      * This method sets CSL parent uncertainty, in ±10 us units.
469      *
470      * @retval CSL parent uncertainty, in ±10 us units.
471      *
472      */
GetCslParentUncertainty(void) const473     uint8_t GetCslParentUncertainty(void) const { return mCslParentUncert; }
474 
475     /**
476      * This method returns CSL parent uncertainty, in ±10 us units.
477      *
478      * @param[in] aCslParentUncert  CSL parent uncertainty, in ±10 us units.
479      *
480      */
SetCslParentUncertainty(uint8_t aCslParentUncert)481     void SetCslParentUncertainty(uint8_t aCslParentUncert) { mCslParentUncert = aCslParentUncert; }
482 
483 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
484 
485     /**
486      * This method sets MAC keys and key index.
487      *
488      * @param[in] aKeyIdMode  MAC key ID mode.
489      * @param[in] aKeyId      The key ID.
490      * @param[in] aPrevKey    The previous MAC key.
491      * @param[in] aCurrKey    The current MAC key.
492      * @param[in] aNextKey    The next MAC key.
493      *
494      */
495     void SetMacKey(uint8_t aKeyIdMode, uint8_t aKeyId, const Key &aPrevKey, const Key &aCurrKey, const Key &aNextKey);
496 
497     /**
498      * This method returns a reference to the current MAC key.
499      *
500      * @returns A reference to the current MAC key.
501      *
502      */
GetCurrentMacKey(void) const503     const Key &GetCurrentMacKey(void) const { return mCurrKey; }
504 
505     /**
506      * This method returns a reference to the previous MAC key.
507      *
508      * @returns A reference to the previous MAC key.
509      *
510      */
GetPreviousMacKey(void) const511     const Key &GetPreviousMacKey(void) const { return mPrevKey; }
512 
513     /**
514      * This method returns a reference to the next MAC key.
515      *
516      * @returns A reference to the next MAC key.
517      *
518      */
GetNextMacKey(void) const519     const Key &GetNextMacKey(void) const { return mNextKey; }
520 
521     /**
522      * This method returns the current MAC frame counter value.
523      *
524      * @returns The current MAC frame counter value.
525      *
526      */
GetFrameCounter(void) const527     uint32_t GetFrameCounter(void) const { return mFrameCounter; }
528 
529     /**
530      * This method sets the current MAC Frame Counter value.
531      *
532      * @param[in] aFrameCounter  The MAC Frame Counter value.
533      *
534      */
535     void SetFrameCounter(uint32_t aFrameCounter);
536 
537 private:
538 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
539     static void HandleCslTimer(Timer &aTimer);
540     void        HandleCslTimer(void);
541     void        GetCslWindowEdges(uint32_t &ahead, uint32_t &after);
542 #endif
543 
544     static constexpr uint8_t  kMinBE             = 3;   // macMinBE (IEEE 802.15.4-2006).
545     static constexpr uint8_t  kMaxBE             = 5;   // macMaxBE (IEEE 802.15.4-2006).
546     static constexpr uint32_t kUnitBackoffPeriod = 20;  // Number of symbols (IEEE 802.15.4-2006).
547     static constexpr uint32_t kAckTimeout        = 16;  // Timeout for waiting on an ACK (in msec).
548     static constexpr uint32_t kCcaSampleInterval = 128; // CCA sample interval, 128 usec.
549 
550 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
551     static constexpr uint32_t kEnergyScanRssiSampleInterval = 128; // RSSI sample interval for energy scan, 128 usec
552 #else
553     static constexpr uint32_t kEnergyScanRssiSampleInterval = 1; // RSSI sample interval during energy scan, 1 msec
554 #endif
555 
556     enum State : uint8_t
557     {
558         kStateDisabled,    // Radio is disabled.
559         kStateSleep,       // Radio is in sleep.
560         kStateReceive,     // Radio in in receive.
561         kStateCsmaBackoff, // CSMA backoff before transmission.
562         kStateTransmit,    // Radio is transmitting.
563         kStateEnergyScan,  // Energy scan.
564 #if !OPENTHREAD_MTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
565         kStateCslTransmit, // CSL transmission.
566 #endif
567 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
568         kStateCslSample, // CSL receive.
569 #endif
570     };
571 
572 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
573     // CSL receive window for the longest possible frame and
574     // ack duration.
575     static constexpr uint32_t kMinCslWindow = OPENTHREAD_CONFIG_CSL_MIN_RECEIVE_ON;
576 
577     // CSL receivers would wake up `kCslReceiveTimeAhead` earlier
578     // than expected sample window. The value is in usec.
579     static constexpr uint32_t kCslReceiveTimeAhead = OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD;
580 
581     static constexpr uint8_t kCslWorstCrystalPpm  = 255; // Worst possible crystal accuracy, in units of ± ppm.
582     static constexpr uint8_t kCslWorstUncertainty = 255; // Worst possible scheduling uncertainty, in units of 100 us.
583     static constexpr uint8_t kUsPerUncertUnit     = 100; // Number of microseconds by uncertainty unit.
584 
585     enum CslState : uint8_t{
586         kCslIdle,   // CSL receiver is not started.
587         kCslSample, // Sampling CSL channel.
588         kCslSleep,  // Radio in sleep.
589     };
590 #endif
591 
RadioSupportsCsmaBackoff(void) const592     bool RadioSupportsCsmaBackoff(void) const
593     {
594         return ((mRadioCaps & (OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_TRANSMIT_RETRIES)) != 0);
595     }
596 
RadioSupportsTransmitSecurity(void) const597     bool RadioSupportsTransmitSecurity(void) const { return ((mRadioCaps & OT_RADIO_CAPS_TRANSMIT_SEC) != 0); }
RadioSupportsRetries(void) const598     bool RadioSupportsRetries(void) const { return ((mRadioCaps & OT_RADIO_CAPS_TRANSMIT_RETRIES) != 0); }
RadioSupportsAckTimeout(void) const599     bool RadioSupportsAckTimeout(void) const { return ((mRadioCaps & OT_RADIO_CAPS_ACK_TIMEOUT) != 0); }
RadioSupportsEnergyScan(void) const600     bool RadioSupportsEnergyScan(void) const { return ((mRadioCaps & OT_RADIO_CAPS_ENERGY_SCAN) != 0); }
RadioSupportsTransmitTiming(void) const601     bool RadioSupportsTransmitTiming(void) const { return ((mRadioCaps & OT_RADIO_CAPS_TRANSMIT_TIMING) != 0); }
RadioSupportsReceiveTiming(void) const602     bool RadioSupportsReceiveTiming(void) const { return ((mRadioCaps & OT_RADIO_CAPS_RECEIVE_TIMING) != 0); }
603 
604     bool ShouldHandleTransmitSecurity(void) const;
605     bool ShouldHandleCsmaBackOff(void) const;
606     bool ShouldHandleAckTimeout(void) const;
607     bool ShouldHandleRetries(void) const;
608     bool ShouldHandleEnergyScan(void) const;
609     bool ShouldHandleTransmitTargetTime(void) const;
610 
611     void ProcessTransmitSecurity(void);
612     void UpdateFrameCounter(uint32_t aFrameCounter);
613     void StartCsmaBackoff(void);
614     void BeginTransmit(void);
615     void SampleRssi(void);
616 
617     void HandleReceiveDone(RxFrame *aFrame, Error aError);
618     void HandleTransmitStarted(TxFrame &aFrame);
619     void HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError);
620     void UpdateFrameCounterOnTxDone(const TxFrame &aFrame);
621     void HandleEnergyScanDone(int8_t aMaxRssi);
622 
623     static void HandleTimer(Timer &aTimer);
624     void        HandleTimer(void);
625 
626     void               SetState(State aState);
627     static const char *StateToString(State aState);
628 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
629     static const char *CslStateToString(CslState aCslState);
630 #endif
631 
632     otRadioCaps        mRadioCaps;
633     State              mState;
634     uint8_t            mCsmaBackoffs;
635     uint8_t            mTransmitRetries;
636     ShortAddress       mShortAddress;
637     ExtAddress         mExtAddress;
638     bool               mRxOnWhenBackoff;
639     int8_t             mEnergyScanMaxRssi;
640     TimeMilli          mEnergyScanEndTime;
641     TxFrame &          mTransmitFrame;
642     Callbacks          mCallbacks;
643     otLinkPcapCallback mPcapCallback;
644     void *             mPcapCallbackContext;
645     Key                mPrevKey;
646     Key                mCurrKey;
647     Key                mNextKey;
648     uint32_t           mFrameCounter;
649     uint8_t            mKeyId;
650 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
651     TimerMicro mTimer;
652 #else
653     TimerMilli                mTimer;
654 #endif
655 
656 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
657     uint16_t   mCslPeriod;                 // The CSL sample period, in units of 10 symbols (160 microseconds).
658     uint8_t    mCslChannel : 7;            // The CSL sample channel (only when `mIsCslChannelSpecified` is `true`).
659     uint8_t    mIsCslChannelSpecified : 1; // Whether the CSL channel was explicitly set
660     TimeMicro  mCslSampleTime;             // The CSL sample time of the current period.
661     TimeMicro  mCslLastSync;               // The timestamp of the last successful CSL synchronization.
662     uint8_t    mCslParentAccuracy;         // Drift of timer used for scheduling CSL tx by the parent, in ± ppm.
663     uint8_t    mCslParentUncert;           // Uncertainty of the scheduling CSL of tx by the parent, in ±10 us units.
664     CslState   mCslState;
665     TimerMicro mCslTimer;
666 #endif
667 };
668 
669 /**
670  * @}
671  *
672  */
673 
674 } // namespace Mac
675 } // namespace ot
676 
677 #endif // SUB_MAC_HPP_
678