From 0e7999e05cfaf6ca2a5cafd1571f95aa910e70a1 Mon Sep 17 00:00:00 2001
From: Philipp Claves <pclaves@web.de>
Date: Sat, 12 Nov 2011 23:15:57 +0100
Subject: [PATCH] CardReader: Reduce APDU timeout to 600ms for the first answer
 byte and 300ms for the following bytes

---
 CardReader/ISO7816-reader.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/CardReader/ISO7816-reader.c b/CardReader/ISO7816-reader.c
index 8b59cae..9eba34f 100644
--- a/CardReader/ISO7816-reader.c
+++ b/CardReader/ISO7816-reader.c
@@ -248,7 +248,7 @@ uint8_t ISO7816_readATR(ISO7816_ATR* atr){
 // }
 
 uint16_t ISO7816_read_byte(void){
-	uint16_t timeout = 30000; //3 sec
+	uint16_t timeout = 3000; //0,3 sec
 	while(!CARD_data_available() && (ISO7816_is_card_present()) && timeout) {timeout--; _delay_us(100);}
 	if (! ISO7816_is_card_present()){
 		return ISO7816_ERR_CARD_REMOVED;
@@ -281,19 +281,16 @@ uint16_t ISO7816_send_apdu(ISO7816_APDU_Header* apdu_header,
 	uint8_t c;
 	uint8_t checksum = 0;
 	
-// 	_delay_us(block_guard_time);
 	CARD_switch_mode_transmit();
 	
 	printf("=> ");
 		
 	//NAD (Node Address, not used)
 	c = 0x00; checksum ^= c; printf("%02x ", c); CARD_transmit_char(c);
-// 	_delay_us(char_guard_time);
 	
 	//Protocol control byte
 	c = seq_number ? 0x40 : 0x00; checksum ^= c; printf("%02x ", c); CARD_transmit_char(c);
 	seq_number = !seq_number;
-// 	_delay_us(char_guard_time);
 	
 	//Message Length
 	uint8_t apdu_legth = sizeof(ISO7816_APDU_Header);
@@ -303,30 +300,25 @@ uint16_t ISO7816_send_apdu(ISO7816_APDU_Header* apdu_header,
 	
 	//APDU Header
 	for (uint8_t i = 0; i < sizeof(ISO7816_APDU_Header); i++){
-// 		_delay_us(char_guard_time);
 		c = ((uint8_t*)apdu_header)[i]; checksum ^= c; printf("%02x ",c); CARD_transmit_char(c);
 	}
 	
 	//APDU Payload length (if 0 this must not be sent)
 	if (apdu_payload_length){
-// 		_delay_us(char_guard_time);
 		c = apdu_payload_length; checksum ^= c; printf("%02x ", c); CARD_transmit_char(c);
 	}
 	
 	//APDU Payload
 	for (uint16_t i = 0; i < apdu_payload_length; i++){
-// 		_delay_us(char_guard_time);
 		c = apdu_payload[i]; checksum ^= c; printf("%02x ", c); CARD_transmit_char(c);
 	}
 	
 	//If a 0 byte answer is expected, LE must not be send
 	if (answer_payload_length){
 		//Send expected answer length byte
-// 		_delay_us(char_guard_time);
 		c = answer_payload_length; checksum ^= c; printf("%02x ", c); CARD_transmit_char(c);
 	}
 	
-// 	_delay_us(char_guard_time);
 	printf("%02x ", checksum);
 	CARD_transmit_char(checksum);
 	
@@ -342,7 +334,10 @@ uint16_t ISO7816_send_apdu(ISO7816_APDU_Header* apdu_header,
 	
 	//Answer Node Address (don't care)
 	ret = ISO7816_read_byte();
-	if (ret & 0xFF00) return ISO7816_ERR_TIMEOUT;
+	if (ret & 0xFF00){
+		ret = ISO7816_read_byte(); //Retry for the first byte (the card may take some time to answer).
+		if (ret & 0xFF00) return ISO7816_ERR_TIMEOUT;
+	}
 	printf("%02x ", ret & 0xFF);
 	checksum ^= ret & 0xFF;
 	
-- 
GitLab