Fix USB/CCID writes when APDU is longer than 64 bytes.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
parent
23dcc91add
commit
c2eda3ca53
2 changed files with 35 additions and 38 deletions
|
|
@ -92,13 +92,11 @@ typedef struct {
|
||||||
}) ccid_header_t;
|
}) ccid_header_t;
|
||||||
|
|
||||||
uint8_t ccid_status = 1;
|
uint8_t ccid_status = 1;
|
||||||
static bool tx_finished = true;
|
|
||||||
#ifndef ENABLE_EMULATION
|
#ifndef ENABLE_EMULATION
|
||||||
static uint8_t itf_num;
|
static uint8_t itf_num;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static usb_buffer_t ccid_rx[ITF_SC_TOTAL] = {0}, ccid_tx[ITF_SC_TOTAL] = {0};
|
static usb_buffer_t ccid_rx[ITF_SC_TOTAL] = {0}, ccid_tx[ITF_SC_TOTAL] = {0};
|
||||||
static write_status_t last_write_result[ITF_SC_TOTAL] = {0};
|
|
||||||
|
|
||||||
int driver_process_usb_packet_ccid(uint8_t itf, uint16_t rx_read);
|
int driver_process_usb_packet_ccid(uint8_t itf, uint16_t rx_read);
|
||||||
|
|
||||||
|
|
@ -114,7 +112,6 @@ void ccid_write(uint8_t itf, uint16_t size) {
|
||||||
ccid_header_t *ccid_response[ITF_SC_TOTAL];
|
ccid_header_t *ccid_response[ITF_SC_TOTAL];
|
||||||
ccid_header_t *ccid_resp_fast[ITF_SC_TOTAL];
|
ccid_header_t *ccid_resp_fast[ITF_SC_TOTAL];
|
||||||
ccid_header_t *ccid_header[ITF_SC_TOTAL];
|
ccid_header_t *ccid_header[ITF_SC_TOTAL];
|
||||||
ccid_header_t ccid_response_last[ITF_SC_TOTAL];
|
|
||||||
|
|
||||||
uint8_t sc_itf_to_usb_itf(uint8_t itf) {
|
uint8_t sc_itf_to_usb_itf(uint8_t itf) {
|
||||||
if (itf == ITF_SC_CCID) {
|
if (itf == ITF_SC_CCID) {
|
||||||
|
|
@ -158,42 +155,23 @@ void tud_vendor_rx_cb(uint8_t itf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes) {
|
void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes) {
|
||||||
if (sent_bytes) {
|
(void) sent_bytes;
|
||||||
#ifdef ESP_PLATFORM
|
tud_vendor_n_write_flush(itf);
|
||||||
taskENTER_CRITICAL(&mutex);
|
|
||||||
#endif
|
|
||||||
if (last_write_result[itf] == WRITE_PENDING) {
|
|
||||||
last_write_result[itf] = WRITE_SUCCESS;
|
|
||||||
ccid_header_t *lresp = &ccid_response_last[itf];
|
|
||||||
if (lresp->bMessageType != CCID_DATA_BLOCK_RET || lresp->dwLength != 0 || lresp->bSlot != 0 || lresp->abRFU0 != CCID_CMD_STATUS_TIMEEXT) {
|
|
||||||
ccid_tx[itf].r_ptr += (uint16_t)sent_bytes;
|
|
||||||
}
|
|
||||||
if (ccid_tx[itf].r_ptr >= ccid_tx[itf].w_ptr) {
|
|
||||||
ccid_tx[itf].r_ptr = ccid_tx[itf].w_ptr = 0;
|
|
||||||
tx_finished = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef ESP_PLATFORM
|
|
||||||
taskEXIT_CRITICAL(&mutex);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int driver_write_ccid(uint8_t itf, const uint8_t *tx_buffer, uint16_t buffer_size) {
|
int driver_write_ccid(uint8_t itf, const uint8_t *tx_buffer, uint16_t buffer_size) {
|
||||||
if (last_write_result[itf] == WRITE_PENDING) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memcpy(&ccid_response_last[itf], tx_buffer, 10);
|
|
||||||
if (*tx_buffer != 0x81) {
|
if (*tx_buffer != 0x81) {
|
||||||
DEBUG_PAYLOAD(tx_buffer, MIN(buffer_size,64));
|
DEBUG_PAYLOAD(tx_buffer, buffer_size);
|
||||||
}
|
|
||||||
int r = tud_vendor_n_write(itf, tx_buffer, MIN(buffer_size,64));
|
|
||||||
last_write_result[itf] = r > 0 ? WRITE_PENDING : WRITE_FAILED;
|
|
||||||
if (r < buffer_size) {
|
|
||||||
tx_finished = false;
|
|
||||||
}
|
}
|
||||||
|
int r = tud_vendor_n_write(itf, tx_buffer, buffer_size);
|
||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
r = tud_vendor_n_flush(itf);
|
tud_vendor_n_flush(itf);
|
||||||
|
|
||||||
|
ccid_tx[itf].r_ptr += (uint16_t)buffer_size;
|
||||||
|
if (ccid_tx[itf].r_ptr >= ccid_tx[itf].w_ptr) {
|
||||||
|
ccid_tx[itf].r_ptr = ccid_tx[itf].w_ptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_EMULATION
|
#ifdef ENABLE_EMULATION
|
||||||
tud_vendor_tx_cb(itf, r);
|
tud_vendor_tx_cb(itf, r);
|
||||||
|
|
@ -202,10 +180,7 @@ int driver_write_ccid(uint8_t itf, const uint8_t *tx_buffer, uint16_t buffer_siz
|
||||||
}
|
}
|
||||||
|
|
||||||
int ccid_write_fast(uint8_t itf, const uint8_t *buffer, uint16_t buffer_size) {
|
int ccid_write_fast(uint8_t itf, const uint8_t *buffer, uint16_t buffer_size) {
|
||||||
if (tx_finished) {
|
return driver_write_ccid(itf, buffer, buffer_size);
|
||||||
return driver_write_ccid(itf, buffer, buffer_size);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int driver_process_usb_packet_ccid(uint8_t itf, uint16_t rx_read) {
|
int driver_process_usb_packet_ccid(uint8_t itf, uint16_t rx_read) {
|
||||||
|
|
@ -333,7 +308,7 @@ void ccid_task() {
|
||||||
else if (status == CCID_ERR_BLOCKED) {
|
else if (status == CCID_ERR_BLOCKED) {
|
||||||
driver_exec_timeout_ccid(itf);
|
driver_exec_timeout_ccid(itf);
|
||||||
}
|
}
|
||||||
if (ccid_tx[itf].w_ptr > ccid_tx[itf].r_ptr && last_write_result[itf] != WRITE_PENDING) {
|
if (ccid_tx[itf].w_ptr > ccid_tx[itf].r_ptr) {
|
||||||
if (driver_write_ccid(itf, ccid_tx[itf].buffer + ccid_tx[itf].r_ptr, ccid_tx[itf].w_ptr - ccid_tx[itf].r_ptr) > 0) {
|
if (driver_write_ccid(itf, ccid_tx[itf].buffer + ccid_tx[itf].r_ptr, ccid_tx[itf].w_ptr - ccid_tx[itf].r_ptr) > 0) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,9 @@
|
||||||
static uint32_t timeout_counter[ITF_TOTAL] = { 0 };
|
static uint32_t timeout_counter[ITF_TOTAL] = { 0 };
|
||||||
static uint8_t card_locked_itf = ITF_TOTAL; // no locked
|
static uint8_t card_locked_itf = ITF_TOTAL; // no locked
|
||||||
static void (*card_locked_func)(void) = NULL;
|
static void (*card_locked_func)(void) = NULL;
|
||||||
|
#ifndef ENABLE_EMULATION
|
||||||
|
static mutex_t mutex;
|
||||||
|
#endif
|
||||||
|
|
||||||
void usb_set_timeout_counter(uint8_t itf, uint32_t v) {
|
void usb_set_timeout_counter(uint8_t itf, uint32_t v) {
|
||||||
timeout_counter[itf] = v;
|
timeout_counter[itf] = v;
|
||||||
|
|
@ -68,6 +71,7 @@ void usb_init() {
|
||||||
desc_device.idProduct = (data[PHY_PID] << 8) | data[PHY_PID+1];
|
desc_device.idProduct = (data[PHY_PID] << 8) | data[PHY_PID+1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mutex_init(&mutex);
|
||||||
#endif
|
#endif
|
||||||
queue_init(&card_to_usb_q, sizeof(uint32_t), 64);
|
queue_init(&card_to_usb_q, sizeof(uint32_t), 64);
|
||||||
queue_init(&usb_to_card_q, sizeof(uint32_t), 64);
|
queue_init(&usb_to_card_q, sizeof(uint32_t), 64);
|
||||||
|
|
@ -87,12 +91,18 @@ bool is_busy() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void usb_send_event(uint32_t flag) {
|
void usb_send_event(uint32_t flag) {
|
||||||
|
#ifndef ENABLE_EMULATION
|
||||||
|
mutex_enter_blocking(&mutex);
|
||||||
|
#endif
|
||||||
queue_add_blocking(&usb_to_card_q, &flag);
|
queue_add_blocking(&usb_to_card_q, &flag);
|
||||||
if (flag == EV_CMD_AVAILABLE) {
|
if (flag == EV_CMD_AVAILABLE) {
|
||||||
timeout_start();
|
timeout_start();
|
||||||
}
|
}
|
||||||
uint32_t m;
|
uint32_t m;
|
||||||
queue_remove_blocking(&card_to_usb_q , &m);
|
queue_remove_blocking(&card_to_usb_q , &m);
|
||||||
|
#ifndef ENABLE_EMULATION
|
||||||
|
mutex_exit(&mutex);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void low_flash_init();
|
extern void low_flash_init();
|
||||||
|
|
@ -127,9 +137,15 @@ void card_exit() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (queue_is_empty(&card_to_usb_q) == false) {
|
while (queue_is_empty(&card_to_usb_q) == false) {
|
||||||
|
#ifndef ENABLE_EMULATION
|
||||||
|
mutex_enter_blocking(&mutex);
|
||||||
|
#endif
|
||||||
if (queue_try_remove(&card_to_usb_q, &m) == false) {
|
if (queue_try_remove(&card_to_usb_q, &m) == false) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifndef ENABLE_EMULATION
|
||||||
|
mutex_exit(&mutex);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
led_set_blink(BLINK_SUSPENDED);
|
led_set_blink(BLINK_SUSPENDED);
|
||||||
multicore_reset_core1();
|
multicore_reset_core1();
|
||||||
|
|
@ -159,7 +175,13 @@ void usb_task() {
|
||||||
int card_status(uint8_t itf) {
|
int card_status(uint8_t itf) {
|
||||||
if (card_locked_itf == itf) {
|
if (card_locked_itf == itf) {
|
||||||
uint32_t m = 0x0;
|
uint32_t m = 0x0;
|
||||||
|
#ifndef ENABLE_EMULATION
|
||||||
|
mutex_enter_blocking(&mutex);
|
||||||
|
#endif
|
||||||
bool has_m = queue_try_remove(&card_to_usb_q, &m);
|
bool has_m = queue_try_remove(&card_to_usb_q, &m);
|
||||||
|
#ifndef ENABLE_EMULATION
|
||||||
|
mutex_exit(&mutex);
|
||||||
|
#endif
|
||||||
//if (m != 0)
|
//if (m != 0)
|
||||||
// printf("\n ------ M = %lu\n",m);
|
// printf("\n ------ M = %lu\n",m);
|
||||||
if (has_m) {
|
if (has_m) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue