From 7a88a2b8e74780e3d5f5a48fb5d5705fbff2d940 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 23 Aug 2024 19:24:18 +0200 Subject: [PATCH] Improved multicore synchronization. Now they exchange signals and protect areas atomically. Signed-off-by: Pol Henarejos --- pico_keys_sdk_import.cmake | 18 +++--- src/apdu.c | 13 ++-- src/fs/low_flash.c | 2 +- src/main.c | 10 ++- src/usb/ccid/ccid.c | 9 +-- src/usb/emulation/emulation.c | 82 ++++++++++++++++++++----- src/usb/emulation/emulation.h | 112 ++++++++++++++++++++++++++++++---- src/usb/hid/hid.c | 22 ++++--- src/usb/usb.c | 73 +++++++++++----------- src/usb/usb.h | 5 +- src/usb/usb_descriptors.h | 2 + 11 files changed, 238 insertions(+), 110 deletions(-) diff --git a/pico_keys_sdk_import.cmake b/pico_keys_sdk_import.cmake index afad05c..6918298 100644 --- a/pico_keys_sdk_import.cmake +++ b/pico_keys_sdk_import.cmake @@ -195,15 +195,6 @@ if(USB_ITF_HID) ) endif() -if (USB_ITF_CCID) - set(SOURCES ${SOURCES} - ${CMAKE_CURRENT_LIST_DIR}/src/usb/ccid/ccid.c - ) - set(INCLUDES ${INCLUDES} - ${CMAKE_CURRENT_LIST_DIR}/src/usb/ccid - ) -endif() - set(LIBRARIES pico_stdlib pico_multicore @@ -259,7 +250,14 @@ if (ENABLE_EMULATION) ${CMAKE_CURRENT_LIST_DIR}/src/usb/emulation ) else() - + if (USB_ITF_CCID) + set(SOURCES ${SOURCES} + ${CMAKE_CURRENT_LIST_DIR}/src/usb/ccid/ccid.c + ) + set(INCLUDES ${INCLUDES} + ${CMAKE_CURRENT_LIST_DIR}/src/usb/ccid + ) + endif() set(SOURCES ${SOURCES} ${CMAKE_CURRENT_LIST_DIR}/src/usb/usb_descriptors.c ) diff --git a/src/apdu.c b/src/apdu.c index 6b9ea03..9745d7f 100644 --- a/src/apdu.c +++ b/src/apdu.c @@ -22,6 +22,9 @@ #ifdef ESP_PLATFORM #include "esp_compat.h" #endif +#ifdef ENABLE_EMULATION +#include "emulation.h" +#endif uint8_t *rdata_gr = NULL; uint16_t rdata_bk = 0x0; @@ -179,14 +182,13 @@ uint16_t set_res_sw(uint8_t sw1, uint8_t sw2) { return make_uint16_t(sw1, sw2); } -#ifndef ENABLE_EMULATION void apdu_thread(void) { card_init_core1(); while (1) { uint32_t m = 0; -#ifndef ENABLE_EMULATION queue_remove_blocking(&usb_to_card_q, &m); -#endif + uint32_t flag = m + 1; + queue_add_blocking(&card_to_usb_q, &flag); if (m == EV_VERIFY_CMD_AVAILABLE || m == EV_MODIFY_CMD_AVAILABLE) { set_res_sw(0x6f, 0x00); @@ -202,10 +204,8 @@ done: ; apdu_finish(); finished_data_size = apdu_next(); - uint32_t flag = EV_EXEC_FINISHED; -#ifndef ENABLE_EMULATION + flag = EV_EXEC_FINISHED; queue_add_blocking(&card_to_usb_q, &flag); -#endif #ifdef ESP_PLATFORM vTaskDelay(pdMS_TO_TICKS(10)); #endif @@ -219,7 +219,6 @@ done: ; vTaskDelete(NULL); #endif } -#endif void apdu_finish() { apdu.rdata[apdu.rlen] = apdu.sw >> 8; diff --git a/src/fs/low_flash.c b/src/fs/low_flash.c index 16d1714..44801b8 100644 --- a/src/fs/low_flash.c +++ b/src/fs/low_flash.c @@ -38,7 +38,6 @@ #define mode_t unsigned short #define lseek _lseek #include "mman.h" -#include #else #ifdef ESP_PLATFORM #include "esp_compat.h" @@ -58,6 +57,7 @@ const esp_partition_t *part0; #define XIP_BASE 0 int fd_map = 0; uint8_t *map = NULL; +#include #endif #include "pico_keys.h" #include diff --git a/src/main.c b/src/main.c index 611b8c7..af900c1 100644 --- a/src/main.c +++ b/src/main.c @@ -85,14 +85,12 @@ static inline void ws2812_program_init(PIO pio, } #endif -#if defined(ENABLE_EMULATION) -#else -#include "usb.h" -#ifndef ESP_PLATFORM +#if !defined(ESP_PLATFORM) && !defined(ENABLE_EMULATION) #include "hardware/rtc.h" #include "bsp/board.h" #endif -#endif + +#include "usb.h" extern void do_flash(); extern void low_flash_init(); @@ -427,8 +425,8 @@ int main(void) { init_rtc(); -#ifndef ENABLE_EMULATION usb_init(); +#ifndef ENABLE_EMULATION #ifdef ESP_PLATFORM tusb_cfg.string_descriptor[3] = pico_serial_str; if (enable_wcid) { diff --git a/src/usb/ccid/ccid.c b/src/usb/ccid/ccid.c index 097a902..b5bc4ec 100644 --- a/src/usb/ccid/ccid.c +++ b/src/usb/ccid/ccid.c @@ -92,7 +92,9 @@ typedef struct { }) ccid_header_t; uint8_t ccid_status = 1; +#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}; @@ -311,12 +313,6 @@ void driver_exec_finished_cont_ccid(uint8_t itf, uint16_t size_next, uint16_t of } void ccid_task() { -#ifdef ENABLE_EMULATION - uint16_t rx_len = emul_read(ITF_CCID); - if (rx_len) { - tud_vendor_rx_cb(ITF_CCID); - } -#else for (int itf = 0; itf < ITF_SC_TOTAL; itf++) { int status = card_status(sc_itf_to_usb_itf(itf)); if (status == CCID_OK) { @@ -331,7 +327,6 @@ void ccid_task() { } } } -#endif } #ifndef ENABLE_EMULATION diff --git a/src/usb/emulation/emulation.c b/src/usb/emulation/emulation.c index e3346c2..d54fee8 100644 --- a/src/usb/emulation/emulation.c +++ b/src/usb/emulation/emulation.c @@ -54,7 +54,10 @@ extern uint8_t thread_type; extern const uint8_t *cbor_data; extern size_t cbor_len; extern uint8_t cmd; +uint8_t emul_rx[USB_BUFFER_SIZE], emul_tx[USB_BUFFER_SIZE]; +uint16_t emul_rx_size = 0, emul_tx_size = 0; extern int cbor_parse(uint8_t cmd, const uint8_t *data, size_t len); +pthread_t hcore0, hcore1; #ifndef _MSC_VER int msleep(long msec) { @@ -178,6 +181,19 @@ socket_t get_sock_itf(uint8_t itf) { return INVALID_SOCKET; } +uint32_t tud_vendor_n_write(uint8_t itf, const uint8_t *buffer, uint32_t n) { + uint16_t ret = driver_write_emul(ITF_CCID, buffer, (uint16_t)n); + tud_vendor_tx_cb(itf, ret); + return ret; +} + +bool tud_hid_n_report(uint8_t itf, uint8_t report_id, const uint8_t *buffer, uint32_t n) { + (void) itf; + (void) report_id; + uint16_t ret = driver_write_emul(ITF_HID, buffer, (uint16_t)n); + return ret > 0; +} + uint16_t driver_write_emul(uint8_t itf, const uint8_t *buffer, uint16_t buffer_size) { uint16_t size = htons(buffer_size); socket_t sock = get_sock_itf(itf); @@ -207,14 +223,11 @@ void driver_exec_finished_cont_emul(uint8_t itf, uint16_t size_next, uint16_t of #endif #ifdef USB_ITF_CCID if (itf == ITF_CCID) { - driver_exec_finished_cont_ccid(itf, size_next, offset); + driver_write_emul(itf, emul_tx, size_next); } #endif } - -uint8_t emul_rx[USB_BUFFER_SIZE]; -uint16_t emul_rx_size = 0, emul_tx_size = 0; uint16_t emul_read(uint8_t itf) { /* First we look for a client */ #ifdef USB_ITF_HID @@ -239,14 +252,15 @@ uint16_t emul_read(uint8_t itf) { if (hid_client_sock > 0) { close(hid_client_sock); } - hid_client_sock = accept(hid_server_sock, (struct sockaddr *) &client_sockaddr, - &client_socklen); - printf("hid_client connected!\n"); + hid_client_sock = accept(hid_server_sock, (struct sockaddr *) &client_sockaddr, &client_socklen); + if (hid_client_sock != INVALID_SOCKET) { + printf("hid_client connected! %d\n", hid_client_sock); + } } - if (send_buffer_size > 0) { + /*if (send_buffer_size > 0) { last_write_result[itf] = WRITE_PENDING; tud_hid_report_complete_cb(ITF_HID, complete_report, complete_len); - } + }*/ } #endif socket_t sock = get_sock_itf(itf); @@ -263,7 +277,8 @@ uint16_t emul_read(uint8_t itf) { __pragma(warning(pop)) #endif struct timeval timeout; - timeout.tv_sec = 0; + int valread = 0; + timeout.tv_sec = 0; timeout.tv_usec = 0 * 1000; int n = select((int)(sock + 1), &input, NULL, NULL, &timeout); if (n == -1) { @@ -274,14 +289,42 @@ uint16_t emul_read(uint8_t itf) { //printf("read timeout [itf:%d]\n", itf); } if (FD_ISSET(sock, &input)) { - int valread = recv(sock, (char *)&len, sizeof(len), 0); + valread = recv(sock, (char *)&len, sizeof(len), 0); len = ntohs(len); if (len > 0) { while (true) { - valread = recv(sock, (char *)emul_rx, len, 0); + valread = recv(sock, (char *)emul_rx + emul_rx_size, len, 0); if (valread > 0) { - emul_rx_size = valread; - return (uint16_t)valread; + if (len == 1) { + uint8_t c = emul_rx[0]; + if (c == 4) { + driver_write_emul(itf, ccid_atr ? ccid_atr + 1 : NULL, ccid_atr ? ccid_atr[0] : 0); + } + } + else { + switch(itf) { +#ifdef USB_ITF_CCID + case ITF_CCID: { + uint16_t sent = 0; + DEBUG_PAYLOAD(emul_rx, len); + apdu.rdata = emul_tx; + if ((sent = apdu_process(itf, emul_rx, len)) > 0) { + process_apdu(); + apdu_finish(); + } + if (sent > 0) { + uint16_t ret = apdu_next(); + DEBUG_PAYLOAD(apdu.rdata, ret); + driver_write_emul(itf, apdu.rdata, ret); + } + break; + } +#endif + default: + emul_rx_size += valread; + } + } + return (uint16_t)emul_rx_size; } msleep(10); } @@ -289,5 +332,14 @@ uint16_t emul_read(uint8_t itf) { } //else // printf("no input for sock %d - %d\n", itf, sock); - return 0; + return emul_rx_size; +} + +void emul_task() { +#ifdef USB_ITF_CCID + emul_read(ITF_CCID); +#endif +#ifdef USB_ITF_HID + emul_read(ITF_HID); +#endif } diff --git a/src/usb/emulation/emulation.h b/src/usb/emulation/emulation.h index c5a9cc1..82e28db 100644 --- a/src/usb/emulation/emulation.h +++ b/src/usb/emulation/emulation.h @@ -19,11 +19,12 @@ #define _EMULATION_H_ #include -#include -#include "usb.h" +#include #ifdef _MSC_VER #include #endif +#include +#define USB_BUFFER_SIZE 2048 extern int emul_init(char *host, uint16_t port); extern uint8_t emul_rx[USB_BUFFER_SIZE]; extern uint16_t emul_rx_size, emul_tx_size; @@ -49,11 +50,7 @@ static inline uint32_t tud_vendor_n_read(uint8_t itf, uint8_t *buffer, uint32_t return n; } extern void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes); -static inline uint32_t tud_vendor_n_write(uint8_t itf, const uint8_t *buffer, uint32_t n) { - uint16_t ret = driver_write_emul(ITF_CCID, buffer, (uint16_t)n); - tud_vendor_tx_cb(itf, ret); - return ret; -} +extern uint32_t tud_vendor_n_write(uint8_t itf, const uint8_t *buffer, uint32_t n); static inline uint32_t tud_vendor_n_flush(uint8_t itf) { (void) itf; return emul_tx_size; @@ -62,12 +59,101 @@ static inline uint32_t tud_vendor_n_flush(uint8_t itf) { #ifdef USB_ITF_HID extern void tud_hid_report_complete_cb(uint8_t instance, uint8_t const *report, uint16_t len); -static inline bool tud_hid_n_report(uint8_t itf, uint8_t report_id, const uint8_t *buffer, uint32_t n) { - (void) itf; - (void) report_id; - uint16_t ret = driver_write_emul(ITF_HID, buffer, (uint16_t)n); - return ret > 0; -} +extern bool tud_hid_n_report(uint8_t itf, uint8_t report_id, const uint8_t *buffer, uint32_t n); #endif +#include +typedef struct { + pthread_mutex_t mtx; + pthread_cond_t cnd; + size_t size_elem; + size_t num_elem; + size_t max_elem; + uint8_t buf[1024]; + bool is_init; +} queue_t; + +static inline void queue_free(queue_t *a) { + pthread_mutex_destroy(&a->mtx); + pthread_cond_destroy(&a->cnd); + a->is_init = false; +} +static inline void queue_init(queue_t *a, size_t size_elem, size_t max_elem) { + if (a->is_init) { + queue_free(a); + } + pthread_mutex_init(&a->mtx, NULL); + pthread_cond_init(&a->cnd, NULL); + a->size_elem = size_elem; + a->max_elem = max_elem; + a->num_elem = 0; + a->is_init = true; +} +static inline void queue_add_blocking(queue_t *a, const void *b) { + pthread_mutex_lock(&a->mtx); + while (a->num_elem == a->max_elem) { + pthread_cond_wait(&a->cnd, &a->mtx); + } + memcpy(a->buf + a->num_elem * a->size_elem, b, a->size_elem); + a->num_elem++; + pthread_cond_signal(&a->cnd); + pthread_mutex_unlock(&a->mtx); +} +static inline void queue_remove_blocking(queue_t *a, void *b) { + pthread_mutex_lock(&a->mtx); + while (a->num_elem == 0) { + pthread_cond_wait(&a->cnd, &a->mtx); + } + memcpy(b, a->buf, a->size_elem); + memmove(a->buf, a->buf + a->size_elem, a->size_elem * (a->num_elem - 1)); + a->num_elem--; + pthread_cond_signal(&a->cnd); + pthread_mutex_unlock(&a->mtx); +} +static inline int queue_try_add(queue_t *a, const void *b) { + pthread_mutex_lock(&a->mtx); + if (a->num_elem == a->max_elem) { + pthread_mutex_unlock(&a->mtx); + return 0; + } + memcpy(a->buf + a->num_elem * a->size_elem, b, a->size_elem); + a->num_elem++; + pthread_cond_signal(&a->cnd); + pthread_mutex_unlock(&a->mtx); + return 1; +} +static inline int queue_try_remove(queue_t *a, void *b) { + pthread_mutex_lock(&a->mtx); + if (a->num_elem == 0) { + pthread_mutex_unlock(&a->mtx); + return 0; + } + memcpy(b, a->buf, a->size_elem); + memmove(a->buf, a->buf + a->size_elem, a->size_elem * (a->num_elem - 1)); + a->num_elem--; + pthread_cond_signal(&a->cnd); + pthread_mutex_unlock(&a->mtx); + return 1; +} +static inline int queue_is_empty(queue_t *a) { + pthread_mutex_lock(&a->mtx); + bool ret = a->num_elem == 0; + pthread_mutex_unlock(&a->mtx); + return ret; +} +static inline int queue_is_full(queue_t *a) { + pthread_mutex_lock(&a->mtx); + bool ret = a->num_elem == a->max_elem; + pthread_mutex_unlock(&a->mtx); + return ret; +} +static inline void queue_clear(queue_t *a) { + pthread_mutex_lock(&a->mtx); + a->num_elem = 0; + pthread_mutex_unlock(&a->mtx); +} +extern pthread_t hcore0, hcore1; +#define multicore_launch_core1(a) pthread_create(&hcore1, NULL, (void *(*) (void *))a, NULL) +#define multicore_reset_core1() pthread_cancel(hcore1) + #endif // _EMULATION_H_ diff --git a/src/usb/hid/hid.c b/src/usb/hid/hid.c index 2614c5d..fde9c53 100644 --- a/src/usb/hid/hid.c +++ b/src/usb/hid/hid.c @@ -250,7 +250,7 @@ int driver_write_hid(uint8_t itf, const uint8_t *buffer, uint16_t buffer_size) { return 0; } #ifdef ENABLE_EMULATION - tud_hid_report_complete_cb(ITF_HID, buffer, buffer_size); + tud_hid_report_complete_cb(ITF_HID_CTAP, buffer, buffer_size); #endif return MIN(64, buffer_size); } @@ -490,10 +490,8 @@ int driver_process_usb_packet_hid(uint16_t read) { msg_packet.len = msg_packet.current_len = 0; last_packet_time = 0; } - else if ((last_cmd == CTAPHID_CBOR || - last_cmd >= CTAPHID_VENDOR_FIRST) && - (msg_packet.len == 0 || - (msg_packet.len == msg_packet.current_len && msg_packet.len > 0))) { + else if ((last_cmd == CTAPHID_CBOR || last_cmd >= CTAPHID_VENDOR_FIRST) && + (msg_packet.len == 0 || (msg_packet.len == msg_packet.current_len && msg_packet.len > 0))) { thread_type = 2; select_app(fido_aid + 1, fido_aid[0]); if (msg_packet.current_len == msg_packet.len && msg_packet.len > 0) { @@ -523,7 +521,6 @@ int driver_process_usb_packet_hid(uint16_t read) { // echo back anything we received from host //tud_hid_report(0, buffer, bufsize); //printf("END\n"); -#ifndef ENABLE_EMULATION if (apdu_sent > 0) { if (apdu_sent == 1) { card_start(ITF_HID, apdu_thread); @@ -533,7 +530,6 @@ int driver_process_usb_packet_hid(uint16_t read) { } usb_send_event(EV_CMD_AVAILABLE); } -#endif } return apdu_sent; } @@ -584,9 +580,15 @@ void hid_task() { #ifdef ENABLE_EMULATION uint16_t rx_len = emul_read(ITF_HID); if (rx_len) { - tud_hid_set_report_cb(ITF_HID, 0, 0, emul_rx, rx_len); + uint16_t rptr = 0; + while (rx_len > 0) { + tud_hid_set_report_cb(ITF_HID, 0, 0, emul_rx + rptr, 64); + rx_len -= 64; + rptr += 64; + } + emul_rx_size = 0; } -#else +#endif int proc_pkt = 0; if (hid_rx[ITF_HID_CTAP].w_ptr - hid_rx[ITF_HID_CTAP].r_ptr >= 64) { //proc_pkt = driver_process_usb_packet_hid(64); @@ -606,7 +608,7 @@ void hid_task() { } } - +#ifndef ENABLE_EMULATION /* Keyboard ITF */ // Poll every 10ms const uint32_t interval_ms = 10; diff --git a/src/usb/usb.c b/src/usb/usb.c index 577609e..b90784b 100644 --- a/src/usb/usb.c +++ b/src/usb/usb.c @@ -28,6 +28,8 @@ #include "apdu.h" #ifndef ENABLE_EMULATION #include "tusb.h" +#else +#include "emulation.h" #endif // For memcpy @@ -36,16 +38,15 @@ // Device specific functions static uint32_t timeout_counter[ITF_TOTAL] = { 0 }; -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; void usb_set_timeout_counter(uint8_t itf, uint32_t v) { timeout_counter[itf] = v; } -#if !defined(ENABLE_EMULATION) -queue_t usb_to_card_q; -queue_t card_to_usb_q; -#endif +queue_t usb_to_card_q = {0}; +queue_t card_to_usb_q = {0}; #ifndef ENABLE_EMULATION extern tusb_desc_device_t desc_device; @@ -67,10 +68,9 @@ void usb_init() { desc_device.idProduct = (data[PHY_PID] << 8) | data[PHY_PID+1]; } } - +#endif queue_init(&card_to_usb_q, sizeof(uint32_t), 64); queue_init(&usb_to_card_q, sizeof(uint32_t), 64); -#endif } uint32_t timeout = 0; @@ -87,12 +87,12 @@ bool is_busy() { } void usb_send_event(uint32_t flag) { -#if !defined(ENABLE_EMULATION) queue_add_blocking(&usb_to_card_q, &flag); -#endif if (flag == EV_CMD_AVAILABLE) { timeout_start(); } + uint32_t m; + queue_remove_blocking(&card_to_usb_q , &m); } extern void low_flash_init(); @@ -106,9 +106,23 @@ uint16_t finished_data_size = 0; void card_start(uint8_t itf, void (*func)(void)) { timeout_start(); - if (card_locked_itf != itf) { -#ifndef ENABLE_EMULATION - uint32_t m = 0; + if (card_locked_itf != itf || card_locked_func != func) { + if (card_locked_itf != ITF_TOTAL || card_locked_func != NULL) { + card_exit(); + } + if (func) { + multicore_launch_core1(func); + } + led_set_blink(BLINK_MOUNTED); + card_locked_itf = itf; + card_locked_func = func; + } +} + +void card_exit() { + if (card_locked_itf != ITF_TOTAL || card_locked_func != NULL) { + usb_send_event(EV_EXIT); + uint32_t m; while (queue_is_empty(&usb_to_card_q) == false) { if (queue_try_remove(&usb_to_card_q, &m) == false) { break; @@ -119,37 +133,25 @@ void card_start(uint8_t itf, void (*func)(void)) { break; } } + led_set_blink(BLINK_SUSPENDED); multicore_reset_core1(); - if (func) { - multicore_launch_core1(func); - } - led_set_blink(BLINK_MOUNTED); -#else - (void)func; -#endif - card_locked_itf = itf; - } -} - -void card_exit() { -#ifndef ENABLE_EMULATION - uint32_t flag = EV_EXIT; - queue_try_add(&usb_to_card_q, &flag); - led_set_blink(BLINK_SUSPENDED); - multicore_reset_core1(); #ifdef ESP_PLATFORM - hcore1 = NULL; + hcore1 = NULL; #endif + } card_locked_itf = ITF_TOTAL; -#endif + card_locked_func = NULL; } extern void hid_task(); extern void ccid_task(); +extern void emul_task(); void usb_task() { -#ifndef ENABLE_EMULATION #ifdef USB_ITF_HID hid_task(); #endif +#ifdef ENABLE_EMULATION + emul_task(); +#else #ifdef USB_ITF_CCID ccid_task(); #endif @@ -157,7 +159,6 @@ void usb_task() { } int card_status(uint8_t itf) { -#ifndef ENABLE_EMULATION if (card_locked_itf == itf) { uint32_t m = 0x0; bool has_m = queue_try_remove(&card_to_usb_q, &m); @@ -167,13 +168,14 @@ int card_status(uint8_t itf) { if (m == EV_EXEC_FINISHED) { timeout_stop(); led_set_blink(BLINK_MOUNTED); - card_locked_itf = ITF_TOTAL; return CCID_OK; } +#ifndef ENABLE_EMULATION else if (m == EV_PRESS_BUTTON) { uint32_t flag = wait_button() ? EV_BUTTON_TIMEOUT : EV_BUTTON_PRESSED; queue_try_add(&usb_to_card_q, &flag); } +#endif return CCID_ERR_FILE_NOT_FOUND; } else { @@ -185,8 +187,5 @@ int card_status(uint8_t itf) { } } } -#else - (void) itf; -#endif return CCID_ERR_FILE_NOT_FOUND; } diff --git a/src/usb/usb.h b/src/usb/usb.h index e2596ad..4cb079d 100644 --- a/src/usb/usb.h +++ b/src/usb/usb.h @@ -19,7 +19,7 @@ #define _USB_H_ #if defined(ENABLE_EMULATION) -#include +#include "emulation.h" #elif defined(ESP_PLATFORM) #include "esp_compat.h" #else @@ -77,11 +77,8 @@ enum { }; extern void usb_task(); -#ifndef ENABLE_EMULATION extern queue_t usb_to_card_q; extern queue_t card_to_usb_q; -#endif -extern uint8_t card_locked_itf; extern void card_start(uint8_t, void (*func)(void)); extern void card_exit(); diff --git a/src/usb/usb_descriptors.h b/src/usb/usb_descriptors.h index f89d7ec..ba90cbc 100644 --- a/src/usb/usb_descriptors.h +++ b/src/usb/usb_descriptors.h @@ -18,6 +18,8 @@ #ifndef USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_ +#include "compat.h" + PACK( struct ccid_class_descriptor { uint8_t bLength;