/*
 *  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
 *   This file implements the OpenThread platform abstraction for radio communication.
 *
 */

#include <openthread/config.h>
// NRF tools use #define PACKAGE - for other purposes
// ie: the physical package the chip comes in
// This conflicts with the GNU Autoconf "PACAKGE" define
#undef PACKAGE

#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

#include <common/code_utils.hpp>
#include <platform-config.h>
#include <openthread/platform/logging.h>
#include <openthread/platform/radio.h>
#include <openthread/platform/diag.h>

#include <device/nrf.h>
#include <nrf_drv_radio802154.h>

#include <openthread-core-config.h>
#include <openthread/config.h>
#include <openthread/types.h>

#define SHORT_ADDRESS_SIZE    2
#define EXTENDED_ADDRESS_SIZE 8
#define PENDING_BIT           0x10

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

static bool sDisabled;

static otRadioFrame sReceivedFrames[RADIO_RX_BUFFERS];
static otRadioFrame sTransmitFrame;

#if defined ( __GNUC__ )

static uint8_t      sTransmitPsdu[OT_RADIO_FRAME_MAX_SIZE + 1]
__attribute__((section("nrf_radio_buffer.sTransmiPsdu")));

#elif defined ( __ICCARM__ )

#pragma location="NRF_RADIO_BUFFER"
static uint8_t      sTransmitPsdu[OT_RADIO_FRAME_MAX_SIZE + 1];

#endif

static otRadioFrame sAckFrame;

static uint32_t     sEnergyDetectionTime;
static uint8_t      sEnergyDetectionChannel;
static int8_t       sEnergyDetected;

typedef enum
{
    kPendingEventSleep,                // Requested to enter Sleep state.
    kPendingEventFrameTransmitted,     // Transmitted frame and received ACK (if requested).
    kPendingEventChannelAccessFailure, // Failed to transmit frame (channel busy).
    kPendingEventEnergyDetectionStart, // Requested to start Energy Detection procedure.
    kPendingEventEnergyDetected,       // Energy Detection finished.
} RadioPendingEvents;

static uint32_t sPendingEvents;

static void dataInit(void)
{
    sDisabled = true;

    sTransmitFrame.mPsdu = sTransmitPsdu + 1;

    for (uint32_t i = 0; i < RADIO_RX_BUFFERS; i++)
    {
        sReceivedFrames[i].mPsdu = NULL;
    }

    memset(&sAckFrame, 0, sizeof(sAckFrame));
}

static void convertShortAddress(uint8_t *aTo, uint16_t aFrom)
{
    aTo[0] = (uint8_t) aFrom;
    aTo[1] = (uint8_t)(aFrom >> 8);
}

static inline bool isPendingEventSet(RadioPendingEvents aEvent)
{
    return sPendingEvents & (1UL << aEvent);
}

static void setPendingEvent(RadioPendingEvents aEvent)
{
    volatile uint32_t pendingEvents;
    uint32_t          bitToSet = 1UL << aEvent;

    do
    {
        pendingEvents = __LDREXW((unsigned long volatile *)&sPendingEvents);
        pendingEvents |= bitToSet;
    }
    while (__STREXW(pendingEvents, (unsigned long volatile *)&sPendingEvents));
}

static void resetPendingEvent(RadioPendingEvents aEvent)
{
    volatile uint32_t pendingEvents;
    uint32_t          bitsToRemain = ~(1UL << aEvent);

    do
    {
        pendingEvents = __LDREXW((unsigned long volatile *)&sPendingEvents);
        pendingEvents &= bitsToRemain;
    }
    while (__STREXW(pendingEvents, (unsigned long volatile *)&sPendingEvents));
}

static inline void clearPendingEvents(void)
{
    // Clear pending events that could cause race in the MAC layer.
    volatile uint32_t pendingEvents;
    uint32_t          bitsToRemain = ~(0UL);

    bitsToRemain &= ~(1UL << kPendingEventFrameTransmitted);
    bitsToRemain &= ~(1UL << kPendingEventChannelAccessFailure);

    bitsToRemain &= ~(1UL << kPendingEventSleep);

    do
    {
        pendingEvents = __LDREXW((unsigned long volatile *)&sPendingEvents);
        pendingEvents &= bitsToRemain;
    }
    while (__STREXW(pendingEvents, (unsigned long volatile *)&sPendingEvents));
}

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

    uint64_t factoryAddress = (uint64_t)NRF_FICR->DEVICEID[0] << 32;
    factoryAddress |=  NRF_FICR->DEVICEID[1];

    memcpy(aIeeeEui64, &factoryAddress, sizeof(factoryAddress));
}

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

    uint8_t address[SHORT_ADDRESS_SIZE];
    convertShortAddress(address, aPanId);

    nrf_drv_radio802154_pan_id_set(address);
}

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

    nrf_drv_radio802154_extended_address_set(aExtendedAddress);
}

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

    uint8_t address[SHORT_ADDRESS_SIZE];
    convertShortAddress(address, aShortAddress);

    nrf_drv_radio802154_short_address_set(address);
}

void nrf5RadioInit(void)
{
    dataInit();
    nrf_drv_radio802154_init();
}

void nrf5RadioDeinit(void)
{
    nrf_drv_radio802154_deinit();
}

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

    if (sDisabled)
    {
        return OT_RADIO_STATE_DISABLED;
    }

    switch (nrf_drv_radio802154_state_get())
    {
    case NRF_DRV_RADIO802154_STATE_SLEEP:
        return OT_RADIO_STATE_SLEEP;

    case NRF_DRV_RADIO802154_STATE_RECEIVE:
    case NRF_DRV_RADIO802154_STATE_ENERGY_DETECTION:
        return OT_RADIO_STATE_RECEIVE;

    case NRF_DRV_RADIO802154_STATE_TRANSMIT:
        return OT_RADIO_STATE_TRANSMIT;

    default:
        assert(false); // Make sure driver returned valid state.
    }

    return OT_RADIO_STATE_RECEIVE; // It is the default state. Return it in case of unknown.
}

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

    otError error;

    if (sDisabled)
    {
        sDisabled = false;
        error = OT_ERROR_NONE;
    }
    else
    {
        error = OT_ERROR_INVALID_STATE;
    }

    return error;
}

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

    otError error;

    if (!sDisabled)
    {
        sDisabled = true;
        error = OT_ERROR_NONE;
    }
    else
    {
        error = OT_ERROR_INVALID_STATE;
    }

    return error;
}

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

    return !sDisabled;
}

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

    if (nrf_drv_radio802154_sleep())
    {
        clearPendingEvents();
    }
    else
    {
        clearPendingEvents();
        setPendingEvent(kPendingEventSleep);
    }

    return OT_ERROR_NONE;
}

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

    nrf_drv_radio802154_receive(aChannel);
    clearPendingEvents();

    return OT_ERROR_NONE;
}

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

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

    if (nrf_drv_radio802154_transmit(&aFrame->mPsdu[-1], aFrame->mChannel, aFrame->mPower, true))
    {
        clearPendingEvents();
    }
    else
    {
        clearPendingEvents();
        setPendingEvent(kPendingEventChannelAccessFailure);
    }

    return OT_ERROR_NONE;
}

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

    return &sTransmitFrame;
}

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

    return nrf_drv_radio802154_rssi_last_get();
}

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

    return OT_RADIO_CAPS_ENERGY_SCAN;
}

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

    return nrf_drv_radio802154_promiscuous_get();
}

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

    nrf_drv_radio802154_promiscuous_set(aEnable);
}

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

    nrf_drv_radio802154_auto_pending_bit_set(aEnable);
}

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

    otError error;

    uint8_t shortAddress[SHORT_ADDRESS_SIZE];
    convertShortAddress(shortAddress, aShortAddress);

    if (nrf_drv_radio802154_pending_bit_for_addr_set(shortAddress, false))
    {
        error = OT_ERROR_NONE;
    }
    else
    {
        error = OT_ERROR_NO_BUFS;
    }

    return error;
}

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

    otError error;

    if (nrf_drv_radio802154_pending_bit_for_addr_set(aExtAddress, true))
    {
        error = OT_ERROR_NONE;
    }
    else
    {
        error = OT_ERROR_NO_BUFS;
    }

    return error;
}

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

    otError error;

    uint8_t shortAddress[SHORT_ADDRESS_SIZE];
    convertShortAddress(shortAddress, aShortAddress);

    if (nrf_drv_radio802154_pending_bit_for_addr_clear(shortAddress, false))
    {
        error = OT_ERROR_NONE;
    }
    else
    {
        error = OT_ERROR_NO_ADDRESS;
    }

    return error;
}

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

    otError error;

    if (nrf_drv_radio802154_pending_bit_for_addr_clear(aExtAddress, true))
    {
        error = OT_ERROR_NONE;
    }
    else
    {
        error = OT_ERROR_NO_ADDRESS;
    }

    return error;
}

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

    nrf_drv_radio802154_pending_bit_for_addr_reset(false);
}

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

    nrf_drv_radio802154_pending_bit_for_addr_reset(true);
}

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

    sEnergyDetectionTime    = (uint32_t) aScanDuration * 1000UL;
    sEnergyDetectionChannel = aScanChannel;

    clearPendingEvents();

    if (nrf_drv_radio802154_energy_detection(aScanChannel, sEnergyDetectionTime))
    {
        resetPendingEvent(kPendingEventEnergyDetectionStart);
    }
    else
    {
        setPendingEvent(kPendingEventEnergyDetectionStart);
    }

    return OT_ERROR_NONE;
}

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

    nrf_drv_radio802154_ack_tx_power_set(aPower);
}

