From 0eaa992682488604d53a4cbca016c7b0981bcbb4 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Fri, 4 Mar 2016 03:03:49 +0100 Subject: [PATCH] cardem: Add support for USB host based set/clear of card_insert This way the application on the USB host can control whether the emulator should emulate that the card be inserted or not. We change the reset-default back to 'not inserted' (GPIO output 0) and wait for the application to explicitly request this by issuing CEMU_USB_MSGT_DT_CARDINSERT. --- firmware/include_board/owhw/board.h | 2 +- firmware/src_simtrace/cardemu_prot.h | 7 +++++++ firmware/src_simtrace/mode_cardemu.c | 25 ++++++++++++++++++------- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/firmware/include_board/owhw/board.h b/firmware/include_board/owhw/board.h index 2d0825b5..a136c82b 100644 --- a/firmware/include_board/owhw/board.h +++ b/firmware/include_board/owhw/board.h @@ -26,7 +26,7 @@ #define PIN_USIM1_CLK_TC {PIO_PA29, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT} #define PINS_TC_USIM1 PIN_USIM1_IO_TC, PIN_USIM1_CLK_TC -#define PIN_SET_USIM1_PRES {PIO_PA12, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT} +#define PIN_SET_USIM1_PRES {PIO_PA12, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT} #define PIN_USIM1_nRST {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT} #define PIN_USIM1_VCC {PIO_PB3, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT} diff --git a/firmware/src_simtrace/cardemu_prot.h b/firmware/src_simtrace/cardemu_prot.h index 2d41c01b..da490344 100644 --- a/firmware/src_simtrace/cardemu_prot.h +++ b/firmware/src_simtrace/cardemu_prot.h @@ -29,6 +29,7 @@ enum cardemu_usb_msg_type { CEMU_USB_MSGT_DT_SET_ATR, /* Set the ATR stored in simulator */ CEMU_USB_MSGT_DT_GET_STATS, /* request DO_STATS */ CEMU_USB_MSGT_DT_GET_STATUS, /* request DO_STATUS */ + CEMU_USB_MSGT_DT_CARDINSERT, /* insert/remove card */ /* Bulk in pipe */ CEMU_USB_MSGT_DO_RX_DATA, /* TPDU data */ @@ -54,6 +55,12 @@ struct cardemu_usb_msg_hdr { /* incdicates a PB is present and we should continue with RX */ #define CEMU_DATA_F_PB_AND_RX 0x00000008 +/* CEMU_USB_MSGT_DT_CARDINSERT */ +struct cardemu_usb_msg_cardinsert { + struct cardemu_usb_msg_hdr hdr; + uint8_t card_insert; +} __attribute__ ((packed)); + /* CEMU_USB_MSGT_DT_SET_ATR */ struct cardemu_usb_msg_set_atr { struct cardemu_usb_msg_hdr hdr; diff --git a/firmware/src_simtrace/mode_cardemu.c b/firmware/src_simtrace/mode_cardemu.c index 1f46d9b3..65057a3b 100644 --- a/firmware/src_simtrace/mode_cardemu.c +++ b/firmware/src_simtrace/mode_cardemu.c @@ -34,6 +34,7 @@ struct cardem_inst { uint8_t ep_out; uint8_t ep_in; uint8_t ep_int; + const Pin pin_insert; }; static struct cardem_inst cardem_inst[] = { @@ -46,6 +47,7 @@ static struct cardem_inst cardem_inst[] = { .ep_out = PHONE_DATAOUT, .ep_in = PHONE_DATAIN, .ep_int = PHONE_INT, + .pin_insert = PIN_SET_USIM1_PRES, }, #ifdef CARDEMU_SECOND_UART { @@ -57,6 +59,7 @@ static struct cardem_inst cardem_inst[] = { .ep_out = CARDEM_USIM2_DATAOUT, .ep_in = CARDEM_USIM2_DATAIN, .ep_int = CARDEM_USIM2_INT, + .pin_insert = PIN_SET_USIM2_PRES, }, #endif }; @@ -284,26 +287,34 @@ static int llist_count(struct llist_head *head) } /* handle a single USB command as received from the USB host */ -static void dispatch_usb_command(struct req_ctx *rctx, struct card_handle *ch) +static void dispatch_usb_command(struct req_ctx *rctx, struct cardem_inst *ci) { struct cardemu_usb_msg_hdr *hdr; struct cardemu_usb_msg_set_atr *atr; + struct cardemu_usb_msg_cardinsert *cardins; struct llist_head *queue; hdr = (struct cardemu_usb_msg_hdr *) rctx->data; switch (hdr->msg_type) { case CEMU_USB_MSGT_DT_TX_DATA: - queue = card_emu_get_uart_tx_queue(ch); + queue = card_emu_get_uart_tx_queue(ci->ch); req_ctx_set_state(rctx, RCTX_S_UART_TX_PENDING); llist_add_tail(&rctx->list, queue); - card_emu_have_new_uart_tx(ch); + card_emu_have_new_uart_tx(ci->ch); break; case CEMU_USB_MSGT_DT_SET_ATR: atr = (struct cardemu_usb_msg_set_atr *) hdr; - card_emu_set_atr(ch, atr->atr, hdr->data_len); + card_emu_set_atr(ci->ch, atr->atr, hdr->data_len); llist_del(&rctx->list); req_ctx_put(rctx); break; + case CEMU_USB_MSGT_DT_CARDINSERT: + cardins = (struct cardemu_usb_msg_cardinsert *) hdr; + if (cardins->card_insert) + PIO_Set(&ci->pin_insert); + else + PIO_Clear(&ci->pin_insert); + break; case CEMU_USB_MSGT_DT_GET_STATS: case CEMU_USB_MSGT_DT_GET_STATUS: default: @@ -314,12 +325,12 @@ static void dispatch_usb_command(struct req_ctx *rctx, struct card_handle *ch) /* iterate over the queue of incoming USB commands and dispatch/execute * them */ -static void process_any_usb_commands(struct llist_head *main_q, struct card_handle *ch) +static void process_any_usb_commands(struct llist_head *main_q, struct cardem_inst *ci) { struct req_ctx *rctx, *tmp; llist_for_each_entry_safe(rctx, tmp, main_q, list) - dispatch_usb_command(rctx, ch); + dispatch_usb_command(rctx, ci); } /* main loop function, called repeatedly */ @@ -356,7 +367,7 @@ void mode_cardemu_run(void) * host */ queue = &ci->usb_out_queue; usb_refill_from_host(queue, ci->ep_out); - process_any_usb_commands(queue, ci->ch); + process_any_usb_commands(queue, ci); } }