1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

scd: Improve watching USB device removal.

* scd/apdu.c(struct reader_table_s): Add require_get_status.
(apdu_connect): Change return value meaning.  Call apdu_reset here.
* scd/app.c (app_new_register): Add require_get_status.
(select_application): Use the return value of apdu_connect.
(scd_update_reader_status_file): Call update_fdset_for_usb with
checking all_have_intr_endp.
(app_list_start, app_list_finish): Remove.
* scd/ccid-driver.c (struct ccid_driver_s): Add transfer.
(intr_cb): Don't call libusb_transfer in this callback.
(ccid_require_get_status): New.
(do_close_reader): Call libusb_transfer here.
* scd/scdaemon.c (update_fdset_for_usb): Remove the first argument.

--

With Gnuk Token, it works fine as expected.  With Gemalto reader,
intr_cb is not called when card is removed.  So, the macro
LIBUSB_WORKS_EXPECTED_FOR_INTERRUPT_ENDP is not defined yet.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2017-01-27 18:01:52 +09:00
parent 031e3fa7b9
commit 25cc8575da
8 changed files with 130 additions and 109 deletions

View file

@ -141,11 +141,12 @@ struct reader_table_s {
} rapdu;
#endif /*USE_G10CODE_RAPDU*/
char *rdrname; /* Name of the connected reader or NULL if unknown. */
int is_t0; /* True if we know that we are running T=0. */
int is_spr532; /* True if we know that the reader is a SPR532. */
int pinpad_varlen_supported; /* True if we know that the reader
supports variable length pinpad
input. */
unsigned int is_t0:1; /* True if we know that we are running T=0. */
unsigned int is_spr532:1; /* True if we know that the reader is a SPR532. */
unsigned int pinpad_varlen_supported:1; /* True if we know that the reader
supports variable length pinpad
input. */
unsigned int require_get_status:1;
unsigned char atr[33];
size_t atrlen; /* A zero length indicates that the ATR has
not yet been read; i.e. the card is not
@ -470,6 +471,7 @@ new_reader_slot (void)
reader_table[reader].is_t0 = 1;
reader_table[reader].is_spr532 = 0;
reader_table[reader].pinpad_varlen_supported = 0;
reader_table[reader].require_get_status = 1;
#ifdef NEED_PCSC_WRAPPER
reader_table[reader].pcsc.req_fd = -1;
reader_table[reader].pcsc.rsp_fd = -1;
@ -2572,6 +2574,7 @@ open_ccid_reader (struct dev_list *dl)
{
int err;
int slot;
int require_get_status;
reader_table_t slotp;
slot = new_reader_slot ();
@ -2596,6 +2599,8 @@ open_ccid_reader (struct dev_list *dl)
err = 0;
}
require_get_status = ccid_require_get_status (slotp->ccid.handle);
reader_table[slot].close_reader = close_ccid_reader;
reader_table[slot].reset_reader = reset_ccid_reader;
reader_table[slot].get_status_reader = get_status_ccid;
@ -2608,6 +2613,7 @@ open_ccid_reader (struct dev_list *dl)
/* Our CCID reader code does not support T=0 at all, thus reset the
flag. */
reader_table[slot].is_t0 = 0;
reader_table[slot].require_get_status = require_get_status;
dump_reader_status (slot);
unlock_slot (slot);
@ -2970,22 +2976,15 @@ apdu_dev_list_start (const char *portstr, struct dev_list **l_p)
return 0;
}
int
void
apdu_dev_list_finish (struct dev_list *dl)
{
int all_have_intr_endp;
#ifdef HAVE_LIBUSB
if (dl->ccid_table)
all_have_intr_endp = ccid_dev_scan_finish (dl->ccid_table, dl->idx_max);
else
all_have_intr_endp = 0;
#else
all_have_intr_endp = 0;
ccid_dev_scan_finish (dl->ccid_table, dl->idx_max);
#endif
xfree (dl);
npth_mutex_unlock (&reader_table_lock);
return all_have_intr_endp;
}
@ -3347,8 +3346,11 @@ apdu_enum_reader (int slot, int *used)
/* Connect a card. This is used to power up the card and make sure
that an ATR is available. Depending on the reader backend it may
return an error for an inactive card or if no card is
available. */
return an error for an inactive card or if no card is available.
Return -1 on error. Return 1 if reader requires get_status to
watch card removal. Return 0 if it's a token (always with a card),
or it supports INTERRUPT endpoint to watch card removal.
*/
int
apdu_connect (int slot)
{
@ -3362,7 +3364,7 @@ apdu_connect (int slot)
{
if (DBG_READER)
log_debug ("leave: apdu_connect => SW_HOST_NO_DRIVER\n");
return SW_HOST_NO_DRIVER;
return -1;
}
/* Only if the access method provides a connect function we use it.
@ -3393,10 +3395,19 @@ apdu_connect (int slot)
else if ((status & APDU_CARD_PRESENT) && !(status & APDU_CARD_ACTIVE))
sw = SW_HOST_CARD_INACTIVE;
if (sw == SW_HOST_CARD_INACTIVE)
{
/* Try power it up again. */
sw = apdu_reset (slot);
}
if (DBG_READER)
log_debug ("leave: apdu_connect => sw=0x%x\n", sw);
return sw;
if (sw)
return -1;
return reader_table[slot].require_get_status;
}