/*
 *  Copyright (c) 2017, 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 implements the OpenThread platform abstraction for radio communication.
 *
 */

/* Openthread configuration */
#include OPENTHREAD_PROJECT_CORE_CONFIG_FILE

/* memcpy */
#include "string.h"

/* uMac, MMAC, Radio */
#include "MMAC.h"
#include "MicroSpecific_arm_sdk2.h"
#include "radio.h"

/* Openthread general */
#include <utils/code_utils.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/diag.h>
#include <openthread/platform/radio.h>

#if USE_RTOS
#include "openthread-system.h"
#endif

extern void BOARD_LedDongleToggle(void);

/* Defines */
#define BIT_SET(arg, posn) ((arg) |= (1ULL << (posn)))
#define BIT_CLR(arg, posn) ((arg) &= ~(1ULL << (posn)))
#define BIT_TST(arg, posn) (!!((arg) & (1ULL << (posn))))

#define ALL_FFs_BYTE (0xFF)

#define K32W_RADIO_MIN_TX_POWER_DBM (-30)
#define K32W_RADIO_MAX_TX_POWER_DBM (15)
#define K32W_RADIO_RX_SENSITIVITY_DBM (-100)
#define K32W_RADIO_DEFAULT_CHANNEL (11)

#define US_PER_SYMBOL (16) /* Duration of a single symbol in [us] */
#define SYMBOLS_TO_US(symbols) ((symbols)*US_PER_SYMBOL)
#define US_TO_MILI_DIVIDER (1000)

#define MAX_FP_ADDRS (10)   /* max number of frame pending children */
#define K32W_RX_BUFFERS (8) /* max number of RX buffers */

/* check IEEE Std. 802.15.4 - 2015: Table 8-81 - MAC sublayer constants */
#define MAC_TX_ATTEMPTS (4)
#define MAC_TX_CSMA_MIN_BE (3)
#define MAC_TX_CSMA_MAX_BE (5)
#define MAC_TX_CSMA_MAX_BACKOFFS (4)

/* Structures */
typedef struct
{
    uint16_t macAddress;
    uint16_t panId;
} fpNeighShortAddr;

typedef struct
{
    uint32_t u32L;
    uint32_t u32H;
} extMacAddr;

typedef struct
{
    extMacAddr extAddr;
    uint16_t   panId;
} fpNeighExtAddr;

typedef struct
{
    tsRxFrameFormat *buffer[K32W_RX_BUFFERS];
    uint8_t          head;
    uint8_t          tail;
    bool             isFull;
} rxRingBuffer;

typedef enum
{
    kFcfSize             = sizeof(uint16_t),
    kDsnSize             = sizeof(uint8_t),
    kSecurityControlSize = sizeof(uint8_t),
    kFrameCounterSize    = sizeof(uint32_t),
    kKeyIndexSize        = sizeof(uint8_t),

    kMacFcfLowOffset = 0, /* Offset of FCF first byte inside Mac Hdr */
    kMacFrameDataReq = 4,

    kFcfTypeBeacon       = 0,
    kFcfTypeMacData      = 1,
    kFcfTypeAck          = 2,
    kFcfTypeMacCommand   = 3,
    kFcfMacFrameTypeMask = 7 << 0,

    kFcfAckRequest        = 1 << 5,
    kFcfPanidCompression  = 1 << 6,
    kFcfSeqNbSuppresssion = 1 << 8,
    kFcfDstAddrNone       = 0 << 10,
    kFcfDstAddrShort      = 2 << 10,
    kFcfDstAddrExt        = 3 << 10,
    kFcfDstAddrMask       = 3 << 10,
    kFcfSrcAddrNone       = 0 << 14,
    kFcfSrcAddrShort      = 2 << 14,
    kFcfSrcAddrExt        = 3 << 14,
    kFcfSrcAddrMask       = 3 << 14,

    kSecLevelMask            = 7 << 0,
    kFrameCounterSuppression = 1 << 5,

    kKeyIdMode0    = 0 << 3,
    kKeyIdMode1    = 1 << 3,
    kKeyIdMode2    = 2 << 3,
    kKeyIdMode3    = 3 << 3,
    kKeyIdModeMask = 3 << 3,

    kKeySourceSizeMode0 = 0,
    kKeySourceSizeMode1 = 0,
    kKeySourceSizeMode2 = 4,
    kKeySourceSizeMode3 = 8,
} macHdr;

typedef enum
{
    macToOtFrame, /* RX */
    otToMacFrame, /* TX */
} frameConversionType;

/* Private functions declaration */
static void             K32WISR(uint32_t u32IntBitmap);
static void             K32WProcessMacHeader(tsRxFrameFormat *aRxFrame);
static void             K32WProcessRxFrames(otInstance *aInstance);
static void             K32WProcessTxFrame(otInstance *aInstance);
static bool             K32WCheckIfFpRequired(tsRxFrameFormat *aRxFrame);
static bool_t           K32WIsDataReq(tsRxFrameFormat *aRxFrame);
static otError          K32WFrameConversion(tsRxFrameFormat *   aMacFormatFrame,
                                            otRadioFrame *      aOtFrame,
                                            frameConversionType convType);
static void             K32WCopy(uint8_t *aFieldValue, uint8_t **aPsdu, uint8_t copySize, frameConversionType convType);
static void             K32WResetRxRingBuffer(rxRingBuffer *aRxRing);
static void             K32WPushRxRingBuffer(rxRingBuffer *aRxRing, tsRxFrameFormat *aRxFrame);
static tsRxFrameFormat *K32WPopRxRingBuffer(rxRingBuffer *aRxRing);
static bool             K32WIsEmptyRxRingBuffer(rxRingBuffer *aRxRing);
static tsRxFrameFormat *K32WGetFrame(tsRxFrameFormat *aRxFrame, uint8_t *aRxFrameIndex);
static void             K32WEnableReceive(bool_t isNewFrameNeeded);
static void             K32WRestartRx(void);

/* Private variables declaration */
static otRadioState sState = OT_RADIO_STATE_DISABLED;
static otInstance * sInstance;    /* Saved OT Instance */
static int8_t       sTxPwrLevel;  /* Default power is 0 dBm */
static uint8_t      sChannel = 0; /* Default channel - must be invalid so it
                                     updates the first time it is set */
static bool_t    sIsFpEnabled;    /* Frame Pending enabled? */
static uint16_t  sPanId;          /* PAN ID currently in use */
static uint16_t  sShortAddress;
static tsExtAddr sExtAddress;
static uint64_t  sCustomExtAddr = 0;

static fpNeighShortAddr sFpShortAddr[MAX_FP_ADDRS]; /* Frame Pending short addresses array */
static uint16_t         sFpShortAddrMask;           /* Mask - sFpShortAddr valid entries */

static fpNeighExtAddr sFpExtAddr[MAX_FP_ADDRS]; /* Frame Pending extended addresses array */
static uint16_t       sFpExtAddrMask;           /* Mask - sFpExtAddr is valid */

static rxRingBuffer     sRxRing;                       /* Receive Ring Buffer */
static tsRxFrameFormat  sRxFrame[K32W_RX_BUFFERS];     /* RX Buffers */
static tsRxFrameFormat *sRxFrameInProcess;             /* RX Frame currently in processing */
static bool_t           sIsRxDisabled;                 /* TRUE if RX was disabled due to no RX bufs */
static uint8_t          sRxFrameIndex;                 /* Index tracking the sRxFrame array */
static teRxOption       sRxOpt = E_MMAC_RX_START_NOW | /* RX Options */
                           E_MMAC_RX_ALIGN_NORMAL | E_MMAC_RX_USE_AUTO_ACK | E_MMAC_RX_NO_MALFORMED |
                           E_MMAC_RX_NO_FCS_ERROR | E_MMAC_RX_ADDRESS_MATCH;

tsRxFrameFormat         sTxMacFrame;                      /* TX Frame */
static tsRxFrameFormat  sRxAckFrame;                      /* Frame used for keeping the ACK */
static otRadioFrame     sRxOtFrame;                       /* Used for TX/RX frame conversion */
static uint8            sRxData[OT_RADIO_FRAME_MAX_SIZE]; /* mPsdu buffer for sRxOtFrame */
static tsRxFrameFormat *pLastRxFrame;

static bool         sRadioInitForLp    = FALSE;
static bool         sPromiscuousEnable = FALSE;
static bool         sTxDone;                          /* TRUE if a TX frame was sent into the air */
static otError      sTxStatus;                        /* Status of the latest TX operation */
static otRadioFrame sTxOtFrame;                       /* OT TX Frame to be send */
static uint8_t      sTxData[OT_RADIO_FRAME_MAX_SIZE]; /* mPsdu buffer for sTxOtFrame */

/* Stub functions for controlling low power mode */
WEAK void App_AllowDeviceToSleep();
WEAK void App_DisallowDeviceToSleep();
/* Stub functions for controlling LEDs on OT RCP USB dongle */
WEAK void BOARD_LedDongleToggle();

/**
 * Stub function used for controlling low power mode
 *
 */
WEAK void App_AllowDeviceToSleep()
{
}

/**
 * Stub function used for controlling low power mode
 *
 */
WEAK void App_DisallowDeviceToSleep()
{
}

/**
 * Stub functions for controlling LEDs on OT RCP USB dongle
 *
 */
WEAK void BOARD_LedDongleToggle()
{
}

void App_SetCustomEui64(uint8_t *aIeeeEui64)
{
    memcpy((uint8_t *)&sCustomExtAddr, aIeeeEui64, sizeof(sCustomExtAddr));
}

void K32WRadioInit(void)
{
    /* RX initialization */
    memset(sRxFrame, 0, sizeof(tsRxFrameFormat) * K32W_RX_BUFFERS);
    sRxFrameIndex = 0;

    /* TX initialization */
    sTxOtFrame.mPsdu = sTxData;
    sRxOtFrame.mPsdu = sRxData;
}

void K32WRadioProcess(otInstance *aInstance)
{
    K32WProcessRxFrames(aInstance);
    K32WProcessTxFrame(aInstance);
}

otRadioState otPlatRadioGetState(otInstance *aInstance)
{
    OT_UNUSED_VARIABLE(aInstance);

    return sState;
}

void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
{
    OT_UNUSED_VARIABLE(aInstance);

    if (0 == sCustomExtAddr)
    {
        tsExtAddr euiAddr;
        vMMAC_GetMacAddress(&euiAddr);

        memcpy(aIeeeEui64, &euiAddr.u32L, sizeof(uint32_t));
        memcpy(aIeeeEui64 + sizeof(uint32_t), &euiAddr.u32H, sizeof(uint32_t));
    }
    else
    {
        memcpy(aIeeeEui64, (uint8_t *)&sCustomExtAddr, sizeof(sCustomExtAddr));
    }
}

void otPlatRadioSetPanId(otInstance *aInstance, uint16_t aPanId)
{
    OT_UNUSED_VARIABLE(aInstance);

    sPanId = aPanId;
    vMMAC_SetRxPanId(aPanId);
}

void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aExtAddress)
{
    OT_UNUSED_VARIABLE(aInstance);

    if (aExtAddress)
    {
        memcpy(&sExtAddress.u32L, aExtAddress->m8, sizeof(uint32_t));
        memcpy(&sExtAddress.u32H, aExtAddress->m8 + sizeof(uint32_t), sizeof(uint32_t));
        vMMAC_SetRxExtendedAddr(&sExtAddress);
    }
}

void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aShortAddress)
{
    OT_UNUSED_VARIABLE(aInstance);

    sShortAddress = aShortAddress;
    vMMAC_SetRxShortAddr(aShortAddress);
}

otError otPlatRadioEnable(otInstance *aInstance)
{
    OT_UNUSED_VARIABLE(aInstance);

    K32WResetRxRingBuffer(&sRxRing);
    sRxFrameIndex = 0;
    vMMAC_Enable();
    vMMAC_EnableInterrupts(K32WISR);
    vMMAC_ConfigureInterruptSources(E_MMAC_INT_TX_COMPLETE | E_MMAC_INT_RX_HEADER | E_MMAC_INT_RX_COMPLETE);
    vMMAC_ConfigureRadio();
    vMMAC_SetTxParameters(MAC_TX_ATTEMPTS, MAC_TX_CSMA_MIN_BE, MAC_TX_CSMA_MAX_BE, MAC_TX_CSMA_MAX_BACKOFFS);

    if (sRadioInitForLp)
    {
        /* Re-set modem settings after low power exit */
        vMMAC_SetChannelAndPower(sChannel, sTxPwrLevel);
        vMMAC_SetRxExtendedAddr(&sExtAddress);
        vMMAC_SetRxPanId(sPanId);
        vMMAC_SetRxShortAddr(sShortAddress);
    }

    sTxOtFrame.mLength = 0;
    sRxOtFrame.mLength = 0;

    sInstance = aInstance;
    sState    = OT_RADIO_STATE_SLEEP;

    return OT_ERROR_NONE;
}

otError otPlatRadioDisable(otInstance *aInstance)
{
    otError error = OT_ERROR_INVALID_STATE;

    otEXPECT(otPlatRadioIsEnabled(aInstance));

    K32WResetRxRingBuffer(&sRxRing);
    sRxFrameIndex = 0;
    vMMAC_Disable();
    sState = OT_RADIO_STATE_DISABLED;
    error  = OT_ERROR_NONE;

exit:
    return error;
}

bool otPlatRadioIsEnabled(otInstance *aInstance)
{
    OT_UNUSED_VARIABLE(aInstance);

    return sState != OT_RADIO_STATE_DISABLED;
}

otError otPlatRadioSleep(otInstance *aInstance)
{
    OT_UNUSED_VARIABLE(aInstance);
    otError status = OT_ERROR_NONE;

    otEXPECT_ACTION(((sState != OT_RADIO_STATE_TRANSMIT) && (sState != OT_RADIO_STATE_DISABLED)),
                    status = OT_ERROR_INVALID_STATE);

    /* The radio has been init and configuration should be restored in otPlatRadioEnable when
       exiting low power */
    sRadioInitForLp = TRUE;

    sState = OT_RADIO_STATE_SLEEP;
    vMMAC_RadioToOffAndWait();
    App_AllowDeviceToSleep();

exit:
    return status;
}

otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
{
    OT_UNUSED_VARIABLE(aInstance);

    otError      error            = OT_ERROR_NONE;
    bool_t       isNewFrameNeeded = TRUE;
    otRadioState tempState        = sState;

    otEXPECT_ACTION(((sState != OT_RADIO_STATE_TRANSMIT) && (sState != OT_RADIO_STATE_DISABLED)),
                    error = OT_ERROR_INVALID_STATE);

    App_DisallowDeviceToSleep();

    /* Check if the channel needs to be changed */
    if (sChannel != aChannel)
    {
        sChannel = aChannel;

        /* The state is set to sleep to prevent a lockup caused by an RX interrup firing during
         * the radio off command called inside set channel and power */
        sState = OT_RADIO_STATE_SLEEP;
        vMMAC_SetChannelAndPower(sChannel, sTxPwrLevel);
        sState = tempState;
    }

    if (OT_RADIO_STATE_RECEIVE != sState)
    {
        sState = OT_RADIO_STATE_RECEIVE;
    }
    else
    {
        /* this might happen when the channel is switched
         * in the middle of a receive operation */
        isNewFrameNeeded = FALSE;
    }
    K32WEnableReceive(isNewFrameNeeded);

exit:
    return error;
}

void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
{
    OT_UNUSED_VARIABLE(aInstance);

    sIsFpEnabled = aEnable;
}

otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
{
    OT_UNUSED_VARIABLE(aInstance);

    otError error = OT_ERROR_NO_BUFS;
    uint8_t idx   = 0;

    for (; idx < MAX_FP_ADDRS; idx++)
    {
        if (!BIT_TST(sFpShortAddrMask, idx))
        {
            sFpShortAddr[idx].panId      = sPanId;
            sFpShortAddr[idx].macAddress = aShortAddress;
            BIT_SET(sFpShortAddrMask, idx);
            error = OT_ERROR_NONE;
            break;
        }
    }

    return error;
}

otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
{
    OT_UNUSED_VARIABLE(aInstance);

    otError error = OT_ERROR_NO_BUFS;
    uint8_t idx   = 0;

    for (; idx < MAX_FP_ADDRS; idx++)
    {
        if (!BIT_TST(sFpExtAddrMask, idx))
        {
            sFpExtAddr[idx].panId = sPanId;
            memcpy(&sFpExtAddr[idx].extAddr.u32L, aExtAddress->m8, sizeof(uint32_t));
            memcpy(&sFpExtAddr[idx].extAddr.u32H, aExtAddress->m8 + sizeof(uint32_t), sizeof(uint32_t));
            BIT_SET(sFpExtAddrMask, idx);
            error = OT_ERROR_NONE;
            break;
        }
    }

    return error;
}

otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
{
    OT_UNUSED_VARIABLE(aInstance);

    otError error = OT_ERROR_NO_ADDRESS;
    uint8_t idx   = 0;

    for (; idx < MAX_FP_ADDRS; idx++)
    {
        if (BIT_TST(sFpShortAddrMask, idx) && (sFpShortAddr[idx].macAddress == aShortAddress))
        {
            BIT_CLR(sFpShortAddrMask, idx);
            error = OT_ERROR_NONE;
            break;
        }
    }

    return error;
}

otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
{
    OT_UNUSED_VARIABLE(aInstance);

    otError error = OT_ERROR_NO_ADDRESS;
    uint8_t idx   = 0;

    for (; idx < MAX_FP_ADDRS; idx++)
    {
        if (BIT_TST(sFpExtAddrMask, idx) && !memcmp(&sFpExtAddr[idx].extAddr.u32L, aExtAddress->m8, sizeof(uint32_t)) &&
            !memcmp(&sFpExtAddr[idx].extAddr.u32H, aExtAddress->m8 + sizeof(uint32_t), sizeof(uint32_t)))
        {
            BIT_CLR(sFpExtAddrMask, idx);
            error = OT_ERROR_NONE;
            break;
        }
    }

    return error;
}

void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
{
    OT_UNUSED_VARIABLE(aInstance);

    sFpShortAddrMask = 0;
}

void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
{
    OT_UNUSED_VARIABLE(aInstance);

    sFpExtAddrMask = 0;
}

otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
{
    OT_UNUSED_VARIABLE(aInstance);

    return &sTxOtFrame;
}

otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
{
    otError    error    = OT_ERROR_NONE;
    teTxOption eOptions = E_MMAC_TX_START_NOW | E_MMAC_TX_USE_AUTO_ACK;

    otEXPECT_ACTION(OT_RADIO_STATE_RECEIVE == sState, error = OT_ERROR_INVALID_STATE);

    /* go to TX state */
    sState    = OT_RADIO_STATE_TRANSMIT;
    sTxStatus = OT_ERROR_NONE;

    /* set tx channel */
    if (sChannel != aFrame->mChannel)
    {
        vMMAC_SetChannelAndPower(aFrame->mChannel, sTxPwrLevel);
    }

    if (aFrame->mInfo.mTxInfo.mCsmaCaEnabled)
    {
        eOptions |= E_MMAC_TX_USE_CCA;
    }

    K32WFrameConversion(&sTxMacFrame, aFrame, otToMacFrame);

    /* stop rx is handled by uMac tx function */
    vMMAC_StartMacTransmit(&sTxMacFrame.sFrameBody, eOptions);

    /* Set RX buffer pointer for ACK */
    vMMAC_SetRxFrame(&sRxAckFrame);

    otPlatRadioTxStarted(aInstance, aFrame);

exit:
    return error;
}

int8_t otPlatRadioGetRssi(otInstance *aInstance)
{
    OT_UNUSED_VARIABLE(aInstance);

    int8_t  rssidBm       = 127;
    int16_t rssiValSigned = 0;
    bool_t  stateChanged  = FALSE;

    /* in RCP designs, the RSSI function is called while the radio is in
     * OT_RADIO_STATE_RECEIVE. Turn off the radio before reading RSSI,
     * otherwise we may end up waiting until a packet is received
     * (in i16Radio_GetRSSI, while loop)
     */

    if (sState == OT_RADIO_STATE_RECEIVE)
    {
        sState = OT_RADIO_STATE_SLEEP;
        vMMAC_RadioToOffAndWait();
        stateChanged = TRUE;
    }

    rssiValSigned = i16Radio_GetRSSI(0, FALSE, NULL);

    if (stateChanged)
    {
        sState = OT_RADIO_STATE_RECEIVE;
        K32WEnableReceive(TRUE);
    }

    rssiValSigned = i16Radio_BoundRssiValue(rssiValSigned);

    /* RSSI reported by radio is in 1/4 dBm step,
     * meaning values are 4 times larger than real dBm value.
     */
    rssidBm = (int8_t)(rssiValSigned >> 2);

    return rssidBm;
}

otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
{
    OT_UNUSED_VARIABLE(aInstance);

    return OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_TRANSMIT_RETRIES | OT_RADIO_CAPS_CSMA_BACKOFF;
}

bool otPlatRadioGetPromiscuous(otInstance *aInstance)
{
    OT_UNUSED_VARIABLE(aInstance);

    return sPromiscuousEnable;
}

void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
{
    OT_UNUSED_VARIABLE(aInstance);

    if (sPromiscuousEnable != aEnable)
    {
        sPromiscuousEnable = aEnable;

        if (aEnable)
        {
            sRxOpt &= ~E_MMAC_RX_ADDRESS_MATCH;
        }
        else
        {
            sRxOpt |= E_MMAC_RX_ADDRESS_MATCH;
        }
    }
}

otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
{
    OT_UNUSED_VARIABLE(aInstance);

    otError status = OT_ERROR_NOT_IMPLEMENTED;

    return status;
}

otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
{
    otError error = OT_ERROR_NONE;
    otEXPECT_ACTION(aPower != NULL, error = OT_ERROR_INVALID_ARGS);

    *aPower = i8Radio_GetTxPowerLevel_dBm();
    return OT_ERROR_NONE;

exit:
    return error;
}

otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
{
    OT_UNUSED_VARIABLE(aInstance);
    otRadioState tempState = sState;
    sState                 = OT_RADIO_STATE_SLEEP;

    /* trim the values to the radio capabilities */
    if (aPower < K32W_RADIO_MIN_TX_POWER_DBM)
    {
        aPower = K32W_RADIO_MIN_TX_POWER_DBM;
    }
    else if (aPower > K32W_RADIO_MAX_TX_POWER_DBM)
    {
        aPower = K32W_RADIO_MAX_TX_POWER_DBM;
    }

    /* save for later use */
    sTxPwrLevel = aPower;

    /* The state is set to sleep to prevent a lockup caused by an RX interrup firing during
     * the radio off command called inside set channel and power */
    if (0 != sChannel)
    {
        vMMAC_SetChannelAndPower(sChannel, aPower);
    }
    else
    {
        /* if the channel has not yet been initialized use K32W_RADIO_DEFAULT_CHANNEL as default */
        vMMAC_SetChannelAndPower(K32W_RADIO_DEFAULT_CHANNEL, aPower);
    }
    sState = tempState;

    return OT_ERROR_NONE;
}

otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold)
{
    OT_UNUSED_VARIABLE(aInstance);
    OT_UNUSED_VARIABLE(aThreshold);

    return OT_ERROR_NOT_IMPLEMENTED;
}

otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold)
{
    OT_UNUSED_VARIABLE(aInstance);
    OT_UNUSED_VARIABLE(aThreshold);

    return OT_ERROR_NOT_IMPLEMENTED;
}

int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
{
    OT_UNUSED_VARIABLE(aInstance);

    return K32W_RADIO_RX_SENSITIVITY_DBM;
}

/**
 * Interrupt service routine (e.g.: TX/RX/MAC HDR received)
 *
 * @param[in] u32IntBitmap  Bitmap telling which interrupt fired
 *
 */
static void K32WISR(uint32_t u32IntBitmap)
{
    tsRxFrameFormat *pRxFrame = NULL;

    switch (sState)
    {
    case OT_RADIO_STATE_RECEIVE:

        /* no rx errors */
        if (0 == u32MMAC_GetRxErrors())
        {
            if (u32IntBitmap & E_MMAC_INT_RX_HEADER)
            {
                /* go back one index from current frame index */
                pRxFrame = &sRxFrame[(sRxFrameIndex + K32W_RX_BUFFERS - 1) % K32W_RX_BUFFERS];

                /* FP processing first */
                K32WProcessMacHeader(pRxFrame);

                /* RX interrupt fired so it's safe to consume the frame */
                K32WPushRxRingBuffer(&sRxRing, pRxFrame);

                if (0 == (pRxFrame->sFrameBody.u16FCF & kFcfAckRequest))
                {
                    K32WEnableReceive(TRUE);
                }
            }
            else if (u32IntBitmap & E_MMAC_INT_RX_COMPLETE)
            {
                K32WEnableReceive(TRUE);
            }
        }
        else
        {
            /* restart RX and keep same buffer as data received contains errors */
            K32WEnableReceive(FALSE);
        }

        BOARD_LedDongleToggle();
        break;
    case OT_RADIO_STATE_TRANSMIT:

        if (u32IntBitmap & E_MMAC_INT_TX_COMPLETE)
        {
            uint32_t txErrors = u32MMAC_GetTxErrors();
            sTxDone           = TRUE;

            if (txErrors & E_MMAC_TXSTAT_CCA_BUSY)
            {
                sTxStatus = OT_ERROR_CHANNEL_ACCESS_FAILURE;
            }
            else if (txErrors & E_MMAC_TXSTAT_NO_ACK)
            {
                sTxStatus = OT_ERROR_NO_ACK;
            }
            else if (txErrors & E_MMAC_TXSTAT_ABORTED)
            {
                sTxStatus = OT_ERROR_ABORT;
            }
            else if ((txErrors & E_MMAC_TXSTAT_TXPCTO) || (txErrors & E_MMAC_TXSTAT_TXTO))
            {
                /* The JN518x/K32W0x1 has a TXTO timeout that we are using to catch and cope with the curious
                hang-up issue */
                vMMAC_AbortRadio();

                /* Describe failure as a CCA failure for onward processing */
                sTxStatus = OT_ERROR_CHANNEL_ACCESS_FAILURE;
            }

            /* go to RX and restore channel */
            if (sChannel != sTxOtFrame.mChannel)
            {
                vMMAC_SetChannelAndPower(sChannel, sTxPwrLevel);
            }

            BOARD_LedDongleToggle();
            sState = OT_RADIO_STATE_RECEIVE;
            K32WEnableReceive(TRUE);
        }
        break;

    default:
        break;
    }

#if USE_RTOS
    otSysEventSignalPending();
#endif
}
/**
 * Process the MAC Header of the latest received packet
 * We are in interrupt context - we need to compute the FP
 * while the hardware generates the ACK.
 *
 * @param[in] aRxFrame     Pointer to the latest received MAC packet
 *
 */
static void K32WProcessMacHeader(tsRxFrameFormat *aRxFrame)
{
    /* check if frame pending processing is required */
    if (aRxFrame && sIsFpEnabled)
    {
        /* Intra-PAN bit set? */
        if ((kFcfPanidCompression & aRxFrame->sFrameBody.u16FCF) &&
            (kFcfDstAddrNone != (aRxFrame->sFrameBody.u16FCF & kFcfDstAddrMask)))
        {
            /* Read destination PAN ID into source PAN ID: they are the same */
            aRxFrame->sFrameBody.u16SrcPAN = aRxFrame->sFrameBody.u16DestPAN;
        }

        if (K32WIsDataReq(aRxFrame))
        {
            vMMAC_SetTxPend(K32WCheckIfFpRequired(aRxFrame));
        }
        else
        {
            /* Make sure this is set to 0 when we are not dealing with a data request */
            aRxFrame->sFrameBody.u16Unused = 0;
        }
    }
}

/**
 * Check if aRxFrame is a MAC Data Request Command
 *
 * @param[in] aRxFrame     Pointer to the latest received MAC packet
 *
 * @return TRUE 	aRxFrame is a MAC Data Request Frame
 * @return FALSE	aRxFrame is not a MAC Data Request Frame
 */
static bool_t K32WIsDataReq(tsRxFrameFormat *aRxFrame)
{
    bool_t  isDataReq = FALSE;
    uint8_t offset    = 0;

    if (kFcfTypeMacCommand == (aRxFrame->sFrameBody.u16FCF & kFcfMacFrameTypeMask))
    {
        uint8_t secControlField = aRxFrame->sFrameBody.uPayload.au8Byte[0];

        if (secControlField & kSecLevelMask)
        {
            offset += kSecurityControlSize;
        }

        if (!(secControlField & kFrameCounterSuppression))
        {
            offset += kFrameCounterSize;
        }

        switch (secControlField & kKeyIdModeMask)
        {
        case kKeyIdMode0:
            offset += kKeySourceSizeMode0;
            break;

        case kKeyIdMode1:
            offset += kKeySourceSizeMode1 + kKeyIndexSize;
            break;

        case kKeyIdMode2:
            offset += kKeySourceSizeMode2 + kKeyIndexSize;
            break;

        case kKeyIdMode3:
            offset += kKeySourceSizeMode3 + kKeyIndexSize;
            break;
        }

        if (kMacFrameDataReq == aRxFrame->sFrameBody.uPayload.au8Byte[offset])
        {
            isDataReq = TRUE;
        }
    }

    return isDataReq;
}

/**
 * Check if Frame Pending was requested by aPsRxFrame
 * We are in interrupt context.
 *
 * @param[in] aRxFrame  Pointer to a Data Request Frame
 *
 * @return    TRUE 	    Frame Pending bit should be set in the reply
 * @return    FALSE	    Frame Pending bit shouldn't be set in the reply
 *
 */
static bool K32WCheckIfFpRequired(tsRxFrameFormat *aRxFrame)
{
    bool     isFpRequired = FALSE;
    uint16_t panId        = aRxFrame->sFrameBody.u16SrcPAN;
    uint8_t  idx          = 0;

    if (kFcfSrcAddrShort == (aRxFrame->sFrameBody.u16FCF & kFcfSrcAddrMask))
    {
        uint16_t shortAddr = aRxFrame->sFrameBody.uSrcAddr.u16Short;

        for (idx = 0; idx < MAX_FP_ADDRS; idx++)
        {
            if (BIT_TST(sFpShortAddrMask, idx) && (sFpShortAddr[idx].macAddress == shortAddr) &&
                sFpShortAddr[idx].panId == panId)
            {
                isFpRequired = TRUE;
                break;
            }
        }
    }
    else
    {
        for (idx = 0; idx < MAX_FP_ADDRS; idx++)
        {
            if (BIT_TST(sFpExtAddrMask, idx) &&
                (sFpExtAddr[idx].extAddr.u32L == aRxFrame->sFrameBody.uSrcAddr.sExt.u32L) &&
                (sFpExtAddr[idx].extAddr.u32H == aRxFrame->sFrameBody.uSrcAddr.sExt.u32H) &&
                sFpExtAddr[idx].panId == panId)
            {
                isFpRequired = TRUE;
                break;
            }
        }
    }
    /* use the unsued filed to store if the frame was ack'ed with FP and report this back to OT stack */
    aRxFrame->sFrameBody.u16Unused = isFpRequired;

    return isFpRequired;
}

/**
 * Process RX frames in process context and call the upper layer call-backs
 *
 * @param[in] aInstance  Pointer to OT instance
 */
static void K32WProcessRxFrames(otInstance *aInstance)
{
    tsRxFrameFormat *pRxMacFormatFrame = NULL;
    uint32_t         savedInterrupts;

    while ((pRxMacFormatFrame = K32WPopRxRingBuffer(&sRxRing)) != NULL)
    {
        if (OT_ERROR_NONE == K32WFrameConversion(pRxMacFormatFrame, &sRxOtFrame, macToOtFrame))
        {
            otPlatRadioReceiveDone(aInstance, &sRxOtFrame, OT_ERROR_NONE);
        }
        else
        {
            otPlatRadioReceiveDone(aInstance, NULL, OT_ERROR_ABORT);
        }
        memset(pRxMacFormatFrame, 0, sizeof(tsRxFrameFormat));

        MICRO_DISABLE_AND_SAVE_INTERRUPTS(savedInterrupts);
        sRxFrameInProcess = NULL;
        if (sIsRxDisabled)
        {
            K32WEnableReceive(TRUE);
        }
        MICRO_RESTORE_INTERRUPTS(savedInterrupts);
    }
}

/**
 * Process TX frame in process context and call the upper layer call-backs
 *
 * @param[in] aInstance  Pointer to OT instance
 */
