diff options
author | NIIBE Yutaka <[email protected]> | 2017-01-27 09:01:52 +0000 |
---|---|---|
committer | NIIBE Yutaka <[email protected]> | 2017-01-27 09:01:52 +0000 |
commit | 25cc8575da9a9b8bf60c64c8059cb5f73cc52e1d (patch) | |
tree | a9100c34073a73e0ed13d802df7deae5d9027ab6 /scd/app.c | |
parent | scd: Wake up the select when new USB scan. (diff) | |
download | gnupg-25cc8575da9a9b8bf60c64c8059cb5f73cc52e1d.tar.gz gnupg-25cc8575da9a9b8bf60c64c8059cb5f73cc52e1d.zip |
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 <[email protected]>
Diffstat (limited to 'scd/app.c')
-rw-r--r-- | scd/app.c | 120 |
1 files changed, 57 insertions, 63 deletions
@@ -174,7 +174,8 @@ app_reset (app_t app, ctrl_t ctrl, int send_reset) } 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; app_t app = NULL; @@ -303,7 +304,7 @@ app_new_register (int slot, ctrl_t ctrl, const char *name) 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); app->next = app_top; @@ -330,7 +331,7 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app, if (scan || !app_top) { struct dev_list *l; - int all_have_intr_endp; + int all_have_intr_endp = 1; err = apdu_dev_list_start (opt.reader_port, &l); if (err) @@ -339,39 +340,31 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app, while (1) { int slot; - int sw; + int require_get_status; slot = apdu_open_reader (l); if (slot < 0) break; - err = 0; - sw = apdu_connect (slot); - - if (sw == SW_HOST_CARD_INACTIVE) + require_get_status = apdu_connect (slot); + if (require_get_status < 0) { - /* Try again. */ - sw = apdu_reset (slot); + /* We close a reader with no card. */ + err = gpg_error (GPG_ERR_ENODEV); } - - 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. */ - apdu_close_reader (slot); + 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); - update_fdset_for_usb (1, all_have_intr_endp); + apdu_dev_list_finish (l); + update_fdset_for_usb (all_have_intr_endp); } npth_mutex_lock (&app_list_lock); @@ -1021,46 +1014,60 @@ void scd_update_reader_status_file (void) { app_t a, app_next; + int all_have_intr_endp = 1; + int removal_detected = 0; npth_mutex_lock (&app_list_lock); 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; - if (a->require_get_status) + + if (sw == SW_HOST_NO_READER) + { + /* Most likely the _reader_ has been unplugged. */ + status = 0; + } + else if (sw) + { + /* Get status failed. Ignore that. */ + if (a->require_get_status) + all_have_intr_endp = 0; + continue; + } + + if (a->card_status != status) { - int sw; - unsigned int status; - sw = apdu_get_status (a->slot, 0, &status); + report_change (a->slot, a->card_status, status); + send_client_notifications (a, status == 0); - if (sw == SW_HOST_NO_READER) - { - /* Most likely the _reader_ has been unplugged. */ - status = 0; - } - else if (sw) + if (status == 0) { - /* Get status failed. Ignore that. */ - continue; + log_debug ("Removal of a card: %d\n", a->slot); + apdu_close_reader (a->slot); + deallocate_app (a); + removal_detected = 1; } - - if (a->card_status != status) + else { - report_change (a->slot, a->card_status, status); - send_client_notifications (a, status == 0); - - if (status == 0) - { - 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; + 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); + + if (removal_detected) + update_fdset_for_usb (all_have_intr_endp); } /* This function must be called once to initialize this module. This @@ -1082,19 +1089,6 @@ initialize_module_command (void) 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 app_send_card_list (ctrl_t ctrl) { |