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;
|
||||
|
||||
uint8_t ccid_status = 1;
|
||||
static bool tx_finished = true;
|
||||
#ifndef ENABLE_EMULATION
|
||||
static uint8_t itf_num;
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -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_resp_fast[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) {
|
||||
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) {
|
||||
if (sent_bytes) {
|
||||
#ifdef ESP_PLATFORM
|
||||
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
|
||||
}
|
||||
(void) sent_bytes;
|
||||
tud_vendor_n_write_flush(itf);
|
||||
}
|
||||
|
||||
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) {
|
||||
DEBUG_PAYLOAD(tx_buffer, MIN(buffer_size,64));
|
||||
}
|
||||
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;
|
||||
DEBUG_PAYLOAD(tx_buffer, buffer_size);
|
||||
}
|
||||
int r = tud_vendor_n_write(itf, tx_buffer, buffer_size);
|
||||
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
|
||||
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) {
|
||||
if (tx_finished) {
|
||||
return driver_write_ccid(itf, buffer, buffer_size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@
|
|||
static uint32_t timeout_counter[ITF_TOTAL] = { 0 };
|
||||
static uint8_t card_locked_itf = ITF_TOTAL; // no locked
|
||||
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) {
|
||||
timeout_counter[itf] = v;
|
||||
|
|
@ -68,6 +71,7 @@ void usb_init() {
|
|||
desc_device.idProduct = (data[PHY_PID] << 8) | data[PHY_PID+1];
|
||||
}
|
||||
}
|
||||
mutex_init(&mutex);
|
||||
#endif
|
||||
queue_init(&card_to_usb_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) {
|
||||
#ifndef ENABLE_EMULATION
|
||||
mutex_enter_blocking(&mutex);
|
||||
#endif
|
||||
queue_add_blocking(&usb_to_card_q, &flag);
|
||||
if (flag == EV_CMD_AVAILABLE) {
|
||||
timeout_start();
|
||||
}
|
||||
uint32_t m;
|
||||
queue_remove_blocking(&card_to_usb_q , &m);
|
||||
#ifndef ENABLE_EMULATION
|
||||
mutex_exit(&mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void low_flash_init();
|
||||
|
|
@ -127,9 +137,15 @@ void card_exit() {
|
|||
}
|
||||
}
|
||||
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) {
|
||||
break;
|
||||
}
|
||||
#ifndef ENABLE_EMULATION
|
||||
mutex_exit(&mutex);
|
||||
#endif
|
||||
}
|
||||
led_set_blink(BLINK_SUSPENDED);
|
||||
multicore_reset_core1();
|
||||
|
|
@ -159,7 +175,13 @@ void usb_task() {
|
|||
int card_status(uint8_t itf) {
|
||||
if (card_locked_itf == itf) {
|
||||
uint32_t m = 0x0;
|
||||
#ifndef ENABLE_EMULATION
|
||||
mutex_enter_blocking(&mutex);
|
||||
#endif
|
||||
bool has_m = queue_try_remove(&card_to_usb_q, &m);
|
||||
#ifndef ENABLE_EMULATION
|
||||
mutex_exit(&mutex);
|
||||
#endif
|
||||
//if (m != 0)
|
||||
// printf("\n ------ M = %lu\n",m);
|
||||
if (has_m) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue