NumLock card change

This commit is contained in:
NIIBE Yutaka
2013-10-29 13:52:05 +09:00
parent 1f30f4b64b
commit 59d522efba
4 changed files with 110 additions and 33 deletions

View File

@@ -17,6 +17,7 @@ struct apdu {
}; };
extern struct apdu apdu; extern struct apdu apdu;
void ccid_card_change_signal (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 */

View File

@@ -252,7 +252,7 @@ static void ccid_init (struct ccid *c, struct ep_in *epi, struct ep_out *epo,
{ {
icc_state_p = &c->icc_state; icc_state_p = &c->icc_state;
c->icc_state = ICC_STATE_START; c->icc_state = ICC_STATE_NOCARD; /* Default should be _START ?? */
c->state = APDU_STATE_WAIT_COMMAND; c->state = APDU_STATE_WAIT_COMMAND;
/* /*
* Note: a is not yet initialized yet, we can't use c->a->cmd_apdu_data here. * Note: a is not yet initialized yet, we can't use c->a->cmd_apdu_data here.
@@ -722,12 +722,12 @@ static void icc_error (struct ccid *c, int offset)
icc_reply[4] = 0x00; icc_reply[4] = 0x00;
icc_reply[5] = 0x00; /* Slot */ icc_reply[5] = 0x00; /* Slot */
icc_reply[ICC_MSG_SEQ_OFFSET] = c->icc_header.seq; icc_reply[ICC_MSG_SEQ_OFFSET] = c->icc_header.seq;
if (c->icc_state == ICC_STATE_START) if (c->icc_state == ICC_STATE_NOCARD)
/* 1: ICC present but not activated 2: No ICC present */ icc_reply[ICC_MSG_STATUS_OFFSET] = 2; /* 2: No ICC present */
icc_reply[ICC_MSG_STATUS_OFFSET] = 1; else if (c->icc_state == ICC_STATE_START)
icc_reply[ICC_MSG_STATUS_OFFSET] = 1; /* 1: ICC present but not activated */
else else
/* An ICC is present and active */ icc_reply[ICC_MSG_STATUS_OFFSET] = 0; /* An ICC is present and active */
icc_reply[ICC_MSG_STATUS_OFFSET] = 0;
icc_reply[ICC_MSG_STATUS_OFFSET] |= ICC_CMD_STATUS_ERROR; /* Failed */ icc_reply[ICC_MSG_STATUS_OFFSET] |= ICC_CMD_STATUS_ERROR; /* Failed */
icc_reply[ICC_MSG_ERROR_OFFSET] = offset; icc_reply[ICC_MSG_ERROR_OFFSET] = offset;
icc_reply[ICC_MSG_CHAIN_OFFSET] = 0x00; icc_reply[ICC_MSG_CHAIN_OFFSET] = 0x00;
@@ -793,12 +793,12 @@ icc_send_status (struct ccid *c)
icc_reply[4] = 0x00; icc_reply[4] = 0x00;
icc_reply[5] = 0x00; /* Slot */ icc_reply[5] = 0x00; /* Slot */
icc_reply[ICC_MSG_SEQ_OFFSET] = c->icc_header.seq; icc_reply[ICC_MSG_SEQ_OFFSET] = c->icc_header.seq;
if (c->icc_state == ICC_STATE_START) if (c->icc_state == ICC_STATE_NOCARD)
/* 1: ICC present but not activated 2: No ICC present */ icc_reply[ICC_MSG_STATUS_OFFSET] = 2; /* 2: No ICC present */
icc_reply[ICC_MSG_STATUS_OFFSET] = 1; else if (c->icc_state == ICC_STATE_START)
icc_reply[ICC_MSG_STATUS_OFFSET] = 1; /* 1: ICC present but not activated */
else else
/* An ICC is present and active */ icc_reply[ICC_MSG_STATUS_OFFSET] = 0; /* An ICC is present and active */
icc_reply[ICC_MSG_STATUS_OFFSET] = 0;
icc_reply[ICC_MSG_ERROR_OFFSET] = 0x00; icc_reply[ICC_MSG_ERROR_OFFSET] = 0x00;
icc_reply[ICC_MSG_CHAIN_OFFSET] = 0x00; icc_reply[ICC_MSG_CHAIN_OFFSET] = 0x00;
@@ -1075,6 +1075,15 @@ icc_handle_data (struct ccid *c)
switch (c->icc_state) switch (c->icc_state)
{ {
case ICC_STATE_NOCARD:
if (c->icc_header.msg_type == ICC_SLOT_STATUS)
icc_send_status (c);
else
{
DEBUG_INFO ("ERR00\r\n");
icc_error (c, ICC_OFFSET_CMD_NOT_SUPPORTED);
}
break;
case ICC_STATE_START: case ICC_STATE_START:
if (c->icc_header.msg_type == ICC_POWER_ON) if (c->icc_header.msg_type == ICC_POWER_ON)
{ {
@@ -1307,6 +1316,15 @@ USBthread (void *arg)
return ccid_thread (thd); return ccid_thread (thd);
} }
void
ccid_card_change_signal (void)
{
struct ccid *c = &ccid;
eventflag_signal (&c->ccid_comm, EV_CARD_CHANGE);
}
static void * static void *
ccid_thread (chopstx_t thd) ccid_thread (chopstx_t thd)
{ {
@@ -1314,6 +1332,7 @@ ccid_thread (chopstx_t thd)
struct ep_out *epo = &endpoint_out; struct ep_out *epo = &endpoint_out;
struct ccid *c = &ccid; struct ccid *c = &ccid;
struct apdu *a = &apdu; struct apdu *a = &apdu;
int card_change_requested = 0;
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);
@@ -1327,7 +1346,33 @@ 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_RX_DATA_READY) if (m == EV_CARD_CHANGE)
{
if (card_change_requested)
{
led_blink (LED_TWOSHOTS);
if (c->icc_state == ICC_STATE_NOCARD)
/* Inserted! */
c->icc_state = ICC_STATE_START;
else
{
if (c->application)
{
eventflag_signal (&c->openpgp_comm, EV_EXIT);
chopstx_join (c->application, NULL);
c->application = 0;
}
c->icc_state = ICC_STATE_NOCARD;
}
card_change_requested = 0;
}
else
card_change_requested = 1;
}
else if (m == EV_RX_DATA_READY)
c->icc_state = icc_handle_data (c); c->icc_state = icc_handle_data (c);
else if (m == EV_EXEC_FINISHED) else if (m == EV_EXEC_FINISHED)
if (c->icc_state == ICC_STATE_EXECUTE) if (c->icc_state == ICC_STATE_EXECUTE)
@@ -1383,7 +1428,10 @@ ccid_thread (chopstx_t thd)
icc_prepare_receive (c); icc_prepare_receive (c);
} }
else /* Timeout */ else /* Timeout */
c->icc_state = icc_handle_timeout (c); {
c->icc_state = icc_handle_timeout (c);
card_change_requested = 0;
}
} }
return NULL; return NULL;

View File

@@ -130,7 +130,11 @@ uint32_t bDeviceState = UNCONNECTED; /* USB device status */
#define USB_HID_REQ_SET_IDLE 10 #define USB_HID_REQ_SET_IDLE 10
#define USB_HID_REQ_SET_PROTOCOL 11 #define USB_HID_REQ_SET_PROTOCOL 11
#define HID_LED_STATUS_NUMLOCK 0x01
static uint8_t hid_idle_rate; /* in 4ms */ static uint8_t hid_idle_rate; /* in 4ms */
static uint8_t hid_report_saved;
static uint16_t hid_report;
static void static void
gnuk_setup_endpoints_for_interface (uint16_t interface, int stop) gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
@@ -346,11 +350,14 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
return USB_SUCCESS; return USB_SUCCESS;
case USB_HID_REQ_GET_REPORT: case USB_HID_REQ_GET_REPORT:
usb_lld_set_data_to_send (&zero, 2); /* Request of LED status and key press */
usb_lld_set_data_to_send (&hid_report, 2);
return USB_SUCCESS; return USB_SUCCESS;
case USB_HID_REQ_SET_REPORT: case USB_HID_REQ_SET_REPORT:
/* Received LED set request! */ /* Received LED set request */
if (len == 1)
usb_lld_set_data_to_recv (&hid_report, len);
return USB_SUCCESS; return USB_SUCCESS;
case USB_HID_REQ_GET_PROTOCOL: case USB_HID_REQ_GET_PROTOCOL:
@@ -388,20 +395,34 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
return USB_UNSUPPORT; return USB_UNSUPPORT;
} }
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
uint16_t index, uint16_t len) void
usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
uint16_t index, uint16_t len)
{ {
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT); uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT) if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
&& USB_SETUP_SET (req) && req_no == USB_FSIJ_GNUK_EXEC && len == 0)
{ {
if (icc_state_p == NULL || *icc_state_p != ICC_STATE_EXITED) if (USB_SETUP_SET (req) && req_no == USB_FSIJ_GNUK_EXEC && len == 0)
return; {
if (icc_state_p == NULL || *icc_state_p != ICC_STATE_EXITED)
return;
(void)value; (void)index; (void)value; (void)index;
usb_lld_prepare_shutdown (); /* No further USB communication */ usb_lld_prepare_shutdown (); /* No further USB communication */
*icc_state_p = ICC_STATE_EXEC_REQUESTED; *icc_state_p = ICC_STATE_EXEC_REQUESTED;
}
}
else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT))
{
if (index == 1 && req_no == USB_HID_REQ_SET_REPORT)
{
if ((hid_report ^ hid_report_saved) & HID_LED_STATUS_NUMLOCK)
ccid_card_change_signal ();
hid_report_saved = hid_report;
}
} }
} }

View File

@@ -18,7 +18,7 @@
static const uint8_t hid_report_desc[] = { static const uint8_t hid_report_desc[] = {
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
0x09, 0x06, /* USAGE (Keyboard) */ 0x09, 0x07, /* USAGE (Keypad) */
0xa1, 0x01, /* COLLECTION (Application) */ 0xa1, 0x01, /* COLLECTION (Application) */
0x05, 0x07, /* USAGE_PAGE (Key Codes) */ 0x05, 0x07, /* USAGE_PAGE (Key Codes) */
0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */ 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */
@@ -29,16 +29,16 @@ static const uint8_t hid_report_desc[] = {
0x95, 0x08, /* REPORT_COUNT (8) */ 0x95, 0x08, /* REPORT_COUNT (8) */
0x81, 0x02, /* INPUT (Data,Var,Abs); Modifier byte */ 0x81, 0x02, /* INPUT (Data,Var,Abs); Modifier byte */
/* NumLock, CapsLock, ScrollLock, Compose, Kana */ /*
* NumLock, CapsLock, ScrollLock, Compose, Kana, Power, Shift,
* Do Not Disturb
*/
0x05, 0x08, /* USAGE_PAGE (LEDs) */ 0x05, 0x08, /* USAGE_PAGE (LEDs) */
0x19, 0x01, /* USAGE_MINIMUM (1) */ 0x19, 0x01, /* USAGE_MINIMUM (1) */
0x29, 0x05, /* USAGE_MAXIMUM (5) */ 0x29, 0x08, /* USAGE_MAXIMUM (8) */
0x95, 0x05, /* REPORT_COUNT (5) */ 0x95, 0x08, /* REPORT_COUNT (8) */
0x75, 0x01, /* REPORT_SIZE (1) */ 0x75, 0x01, /* REPORT_SIZE (1) */
0x91, 0x02, /* OUTPUT (Data,Var,Abs); LED report */ 0x91, 0x02, /* OUTPUT (Data,Var,Abs); LED report */
0x95, 0x01, /* REPORT_COUNT (1) */
0x75, 0x03, /* REPORT_SIZE (3) */
0x91, 0x01, /* OUTPUT (Constant); LED report padding */
0x05, 0x07, /* USAGE_PAGE (Key Codes) */ 0x05, 0x07, /* USAGE_PAGE (Key Codes) */
0x19, 0x00, /* USAGE_MINIMUM (Reserved (no event indicated)) */ 0x19, 0x00, /* USAGE_MINIMUM (Reserved (no event indicated)) */
@@ -73,7 +73,7 @@ static const uint8_t gnukDeviceDescriptor[] = {
0x01 /* bNumConfigurations */ 0x01 /* bNumConfigurations */
}; };
#define ICC_TOTAL_LENGTH (9+9+54+7+7) #define ICC_TOTAL_LENGTH (9+9+54+7+7+7)
#define ICC_NUM_INTERFACES 1 #define ICC_NUM_INTERFACES 1
#define HID_TOTAL_LENGTH (9+9+7) #define HID_TOTAL_LENGTH (9+9+7)
@@ -126,7 +126,7 @@ static const uint8_t gnukConfigDescriptor[] = {
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
0, /* bInterfaceNumber: Index of this interface */ 0, /* bInterfaceNumber: Index of this interface */
0, /* Alternate setting for this interface */ 0, /* Alternate setting for this interface */
2, /* bNumEndpoints: Bulk-IN, Bulk-OUT */ 3, /* bNumEndpoints: Bulk-IN, Bulk-OUT, Intr-IN */
USB_ICC_INTERFACE_CLASS, USB_ICC_INTERFACE_CLASS,
USB_ICC_INTERFACE_SUBCLASS, USB_ICC_INTERFACE_SUBCLASS,
USB_ICC_INTERFACE_BULK_PROTOCOL, USB_ICC_INTERFACE_BULK_PROTOCOL,
@@ -197,6 +197,13 @@ static const uint8_t gnukConfigDescriptor[] = {
0x02, /* bmAttributes: Bulk */ 0x02, /* bmAttributes: Bulk */
USB_ICC_DATA_SIZE, 0x00, /* wMaxPacketSize: */ USB_ICC_DATA_SIZE, 0x00, /* wMaxPacketSize: */
0x00, /* bInterval */ 0x00, /* bInterval */
/*Endpoint IN2 Descriptor*/
7, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
0x82, /* bEndpointAddress: (IN2) */
0x03, /* bmAttributes: Interrupt */
4, 0x00, /* wMaxPacketSize: */
0x20, /* bInterval (32ms) */
/* Interface Descriptor */ /* Interface Descriptor */
9, /* bLength: Interface Descriptor size */ 9, /* bLength: Interface Descriptor size */