aboutsummaryrefslogtreecommitdiffstats
path: root/scd/apdu.c
diff options
context:
space:
mode:
Diffstat (limited to 'scd/apdu.c')
-rw-r--r--scd/apdu.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/scd/apdu.c b/scd/apdu.c
index b3c0f66db..bbd7ea801 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -1,5 +1,5 @@
/* apdu.c - ISO 7816 APDU functions and low level I/O
- * Copyright (C) 2003, 2004, 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2003, 2004, 2008, 2009 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -295,6 +295,9 @@ long (* DLSTDCALL pcsc_set_timeout) (unsigned long context,
/* Prototypes. */
static int pcsc_get_status (int slot, unsigned int *status);
static int reset_pcsc_reader (int slot);
+static int apdu_get_status_internal (int slot, int hang, int no_atr_reset,
+ unsigned int *status,
+ unsigned int *changed);
@@ -2565,9 +2568,18 @@ apdu_connect (int slot)
}
else
sw = 0;
+
+ /* We need to call apdu_get_status_internal, so that the last-status
+ machinery gets setup properly even if a card is inserted while
+ 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);
+
return sw;
}
+
int
apdu_disconnect (int slot)
{
@@ -2706,9 +2718,9 @@ apdu_get_atr (int slot, size_t *atrlen)
of card insertions. This value may be used to detect a card
change.
*/
-int
-apdu_get_status (int slot, int hang,
- unsigned int *status, unsigned int *changed)
+static int
+apdu_get_status_internal (int slot, int hang, int no_atr_reset,
+ unsigned int *status, unsigned int *changed)
{
int sw;
unsigned int s;
@@ -2736,8 +2748,9 @@ apdu_get_status (int slot, int hang,
{
reader_table[slot].change_counter++;
/* Make sure that the ATR is invalid so that a reset will be
- triggered by activate. */
- reader_table[slot].atrlen = 0;
+ triggered by apdu_activate. */
+ if (!no_atr_reset)
+ reader_table[slot].atrlen = 0;
}
reader_table[slot].any_status = 1;
reader_table[slot].last_status = s;
@@ -2750,6 +2763,15 @@ apdu_get_status (int slot, int hang,
}
+/* See above for a description. */
+int
+apdu_get_status (int slot, int hang,
+ unsigned int *status, unsigned int *changed)
+{
+ return apdu_get_status_internal (slot, hang, 0, status, changed);
+}
+
+
/* Check whether the reader supports the ISO command code COMMAND on
the keypad. Return 0 on success. For a description of the pin
parameters, see ccid-driver.c */