mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-25 17:58:32 +03:00
host_communication/card_emu: adapt to nwe req_ctx / queuing paradignm
This commit is contained in:
@@ -30,6 +30,7 @@
|
|||||||
#include "card_emu.h"
|
#include "card_emu.h"
|
||||||
#include "req_ctx.h"
|
#include "req_ctx.h"
|
||||||
#include "cardemu_prot.h"
|
#include "cardemu_prot.h"
|
||||||
|
#include "linuxlist.h"
|
||||||
|
|
||||||
|
|
||||||
#define NUM_SLOTS 2
|
#define NUM_SLOTS 2
|
||||||
@@ -135,6 +136,9 @@ struct card_handle {
|
|||||||
struct req_ctx *uart_rx_ctx; /* UART RX -> USB TX */
|
struct req_ctx *uart_rx_ctx; /* UART RX -> USB TX */
|
||||||
struct req_ctx *uart_tx_ctx; /* USB RX -> UART TX */
|
struct req_ctx *uart_tx_ctx; /* USB RX -> UART TX */
|
||||||
|
|
||||||
|
struct llist_head usb_tx_queue;
|
||||||
|
struct llist_head uart_tx_queue;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint32_t tx_bytes;
|
uint32_t tx_bytes;
|
||||||
uint32_t rx_bytes;
|
uint32_t rx_bytes;
|
||||||
@@ -142,6 +146,16 @@ struct card_handle {
|
|||||||
} stats;
|
} stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct llist_head *card_emu_get_usb_tx_queue(struct card_handle *ch)
|
||||||
|
{
|
||||||
|
return &ch->usb_tx_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch)
|
||||||
|
{
|
||||||
|
return &ch->uart_tx_queue;
|
||||||
|
}
|
||||||
|
|
||||||
static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts);
|
static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts);
|
||||||
static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss);
|
static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss);
|
||||||
|
|
||||||
@@ -154,12 +168,14 @@ static void flush_rx_buffer(struct card_handle *ch)
|
|||||||
if (!rctx)
|
if (!rctx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rd = (struct cardemu_usb_msg_rx_data *) ch->uart_rx_ctx->data;
|
ch->uart_rx_ctx = NULL;
|
||||||
|
|
||||||
/* store length of data payload fild in header */
|
/* store length of data payload fild in header */
|
||||||
|
rd = (struct cardemu_usb_msg_rx_data *) ch->uart_rx_ctx->data;
|
||||||
rd->hdr.data_len = rctx->idx;
|
rd->hdr.data_len = rctx->idx;
|
||||||
|
|
||||||
|
llist_add_tail(&rctx->list, &ch->usb_tx_queue);
|
||||||
req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING);
|
req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING);
|
||||||
ch->uart_rx_ctx = NULL;
|
|
||||||
|
|
||||||
/* FIXME: call into USB code to see if this buffer can
|
/* FIXME: call into USB code to see if this buffer can
|
||||||
* be transmitted now */
|
* be transmitted now */
|
||||||
@@ -214,6 +230,7 @@ static void flush_pts(struct card_handle *ch)
|
|||||||
ptsi->hdr.data_len = serialize_pts(ptsi->req, ch->pts.req);
|
ptsi->hdr.data_len = serialize_pts(ptsi->req, ch->pts.req);
|
||||||
serialize_pts(ptsi->resp, ch->pts.resp);
|
serialize_pts(ptsi->resp, ch->pts.resp);
|
||||||
|
|
||||||
|
llist_add_tail(&rctx->list, &ch->usb_tx_queue);
|
||||||
req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING);
|
req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING);
|
||||||
|
|
||||||
/* FIXME: call into USB code to see if this buffer can
|
/* FIXME: call into USB code to see if this buffer can
|
||||||
@@ -637,11 +654,15 @@ static int tx_byte_tpdu(struct card_handle *ch)
|
|||||||
/* ensure we are aware of any data that might be pending for
|
/* ensure we are aware of any data that might be pending for
|
||||||
* transmit */
|
* transmit */
|
||||||
if (!ch->uart_tx_ctx) {
|
if (!ch->uart_tx_ctx) {
|
||||||
ch->uart_tx_ctx = req_ctx_find_get(0, RCTX_S_UART_TX_PENDING,
|
if (llist_empty(&ch->uart_tx_queue))
|
||||||
RCTX_S_UART_TX_BUSY);
|
|
||||||
if (!ch->uart_tx_ctx)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* dequeue first at head */
|
||||||
|
ch->uart_tx_ctx = llist_entry(ch->uart_tx_queue.next,
|
||||||
|
struct req_ctx, list);
|
||||||
|
llist_del(&ch->uart_tx_ctx->list);
|
||||||
|
req_ctx_set_state(ch->uart_tx_ctx, RCTX_S_UART_TX_BUSY);
|
||||||
|
|
||||||
/* start with index zero */
|
/* start with index zero */
|
||||||
ch->uart_tx_ctx->idx = 0;
|
ch->uart_tx_ctx->idx = 0;
|
||||||
|
|
||||||
@@ -855,6 +876,9 @@ struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uar
|
|||||||
|
|
||||||
memset(ch, 0, sizeof(*ch));
|
memset(ch, 0, sizeof(*ch));
|
||||||
|
|
||||||
|
INIT_LLIST_HEAD(&ch->usb_tx_queue);
|
||||||
|
INIT_LLIST_HEAD(&ch->uart_tx_queue);
|
||||||
|
|
||||||
/* initialize the card_handle with reasonabe defaults */
|
/* initialize the card_handle with reasonabe defaults */
|
||||||
ch->state = ISO_S_WAIT_POWER;
|
ch->state = ISO_S_WAIT_POWER;
|
||||||
ch->vcc_active = 0;
|
ch->vcc_active = 0;
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active);
|
|||||||
/* User sets a new ATR to be returned during next card reset */
|
/* User sets a new ATR to be returned during next card reset */
|
||||||
int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len);
|
int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len);
|
||||||
|
|
||||||
|
struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch);
|
||||||
|
struct llist_head *card_emu_get_usb_tx_queue(struct card_handle *ch);
|
||||||
|
|
||||||
#define ENABLE_TX 0x01
|
#define ENABLE_TX 0x01
|
||||||
#define ENABLE_RX 0x02
|
#define ENABLE_RX 0x02
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "req_ctx.h"
|
#include "req_ctx.h"
|
||||||
|
#include "linuxlist.h"
|
||||||
|
|
||||||
|
static volatile uint32_t usbep_in_progress[BOARD_USB_NUMENDPOINTS];
|
||||||
|
|
||||||
/* call-back after (successful?) transfer of a buffer */
|
/* call-back after (successful?) transfer of a buffer */
|
||||||
static void usb_write_cb(uint8_t *arg, uint8_t status, uint32_t transferred,
|
static void usb_write_cb(uint8_t *arg, uint8_t status, uint32_t transferred,
|
||||||
@@ -7,6 +10,8 @@ static void usb_write_cb(uint8_t *arg, uint8_t status, uint32_t transferred,
|
|||||||
{
|
{
|
||||||
struct req_ctx *rctx = (struct req_ctx *) arg;
|
struct req_ctx *rctx = (struct req_ctx *) arg;
|
||||||
|
|
||||||
|
usbep_in_progress[rctx->ep] = 0;
|
||||||
|
|
||||||
if (status != USBD_STATUS_SUCCESS)
|
if (status != USBD_STATUS_SUCCESS)
|
||||||
TRACE_ERROR("%s error, status=%d\n", __func__, status);
|
TRACE_ERROR("%s error, status=%d\n", __func__, status);
|
||||||
|
|
||||||
@@ -14,15 +19,24 @@ static void usb_write_cb(uint8_t *arg, uint8_t status, uint32_t transferred,
|
|||||||
req_ctx_set_state(rctx, RCTX_S_FREE);
|
req_ctx_set_state(rctx, RCTX_S_FREE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int usb_to_host(void)
|
int usb_refill_to_host(struct llist_head *queue, uint32_t ep)
|
||||||
{
|
{
|
||||||
struct req_ctx *rctx;
|
struct req_ctx *rctx;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rctx = req_ctx_find_get(0, RCTX_S_USB_TX_PENDING, RCTX_S_USB_TX_BUSY);
|
if (usbep_in_progress[ep])
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* FIXME: obtain endpoint number from req_ctx! */
|
if (llist_empty(queue))
|
||||||
rc = USBD_Write(PHONE_DATAIN, rctx->data, rctx->tot_len,
|
return 0;
|
||||||
|
|
||||||
|
rctx = llist_entry(queue->next, struct req_ctx, list);
|
||||||
|
llist_del(&rctx->list);
|
||||||
|
|
||||||
|
req_ctx_set_state(rctx, RCTX_S_USB_TX_BUSY);
|
||||||
|
rctx->ep = ep;
|
||||||
|
|
||||||
|
rc = USBD_Write(ep, rctx->data, rctx->tot_len,
|
||||||
(TransferCallback) &usb_write_cb, rctx);
|
(TransferCallback) &usb_write_cb, rctx);
|
||||||
if (rc != USBD_STATUS_SUCCESS) {
|
if (rc != USBD_STATUS_SUCCESS) {
|
||||||
TRACE_ERROR("%s error %x\n", __func__, rc);
|
TRACE_ERROR("%s error %x\n", __func__, rc);
|
||||||
@@ -30,6 +44,8 @@ int usb_to_host(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
usbep_in_progress[ep] = 1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +53,9 @@ static void usb_read_cb(uint8_t *arg, uint8_t status, uint32_t transferred,
|
|||||||
uint32_t remaining)
|
uint32_t remaining)
|
||||||
{
|
{
|
||||||
struct req_ctx *rctx = (struct req_ctx *) arg;
|
struct req_ctx *rctx = (struct req_ctx *) arg;
|
||||||
|
struct llist_head *queue = (struct llist_head *) usbep_in_progress[rctx->ep];
|
||||||
|
|
||||||
|
usbep_in_progress[rctx->ep] = 0;
|
||||||
|
|
||||||
if (status != USBD_STATUS_SUCCESS) {
|
if (status != USBD_STATUS_SUCCESS) {
|
||||||
TRACE_ERROR("%s error, status=%d\n", __func__, status);
|
TRACE_ERROR("%s error, status=%d\n", __func__, status);
|
||||||
@@ -45,14 +64,19 @@ static void usb_read_cb(uint8_t *arg, uint8_t status, uint32_t transferred,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
int usb_from_host(int ep)
|
int usb_refill_from_host(struct llist_head *queue, int ep)
|
||||||
{
|
{
|
||||||
struct req_ctx *rctx;
|
struct req_ctx *rctx;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (usbep_in_progress[ep])
|
||||||
|
return 0;
|
||||||
|
|
||||||
rctx = req_ctx_find_get(0, RCTX_S_FREE, RCTX_S_USB_RX_BUSY);
|
rctx = req_ctx_find_get(0, RCTX_S_FREE, RCTX_S_USB_RX_BUSY);
|
||||||
|
rctx->ep = ep;
|
||||||
|
|
||||||
rc = USBD_Read(ep, rctx->data, rctx->size,
|
rc = USBD_Read(ep, rctx->data, rctx->size,
|
||||||
(TransferCallback) &usb_read_cb, rctx);
|
(TransferCallback) &usb_read_cb, rctx);
|
||||||
@@ -60,7 +84,10 @@ int usb_from_host(int ep)
|
|||||||
if (rc != USBD_STATUS_SUCCESS) {
|
if (rc != USBD_STATUS_SUCCESS) {
|
||||||
TRACE_ERROR("%s error %x\n", __func__, rc);
|
TRACE_ERROR("%s error %x\n", __func__, rc);
|
||||||
req_ctx_put(rctx);
|
req_ctx_put(rctx);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
usbep_in_progress[ep] = (uint32_t) queue;
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,6 @@ extern int main( void )
|
|||||||
last_simtrace_config = simtrace_config;
|
last_simtrace_config = simtrace_config;
|
||||||
} else {
|
} else {
|
||||||
config_func_ptrs[simtrace_config].run();
|
config_func_ptrs[simtrace_config].run();
|
||||||
usb_to_host();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "card_emu.h"
|
#include "card_emu.h"
|
||||||
#include "iso7816_fidi.h"
|
#include "iso7816_fidi.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#define TRACE_ENTRY() TRACE_DEBUG("%s entering\n", __func__)
|
#define TRACE_ENTRY() TRACE_DEBUG("%s entering\n", __func__)
|
||||||
|
|
||||||
@@ -204,10 +205,8 @@ void mode_cardemu_exit(void)
|
|||||||
/* main loop function, called repeatedly */
|
/* main loop function, called repeatedly */
|
||||||
void mode_cardemu_run(void)
|
void mode_cardemu_run(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* usb_to_host() is handled by main() */
|
|
||||||
|
|
||||||
if (ch1) {
|
if (ch1) {
|
||||||
|
/* drain the ring buffer from UART into card_emu */
|
||||||
while (1) {
|
while (1) {
|
||||||
__disable_irq();
|
__disable_irq();
|
||||||
if (rbuf_is_empty(&ch1_rb)) {
|
if (rbuf_is_empty(&ch1_rb)) {
|
||||||
@@ -218,8 +217,9 @@ void mode_cardemu_run(void)
|
|||||||
__enable_irq();
|
__enable_irq();
|
||||||
card_emu_process_rx_byte(ch1, byte);
|
card_emu_process_rx_byte(ch1, byte);
|
||||||
}
|
}
|
||||||
|
usb_refill_to_host(card_emu_get_usb_tx_queue(ch1), PHONE_DATAIN);
|
||||||
|
usb_refill_from_host(card_emu_get_uart_tx_queue(ch1), PHONE_DATAOUT);
|
||||||
}
|
}
|
||||||
usb_from_host(PHONE_DATAOUT);
|
|
||||||
|
|
||||||
#ifdef CARDEMU_SECOND_UART
|
#ifdef CARDEMU_SECOND_UART
|
||||||
if (ch2) {
|
if (ch2) {
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ extern void MITM_run( void );
|
|||||||
void Timer_Init( void );
|
void Timer_Init( void );
|
||||||
void TC0_Counter_Reset( void );
|
void TC0_Counter_Reset( void );
|
||||||
|
|
||||||
int usb_to_host(void);
|
struct llist_head;
|
||||||
int usb_from_host(int ep);
|
int usb_refill_to_host(struct llist_head *queue, uint32_t ep);
|
||||||
|
int usb_refill_from_host(struct llist_head *queue, int ep);
|
||||||
|
|
||||||
#endif /* SIMTRACE_H */
|
#endif /* SIMTRACE_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user