/*
 *  Copyright (c) 2016-2018, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 *   This file includes definitions for the IEEE 802.15.4 MAC layer (sub-MAC).
 */

#ifndef SUB_MAC_HPP_
#define SUB_MAC_HPP_

#include "openthread-core-config.h"

#include <openthread/link.h>

#include <openthread/platform/crypto.h>

#include "common/callback.hpp"
#include "common/locator.hpp"
#include "common/non_copyable.hpp"
#include "common/timer.hpp"
#include "mac/mac_frame.hpp"
#include "radio/radio.hpp"

namespace ot {

/**
 * @addtogroup core-mac
 *
 * @brief
 *   This module includes definitions for the IEEE 802.15.4 MAC (sub-MAC).
 *
 * @{
 *
 */

namespace Mac {

#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE && (OPENTHREAD_CONFIG_THREAD_VERSION < OT_THREAD_VERSION_1_2)
#error "Thread 1.2 or higher version is required for OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE."
#endif

#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE

#if (OPENTHREAD_CONFIG_THREAD_VERSION < OT_THREAD_VERSION_1_2)
#error "Thread 1.2 or higher version is required for OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE."
#endif

#if !OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
#error "Microsecond timer OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE is required for "\
    "OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE"
#endif

#endif

#if OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE && !OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
#error "OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE is required for OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE."
#endif

#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
class LinkRaw;
#endif

/**
 * Implements the IEEE 802.15.4 MAC (sub-MAC).
 *
 * Sub-MAC layer implements a subset of IEEE802.15.4 MAC primitives which are shared by both MAC layer (in FTD/MTD
 * modes) and Raw Link (Radio only mode).

 * The sub-MAC layer handles the following (if not provided by radio platform):
 *
 *    - Ack timeout for frame transmission,
 *    - CSMA backoff logic,
 *    - Frame re-transmissions,
 *    - Energy scan on a single channel and RSSI sampling.
 *
 * It also act as the interface (to radio platform) for setting/getting radio configurations such as short or extended
 * addresses and PAN Id.
 *
 */
class SubMac : public InstanceLocator, private NonCopyable
{
    friend class Radio::Callbacks;
    friend class LinkRaw;

public:
    /**
     * Defines the callbacks notifying `SubMac` user of changes and events.
     *
     */
    class Callbacks : public InstanceLocator
    {
    public:
        /**
         * Initializes the `Callbacks` object.
         *
         * @param[in]  aInstance  A reference to the OpenThread instance.
         *
         */
        explicit Callbacks(Instance &aInstance);

        /**
         * Notifies user of `SubMac` of a received frame.
         *
         * @param[in]  aFrame    A pointer to the received frame or `nullptr` if the receive operation failed.
         * @param[in]  aError    kErrorNone when successfully received a frame,
         *                       kErrorAbort when reception was aborted and a frame was not received,
         *                       kErrorNoBufs when a frame could not be received due to lack of rx buffer space.
         *
         */
        void ReceiveDone(RxFrame *aFrame, Error aError);

        /**
         * Notifies user of `SubMac` of CCA status (success/failure) for a frame transmission attempt.
         *
         * This is intended for updating counters, logging, and/or tracking CCA failure rate statistics.
         *
         * @param[in] aCcaSuccess   TRUE if the CCA succeeded, FALSE otherwise.
         * @param[in] aChannel      The channel on which CCA was performed.
         *
         */
        void RecordCcaStatus(bool aCcaSuccess, uint8_t aChannel);

