mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-20 07:18:33 +03:00
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:
@@ -26,7 +26,7 @@
|
|||||||
#define PIN_USIM1_CLK_TC {PIO_PA29, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
#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 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_nRST {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||||
#define PIN_USIM1_VCC {PIO_PB3, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
|
#define PIN_USIM1_VCC {PIO_PB3, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
|
||||||
|
|
||||||
|
|||||||
@@ -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_SET_ATR, /* Set the ATR stored in simulator */
|
||||||
CEMU_USB_MSGT_DT_GET_STATS, /* request DO_STATS */
|
CEMU_USB_MSGT_DT_GET_STATS, /* request DO_STATS */
|
||||||
CEMU_USB_MSGT_DT_GET_STATUS, /* request DO_STATUS */
|
CEMU_USB_MSGT_DT_GET_STATUS, /* request DO_STATUS */
|
||||||
|
CEMU_USB_MSGT_DT_CARDINSERT, /* insert/remove card */
|
||||||
|
|
||||||
/* Bulk in pipe */
|
/* Bulk in pipe */
|
||||||
CEMU_USB_MSGT_DO_RX_DATA, /* TPDU data */
|
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 */
|
/* incdicates a PB is present and we should continue with RX */
|
||||||
#define CEMU_DATA_F_PB_AND_RX 0x00000008
|
#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 */
|
/* CEMU_USB_MSGT_DT_SET_ATR */
|
||||||
struct cardemu_usb_msg_set_atr {
|
struct cardemu_usb_msg_set_atr {
|
||||||
struct cardemu_usb_msg_hdr hdr;
|
struct cardemu_usb_msg_hdr hdr;
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ struct cardem_inst {
|
|||||||
uint8_t ep_out;
|
uint8_t ep_out;
|
||||||
uint8_t ep_in;
|
uint8_t ep_in;
|
||||||
uint8_t ep_int;
|
uint8_t ep_int;
|
||||||
|
const Pin pin_insert;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct cardem_inst cardem_inst[] = {
|
static struct cardem_inst cardem_inst[] = {
|
||||||
@@ -46,6 +47,7 @@ static struct cardem_inst cardem_inst[] = {
|
|||||||
.ep_out = PHONE_DATAOUT,
|
.ep_out = PHONE_DATAOUT,
|
||||||
.ep_in = PHONE_DATAIN,
|
.ep_in = PHONE_DATAIN,
|
||||||
.ep_int = PHONE_INT,
|
.ep_int = PHONE_INT,
|
||||||
|
.pin_insert = PIN_SET_USIM1_PRES,
|
||||||
},
|
},
|
||||||
#ifdef CARDEMU_SECOND_UART
|
#ifdef CARDEMU_SECOND_UART
|
||||||
{
|
{
|
||||||
@@ -57,6 +59,7 @@ static struct cardem_inst cardem_inst[] = {
|
|||||||
.ep_out = CARDEM_USIM2_DATAOUT,
|
.ep_out = CARDEM_USIM2_DATAOUT,
|
||||||
.ep_in = CARDEM_USIM2_DATAIN,
|
.ep_in = CARDEM_USIM2_DATAIN,
|
||||||
.ep_int = CARDEM_USIM2_INT,
|
.ep_int = CARDEM_USIM2_INT,
|
||||||
|
.pin_insert = PIN_SET_USIM2_PRES,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -284,26 +287,34 @@ static int llist_count(struct llist_head *head)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* handle a single USB command as received from the USB host */
|
/* 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_hdr *hdr;
|
||||||
struct cardemu_usb_msg_set_atr *atr;
|
struct cardemu_usb_msg_set_atr *atr;
|
||||||
|
struct cardemu_usb_msg_cardinsert *cardins;
|
||||||
struct llist_head *queue;
|
struct llist_head *queue;
|
||||||
|
|
||||||
hdr = (struct cardemu_usb_msg_hdr *) rctx->data;
|
hdr = (struct cardemu_usb_msg_hdr *) rctx->data;
|
||||||
switch (hdr->msg_type) {
|
switch (hdr->msg_type) {
|
||||||
case CEMU_USB_MSGT_DT_TX_DATA:
|
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);
|
req_ctx_set_state(rctx, RCTX_S_UART_TX_PENDING);
|
||||||
llist_add_tail(&rctx->list, queue);
|
llist_add_tail(&rctx->list, queue);
|
||||||
card_emu_have_new_uart_tx(ch);
|
card_emu_have_new_uart_tx(ci->ch);
|
||||||
break;
|
break;
|
||||||
case CEMU_USB_MSGT_DT_SET_ATR:
|
case CEMU_USB_MSGT_DT_SET_ATR:
|
||||||
atr = (struct cardemu_usb_msg_set_atr *) hdr;
|
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);
|
llist_del(&rctx->list);
|
||||||
req_ctx_put(rctx);
|
req_ctx_put(rctx);
|
||||||
break;
|
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_STATS:
|
||||||
case CEMU_USB_MSGT_DT_GET_STATUS:
|
case CEMU_USB_MSGT_DT_GET_STATUS:
|
||||||
default:
|
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
|
/* iterate over the queue of incoming USB commands and dispatch/execute
|
||||||
* them */
|
* 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;
|
struct req_ctx *rctx, *tmp;
|
||||||
|
|
||||||
llist_for_each_entry_safe(rctx, tmp, main_q, list)
|
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 */
|
/* main loop function, called repeatedly */
|
||||||
@@ -356,7 +367,7 @@ void mode_cardemu_run(void)
|
|||||||
* host */
|
* host */
|
||||||
queue = &ci->usb_out_queue;
|
queue = &ci->usb_out_queue;
|
||||||
usb_refill_from_host(queue, ci->ep_out);
|
usb_refill_from_host(queue, ci->ep_out);
|
||||||
process_any_usb_commands(queue, ci->ch);
|
process_any_usb_commands(queue, ci);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user