对比新文件 |
| | |
| | | /* |
| | | * 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 <stdio.h> |
| | | #include <stdlib.h> |
| | | #include <stddef.h> |
| | | #include <stdarg.h> |
| | | #include <errno.h> |
| | | #include <string.h> |
| | | #include <ctype.h> |
| | | #include <stdint.h> |
| | | #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; |
| | | } |