NumLock card change
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user