static void K32WProcessTxFrame(otInstance *aInstance)
{
    if (sTxDone)
    {
        sTxDone = FALSE;
        if ((sTxOtFrame.mPsdu[kMacFcfLowOffset] & kFcfAckRequest) && (OT_ERROR_NONE == sTxStatus))
        {
            K32WFrameConversion(&sRxAckFrame, &sRxOtFrame, macToOtFrame);
            otPlatRadioTxDone(aInstance, &sTxOtFrame, &sRxOtFrame, sTxStatus);
        }
        else
        {
            otPlatRadioTxDone(aInstance, &sTxOtFrame, NULL, sTxStatus);
        }
    }
}

/**
 * aMacFormatFrame <-> aOtFrame bidirectional conversion
 *
 * @param[in] aMacFrameFormat  Pointer to a MAC Format frame
 * @param[in] aOtFrame         Pointer to OpenThread Frame
 * @param[in] convType         Conversion direction
 *
 * @return    OT_ERROR_NONE      No conversion error
 * @return    OT_ERROR_PARSE     Conversion failed due to parsing error
 */
static otError K32WFrameConversion(tsRxFrameFormat *   aMacFormatFrame,
                                   otRadioFrame *      aOtFrame,
                                   frameConversionType convType)
{
    tsMacFrame *pMacFrame         = &aMacFormatFrame->sFrameBody;
    uint8_t *   pSavedStartRxPSDU = aOtFrame->mPsdu;
    uint8_t *   pPsdu             = aOtFrame->mPsdu;
    uint16_t    aFcf              = 0;
    otError     error             = OT_ERROR_NONE;

    /* frame control field */
    K32WCopy((uint8_t *)&pMacFrame->u16FCF, &pPsdu, kFcfSize, convType);
    aFcf = pMacFrame->u16FCF;

    /* sequence number */
    if (0 == (aFcf & kFcfSeqNbSuppresssion))
    {
        K32WCopy(&pMacFrame->u8SequenceNum, &pPsdu, kDsnSize, convType);
    }

    /* destination Pan Id + address */
    switch (aFcf & kFcfDstAddrMask)
    {
    case kFcfDstAddrNone:
        break;

    case kFcfDstAddrShort:
        K32WCopy((uint8_t *)&pMacFrame->u16DestPAN, &pPsdu, sizeof(otPanId), convType);
        K32WCopy((uint8_t *)&pMacFrame->uDestAddr.u16Short, &pPsdu, sizeof(otShortAddress), convType);
        break;

    case kFcfDstAddrExt:
        K32WCopy((uint8_t *)&pMacFrame->u16DestPAN, &pPsdu, sizeof(otPanId), convType);
        K32WCopy((uint8_t *)&pMacFrame->uDestAddr.sExt.u32L, &pPsdu, sizeof(uint32_t), convType);
        K32WCopy((uint8_t *)&pMacFrame->uDestAddr.sExt.u32H, &pPsdu, sizeof(uint32_t), convType);
        break;

    default:
        error = OT_ERROR_PARSE;
        otEXPECT(false);
    }

    /* Source Pan Id */
    if ((aFcf & kFcfSrcAddrMask) != kFcfSrcAddrNone && (aFcf & kFcfPanidCompression) == 0)
    {
        K32WCopy((uint8_t *)&pMacFrame->u16SrcPAN, &pPsdu, sizeof(otPanId), convType);
    }

    /* Source Address */
    switch (aFcf & kFcfSrcAddrMask)
    {
    case kFcfSrcAddrNone:
        break;

    case kFcfSrcAddrShort:
        K32WCopy((uint8_t *)&pMacFrame->uSrcAddr.u16Short, &pPsdu, sizeof(otShortAddress), convType);
        break;

    case kFcfSrcAddrExt:
        K32WCopy((uint8_t *)&pMacFrame->uSrcAddr.sExt.u32L, &pPsdu, sizeof(uint32_t), convType);
        K32WCopy((uint8_t *)&pMacFrame->uSrcAddr.sExt.u32H, &pPsdu, sizeof(uint32_t), convType);
        break;

    default:
        error = OT_ERROR_PARSE;
        otEXPECT(false);
    }

    if (convType == otToMacFrame)
    {
        pMacFrame->u8PayloadLength = aOtFrame->mLength - (pPsdu - pSavedStartRxPSDU) - kFcfSize;
    }
    else
    {
        aOtFrame->mInfo.mRxInfo.mAckedWithFramePending = (bool)aMacFormatFrame->sFrameBody.u16Unused;
        aOtFrame->mInfo.mRxInfo.mLqi                   = aMacFormatFrame->u8LinkQuality;
        aOtFrame->mInfo.mRxInfo.mRssi                  = i8Radio_GetLastPacketRSSI();
        aOtFrame->mChannel                             = sChannel;
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
#error Time sync requires the timestamp of SFD rather than that of rx done!
#else
        if (otPlatRadioGetPromiscuous(sInstance))
#endif
        {
            aOtFrame->mInfo.mRxInfo.mTimestamp = otPlatAlarmMilliGetNow() * 1000;
        }

        aOtFrame->mLength = pPsdu + (pMacFrame->u8PayloadLength) - pSavedStartRxPSDU + sizeof(pMacFrame->u16FCS);
    }
    K32WCopy((uint8_t *)&pMacFrame->uPayload, &pPsdu, pMacFrame->u8PayloadLength, convType);

exit:
    return error;
}

/**
 * Helper function for aMacFrame <-> aOtFrame bidirectional conversion
 * Copies from/to PSDU to/from specific field
 *
 * @param[in] aFieldValue     Pointer to field Value which needs to be copied/filled
 * @param[in] aPsdu           Pointer to PSDU part which needs to be copied/filled
 * @param[in] copySize        Bytes copied
 * @param[in] convType        Conversion Type
 *
 * @return    OT_ERROR_NONE      No conversion error
 * @return    OT_ERROR_PARSE     Conversion failed due to parsing error
 */
static void K32WCopy(uint8_t *aFieldValue, uint8_t **aPsdu, uint8_t copySize, frameConversionType convType)
{
    if (convType == macToOtFrame)
    {
        memcpy(*aPsdu, aFieldValue, copySize);
    }
    else
    {
        memcpy(aFieldValue, *aPsdu, copySize);
    }

    (*aPsdu) += copySize;
}

/**
 * Function used to init/reset an RX Ring Buffer
 *
 * @param[in] aRxRing         Pointer to an RX Ring Buffer
 */
static void K32WResetRxRingBuffer(rxRingBuffer *aRxRing)
{
    aRxRing->head   = 0;
    aRxRing->tail   = 0;
    aRxRing->isFull = FALSE;
}

/**
 * Function used to push the address of a received frame to the RX Ring buffer.
 * In case the ring buffer is full, the oldest address is overwritten.
 *
 * @param[in] aRxRing             Pointer to the RX Ring Buffer
 * @param[in] rxFrame             The address for a received frame
 */
static void K32WPushRxRingBuffer(rxRingBuffer *aRxRing, tsRxFrameFormat *aRxFrame)
{
    aRxRing->buffer[aRxRing->head] = aRxFrame;
    if (aRxRing->isFull)
    {
        aRxRing->tail = (aRxRing->tail + 1) % K32W_RX_BUFFERS;
    }

    aRxRing->head   = (aRxRing->head + 1) % K32W_RX_BUFFERS;
    aRxRing->isFull = (aRxRing->head == aRxRing->tail);
}

/**
 * Function used to pop the address of a received frame from the RX Ring buffer
 * Process Context: the consumer will pop frames with the interrupts disabled
 *                  to make sure the interrupt context(ISR) doesn't push in
 *                  the middle of a pop.
 *
 * @param[in] aRxRing           Pointer to the RX Ring Buffer
 *
 * @return    tsRxFrameFormat   Pointer to a received frame
 * @return    NULL              In case the RX Ring buffer is empty
 */
static tsRxFrameFormat *K32WPopRxRingBuffer(rxRingBuffer *aRxRing)
{
    tsRxFrameFormat *rxFrame = NULL;
    uint32_t         savedInterrupts;

    MICRO_DISABLE_AND_SAVE_INTERRUPTS(savedInterrupts);
    if (!K32WIsEmptyRxRingBuffer(aRxRing))
    {
        rxFrame         = aRxRing->buffer[aRxRing->tail];
        aRxRing->isFull = FALSE;
        aRxRing->tail   = (aRxRing->tail + 1) % K32W_RX_BUFFERS;
    }
    MICRO_RESTORE_INTERRUPTS(savedInterrupts);

    return rxFrame;
}

/**
 * Function used to check if an RX Ring buffer is empty
 *
 * @param[in] aRxRing           Pointer to the RX Ring Buffer
 *
 * @return    TRUE              RX Ring Buffer is not empty
 * @return    FALSE             RX Ring Buffer is empty
 */
static bool K32WIsEmptyRxRingBuffer(rxRingBuffer *aRxRing)
{
    return (!aRxRing->isFull && (aRxRing->head == aRxRing->tail));
}

/**
 * Function used to get the next frame from aRxFrame pointed by aRxFrameIndex.
 *
 * This is the address where the BBC should DMA a received frame. Once the
 * reception is complete (the RX interrupt fires) this address is added to the
 * ring buffer and the frame can be consumed by the process context.
 *
 * @param[in] aRxFrame            Pointer to an array of tsRxFrameFormat
 * @param[in] aRxFrameIndex       Pointer to the current index in aRxFrame array
 *
 * @return    tsRxFrameFormat     Pointer to a tsRxFrameFormat
 */
static tsRxFrameFormat *K32WGetFrame(tsRxFrameFormat *aRxFrame, uint8_t *aRxFrameIndex)
{
    tsRxFrameFormat *frame = NULL;

    frame = &aRxFrame[*aRxFrameIndex];
    if (frame != sRxFrameInProcess)
    {
        *aRxFrameIndex = (*aRxFrameIndex + 1) % K32W_RX_BUFFERS;
    }
    else
    {
        /* this can happen only if the RX buffer is full and the
         * process context is interrupted right in the middle of
         * starting to process a frame. In this case, wait for
         * the process context to finish the processing then
         * re-enable RX
         */

        sIsRxDisabled = TRUE;
        frame         = NULL;
    }

    return frame;
}

/**
 * Function used to enable the receiving of a frame
 *
 * @param[in] isNewFrameNeeded FALSE in case the current RX buffer can be
 *                             used for a new RX operation.
 *
 */
static void K32WEnableReceive(bool_t isNewFrameNeeded)
{
    tsRxFrameFormat *pRxFrame = NULL;

    if (isNewFrameNeeded)
    {
        if ((pRxFrame = K32WGetFrame(sRxFrame, &sRxFrameIndex)) != NULL)
        {
            pLastRxFrame = pRxFrame;
            vMMAC_StartMacReceive(&pRxFrame->sFrameBody, sRxOpt);
        }
    }
    else
    {
        vMMAC_StartMacReceive(&pLastRxFrame->sFrameBody, sRxOpt);
    }
}

/**
 * Function used for MMAC-RX Restart
 *
 */
static void K32WRestartRx(void)
{
    vMMAC_SetRxProm(((uint32)sRxOpt >> 8) & ALL_FFs_BYTE);
    vMMAC_RxCtlUpdate(((uint32)sRxOpt) & ALL_FFs_BYTE);
}
