USB Reset handling

This commit is contained in:
NIIBE Yutaka 2015-09-09 18:49:01 +09:00
parent 748c3cac6c
commit f505dea314
17 changed files with 166 additions and 142 deletions

View File

@ -1,6 +1,14 @@
2015-09-09 Niibe Yutaka <gniibe@fsij.org>
* src/main.c (main): Handle LED_USB_RESET.
* src/usb-icc.c (ccid_usb_reset): New.
(ccid_thread): Upon receival of EV_USB_RESET, finish
the thread, canceling the card thread.
2015-09-08 Niibe Yutaka <gniibe@fsij.org> 2015-09-08 Niibe Yutaka <gniibe@fsij.org>
* src/gnuk.h (EV_RESET, LED_RESET): New. * src/gnuk.h (EV_USB_RESET, LED_USB_RESET): New.
* src/usb_ctrl.c (CDC_CTRL_DTR): New. * src/usb_ctrl.c (CDC_CTRL_DTR): New.
(vcom_port_data_setup): Distinguish detail->value for DTR. (vcom_port_data_setup): Distinguish detail->value for DTR.

View File

@ -22,13 +22,14 @@ extern struct apdu apdu;
#define CARD_CHANGE_REMOVE 1 #define CARD_CHANGE_REMOVE 1
#define CARD_CHANGE_TOGGLE 2 #define CARD_CHANGE_TOGGLE 2
void ccid_card_change_signal (int how); void ccid_card_change_signal (int how);
void ccid_usb_reset (void);
/* CCID thread */ /* CCID thread */
#define EV_RX_DATA_READY 1 /* USB Rx data available */ #define EV_RX_DATA_READY 1 /* USB Rx data available */
#define EV_EXEC_FINISHED 2 /* OpenPGP Execution finished */ #define EV_EXEC_FINISHED 2 /* OpenPGP Execution finished */
#define EV_TX_FINISHED 4 /* CCID Tx finished */ #define EV_TX_FINISHED 4 /* CCID Tx finished */
#define EV_CARD_CHANGE 8 #define EV_CARD_CHANGE 8
#define EV_RESET 16 #define EV_USB_RESET 16
/* OpenPGPcard thread */ /* OpenPGPcard thread */
#define EV_PINPAD_INPUT_DONE 1 #define EV_PINPAD_INPUT_DONE 1
@ -423,7 +424,7 @@ extern const uint8_t gnuk_string_serial[];
#define LED_START_COMMAND 8 #define LED_START_COMMAND 8
#define LED_FINISH_COMMAND 16 #define LED_FINISH_COMMAND 16
#define LED_FATAL 32 #define LED_FATAL 32
#define LED_RESET 64 #define LED_USB_RESET 64
void led_blink (int spec); void led_blink (int spec);
#if defined(PINPAD_SUPPORT) #if defined(PINPAD_SUPPORT)

View File

@ -391,6 +391,13 @@ main (int argc, char *argv[])
case LED_FATAL: case LED_FATAL:
display_fatal_code (); display_fatal_code ();
break; break;
case LED_USB_RESET:
ccid_reset ();
chopstx_join (ccid_thd, NULL);
/* Invoke the CCID thread again. */
ccid_thd = chopstx_create (PRIO_CCID, __stackaddr_ccid,
__stacksize_ccid, USBthread, NULL);
break;
default: default:
if ((m = emit_led (LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP))) if ((m = emit_led (LED_TIMEOUT_ZERO, LED_TIMEOUT_STOP)))
goto got_it; goto got_it;

View File

@ -1,7 +1,7 @@
/* /*
* usb-icc.c -- USB CCID protocol handling * usb-icc.c -- USB CCID protocol handling
* *
* Copyright (C) 2010, 2011, 2012, 2013, 2014 * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015
* Free Software Initiative of Japan * Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
@ -256,10 +256,7 @@ static void ccid_init (struct ccid *c, struct ep_in *epi, struct ep_out *epo,
c->icc_state = ICC_STATE_NOCARD; c->icc_state = ICC_STATE_NOCARD;
c->state = APDU_STATE_WAIT_COMMAND; c->state = APDU_STATE_WAIT_COMMAND;
/* c->p = a->cmd_apdu_data;
* Note: a is not yet initialized yet, we can't use c->a->cmd_apdu_data here.
*/
c->p = &icc_buffer[5];
c->len = MAX_CMD_APDU_DATA_SIZE; c->len = MAX_CMD_APDU_DATA_SIZE;
c->err = 0; c->err = 0;
memset (&c->icc_header, 0, sizeof (struct icc_header)); memset (&c->icc_header, 0, sizeof (struct icc_header));
@ -748,7 +745,7 @@ const size_t __stacksize_gpg = (size_t)&__process3_stack_size__;
/* Send back ATR (Answer To Reset) */ /* Send back ATR (Answer To Reset) */
enum icc_state static enum icc_state
icc_power_on (struct ccid *c) icc_power_on (struct ccid *c)
{ {
size_t size_atr = sizeof (ATR); size_t size_atr = sizeof (ATR);
@ -814,7 +811,7 @@ icc_send_status (struct ccid *c)
#endif #endif
} }
enum icc_state static enum icc_state
icc_power_off (struct ccid *c) icc_power_off (struct ccid *c)
{ {
if (c->application) if (c->application)
@ -1310,6 +1307,25 @@ EP2_IN_Callback (void)
} }
void
ccid_card_change_signal (int how)
{
struct ccid *c = &ccid;
if (how == CARD_CHANGE_TOGGLE
|| (c->icc_state == ICC_STATE_NOCARD && how == CARD_CHANGE_INSERT)
|| (c->icc_state != ICC_STATE_NOCARD && how == CARD_CHANGE_REMOVE))
eventflag_signal (&c->ccid_comm, EV_CARD_CHANGE);
}
void
ccid_usb_reset (void)
{
struct ccid *c = &ccid;
eventflag_signal (&c->ccid_comm, EV_USB_RESET);
}
#define USB_ICC_TIMEOUT (1950*1000) #define USB_ICC_TIMEOUT (1950*1000)
#define GPG_THREAD_TERMINATED 0xffff #define GPG_THREAD_TERMINATED 0xffff
@ -1326,18 +1342,6 @@ USBthread (void *arg)
return ccid_thread (thd); return ccid_thread (thd);
} }
void
ccid_card_change_signal (int how)
{
struct ccid *c = &ccid;
if (how == CARD_CHANGE_TOGGLE
|| (c->icc_state == ICC_STATE_NOCARD && how == CARD_CHANGE_INSERT)
|| (c->icc_state != ICC_STATE_NOCARD && how == CARD_CHANGE_REMOVE))
eventflag_signal (&c->ccid_comm, EV_CARD_CHANGE);
}
#define NOTIFY_SLOT_CHANGE 0x50 #define NOTIFY_SLOT_CHANGE 0x50
static void * __attribute__ ((noinline)) static void * __attribute__ ((noinline))
@ -1353,8 +1357,8 @@ ccid_thread (chopstx_t thd)
epi_init (epi, ENDP1, notify_tx, c); epi_init (epi, ENDP1, notify_tx, c);
epo_init (epo, ENDP1, notify_icc, c); epo_init (epo, ENDP1, notify_icc, c);
ccid_init (c, epi, epo, a, thd);
apdu_init (a); apdu_init (a);
ccid_init (c, epi, epo, a, thd);
icc_prepare_receive (c); icc_prepare_receive (c);
while (1) while (1)
@ -1363,7 +1367,9 @@ ccid_thread (chopstx_t thd)
m = eventflag_wait_timeout (&c->ccid_comm, USB_ICC_TIMEOUT); m = eventflag_wait_timeout (&c->ccid_comm, USB_ICC_TIMEOUT);
if (m == EV_CARD_CHANGE) if (m == EV_USB_RESET)
break;
else if (m == EV_CARD_CHANGE)
{ {
if (c->icc_state == ICC_STATE_NOCARD) if (c->icc_state == ICC_STATE_NOCARD)
{ /* Inserted! */ { /* Inserted! */
@ -1447,9 +1453,11 @@ ccid_thread (chopstx_t thd)
if (c->application) if (c->application)
{ {
chopstx_cancel (c->application);
chopstx_join (c->application, NULL); chopstx_join (c->application, NULL);
c->application = 0; c->application = 0;
} }
icc_state_p = NULL;
return NULL; return NULL;
} }

View File

@ -215,7 +215,7 @@ usb_cb_device_reset (void)
gnuk_setup_endpoints_for_interface (i, 0); gnuk_setup_endpoints_for_interface (i, 0);
bDeviceState = ATTACHED; bDeviceState = ATTACHED;
led_blink (LED_RESET); /* Notify the main. */ led_blink (LED_USB_RESET); /* Notify the main. */
} }
#define USB_CCID_REQ_ABORT 0x01 #define USB_CCID_REQ_ABORT 0x01