/*
|
* 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;
|
}
|