mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +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:
parent
031e3fa7b9
commit
25cc8575da
47
scd/apdu.c
47
scd/apdu.c
@ -141,11 +141,12 @@ struct reader_table_s {
|
|||||||
} rapdu;
|
} rapdu;
|
||||||
#endif /*USE_G10CODE_RAPDU*/
|
#endif /*USE_G10CODE_RAPDU*/
|
||||||
char *rdrname; /* Name of the connected reader or NULL if unknown. */
|
char *rdrname; /* Name of the connected reader or NULL if unknown. */
|
||||||
int is_t0; /* True if we know that we are running T=0. */
|
unsigned int is_t0:1; /* True if we know that we are running T=0. */
|
||||||
int is_spr532; /* True if we know that the reader is a SPR532. */
|
unsigned int is_spr532:1; /* True if we know that the reader is a SPR532. */
|
||||||
int pinpad_varlen_supported; /* True if we know that the reader
|
unsigned int pinpad_varlen_supported:1; /* True if we know that the reader
|
||||||
supports variable length pinpad
|
supports variable length pinpad
|
||||||
input. */
|
input. */
|
||||||
|
unsigned int require_get_status:1;
|
||||||
unsigned char atr[33];
|
unsigned char atr[33];
|
||||||
size_t atrlen; /* A zero length indicates that the ATR has
|
size_t atrlen; /* A zero length indicates that the ATR has
|
||||||
not yet been read; i.e. the card is not
|
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_t0 = 1;
|
||||||
reader_table[reader].is_spr532 = 0;
|
reader_table[reader].is_spr532 = 0;
|
||||||
reader_table[reader].pinpad_varlen_supported = 0;
|
reader_table[reader].pinpad_varlen_supported = 0;
|
||||||
|
reader_table[reader].require_get_status = 1;
|
||||||
#ifdef NEED_PCSC_WRAPPER
|
#ifdef NEED_PCSC_WRAPPER
|
||||||
reader_table[reader].pcsc.req_fd = -1;
|
reader_table[reader].pcsc.req_fd = -1;
|
||||||
reader_table[reader].pcsc.rsp_fd = -1;
|
reader_table[reader].pcsc.rsp_fd = -1;
|
||||||
@ -2572,6 +2574,7 @@ open_ccid_reader (struct dev_list *dl)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
int slot;
|
int slot;
|
||||||
|
int require_get_status;
|
||||||
reader_table_t slotp;
|
reader_table_t slotp;
|
||||||
|
|
||||||
slot = new_reader_slot ();
|
slot = new_reader_slot ();
|
||||||
@ -2596,6 +2599,8 @@ open_ccid_reader (struct dev_list *dl)
|
|||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require_get_status = ccid_require_get_status (slotp->ccid.handle);
|
||||||
|
|
||||||
reader_table[slot].close_reader = close_ccid_reader;
|
reader_table[slot].close_reader = close_ccid_reader;
|
||||||
reader_table[slot].reset_reader = reset_ccid_reader;
|
reader_table[slot].reset_reader = reset_ccid_reader;
|
||||||
reader_table[slot].get_status_reader = get_status_ccid;
|
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
|
/* Our CCID reader code does not support T=0 at all, thus reset the
|
||||||
flag. */
|
flag. */
|
||||||
reader_table[slot].is_t0 = 0;
|
reader_table[slot].is_t0 = 0;
|
||||||
|
reader_table[slot].require_get_status = require_get_status;
|
||||||
|
|
||||||
dump_reader_status (slot);
|
dump_reader_status (slot);
|
||||||
unlock_slot (slot);
|
unlock_slot (slot);
|
||||||
@ -2970,22 +2976,15 @@ apdu_dev_list_start (const char *portstr, struct dev_list **l_p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
apdu_dev_list_finish (struct dev_list *dl)
|
apdu_dev_list_finish (struct dev_list *dl)
|
||||||
{
|
{
|
||||||
int all_have_intr_endp;
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBUSB
|
#ifdef HAVE_LIBUSB
|
||||||
if (dl->ccid_table)
|
if (dl->ccid_table)
|
||||||
all_have_intr_endp = ccid_dev_scan_finish (dl->ccid_table, dl->idx_max);
|
ccid_dev_scan_finish (dl->ccid_table, dl->idx_max);
|
||||||
else
|
|
||||||
all_have_intr_endp = 0;
|
|
||||||
#else
|
|
||||||
all_have_intr_endp = 0;
|
|
||||||
#endif
|
#endif
|
||||||
xfree (dl);
|
xfree (dl);
|
||||||
npth_mutex_unlock (&reader_table_lock);
|
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
|
/* 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
|
that an ATR is available. Depending on the reader backend it may
|
||||||
return an error for an inactive card or if no card is
|
return an error for an inactive card or if no card is available.
|
||||||
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
|
int
|
||||||
apdu_connect (int slot)
|
apdu_connect (int slot)
|
||||||
{
|
{
|
||||||
@ -3362,7 +3364,7 @@ apdu_connect (int slot)
|
|||||||
{
|
{
|
||||||
if (DBG_READER)
|
if (DBG_READER)
|
||||||
log_debug ("leave: apdu_connect => SW_HOST_NO_DRIVER\n");
|
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.
|
/* 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))
|
else if ((status & APDU_CARD_PRESENT) && !(status & APDU_CARD_ACTIVE))
|
||||||
sw = SW_HOST_CARD_INACTIVE;
|
sw = SW_HOST_CARD_INACTIVE;
|
||||||
|
|
||||||
|
if (sw == SW_HOST_CARD_INACTIVE)
|
||||||
|
{
|
||||||
|
/* Try power it up again. */
|
||||||
|
sw = apdu_reset (slot);
|
||||||
|
}
|
||||||
|
|
||||||
if (DBG_READER)
|
if (DBG_READER)
|
||||||
log_debug ("leave: apdu_connect => sw=0x%x\n", sw);
|
log_debug ("leave: apdu_connect => sw=0x%x\n", sw);
|
||||||
|
|
||||||
return sw;
|
if (sw)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return reader_table[slot].require_get_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ struct dev_list;
|
|||||||
gpg_error_t apdu_init (void);
|
gpg_error_t apdu_init (void);
|
||||||
|
|
||||||
gpg_error_t apdu_dev_list_start (const char *portstr, struct dev_list **l_p);
|
gpg_error_t apdu_dev_list_start (const char *portstr, struct dev_list **l_p);
|
||||||
int apdu_dev_list_finish (struct dev_list *l);
|
void apdu_dev_list_finish (struct dev_list *l);
|
||||||
|
|
||||||
/* Note, that apdu_open_reader returns no status word but -1 on error. */
|
/* Note, that apdu_open_reader returns no status word but -1 on error. */
|
||||||
int apdu_open_reader (struct dev_list *l);
|
int apdu_open_reader (struct dev_list *l);
|
||||||
|
@ -121,8 +121,6 @@ size_t app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff);
|
|||||||
|
|
||||||
|
|
||||||
/*-- app.c --*/
|
/*-- app.c --*/
|
||||||
app_t app_list_start (void);
|
|
||||||
void app_list_finish (void);
|
|
||||||
void app_send_card_list (ctrl_t ctrl);
|
void app_send_card_list (ctrl_t ctrl);
|
||||||
char *app_get_serialno (app_t app);
|
char *app_get_serialno (app_t app);
|
||||||
|
|
||||||
|
126
scd/app.c
126
scd/app.c
@ -174,7 +174,8 @@ app_reset (app_t app, ctrl_t ctrl, int send_reset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
app_new_register (int slot, ctrl_t ctrl, const char *name)
|
app_new_register (int slot, ctrl_t ctrl, const char *name,
|
||||||
|
int require_get_status)
|
||||||
{
|
{
|
||||||
gpg_error_t err = 0;
|
gpg_error_t err = 0;
|
||||||
app_t app = NULL;
|
app_t app = NULL;
|
||||||
@ -303,7 +304,7 @@ app_new_register (int slot, ctrl_t ctrl, const char *name)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
app->require_get_status = 1; /* For token, this can be 0. */
|
app->require_get_status = require_get_status;
|
||||||
|
|
||||||
npth_mutex_lock (&app_list_lock);
|
npth_mutex_lock (&app_list_lock);
|
||||||
app->next = app_top;
|
app->next = app_top;
|
||||||
@ -330,7 +331,7 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
|
|||||||
if (scan || !app_top)
|
if (scan || !app_top)
|
||||||
{
|
{
|
||||||
struct dev_list *l;
|
struct dev_list *l;
|
||||||
int all_have_intr_endp;
|
int all_have_intr_endp = 1;
|
||||||
|
|
||||||
err = apdu_dev_list_start (opt.reader_port, &l);
|
err = apdu_dev_list_start (opt.reader_port, &l);
|
||||||
if (err)
|
if (err)
|
||||||
@ -339,39 +340,31 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
|
|||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
int slot;
|
int slot;
|
||||||
int sw;
|
int require_get_status;
|
||||||
|
|
||||||
slot = apdu_open_reader (l);
|
slot = apdu_open_reader (l);
|
||||||
if (slot < 0)
|
if (slot < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
err = 0;
|
require_get_status = apdu_connect (slot);
|
||||||
sw = apdu_connect (slot);
|
if (require_get_status < 0)
|
||||||
|
|
||||||
if (sw == SW_HOST_CARD_INACTIVE)
|
|
||||||
{
|
|
||||||
/* Try again. */
|
|
||||||
sw = apdu_reset (slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sw || sw == SW_HOST_ALREADY_CONNECTED)
|
|
||||||
err = 0;
|
|
||||||
else if (sw == SW_HOST_NO_CARD)
|
|
||||||
err = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
|
|
||||||
else
|
|
||||||
err = gpg_error (GPG_ERR_ENODEV);
|
|
||||||
|
|
||||||
if (!err)
|
|
||||||
err = app_new_register (slot, ctrl, name);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* We close a reader with no card. */
|
/* We close a reader with no card. */
|
||||||
apdu_close_reader (slot);
|
err = gpg_error (GPG_ERR_ENODEV);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = app_new_register (slot, ctrl, name, require_get_status);
|
||||||
|
if (require_get_status)
|
||||||
|
all_have_intr_endp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
apdu_close_reader (slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
all_have_intr_endp = apdu_dev_list_finish (l);
|
apdu_dev_list_finish (l);
|
||||||
update_fdset_for_usb (1, all_have_intr_endp);
|
update_fdset_for_usb (all_have_intr_endp);
|
||||||
}
|
}
|
||||||
|
|
||||||
npth_mutex_lock (&app_list_lock);
|
npth_mutex_lock (&app_list_lock);
|
||||||
@ -1021,46 +1014,60 @@ void
|
|||||||
scd_update_reader_status_file (void)
|
scd_update_reader_status_file (void)
|
||||||
{
|
{
|
||||||
app_t a, app_next;
|
app_t a, app_next;
|
||||||
|
int all_have_intr_endp = 1;
|
||||||
|
int removal_detected = 0;
|
||||||
|
|
||||||
npth_mutex_lock (&app_list_lock);
|
npth_mutex_lock (&app_list_lock);
|
||||||
for (a = app_top; a; a = app_next)
|
for (a = app_top; a; a = app_next)
|
||||||
{
|
{
|
||||||
|
int sw;
|
||||||
|
unsigned int status;
|
||||||
|
|
||||||
|
sw = apdu_get_status (a->slot, 0, &status);
|
||||||
app_next = a->next;
|
app_next = a->next;
|
||||||
if (a->require_get_status)
|
|
||||||
|
if (sw == SW_HOST_NO_READER)
|
||||||
{
|
{
|
||||||
int sw;
|
/* Most likely the _reader_ has been unplugged. */
|
||||||
unsigned int status;
|
status = 0;
|
||||||
sw = apdu_get_status (a->slot, 0, &status);
|
}
|
||||||
|
else if (sw)
|
||||||
|
{
|
||||||
|
/* Get status failed. Ignore that. */
|
||||||
|
if (a->require_get_status)
|
||||||
|
all_have_intr_endp = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (sw == SW_HOST_NO_READER)
|
if (a->card_status != status)
|
||||||
{
|
{
|
||||||
/* Most likely the _reader_ has been unplugged. */
|
report_change (a->slot, a->card_status, status);
|
||||||
status = 0;
|
send_client_notifications (a, status == 0);
|
||||||
}
|
|
||||||
else if (sw)
|
|
||||||
{
|
|
||||||
/* Get status failed. Ignore that. */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a->card_status != status)
|
if (status == 0)
|
||||||
{
|
{
|
||||||
report_change (a->slot, a->card_status, status);
|
log_debug ("Removal of a card: %d\n", a->slot);
|
||||||
send_client_notifications (a, status == 0);
|
apdu_close_reader (a->slot);
|
||||||
|
deallocate_app (a);
|
||||||
if (status == 0)
|
removal_detected = 1;
|
||||||
{
|
|
||||||
log_debug ("Removal of a card: %d\n", a->slot);
|
|
||||||
apdu_close_reader (a->slot);
|
|
||||||
deallocate_app (a);
|
|
||||||
update_fdset_for_usb (0, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
a->card_status = status;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a->card_status = status;
|
||||||
|
if (a->require_get_status)
|
||||||
|
all_have_intr_endp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (a->require_get_status)
|
||||||
|
all_have_intr_endp = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
npth_mutex_unlock (&app_list_lock);
|
npth_mutex_unlock (&app_list_lock);
|
||||||
|
|
||||||
|
if (removal_detected)
|
||||||
|
update_fdset_for_usb (all_have_intr_endp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function must be called once to initialize this module. This
|
/* This function must be called once to initialize this module. This
|
||||||
@ -1082,19 +1089,6 @@ initialize_module_command (void)
|
|||||||
return apdu_init ();
|
return apdu_init ();
|
||||||
}
|
}
|
||||||
|
|
||||||
app_t
|
|
||||||
app_list_start (void)
|
|
||||||
{
|
|
||||||
npth_mutex_lock (&app_list_lock);
|
|
||||||
return app_top;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
app_list_finish (void)
|
|
||||||
{
|
|
||||||
npth_mutex_unlock (&app_list_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
app_send_card_list (ctrl_t ctrl)
|
app_send_card_list (ctrl_t ctrl)
|
||||||
{
|
{
|
||||||
|
@ -274,6 +274,7 @@ struct ccid_driver_s
|
|||||||
void *progress_cb_arg;
|
void *progress_cb_arg;
|
||||||
|
|
||||||
unsigned char intr_buf[64];
|
unsigned char intr_buf[64];
|
||||||
|
struct libusb_transfer *transfer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1699,17 +1700,13 @@ ccid_dev_scan (int *idx_max_p, struct ccid_dev_table **t_p)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
ccid_dev_scan_finish (struct ccid_dev_table *tbl, int max)
|
ccid_dev_scan_finish (struct ccid_dev_table *tbl, int max)
|
||||||
{
|
{
|
||||||
int all_have_intr_endp = 1;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < max; i++)
|
for (i = 0; i < max; i++)
|
||||||
{
|
{
|
||||||
if (tbl[i].ep_intr == -1)
|
|
||||||
all_have_intr_endp = 0;
|
|
||||||
|
|
||||||
free (tbl[i].ifcdesc_extra);
|
free (tbl[i].ifcdesc_extra);
|
||||||
tbl[i].transport = 0;
|
tbl[i].transport = 0;
|
||||||
tbl[i].n = 0;
|
tbl[i].n = 0;
|
||||||
@ -1723,8 +1720,6 @@ ccid_dev_scan_finish (struct ccid_dev_table *tbl, int max)
|
|||||||
}
|
}
|
||||||
libusb_free_device_list (ccid_usb_dev_list, 1);
|
libusb_free_device_list (ccid_usb_dev_list, 1);
|
||||||
ccid_usb_dev_list = NULL;
|
ccid_usb_dev_list = NULL;
|
||||||
|
|
||||||
return all_have_intr_endp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
@ -1767,14 +1762,14 @@ intr_cb (struct libusb_transfer *transfer)
|
|||||||
{
|
{
|
||||||
ccid_driver_t handle = transfer->user_data;
|
ccid_driver_t handle = transfer->user_data;
|
||||||
|
|
||||||
DEBUGOUT ("CCID: interrupt callback\n");
|
DEBUGOUT_1 ("CCID: interrupt callback %d\n", transfer->status);
|
||||||
|
|
||||||
if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE)
|
if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE
|
||||||
|
|| transfer->status == LIBUSB_TRANSFER_ERROR)
|
||||||
{
|
{
|
||||||
device_removed:
|
device_removed:
|
||||||
DEBUGOUT ("CCID: device removed\n");
|
DEBUGOUT ("CCID: device removed\n");
|
||||||
handle->powered_off = 1;
|
handle->powered_off = 1;
|
||||||
libusb_free_transfer (transfer);
|
|
||||||
}
|
}
|
||||||
else if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
|
else if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
|
||||||
{
|
{
|
||||||
@ -1784,7 +1779,6 @@ intr_cb (struct libusb_transfer *transfer)
|
|||||||
{
|
{
|
||||||
DEBUGOUT ("CCID: card removed\n");
|
DEBUGOUT ("CCID: card removed\n");
|
||||||
handle->powered_off = 1;
|
handle->powered_off = 1;
|
||||||
libusb_free_transfer (transfer);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1795,12 +1789,12 @@ intr_cb (struct libusb_transfer *transfer)
|
|||||||
if (err == LIBUSB_ERROR_NO_DEVICE)
|
if (err == LIBUSB_ERROR_NO_DEVICE)
|
||||||
goto device_removed;
|
goto device_removed;
|
||||||
|
|
||||||
DEBUGOUT_1 ("CCID submit transfer again %d", err);
|
DEBUGOUT_1 ("CCID submit transfer again %d\n", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
;
|
DEBUGOUT_1 ("CCID intr_cb: %d\n", transfer->status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1811,6 +1805,7 @@ ccid_setup_intr (ccid_driver_t handle)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
transfer = libusb_alloc_transfer (0);
|
transfer = libusb_alloc_transfer (0);
|
||||||
|
handle->transfer = transfer;
|
||||||
libusb_fill_interrupt_transfer (transfer, handle->idev, handle->ep_intr,
|
libusb_fill_interrupt_transfer (transfer, handle->idev, handle->ep_intr,
|
||||||
handle->intr_buf, sizeof (handle->intr_buf),
|
handle->intr_buf, sizeof (handle->intr_buf),
|
||||||
intr_cb, handle, 0);
|
intr_cb, handle, 0);
|
||||||
@ -1913,7 +1908,7 @@ ccid_open_usb_reader (const char *spec_reader_name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*handle)->ep_intr)
|
if ((*handle)->ep_intr >= 0)
|
||||||
ccid_setup_intr (*handle);
|
ccid_setup_intr (*handle);
|
||||||
|
|
||||||
rc = ccid_vendor_specific_init (*handle);
|
rc = ccid_vendor_specific_init (*handle);
|
||||||
@ -2010,6 +2005,26 @@ ccid_open_reader (const char *spec_reader_name, int idx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
ccid_require_get_status (ccid_driver_t handle)
|
||||||
|
{
|
||||||
|
#ifdef LIBUSB_WORKS_EXPECTED_FOR_INTERRUPT_ENDP
|
||||||
|
if (handle->ep_intr >= 0)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Here comes products check for tokens which
|
||||||
|
always have card inserted. */
|
||||||
|
switch (handle->id_vendor)
|
||||||
|
{
|
||||||
|
case VENDOR_FSIJ:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_close_reader (ccid_driver_t handle)
|
do_close_reader (ccid_driver_t handle)
|
||||||
{
|
{
|
||||||
@ -2037,6 +2052,7 @@ do_close_reader (ccid_driver_t handle)
|
|||||||
}
|
}
|
||||||
if (handle->idev)
|
if (handle->idev)
|
||||||
{
|
{
|
||||||
|
libusb_free_transfer (handle->transfer);
|
||||||
libusb_release_interface (handle->idev, handle->ifc_no);
|
libusb_release_interface (handle->idev, handle->ifc_no);
|
||||||
libusb_close (handle->idev);
|
libusb_close (handle->idev);
|
||||||
handle->idev = NULL;
|
handle->idev = NULL;
|
||||||
|
@ -115,7 +115,7 @@ int ccid_set_debug_level (int level);
|
|||||||
char *ccid_get_reader_list (void);
|
char *ccid_get_reader_list (void);
|
||||||
|
|
||||||
gpg_error_t ccid_dev_scan (int *idx_max, struct ccid_dev_table **t_p);
|
gpg_error_t ccid_dev_scan (int *idx_max, struct ccid_dev_table **t_p);
|
||||||
int ccid_dev_scan_finish (struct ccid_dev_table *tbl, int max);
|
void ccid_dev_scan_finish (struct ccid_dev_table *tbl, int max);
|
||||||
unsigned int ccid_get_BAI (int, struct ccid_dev_table *tbl);
|
unsigned int ccid_get_BAI (int, struct ccid_dev_table *tbl);
|
||||||
int ccid_compare_BAI (ccid_driver_t handle, unsigned int);
|
int ccid_compare_BAI (ccid_driver_t handle, unsigned int);
|
||||||
int ccid_open_reader (const char *spec_reader_name,
|
int ccid_open_reader (const char *spec_reader_name,
|
||||||
@ -140,7 +140,7 @@ int ccid_transceive_escape (ccid_driver_t handle,
|
|||||||
const unsigned char *data, size_t datalen,
|
const unsigned char *data, size_t datalen,
|
||||||
unsigned char *resp, size_t maxresplen,
|
unsigned char *resp, size_t maxresplen,
|
||||||
size_t *nresp);
|
size_t *nresp);
|
||||||
|
int ccid_require_get_status (ccid_driver_t handle);
|
||||||
|
|
||||||
|
|
||||||
#endif /*CCID_DRIVER_H*/
|
#endif /*CCID_DRIVER_H*/
|
||||||
|
@ -1202,15 +1202,14 @@ start_connection_thread (void *arg)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
update_fdset_for_usb (int scanned, int all_have_intr_endp)
|
update_fdset_for_usb (int all_have_intr_endp)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LIBUSB
|
#ifdef HAVE_LIBUSB
|
||||||
const struct libusb_pollfd **pfd_array = libusb_get_pollfds (NULL);
|
const struct libusb_pollfd **pfd_array = libusb_get_pollfds (NULL);
|
||||||
const struct libusb_pollfd **p;
|
const struct libusb_pollfd **p;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (scanned)
|
usb_all_have_intr_endp = all_have_intr_endp;
|
||||||
usb_all_have_intr_endp = all_have_intr_endp;
|
|
||||||
|
|
||||||
FD_ZERO (&fdset);
|
FD_ZERO (&fdset);
|
||||||
nfd = 0;
|
nfd = 0;
|
||||||
@ -1230,6 +1229,7 @@ update_fdset_for_usb (int scanned, int all_have_intr_endp)
|
|||||||
if (nfd < fd)
|
if (nfd < fd)
|
||||||
nfd = fd;
|
nfd = fd;
|
||||||
p++;
|
p++;
|
||||||
|
log_debug ("USB: add %d to fdset\n", fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
libusb_free_pollfds (pfd_array);
|
libusb_free_pollfds (pfd_array);
|
||||||
@ -1238,8 +1238,7 @@ update_fdset_for_usb (int scanned, int all_have_intr_endp)
|
|||||||
/* Kick the select loop. */
|
/* Kick the select loop. */
|
||||||
write (notify_fd, "", 1);
|
write (notify_fd, "", 1);
|
||||||
|
|
||||||
log_debug ("update_fdset_for_usb (%d, %d): %d %lx\n",
|
log_debug ("update_fdset_for_usb (%d): %d\n", all_have_intr_endp, nfd);
|
||||||
scanned, all_have_intr_endp, nfd, fdset.fds_bits[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1395,6 +1394,7 @@ handle_connections (void)
|
|||||||
char buf[256];
|
char buf[256];
|
||||||
|
|
||||||
read (pipe_fd[0], buf, sizeof buf);
|
read (pipe_fd[0], buf, sizeof buf);
|
||||||
|
ret--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset))
|
if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset))
|
||||||
@ -1439,6 +1439,8 @@ handle_connections (void)
|
|||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
struct timeval tv = {0, 0};
|
struct timeval tv = {0, 0};
|
||||||
|
|
||||||
|
log_debug ("scd main: USB handle events\n");
|
||||||
libusb_handle_events_timeout_completed (NULL, &tv, NULL);
|
libusb_handle_events_timeout_completed (NULL, &tv, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -125,7 +125,7 @@ void send_status_info (ctrl_t ctrl, const char *keyword, ...)
|
|||||||
void send_status_direct (ctrl_t ctrl, const char *keyword, const char *args);
|
void send_status_direct (ctrl_t ctrl, const char *keyword, const char *args);
|
||||||
void scd_update_reader_status_file (void);
|
void scd_update_reader_status_file (void);
|
||||||
void send_client_notifications (app_t app, int removal);
|
void send_client_notifications (app_t app, int removal);
|
||||||
void update_fdset_for_usb (int scanned, int all_have_intr_endp);
|
void update_fdset_for_usb (int all_have_intr_endp);
|
||||||
|
|
||||||
|
|
||||||
#endif /*SCDAEMON_H*/
|
#endif /*SCDAEMON_H*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user