/* * Copyright (c) 2019-2023 Beijing Hanwei Innovation Technology Ltd. Co. and * its subsidiaries and affiliates (collectly called MKSEMI). * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form, except as embedded into an MKSEMI * integrated circuit in a product or a software update for such product, * must reproduce the above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of MKSEMI nor the names of its contributors may be used * to endorse or promote products derived from this software without * specific prior written permission. * * 4. This software, with or without modification, must only be used with a * MKSEMI integrated circuit. * * 5. Any software provided in binary form under this license must not be * reverse engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY MKSEMI "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL MKSEMI OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include "se_api.h" #include "mk_trace.h" #include "uart_in_spi.h" #include "mk_gpio.h" #include "mk_spi.h" #define SE_PRINT_DEBUG (0) #if SE_PRINT_DEBUG == 1 #include "mk_uwb.h" #include "RTTDEBUG.h" #endif static uint8_t g_uart_data[1024]; uint16_t passthrough_apdu_to_t1(uint8_t *cmd_buf, uint16_t cmd_len, uint32_t *resp_buf_addr, uint16_t *resp_len) { SE_data cmd_apdu; SE_data rsp_apdu; ESESTATUS status = ESESTATUS_FAILED; // memset(&cmd_apdu, 0x00, sizeof(SE_data)); // memset(&rsp_apdu, 0x00, sizeof(SE_data)); cmd_apdu.p_data = cmd_buf; cmd_apdu.len = cmd_len; status = se_transmit_receive(&cmd_apdu, &rsp_apdu); if (status == ESESTATUS_SUCCESS) { if (rsp_apdu.len > 0) { int i = 0; LOG_INFO(TRACE_MODULE_SE, "[TX][%d]", rsp_apdu.len); while (i < rsp_apdu.len) { LOG_INFO(TRACE_NO_OPTION | TRACE_MODULE_SE, "%02X", rsp_apdu.p_data[i]); i++; } LOG_INFO(TRACE_NO_OPTION | TRACE_MODULE_SE, "\r\n"); } *resp_buf_addr = (uint32_t)rsp_apdu.p_data; *resp_len = rsp_apdu.len; } else { LOG_INFO(TRACE_MODULE_SE, "response status=%d\r\n", status); } return (uint16_t)status; } static void __NO_RETURN cmd_from_uart_to_t1(void) { int len; uint32_t resp_addr; uint16_t resp_len; uint8_t *p_data; #if SE_PRINT_DEBUG == 1 uint32_t timer1, timer2; uint8_t ins; #endif while (1) { do { // memset(g_uart_data, 0, sizeof(g_uart_data)); len = uart_receive_in_spi(g_uart_data, (uint16_t)sizeof(g_uart_data), NULL); if (len >= 5) { break; } } while (1); #if SE_PRINT_DEBUG == 1 timer1 = phy_timer_count_get(); ins = g_uart_data[1]; #endif passthrough_apdu_to_t1(g_uart_data, (uint16_t)len, &resp_addr, (uint16_t *)&resp_len); p_data = (uint8_t *)resp_addr; #if SE_PRINT_DEBUG == 1 timer2 = phy_timer_count_get(); SEGGER_RTT_printf(0, "T %u, ins = %02x\r\n", PHY_TIMER_COUNT_TO_MS(timer2 - timer1), ins); #endif do { if (uart_send_in_spi(p_data, resp_len, NULL) == DRV_OK) { break; } } while (1); }; } int tm_main(void) { if (se_init(ESE_MODE_NORMAL) != ESESTATUS_SUCCESS) { return 0; } uart_in_spi_init(); #if SE_PRINT_DEBUG == 1 RTTInit(); #endif // SEGGER_RTT_printf(0,"\n\rinstall applet\n\r"); cmd_from_uart_to_t1(); // se_deinit (); // return 1; } uint16_t transmit_only_apdu_to_t1(uint8_t *cmd_buf, uint16_t cmd_len) { SE_data cmd_apdu; ESESTATUS status = ESESTATUS_FAILED; // memset(&cmd_apdu, 0x00, sizeof(SE_data)); cmd_apdu.p_data = cmd_buf; cmd_apdu.len = cmd_len; status = se_transmit_only(&cmd_apdu); if (status == ESESTATUS_SUCCESS) { } else { LOG_INFO(TRACE_MODULE_SE, "response status=%d\r\n", status); } return (uint16_t)status; } uint16_t receive_only_resp_from_t1(uint32_t *resp_buf_addr, uint16_t *resp_len) { SE_data rsp_apdu; ESESTATUS status = ESESTATUS_FAILED; status = se_receive_only(&rsp_apdu); /* if (status == ESESTATUS_NO_DATA_TO_RECEIVE) { } else */ if (status == ESESTATUS_SUCCESS) { *resp_buf_addr = (uint32_t)rsp_apdu.p_data; *resp_len = rsp_apdu.len; } else { // LOG_INFO(TRACE_MODULE_SE, "response status=%d\r\n", status); } return (uint16_t)status; } uint8_t uwbs_check_se(uint8_t *p_des_data, uint8_t *p_des_len); uint8_t uwbs_check_se(uint8_t *p_des_data, uint8_t *p_des_len) { struct SPI_CFG_T usr_spi_cfg = { .bit_rate = 1000000, .data_bits = 8, .slave = 0, .clk_phase = 0, .clk_polarity = 0, .ti_mode = 0, .dma_rx = false, .dma_tx = false, .int_rx = false, .int_tx = false, }; // get default AID from SE SE_data cmd_apdu = { .p_data = (uint8_t[]){0x00, 0xA4, 0x04, 0x00, 0x00}, .len = 5, }; SE_data rsp_apdu; uint8_t ret = DRV_OK; if (NULL == p_des_data || NULL == p_des_len) { LOG_ERROR(TRACE_MODULE_SE, "%s: input error!\r\n", __FUNCTION__); *p_des_len = 1; return DRV_ERROR; } // memset(&rsp_apdu, 0, sizeof(rsp_apdu)); if (DRV_OK != (uint8_t)spi_open(SPI_ID1, &usr_spi_cfg)) { LOG_ERROR(TRACE_MODULE_SE, "%s: spi open error!\r\n", __FUNCTION__); *p_des_len = 1; return DRV_ERROR; } gpio_pin_set_dir(IO_PIN_8, GPIO_DIR_OUT, 1); ESESTATUS status = se_init(ESE_MODE_NORMAL); if (status != ESESTATUS_SUCCESS) { ret = (uint8_t)status; LOG_ERROR(TRACE_MODULE_SE, "%s:se init error, ret=%02x\r\n", __FUNCTION__, ret); *p_des_len = 1; goto Errout; } status = se_transmit_receive(&cmd_apdu, &rsp_apdu); if (status != ESESTATUS_SUCCESS) { ret = (uint8_t)status; LOG_ERROR(TRACE_MODULE_SE, "%s: se transceive error! ret=%02x\r\n", __FUNCTION__, ret); *p_des_len = 1; goto Errout; } else { *p_des_len = (uint8_t)rsp_apdu.len; memcpy(p_des_data, rsp_apdu.p_data, rsp_apdu.len); } status = se_init(ESE_MODE_NORMAL); if (status != ESESTATUS_SUCCESS) { LOG_ERROR(TRACE_MODULE_SE, "%s: last se init error, status=%02x\r\n", __FUNCTION__, (uint8_t)status); } if (DRV_OK != spi_close(SPI_ID1)) { LOG_ERROR(TRACE_MODULE_SE, "%s: spi close error!\r\n", __FUNCTION__); *p_des_len = 1; return DRV_ERROR; } return DRV_OK; Errout: se_init(ESE_MODE_NORMAL); spi_close(SPI_ID1); return ret; }