From 2e7c200cb2714a34ecf8361afdd4eda012d6b5dc Mon Sep 17 00:00:00 2001 From: Philipp Claves <pclaves@web.de> Date: Thu, 1 Dec 2011 19:00:57 +0100 Subject: [PATCH] CardReader: Improve Error condition user feedback. Display control error messages on Cardreader display Reset Cardreader display after 4 seconds of idle to make sure the display is clean when a new user inserts a card. Detect a dead portal control and display an error message. --- CardReader/Makefile | 14 +----- CardReader/main.c | 86 ++++++++++++++++++++++++++++++---- Control/cardreader_interface.c | 16 +++---- Control/door.c | 28 ++++++----- Control/door.h | 6 +-- Control/random.c | 4 +- Control/shell/shell.c | 10 +++- 7 files changed, 116 insertions(+), 48 deletions(-) diff --git a/CardReader/Makefile b/CardReader/Makefile index f0da19b..7275144 100644 --- a/CardReader/Makefile +++ b/CardReader/Makefile @@ -31,18 +31,8 @@ # MCU name -# MCU = atmega1284p MCU = atmega644p -#ATmega 128 wird von mir nicht unterstützt oder nur teilweise! -#MCU = atmega128 - -#Fuse settings for ATmega1284P -ifeq ($(MCU), atmega1284p) - FUSE_BITS = -u -U lfuse:w:0x82:m -U hfuse:w:0xd9:m - HEX_FILE_NAME = MEGA1284 -endif - #Fuse settings for ATmega644P ifeq ($(MCU), atmega644p) @@ -153,8 +143,8 @@ LDFLAGS += -lm #AVRDUDE_PROGRAMMER = stk500v2 #AVRDUDE_PROGRAMMER = dragon_isp -#AVRDUDE_PROGRAMMER = usbtiny -AVRDUDE_PROGRAMMER = USBasp +AVRDUDE_PROGRAMMER = usbtiny +# AVRDUDE_PROGRAMMER = USBasp AVRDUDE_PORT = usb # programmer connected to USB port #AVRDUDE_PORT = /dev/ttyUSB0 # programmer connected to serial device diff --git a/CardReader/main.c b/CardReader/main.c index 348d05c..5160cb1 100644 --- a/CardReader/main.c +++ b/CardReader/main.c @@ -17,11 +17,21 @@ volatile uint8_t card_status = CARD_STATUS_REMOVED; -volatile uint16_t host_watchdog = 0x0; + volatile uint8_t powersave_mode = 1; uint8_t card_atr_error = 0; ISO7816_ATR card_atr; +#define HOST_TIMEOUT 200 +#define HOST_PING_TIME 100 +volatile uint16_t host_timeout = HOST_TIMEOUT; +volatile uint8_t host_ping = 1; +volatile uint8_t host_dead = 0; + +#define DISPLAY_RESET_TIMEOUT 400 /* 400*10 = 4 sec */ +volatile uint16_t display_reset_timeout = DISPLAY_RESET_TIMEOUT; +volatile uint8_t display_reset = 1; + //----------- Hardware interrupt handler ----------- void ISO7816_card_presence_changed(uint8_t inserted){ @@ -36,16 +46,47 @@ void ISO7816_card_presence_changed(uint8_t inserted){ } } +ISR(TIMER0_COMPA_vect){ + if (display_reset_timeout){ + display_reset_timeout--; + if (display_reset_timeout == 0){ + display_reset = 1; + } + } + if (host_timeout){ + host_timeout--; + if (host_timeout == HOST_PING_TIME || host_timeout == 0){ + if (host_timeout == 0){ + host_dead = 1; + display_reset = 1; + host_timeout = HOST_TIMEOUT; + } + host_ping = 1; + } + } +} + +void timer_init(void){ + TCCR0A = (1 << WGM01); + TCCR0B = (1 << CS00) | (1 << CS02); //Prescaler /1024 + OCR0A = 89; // 9216000Hz/1024/(1+89) = 100Hz + TIMSK0 = (1 << OCIE0A); +} + //----------- Interrupt Message Handler ----------- void reset(void){ wdt_enable(WDTO_15MS); while(1){;} } void host_alive(void){ - host_watchdog = 0xFFFF; + host_timeout = HOST_TIMEOUT; + if (host_dead){ + host_dead = 0; + display_reset = 1; + } } void cardreader_alive(void){ - transport_send_interrupt_message(2); + transport_send_interrupt_message(CARDREADER_INTERRUPT_CARDREADER_ALIVE); } //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -101,6 +142,12 @@ void handle_card_msg(uint8_t* msg, uint8_t length){ void handle_display_msg(uint8_t* msg, uint8_t length){ uint8_t type = msg[0]; uint8_t success = 0; + + char* text = (char*)(&msg[1]); + uint8_t text_len = length - 1; + + display_reset_timeout = DISPLAY_RESET_TIMEOUT; + switch (type){ case CARDREADER_DISPLAY_MSG_CLEAR: lcd_clear(); @@ -114,7 +161,16 @@ void handle_display_msg(uint8_t* msg, uint8_t length){ } break; case CARDREADER_DISPLAY_MSG_WRITE: - lcd_write_string((char*)&msg[1], length - 1); + + if (text_len <= 16){ + lcd_write_string(text, text_len); + } else { + lcd_clear(); + lcd_home(); + lcd_write_string(text, 16); + lcd_set_pos(0,1); + lcd_write_string(text+16, text_len - 16); + } success = 1; break; case CARDREADER_DISPLAY_MSG_SET_BACKLIGHT: @@ -148,6 +204,11 @@ void display_receive_error(uint16_t status){ void display_card_status(void){ lcd_clear(); lcd_home(); + if (host_dead){ + lcd_write_string_sz_P(PSTR("0xDEAD 0xBEAF")); + return; + } + lcd_write_string_sz_P(PSTR("PortalCardReader")); lcd_set_pos(0,1); switch (card_status){ @@ -202,11 +263,11 @@ int main(void){ display_card_status(); //lcd_write_string_sz_P(PSTR("Waiting for Host")); - - //"Ping" host + if (ISO7816_is_card_present()) card_status = CARD_STATUS_INSERTED; + timer_init(); sei(); cardreader_message_t msg; @@ -214,14 +275,21 @@ int main(void){ uint8_t length; uint8_t old_card_status = CARD_STATUS_REMOVED; - - transport_send_interrupt_message(CARDREADER_INTERRUPT_CARDREADER_ALIVE); - transport_send_interrupt_message(CARDREADER_INTERRUPT_HOST_ALIVE); + transport_send_interrupt_message(CARDREADER_INTERRUPT_CARDREADER_ALIVE); while(1){ wdt_reset(); + if (display_reset){ + display_reset = 0; + display_card_status(); + } + if (host_ping){ + transport_send_interrupt_message(CARDREADER_INTERRUPT_HOST_ALIVE); + host_ping = 0; + } + if (card_status == CARD_STATUS_REMOVED) sleep(); if (card_status != old_card_status){ diff --git a/Control/cardreader_interface.c b/Control/cardreader_interface.c index 715824a..b3828db 100644 --- a/Control/cardreader_interface.c +++ b/Control/cardreader_interface.c @@ -334,14 +334,14 @@ uint8_t cardreader_update_key_result(uint8_t* msg_buffer, uint8_t length){ printf_P(PSTR("Update okay.\n")); - cardreader_display_show_result(1); - - toggle_lock_unlock(); +// cardreader_display_show_result(1); cardreader_display_clear(); - cardreader_display_write_sz_P(PSTR("Auth Successful")); - cardreader_display_move(0,1); - cardreader_display_write_sz_P(PSTR("Remove Card")); + if (toggle_lock_unlock(cardreader_display_write_sz_P)){ +// cardreader_display_write_sz_P(PSTR("Auth Successful")); + cardreader_display_move(0,1); + cardreader_display_write_sz_P(PSTR("Remove Card")); + } keystore_update_salt(); @@ -442,9 +442,9 @@ void cardreader_display_write_sz_P(char* string){ void cardreader_display_show_result(uint8_t success){ cardreader_display_move(0,1); if (success) { - cardreader_display_write_sz_P(PSTR("OK")); + cardreader_display_write_sz_P(PSTR("OK ")); } else { - cardreader_display_write_sz_P(PSTR("Failed :(")); + cardreader_display_write_sz_P(PSTR("Failed :( ")); } } diff --git a/Control/door.c b/Control/door.c index 479fa57..e44f07f 100644 --- a/Control/door.c +++ b/Control/door.c @@ -149,38 +149,40 @@ void lock(void){ DOOR_PORT = (DOOR_PORT & (uint8_t)~COMMAND_UNLOCK_PIN) | COMMAND_LOCK_PIN; } -uint8_t toggle_lock_unlock(void){ +uint8_t toggle_lock_unlock( void (*msg_target)(char*) ){ if ((door_status & DOOR_STATUS_UNLOCKED) == 0){ -// if (door_status & DOOR_STATUS_LOCKED){ - return unlock_checked(); + return unlock_checked(msg_target); } else { - return lock_checked(); + return lock_checked(msg_target); } } -uint8_t unlock_checked(void){ +uint8_t unlock_checked( void (*msg_target)(char*) ){ if (door_status & DOOR_STATUS_UNLOCKED){ - printf_P(PSTR("Already unlocked\n")); + msg_target(PSTR("Already unlocked\n")); } else if (door_status & DOOR_STATUS_LOCKING){ - printf_P(PSTR("Can't unlock while locking in progress\n")); + msg_target(PSTR("Can't unlock while locking\n")); } else { unlock(); + msg_target(PSTR("Unlocking...\n")); return 1; } return 0; } -uint8_t lock_checked(void){ - if (door_status & DOOR_STATUS_ALARM){ - printf_P(PSTR("Can't lock in alarm state\n")); + +uint8_t lock_checked( void (*msg_target)(char*) ){ + if (is_alarm_status(door_status)){ + msg_target(PSTR("Can't lock in alarm state\n")); } else if (door_status & DOOR_STATUS_UNLOCKING) { - printf_P(PSTR("Can't lock while unlocking in progress\n")); + msg_target(PSTR("Can't lock while unlocking\n")); } else if (door_status & DOOR_STATUS_OPEN){ - printf_P(PSTR("Can't lock while door open\n")); + msg_target(PSTR("Can't lock while door open\n")); } else if (door_status & DOOR_STATUS_LOCKED){ - printf_P(PSTR("Already locked\n")); + msg_target(PSTR("Already locked\n")); } else { lock(); + msg_target(PSTR("Locking...\n")); return 1; } return 0; diff --git a/Control/door.h b/Control/door.h index 8492455..21da68d 100644 --- a/Control/door.h +++ b/Control/door.h @@ -43,7 +43,7 @@ uint8_t door_clear_alarm(void); void unlock(void); void lock(void); -uint8_t toggle_lock_unlock(void); -uint8_t unlock_checked(void); -uint8_t lock_checked(void); +uint8_t toggle_lock_unlock( void (*msg_target)(char*) ); +uint8_t unlock_checked( void (*msg_target)(char*) ); +uint8_t lock_checked( void (*msg_target)(char*) ); void door_write_status(void); \ No newline at end of file diff --git a/Control/random.c b/Control/random.c index c6ca1eb..ad7b8ad 100644 --- a/Control/random.c +++ b/Control/random.c @@ -41,7 +41,7 @@ uint8_t rnd_adc_read(void){ return result; } -uint8_t rnd_get_byte(){ +uint8_t rnd_get_byte(void){ seed = _crc16_update(seed, rnd_adc_read()); return ((seed & 0xFF) ^ (seed >> 8)); } @@ -53,5 +53,7 @@ uint8_t rnd_get_bytes(uint8_t* buffer, uint8_t length){ for (uint8_t i = 0; i < length; i++){ buffer[i] = rnd_get_byte(); } + + RNG_DORT &= ~RNG_POWER_PIN; return 1; } \ No newline at end of file diff --git a/Control/shell/shell.c b/Control/shell/shell.c index cedda17..06231ff 100644 --- a/Control/shell/shell.c +++ b/Control/shell/shell.c @@ -291,20 +291,26 @@ void cmd_keyslot_list(readline_parsed_cmd_t* cmd){ keystore_list(); } +void print_P(char* pstr){ + printf_P(pstr); +} + + void cmd_lock(readline_parsed_cmd_t* cmd){ if ((cmd->num_args > 0) && (strcmp(cmd->args[0], "-f") == 0)){ lock(); } else { - lock_checked(); + lock_checked(print_P); } } void cmd_unlock(readline_parsed_cmd_t* cmd){ if ((cmd->num_args > 0) && (strcmp(cmd->args[0], "-f") == 0)){ unlock(); } else { - unlock_checked(); + unlock_checked(print_P); } } + void cmd_status(readline_parsed_cmd_t* cmd){ door_write_status(); printf_P(PSTR("\n")); -- GitLab