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