        /**
         * Notifies user of `SubMac` of the status of a frame transmission attempt.
         *
         * This is intended for updating counters, logging, and/or collecting statistics.
         *
         * @note Unlike `TransmitDone` which is invoked after all re-transmission attempts to indicate the final status
         * of a frame transmission, this method is invoked on all frame transmission attempts.
         *
         * @param[in] aFrame      The transmitted frame.
         * @param[in] aError      kErrorNone when the frame was transmitted successfully,
         *                        kErrorNoAck when the frame was transmitted but no ACK was received,
         *                        kErrorChannelAccessFailure tx failed due to activity on the channel,
         *                        kErrorAbort when transmission was aborted for other reasons.
         * @param[in] aRetryCount Current retry count. This is valid only when sub-mac handles frame re-transmissions.
         * @param[in] aWillRetx   Indicates whether frame will be retransmitted or not. This is applicable only
         *                        when there was an error in current transmission attempt.
         *
         */
        void RecordFrameTransmitStatus(const TxFrame &aFrame, Error aError, uint8_t aRetryCount, bool aWillRetx);

        /**
         * The method notifies user of `SubMac` that the transmit operation has completed, providing, if applicable,
         * the received ACK frame.
         *
         * @param[in]  aFrame     The transmitted frame.
         * @param[in]  aAckFrame  A pointer to the ACK frame, `nullptr` if no ACK was received.
         * @param[in]  aError     kErrorNone when the frame was transmitted,
         *                        kErrorNoAck when the frame was transmitted but no ACK was received,
         *                        kErrorChannelAccessFailure tx failed due to activity on the channel,
         *                        kErrorAbort when transmission was aborted for other reasons.
         *
         */
        void TransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError);

        /**
         * Notifies user of `SubMac` that energy scan is complete.
         *
         * @param[in]  aMaxRssi  Maximum RSSI seen on the channel, or `Radio::kInvalidRssi` if failed.
         *
         */
        void EnergyScanDone(int8_t aMaxRssi);

        /**
         * Notifies user of `SubMac` that a specific MAC frame counter is used for transmission.
         *
         * It is possible that this callback is invoked out of order in terms of counter values (i.e., called for a
         * smaller counter value after a call for a larger counter value).
         *
         * @param[in]  aFrameCounter  The MAC frame counter value which was used.
         *
         */
        void FrameCounterUsed(uint32_t aFrameCounter);
    };

    /**
     * Initializes the `SubMac` object.
     *
     * @param[in]  aInstance  A reference to the OpenThread instance.
     *
     */
    explicit SubMac(Instance &aInstance);

    /**
     * Gets the capabilities provided by platform radio.
     *
     * @returns The capability bit vector (see `OT_RADIO_CAP_*` definitions).
     *
     */
    otRadioCaps GetRadioCaps(void) const { return mRadioCaps; }

    /**
     * Gets the capabilities provided by `SubMac` layer.
     *
     * @returns The capability bit vector (see `OT_RADIO_CAP_*` definitions).
     *
     */
    otRadioCaps GetCaps(void) const;

    /**
     * Sets the PAN ID.
     *
     * @param[in] aPanId  The PAN ID.
     *
     */
    void SetPanId(PanId aPanId);

    /**
     * Gets the short address.
     *
     * @returns The short address.
     *
     */
    ShortAddress GetShortAddress(void) const { return mShortAddress; }

    /**
     * Sets the short address.
     *
     * @param[in] aShortAddress   The short address.
     *
     */
    void SetShortAddress(ShortAddress aShortAddress);

    /**
     * Gets the extended address.
     *
     * @returns A reference to the extended address.
     *
     */
    const ExtAddress &GetExtAddress(void) const { return mExtAddress; }

    /**
     * Sets extended address.
     *
     * @param[in] aExtAddress  The extended address.
     *
     */
    void SetExtAddress(const ExtAddress &aExtAddress);

    /**
     * Registers a callback to provide received packet capture for IEEE 802.15.4 frames.
     *
     * @param[in]  aPcapCallback     A pointer to a function that is called when receiving an IEEE 802.15.4 link frame
     *                               or `nullptr` to disable the callback.
     * @param[in]  aCallbackContext  A pointer to application-specific context.
     *
     */
    void SetPcapCallback(otLinkPcapCallback aPcapCallback, void *aCallbackContext)
    {
        mPcapCallback.Set(aPcapCallback, aCallbackContext);
    }

