From 0bb7fd0cab2d53cd0d44b21301b23edfe817e66b Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 21 Nov 2017 11:52:54 +0900 Subject: [PATCH] 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 --- scd/apdu.c | 9 +++++++-- scd/app.c | 10 ++++------ scd/ccid-driver.c | 10 ++++++---- scd/scdaemon.c | 1 + 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/scd/apdu.c b/scd/apdu.c index 97624ebad..c50afbde2 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -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; diff --git a/scd/app.c b/scd/app.c index ec04b404f..f3f1205f8 100644 --- a/scd/app.c +++ b/scd/app.c @@ -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 (); } diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 9c22f5188..4f4a32dfc 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -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); diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 60d539ddd..0bedb8de2 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -1003,6 +1003,7 @@ handle_signal (int signo) case SIGCONT: /* Nothing. */ + log_debug ("SIGCONT received - breaking select\n"); break; case SIGTERM: