From de51fc2fd4bfb5ab3e30fc8499de9adcd95be422 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 18 Jun 2012 12:24:54 +0900 Subject: [PATCH] LED display change --- ChangeLog | 23 ++ NEWS | 7 + src/flash.c | 2 +- src/gnuk.h | 15 +- src/main.c | 276 ++++++++++-------------- src/main.c.~HEAD~ | 519 ++++++++++++++++++++++++++++++++++++++++++++++ src/neug.c | 6 +- src/openpgp-do.c | 6 +- src/openpgp.c | 14 +- src/pin-cir.c | 6 +- src/pin-dial.c | 2 +- src/pin-dnd.c | 4 +- src/sys.c | 2 +- src/usb-icc.c | 3 +- src/usb-msc.c | 4 +- src/usb_ctrl.c | 1 - src/usb_desc.c | 2 +- src/usb_lld.c | 6 +- 18 files changed, 696 insertions(+), 202 deletions(-) create mode 100644 src/main.c.~HEAD~ diff --git a/ChangeLog b/ChangeLog index 93848bd..ee9265d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2012-06-18 Niibe Yutaka + + LED display output change. + * src/main.c (MAIN_TIMEOUT_INTERVAL): New. + (LED_TIMEOUT_INTERVAL, etc.): New values. + (main_mode, display_interaction): Remove. + (led_inverted, emit_led): New. + (display_status_code): Use emit_led. + (led_blink): Use LED_* for spec. + (main, fatal): New LED display output. + * src/gnuk.h (LED_ONESHOT, LED_TWOSHOTS, LED_SHOW_STATUS) + (LED_START_COMMAND, LED_FINISH_COMMAND, LED_FATAL): New semantics. + (main_thread): Remove. + * src/openpgp-do.c (gpg_do_keygen): Don't touch LED here. + * src/openpgp.c (get_pinpad_input): Call led_blink. + (cmd_pso, cmd_internal_authenticate): Don't touch LED here. + (GPGthread): Call led_blink. + * src/pin-cir.c (pinpad_getline): Change arg of led_blink. + * src/pin-dnd.c (pinpad_getline): Ditto. + * src/usb-icc.c (icc_handle_timeout): Ditto. + (icc_send_status): Call led_blink. + * src/usb_ctrl.c (gnuk_usb_event): Don't touch LED here. + 2012-06-16 Niibe Yutaka Use SHA256 format for "external authenticate". diff --git a/NEWS b/NEWS index c1c8e4f..a1ac945 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,13 @@ Gnuk NEWS - User visible changes Released 2012-XX-XX, by NIIBE Yutaka +** LED display output change +LED display output by Gnuk is now more reactive. It shows status code +when it gets GET_STATUS message of CCID. When you communicate Gnuk by +internal CCID driver of GnuPG (instead of PC/SC), and enable +'debug-disable-ticker' option in .gnupg/scdaemon.conf, it is more +silent now. + ** Key generation feature added Finally, key generation is supported. Note that it may be very slow. It will take a few minutes (or more) to generate two or three keys, diff --git a/src/flash.c b/src/flash.c index d8ad658..0f13b62 100644 --- a/src/flash.c +++ b/src/flash.c @@ -46,7 +46,7 @@ * .data * _bss_start * .bss - * _end + * _end * * ch_certificate_startp * <2048 bytes> diff --git a/src/gnuk.h b/src/gnuk.h index 26762a2..8b33400 100644 --- a/src/gnuk.h +++ b/src/gnuk.h @@ -315,7 +315,7 @@ extern uint8_t admin_authorized; /* 123-counters: Recorded in flash memory by 2-halfword (4-byte). */ /* * Representation of 123-counters: - * 0: No record in flash memory + * 0: No record in flash memory * 1: 0xfe?? 0xffff * 2: 0xfe?? 0xc3c3 * 3: 0xfe?? 0x0000 @@ -366,13 +366,12 @@ extern void flash_do_write_internal (const uint8_t *p, int nr, const uint8_t *da extern const uint8_t gnukStringSerial[]; -#define LED_ONESHOT_SHORT ((eventmask_t)1) -#define LED_ONESHOT_LONG ((eventmask_t)2) -#define LED_TWOSHOT ((eventmask_t)4) -#define LED_STATUS_MODE ((eventmask_t)8) -#define LED_WAIT_MODE ((eventmask_t)16) -#define LED_FATAL_MODE ((eventmask_t)32) -extern Thread *main_thread; +#define LED_ONESHOT ((eventmask_t)1) +#define LED_TWOSHOTS ((eventmask_t)2) +#define LED_SHOW_STATUS ((eventmask_t)4) +#define LED_START_COMMAND ((eventmask_t)8) +#define LED_FINISH_COMMAND ((eventmask_t)16) +#define LED_FATAL ((eventmask_t)32) extern void led_blink (int spec); #if defined(PINPAD_SUPPORT) diff --git a/src/main.c b/src/main.c index 1bd2e99..35a7979 100644 --- a/src/main.c +++ b/src/main.c @@ -170,10 +170,12 @@ extern msg_t USBthread (void *arg); /* * main thread does 1-bit LED display output */ -#define LED_TIMEOUT_INTERVAL MS2ST(100) -#define LED_TIMEOUT_ZERO MS2ST(50) -#define LED_TIMEOUT_ONE MS2ST(200) -#define LED_TIMEOUT_STOP MS2ST(500) +#define MAIN_TIMEOUT_INTERVAL MS2ST(5000) + +#define LED_TIMEOUT_INTERVAL MS2ST(75) +#define LED_TIMEOUT_ZERO MS2ST(25) +#define LED_TIMEOUT_ONE MS2ST(100) +#define LED_TIMEOUT_STOP MS2ST(200) #define ID_OFFSET 22 @@ -194,7 +196,7 @@ device_initialize_once (void) for (i = 0; i < 4; i++) { uint8_t b = u[i]; - uint8_t nibble; + uint8_t nibble; nibble = (b >> 4); nibble += (nibble >= 10 ? ('A' - 10) : '0'); @@ -208,94 +210,64 @@ device_initialize_once (void) static volatile uint8_t fatal_code; -Thread *main_thread; - -#define GNUK_INIT 0 -#define GNUK_RUNNING 1 -#define GNUK_WAIT 2 -#define GNUK_FATAL 255 -/* - * 0 for initializing - * 1 for normal mode - * 2 for input waiting / under calculation - * 255 for fatal - */ -static uint8_t main_mode; - -static void display_interaction (void) -{ - eventmask_t m; - - set_led (1); - while (1) - { - m = chEvtWaitOne (ALL_EVENTS); - set_led (0); - switch (m) - { - case LED_ONESHOT_SHORT: - chThdSleep (MS2ST (100)); - break; - case LED_ONESHOT_LONG: - chThdSleep (MS2ST (400)); - break; - case LED_TWOSHOT: - chThdSleep (MS2ST (50)); - set_led (1); - chThdSleep (MS2ST (50)); - set_led (0); - chThdSleep (MS2ST (50)); - break; - case LED_STATUS_MODE: - main_mode = GNUK_RUNNING; - return; - case LED_FATAL_MODE: - main_mode = GNUK_FATAL; - return; - default: - break; - } - set_led (1); - } -} +static Thread *main_thread; static void display_fatal_code (void) { - set_led (1); - chThdSleep (LED_TIMEOUT_ZERO); - set_led (0); - chThdSleep (LED_TIMEOUT_INTERVAL); - set_led (1); - chThdSleep (LED_TIMEOUT_ZERO); - set_led (0); - chThdSleep (LED_TIMEOUT_INTERVAL); - set_led (1); - chThdSleep (LED_TIMEOUT_ZERO); - set_led (0); - chThdSleep (LED_TIMEOUT_STOP); - set_led (1); - if (fatal_code & 1) - chThdSleep (LED_TIMEOUT_ONE); - else - chThdSleep (LED_TIMEOUT_ZERO); - set_led (0); - chThdSleep (LED_TIMEOUT_INTERVAL); - set_led (1); - if (fatal_code & 2) - chThdSleep (LED_TIMEOUT_ONE); - else - chThdSleep (LED_TIMEOUT_ZERO); - set_led (0); - chThdSleep (LED_TIMEOUT_INTERVAL); - set_led (1); - chThdSleep (LED_TIMEOUT_STOP); - set_led (0); - chThdSleep (LED_TIMEOUT_INTERVAL); + while (1) + { + set_led (1); + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_STOP); + set_led (1); + if (fatal_code & 1) + chThdSleep (LED_TIMEOUT_ONE); + else + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + if (fatal_code & 2) + chThdSleep (LED_TIMEOUT_ONE); + else + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + chThdSleep (LED_TIMEOUT_STOP); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL*10); + } } -static void display_status_code (void) +static uint8_t led_inverted; + +static eventmask_t emit_led (int on_time, int off_time) +{ + eventmask_t m; + + set_led (!led_inverted); + m = chEvtWaitOneTimeout (ALL_EVENTS, on_time); + set_led (led_inverted); + if (m) return m; + if ((m = chEvtWaitOneTimeout (ALL_EVENTS, off_time))) + return m; + return 0; +} + +static eventmask_t display_status_code (void) { enum icc_state icc_state; + eventmask_t m; if (icc_state_p == NULL) icc_state = ICC_STATE_START; @@ -303,70 +275,47 @@ static void display_status_code (void) icc_state = *icc_state_p; if (icc_state == ICC_STATE_START) - { - set_led (1); - chThdSleep (LED_TIMEOUT_ONE); - set_led (0); - chThdSleep (LED_TIMEOUT_STOP * 3); - } + return emit_led (LED_TIMEOUT_ONE, LED_TIMEOUT_STOP); else /* GPGthread running */ { - set_led (1); - if ((auth_status & AC_ADMIN_AUTHORIZED) != 0) - chThdSleep (LED_TIMEOUT_ONE); - else - chThdSleep (LED_TIMEOUT_ZERO); - set_led (0); - chThdSleep (LED_TIMEOUT_INTERVAL); - set_led (1); - if ((auth_status & AC_OTHER_AUTHORIZED) != 0) - chThdSleep (LED_TIMEOUT_ONE); - else - chThdSleep (LED_TIMEOUT_ZERO); - set_led (0); - chThdSleep (LED_TIMEOUT_INTERVAL); - set_led (1); - if ((auth_status & AC_PSO_CDS_AUTHORIZED) != 0) - chThdSleep (LED_TIMEOUT_ONE); - else - chThdSleep (LED_TIMEOUT_ZERO); + if ((m = emit_led ((auth_status & AC_ADMIN_AUTHORIZED)? + LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, + LED_TIMEOUT_INTERVAL))) + return m; + if ((m = emit_led ((auth_status & AC_OTHER_AUTHORIZED)? + LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, + LED_TIMEOUT_INTERVAL))) + return m; + if ((m = emit_led ((auth_status & AC_PSO_CDS_AUTHORIZED)? + LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, + LED_TIMEOUT_INTERVAL))) + return m; if (icc_state == ICC_STATE_WAIT) { - set_led (0); - chThdSleep (LED_TIMEOUT_STOP * 2); - } - else if (icc_state == ICC_STATE_RECEIVE) - { - set_led (0); - chThdSleep (LED_TIMEOUT_INTERVAL); - set_led (1); - chThdSleep (LED_TIMEOUT_ONE); - set_led (0); - chThdSleep (LED_TIMEOUT_STOP); + if ((m = chEvtWaitOneTimeout (ALL_EVENTS, LED_TIMEOUT_STOP * 2))) + return m; } else { - set_led (0); - chThdSleep (LED_TIMEOUT_INTERVAL); - set_led (1); - chThdSleep (LED_TIMEOUT_STOP); - set_led (0); - chThdSleep (LED_TIMEOUT_INTERVAL); + if ((m = chEvtWaitOneTimeout (ALL_EVENTS, LED_TIMEOUT_INTERVAL))) + return m; + + if ((m = emit_led (icc_state == ICC_STATE_RECEIVE? + LED_TIMEOUT_ONE : LED_TIMEOUT_ZERO, + LED_TIMEOUT_STOP))) + return m; } + + return 0; } } void led_blink (int spec) { - if (spec == 0) - chEvtSignal (main_thread, LED_ONESHOT_SHORT); - else if (spec == 1) - chEvtSignal (main_thread, LED_ONESHOT_LONG); - else - chEvtSignal (main_thread, LED_TWOSHOT); + chEvtSignal (main_thread, spec); } @@ -379,7 +328,9 @@ led_blink (int spec) int main (int argc, char *argv[]) { +#ifdef DEBUG_MORE int count = 0; +#endif (void)argc; (void)argv; @@ -416,6 +367,7 @@ main (int argc, char *argv[]) msc_init (); #endif + while (1) { eventmask_t m; @@ -423,42 +375,42 @@ main (int argc, char *argv[]) if (icc_state_p != NULL && *icc_state_p == ICC_STATE_EXEC_REQUESTED) break; +#ifdef DEBUG_MORE count++; - m = chEvtWaitOneTimeout (ALL_EVENTS, LED_TIMEOUT_INTERVAL); +#endif + + m = chEvtWaitOneTimeout (ALL_EVENTS, MAIN_TIMEOUT_INTERVAL); + got_it: switch (m) { - case LED_STATUS_MODE: - main_mode = GNUK_RUNNING; + case LED_ONESHOT: + if ((m = emit_led (MS2ST (100), MAIN_TIMEOUT_INTERVAL))) goto got_it; break; - case LED_FATAL_MODE: - main_mode = GNUK_FATAL; + case LED_TWOSHOTS: + if ((m = emit_led (MS2ST (50), MS2ST (50)))) goto got_it; + if ((m = emit_led (MS2ST (50), MAIN_TIMEOUT_INTERVAL))) goto got_it; break; - case LED_WAIT_MODE: - main_mode = GNUK_WAIT; + case LED_SHOW_STATUS: + if ((m = display_status_code ())) goto got_it; break; - default: + case LED_START_COMMAND: + set_led (1); + led_inverted = 1; break; - } - - switch (main_mode) - { - case GNUK_FATAL: + case LED_FINISH_COMMAND: + led_inverted = 0; + set_led (0); + if ((m = chEvtWaitOneTimeout (ALL_EVENTS, LED_TIMEOUT_INTERVAL))) + goto got_it; + break; + case LED_FATAL: display_fatal_code (); break; - case GNUK_INIT: - set_led (1); - chThdSleep (LED_TIMEOUT_ZERO); - set_led (0); - chThdSleep (LED_TIMEOUT_STOP * 3); - break; - case GNUK_WAIT: - display_interaction (); - break; - case GNUK_RUNNING: default: - display_status_code (); + if ((m = emit_led (LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP))) + goto got_it; break; - } + } #ifdef DEBUG_MORE if (bDeviceState == CONFIGURED && (count % 10) == 0) @@ -496,12 +448,12 @@ main (int argc, char *argv[]) /* copy system service routines */ flash_write (FLASH_SYS_START_ADDR, &_sys, 0x1000); - /* Leave Gnuk to exec reGNUal */ + /* Leave Gnuk to exec reGNUal */ (*func) (*((void (**)(void))(&_regnual_start+4))); for (;;); } #else - /* Leave Gnuk to exec reGNUal */ + /* Leave Gnuk to exec reGNUal */ flash_erase_all_and_exec (*((void (**)(void))(&_regnual_start+4))); #endif @@ -513,7 +465,7 @@ void fatal (uint8_t code) { fatal_code = code; - chEvtSignal (main_thread, LED_FATAL_MODE); + chEvtSignal (main_thread, LED_FATAL); _write ("fatal\r\n", 7); for (;;); } diff --git a/src/main.c.~HEAD~ b/src/main.c.~HEAD~ new file mode 100644 index 0000000..1bd2e99 --- /dev/null +++ b/src/main.c.~HEAD~ @@ -0,0 +1,519 @@ +/* + * main.c - main routine of Gnuk + * + * Copyright (C) 2010, 2011, 2012 Free Software Initiative of Japan + * Author: NIIBE Yutaka + * + * This file is a part of Gnuk, a GnuPG USB Token implementation. + * + * Gnuk is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Gnuk is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "config.h" +#include "ch.h" +#include "hal.h" +#include "sys.h" +#include "gnuk.h" +#include "usb_lld.h" +#include "usb-cdc.h" + +#ifdef DEBUG +struct stdout { + Mutex m; + CondVar start_cnd; + CondVar finish_cnd; + const char *str; + int size; +}; + +static struct stdout stdout; + +static void +stdout_init (void) +{ + chMtxInit (&stdout.m); + chCondInit (&stdout.start_cnd); + chCondInit (&stdout.finish_cnd); + stdout.size = 0; + stdout.str = NULL; +} + +void +_write (const char *s, int size) +{ + if (size == 0) + return; + + chMtxLock (&stdout.m); + while (stdout.str) + chCondWait (&stdout.finish_cnd); + stdout.str = s; + stdout.size = size; + chCondSignal (&stdout.start_cnd); + chCondWait (&stdout.finish_cnd); + chMtxUnlock (); +} + +Thread *stdout_thread; +uint32_t count_in; +uint8_t buffer_in[VIRTUAL_COM_PORT_DATA_SIZE]; + +static WORKING_AREA(waSTDOUTthread, 128); + +static msg_t +STDOUTthread (void *arg) +{ + (void)arg; + stdout_thread = chThdSelf (); + + again: + + while (1) + { + if (bDeviceState == CONFIGURED) + break; + + chThdSleepMilliseconds (100); + } + + while (1) + { + const char *p; + int len; + + if (bDeviceState != CONFIGURED) + break; + + chMtxLock (&stdout.m); + if (stdout.str == NULL) + chCondWait (&stdout.start_cnd); + + p = stdout.str; + len = stdout.size; + while (1) + { + int i; + + if (len == 0) + if (count_in != VIRTUAL_COM_PORT_DATA_SIZE) + break; + + if (len < VIRTUAL_COM_PORT_DATA_SIZE) + { + for (i = 0; i < len; i++) + buffer_in[i] = p[i]; + count_in = len; + len = 0; + } + else + { + for (i = 0; i < VIRTUAL_COM_PORT_DATA_SIZE; i++) + buffer_in[i] = p[i]; + len -= VIRTUAL_COM_PORT_DATA_SIZE; + count_in = VIRTUAL_COM_PORT_DATA_SIZE; + p += count_in; + } + + chEvtClear (EV_TX_READY); + + usb_lld_write (ENDP3, buffer_in, count_in); + + chEvtWaitOne (EV_TX_READY); + } + + stdout.str = NULL; + stdout.size = 0; + chCondBroadcast (&stdout.finish_cnd); + chMtxUnlock (); + } + + goto again; + return 0; +} + +void +EP3_IN_Callback (void) +{ + if (stdout_thread) + chEvtSignalI (stdout_thread, EV_TX_READY); +} + +void +EP5_OUT_Callback (void) +{ + usb_lld_rx_enable (ENDP5); +} +#else +void +_write (const char *s, int size) +{ + (void)s; + (void)size; +} +#endif + +static WORKING_AREA(waUSBthread, 128); +extern msg_t USBthread (void *arg); + +/* + * main thread does 1-bit LED display output + */ +#define LED_TIMEOUT_INTERVAL MS2ST(100) +#define LED_TIMEOUT_ZERO MS2ST(50) +#define LED_TIMEOUT_ONE MS2ST(200) +#define LED_TIMEOUT_STOP MS2ST(500) + + +#define ID_OFFSET 22 +static void +device_initialize_once (void) +{ + const uint8_t *p = &gnukStringSerial[ID_OFFSET]; + + if (p[0] == 0xff && p[1] == 0xff && p[2] == 0xff && p[3] == 0xff) + { + /* + * This is the first time invocation. + * Setup serial number by unique device ID. + */ + const uint8_t *u = unique_device_id (); + int i; + + for (i = 0; i < 4; i++) + { + uint8_t b = u[i]; + uint8_t nibble; + + nibble = (b >> 4); + nibble += (nibble >= 10 ? ('A' - 10) : '0'); + flash_put_data_internal (&p[i*4], nibble); + nibble = (b & 0x0f); + nibble += (nibble >= 10 ? ('A' - 10) : '0'); + flash_put_data_internal (&p[i*4+2], nibble); + } + } +} + +static volatile uint8_t fatal_code; + +Thread *main_thread; + +#define GNUK_INIT 0 +#define GNUK_RUNNING 1 +#define GNUK_WAIT 2 +#define GNUK_FATAL 255 +/* + * 0 for initializing + * 1 for normal mode + * 2 for input waiting / under calculation + * 255 for fatal + */ +static uint8_t main_mode; + +static void display_interaction (void) +{ + eventmask_t m; + + set_led (1); + while (1) + { + m = chEvtWaitOne (ALL_EVENTS); + set_led (0); + switch (m) + { + case LED_ONESHOT_SHORT: + chThdSleep (MS2ST (100)); + break; + case LED_ONESHOT_LONG: + chThdSleep (MS2ST (400)); + break; + case LED_TWOSHOT: + chThdSleep (MS2ST (50)); + set_led (1); + chThdSleep (MS2ST (50)); + set_led (0); + chThdSleep (MS2ST (50)); + break; + case LED_STATUS_MODE: + main_mode = GNUK_RUNNING; + return; + case LED_FATAL_MODE: + main_mode = GNUK_FATAL; + return; + default: + break; + } + set_led (1); + } +} + +static void display_fatal_code (void) +{ + set_led (1); + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_STOP); + set_led (1); + if (fatal_code & 1) + chThdSleep (LED_TIMEOUT_ONE); + else + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + if (fatal_code & 2) + chThdSleep (LED_TIMEOUT_ONE); + else + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + chThdSleep (LED_TIMEOUT_STOP); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); +} + +static void display_status_code (void) +{ + enum icc_state icc_state; + + if (icc_state_p == NULL) + icc_state = ICC_STATE_START; + else + icc_state = *icc_state_p; + + if (icc_state == ICC_STATE_START) + { + set_led (1); + chThdSleep (LED_TIMEOUT_ONE); + set_led (0); + chThdSleep (LED_TIMEOUT_STOP * 3); + } + else + /* GPGthread running */ + { + set_led (1); + if ((auth_status & AC_ADMIN_AUTHORIZED) != 0) + chThdSleep (LED_TIMEOUT_ONE); + else + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + if ((auth_status & AC_OTHER_AUTHORIZED) != 0) + chThdSleep (LED_TIMEOUT_ONE); + else + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + if ((auth_status & AC_PSO_CDS_AUTHORIZED) != 0) + chThdSleep (LED_TIMEOUT_ONE); + else + chThdSleep (LED_TIMEOUT_ZERO); + + if (icc_state == ICC_STATE_WAIT) + { + set_led (0); + chThdSleep (LED_TIMEOUT_STOP * 2); + } + else if (icc_state == ICC_STATE_RECEIVE) + { + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + chThdSleep (LED_TIMEOUT_ONE); + set_led (0); + chThdSleep (LED_TIMEOUT_STOP); + } + else + { + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + chThdSleep (LED_TIMEOUT_STOP); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + } + } +} + +void +led_blink (int spec) +{ + if (spec == 0) + chEvtSignal (main_thread, LED_ONESHOT_SHORT); + else if (spec == 1) + chEvtSignal (main_thread, LED_ONESHOT_LONG); + else + chEvtSignal (main_thread, LED_TWOSHOT); +} + + +/* + * Entry point. + * + * NOTE: the main function is already a thread in the system on entry. + * See the hwinit1_common function. + */ +int +main (int argc, char *argv[]) +{ + int count = 0; + + (void)argc; + (void)argv; + + main_thread = chThdSelf (); + + flash_unlock (); + device_initialize_once (); + usb_lld_init (Config_Descriptor.Descriptor[7]); + random_init (); + + while (1) + { + if (bDeviceState != UNCONNECTED) + break; + + chThdSleepMilliseconds (250); + } + +#ifdef DEBUG + stdout_init (); + + /* + * Creates 'stdout' thread. + */ + chThdCreateStatic (waSTDOUTthread, sizeof(waSTDOUTthread), + NORMALPRIO, STDOUTthread, NULL); +#endif + + chThdCreateStatic (waUSBthread, sizeof(waUSBthread), + NORMALPRIO, USBthread, NULL); + +#ifdef PINPAD_DND_SUPPORT + msc_init (); +#endif + + while (1) + { + eventmask_t m; + + if (icc_state_p != NULL && *icc_state_p == ICC_STATE_EXEC_REQUESTED) + break; + + count++; + m = chEvtWaitOneTimeout (ALL_EVENTS, LED_TIMEOUT_INTERVAL); + switch (m) + { + case LED_STATUS_MODE: + main_mode = GNUK_RUNNING; + break; + case LED_FATAL_MODE: + main_mode = GNUK_FATAL; + break; + case LED_WAIT_MODE: + main_mode = GNUK_WAIT; + break; + default: + break; + } + + switch (main_mode) + { + case GNUK_FATAL: + display_fatal_code (); + break; + case GNUK_INIT: + set_led (1); + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_STOP * 3); + break; + case GNUK_WAIT: + display_interaction (); + break; + case GNUK_RUNNING: + default: + display_status_code (); + break; + } + +#ifdef DEBUG_MORE + if (bDeviceState == CONFIGURED && (count % 10) == 0) + { + DEBUG_SHORT (count / 10); + _write ("\r\nThis is ChibiOS 2.0.8 on STM32.\r\n" + "Testing USB driver.\n\n" + "Hello world\r\n\r\n", 35+21+15); + } +#endif + } + + set_led (1); + usb_lld_shutdown (); + /* Disable SysTick */ + SysTick->CTRL = 0; + /* Disable all interrupts */ + port_disable (); + /* Set vector */ + SCB->VTOR = (uint32_t)&_regnual_start; +#ifdef DFU_SUPPORT +#define FLASH_SYS_START_ADDR 0x08000000 +#define FLASH_SYS_END_ADDR (0x08000000+0x1000) + { + extern uint8_t _sys; + uint32_t addr; + handler *new_vector = (handler *)FLASH_SYS_START_ADDR; + void (*func) (void (*)(void)) = (void (*)(void (*)(void)))new_vector[10]; + + /* Kill DFU */ + for (addr = FLASH_SYS_START_ADDR; addr < FLASH_SYS_END_ADDR; + addr += FLASH_PAGE_SIZE) + flash_erase_page (addr); + + /* copy system service routines */ + flash_write (FLASH_SYS_START_ADDR, &_sys, 0x1000); + + /* Leave Gnuk to exec reGNUal */ + (*func) (*((void (**)(void))(&_regnual_start+4))); + for (;;); + } +#else + /* Leave Gnuk to exec reGNUal */ + flash_erase_all_and_exec (*((void (**)(void))(&_regnual_start+4))); +#endif + + /* Never reached */ + return 0; +} + +void +fatal (uint8_t code) +{ + fatal_code = code; + chEvtSignal (main_thread, LED_FATAL_MODE); + _write ("fatal\r\n", 7); + for (;;); +} diff --git a/src/neug.c b/src/neug.c index be95ae9..5753094 100644 --- a/src/neug.c +++ b/src/neug.c @@ -32,15 +32,15 @@ static Thread *rng_thread; /* Total number of channels to be sampled by a single ADC operation.*/ #define ADC_GRP1_NUM_CHANNELS 2 - + /* Depth of the conversion buffer, channels are sampled one time each.*/ #define ADC_GRP1_BUF_DEPTH 4 - + /* * ADC samples buffer. */ static adcsample_t samp[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH]; - + static void adccb (adcsample_t *buffer, size_t n); /* diff --git a/src/openpgp-do.c b/src/openpgp-do.c index 300b50f..d9c0406 100644 --- a/src/openpgp-do.c +++ b/src/openpgp-do.c @@ -807,7 +807,7 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len, uint8_t ks123_pw1[KEYSTRING_SIZE_PW1]; ks123_pw1[0] = strlen (OPENPGP_CARD_INITIAL_PW1); - sha256 ((uint8_t *)OPENPGP_CARD_INITIAL_PW1, + sha256 ((uint8_t *)OPENPGP_CARD_INITIAL_PW1, strlen (OPENPGP_CARD_INITIAL_PW1), ks123_pw1+1); encrypt_dek (ks123_pw1+1, pd->dek_encrypted_1); } @@ -1036,7 +1036,7 @@ gpg_do_table[] = { / sizeof (struct do_table_entry)) /* - * Reading data from Flash ROM, initialize DO_PTR, PW_ERR_COUNTERS, etc. + * Reading data from Flash ROM, initialize DO_PTR, PW_ERR_COUNTERS, etc. */ void gpg_data_scan (const uint8_t *p_start) @@ -1534,9 +1534,7 @@ gpg_do_keygen (uint8_t kk_byte) else keystring_admin = NULL; - chEvtSignal (main_thread, LED_WAIT_MODE); p_q_modulus = rsa_genkey (); - chEvtSignal (main_thread, LED_STATUS_MODE); if (p_q_modulus == NULL) { GPG_MEMORY_FAILURE (); diff --git a/src/openpgp.c b/src/openpgp.c index 89b218b..966d017 100644 --- a/src/openpgp.c +++ b/src/openpgp.c @@ -107,7 +107,7 @@ gpg_fini (void) } #if defined(PINPAD_SUPPORT) -/* +/* * Let user input PIN string. * Return length of the string. * The string itself is in PIN_INPUT_BUFFER. @@ -117,9 +117,9 @@ get_pinpad_input (int msg_code) { int r; - chEvtSignal (main_thread, LED_WAIT_MODE); + led_blink (LED_START_COMMAND); r = pinpad_getline (msg_code, MS2ST (8000)); - chEvtSignal (main_thread, LED_STATUS_MODE); + led_blink (LED_FINISH_COMMAND); return r; } #endif @@ -724,10 +724,8 @@ cmd_pso (void) DEBUG_SHORT (len); DEBUG_BINARY (&kd[GPG_KEY_FOR_SIGNING], KEY_CONTENT_LEN); - chEvtSignal (main_thread, LED_WAIT_MODE); r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len, &kd[GPG_KEY_FOR_SIGNING]); - chEvtSignal (main_thread, LED_STATUS_MODE); if (r < 0) { ac_reset_pso_cds (); @@ -752,10 +750,8 @@ cmd_pso (void) /* Skip padding 0x00 */ len--; - chEvtSignal (main_thread, LED_WAIT_MODE); r = rsa_decrypt (apdu.cmd_apdu_data+1, res_APDU, len, &kd[GPG_KEY_FOR_DECRYPTION]); - chEvtSignal (main_thread, LED_STATUS_MODE); if (r < 0) GPG_ERROR (); } @@ -799,10 +795,8 @@ cmd_internal_authenticate (void) return; } - chEvtSignal (main_thread, LED_WAIT_MODE); r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len, &kd[GPG_KEY_FOR_AUTHENTICATION]); - chEvtSignal (main_thread, LED_STATUS_MODE); if (r < 0) GPG_ERROR (); } @@ -1139,7 +1133,9 @@ GPGthread (void *arg) else if (m == EV_NOP) continue; + led_blink (LED_START_COMMAND); process_command_apdu (); + led_blink (LED_FINISH_COMMAND); done: chEvtSignal (icc_thread, EV_EXEC_FINISHED); } diff --git a/src/pin-cir.c b/src/pin-cir.c index 4bf1052..75c8f62 100644 --- a/src/pin-cir.c +++ b/src/pin-cir.c @@ -595,7 +595,7 @@ cir_getchar (systime_t timeout) static Thread *pin_thread; -/* +/* * Let user input PIN string. * Return length of the string. * The string itself is in PIN_INPUT_BUFFER. @@ -620,7 +620,7 @@ pinpad_getline (int msg_code, systime_t timeout) if (ch_is_backspace (ch)) { - led_blink (2); + led_blink (LED_TWOSHOTS); if (pin_input_len > 0) pin_input_len--; } @@ -628,7 +628,7 @@ pinpad_getline (int msg_code, systime_t timeout) break; else if (pin_input_len < MAX_PIN_CHARS) { - led_blink (0); + led_blink (LED_ONESHOT); pin_input_buffer[pin_input_len++] = ch; } } diff --git a/src/pin-dial.c b/src/pin-dial.c index 5fd471e..d1e49d5 100644 --- a/src/pin-dial.c +++ b/src/pin-dial.c @@ -51,7 +51,7 @@ uint8_t pin_input_len; #define OFF '\x00' #define ENTER '\x0a' -static struct led_pattern { uint8_t c, v; } led_pattern[] = +static struct led_pattern { uint8_t c, v; } led_pattern[] = { /* char : dp a b c d e f g */ { ENTER, 0xf8 }, /* |- : 1 1 1 1 1 0 0 0 (enter) */ diff --git a/src/pin-dnd.c b/src/pin-dnd.c index 08238e6..aa1e1e4 100644 --- a/src/pin-dnd.c +++ b/src/pin-dnd.c @@ -41,7 +41,7 @@ uint8_t pin_input_len; static Thread *pin_thread; -/* +/* * Let user input PIN string. * Return length of the string. * The string itself is in PIN_INPUT_BUFFER. @@ -71,7 +71,7 @@ pinpad_getline (int msg_code, systime_t timeout) msg = chThdSelf ()->p_u.rdymsg; chSysUnlock (); - led_blink (0); + led_blink (LED_ONESHOT); if (msg != 0) break; } diff --git a/src/sys.c b/src/sys.c index 0c1cc00..7e70df1 100644 --- a/src/sys.c +++ b/src/sys.c @@ -116,7 +116,7 @@ flash_erase_page (uint32_t addr) if (status == 0) { FLASH->CR |= FLASH_CR_PER; - FLASH->AR = addr; + FLASH->AR = addr; FLASH->CR |= FLASH_CR_STRT; status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT); diff --git a/src/usb-icc.c b/src/usb-icc.c index bb04104..d906548 100644 --- a/src/usb-icc.c +++ b/src/usb-icc.c @@ -803,6 +803,7 @@ icc_send_status (struct ccid *c) c->epi->tx_done = 1; usb_lld_write (c->epi->ep_num, icc_reply, ICC_MSG_HEADER_SIZE); + led_blink (LED_SHOW_STATUS); #ifdef DEBUG_MORE DEBUG_INFO ("St\r\n"); #endif @@ -1260,7 +1261,7 @@ icc_handle_timeout (struct ccid *c) { case ICC_STATE_EXECUTE: icc_send_data_block (c, ICC_CMD_STATUS_TIMEEXT); - led_blink (2); + led_blink (LED_ONESHOT); break; default: break; diff --git a/src/usb-msc.c b/src/usb-msc.c index 0a5ebac..cacef7a 100644 --- a/src/usb-msc.c +++ b/src/usb-msc.c @@ -372,7 +372,7 @@ void msc_handle_command (void) msc_send_result (buf, 12); return; case SCSI_START_STOP_UNIT: - if (CBW.CBWCB[4] == 0x00 /* stop */ + if (CBW.CBWCB[4] == 0x00 /* stop */ || CBW.CBWCB[4] == 0x02 /* eject */ || CBW.CBWCB[4] == 0x03 /* close */) { msc_scsi_stop (CBW.CBWCB[4]); @@ -380,7 +380,7 @@ void msc_handle_command (void) contingent_allegiance = 1; keep_contingent_allegiance = 1; } - /* CBW.CBWCB[4] == 0x01 *//* start */ + /* CBW.CBWCB[4] == 0x01 *//* start */ goto success; case SCSI_TEST_UNIT_READY: if (contingent_allegiance) diff --git a/src/usb_ctrl.c b/src/usb_ctrl.c index 4609f01..49cb8d0 100644 --- a/src/usb_ctrl.c +++ b/src/usb_ctrl.c @@ -381,7 +381,6 @@ static int gnuk_usb_event (uint8_t event_type, uint16_t value) for (i = 0; i < NUM_INTERFACES; i++) gnuk_setup_endpoints_for_interface (i, 0); bDeviceState = CONFIGURED; - chEvtSignalI (main_thread, LED_STATUS_MODE); } else if (current_conf != value) { diff --git a/src/usb_desc.c b/src/usb_desc.c index 9cb5406..c6f1fa4 100644 --- a/src/usb_desc.c +++ b/src/usb_desc.c @@ -261,7 +261,7 @@ const uint8_t gnukStringSerial[] = { 18*2+2, /* bLength */ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ /* FSIJ-0.19 */ - 'F', 0, 'S', 0, 'I', 0, 'J', 0, '-', 0, + 'F', 0, 'S', 0, 'I', 0, 'J', 0, '-', 0, '0', 0, '.', 0, '1', 0, '9', 0, /* Version number of Gnuk */ '-', 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, diff --git a/src/usb_lld.c b/src/usb_lld.c index 3827c32..df0c2f9 100644 --- a/src/usb_lld.c +++ b/src/usb_lld.c @@ -852,11 +852,11 @@ static void handle_setup0 (void) if (USB_SETUP_GET (ctrl_p->bmRequestType)) { uint32_t len = ctrl_p->wLength; - + /* Restrict the data length to be the one host asks for */ if (data_p->len > len) data_p->len = len; - + if ((data_p->len % USB_MAX_PACKET_SIZE) == 0) data_p->require_zlp = TRUE; else @@ -871,7 +871,7 @@ static void handle_setup0 (void) st103_set_tx_count (ENDP0, 0); st103_ep_set_rxtx_status (ENDP0, EP_RX_STALL, EP_TX_VALID); } - else + else { dev_p->state = OUT_DATA; st103_ep_set_rx_status (ENDP0, EP_RX_VALID);