mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-07 17:33:02 +01:00
scd: Fix GetSlotStatus.
* scd/apdu.c (get_status_reader): Add ON_WIRE arg, here. (ct_get_status, pcsc_get_status_direct, pcsc_get_status_wrapped) (pcsc_get_status, get_status_ccid, my_rapdu_get_status): Likewise. (reset_pcsc_reader_wrapped, open_pcsc_reader_wrapped): Follow the change. (apdu_get_status_internal): It's lower-level driver which judge it's not needed. Otherwise, it can't detect the removal. * scd/ccid-driver.c (ccid_slot_status): After the POWERED_OFF check, we can skip sending GetSlotStatus packet on wire, when no need. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org> Fixes-commit: c8eee4d396a751d41fd1ee1e1b87b851fca172a
This commit is contained in:
parent
7c8eee4d39
commit
2a025039c1
44
scd/apdu.c
44
scd/apdu.c
@ -109,7 +109,7 @@ struct reader_table_s {
|
|||||||
int (*disconnect_card)(int);
|
int (*disconnect_card)(int);
|
||||||
int (*close_reader)(int);
|
int (*close_reader)(int);
|
||||||
int (*reset_reader)(int);
|
int (*reset_reader)(int);
|
||||||
int (*get_status_reader)(int, unsigned int *);
|
int (*get_status_reader)(int, unsigned int *, int);
|
||||||
int (*send_apdu_reader)(int,unsigned char *,size_t,
|
int (*send_apdu_reader)(int,unsigned char *,size_t,
|
||||||
unsigned char *, size_t *, pininfo_t *);
|
unsigned char *, size_t *, pininfo_t *);
|
||||||
int (*check_pinpad)(int, int, pininfo_t *);
|
int (*check_pinpad)(int, int, pininfo_t *);
|
||||||
@ -365,7 +365,7 @@ long (* DLSTDCALL pcsc_control) (long card,
|
|||||||
|
|
||||||
/* Prototypes. */
|
/* Prototypes. */
|
||||||
static int pcsc_vendor_specific_init (int slot);
|
static int pcsc_vendor_specific_init (int slot);
|
||||||
static int pcsc_get_status (int slot, unsigned int *status);
|
static int pcsc_get_status (int slot, unsigned int *status, int on_wire);
|
||||||
static int reset_pcsc_reader (int slot);
|
static int reset_pcsc_reader (int slot);
|
||||||
static int apdu_get_status_internal (int slot, int hang, unsigned int *status,
|
static int apdu_get_status_internal (int slot, int hang, unsigned int *status,
|
||||||
int on_wire);
|
int on_wire);
|
||||||
@ -665,9 +665,10 @@ reset_ct_reader (int slot)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ct_get_status (int slot, unsigned int *status)
|
ct_get_status (int slot, unsigned int *status, int on_wire)
|
||||||
{
|
{
|
||||||
(void)slot;
|
(void)slot;
|
||||||
|
(void)on_wire;
|
||||||
/* The status we returned is wrong but we don't care because ctAPI
|
/* The status we returned is wrong but we don't care because ctAPI
|
||||||
is not anymore required. */
|
is not anymore required. */
|
||||||
*status = APDU_CARD_USABLE|APDU_CARD_PRESENT|APDU_CARD_ACTIVE;
|
*status = APDU_CARD_USABLE|APDU_CARD_PRESENT|APDU_CARD_ACTIVE;
|
||||||
@ -929,11 +930,12 @@ dump_pcsc_reader_status (int slot)
|
|||||||
|
|
||||||
#ifndef NEED_PCSC_WRAPPER
|
#ifndef NEED_PCSC_WRAPPER
|
||||||
static int
|
static int
|
||||||
pcsc_get_status_direct (int slot, unsigned int *status)
|
pcsc_get_status_direct (int slot, unsigned int *status, int on_wire)
|
||||||
{
|
{
|
||||||
long err;
|
long err;
|
||||||
struct pcsc_readerstate_s rdrstates[1];
|
struct pcsc_readerstate_s rdrstates[1];
|
||||||
|
|
||||||
|
(void)on_wire;
|
||||||
memset (rdrstates, 0, sizeof *rdrstates);
|
memset (rdrstates, 0, sizeof *rdrstates);
|
||||||
rdrstates[0].reader = reader_table[slot].rdrname;
|
rdrstates[0].reader = reader_table[slot].rdrname;
|
||||||
rdrstates[0].current_state = PCSC_STATE_UNAWARE;
|
rdrstates[0].current_state = PCSC_STATE_UNAWARE;
|
||||||
@ -992,7 +994,7 @@ pcsc_get_status_direct (int slot, unsigned int *status)
|
|||||||
|
|
||||||
#ifdef NEED_PCSC_WRAPPER
|
#ifdef NEED_PCSC_WRAPPER
|
||||||
static int
|
static int
|
||||||
pcsc_get_status_wrapped (int slot, unsigned int *status)
|
pcsc_get_status_wrapped (int slot, unsigned int *status, int on_wire)
|
||||||
{
|
{
|
||||||
long err;
|
long err;
|
||||||
reader_table_t slotp;
|
reader_table_t slotp;
|
||||||
@ -1002,6 +1004,7 @@ pcsc_get_status_wrapped (int slot, unsigned int *status)
|
|||||||
unsigned char buffer[16];
|
unsigned char buffer[16];
|
||||||
int sw = SW_HOST_CARD_IO_ERROR;
|
int sw = SW_HOST_CARD_IO_ERROR;
|
||||||
|
|
||||||
|
(void)on_wire;
|
||||||
slotp = reader_table + slot;
|
slotp = reader_table + slot;
|
||||||
|
|
||||||
if (slotp->pcsc.req_fd == -1
|
if (slotp->pcsc.req_fd == -1
|
||||||
@ -1101,12 +1104,12 @@ pcsc_get_status_wrapped (int slot, unsigned int *status)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pcsc_get_status (int slot, unsigned int *status)
|
pcsc_get_status (int slot, unsigned int *status, int on_wire)
|
||||||
{
|
{
|
||||||
#ifdef NEED_PCSC_WRAPPER
|
#ifdef NEED_PCSC_WRAPPER
|
||||||
return pcsc_get_status_wrapped (slot, status);
|
return pcsc_get_status_wrapped (slot, status, on_wire);
|
||||||
#else
|
#else
|
||||||
return pcsc_get_status_direct (slot, status);
|
return pcsc_get_status_direct (slot, status, on_wire);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1705,7 +1708,7 @@ reset_pcsc_reader_wrapped (int slot)
|
|||||||
slotp->atrlen = len;
|
slotp->atrlen = len;
|
||||||
|
|
||||||
/* Read the status so that IS_T0 will be set. */
|
/* Read the status so that IS_T0 will be set. */
|
||||||
pcsc_get_status (slot, &dummy_status);
|
pcsc_get_status (slot, &dummy_status, 1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -2184,7 +2187,7 @@ open_pcsc_reader_wrapped (const char *portstr)
|
|||||||
pcsc_vendor_specific_init (slot);
|
pcsc_vendor_specific_init (slot);
|
||||||
|
|
||||||
/* Read the status so that IS_T0 will be set. */
|
/* Read the status so that IS_T0 will be set. */
|
||||||
pcsc_get_status (slot, &dummy_status);
|
pcsc_get_status (slot, &dummy_status, 1);
|
||||||
|
|
||||||
dump_reader_status (slot);
|
dump_reader_status (slot);
|
||||||
unlock_slot (slot);
|
unlock_slot (slot);
|
||||||
@ -2471,12 +2474,12 @@ set_progress_cb_ccid_reader (int slot, gcry_handler_progress_t cb, void *cb_arg)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_status_ccid (int slot, unsigned int *status)
|
get_status_ccid (int slot, unsigned int *status, int on_wire)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
int bits;
|
int bits;
|
||||||
|
|
||||||
rc = ccid_slot_status (reader_table[slot].ccid.handle, &bits);
|
rc = ccid_slot_status (reader_table[slot].ccid.handle, &bits, on_wire);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@ -2718,13 +2721,14 @@ reset_rapdu_reader (int slot)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
my_rapdu_get_status (int slot, unsigned int *status)
|
my_rapdu_get_status (int slot, unsigned int *status, int on_wire)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
reader_table_t slotp;
|
reader_table_t slotp;
|
||||||
rapdu_msg_t msg = NULL;
|
rapdu_msg_t msg = NULL;
|
||||||
int oldslot;
|
int oldslot;
|
||||||
|
|
||||||
|
(void)on_wire;
|
||||||
slotp = reader_table + slot;
|
slotp = reader_table + slot;
|
||||||
|
|
||||||
oldslot = rapdu_set_reader (slotp->rapdu.handle, slot);
|
oldslot = rapdu_set_reader (slotp->rapdu.handle, slot);
|
||||||
@ -3565,20 +3569,8 @@ apdu_get_status_internal (int slot, int hang, unsigned int *status, int on_wire)
|
|||||||
if ((sw = hang? lock_slot (slot) : trylock_slot (slot)))
|
if ((sw = hang? lock_slot (slot) : trylock_slot (slot)))
|
||||||
return sw;
|
return sw;
|
||||||
|
|
||||||
/* If the card (with its lower-level driver) doesn't require
|
|
||||||
GET_STATUS on wire (because it supports INTERRUPT transfer for
|
|
||||||
status change, or it's a token which has a card always inserted),
|
|
||||||
no need to send on wire. */
|
|
||||||
if (!on_wire && !reader_table[slot].require_get_status)
|
|
||||||
{
|
|
||||||
unlock_slot (slot);
|
|
||||||
if (status)
|
|
||||||
*status = (APDU_CARD_USABLE|APDU_CARD_ACTIVE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reader_table[slot].get_status_reader)
|
if (reader_table[slot].get_status_reader)
|
||||||
sw = reader_table[slot].get_status_reader (slot, &s);
|
sw = reader_table[slot].get_status_reader (slot, &s, on_wire);
|
||||||
|
|
||||||
unlock_slot (slot);
|
unlock_slot (slot);
|
||||||
|
|
||||||
|
@ -2708,7 +2708,7 @@ ccid_poll (ccid_driver_t handle)
|
|||||||
/* Note that this function won't return the error codes NO_CARD or
|
/* Note that this function won't return the error codes NO_CARD or
|
||||||
CARD_INACTIVE */
|
CARD_INACTIVE */
|
||||||
int
|
int
|
||||||
ccid_slot_status (ccid_driver_t handle, int *statusbits)
|
ccid_slot_status (ccid_driver_t handle, int *statusbits, int on_wire)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
unsigned char msg[100];
|
unsigned char msg[100];
|
||||||
@ -2719,6 +2719,16 @@ ccid_slot_status (ccid_driver_t handle, int *statusbits)
|
|||||||
if (handle->powered_off)
|
if (handle->powered_off)
|
||||||
return CCID_DRIVER_ERR_NO_READER;
|
return CCID_DRIVER_ERR_NO_READER;
|
||||||
|
|
||||||
|
/* If the card (with its lower-level driver) doesn't require
|
||||||
|
GET_STATUS on wire (because it supports INTERRUPT transfer for
|
||||||
|
status change, or it's a token which has a card always inserted),
|
||||||
|
no need to send on wire. */
|
||||||
|
if (!on_wire && !ccid_require_get_status (handle))
|
||||||
|
{
|
||||||
|
*statusbits = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
msg[0] = PC_to_RDR_GetSlotStatus;
|
msg[0] = PC_to_RDR_GetSlotStatus;
|
||||||
msg[5] = 0; /* slot */
|
msg[5] = 0; /* slot */
|
||||||
@ -2935,7 +2945,7 @@ ccid_get_atr (ccid_driver_t handle,
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* First check whether a card is available. */
|
/* First check whether a card is available. */
|
||||||
rc = ccid_slot_status (handle, &statusbits);
|
rc = ccid_slot_status (handle, &statusbits, 1);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
if (statusbits == 2)
|
if (statusbits == 2)
|
||||||
|
@ -128,7 +128,7 @@ int ccid_shutdown_reader (ccid_driver_t handle);
|
|||||||
int ccid_close_reader (ccid_driver_t handle);
|
int ccid_close_reader (ccid_driver_t handle);
|
||||||
int ccid_get_atr (ccid_driver_t handle,
|
int ccid_get_atr (ccid_driver_t handle,
|
||||||
unsigned char *atr, size_t maxatrlen, size_t *atrlen);
|
unsigned char *atr, size_t maxatrlen, size_t *atrlen);
|
||||||
int ccid_slot_status (ccid_driver_t handle, int *statusbits);
|
int ccid_slot_status (ccid_driver_t handle, int *statusbits, int on_wire);
|
||||||
int ccid_transceive (ccid_driver_t handle,
|
int ccid_transceive (ccid_driver_t handle,
|
||||||
const unsigned char *apdu, size_t apdulen,
|
const unsigned char *apdu, size_t apdulen,
|
||||||
unsigned char *resp, size_t maxresplen, size_t *nresp);
|
unsigned char *resp, size_t maxresplen, size_t *nresp);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user