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