scd: Enable card removal check after select_application.

* scd/apdu.c (open_ccid_reader): Fix error handling of ccid_get_atr.
* scd/app.c (select_application): Always kick the loop if new APP.
* scd/ccid-driver.c (ccid_open_usb_reader): Don't setup at open.
(ccid_slot_status): Setup interrupt transfer when !ON_WIRE.

--

We can use the interrupt transfer to be notified about card status
change.  In this case, we don't need to issue PC_to_RDR_GetSlotStatus
command.  This change improve the setup the notification; it should be
done after registration of APP.

When the setup is done just after opening the USB connection (before
issuing PC_to_RDR_IccPowerOn), a reader might notifies about no card
availability (because of not yet powered on), even though the card is
ready to be powered on.

GnuPG-bug-id: 3508
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2017-11-21 11:52:54 +09:00
parent e0140c0a6a
commit 0bb7fd0cab
4 changed files with 18 additions and 12 deletions

View File

@ -1497,8 +1497,13 @@ open_ccid_reader (struct dev_list *dl)
err = ccid_open_reader (dl->portstr, dl->idx, dl->ccid_table,
&slotp->ccid.handle, &slotp->rdrname);
if (!err)
err = ccid_get_atr (slotp->ccid.handle,
slotp->atr, sizeof slotp->atr, &slotp->atrlen);
{
err = ccid_get_atr (slotp->ccid.handle,
slotp->atr, sizeof slotp->atr, &slotp->atrlen);
if (err)
ccid_close_reader (slotp->ccid.handle);
}
if (err)
{
slotp->used = 0;

View File

@ -323,7 +323,7 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
if (scan || !app_top)
{
struct dev_list *l;
int periodical_check_needed = 0;
int new_app = 0;
/* Scan the devices to find new device(s). */
err = apdu_dev_list_start (opt.reader_port, &l);
@ -349,8 +349,7 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
{
err = app_new_register (slot, ctrl, name,
periodical_check_needed_this);
if (periodical_check_needed_this)
periodical_check_needed = 1;
new_app++;
}
if (err)
@ -359,9 +358,8 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
apdu_dev_list_finish (l);
/* If periodical check is needed for new device(s), kick the
scdaemon loop. */
if (periodical_check_needed)
/* If new device(s), kick the scdaemon loop. */
if (new_app)
scd_kick_the_loop ();
}

View File

@ -1661,9 +1661,6 @@ ccid_open_usb_reader (const char *spec_reader_name,
}
}
if ((*handle)->ep_intr >= 0)
ccid_setup_intr (*handle);
rc = ccid_vendor_specific_init (*handle);
leave:
@ -2311,6 +2308,11 @@ ccid_slot_status (ccid_driver_t handle, int *statusbits, int on_wire)
no need to send on wire. */
if (!on_wire && !ccid_require_get_status (handle))
{
/* Setup interrupt transfer at the initial call of slot_status
with ON_WIRE == 0 */
if (handle->transfer == NULL && handle->ep_intr >= 0)
ccid_setup_intr (handle);
*statusbits = 0;
return 0;
}
@ -3748,7 +3750,7 @@ main (int argc, char **argv)
if (!no_poll)
ccid_poll (ccid);
fputs ("getting slot status ...\n", stderr);
rc = ccid_slot_status (ccid, &slotstat);
rc = ccid_slot_status (ccid, &slotstat, 1);
if (rc)
{
print_error (rc);

View File

@ -1003,6 +1003,7 @@ handle_signal (int signo)
case SIGCONT:
/* Nothing. */
log_debug ("SIGCONT received - breaking select\n");
break;
case SIGTERM: