explicitly inform card_emu once data to transmit has arrived

This commit is contained in:
Harald Welte 2016-03-02 10:27:58 +01:00
parent 8a416b1812
commit acae412b2a
3 changed files with 48 additions and 2 deletions

View File

@ -788,6 +788,23 @@ int card_emu_tx_byte(struct card_handle *ch)
return rc;
}
void card_emu_have_new_uart_tx(struct card_handle *ch)
{
switch (ch->state) {
case ISO_S_IN_TPDU:
switch (ch->tpdu.state) {
case TPDU_S_WAIT_TX:
case TPDU_S_WAIT_PB:
card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
break;
default:
break;
}
default:
break;
}
}
/* 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)
{

View File

@ -26,6 +26,7 @@ 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);
void card_emu_have_new_uart_tx(struct card_handle *ch);
#define ENABLE_TX 0x01
#define ENABLE_RX 0x02

View File

@ -2,6 +2,7 @@
#include "card_emu.h"
#include "iso7816_fidi.h"
#include "utils.h"
#include "linuxlist.h"
#define TRACE_ENTRY() TRACE_DEBUG("%s entering\n", __func__)
@ -207,9 +208,24 @@ void mode_cardemu_exit(void)
#endif
}
static int llist_count(struct llist_head *head)
{
struct llist_head *list;
int i = 0;
llist_for_each(list, head)
i++;
return i;
}
static int usb_pending_old = 0;
/* main loop function, called repeatedly */
void mode_cardemu_run(void)
{
struct llist_head *queue;
if (ch1) {
/* drain the ring buffer from UART into card_emu */
while (1) {
@ -221,9 +237,21 @@ void mode_cardemu_run(void)
uint8_t byte = rbuf_read(&ch1_rb);
__enable_irq();
card_emu_process_rx_byte(ch1, byte);
TRACE_ERROR("Rx%02x\r\n", 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);
queue = card_emu_get_usb_tx_queue(ch1);
int usb_pending = llist_count(queue);
if (usb_pending != usb_pending_old) {
// printf("usb_pending=%d\r\n", usb_pending);
usb_pending_old = usb_pending;
}
usb_refill_to_host(queue, PHONE_DATAIN);
queue = card_emu_get_uart_tx_queue(ch1);
usb_refill_from_host(queue, PHONE_DATAOUT);
if (llist_count(queue))
card_emu_have_new_uart_tx(ch1);
}
#ifdef CARDEMU_SECOND_UART