/*
 *  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.
 *
 */

#include "asf.h"
#include "phy.h"

#include <openthread/config.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/radio.h>

#include "platform-samr21.h"

#include "common/logging.hpp"
#include "utils/code_utils.h"

enum
{
    IEEE802154_FRAME_TYPE_ACK = 0x2,
    IEEE802154_DSN_OFFSET     = 2,
    IEEE802154_FRAME_PENDING  = 1 << 4,
    IEEE802154_ACK_REQUEST    = 1 << 5,
    IEEE802154_ACK_LENGTH     = 5,
    IEEE802154_FCS_SIZE       = 2
};

enum
{
    SAMR21_RECEIVE_SENSITIVITY = -99 // dBm
};

static otRadioFrame sTransmitFrame;
static uint8_t      sTransmitPsdu[OT_RADIO_FRAME_MAX_SIZE + 1];

static otRadioFrame sReceiveFrame;

static bool         sSleep       = false;
static bool         sRxEnable    = false;
static bool         sTxDone      = false;
static bool         sRxDone      = false;
static uint8_t      sTxStatus    = PHY_STATUS_SUCCESS;
static int8_t       sPower       = OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER;
static otRadioState sState       = OT_RADIO_STATE_DISABLED;
static bool         sPromiscuous = false;
static uint8_t      sChannel     = 0xFF;

static int8_t   sMaxRssi;
static uint32_t sScanStartTime;
static uint16_t sScanDuration;
static bool     sStartScan = false;

static int8_t sTxPowerTable[] = {4, 4, 3, 3, 3, 2, 1, 0, -1, -2, -3, -4, -6, -8, -12, -17};

/*******************************************************************************
 * Static
 ******************************************************************************/

static void radioSleep()
{
    if (!sSleep)
    {
        PHY_SetRxState(false);
        PHY_Sleep();

        sSleep    = true;
        sRxEnable = false;
    }
}

static void radioWakeup()
{
    if (sSleep)
    {
        PHY_Wakeup();
    }
}

static void radioRxEnable()
{
    if (sSleep)
    {
        PHY_Wakeup();

        sSleep = false;
    }

    if (!sRxEnable)
    {
        PHY_SetRxState(true);

        sRxEnable = true;
    }
}

static void radioTrxOff()
{
    if (sSleep)
    {
        PHY_Wakeup();
    }
    else if (sRxEnable)
    {
        PHY_SetRxState(false);
    }
}

static void radioRestore()
{
    if (sSleep)
    {
        PHY_Sleep();
    }
    else if (sRxEnable)
    {
        PHY_SetRxState(true);
    }
}

static void setTxPower(uint8_t aPower)
{
    if (aPower != sPower)
    {
        uint8_t i;

        for (i = 0; i < (sizeof(sTxPowerTable) / sizeof(*sTxPowerTable) - 1); i++)
        {
            if (aPower >= sTxPowerTable[i])
            {
                break;
            }
        }

        otLogDebgPlat("Radio set tx power: %d, %d", aPower, i);

        radioTrxOff();

        PHY_SetTxPower(i);

        radioRestore();

        sPower = aPower;
    }
}

static void setChannel(uint8_t aChannel)
{
    if (aChannel != sChannel)
    {
        otLogDebgPlat("Radio set channel: %d", aChannel);

        radioTrxOff();

        PHY_SetChannel(aChannel);

        radioRestore();

        sChannel = aChannel;
    }
}

static void handleEnergyScan()
{
    if (sStartScan)
    {
        if ((otPlatAlarmMilliGetNow() - sScanStartTime) < sScanDuration)
        {
            int8_t curRssi = PHY_EdReq();

            if (curRssi > sMaxRssi)
            {
                sMaxRssi = curRssi;
            }
        }
        else
        {
            sStartScan = false;

            otPlatRadioEnergyScanDone(sInstance, sMaxRssi);

            radioRestore();
        }
    }
}

static void handleRx(void)
{
    if (sRxDone)
    {
        sRxDone = false;

#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
        {
            // The current driver only supports milliseconds resolution.
            sReceiveFrame.mInfo.mRxInfo.mTimestamp = otPlatAlarmMilliGetNow() * 1000;
        }

        // TODO Set this flag only when the packet is really acknowledged with frame pending set.
        // See https://github.com/openthread/openthread/pull/3785
        sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = true;

#if OPENTHREAD_CONFIG_DIAG_ENABLE

        if (otPlatDiagModeGet())
        {
            otPlatDiagRadioReceiveDone(sInstance, &sReceiveFrame, OT_ERROR_NONE);
        }
        else
#endif
        {
            // signal MAC layer for each received frame if promiscous is enabled
            // otherwise only signal MAC layer for non-ACK frame
            if (sPromiscuous || sReceiveFrame.mLength > IEEE802154_ACK_LENGTH)
            {
                otLogDebgPlat("Radio receive done, rssi: %d", sReceiveFrame.mInfo.mRxInfo.mRssi);

                otPlatRadioReceiveDone(sInstance, &sReceiveFrame, OT_ERROR_NONE);
            }
        }
    }
}

static void handleTx(void)
{
    otError      otStatus;
    otRadioFrame ackFrame;
    uint8_t      psdu[IEEE802154_ACK_LENGTH];

    if (sTxDone)
    {
        sTxDone = false;

        // SAMR21 RF doesn't provide ACK frame, generate it manually
        ackFrame.mPsdu    = psdu;
        ackFrame.mLength  = IEEE802154_ACK_LENGTH;
        ackFrame.mPsdu[0] = IEEE802154_FRAME_TYPE_ACK;
        ackFrame.mPsdu[1] = 0;
        ackFrame.mPsdu[2] = sTransmitFrame.mPsdu[IEEE802154_DSN_OFFSET];

        switch (sTxStatus)
        {
        // This is WA to handle pending bit in ACK.
        // SAMR21 phy driver doesn't provide pending status and returns
        // PHY_STATUS_ERROR. This status is returned also RF transaction not yet
        // finished. This situation should not happens. Currently PHY_STATUS_ERROR
        // is only way to detect pending bit.
        case PHY_STATUS_ERROR:
            ackFrame.mPsdu[0] |= IEEE802154_FRAME_PENDING;
            // fall through

        case PHY_STATUS_SUCCESS:
            otStatus = OT_ERROR_NONE;
            break;

        case PHY_STATUS_CHANNEL_ACCESS_FAILURE:
            otStatus = OT_ERROR_CHANNEL_ACCESS_FAILURE;
            break;

        case PHY_STATUS_NO_ACK:
            otStatus = OT_ERROR_NO_ACK;
            break;

        default:
            otStatus = OT_ERROR_ABORT;
            break;
        }

        sState = OT_RADIO_STATE_RECEIVE;

#if OPENTHREAD_CONFIG_DIAG_ENABLE
        if (otPlatDiagModeGet())
        {
            otPlatDiagRadioTransmitDone(sInstance, &sTransmitFrame, otStatus);
        }
        else
#endif
        {
            otLogDebgPlat("Radio transmit done, status: %d", otStatus);

            otRadioFrame *ackFramePtr = &ackFrame;

            if (((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0) || (otStatus != OT_ERROR_NONE))
            {
                ackFramePtr = NULL;
            }

            otPlatRadioTxDone(sInstance, &sTransmitFrame, ackFramePtr, otStatus);
        }
    }
}

/*******************************************************************************
 * PHY
 ******************************************************************************/

void PHY_DataInd(PHY_DataInd_t *ind)
{
    sReceiveFrame.mPsdu               = ind->data;
    sReceiveFrame.mLength             = ind->size + IEEE802154_FCS_SIZE;
    sReceiveFrame.mInfo.mRxInfo.mRssi = ind->rssi;

    sRxDone = true;
}

void PHY_DataConf(uint8_t status)
{
    sTxStatus = status;
    sTxDone   = true;
}

/*******************************************************************************
 * Platform
 ******************************************************************************/
void samr21RadioInit(void)
{
    sTransmitFrame.mLength = 0;
    sTransmitFrame.mPsdu   = sTransmitPsdu + 1;

    sReceiveFrame.mLength = 0;
    sReceiveFrame.mPsdu   = NULL;

    PHY_Init();

    sal_init();
}

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

    PHY_TaskHandler();

    handleEnergyScan();
    handleRx();
    handleTx();
}

uint32_t samr21RadioRandomGet(void)
{
    uint32_t result;

    radioWakeup();

    result = PHY_RandomReq() << 16 | PHY_RandomReq();

    radioRestore();

    return result;
}

