diff options
-rw-r--r-- | firmware/Makefile | 2 | ||||
-rw-r--r-- | firmware/src_simtrace/host_communication.c | 85 | ||||
-rw-r--r-- | firmware/src_simtrace/main.c | 9 | ||||
-rw-r--r-- | firmware/src_simtrace/mode_cardemu.c | 172 | ||||
-rw-r--r-- | firmware/src_simtrace/simtrace.h | 11 |
5 files changed, 238 insertions, 41 deletions
diff --git a/firmware/Makefile b/firmware/Makefile index 4ec68bb..405bd31 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -140,7 +140,7 @@ C_CMSIS = core_cm3.o C_LOWLEVEL = board_cstartup_gnu.o board_lowlevel.o syscalls.o exceptions.o C_LIBLEVEL = spi.o pio.o pmc.o usart.o pio_it.o pio_capture.o uart_console.o iso7816_4.o wdt.o led.o tc.o C_CCID = cciddriver.o USBD.o USBDDriver.o USBD_HAL.o USBRequests.o USBDCallbacks.o USBDescriptors.o USBDDriverCallbacks.o -C_SIMTRACE = simtrace_iso7816.o usb.o ccid.o sniffer.o phone.o mitm.o ringbuffer.o host_communication.o iso7816_fidi.o tc_etu.o req_ctx.o card_emu.o card_emu_target.o +C_SIMTRACE = simtrace_iso7816.o usb.o ccid.o sniffer.o mitm.o ringbuffer.o host_communication.o iso7816_fidi.o tc_etu.o req_ctx.o card_emu.o mode_cardemu.o C_APPLEVEL = main.o C_OBJECTS = $(C_CMSIS) $(C_LOWLEVEL) $(C_LIBLEVEL) $(C_APPLEVEL) $(C_CCID) $(C_SIMTRACE) diff --git a/firmware/src_simtrace/host_communication.c b/firmware/src_simtrace/host_communication.c index ab57a5d..e73b826 100644 --- a/firmware/src_simtrace/host_communication.c +++ b/firmware/src_simtrace/host_communication.c @@ -1,45 +1,66 @@ #include "board.h" +#include "req_ctx.h" -static volatile bool write_to_host_in_progress = false; -static bool check_for_pts = false; +/* call-back after (successful?) transfer of a buffer */ +static void usb_write_cb(uint8_t *arg, uint8_t status, uint32_t transferred, + uint32_t remaining) +{ + struct req_ctx *rctx = (struct req_ctx *) arg; + + if (status != USBD_STATUS_SUCCESS) + TRACE_ERROR("%s error, status=%d\n", __func__, status); -static struct Usart_info usart_info = {.base = USART_PHONE, .id = ID_USART_PHONE, .state = USART_RCV}; + /* release request contxt to pool */ + req_ctx_set_state(rctx, RCTX_S_FREE); +} -static void USB_write_callback(uint8_t *pArg, uint8_t status, uint32_t transferred, uint32_t remaining) +int usb_to_host(void) { - if (status != USBD_STATUS_SUCCESS) { - TRACE_ERROR("USB err status: %d(%s)\n", __FUNCTION__, status); - } - write_to_host_in_progress = false; - TRACE_DEBUG("WR_CB\n"); + struct req_ctx *rctx; + int rc; + + rctx = req_ctx_find_get(0, RCTX_S_USB_TX_PENDING, RCTX_S_USB_TX_BUSY); + + /* FIXME: obtain endpoint number from req_ctx! */ + rc = USBD_Write(PHONE_DATAIN, rctx->data, rctx->tot_len, + (TransferCallback) &usb_write_cb, rctx); + if (rc != USBD_STATUS_SUCCESS) { + TRACE_ERROR("%s error %x\n", __func__, ret); + req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING); + return 0; + } + + return 1; } -static int send_to_host() +static void usb_read_cb(uint8_t *arg, uint8_t status, uint32_t transferred, + uint32_t remaining) { - static uint8_t msg[RING_BUFLEN]; - int ret = 0; - unsigned int i; - - for(i = 0; !rbuf_is_empty(&sim_rcv_buf) && i < sizeof(msg); i++) { - msg[i] = rbuf_read(&sim_rcv_buf); - } - TRACE_DEBUG("Wr %d\n", i); - write_to_host_in_progress = true; - ret = USBD_Write( PHONE_DATAIN, msg, i, (TransferCallback)&USB_write_callback, 0 ); - if (ret != USBD_STATUS_SUCCESS) { - TRACE_ERROR("Error sending to host (%x)\n", ret); - write_to_host_in_progress = false; - } - return ret; + struct req_ctx *rctx = (struct req_ctx *) arg; + + if (status != USBD_STATUS_SUCCESS) { + TRACE_ERROR("%s error, status=%d\n", __func__, status); + /* release request contxt to pool */ + req_ctx_put(rctx); + return; + } + req_ctx_set_state(rctx, RCTX_S_UART_TX_PENDING); } -int check_data_from_phone() +int usb_from_host(int ep) { - int ret = 0; + struct req_ctx *rctx; + int rc; + + rctx = req_ctx_find_get(0, RCTX_S_FREE, RCTX_S_USB_RX_BUSY); + + rc = USBD_Read(ep, rctx->data, rctx->size, + (TransferCallback) &usb_read_cb, rctx); + + if (rc != USBD_STATUS_SUCCESS) { + TRACE_ERROR("%s error %x\n", __func__, ret); + req_ctx_put(rctx); + } - if((rbuf_is_empty(&sim_rcv_buf) || write_to_host_in_progress == true)) { - return ret; - } - ret = send_to_host(); - return ret; + return 0; } diff --git a/firmware/src_simtrace/main.c b/firmware/src_simtrace/main.c index 2b0bed5..36d86ee 100644 --- a/firmware/src_simtrace/main.c +++ b/firmware/src_simtrace/main.c @@ -39,10 +39,10 @@ static const conf_func config_func_ptrs[] = { #endif #ifdef HAVE_CARDEM [CFG_NUM_PHONE] = { - .configure = Phone_configure, - .init = Phone_init, - .exit = Phone_exit, - .run = Phone_run, + .configure = mode_cardemu_configure, + .init = mode_cardemu_init, + .exit = mode_cardemu_exit, + .run = mode_cardemu_run, }, #endif #ifdef HAVE_MITM @@ -140,6 +140,7 @@ extern int main( void ) last_simtrace_config = simtrace_config; } else { config_func_ptrs[simtrace_config].run(); + usb_to_host(); } } } diff --git a/firmware/src_simtrace/mode_cardemu.c b/firmware/src_simtrace/mode_cardemu.c new file mode 100644 index 0000000..fd887a9 --- /dev/null +++ b/firmware/src_simtrace/mode_cardemu.c @@ -0,0 +1,172 @@ +#include "board.h" +#include "card_emu.h" + +static const Pin pins_cardsim[] = PINS_CARDSIM; + +/* UART pins */ +static const Pin pins_usim1[] = {PINS_USIM1}; +static const Pin pin_usim1_rst = PIN_USIM1_nRST; +static const Pin pin_usim1_vcc = PIN_USIM1_VCC; + +#ifdef CARDEMU_SECOND_UART +static const Pin pins_usim2[] = {PINS_USIM1}; +static const Pin pin_usim2_rst = PIN_USIM2_nRST; +static const Pin pin_usim2_vcc = PIN_USIM2_VCC; +#endif + +static struct card_handle *ch1, *ch2; + +static struct Usart_info usart_info[] = { + { + .base = USART1, + .id = ID_USART1, + .state = USART_RCV + }, +#ifdef CARDEMU_SECOND_UART + { + .base = USART0, + .id = ID_USART0, + .state = USART_RCV + }, +#endif +}; + +static Usart *get_usart_by_chan(uint8_t uart_chan) +{ + switch (uart_chan) { + case 0: + return USART1; +#ifdef CARDEMU_SECOND_UART + case 1: + return USART0; +#endif + } + return NULL; +} + +/*********************************************************************** + * Call-Backs from card_emu.c + ***********************************************************************/ + +/* call-back from card_emu.c to enable/disable transmit and/or receive */ +void card_emu_uart_enable(uint8_t uart_chan, uint8_t rxtx) +{ + Usart *usart = get_usart_by_chan(uart_chan); + switch (rxtx) { + case ENABLE_TX: + USART_SetReceiverEnabled(usart, 0); + USART_SetTransmitterEnabled(usart, 1); + break; + case ENABLE_RX: + USART_SetTransmitterEnabled(usart, 0); + USART_SetReceiverEnabled(usart, 1); + break; + case 0: + default: + USART_SetTransmitterEnabled(usart, 0); + USART_SetReceiverEnabled(usart, 0); + break; + } +} + +/* call-back from card_emu.c to transmit a byte */ +int card_emu_uart_tx(uint8_t uart_chan, uint8_t byte) +{ + Usart_info *ui = &usart_info[uart_chan]; + ISO7816_SendChar(byte, ui); + return 1; +} + + +/* FIXME: integrate this with actual irq handler */ +void usart_irq_rx(uint8_t uart, uint32_t csr, uint8_t byte) +{ + struct card_handle *ch = ch1; +#ifdef CARDEMU_SECOND_UART + if (uart == 0) + ch = ch2; +#endif + + if (csr & US_CSR_TXRDY) + card_emu_tx_byte(ch); + + if (csr & US_CSR_RXRDY) + card_emu_process_rx_byte(ch, byte); + + if (csr & (US_CSR_OVRE|US_CSR_FRAME|US_CSR_PARE| + US_CSR_TIMEOUT|US_CSR_NACK|(1<<10))) { + TRACE_DEBUG("e 0x%x st: 0x%x\n", byte, csr); + } +} + + +/*********************************************************************** + * Core USB / mainloop integration + ***********************************************************************/ + +/* executed once at system boot for each config */ +void mode_cardemu_configure(void) +{ +} + +/* called if config is activated */ +void mode_cardemu_init(void) +{ + PIO_Configure(pins_cardsim, PIO_LISTSIZE(pins_cardsim)); + + PIO_Configure(pins_usim1, PIO_LISTSIZE(pins_usim1)); + ISO7816_Init(&usart_info[0], CLK_SLAVE); + USART_EnableIt(USART1, US_IER_RXRDY); + NVIC_EnableIRQ(USART1_IRQn); + ch1 = card_emu_init(0, 2, 0); + +#ifdef CARDEMU_SECOND_UART + PIO_Configure(pins_usim2, PIO_LISTSIZE(pins_usim2)); + ISO7816_Init(&usart_info[1], CLK_SLAVE); + USART_EnableIt(USART0, US_IER_RXRDY); + NVIC_EnableIRQ(USART0_IRQn); + ch2 = card_emu_init(1, 0, 1); +#endif +} + +/* called if config is deactivated */ +void mode_cardemu_exit(void) +{ + NVIC_DisableIRQ(USART1_IRQn); + USART_SetTransmitterEnabled(USART1, 0); + USART_SetReceiverEnabled(USART1, 0); + +#ifdef CARDEMU_SECOND_UART + NVIC_DisableIRQ(USART0_IRQn); + USART_SetTransmitterEnabled(USART0, 0); + USART_SetReceiverEnabled(USART0, 0); +#endif +} + +/* main loop function, called repeatedly */ +void mode_cardemu_run(void) +{ + int rst_active, vcc_active; + + /* usb_to_host() is handled by main() */ + + if (ch1) { + rst_active = PIO_Get(&pin_usim1_rst) ? 0 : 1; + vcc_active = PIO_Get(&pin_usim1_vcc) ? 1 : 0; + card_emu_io_statechg(ch1, CARD_IO_RST, rst_active); + card_emu_io_statechg(ch1, CARD_IO_VCC, vcc_active); + /* FIXME: clock ? */ + } + usb_from_host(PHONE_DATAOUT); + +#ifdef CARDEMU_SECOND_UART + if (ch2) { + rst_active = PIO_Get(&pin_usim2_rst) ? 0 : 1; + vcc_active = PIO_Get(&pin_usim2_vcc) ? 1 : 0; + card_emu_io_statechg(ch2, CARD_IO_RST, rst_active); + card_emu_io_statechg(ch2, CARD_IO_VCC, vcc_active); + /* FIXME: clock ? */ + } + usb_from_host(FIXME); +#endif +} diff --git a/firmware/src_simtrace/simtrace.h b/firmware/src_simtrace/simtrace.h index 00d2b73..687d219 100644 --- a/firmware/src_simtrace/simtrace.h +++ b/firmware/src_simtrace/simtrace.h @@ -65,13 +65,13 @@ void ISR_PhoneRST( const Pin *pPin); /* Configure functions */ extern void Sniffer_configure( void ); extern void CCID_configure( void ); -extern void Phone_configure( void ); +extern void mode_cardemu_configure(void); extern void MITM_configure( void ); /* Init functions */ extern void Sniffer_init( void ); extern void CCID_init( void ); -extern void Phone_init( void ); +extern void mode_cardemu_init(void); extern void MITM_init( void ); extern void SIMtrace_USB_Initialize( void ); @@ -79,17 +79,20 @@ extern void SIMtrace_USB_Initialize( void ); /* Exit functions */ extern void Sniffer_exit( void ); extern void CCID_exit( void ); -extern void Phone_exit( void ); +extern void mode_cardemu_exit(void); extern void MITM_exit( void ); /* Run functions */ extern void Sniffer_run( void ); extern void CCID_run( void ); -extern void Phone_run( void ); +extern void mode_cardemu_run(void); extern void MITM_run( void ); /* Timer helper function */ void Timer_Init( void ); void TC0_Counter_Reset( void ); +int usb_to_host(void); +int usb_from_host(int ep); + #endif /* SIMTRACE_H */ |