    /**
     * Indicates whether radio should stay in Receive or Sleep during CSMA backoff.
     *
     * @param[in]  aRxOnWhenBackoff  TRUE to keep radio in Receive, FALSE to put to Sleep during CSMA backoff.
     *
     */
    void SetRxOnWhenBackoff(bool aRxOnWhenBackoff) { mRxOnWhenBackoff = aRxOnWhenBackoff; }

    /**
     * Enables the radio.
     *
     * @retval kErrorNone     Successfully enabled.
     * @retval kErrorFailed   The radio could not be enabled.
     *
     */
    Error Enable(void);

    /**
     * Disables the radio.
     *
     * @retval kErrorNone     Successfully disabled the radio.
     *
     */
    Error Disable(void);

    /**
     * Transitions the radio to Sleep.
     *
     * @retval kErrorNone          Successfully transitioned to Sleep.
     * @retval kErrorBusy          The radio was transmitting.
     * @retval kErrorInvalidState  The radio was disabled.
     *
     */
    Error Sleep(void);

    /**
     * Indicates whether the sub-mac is busy transmitting or scanning.
     *
     * @retval TRUE if the sub-mac is busy transmitting or scanning.
     * @retval FALSE if the sub-mac is not busy transmitting or scanning.
     *
     */
    bool IsTransmittingOrScanning(void) const { return (mState == kStateTransmit) || (mState == kStateEnergyScan); }

    /**
     * Transitions the radio to Receive.
     *
     * @param[in]  aChannel   The channel to use for receiving.
     *
     * @retval kErrorNone          Successfully transitioned to Receive.
     * @retval kErrorInvalidState  The radio was disabled or transmitting.
     *
     */
    Error Receive(uint8_t aChannel);

    /**
     * Gets the radio transmit frame.
     *
     * @returns The transmit frame.
     *
     */
    TxFrame &GetTransmitFrame(void) { return mTransmitFrame; }

    /**
     * Sends a prepared frame.
     *
     * The frame should be placed in `GetTransmitFrame()` frame.
     *
     * The `SubMac` layer handles Ack timeout, CSMA backoff, and frame retransmission.
     *
     * @retval kErrorNone          Successfully started the frame transmission
     * @retval kErrorInvalidState  The radio was disabled or transmitting.
     *
     */
    Error Send(void);

    /**
     * Gets the number of transmit retries of last transmitted frame.
     *
     * @returns Number of transmit retries.
     *
     */
    uint8_t GetTransmitRetries(void) const { return mTransmitRetries; }

    /**
     * Gets the most recent RSSI measurement.
     *
     * @returns The RSSI in dBm when it is valid. `Radio::kInvalidRssi` when RSSI is invalid.
     *
     */
    int8_t GetRssi(void) const;

    /**
     * Begins energy scan.
     *
     * @param[in] aScanChannel   The channel to perform the energy scan on.
     * @param[in] aScanDuration  The duration, in milliseconds, for the channel to be scanned.
     *
     * @retval kErrorNone            Successfully started scanning the channel.
     * @retval kErrorBusy            The radio is performing energy scanning.
     * @retval kErrorInvalidState    The radio was disabled or transmitting.
     * @retval kErrorNotImplemented  Energy scan is not supported (applicable in link-raw/radio mode only).
     *
     */
    Error EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration);

    /**
     * Returns the noise floor value (currently use the radio receive sensitivity value).
     *
     * @returns The noise floor value in dBm.
     *
     */
    int8_t GetNoiseFloor(void) const;

#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
    /**
     * Configures CSL parameters in 'SubMac'.
     *
     * @param[in]  aPeriod    The CSL period (in unit of 10 symbols).
     * @param[in]  aChannel   The CSL channel.
     * @param[in]  aShortAddr The short source address of CSL receiver's peer.
     * @param[in]  aExtAddr   The extended source address of CSL receiver's peer.
     *
     * @retval  TRUE if CSL Period or CSL Channel changed.
     * @retval  FALSE if CSL Period and CSL Channel did not change.
     *
     */
    bool UpdateCsl(uint16_t aPeriod, uint8_t aChannel, otShortAddress aShortAddr, const otExtAddress *aExtAddr);

