对比新文件 |
| | |
| | | #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; |
| | | } |