/*
 *  Copyright (c) 2016-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 <string.h>

#include <openthread/platform/diag.h>
#include <openthread/platform/radio.h>

#include "utils/code_utils.h"

#include "radio_qorvo.h"

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

enum
{
    IEEE802154_MIN_LENGTH      = 5,
    IEEE802154_MAX_LENGTH      = 127,
    IEEE802154_ACK_LENGTH      = 5,
    IEEE802154_FRAME_TYPE_MASK = 0x7,
    IEEE802154_FRAME_TYPE_ACK  = 0x2,
    IEEE802154_FRAME_PENDING   = 1 << 4,
    IEEE802154_ACK_REQUEST     = 1 << 5,
    IEEE802154_DSN_OFFSET      = 2,
};

enum
{
    QORVO_RSSI_OFFSET  = 73,
    QORVO_CRC_BIT_MASK = 0x80,
    QORVO_LQI_BIT_MASK = 0x7f,
};

extern otRadioFrame sTransmitFrame;

static otRadioState sState;
static otInstance * pQorvoInstance;

typedef struct otCachedSettings_s
{
    uint16_t panid;
} otCachedSettings_t;

static otCachedSettings_t otCachedSettings;

static uint8_t sScanstate         = 0;
static int8_t  sLastReceivedPower = 127;

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

    qorvoRadioGetIeeeEui64(aIeeeEui64);
}

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

    qorvoRadioSetPanId(panid);
    otCachedSettings.panid = panid;
}

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

    qorvoRadioSetExtendedAddress(address->m8);
}

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

    qorvoRadioSetShortAddress(address);
}

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

    return (sState != OT_RADIO_STATE_DISABLED);
}

otError otPlatRadioEnable(otInstance *aInstance)
{
    pQorvoInstance = aInstance;
    memset(&otCachedSettings, 0x00, sizeof(otCachedSettings_t));

    if (!otPlatRadioIsEnabled(aInstance))
    {
        sState = OT_RADIO_STATE_SLEEP;
    }

    return OT_ERROR_NONE;
}

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

    otEXPECT(otPlatRadioIsEnabled(aInstance));

    if (sState == OT_RADIO_STATE_RECEIVE)
    {
        qorvoRadioSetRxOnWhenIdle(false);
    }

    sState = OT_RADIO_STATE_DISABLED;

exit:
    return OT_ERROR_NONE;
}

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

    otError error = OT_ERROR_INVALID_STATE;

    if (sState == OT_RADIO_STATE_RECEIVE)
    {
        qorvoRadioSetRxOnWhenIdle(false);
        error  = OT_ERROR_NONE;
        sState = OT_RADIO_STATE_SLEEP;
    }

    return error;
}

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

    pQorvoInstance = aInstance;

    if ((sState != OT_RADIO_STATE_DISABLED) && (sScanstate == 0))
    {
        qorvoRadioSetCurrentChannel(aChannel);
        error = OT_ERROR_NONE;
    }

    if (sState == OT_RADIO_STATE_SLEEP)
    {
        qorvoRadioSetRxOnWhenIdle(true);
        error  = OT_ERROR_NONE;
        sState = OT_RADIO_STATE_RECEIVE;
    }

    return error;
}

otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aPacket)
{
    otError err = OT_ERROR_NONE;

    pQorvoInstance = aInstance;

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

    err = qorvoRadioTransmit(aPacket);

exit:
    return err;
}

void cbQorvoRadioTransmitDone(otRadioFrame *aPacket, bool aFramePending, otError aError)
{
    // TODO: pass received ACK frame instead of generating one.
    otRadioFrame ackFrame;
    uint8_t      psdu[IEEE802154_ACK_LENGTH];

    ackFrame.mPsdu    = psdu;
    ackFrame.mLength  = IEEE802154_ACK_LENGTH;
    ackFrame.mPsdu[0] = IEEE802154_FRAME_TYPE_ACK;

    if (aFramePending)
    {
        ackFrame.mPsdu[0] |= IEEE802154_FRAME_PENDING;
    }

    ackFrame.mPsdu[1] = 0;
    ackFrame.mPsdu[2] = aPacket->mPsdu[IEEE802154_DSN_OFFSET];

    otPlatRadioTxDone(pQorvoInstance, aPacket, &ackFrame, aError);
}

void cbQorvoRadioReceiveDone(otRadioFrame *aPacket, otError aError)
{
    if (aError == OT_ERROR_NONE)
    {
        sLastReceivedPower = aPacket->mInfo.mRxInfo.mRssi;
    }

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

    otPlatRadioReceiveDone(pQorvoInstance, aPacket, aError);
}

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

    return &sTransmitFrame;
}

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

    return sLastReceivedPower;
}

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

    return OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_ENERGY_SCAN | OT_RADIO_CAPS_TRANSMIT_RETRIES;
}

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

    return false;
}

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

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

    qorvoRadioEnableSrcMatch(aEnable);
}

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

    return qorvoRadioAddSrcMatchShortEntry(aShortAddress, otCachedSettings.panid);
}

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

    return qorvoRadioAddSrcMatchExtEntry(aExtAddress->m8, otCachedSettings.panid);
}

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

    return qorvoRadioClearSrcMatchShortEntry(aShortAddress, otCachedSettings.panid);
}

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

    return qorvoRadioClearSrcMatchExtEntry(aExtAddress->m8, otCachedSettings.panid);
}

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

    /* clear both short and extended addresses here */
    qorvoRadioClearSrcMatchEntries();
}

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

    /* not implemented */
    /* assumes clearing of short and extended entries is done simultaniously by the openthread stack */
}

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

    sScanstate = 1;
    return qorvoRadioEnergyScan(aScanChannel, aScanDuration);
}

void cbQorvoRadioEnergyScanDone(int8_t aEnergyScanMaxRssi)
{
    sScanstate = 0;
    otPlatRadioEnergyScanDone(pQorvoInstance, aEnergyScanMaxRssi);
}

otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
{
    // TODO: Create a proper implementation for this driver.
    OT_UNUSED_VARIABLE(aInstance);
    OT_UNUSED_VARIABLE(aPower);

    return OT_ERROR_NOT_IMPLEMENTED;
}

otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
{
    // TODO: Create a proper implementation for this driver.
    OT_UNUSED_VARIABLE(aInstance);
    OT_UNUSED_VARIABLE(aPower);

    return OT_ERROR_NOT_IMPLEMENTED;
}

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