/*
 *  Copyright (c) 2016, 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 radio.cpp
* Platform abstraction for radio communication.
*/

#include <openthread/openthread.h>
#include <openthread/platform/alarm.h>
#include <openthread/platform/radio.h>
#include "utils/code_utils.h"

#include <string.h>

#include "platform-da15000.h"

#include "ad_ftdf.h"
#include "ad_ftdf_phy_api.h"
#include "hw_otpc.h"
#include "hw_rf.h"
#include "internal.h"
#include "regmap.h"

#define FACTORY_TEST_TIMESTAMP      (0x7F8EA08) // Register holds a timestamp of facotry test of a chip
#define FACTORY_TESTER_ID           (0x7F8EA0C) // Register holds test machine ID used for factory test

#define DEFAULT_CHANNEL                 (11)

#define PRIVILEGED_DATA                 __attribute__((section("privileged_data_zi")))

#define IEEE802154_ACK_LENGTH           5
#define IEEE802154_FRAME_TYPE_MASK      0x07
#define IEEE802154_FRAME_TYPE_ACK       0x02
#define IEEE802154_FRAME_PENDING        1 << 4
#define IEEE802154_ACK_REQUEST          1 << 5
#define IEEE802154_DSN_OFFSET           2

#define RSSI_TABLE_SIZE                 8
#define EUI64_TABLE_SIZE                8

enum
{
    DA15000_RECEIVE_SENSITIVITY = -100,  // dBm
};

static void          da15000OtpRead(void);
static uint8_t       eui64[EUI64_TABLE_SIZE] = {0};

static otInstance   *sThreadInstance;
static otRadioState  sRadioState             = OT_RADIO_STATE_DISABLED;
static otRadioFrame  sReceiveFrame;
static otRadioFrame  sTransmitFrame;
static otError       sTransmitStatus;
static bool          sFramePending           = false;
static bool          sRadioPromiscuous       = false;
static bool          sRssiInit               = true;
static uint8_t       sChannel                = DEFAULT_CHANNEL;
static uint8_t       sRssiCtr                = 0;
static uint32_t      sSleepInitDelay         = 0;

static uint8_t       sReceivePsdu[OT_RADIO_FRAME_MAX_SIZE];
static uint8_t       sRssiTable[RSSI_TABLE_SIZE];
static uint8_t       sTransmitPsdu[OT_RADIO_FRAME_MAX_SIZE];

PRIVILEGED_DATA static uint8_t sEnableRX;

static void da15000OtpRead(void)
{
    hw_otpc_init();         // Start clock.
    hw_otpc_disable();      // Make sure it is in standby mode.
    hw_otpc_init();         // Restart clock.
    hw_otpc_manual_read_on(false);

    __DMB();
    uint32_t *factoryTestTimeStamp  = (uint32_t *) FACTORY_TEST_TIMESTAMP;
    uint32_t *factoryTestId         = (uint32_t *) FACTORY_TESTER_ID;
    __DMB();

    eui64[0] = 0x80;    //80-EA-CA is for Dialog Semiconductor
    eui64[1] = 0xEA;
    eui64[2] = 0xCA;
    eui64[3] = (*factoryTestId        >>  8) & 0xff;
    eui64[4] = (*factoryTestTimeStamp >> 24) & 0xff;
    eui64[5] = (*factoryTestTimeStamp >> 16) & 0xff;
    eui64[6] = (*factoryTestTimeStamp >>  8) & 0xff;
    eui64[7] =  *factoryTestTimeStamp        & 0xff;

    hw_otpc_manual_read_off();
    hw_otpc_disable();
}

void da15000RadioInit(void)
{
    /* Wake up power domains */
    REG_CLR_BIT(CRG_TOP, PMU_CTRL_REG, FTDF_SLEEP);

    while (REG_GETF(CRG_TOP, SYS_STAT_REG, FTDF_IS_UP) == 0x0);

    REG_CLR_BIT(CRG_TOP, PMU_CTRL_REG, RADIO_SLEEP);

    while (REG_GETF(CRG_TOP, SYS_STAT_REG, RAD_IS_UP) == 0x0);

    REG_SETF(CRG_TOP, CLK_RADIO_REG, FTDF_MAC_ENABLE, 1);
    REG_SETF(CRG_TOP, CLK_RADIO_REG, FTDF_MAC_DIV, 0);

    hw_rf_poweron();
    hw_rf_system_init();

    ad_ftdf_init_phy_api();

    da15000OtpRead();

    sChannel             = DEFAULT_CHANNEL;
    sTransmitFrame.mPsdu = sTransmitPsdu;
    sReceiveFrame.mPsdu  = sReceivePsdu;
}

void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
{
    (void)aInstance;
    memcpy(aIeeeEui64, eui64, EUI64_TABLE_SIZE);
}

void otPlatRadioSetPanId(otInstance *aInstance, uint16_t panid)
{
    (void)aInstance;

    FTDF_setValue(FTDF_PIB_PAN_ID, &panid);
}

void otPlatRadioSetExtendedAddress(otInstance *aInstance, uint8_t *address)
{
    (void)aInstance;

    FTDF_setValue(FTDF_PIB_EXTENDED_ADDRESS, address);
}

void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t address)
{
    (void)aInstance;

    FTDF_setValue(FTDF_PIB_SHORT_ADDRESS, &address);
}

otError otPlatRadioEnable(otInstance *aInstance)
{
    uint8_t maxRetries;

    otError error = OT_ERROR_NONE;
    otEXPECT_ACTION(sRadioState == OT_RADIO_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);

    sThreadInstance = aInstance;

    sEnableRX = 1;
    FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
    FTDF_setValue(FTDF_PIB_CURRENT_CHANNEL, &sChannel);
    maxRetries = 0;
    FTDF_setValue(FTDF_PIB_MAX_FRAME_RETRIES, &maxRetries);

    FTDF_Bitmap32 options =  FTDF_TRANSPARENT_ENABLE_FCS_GENERATION;
    options |= FTDF_TRANSPARENT_WAIT_FOR_ACK;
    options |= FTDF_TRANSPARENT_AUTO_ACK;

    FTDF_enableTransparentMode(FTDF_TRUE, options);
    otPlatRadioSetPromiscuous(aInstance, false);
    sRadioState = OT_RADIO_STATE_SLEEP;

exit:
    return error;
}

otError otPlatRadioDisable(otInstance *aInstance)
{
    (void)aInstance;
    sEnableRX = 0;
    FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
    ad_ftdf_sleep_when_possible(FTDF_TRUE);

    FTDF_fpprReset();

    sRadioState = OT_RADIO_STATE_DISABLED;

    return OT_ERROR_NONE;
}

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

    return (sRadioState != OT_RADIO_STATE_DISABLED);
}

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

    if (sRadioState == OT_RADIO_STATE_RECEIVE && sSleepInitDelay == 0)
    {
        sSleepInitDelay = otPlatAlarmGetNow();
        return OT_ERROR_NONE;
    }
    else if ((otPlatAlarmGetNow() - sSleepInitDelay) < dg_configINITIAL_SLEEP_DELAY_TIME)
    {
        return OT_ERROR_NONE;
    }

    otError error = OT_ERROR_NONE;
    otEXPECT_ACTION(sRadioState == OT_RADIO_STATE_RECEIVE, error = OT_ERROR_INVALID_STATE);

    sRadioState = OT_RADIO_STATE_SLEEP;
    sEnableRX = 0;
    FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
    ad_ftdf_sleep_when_possible(FTDF_TRUE);

exit:
    return error;
}

otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
{
    (void)aInstance;
    otError error = OT_ERROR_NONE;

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

    ad_ftdf_wake_up();

    sEnableRX = 0;
    FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);

    sChannel = aChannel;
    FTDF_setValue(FTDF_PIB_CURRENT_CHANNEL, &aChannel);

    sEnableRX = 1;
    FTDF_setValue(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
    sRadioState = OT_RADIO_STATE_RECEIVE;

exit:
    return error;
}

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

otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
{
    (void)aInstance;
    otError error = OT_ERROR_NONE;
    uint8_t entry;
    uint8_t entryIdx;

    // check if address already stored

    otEXPECT(!FTDF_fpprLookupShortAddress(aShortAddress, &entry, &entryIdx));

    otEXPECT_ACTION(FTDF_fpprGetFreeShortAddress(&entry, &entryIdx), error = OT_ERROR_NO_BUFS);

    FTDF_fpprSetShortAddress(entry, entryIdx, aShortAddress);
    FTDF_fpprSetShortAddressValid(entry, entryIdx, FTDF_TRUE);

exit:
    return error;

}

otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress)
{
    (void)aInstance;

    uint8_t entry;
    FTDF_ExtAddress addr;
    uint32_t addrL;
    uint64_t addrH;

    addrL = (aExtAddress[3] << 24) | (aExtAddress[2] << 16) | (aExtAddress[1] << 8) | (aExtAddress[0] << 0);
    addrH = (aExtAddress[7] << 24) | (aExtAddress[6] << 16) | (aExtAddress[5] << 8) | (aExtAddress[4] << 0);
    addr = addrL | (addrH << 32);

    // check if address already stored
    otError error = OT_ERROR_NONE;
    otEXPECT(!FTDF_fpprLookupExtAddress(addr, &entry));

    otEXPECT_ACTION(FTDF_fpprGetFreeExtAddress(&entry), error = OT_ERROR_NO_BUFS);

    FTDF_fpprSetExtAddress(entry, addr);
    FTDF_fpprSetExtAddressValid(entry, FTDF_TRUE);

exit:
    return error;
}

otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
{
    (void)aInstance;
    otError error = OT_ERROR_NONE;
    uint8_t entry;
    uint8_t entryIdx;


    otEXPECT_ACTION(FTDF_fpprLookupShortAddress(aShortAddress, &entry, &entryIdx), error = OT_ERROR_NO_ADDRESS);

    FTDF_fpprSetShortAddress(entry, entryIdx, 0);
    FTDF_fpprSetShortAddressValid(entry, entryIdx, FTDF_FALSE);

exit:
    return error;
}

otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress)
{
    (void)aInstance;

    uint8_t entry;
    FTDF_ExtAddress addr;
    uint32_t addrL;
    uint64_t addrH;

    addrL = (aExtAddress[3] << 24) | (aExtAddress[2] << 16) | (aExtAddress[1] << 8) | (aExtAddress[0] << 0);
    addrH = (aExtAddress[7] << 24) | (aExtAddress[6] << 16) | (aExtAddress[5] << 8) | (aExtAddress[4] << 0);
    addr = addrL | (addrH << 32);

    otError error = OT_ERROR_NONE;
    otEXPECT_ACTION(FTDF_fpprLookupExtAddress(addr, &entry), error = OT_ERROR_NO_ADDRESS);

    FTDF_fpprSetExtAddress(entry, 0);
    FTDF_fpprSetExtAddressValid(entry, FTDF_FALSE);

exit:
    return error;
}

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

    uint8_t i, j;

    for (i = 0; i < FTDF_FPPR_TABLE_ENTRIES; i++)
    {
        for (j = 0; j < 4; j++)
        {
            if (FTDF_fpprGetShortAddressValid(i, j))
            {
                FTDF_fpprSetShortAddressValid(i, j, FTDF_FALSE);
            }
        }
    }
}

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

    uint8_t i;

    for (i = 0; i < FTDF_FPPR_TABLE_ENTRIES; i++)
    {
        if (FTDF_fpprGetExtAddressValid(i))
        {
            FTDF_fpprSetExtAddressValid(i, FTDF_FALSE);
        }
    }
}

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

    return &sTransmitFrame;
}

otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
{
    (void)aInstance;

    uint8_t csmaSuppress;

    otError error = OT_ERROR_NONE;
    otEXPECT_ACTION(sRadioState != OT_RADIO_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);

    csmaSuppress = 0;
    ad_ftdf_send_frame_simple(aFrame->mLength, aFrame->mPsdu, aFrame->mChannel, 0, csmaSuppress); //Prio 0 for all.
    sRadioState = OT_RADIO_STATE_TRANSMIT;

exit:
    return error;
}

int8_t otPlatRadioGetRssi(otInstance *aInstance)
{
    (void)aInstance;
    uint16_t result = 0;

    // fill table with same value for init
    if (sRssiInit)
    {
        for (uint8_t i = 0; i < RSSI_TABLE_SIZE; i++)
        {
            sRssiTable[i] = sReceiveFrame.mLqi;
        }

        sRssiInit = false;
    }
    else
    {
        ASSERT_ERROR(sRssiCtr < RSSI_TABLE_SIZE);
        sRssiTable[sRssiCtr] = sReceiveFrame.mLqi;
        sRssiCtr++;

        if (sRssiCtr >= RSSI_TABLE_SIZE)
        {
            sRssiCtr = 0;
        }
    }

    // average of 8 last lqi
    for (uint8_t i = 0; i < RSSI_TABLE_SIZE; i++)
    {
        result += sRssiTable[i];
    }

    result = result / RSSI_TABLE_SIZE;

    // Approximation to dB scale by divide by 9
    return result / 9;
}

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

    return OT_RADIO_CAPS_ACK_TIMEOUT;
}

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

    return sRadioPromiscuous;
}

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

    FTDF_setValue(FTDF_PIB_PROMISCUOUS_MODE, &aEnable);
    sRadioPromiscuous = aEnable;
}

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

    return OT_ERROR_NOT_IMPLEMENTED;
}

void otPlatRadioSetDefaultTxPower(otInstance *aInstance, int8_t aPower)
{
    (void)aInstance;

    FTDF_setValue(FTDF_PIB_TX_POWER, &aPower);
}

void da15000RadioProcess(otInstance *aInstance)
{
    (void)aInstance;
    uint32_t ftdfCe = *FTDF_GET_REG_ADDR(ON_OFF_REGMAP_FTDF_CE);

    FTDF_confirmLmacInterrupt();

    if (ftdfCe & FTDF_MSK_RX_CE)
    {
        FTDF_processRxEvent();
    }

    if (ftdfCe & FTDF_MSK_TX_CE)
    {
        FTDF_processTxEvent();
    }

    volatile uint32_t *ftdfCm = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_FTDF_CM);
    *ftdfCm = FTDF_MSK_TX_CE | FTDF_MSK_RX_CE | FTDF_MSK_SYMBOL_TMR_CE;
}

void FTDF_sendFrameTransparentConfirm(void *handle, FTDF_Bitmap32 status)
{
    (void)handle;

    switch (status)
    {
    case FTDF_TRANSPARENT_SEND_SUCCESSFUL:
        sTransmitStatus = OT_ERROR_NONE;
        break;

    case FTDF_TRANSPARENT_CSMACA_FAILURE:
        sTransmitStatus = OT_ERROR_CHANNEL_ACCESS_FAILURE;
        break;

    case FTDF_TRANSPARENT_NO_ACK:
        sTransmitStatus = OT_ERROR_NO_ACK;
        break;

    default:
        sTransmitStatus = OT_ERROR_ABORT;
        break;
    }

    sRadioState = OT_RADIO_STATE_RECEIVE;

    if (((sTransmitFrame.mPsdu[0] & IEEE802154_ACK_REQUEST) == 0) || sTransmitStatus != OT_ERROR_NONE)
    {
        otPlatRadioTxDone(sThreadInstance, &sTransmitFrame, NULL, sTransmitStatus);
    }
    else
    {
        otPlatRadioTxDone(sThreadInstance, &sTransmitFrame, &sReceiveFrame, sTransmitStatus);
    }
}

void FTDF_rcvFrameTransparent(FTDF_DataLength frameLength,
                              FTDF_Octet     *frame,
                              FTDF_Bitmap32   status,
                              FTDF_LinkQuality lqi)
{
    sReceiveFrame.mChannel   = sChannel;
    sReceiveFrame.mLength    = frameLength;
    sReceiveFrame.mPsdu      = frame;
    sReceiveFrame.mLqi       = lqi;
    sReceiveFrame.mPower     = otPlatRadioGetRssi(sThreadInstance);

    if (sRadioState != OT_RADIO_STATE_DISABLED)
    {
        sRadioState = OT_RADIO_STATE_RECEIVE;
    }

    if ((sReceiveFrame.mPsdu[0]  & IEEE802154_FRAME_TYPE_MASK) == IEEE802154_FRAME_TYPE_ACK &&
        ((sReceiveFrame.mPsdu[0] & IEEE802154_FRAME_PENDING) != 0))
    {
        sFramePending = true;
    }

    if (status == FTDF_TRANSPARENT_RCV_SUCCESSFUL)
    {
        otPlatRadioReceiveDone(sThreadInstance, &sReceiveFrame, OT_ERROR_NONE);
    }
    else
    {
        otPlatRadioReceiveDone(sThreadInstance, &sReceiveFrame, OT_ERROR_ABORT);
    }

}

int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
{
    (void)aInstance;
    return DA15000_RECEIVE_SENSITIVITY;
}
