aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/src/simtrace/iso7816_uart.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/src/simtrace/iso7816_uart.c')
-rw-r--r--firmware/src/simtrace/iso7816_uart.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/firmware/src/simtrace/iso7816_uart.c b/firmware/src/simtrace/iso7816_uart.c
index 6186e5e..37b2fd7 100644
--- a/firmware/src/simtrace/iso7816_uart.c
+++ b/firmware/src/simtrace/iso7816_uart.c
@@ -251,6 +251,20 @@ static void set_state(struct iso7816_3_handle *ih, enum iso7816_3_state new_stat
ih->state = new_state;
}
+static enum iso7816_3_state
+transition_to_tck(struct iso7816_3_handle *ih)
+{
+ if (ih->prot_t_supported == 0x01) {
+ /* If only T=0 supported, there is no TCK but we
+ * immediately transition to APDUs */
+ set_atr_state(ih, ATR_S_DONE);
+ return ISO7816_S_WAIT_APDU;
+ } else {
+ set_atr_state(ih, ATR_S_WAIT_TCK);
+ return ISO7816_S_IN_ATR;
+ }
+}
+
/* determine the next ATR state based on received interface byte */
static enum atr_state next_intb_state(struct iso7816_3_handle *ih, u_int8_t ch)
{
@@ -288,7 +302,11 @@ from_tc:
if (ih->atr_last_td & 0x80)
return ATR_S_WAIT_TD;
- return ATR_S_WAIT_HIST;
+ /* Historical bytes are common, but optional! */
+ if (ih->atr_hist_len)
+ return ATR_S_WAIT_HIST;
+ else
+ return transition_to_tck(ih);
}
/* process an incomng ATR byte */
@@ -324,16 +342,8 @@ process_byte_atr(struct iso7816_3_handle *ih, u_int8_t byte)
case ATR_S_WAIT_HIST:
ih->atr_hist_len--;
/* after all historical bytes are recieved, go to TCK */
- if (ih->atr_hist_len == 0) {
- if (ih->prot_t_supported == 0x01) {
- /* If only T=0 supported, there is no
- * TCK but we immediately transition to
- * APDUs */
- set_atr_state(ih, ATR_S_DONE);
- return ISO7816_S_WAIT_APDU;
- }
- set_atr_state(ih, ATR_S_WAIT_TCK);
- }
+ if (ih->atr_hist_len == 0)
+ return transition_to_tck(ih);
break;
case ATR_S_WAIT_TCK:
/* FIXME: process and verify the TCK */