    /**
     * Lets `SubMac` start CSL sample mode given a configured non-zero CSL period.
     *
     * `SubMac` would switch the radio state between `Receive` and `Sleep` according the CSL timer.
     *
     */
    void CslSample(void);

    /**
     * Returns parent CSL accuracy (clock accuracy and uncertainty).
     *
     * @returns The parent CSL accuracy.
     *
     */
    const CslAccuracy &GetCslParentAccuracy(void) const { return mCslParentAccuracy; }

    /**
     * Sets parent CSL accuracy.
     *
     * @param[in] aCslAccuracy  The parent CSL accuracy.
     *
     */
    void SetCslParentAccuracy(const CslAccuracy &aCslAccuracy) { mCslParentAccuracy = aCslAccuracy; }

#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE

    /**
     * Sets MAC keys and key index.
     *
     * @param[in] aKeyIdMode  MAC key ID mode.
     * @param[in] aKeyId      The key ID.
     * @param[in] aPrevKey    The previous MAC key.
     * @param[in] aCurrKey    The current MAC key.
     * @param[in] aNextKey    The next MAC key.
     *
     */
    void SetMacKey(uint8_t            aKeyIdMode,
                   uint8_t            aKeyId,
                   const KeyMaterial &aPrevKey,
                   const KeyMaterial &aCurrKey,
                   const KeyMaterial &aNextKey);

    /**
     * Returns a reference to the current MAC key.
     *
     * @returns A reference to the current MAC key.
     *
     */
    const KeyMaterial &GetCurrentMacKey(void) const { return mCurrKey; }

    /**
     * Returns a reference to the previous MAC key.
     *
     * @returns A reference to the previous MAC key.
     *
     */
    const KeyMaterial &GetPreviousMacKey(void) const { return mPrevKey; }

    /**
     * Returns a reference to the next MAC key.
     *
     * @returns A reference to the next MAC key.
     *
     */
    const KeyMaterial &GetNextMacKey(void) const { return mNextKey; }

    /**
     * Clears the stored MAC keys.
     *
     */
    void ClearMacKeys(void)
    {
        mPrevKey.Clear();
        mCurrKey.Clear();
        mNextKey.Clear();
    }

    /**
     * Returns the current MAC frame counter value.
     *
     * @returns The current MAC frame counter value.
     *
     */
    uint32_t GetFrameCounter(void) const { return mFrameCounter; }

    /**
     * Sets the current MAC Frame Counter value.
     *
     * @param[in] aFrameCounter  The MAC Frame Counter value.
     * @param[in] aSetIfLarger   If `true`, set only if the new value @p aFrameCounter is larger than the current value.
     *                           If `false`, set the new value independent of the current value.
     *
     */
    void SetFrameCounter(uint32_t aFrameCounter, bool aSetIfLarger);

#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
    /**
     * Enables/disables the radio filter.
     *
     * When radio filter is enabled, radio is put to sleep instead of receive (to ensure device does not receive any
     * frame and/or potentially send ack). Also the frame transmission requests return immediately without sending the
     * frame over the air (return "no ack" error if ack is requested, otherwise return success).
     *
     * @param[in] aFilterEnabled    TRUE to enable radio filter, FALSE to disable.
     *
     */
    void SetRadioFilterEnabled(bool aFilterEnabled) { mRadioFilterEnabled = aFilterEnabled; }

