diff --git a/firmware/libcommon/include/card_emu.h b/firmware/libcommon/include/card_emu.h index aaa07c50..8a73d5ca 100644 --- a/firmware/libcommon/include/card_emu.h +++ b/firmware/libcommon/include/card_emu.h @@ -66,3 +66,7 @@ int card_emu_uart_tx(uint8_t uart_chan, uint8_t byte); void card_emu_uart_enable(uint8_t uart_chan, uint8_t rxtx); void card_emu_uart_wait_tx_idle(uint8_t uart_chan); void card_emu_uart_interrupt(uint8_t uart_chan); + +struct cardemu_usb_msg_config; +int card_emu_set_config(struct card_handle *ch, const struct cardemu_usb_msg_config *scfg, + unsigned int scfg_len); diff --git a/firmware/libcommon/include/simtrace_prot.h b/firmware/libcommon/include/simtrace_prot.h index 878bc34f..eca844ad 100644 --- a/firmware/libcommon/include/simtrace_prot.h +++ b/firmware/libcommon/include/simtrace_prot.h @@ -62,6 +62,8 @@ enum simtrace_msg_type_cardem { SIMTRACE_MSGT_DO_CEMU_RX_DATA, /* Indicate PTS request from phone */ SIMTRACE_MSGT_DO_CEMU_PTS, + /* Set configurable parameters */ + SIMTRACE_MSGT_BD_CEMU_CONFIG, }; /* SIMTRACE_MSGC_MODEM */ @@ -254,6 +256,15 @@ struct cardemu_usb_msg_error { uint8_t msg[0]; } __attribute__ ((packed)); +/* enable/disable the generation of DO_STATUS on IRQ endpoint */ +#define CEMU_FEAT_F_STATUS_IRQ 0x00000001 + +/* SIMTRACE_MSGT_BD_CEMU_CONFIG */ +struct cardemu_usb_msg_config { + /* bit-mask of CEMU_FEAT_F flags */ + uint32_t features; +} __attribute__ ((packed)); + /*********************************************************************** * MODEM CONTROL ***********************************************************************/ diff --git a/firmware/libcommon/source/card_emu.c b/firmware/libcommon/source/card_emu.c index 352284fd..8da844f0 100644 --- a/firmware/libcommon/source/card_emu.c +++ b/firmware/libcommon/source/card_emu.c @@ -37,6 +37,9 @@ #define NUM_SLOTS 2 +/* bit-mask of supported CEMU_FEAT_F_ flags */ +#define SUPPORTED_FEATURES 0 + #define ISO7816_3_INIT_WTIME 9600 #define ISO7816_3_DEFAULT_WI 10 #define ISO7816_3_ATR_LEN_MAX (1+32) /* TS plus 32 chars */ @@ -195,6 +198,9 @@ const struct value_string tpdu_state_names[] = { struct card_handle { unsigned int num; + /* bit-mask of enabled optional features (CEMU_FEAT_F_*) */ + uint32_t features; + enum iso7816_3_card_state state; /* signal levels */ @@ -1081,6 +1087,22 @@ void card_emu_report_status(struct card_handle *ch, bool report_on_irq) usb_buf_upd_len_and_submit(msg); } +static void card_emu_report_config(struct card_handle *ch) +{ + struct msgb *msg; + struct cardemu_usb_msg_config *cfg; + uint8_t ep = ch->in_ep; + + msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_BD_CEMU_CONFIG); + if (!msg) + return; + + cfg = (struct cardemu_usb_msg_config *) msgb_put(msg, sizeof(*cfg)); + cfg->features = ch->features; + + usb_buf_upd_len_and_submit(msg); +} + /* hardware driver informs us that a card I/O signal has changed */ void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active) { @@ -1204,6 +1226,18 @@ static const uint8_t default_atr[] = { 0x3B, 0x00 }; static struct card_handle card_handles[NUM_SLOTS]; +int card_emu_set_config(struct card_handle *ch, const struct cardemu_usb_msg_config *scfg, + unsigned int scfg_len) +{ + if (scfg_len >= sizeof(uint32_t)) + ch->features = (scfg->features & SUPPORTED_FEATURES); + + /* send back a report of our current configuration */ + card_emu_report_config(ch); + + return 0; +} + struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan, uint8_t in_ep, uint8_t irq_ep, bool vcc_active, bool in_reset, bool clocked) { struct card_handle *ch; diff --git a/firmware/libcommon/source/mode_cardemu.c b/firmware/libcommon/source/mode_cardemu.c index fbc042f2..c5c173fe 100644 --- a/firmware/libcommon/source/mode_cardemu.c +++ b/firmware/libcommon/source/mode_cardemu.c @@ -507,6 +507,7 @@ static void dispatch_usb_command_cardem(struct msgb *msg, struct cardem_inst *ci struct simtrace_msg_hdr *hdr; struct cardemu_usb_msg_set_atr *atr; struct cardemu_usb_msg_cardinsert *cardins; + struct cardemu_usb_msg_config *cfg; struct llist_head *queue; hdr = (struct simtrace_msg_hdr *) msg->l1h; @@ -541,6 +542,10 @@ static void dispatch_usb_command_cardem(struct msgb *msg, struct cardem_inst *ci card_emu_report_status(ci->ch, false); usb_buf_free(msg); break; + case SIMTRACE_MSGT_BD_CEMU_CONFIG: + cfg = (struct cardemu_usb_msg_config *) msg->l2h; + card_emu_set_config(ci->ch, cfg, msgb_l2len(msg)); + break; case SIMTRACE_MSGT_BD_CEMU_STATS: default: /* FIXME: Send Error */