diff options
author | Min Xu <min.xu@min-info.net> | 2014-10-25 20:55:01 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2014-11-11 22:30:54 +0100 |
commit | ab325fc295a23d04f27cc7300b12d2564e4d83e6 (patch) | |
tree | 7ded03272565766e166b04c20fa18ff94ef3ac9c /firmware/src/simtrace/iso7816_uart.c | |
parent | 9bd1b003a63d61e91db3827c2b66290abc1adf13 (diff) |
Ensure to transmit current req_ctx on RESET/VCC events
When any of the following events occur:
* VCC_PHONE off
* nRST
* RST
we tranmsit the current req_ctx, if there is data pending.
This ensures that for any successive data, the ATR flag in the next
req_ctx containing the data, not in the previous req_ctx. It also
ensures that the ATR is aligned at 0 offset in the new req_ctx, which is
an assumption the host software makes but the previous code didn't
ensure.
Furthermore, we introduce a periodic flushing of any pending but
incomplete req_ctx.
Diffstat (limited to 'firmware/src/simtrace/iso7816_uart.c')
-rw-r--r-- | firmware/src/simtrace/iso7816_uart.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/firmware/src/simtrace/iso7816_uart.c b/firmware/src/simtrace/iso7816_uart.c index 611ccfb..780340f 100644 --- a/firmware/src/simtrace/iso7816_uart.c +++ b/firmware/src/simtrace/iso7816_uart.c @@ -575,6 +575,23 @@ void iso7816_wtime_expired(void) set_state(&isoh, ISO7816_S_WAIT_APDU); } +void iso_uart_flush(void) +{ + send_rctx(&isoh); +} + +void iso_uart_idleflush(void) +{ + static struct req_ctx *last_req = NULL; + static u_int16_t last_len = 0; + + if (last_req == isoh.rctx || last_len == isoh.rctx->tot_len) { + send_rctx(&isoh); + } + last_req = isoh.rctx; + last_len = isoh.rctx->tot_len; +} + static __ramfunc void usart_irq(void) { u_int32_t csr = usart->US_CSR; @@ -618,9 +635,13 @@ static __ramfunc void usart_irq(void) static void reset_pin_irq(u_int32_t pio) { if (!AT91F_PIO_IsInputSet(AT91C_BASE_PIOA, pio)) { + /* make sure to flush pending req_ctx */ + iso_uart_flush(); DEBUGPCR("nRST"); set_state(&isoh, ISO7816_S_RESET); } else { + /* make sure to flush pending req_ctx */ + iso_uart_flush(); DEBUGPCR("RST"); set_state(&isoh, ISO7816_S_WAIT_ATR); isoh.stats.rst++; |