    /**
     * Indicates whether the radio filter is enabled or not.
     *
     * @retval TRUE   If the radio filter is enabled.
     * @retval FALSE  If the radio filter is disabled.
     *
     */
    bool IsRadioFilterEnabled(void) const { return mRadioFilterEnabled; }
#endif

private:
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
    static void HandleCslTimer(Timer &aTimer);
    void        HandleCslTimer(void);
    void        GetCslWindowEdges(uint32_t &aAhead, uint32_t &aAfter);
#if OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE
    void LogReceived(RxFrame *aFrame);
#endif
#endif

    static constexpr uint8_t  kCsmaMinBe         = 3;   // macMinBE (IEEE 802.15.4-2006).
    static constexpr uint8_t  kCsmaMaxBe         = 5;   // macMaxBE (IEEE 802.15.4-2006).
    static constexpr uint32_t kUnitBackoffPeriod = 20;  // Number of symbols (IEEE 802.15.4-2006).
    static constexpr uint32_t kAckTimeout        = 16;  // Timeout for waiting on an ACK (in msec).
    static constexpr uint32_t kCcaSampleInterval = 128; // CCA sample interval, 128 usec.

#if OPENTHREAD_CONFIG_MAC_ADD_DELAY_ON_NO_ACK_ERROR_BEFORE_RETRY
    static constexpr uint8_t kRetxDelayMinBackoffExponent = OPENTHREAD_CONFIG_MAC_RETX_DELAY_MIN_BACKOFF_EXPONENT;
    static constexpr uint8_t kRetxDelayMaxBackoffExponent = OPENTHREAD_CONFIG_MAC_RETX_DELAY_MAX_BACKOFF_EXPONENT;
#endif

#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
    static constexpr uint32_t kEnergyScanRssiSampleInterval = 128; // RSSI sample interval for energy scan, 128 usec
#else
    static constexpr uint32_t kEnergyScanRssiSampleInterval = 1; // RSSI sample interval during energy scan, 1 msec
#endif

    enum State : uint8_t
    {
        kStateDisabled,    // Radio is disabled.
        kStateSleep,       // Radio is in sleep.
        kStateReceive,     // Radio in in receive.
        kStateCsmaBackoff, // CSMA backoff before transmission.
        kStateTransmit,    // Radio is transmitting.
        kStateEnergyScan,  // Energy scan.
#if OPENTHREAD_CONFIG_MAC_ADD_DELAY_ON_NO_ACK_ERROR_BEFORE_RETRY
        kStateDelayBeforeRetx, // Delay before retx
#endif
#if !OPENTHREAD_MTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
        kStateCslTransmit, // CSL transmission.
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
        kStateCslSample, // CSL receive.
#endif
    };

#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
    // Radio on times needed before and after MHR time for proper frame detection
    static constexpr uint32_t kMinReceiveOnAhead = OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AHEAD;
    static constexpr uint32_t kMinReceiveOnAfter = OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AFTER;

    // CSL receivers would wake up `kCslReceiveTimeAhead` earlier
    // than expected sample window. The value is in usec.
    static constexpr uint32_t kCslReceiveTimeAhead = OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD;
#endif

#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
    // CSL transmitter would schedule delayed transmission `kCslTransmitTimeAhead` earlier
    // than expected delayed transmit time. The value is in usec.
    // Only for radios not supporting OT_RADIO_CAPS_TRANSMIT_TIMING.
    static constexpr uint32_t kCslTransmitTimeAhead = OPENTHREAD_CONFIG_CSL_TRANSMIT_TIME_AHEAD;
#endif

    /**
     * Initializes the states of the sub-MAC layer.
     *
     */
    void Init(void);

    bool RadioSupportsCsmaBackoff(void) const
    {
        return ((mRadioCaps & (OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_TRANSMIT_RETRIES)) != 0);
    }