void nrf5RadioProcess(otInstance *aInstance)
{
    for (uint32_t i = 0; i < RADIO_RX_BUFFERS; i++)
    {
        if (sReceivedFrames[i].mPsdu != NULL)
        {
#if OPENTHREAD_ENABLE_DIAG

            if (otPlatDiagModeGet())
            {
                otPlatDiagRadioReceiveDone(aInstance, &sReceivedFrames[i], OT_ERROR_NONE);
            }
            else
#endif
            {
                otPlatRadioReceiveDone(aInstance, &sReceivedFrames[i], OT_ERROR_NONE);
            }

            uint8_t *bufferAddress = &sReceivedFrames[i].mPsdu[-1];
            sReceivedFrames[i].mPsdu = NULL;
            nrf_drv_radio802154_buffer_free(bufferAddress);
        }
    }

    if (isPendingEventSet(kPendingEventFrameTransmitted))
    {
#if OPENTHREAD_ENABLE_DIAG

        if (otPlatDiagModeGet())
        {
            otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, OT_ERROR_NONE);
        }
        else
#endif
        {
            otRadioFrame *ackPtr = (sAckFrame.mPsdu == NULL) ? NULL : &sAckFrame;
            otPlatRadioTxDone(aInstance, &sTransmitFrame, ackPtr, OT_ERROR_NONE);
        }

        if (sAckFrame.mPsdu != NULL)
        {
            nrf_drv_radio802154_buffer_free(sAckFrame.mPsdu - 1);
            sAckFrame.mPsdu = NULL;
        }

        resetPendingEvent(kPendingEventFrameTransmitted);
    }

    if (isPendingEventSet(kPendingEventChannelAccessFailure))
    {
#if OPENTHREAD_ENABLE_DIAG

        if (otPlatDiagModeGet())
        {
            otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, OT_ERROR_CHANNEL_ACCESS_FAILURE);
        }
        else
#endif
        {
            otPlatRadioTxDone(aInstance, &sTransmitFrame, NULL, OT_ERROR_CHANNEL_ACCESS_FAILURE);
        }

        resetPendingEvent(kPendingEventChannelAccessFailure);
    }

    if (isPendingEventSet(kPendingEventEnergyDetected))
    {
        otPlatRadioEnergyScanDone(aInstance, sEnergyDetected);

        resetPendingEvent(kPendingEventEnergyDetected);
    }

    if (isPendingEventSet(kPendingEventSleep))
    {
        if (nrf_drv_radio802154_sleep())
        {
            resetPendingEvent(kPendingEventSleep);
        }
    }

    if (isPendingEventSet(kPendingEventEnergyDetectionStart))
    {
        if (nrf_drv_radio802154_energy_detection(sEnergyDetectionChannel, sEnergyDetectionTime))
        {
            resetPendingEvent(kPendingEventEnergyDetectionStart);
        }
    }
}

void nrf_drv_radio802154_received(uint8_t *p_data, int8_t power, int8_t lqi)
{
    otRadioFrame *receivedFrame = NULL;

    for (uint32_t i = 0; i < RADIO_RX_BUFFERS; i++)
    {
        if (sReceivedFrames[i].mPsdu == NULL)
        {
            receivedFrame = &sReceivedFrames[i];
            break;
        }
    }

    assert(receivedFrame != NULL);

    memset(receivedFrame, 0, sizeof(*receivedFrame));

    receivedFrame->mPsdu    = &p_data[1];
    receivedFrame->mLength  = p_data[0];
    receivedFrame->mPower   = power;
    receivedFrame->mLqi     = lqi;
    receivedFrame->mChannel = nrf_drv_radio802154_channel_get();
}

void nrf_drv_radio802154_transmitted(uint8_t *aAckPsdu, int8_t aPower, int8_t aLqi)
{
    if (aAckPsdu == NULL)
    {
        sAckFrame.mPsdu = NULL;
    }
    else
    {
        sAckFrame.mPsdu    = &aAckPsdu[1];
        sAckFrame.mLength  = aAckPsdu[0];
        sAckFrame.mPower   = aPower;
        sAckFrame.mLqi     = aLqi;
        sAckFrame.mChannel = nrf_drv_radio802154_channel_get();
    }

    setPendingEvent(kPendingEventFrameTransmitted);
}

void nrf_drv_radio802154_busy_channel(void)
{
    setPendingEvent(kPendingEventChannelAccessFailure);
}

void nrf_drv_radio802154_energy_detected(int8_t result)
{
    // TODO: Correct RSSI calculation after lab tests.
    sEnergyDetected = 94 - result;

    setPendingEvent(kPendingEventEnergyDetected);
}

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