Skip to content
Snippets Groups Projects
Commit 4631e16a authored by da1l6's avatar da1l6
Browse files

CardReader: Handle card removal during ATR read.

parent c2d929d5
No related branches found
No related tags found
No related merge requests found
...@@ -19,8 +19,10 @@ uint16_t rate_adjustment_di[16] = {DI_RFU, 1,2,4,8,16,32,64, 12,20, DI_RFU, DI_R ...@@ -19,8 +19,10 @@ uint16_t rate_adjustment_di[16] = {DI_RFU, 1,2,4,8,16,32,64, 12,20, DI_RFU, DI_R
#define STOPBITS 2 #define STOPBITS 2
#include "../common/serial.h" #include "../common/serial.h"
uint16_t char_guard_time; uint16_t ISO7816_read_byte(void);
uint16_t block_guard_time;
// uint16_t char_guard_time;
// uint16_t block_guard_time;
uint8_t seq_number = 0; uint8_t seq_number = 0;
...@@ -82,15 +84,20 @@ uint8_t ISO7816_readATR(ISO7816_ATR* atr){ ...@@ -82,15 +84,20 @@ uint8_t ISO7816_readATR(ISO7816_ATR* atr){
while (c != 0x3B){ while (c != 0x3B){
timeout = 2000; timeout = 2000;
while (!CARD_data_available() && timeout != 0) {timeout--; _delay_ms(1);} while (!CARD_data_available() && ISO7816_is_card_present() && timeout != 0) {timeout--; _delay_ms(1);}
if (!ISO7816_is_card_present()) return ERR_ATR_CARD_REMOVED;
if (timeout == 0) return ERR_ATR_TIMEOUT; if (timeout == 0) return ERR_ATR_TIMEOUT;
c = CARD_read_char(); c = CARD_read_char();
printf("%02X ", c);
} }
atr->initial_char = c; atr->initial_char = c;
uint16_t ret;
//Read T0 //Read T0
c = CARD_read_char(); ret = ISO7816_read_byte();
if (!ISO7816_is_card_present()) return ERR_ATR_CARD_REMOVED;
if (ret & 0xFF00) return ERR_ATR_TIMEOUT;
c = ret & 0xFF;
checksum ^= c; checksum ^= c;
atr->t0 = c; atr->t0 = c;
...@@ -100,11 +107,33 @@ uint8_t ISO7816_readATR(ISO7816_ATR* atr){ ...@@ -100,11 +107,33 @@ uint8_t ISO7816_readATR(ISO7816_ATR* atr){
while (next_interface_bytes){ while (next_interface_bytes){
if (i >= ATR_MAX_INTERFACE_BYTE_SETS) return ERR_TOO_MANY_ATR_INTERFACE_BYTES; if (i >= ATR_MAX_INTERFACE_BYTE_SETS) return ERR_TOO_MANY_ATR_INTERFACE_BYTES;
if (next_interface_bytes & 0x01) {c = CARD_read_char(); checksum ^= c; atr->interface_bytes[i].ta = c;} if (next_interface_bytes & 0x01) {
if (next_interface_bytes & 0x02) {c = CARD_read_char(); checksum ^= c; atr->interface_bytes[i].tb = c;} ret = ISO7816_read_byte();
if (next_interface_bytes & 0x04) {c = CARD_read_char(); checksum ^= c; atr->interface_bytes[i].tc = c;} if (ret & 0xFF00) return ret;
c = ret & 0xFF;
checksum ^= c;
atr->interface_bytes[i].ta = c;
}
if (next_interface_bytes & 0x02) {
ret = ISO7816_read_byte();
if (ret & 0xFF00) return ret;
c = ret & 0xFF;
checksum ^= c;
atr->interface_bytes[i].tb = c;
}
if (next_interface_bytes & 0x04) {
ret = ISO7816_read_byte();
if (ret & 0xFF00) return ret;
c = ret & 0xFF;
checksum ^= c;
atr->interface_bytes[i].tc = c;
}
if (next_interface_bytes & 0x08) { if (next_interface_bytes & 0x08) {
c = CARD_read_char(); ret = ISO7816_read_byte();
if (ret & 0xFF00) return ret;
c = ret & 0xFF;
checksum ^= c; checksum ^= c;
atr->interface_bytes[i].td = c; atr->interface_bytes[i].td = c;
next_interface_bytes = c >> 4; next_interface_bytes = c >> 4;
...@@ -114,11 +143,20 @@ uint8_t ISO7816_readATR(ISO7816_ATR* atr){ ...@@ -114,11 +143,20 @@ uint8_t ISO7816_readATR(ISO7816_ATR* atr){
i++; i++;
} }
for (i = 0; i < num_hist_bytes; i++){ for (i = 0; i < num_hist_bytes; i++){
c = CARD_read_char(); ret = ISO7816_read_byte();
if (!ISO7816_is_card_present()) return ERR_ATR_CARD_REMOVED;
if (ret & 0xFF00) return ERR_ATR_TIMEOUT;
c = ret & 0xFF;
checksum ^= c; checksum ^= c;
atr->historical_bytes[i] = c; atr->historical_bytes[i] = c;
} }
c = CARD_read_char();
ret = ISO7816_read_byte();
if (!ISO7816_is_card_present()) return ERR_ATR_CARD_REMOVED;
if (ret & 0xFF00) return ERR_ATR_TIMEOUT;
c = ret & 0xFF;
atr->checksum = c; atr->checksum = c;
if (checksum != c) return ERR_ATR_CHECKSUM_FAIL; if (checksum != c) return ERR_ATR_CHECKSUM_FAIL;
...@@ -211,8 +249,10 @@ uint8_t ISO7816_readATR(ISO7816_ATR* atr){ ...@@ -211,8 +249,10 @@ uint8_t ISO7816_readATR(ISO7816_ATR* atr){
uint16_t ISO7816_read_byte(void){ uint16_t ISO7816_read_byte(void){
uint16_t timeout = 30000; //3 sec uint16_t timeout = 30000; //3 sec
while(!CARD_data_available() && timeout) {timeout--; _delay_us(100);} while(!CARD_data_available() && (ISO7816_is_card_present()) && timeout) {timeout--; _delay_us(100);}
if (timeout > 0){ if (! ISO7816_is_card_present()){
return ISO7816_ERR_CARD_REMOVED;
} else if (CARD_data_available()){
uint8_t c = CARD_read_char(); uint8_t c = CARD_read_char();
return c; return c;
} else { } else {
......
...@@ -23,12 +23,13 @@ ...@@ -23,12 +23,13 @@
#define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif #endif
#define ATR_READ_SUCCESS 0x00
#define ATR_IS_ERROR(x) (((x) & 0x80) == 0x80) #define ATR_IS_ERROR(x) (((x) & 0x80) == 0x80)
#define ERR_ATR_TIMEOUT 0x81 #define ATR_READ_SUCCESS 0x00
#define ERR_ATR_TIMEOUT 0x81
#define ERR_TOO_MANY_ATR_INTERFACE_BYTES 0x82 #define ERR_TOO_MANY_ATR_INTERFACE_BYTES 0x82
#define ERR_ATR_CHECKSUM_FAIL 0x83 #define ERR_ATR_CHECKSUM_FAIL 0x83
#define ERR_PROTOCOL_NOT_SUPPORTED 0x84 #define ERR_PROTOCOL_NOT_SUPPORTED 0x84
#define ERR_ATR_CARD_REMOVED 0x85
#ifdef CARD_PRESENCE_INTERUPT #ifdef CARD_PRESENCE_INTERUPT
#include <avr/interrupt.h> #include <avr/interrupt.h>
...@@ -36,8 +37,9 @@ ...@@ -36,8 +37,9 @@
#endif #endif
#define ISO7816_IS_ERROR(ret) (((ret) & 0xFF) == 0xFF) #define ISO7816_IS_ERROR(ret) (((ret) & 0xFF) == 0xFF)
#define ISO7816_ERR_TIMEOUT 0xFFFF #define ISO7816_ERR_TIMEOUT 0xFFFF
#define ISO7816_ERR_CHECKSUM_FAIL 0xFFFE #define ISO7816_ERR_CHECKSUM_FAIL 0xFFFE
#define ISO7816_ERR_CARD_REMOVED 0xFFFD
void ISO7816_init(void); void ISO7816_init(void);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment