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;
void ccid_card_change_signal (void);
/* CCID thread */
#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;
c->icc_state = ICC_STATE_START;
c->icc_state = ICC_STATE_NOCARD; /* Default should be _START ?? */
c->state = APDU_STATE_WAIT_COMMAND;
/*
* 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[5] = 0x00; /* Slot */
icc_reply[ICC_MSG_SEQ_OFFSET] = c->icc_header.seq;
if (c->icc_state == ICC_STATE_START)
/* 1: ICC present but not activated 2: No ICC present */
icc_reply[ICC_MSG_STATUS_OFFSET] = 1;
if (c->icc_state == ICC_STATE_NOCARD)
icc_reply[ICC_MSG_STATUS_OFFSET] = 2; /* 2: No ICC present */
else if (c->icc_state == ICC_STATE_START)
icc_reply[ICC_MSG_STATUS_OFFSET] = 1; /* 1: ICC present but not activated */
else
/* An ICC is present and active */
icc_reply[ICC_MSG_STATUS_OFFSET] = 0;
icc_reply[ICC_MSG_STATUS_OFFSET] = 0; /* An ICC is present and active */
icc_reply[ICC_MSG_STATUS_OFFSET] |= ICC_CMD_STATUS_ERROR; /* Failed */
icc_reply[ICC_MSG_ERROR_OFFSET] = offset;
icc_reply[ICC_MSG_CHAIN_OFFSET] = 0x00;
@@ -793,12 +793,12 @@ icc_send_status (struct ccid *c)
icc_reply[4] = 0x00;
icc_reply[5] = 0x00; /* Slot */
icc_reply[ICC_MSG_SEQ_OFFSET] = c->icc_header.seq;
if (c->icc_state == ICC_STATE_START)
/* 1: ICC present but not activated 2: No ICC present */
icc_reply[ICC_MSG_STATUS_OFFSET] = 1;
if (c->icc_state == ICC_STATE_NOCARD)
icc_reply[ICC_MSG_STATUS_OFFSET] = 2; /* 2: No ICC present */
else if (c->icc_state == ICC_STATE_START)
icc_reply[ICC_MSG_STATUS_OFFSET] = 1; /* 1: ICC present but not activated */
else
/* An ICC is present and active */
icc_reply[ICC_MSG_STATUS_OFFSET] = 0;
icc_reply[ICC_MSG_STATUS_OFFSET] = 0; /* An ICC is present and active */
icc_reply[ICC_MSG_ERROR_OFFSET] = 0x00;
icc_reply[ICC_MSG_CHAIN_OFFSET] = 0x00;
@@ -1075,6 +1075,15 @@ icc_handle_data (struct ccid *c)
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:
if (c->icc_header.msg_type == ICC_POWER_ON)
{
@@ -1307,6 +1316,15 @@ USBthread (void *arg)
return ccid_thread (thd);
}
void
ccid_card_change_signal (void)
{
struct ccid *c = &ccid;
eventflag_signal (&c->ccid_comm, EV_CARD_CHANGE);
}
static void *
ccid_thread (chopstx_t thd)
{
@@ -1314,6 +1332,7 @@ ccid_thread (chopstx_t thd)
struct ep_out *epo = &endpoint_out;
struct ccid *c = &ccid;
struct apdu *a = &apdu;
int card_change_requested = 0;
epi_init (epi, ENDP1, notify_tx, 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);
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);
else if (m == EV_EXEC_FINISHED)
if (c->icc_state == ICC_STATE_EXECUTE)
@@ -1383,7 +1428,10 @@ ccid_thread (chopstx_t thd)
icc_prepare_receive (c);
}
else /* Timeout */
{
c->icc_state = icc_handle_timeout (c);
card_change_requested = 0;
}
}
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_PROTOCOL 11
#define HID_LED_STATUS_NUMLOCK 0x01
static uint8_t hid_idle_rate; /* in 4ms */
static uint8_t hid_report_saved;
static uint16_t hid_report;
static void
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;
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;
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;
case USB_HID_REQ_GET_PROTOCOL:
@@ -388,13 +395,16 @@ usb_cb_setup (uint8_t req, uint8_t req_no,
return USB_UNSUPPORT;
}
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
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);
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT)
&& USB_SETUP_SET (req) && req_no == USB_FSIJ_GNUK_EXEC && len == 0)
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
{
if (USB_SETUP_SET (req) && req_no == USB_FSIJ_GNUK_EXEC && len == 0)
{
if (icc_state_p == NULL || *icc_state_p != ICC_STATE_EXITED)
return;
@@ -404,6 +414,17 @@ void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
*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;
}
}
}
int usb_cb_handle_event (uint8_t event_type, uint16_t value)

View File

@@ -18,7 +18,7 @@
static const uint8_t hid_report_desc[] = {
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
0x09, 0x06, /* USAGE (Keyboard) */
0x09, 0x07, /* USAGE (Keypad) */
0xa1, 0x01, /* COLLECTION (Application) */
0x05, 0x07, /* USAGE_PAGE (Key Codes) */
0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */
@@ -29,16 +29,16 @@ static const uint8_t hid_report_desc[] = {
0x95, 0x08, /* REPORT_COUNT (8) */
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) */
0x19, 0x01, /* USAGE_MINIMUM (1) */
0x29, 0x05, /* USAGE_MAXIMUM (5) */
0x95, 0x05, /* REPORT_COUNT (5) */
0x29, 0x08, /* USAGE_MAXIMUM (8) */
0x95, 0x08, /* REPORT_COUNT (8) */
0x75, 0x01, /* REPORT_SIZE (1) */
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) */
0x19, 0x00, /* USAGE_MINIMUM (Reserved (no event indicated)) */
@@ -73,7 +73,7 @@ static const uint8_t gnukDeviceDescriptor[] = {
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 HID_TOTAL_LENGTH (9+9+7)
@@ -126,7 +126,7 @@ static const uint8_t gnukConfigDescriptor[] = {
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
0, /* bInterfaceNumber: Index of 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_SUBCLASS,
USB_ICC_INTERFACE_BULK_PROTOCOL,
@@ -197,6 +197,13 @@ static const uint8_t gnukConfigDescriptor[] = {
0x02, /* bmAttributes: Bulk */
USB_ICC_DATA_SIZE, 0x00, /* wMaxPacketSize: */
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 */
9, /* bLength: Interface Descriptor size */