aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2011-12-12 19:34:12 +0000
committerNIIBE Yutaka <[email protected]>2012-06-08 03:38:46 +0000
commit775a5f4b92fde3151d0faa88fae2b8ccfbea2928 (patch)
treecb94388ee1d11b3ad58071407b5a2c4a41480030
parentSupport the Cherry ST-2000 card reader. (diff)
downloadgnupg-775a5f4b92fde3151d0faa88fae2b8ccfbea2928.tar.gz
gnupg-775a5f4b92fde3151d0faa88fae2b8ccfbea2928.zip
Fix detection of card removal and insertion.
* scd/apdu.c (apdu_connect): Return status codes for no card available and inactive card. * scd/command.c (TEST_CARD_REMOVAL): Also test for GPG_ERR_CARD_RESET. (open_card): Map apdu_connect status to GPG_ERR_CARD_RESET.
-rw-r--r--scd/apdu.c15
-rw-r--r--scd/command.c8
2 files changed, 18 insertions, 5 deletions
diff --git a/scd/apdu.c b/scd/apdu.c
index b68cd71fa..b8bfceca0 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -2596,11 +2596,14 @@ 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. */
+ 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. */
int
apdu_connect (int slot)
{
int sw;
+ unsigned int status;
if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
return SW_HOST_NO_DRIVER;
@@ -2625,7 +2628,15 @@ apdu_connect (int slot)
scdaemon is fired up and apdu_get_status has not yet been called.
Without that we would force a reset of the card with the next
call to apdu_get_status. */
- apdu_get_status_internal (slot, 1, 1, NULL, NULL);
+ apdu_get_status_internal (slot, 1, 1, &status, NULL);
+ if (sw)
+ ;
+ else if (!(status & APDU_CARD_PRESENT))
+ sw = SW_HOST_NO_CARD;
+ else if (((status & APDU_CARD_PRESENT) && !(status & APDU_CARD_ACTIVE))
+ || !reader_table[slot].atrlen)
+ sw = SW_HOST_CARD_INACTIVE;
+
return sw;
}
diff --git a/scd/command.c b/scd/command.c
index 52b22c6a0..0a1f7856d 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -60,6 +60,7 @@
int _r = (r); \
if (gpg_err_code (_r) == GPG_ERR_CARD_NOT_PRESENT \
|| gpg_err_code (_r) == GPG_ERR_CARD_REMOVED \
+ || gpg_err_code (_r) == GPG_ERR_CARD_RESET \
|| gpg_err_code (_r) == GPG_ERR_ENODEV ) \
update_card_removed ((c)->reader_slot, 1); \
} while (0)
@@ -420,9 +421,8 @@ get_reader_slot (void)
return 0;
}
-/* If the card has not yet been opened, do it. Note that this
- function returns an Assuan error, so don't map the error a second
- time. */
+
+/* If the card has not yet been opened, do it. */
static gpg_error_t
open_card (ctrl_t ctrl, const char *apptype)
{
@@ -477,6 +477,8 @@ open_card (ctrl_t ctrl, const char *apptype)
{
if (sw == SW_HOST_NO_CARD)
err = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
+ else if (sw == SW_HOST_CARD_INACTIVE)
+ err = gpg_error (GPG_ERR_CARD_RESET);
else
err = gpg_error (GPG_ERR_CARD);
}