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.
This commit is contained in:
Harald Welte
2016-03-04 03:03:49 +01:00
parent 7abdb51f8f
commit 0eaa992682
3 changed files with 26 additions and 8 deletions

View File

@@ -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}

View File

@@ -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;

View File

@@ -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);
}
}