Fix synchronous sending.
This commit is contained in:
15
ChangeLog
15
ChangeLog
@@ -3,14 +3,17 @@
|
|||||||
* src/openpgp.c (cmd_pso, cmd_internal_authenticate): Use
|
* src/openpgp.c (cmd_pso, cmd_internal_authenticate): Use
|
||||||
ccid_comm.
|
ccid_comm.
|
||||||
|
|
||||||
* src/usb-ccid.c (wait_for_tx_finish): New.
|
* src/usb-ccid.c (struct ccid): New field tx_busy.
|
||||||
(ccid_error, ccid_power_on, ccid_send_status, ccid_power_off)
|
(ccid_error, ccid_power_on, ccid_send_status, ccid_power_off)
|
||||||
(ccid_send_data_block_internal, ccid_send_data_block_0x9000)
|
(ccid_send_data_block_internal, ccid_send_data_block_0x9000)
|
||||||
(ccid_send_data_block_gr, ccid_send_params): Add call of
|
(ccid_send_data_block_gr, ccid_send_params): Set c->tx_busy.
|
||||||
wait_for_tx_finish.
|
(ccid_state_p): Remove.
|
||||||
(ccid_handle_data): Move c->state change before
|
(ccid_get_ccid_state): New.
|
||||||
ccid_send_datablock_gr, because of wait_for_tx_finish.
|
(ccid_thread): Only handle EV_TX_FINISHED event when c->tx_busy.
|
||||||
(ccid_thread): Don't handle EV_TX_FINISHED.
|
|
||||||
|
* src/usb_ctrl.c (usb_setup, usb_ctrl_write_finish): Use
|
||||||
|
ccid_get_ccid_state.
|
||||||
|
* src/main.c (display_status_code): Likewise.
|
||||||
|
|
||||||
2018-11-09 NIIBE Yutaka <gniibe@fsij.org>
|
2018-11-09 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
|||||||
2
chopstx
2
chopstx
Submodule chopstx updated: 2992b894e0...1369361e59
@@ -64,7 +64,7 @@ enum ccid_state {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern enum ccid_state *const ccid_state_p;
|
enum ccid_state ccid_get_ccid_state (void);
|
||||||
|
|
||||||
extern volatile uint8_t auth_status;
|
extern volatile uint8_t auth_status;
|
||||||
#define AC_NONE_AUTHORIZED 0x00
|
#define AC_NONE_AUTHORIZED 0x00
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ emit_led (uint32_t on_time, uint32_t off_time)
|
|||||||
static void
|
static void
|
||||||
display_status_code (void)
|
display_status_code (void)
|
||||||
{
|
{
|
||||||
enum ccid_state ccid_state = *ccid_state_p;
|
enum ccid_state ccid_state = ccid_get_ccid_state ();
|
||||||
uint32_t usec;
|
uint32_t usec;
|
||||||
|
|
||||||
if (ccid_state == CCID_STATE_START)
|
if (ccid_state == CCID_STATE_START)
|
||||||
|
|||||||
@@ -186,9 +186,10 @@ struct ccid_header {
|
|||||||
|
|
||||||
/* Data structure handled by CCID layer */
|
/* Data structure handled by CCID layer */
|
||||||
struct ccid {
|
struct ccid {
|
||||||
enum ccid_state ccid_state;
|
uint32_t ccid_state : 4;
|
||||||
uint8_t state;
|
uint32_t state : 4;
|
||||||
uint8_t err;
|
uint32_t err : 1;
|
||||||
|
uint32_t tx_busy : 1;
|
||||||
|
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
size_t len;
|
size_t len;
|
||||||
@@ -245,6 +246,7 @@ struct ccid {
|
|||||||
static void ccid_reset (struct ccid *c)
|
static void ccid_reset (struct ccid *c)
|
||||||
{
|
{
|
||||||
c->err = 0;
|
c->err = 0;
|
||||||
|
c->tx_busy = 0;
|
||||||
c->state = APDU_STATE_WAIT_COMMAND;
|
c->state = APDU_STATE_WAIT_COMMAND;
|
||||||
c->p = c->a->cmd_apdu_data;
|
c->p = c->a->cmd_apdu_data;
|
||||||
c->len = MAX_CMD_APDU_DATA_SIZE;
|
c->len = MAX_CMD_APDU_DATA_SIZE;
|
||||||
@@ -256,10 +258,11 @@ static void ccid_init (struct ccid *c, struct ep_in *epi, struct ep_out *epo,
|
|||||||
struct apdu *a)
|
struct apdu *a)
|
||||||
{
|
{
|
||||||
c->ccid_state = CCID_STATE_START;
|
c->ccid_state = CCID_STATE_START;
|
||||||
|
c->err = 0;
|
||||||
|
c->tx_busy = 0;
|
||||||
c->state = APDU_STATE_WAIT_COMMAND;
|
c->state = APDU_STATE_WAIT_COMMAND;
|
||||||
c->p = a->cmd_apdu_data;
|
c->p = a->cmd_apdu_data;
|
||||||
c->len = MAX_CMD_APDU_DATA_SIZE;
|
c->len = MAX_CMD_APDU_DATA_SIZE;
|
||||||
c->err = 0;
|
|
||||||
memset (&c->ccid_header, 0, sizeof (struct ccid_header));
|
memset (&c->ccid_header, 0, sizeof (struct ccid_header));
|
||||||
c->sw1sw2[0] = 0x90;
|
c->sw1sw2[0] = 0x90;
|
||||||
c->sw1sw2[1] = 0x00;
|
c->sw1sw2[1] = 0x00;
|
||||||
@@ -769,18 +772,6 @@ usb_tx_done (uint8_t ep_num, uint16_t len)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wait_for_tx_finish (struct ccid *c)
|
|
||||||
{
|
|
||||||
eventflag_wait_all (&c->ccid_comm, EV_TX_FINISHED);
|
|
||||||
|
|
||||||
if (c->state == APDU_STATE_RESULT)
|
|
||||||
ccid_reset (c);
|
|
||||||
|
|
||||||
if (c->state == APDU_STATE_WAIT_COMMAND
|
|
||||||
|| c->state == APDU_STATE_COMMAND_CHAINING
|
|
||||||
|| c->state == APDU_STATE_RESULT_GET_RESPONSE)
|
|
||||||
ccid_prepare_receive (c);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ATR (Answer To Reset) string
|
* ATR (Answer To Reset) string
|
||||||
@@ -837,7 +828,7 @@ static void ccid_error (struct ccid *c, int offset)
|
|||||||
#else
|
#else
|
||||||
usb_lld_write (c->epi->ep_num, ccid_reply, CCID_MSG_HEADER_SIZE);
|
usb_lld_write (c->epi->ep_num, ccid_reply, CCID_MSG_HEADER_SIZE);
|
||||||
#endif
|
#endif
|
||||||
wait_for_tx_finish (c);
|
c->tx_busy = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void *openpgp_card_thread (void *arg);
|
extern void *openpgp_card_thread (void *arg);
|
||||||
@@ -911,8 +902,7 @@ ccid_power_on (struct ccid *c)
|
|||||||
usb_lld_tx_enable (c->epi->ep_num, CCID_MSG_HEADER_SIZE + size_atr);
|
usb_lld_tx_enable (c->epi->ep_num, CCID_MSG_HEADER_SIZE + size_atr);
|
||||||
#endif
|
#endif
|
||||||
DEBUG_INFO ("ON\r\n");
|
DEBUG_INFO ("ON\r\n");
|
||||||
wait_for_tx_finish (c);
|
c->tx_busy = 1;
|
||||||
|
|
||||||
return CCID_STATE_WAIT;
|
return CCID_STATE_WAIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -953,7 +943,7 @@ ccid_send_status (struct ccid *c)
|
|||||||
#ifdef DEBUG_MORE
|
#ifdef DEBUG_MORE
|
||||||
DEBUG_INFO ("St\r\n");
|
DEBUG_INFO ("St\r\n");
|
||||||
#endif
|
#endif
|
||||||
wait_for_tx_finish (c);
|
c->tx_busy = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum ccid_state
|
static enum ccid_state
|
||||||
@@ -969,7 +959,7 @@ ccid_power_off (struct ccid *c)
|
|||||||
c->ccid_state = CCID_STATE_START; /* This status change should be here */
|
c->ccid_state = CCID_STATE_START; /* This status change should be here */
|
||||||
ccid_send_status (c);
|
ccid_send_status (c);
|
||||||
DEBUG_INFO ("OFF\r\n");
|
DEBUG_INFO ("OFF\r\n");
|
||||||
wait_for_tx_finish (c);
|
c->tx_busy = 1;
|
||||||
return CCID_STATE_START;
|
return CCID_STATE_START;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1012,7 +1002,7 @@ ccid_send_data_block_internal (struct ccid *c, uint8_t status, uint8_t error)
|
|||||||
#else
|
#else
|
||||||
usb_lld_tx_enable (c->epi->ep_num, CCID_MSG_HEADER_SIZE);
|
usb_lld_tx_enable (c->epi->ep_num, CCID_MSG_HEADER_SIZE);
|
||||||
#endif
|
#endif
|
||||||
wait_for_tx_finish (c);
|
c->tx_busy = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1090,7 +1080,7 @@ ccid_send_data_block_internal (struct ccid *c, uint8_t status, uint8_t error)
|
|||||||
#ifdef DEBUG_MORE
|
#ifdef DEBUG_MORE
|
||||||
DEBUG_INFO ("DATA\r\n");
|
DEBUG_INFO ("DATA\r\n");
|
||||||
#endif
|
#endif
|
||||||
wait_for_tx_finish (c);
|
c->tx_busy = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1142,7 +1132,7 @@ ccid_send_data_block_0x9000 (struct ccid *c)
|
|||||||
#ifdef DEBUG_MORE
|
#ifdef DEBUG_MORE
|
||||||
DEBUG_INFO ("DATA\r\n");
|
DEBUG_INFO ("DATA\r\n");
|
||||||
#endif
|
#endif
|
||||||
wait_for_tx_finish (c);
|
c->tx_busy = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1239,7 +1229,7 @@ ccid_send_data_block_gr (struct ccid *c, size_t chunk_len)
|
|||||||
#ifdef DEBUG_MORE
|
#ifdef DEBUG_MORE
|
||||||
DEBUG_INFO ("DATA\r\n");
|
DEBUG_INFO ("DATA\r\n");
|
||||||
#endif
|
#endif
|
||||||
wait_for_tx_finish (c);
|
c->tx_busy = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1288,7 +1278,7 @@ ccid_send_params (struct ccid *c)
|
|||||||
#ifdef DEBUG_MORE
|
#ifdef DEBUG_MORE
|
||||||
DEBUG_INFO ("PARAMS\r\n");
|
DEBUG_INFO ("PARAMS\r\n");
|
||||||
#endif
|
#endif
|
||||||
wait_for_tx_finish (c);
|
c->tx_busy = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1369,9 +1359,9 @@ ccid_handle_data (struct ccid *c)
|
|||||||
if (c->len <= c->a->expected_res_size)
|
if (c->len <= c->a->expected_res_size)
|
||||||
len = c->len;
|
len = c->len;
|
||||||
|
|
||||||
|
ccid_send_data_block_gr (c, len);
|
||||||
if (c->len == 0)
|
if (c->len == 0)
|
||||||
c->state = APDU_STATE_RESULT;
|
c->state = APDU_STATE_RESULT;
|
||||||
ccid_send_data_block_gr (c, len);
|
|
||||||
c->ccid_state = CCID_STATE_WAIT;
|
c->ccid_state = CCID_STATE_WAIT;
|
||||||
DEBUG_INFO ("GET Response.\r\n");
|
DEBUG_INFO ("GET Response.\r\n");
|
||||||
}
|
}
|
||||||
@@ -1536,7 +1526,13 @@ ccid_handle_timeout (struct ccid *c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct ccid ccid;
|
static struct ccid ccid;
|
||||||
enum ccid_state *const ccid_state_p = &ccid.ccid_state;
|
|
||||||
|
enum ccid_state
|
||||||
|
ccid_get_ccid_state (void)
|
||||||
|
{
|
||||||
|
return ccid.ccid_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ccid_card_change_signal (int how)
|
ccid_card_change_signal (int how)
|
||||||
@@ -1717,11 +1713,11 @@ usb_event_handle (struct usb_dev *dev)
|
|||||||
|
|
||||||
static chopstx_poll_cond_t ccid_event_poll_desc;
|
static chopstx_poll_cond_t ccid_event_poll_desc;
|
||||||
static struct chx_poll_head *const ccid_poll[] = {
|
static struct chx_poll_head *const ccid_poll[] = {
|
||||||
|
(struct chx_poll_head *const)&usb_intr,
|
||||||
|
(struct chx_poll_head *const)&ccid_event_poll_desc
|
||||||
#ifdef ACKBTN_SUPPORT
|
#ifdef ACKBTN_SUPPORT
|
||||||
(struct chx_poll_head *const)&ack_intr,
|
(struct chx_poll_head *const)&ack_intr,
|
||||||
#endif
|
#endif
|
||||||
(struct chx_poll_head *const)&usb_intr,
|
|
||||||
(struct chx_poll_head *const)&ccid_event_poll_desc
|
|
||||||
};
|
};
|
||||||
#define CCID_POLL_NUM (sizeof (ccid_poll)/sizeof (struct chx_poll_head *))
|
#define CCID_POLL_NUM (sizeof (ccid_poll)/sizeof (struct chx_poll_head *))
|
||||||
|
|
||||||
@@ -1775,7 +1771,13 @@ ccid_thread (void *arg)
|
|||||||
else
|
else
|
||||||
timeout_p = NULL;
|
timeout_p = NULL;
|
||||||
|
|
||||||
|
eventflag_set_mask (&c->ccid_comm, c->tx_busy ? EV_TX_FINISHED : ~0);
|
||||||
|
|
||||||
|
#ifdef ACKBTN_SUPPORT
|
||||||
|
chopstx_poll (timeout_p, CCID_POLL_NUM - c->tx_busy, ccid_poll);
|
||||||
|
#else
|
||||||
chopstx_poll (timeout_p, CCID_POLL_NUM, ccid_poll);
|
chopstx_poll (timeout_p, CCID_POLL_NUM, ccid_poll);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (usb_intr.ready)
|
if (usb_intr.ready)
|
||||||
{
|
{
|
||||||
@@ -1892,6 +1894,18 @@ ccid_thread (void *arg)
|
|||||||
DEBUG_INFO ("ERR06\r\n");
|
DEBUG_INFO ("ERR06\r\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else if (m == EV_TX_FINISHED)
|
||||||
|
{
|
||||||
|
if (c->state == APDU_STATE_RESULT)
|
||||||
|
ccid_reset (c);
|
||||||
|
else
|
||||||
|
c->tx_busy = 0;
|
||||||
|
|
||||||
|
if (c->state == APDU_STATE_WAIT_COMMAND
|
||||||
|
|| c->state == APDU_STATE_COMMAND_CHAINING
|
||||||
|
|| c->state == APDU_STATE_RESULT_GET_RESPONSE)
|
||||||
|
ccid_prepare_receive (c);
|
||||||
|
}
|
||||||
else /* Timeout */
|
else /* Timeout */
|
||||||
c->ccid_state = ccid_handle_timeout (c);
|
c->ccid_state = ccid_handle_timeout (c);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ usb_setup (struct usb_dev *dev)
|
|||||||
if (arg->request == USB_FSIJ_GNUK_DOWNLOAD)
|
if (arg->request == USB_FSIJ_GNUK_DOWNLOAD)
|
||||||
{
|
{
|
||||||
#ifdef FLASH_UPGRADE_SUPPORT
|
#ifdef FLASH_UPGRADE_SUPPORT
|
||||||
if (*ccid_state_p != CCID_STATE_EXITED)
|
if (ccid_get_ccid_state () != CCID_STATE_EXITED)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (addr < &_regnual_start || addr + arg->len > __heap_end__)
|
if (addr < &_regnual_start || addr + arg->len > __heap_end__)
|
||||||
@@ -299,7 +299,7 @@ usb_setup (struct usb_dev *dev)
|
|||||||
else if (arg->request == USB_FSIJ_GNUK_EXEC && arg->len == 0)
|
else if (arg->request == USB_FSIJ_GNUK_EXEC && arg->len == 0)
|
||||||
{
|
{
|
||||||
#ifdef FLASH_UPGRADE_SUPPORT
|
#ifdef FLASH_UPGRADE_SUPPORT
|
||||||
if (*ccid_state_p != CCID_STATE_EXITED)
|
if (ccid_get_ccid_state () != CCID_STATE_EXITED)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (((uintptr_t)addr & 0x03))
|
if (((uintptr_t)addr & 0x03))
|
||||||
@@ -404,7 +404,7 @@ usb_ctrl_write_finish (struct usb_dev *dev)
|
|||||||
{
|
{
|
||||||
if (USB_SETUP_SET (arg->type) && arg->request == USB_FSIJ_GNUK_EXEC)
|
if (USB_SETUP_SET (arg->type) && arg->request == USB_FSIJ_GNUK_EXEC)
|
||||||
{
|
{
|
||||||
if (*ccid_state_p != CCID_STATE_EXITED)
|
if (ccid_get_ccid_state () != CCID_STATE_EXITED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
|
bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
|
||||||
|
|||||||
Reference in New Issue
Block a user