From 9363dcd9944d348b1fc50e8c195c8c30ecbc0cc3 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Thu, 11 May 2023 00:56:51 +0200 Subject: [PATCH] Only change speed after ATR if TA2 bit 5 is unset Based on ISO 7816-3 8.3: If bit 5 is set to 0, then the integers Fi and Di defined above by TA1 shall apply. If bit 5 is set to 1, then implicit values (not defined by the interface bytes) shall apply. --- atr.c | 10 +++++++--- atr.h | 2 +- atr_test.c | 6 +++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/atr.c b/atr.c index b1cb128..218c303 100644 --- a/atr.c +++ b/atr.c @@ -11,6 +11,7 @@ void atr_init(struct atr *atr) { atr->bytes_left = 2; atr->first_protocol_suggested = NO_VALUE; atr->ta1_value = NO_VALUE; + atr->ta2_value = NO_VALUE; } static int handle_t_bits(struct atr *atr, unsigned char data, unsigned *complete) { @@ -44,7 +45,7 @@ static void handle_ta_byte(struct atr *atr, unsigned char data) { atr->ta1_value = data; break; case 2: - atr->ta2_seen = 1; + atr->ta2_value = data; break; } } @@ -100,7 +101,10 @@ void atr_result(struct atr *atr, unsigned *new_proto, unsigned *new_speed) { if (new_proto && atr->first_protocol_suggested != NO_VALUE) { *new_proto = atr->first_protocol_suggested; } - if (new_speed && atr->ta1_value != NO_VALUE && atr->ta2_seen) { - *new_speed = atr->ta1_value; + if (new_speed && atr->ta1_value != NO_VALUE) { + if (atr->ta2_value != NO_VALUE && (atr->ta2_value & 0x10) == 0) { + // Switch if TA2 bit 5 is cleared. + *new_speed = atr->ta1_value; + } } } diff --git a/atr.h b/atr.h index 65a08c2..aa1e241 100644 --- a/atr.h +++ b/atr.h @@ -23,7 +23,7 @@ struct atr { unsigned num_historical_bytes; unsigned t_cycle; unsigned ta1_value; - unsigned ta2_seen; + unsigned ta2_value; }; void atr_init(struct atr *atr); diff --git a/atr_test.c b/atr_test.c index d307e86..cd7599d 100644 --- a/atr_test.c +++ b/atr_test.c @@ -34,10 +34,14 @@ static const struct sample { .data = {0x3B, 0x93, 0x95, 0x80, 0x1F, 0xC7, 0x80, 0x31, 0x80, 0x6F}, .len = 10, }, - { // TA(1) and TA(2) supplied, new speed in use. + { // TA(1) with speed, TA(2) with bit 5 cleared, new speed in use. .data = {0x3B, 0xD2, 0x13, 0xFF, 0x10, 0x80, 0x07, 0x14}, .len = 8, .speed = 0x13, }, + { // TA(1) with speed, TA(2) with bit 5 set, no speed change. + .data = {0x3B, 0xD2, 0x13, 0xFF, 0x10, 0x90, 0x07, 0x14}, + .len = 8, + }, { // TD(1) present but as last byte. .data = {0x3B, 0x80, 0x00}, .len = 3, },