void samr21RadioRandomGetTrue(uint8_t *aOutput, uint16_t aOutputLength)
{
    radioWakeup();

    for (uint16_t i = 0; i < aOutputLength / sizeof(uint16_t); i++)
    {
        *((uint16_t *)aOutput) = PHY_RandomReq();
        aOutput += sizeof(uint16_t);
    }

    for (uint16_t i = 0; i < aOutputLength % sizeof(uint16_t); i++)
    {
        aOutput[i] = PHY_RandomReq();
    }

    radioRestore();
}

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

    return sState;
}

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

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

    otLogDebgPlat("Set Pan ID: 0x%04X", aPanId);

    radioTrxOff();

    PHY_SetPanId(aPanId);

    radioRestore();
}

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

    radioTrxOff();

    PHY_SetIEEEAddr((uint8_t *)aAddress);

    radioRestore();
}

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

    radioTrxOff();

    PHY_SetShortAddr(aAddress);

    radioRestore();
}

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

    return (sState != OT_RADIO_STATE_DISABLED);
}

otError otPlatRadioEnable(otInstance *aInstance)
{
    otLogDebgPlat("Radio enable");

    if (!otPlatRadioIsEnabled(aInstance))
    {
        radioSleep();

        sState = OT_RADIO_STATE_SLEEP;
    }

    return OT_ERROR_NONE;
}

otError otPlatRadioDisable(otInstance *aInstance)
{
    otLogDebgPlat("Radio disable");

    if (otPlatRadioIsEnabled(aInstance))
    {
        radioSleep();

        sState = OT_RADIO_STATE_DISABLED;
    }

    return OT_ERROR_NONE;
}

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

    otLogDebgPlat("Radio sleep");

    otError error = OT_ERROR_NONE;

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

    radioSleep();

    sState = OT_RADIO_STATE_SLEEP;

exit:

    return error;
}

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

    otLogDebgPlat("Radio receive, channel: %d", aChannel);

    otError error = OT_ERROR_NONE;

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

    setChannel(aChannel);

    radioRxEnable();

    sState = OT_RADIO_STATE_RECEIVE;

exit:

    return error;
}

otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
{
    otError error = OT_ERROR_NONE;

    OT_UNUSED_VARIABLE(aInstance);

    otLogDebgPlat("Radio transmit");

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

    setChannel(aFrame->mChannel);

    aFrame->mPsdu[-1] = aFrame->mLength - IEEE802154_FCS_SIZE;

    PHY_DataReq(&aFrame->mPsdu[-1]);

    otPlatRadioTxStarted(aInstance, aFrame);

    sState = OT_RADIO_STATE_TRANSMIT;

exit:

    return error;
}

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

    return &sTransmitFrame;
}

int8_t otPlatRadioGetRssi(otInstance *aInstance)
{
    return sMaxRssi;
}

otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
{
    return OT_RADIO_CAPS_ENERGY_SCAN | OT_RADIO_CAPS_TRANSMIT_RETRIES | OT_RADIO_CAPS_ACK_TIMEOUT;
}

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

    return sPromiscuous;
}

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

    sPromiscuous = aEnable;
}

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

otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
{
    return OT_ERROR_NOT_IMPLEMENTED;
}

otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
{
    return OT_ERROR_NOT_IMPLEMENTED;
}

otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
{
    return OT_ERROR_NOT_IMPLEMENTED;
}

otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
{
    return OT_ERROR_NOT_IMPLEMENTED;
}

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

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

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

    sScanStartTime = otPlatAlarmMilliGetNow();
    sScanDuration  = aScanDuration;

    sMaxRssi = PHY_EdReq();

    sStartScan = true;

    return OT_ERROR_NONE;
}

otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
{
    otError error = OT_ERROR_NONE;

    otEXPECT_ACTION(aPower != NULL, error = OT_ERROR_INVALID_ARGS);
    *aPower = sPower;

exit:
    return error;
}

otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
{
    OT_UNUSED_VARIABLE(aInstance);

    otLogDebgPlat("Radio set default TX power: %d", aPower);

    setTxPower(aPower);

    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 SAMR21_RECEIVE_SENSITIVITY;
}