    bool RadioSupportsTransmitSecurity(void) const { return ((mRadioCaps & OT_RADIO_CAPS_TRANSMIT_SEC) != 0); }
    bool RadioSupportsRetries(void) const { return ((mRadioCaps & OT_RADIO_CAPS_TRANSMIT_RETRIES) != 0); }
    bool RadioSupportsAckTimeout(void) const { return ((mRadioCaps & OT_RADIO_CAPS_ACK_TIMEOUT) != 0); }
    bool RadioSupportsEnergyScan(void) const { return ((mRadioCaps & OT_RADIO_CAPS_ENERGY_SCAN) != 0); }
    bool RadioSupportsTransmitTiming(void) const { return ((mRadioCaps & OT_RADIO_CAPS_TRANSMIT_TIMING) != 0); }
    bool RadioSupportsReceiveTiming(void) const { return ((mRadioCaps & OT_RADIO_CAPS_RECEIVE_TIMING) != 0); }

    bool ShouldHandleTransmitSecurity(void) const;
    bool ShouldHandleCsmaBackOff(void) const;
    bool ShouldHandleAckTimeout(void) const;
    bool ShouldHandleRetries(void) const;
    bool ShouldHandleEnergyScan(void) const;
    bool ShouldHandleTransmitTargetTime(void) const;

    void ProcessTransmitSecurity(void);
    void SignalFrameCounterUsed(uint32_t aFrameCounter, uint8_t aKeyId);
    void StartCsmaBackoff(void);
    void StartTimerForBackoff(uint8_t aBackoffExponent);
    void BeginTransmit(void);
    void SampleRssi(void);

    void HandleReceiveDone(RxFrame *aFrame, Error aError);
    void HandleTransmitStarted(TxFrame &aFrame);
    void HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError);
    void SignalFrameCounterUsedOnTxDone(const TxFrame &aFrame);
    void HandleEnergyScanDone(int8_t aMaxRssi);
    void HandleTimer(void);

    void               SetState(State aState);
    static const char *StateToString(State aState);

    using SubMacTimer =
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
        TimerMicroIn<SubMac, &SubMac::HandleTimer>;
#else
        TimerMilliIn<SubMac, &SubMac::HandleTimer>;
#endif

    otRadioCaps  mRadioCaps;
    State        mState;
    uint8_t      mCsmaBackoffs;
    uint8_t      mTransmitRetries;
    ShortAddress mShortAddress;
    ExtAddress   mExtAddress;
    bool         mRxOnWhenBackoff : 1;
#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
    bool mRadioFilterEnabled : 1;
#endif
    int8_t                       mEnergyScanMaxRssi;
    TimeMilli                    mEnergyScanEndTime;
    TxFrame                     &mTransmitFrame;
    Callbacks                    mCallbacks;
    Callback<otLinkPcapCallback> mPcapCallback;
    KeyMaterial                  mPrevKey;
    KeyMaterial                  mCurrKey;
    KeyMaterial                  mNextKey;
    uint32_t                     mFrameCounter;
    uint8_t                      mKeyId;
#if OPENTHREAD_CONFIG_MAC_ADD_DELAY_ON_NO_ACK_ERROR_BEFORE_RETRY
    uint8_t mRetxDelayBackOffExponent;
#endif
    SubMacTimer mTimer;

#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
    uint16_t mCslPeriod;      // The CSL sample period, in units of 10 symbols (160 microseconds).
    uint8_t  mCslChannel : 7; // The CSL sample channel.
    bool mIsCslSampling : 1;  // Indicates that the radio is receiving in CSL state for platforms not supporting delayed
                              // reception.
    uint16_t    mCslPeerShort;      // The CSL peer short address.
    TimeMicro   mCslSampleTime;     // The CSL sample time of the current period relative to the local radio clock.
    TimeMicro   mCslLastSync;       // The timestamp of the last successful CSL synchronization.
    CslAccuracy mCslParentAccuracy; // The parent's CSL accuracy (clock accuracy and uncertainty).
    TimerMicro  mCslTimer;
#endif
};

/**
 * @}
 *
 */

} // namespace Mac
} // namespace ot

#endif // SUB_MAC_HPP_
