/*
 * @author NXP Semiconductors
 * @version 1.0
 * @par License
 *
 * Copyright 2016,2020 NXP
 * SPDX-License-Identifier: Apache-2.0
 *
 * @par History
 *
 *****************************************************************************/
/**
 * @file a71_debug.c
 * @par Description
 * Wrap Debug Mode specific APDU's of A71CH.
*/

#include <stddef.h>
#include <stdio.h>
#include <string.h>

#include "scp.h"
#include "sm_apdu.h"
#include "sm_errors.h"
#include "ax_api.h"
#include "ax_common.h"

#include "a71_debug.h"

/**
* Resets the Secure Module to the initial state.
* @retval ::SW_OK Upon successful execution
*/
U16 A71_DbgReset(void)
{
    U16 rv = 0;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;

    pApdu->cla   = AX_CLA;
    pApdu->ins   = A71XX_INS_ERASE_MODULE;
    pApdu->p1    = P1_RESET;
    pApdu->p2    = P2_RESET;

    AllocateAPDUBuffer(pApdu);
    SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);

    rv = (U16)scp_Transceive(NULL, pApdu, NO_C_MAC_NO_C_ENC_NO_R_MAC_NO_R_ENC);

    // no response data expected
    if (rv == SMCOM_OK)
    {
        // No response data expected
        rv = CheckNoResponseData(pApdu);
    }
    FreeAPDUBuffer(pApdu);
    return rv;
}

/**
* Permanently disables the Debug API.
* @retval ::SW_OK Upon successful execution
*/
U16 A71_DbgDisableDebug(void)
{
    U16 rv = 0;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;

    pApdu->cla   = AX_CLA;
    pApdu->ins   = A71XX_INS_FREEZE_MODULE;
    pApdu->p1    = P1_DISABLE_DEBUG;
    pApdu->p2    = P2_DISABLE_DEBUG;

    AllocateAPDUBuffer(pApdu);
    SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);

    rv = (U16)scp_Transceive(NULL, pApdu, NO_C_MAC_NO_C_ENC_NO_R_MAC_NO_R_ENC);

    // no response data expected
    if (rv == SMCOM_OK)
    {
        // No response data expected
        rv = CheckNoResponseData(pApdu);
    }
    FreeAPDUBuffer(pApdu);
    return rv;
}

/// @cond
static U16 DBG_GetFreeMem(U8 type, S16 *freeMem)
{
    U16 rv = 0;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;
    U8 buf[256];
    U16 bufLen = sizeof(buf);
    U8 isOk;

#ifndef A71_IGNORE_PARAM_CHECK
    if (freeMem == NULL) {
        return ERR_API_ERROR;
    }
#endif

    pApdu->cla   = AX_CLA;
    pApdu->ins   = A71XX_INS_GET_MODULE;
    pApdu->p1    = type;
    pApdu->p2    = P2_FREE_MEMORY;

    AllocateAPDUBuffer(pApdu);
    SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);
    *freeMem = 0;

    rv = (U16)scp_Transceive(NULL, pApdu, NO_C_MAC_NO_C_ENC_NO_R_MAC_NO_R_ENC);
    if (rv == SMCOM_OK)
    {
        rv = smGetSw(pApdu, &isOk);
        if (isOk)
        {
            rv = smApduGetResponseBody(pApdu, buf, &bufLen);
            if (rv == SW_OK)
            {
                if (bufLen == 2)
                {
                    *freeMem = (S16)((buf[0] << 8) + (buf[1] & 0x000000FF));
                }
            }
        }
    }

    FreeAPDUBuffer(pApdu);
    return rv;
}
/// @endcond

/**
* Reports the available persistent memory in the Security Module.
* @retval ::SW_OK Upon successful execution
*/
U16 A71_DbgGetFreePersistentMemory(S16 *freeMem)
{
    return DBG_GetFreeMem(P1_EEPROM, freeMem);
}

/**
* Reports the available transient memory in the Security Module.
* @retval ::SW_OK Upon successful execution
*/
U16 A71_DbgGetFreeTransientMemory(S16 *freeMem)
{
    return DBG_GetFreeMem(P1_TRANSIENT_MEMORY, freeMem);
}

/**
* Invokes data reflection APDU (facilitates link testing). No check of data payload returned
* @param[in] sndBuf
* @param[in] sndBufLen
* @param[in,out] rcvBuf
* @param[in,out] rcvBufLen
* @return
*/
U16 A71_DbgReflect(U8 *sndBuf, U16 sndBufLen, U8 *rcvBuf, U16 *rcvBufLen)
{
    U16 err = 0;
    apdu_t apdu;
    apdu_t * pApdu = (apdu_t *) &apdu;
    U8 isOk = 0x00;

#ifndef A71_IGNORE_PARAM_CHECK
    if ((sndBuf == NULL) || (rcvBuf== NULL) || (rcvBufLen == NULL)) {
        return ERR_API_ERROR;
    }
#endif

    pApdu->cla   = A71XX_CLA;
    pApdu->ins   = A71XX_INS_REFLECT;
    pApdu->p1    = 0x00;
    pApdu->p2    = 0x00;

    AllocateAPDUBuffer(pApdu);
    SetApduHeader(pApdu, USE_STANDARD_APDU_LEN);

    smApduAppendCmdData(pApdu, sndBuf, sndBufLen);

    err = (U16)scp_Transceive(NULL, pApdu, SCP_MODE);
    if (err == SMCOM_OK)
    {
        err = smGetSw( pApdu, &isOk);

        if (isOk)
        {
            if ( (pApdu->rxlen-2) > *rcvBufLen )
            {
                *rcvBufLen = 0;
                return ERR_BUF_TOO_SMALL;
            }
            else
            {
                *rcvBufLen = pApdu->rxlen-2;
                memcpy(rcvBuf, pApdu->pBuf, *rcvBufLen);
            }
        }
    }

    return err;
}
