chen
2024-11-08 cc432b761c884a0bd8e9d83db0a4e26109fc08b1
keil/include/components/se/src/se_api.c
对比新文件
@@ -0,0 +1,303 @@
#include <string.h>
#include "se_api.h"
#include "phdriver.h"
#include "mk_trace.h"
#include "mk_misc.h"
/*********************** Global Variables *************************************/
SE_context g_ese_ctx = {0};
/**
 * First read, use the default length(0xFE).
 * Ohters read, use the IFSD REQ length, if this REQ is success.
 * This memory cannot be freed, unitl this process died.
 */
static void init_se_ctx_from_config(void);
/*****************************************************************************
 * @Function    se_open
 * @Param       init_mode - init mode for normal OMA or download mode
 * @Returns     This function return ESESTATUS_SUCCES (0) in case of success.
 ******************************************************************************/
ESESTATUS se_open(SE_init_mode init_mode)
{
    ESESTATUS status = ESESTATUS_SUCCESS;
    phdriver_open();
    // memset(&g_ese_ctx, 0x00, sizeof(g_ese_ctx));
    init_se_ctx_from_config();
    status = ESESTATUS_SUCCESS;
    g_ese_ctx.ESE_lib_status = ESESTATUS_OPENED;
    return status;
}
/*****************************************************************************
 * @Function    se_init
 * @Param       init_mode - init mode for normal OMA or download mode
 * @Returns     This function return ESESTATUS_SUCCES (0) in case of success.
 ******************************************************************************/
ESESTATUS se_init(SE_init_mode init_mode)
{
    ESESTATUS status = ESESTATUS_SUCCESS;
    short cnt;
    LOG_INFO(TRACE_MODULE_SE, "%s: enter\r\n", __FUNCTION__);
    status = se_open(init_mode);
    if (ESESTATUS_SUCCESS != status)
    {
        LOG_INFO(TRACE_MODULE_SE, "%s: open device failed, errno = %d\r\n", __FUNCTION__, errno);
        goto cleanup;
    }
    cnt = 0;
    do
    {
        status = t1_CIP_req();
        if ((ESESTATUS_SUCCESS == status) && (g_ese_ctx.max_IFSC != 0))
        {
            break;
        }
        cnt++;
        if (cnt >= 1)
        {
            LOG_INFO(TRACE_MODULE_SE, "%s: CIP REQ failed[%d]\r\n", __FUNCTION__, status);
            goto cleanup;
        }
        else
        {
            sys_timer_delay_ms(100);
        }
    } while (1);
    if (!g_ese_ctx.is_T1_ext_hdr_len)
    {
        goto cleanup;
    }
    status = t1_IFSD_req();
    if (ESESTATUS_SUCCESS != status)
    {
        LOG_INFO(TRACE_MODULE_SE, "%s: IFSD REQ failed[%d]\r\n", __FUNCTION__, status);
        status = ESESTATUS_SUCCESS;
        goto cleanup;
    }
cleanup:
    return status;
}
ESESTATUS se_status(void)
{
    return g_ese_ctx.ESE_lib_status;
}
/*****************************************************************************
 * @Function    se_transmit_receive
 * @Param       p_cmd  - Command to eSE
 *              p_resp - Response from eSE (Returned data to be freed after copying)
 * @Returns     On Success ESESTATUS_SUCCESS else an error code.
 *****************************************************************************/
ESESTATUS se_transmit_receive(SE_data *p_cmd, SE_data *p_resp)
{
    ESESTATUS status = ESESTATUS_SUCCESS;
    if ((NULL == p_cmd) || (NULL == p_resp))
    {
        status = ESESTATUS_INVALID_PARAMETER;
        goto cleanup;
    }
    if ((0 == p_cmd->len) || (NULL == p_cmd->p_data))
    {
        LOG_INFO(TRACE_MODULE_SE, "%s: Invalid Parameter no data\r\n", __FUNCTION__);
        status = ESESTATUS_INVALID_PARAMETER;
        goto cleanup;
    }
    else if ((ESESTATUS_CLOSED == g_ese_ctx.ESE_lib_status))
    {
        LOG_INFO(TRACE_MODULE_SE, "%s ESE Not Initialized\r\n", __FUNCTION__);
        status = ESESTATUS_NOT_INITIALISED;
        goto cleanup;
    }
    status = t1_transmit_receive_apdu(p_cmd->p_data, p_cmd->len);
    if (ESESTATUS_SUCCESS == status)
    {
        status = t1_receive_data_and_get(&p_resp->p_data, &p_resp->len);
    }
    else
    {
        LOG_INFO(TRACE_MODULE_SE, "%s failed, status = %d\n\r", __FUNCTION__, status);
        p_resp->p_data = NULL;
    }
    // LOG_INFO(TRACE_MODULE_SE, "%s Processing complete\n\r", __FUNCTION__);
cleanup:
    return status;
}
/*****************************************************************************
 * @Function    se_deinit
 * @Returns     ESESTATUS_SUCCESS Always return ESESTATUS_SUCCESS (0).
 *****************************************************************************/
ESESTATUS se_deinit(void)
{
    ESESTATUS status = ESESTATUS_SUCCESS;
    if ((ESESTATUS_CLOSED == g_ese_ctx.ESE_lib_status))
    {
        LOG_INFO(TRACE_MODULE_SE, " %s ESE Not Initialized \n", __FUNCTION__);
        status = ESESTATUS_NOT_INITIALISED;
        goto cleanup;
    }
    status = t1_prop_end_apdu_req();
    if (ESESTATUS_SUCCESS != status)
    {
        LOG_INFO(TRACE_MODULE_SE, "%s: END_APUD REQ failed[%d]", __FUNCTION__, status);
        LOG_INFO(TRACE_MODULE_SE, "%s: IntfReset (CIP)", __FUNCTION__);
        status = t1_CIP_req();
        if (status != ESESTATUS_SUCCESS)
        {
            LOG_INFO(TRACE_MODULE_SE, "%s: IntfReset Failed", __FUNCTION__);
        }
    }
    else
    {
        LOG_INFO(TRACE_MODULE_SE, "%s: END_APUD REQ success", __FUNCTION__);
    }
cleanup:
    status = se_close();
    return status;
}
/*****************************************************************************
 * @Function    se_close
 * @Returns     This function return ESESTATUS_SUCCES (0) in case of success.
 *****************************************************************************/
ESESTATUS se_close(void)
{
    ESESTATUS status = ESESTATUS_SUCCESS;
    if ((ESESTATUS_CLOSED == g_ese_ctx.ESE_lib_status))
    {
        LOG_INFO(TRACE_MODULE_SE, " %s ESE Not Opened", __FUNCTION__);
        status = ESESTATUS_CLOSED;
        return status;
    }
    status = ESESTATUS_SUCCESS;
    return status;
}
static void init_se_ctx_from_config(void)
{
    g_ese_ctx.max_write_retry_cnt = 10;
    g_ese_ctx.write_retry_time = 1000;
    // WTX is 1s, read error will delay 1ms and retry, so the max retry is 1010
    g_ese_ctx.max_read_retry_cnt = 1010;
    g_ese_ctx.read_retry_time = 1000;
    g_ese_ctx.max_IFSD = 258;
    g_ese_ctx.max_recovery_cnt = 3;
    g_ese_ctx.max_blk_retry_cnt = 3;
    g_ese_ctx.max_wtx_cnt = 30;
}
/******************************************************************
 * @Function    se_transmit_only
 * @Param       p_cmd - Command to eSE
 * @Returns     On Success ESESTATUS_SUCCESS else an error code.
 *****************************************************************/
ESESTATUS se_transmit_only(SE_data *p_cmd)
{
    ESESTATUS status = ESESTATUS_SUCCESS;
    if (NULL == p_cmd) // || (NULL == pRsp))
    {
        status = ESESTATUS_INVALID_PARAMETER;
        goto cleanup;
    }
    if ((0 == p_cmd->len) || (NULL == p_cmd->p_data))
    {
        LOG_INFO(TRACE_MODULE_SE, "%s: Invalid Parameter no data", __FUNCTION__);
        status = ESESTATUS_INVALID_PARAMETER;
        goto cleanup;
    }
    else if ((ESESTATUS_CLOSED == g_ese_ctx.ESE_lib_status))
    {
        LOG_INFO(TRACE_MODULE_SE, "%s ESE Not Initialized", __FUNCTION__);
        status = ESESTATUS_NOT_INITIALISED;
        goto cleanup;
    }
    status = t1_transmit_only_apdu(p_cmd->p_data, p_cmd->len);
    if (ESESTATUS_SUCCESS == status)
    {
    }
    else
    {
        LOG_INFO(TRACE_MODULE_SE, "%s failed, status = %d\n\r", __FUNCTION__, status);
        // pRsp->p_data = NULL;
    }
    // LOG_INFO(TRACE_MODULE_SE, "%s Processing complete\n\r", __FUNCTION__);
cleanup:
    return status;
}
/*****************************************************************************
 * @Function    se_receive_only
 * @Param      p_resp - Response from eSE (Returned data to be freed after copying)
 * @Returns     On Success ESESTATUS_SUCCESS else an error code.
 *****************************************************************************/
ESESTATUS se_receive_only(SE_data *p_resp)
{
    ESESTATUS status = ESESTATUS_SUCCESS;
    if (NULL == p_resp) // || (NULL == pRsp))
    {
        status = ESESTATUS_INVALID_PARAMETER;
        goto cleanup;
    }
    if ((ESESTATUS_CLOSED == g_ese_ctx.ESE_lib_status))
    {
        LOG_INFO(TRACE_MODULE_SE, "%s ESE Not Initialized\r\n", __FUNCTION__);
        status = ESESTATUS_NOT_INITIALISED;
        goto cleanup;
    }
    status = t1_receive_only_apdu();
    if (ESESTATUS_NO_DATA_TO_RECEIVE == status)
    {
        // LOG_INFO(TRACE_MODULE_SE, "%s : NO data from SE, status = %d\r\r", __FUNCTION__, status);
    }
    else if (ESESTATUS_SUCCESS == status)
    {
        status = t1_receive_data_and_get(&p_resp->p_data, &p_resp->len);
        // LOG_INFO(TRACE_MODULE_SE, "%s Processing complete\r\n", __FUNCTION__);
    }
    else
    {
        // LOG_INFO(TRACE_MODULE_SE, "%s failed, status = %d\r\n", __FUNCTION__, status);
        p_resp->p_data = NULL;
    }
cleanup:
    return status;
}