mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-12 22:11:29 +02:00
scd,pcsc: Use a single context.
* scd/apdu.c (pcsc): New variable. (struct reader_table_s): Remove pcsc.context from member. (pcsc_get_status, connect_pcsc_card): Use pcsc.context. (close_pcsc_reader): Release pcsc.context here with reference count. (pcsc_init): New. (open_pcsc_reader): Don't call pcsc_establish_context here. Call close_pcsc_reader instead of pcsc_release_context. (apdu_open_reader): Call pcsc_init if needed. (apdu_init): Initialize pcsc.count and pcsc.context. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
f44aa290c1
commit
1080e91efd
72
scd/apdu.c
72
scd/apdu.c
@ -76,6 +76,12 @@ typedef unsigned int pcsc_dword_t;
|
|||||||
typedef unsigned long pcsc_dword_t;
|
typedef unsigned long pcsc_dword_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* PC/SC context to access readers. Shared among all readers. */
|
||||||
|
static struct pcsc {
|
||||||
|
int count;
|
||||||
|
long context;
|
||||||
|
} pcsc;
|
||||||
|
|
||||||
/* A structure to collect information pertaining to one reader
|
/* A structure to collect information pertaining to one reader
|
||||||
slot. */
|
slot. */
|
||||||
struct reader_table_s {
|
struct reader_table_s {
|
||||||
@ -101,7 +107,6 @@ struct reader_table_s {
|
|||||||
ccid_driver_t handle;
|
ccid_driver_t handle;
|
||||||
} ccid;
|
} ccid;
|
||||||
struct {
|
struct {
|
||||||
long context;
|
|
||||||
long card;
|
long card;
|
||||||
pcsc_dword_t protocol;
|
pcsc_dword_t protocol;
|
||||||
pcsc_dword_t verify_ioctl;
|
pcsc_dword_t verify_ioctl;
|
||||||
@ -652,9 +657,7 @@ pcsc_get_status (int slot, unsigned int *status, int 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 = reader_table[slot].pcsc.current_state;
|
rdrstates[0].current_state = reader_table[slot].pcsc.current_state;
|
||||||
err = pcsc_get_status_change (reader_table[slot].pcsc.context,
|
err = pcsc_get_status_change (pcsc.context, 0, rdrstates, 1);
|
||||||
0,
|
|
||||||
rdrstates, 1);
|
|
||||||
if (err == PCSC_E_TIMEOUT)
|
if (err == PCSC_E_TIMEOUT)
|
||||||
err = 0; /* Timeout is no error here. */
|
err = 0; /* Timeout is no error here. */
|
||||||
if (err)
|
if (err)
|
||||||
@ -788,7 +791,12 @@ control_pcsc (int slot, pcsc_dword_t ioctl_code,
|
|||||||
static int
|
static int
|
||||||
close_pcsc_reader (int slot)
|
close_pcsc_reader (int slot)
|
||||||
{
|
{
|
||||||
pcsc_release_context (reader_table[slot].pcsc.context);
|
(void)slot;
|
||||||
|
if (--pcsc.count == 0)
|
||||||
|
{
|
||||||
|
pcsc_release_context (pcsc.context);
|
||||||
|
pcsc.context = -1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -807,7 +815,7 @@ connect_pcsc_card (int slot)
|
|||||||
reader_table[slot].atrlen = 0;
|
reader_table[slot].atrlen = 0;
|
||||||
reader_table[slot].is_t0 = 0;
|
reader_table[slot].is_t0 = 0;
|
||||||
|
|
||||||
err = pcsc_connect (reader_table[slot].pcsc.context,
|
err = pcsc_connect (pcsc.context,
|
||||||
reader_table[slot].rdrname,
|
reader_table[slot].rdrname,
|
||||||
PCSC_SHARE_EXCLUSIVE,
|
PCSC_SHARE_EXCLUSIVE,
|
||||||
PCSC_PROTOCOL_T0|PCSC_PROTOCOL_T1,
|
PCSC_PROTOCOL_T0|PCSC_PROTOCOL_T1,
|
||||||
@ -826,10 +834,11 @@ connect_pcsc_card (int slot)
|
|||||||
pcsc_dword_t readerlen, atrlen;
|
pcsc_dword_t readerlen, atrlen;
|
||||||
pcsc_dword_t card_state, card_protocol;
|
pcsc_dword_t card_state, card_protocol;
|
||||||
|
|
||||||
|
pcsc.count++;
|
||||||
pcsc_vendor_specific_init (slot);
|
pcsc_vendor_specific_init (slot);
|
||||||
|
|
||||||
atrlen = DIM (reader_table[0].atr);
|
atrlen = DIM (reader_table[0].atr);
|
||||||
readerlen = sizeof reader -1 ;
|
readerlen = sizeof reader - 1;
|
||||||
err = pcsc_status (reader_table[slot].pcsc.card,
|
err = pcsc_status (reader_table[slot].pcsc.card,
|
||||||
reader, &readerlen,
|
reader, &readerlen,
|
||||||
&card_state, &card_protocol,
|
&card_state, &card_protocol,
|
||||||
@ -1042,6 +1051,21 @@ pcsc_vendor_specific_init (int slot)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pcsc_init (void)
|
||||||
|
{
|
||||||
|
long err;
|
||||||
|
|
||||||
|
err = pcsc_establish_context (PCSC_SCOPE_SYSTEM, NULL, NULL, &pcsc.context);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("pcsc_establish_context failed: %s (0x%lx)\n",
|
||||||
|
pcsc_error_string (err), err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Open the PC/SC reader without using the wrapper. Returns -1 on
|
/* Open the PC/SC reader without using the wrapper. Returns -1 on
|
||||||
error or a slot number for the reader. */
|
error or a slot number for the reader. */
|
||||||
@ -1059,40 +1083,28 @@ open_pcsc_reader (const char *portstr)
|
|||||||
if (slot == -1)
|
if (slot == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Fixme: Allocating a context for each slot is not required. One
|
reader_table[slot].used = 0;
|
||||||
global context should be sufficient. */
|
unlock_slot (slot);
|
||||||
err = pcsc_establish_context (PCSC_SCOPE_SYSTEM, NULL, NULL,
|
|
||||||
&reader_table[slot].pcsc.context);
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
log_error ("pcsc_establish_context failed: %s (0x%lx)\n",
|
|
||||||
pcsc_error_string (err), err);
|
|
||||||
reader_table[slot].used = 0;
|
|
||||||
unlock_slot (slot);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = pcsc_list_readers (reader_table[slot].pcsc.context,
|
err = pcsc_list_readers (pcsc.context, NULL, NULL, &nreader);
|
||||||
NULL, NULL, &nreader);
|
|
||||||
if (!err)
|
if (!err)
|
||||||
{
|
{
|
||||||
list = xtrymalloc (nreader+1); /* Better add 1 for safety reasons. */
|
list = xtrymalloc (nreader+1); /* Better add 1 for safety reasons. */
|
||||||
if (!list)
|
if (!list)
|
||||||
{
|
{
|
||||||
log_error ("error allocating memory for reader list\n");
|
log_error ("error allocating memory for reader list\n");
|
||||||
pcsc_release_context (reader_table[slot].pcsc.context);
|
close_pcsc_reader (0);
|
||||||
reader_table[slot].used = 0;
|
reader_table[slot].used = 0;
|
||||||
unlock_slot (slot);
|
unlock_slot (slot);
|
||||||
return -1 /*SW_HOST_OUT_OF_CORE*/;
|
return -1 /*SW_HOST_OUT_OF_CORE*/;
|
||||||
}
|
}
|
||||||
err = pcsc_list_readers (reader_table[slot].pcsc.context,
|
err = pcsc_list_readers (pcsc.context, NULL, list, &nreader);
|
||||||
NULL, list, &nreader);
|
|
||||||
}
|
}
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_error ("pcsc_list_readers failed: %s (0x%lx)\n",
|
log_error ("pcsc_list_readers failed: %s (0x%lx)\n",
|
||||||
pcsc_error_string (err), err);
|
pcsc_error_string (err), err);
|
||||||
pcsc_release_context (reader_table[slot].pcsc.context);
|
close_pcsc_reader (0);
|
||||||
reader_table[slot].used = 0;
|
reader_table[slot].used = 0;
|
||||||
xfree (list);
|
xfree (list);
|
||||||
unlock_slot (slot);
|
unlock_slot (slot);
|
||||||
@ -1123,7 +1135,7 @@ open_pcsc_reader (const char *portstr)
|
|||||||
if (!reader_table[slot].rdrname)
|
if (!reader_table[slot].rdrname)
|
||||||
{
|
{
|
||||||
log_error ("error allocating memory for reader name\n");
|
log_error ("error allocating memory for reader name\n");
|
||||||
pcsc_release_context (reader_table[slot].pcsc.context);
|
close_pcsc_reader (0);
|
||||||
reader_table[slot].used = 0;
|
reader_table[slot].used = 0;
|
||||||
unlock_slot (slot);
|
unlock_slot (slot);
|
||||||
return -1;
|
return -1;
|
||||||
@ -2113,6 +2125,11 @@ apdu_open_reader (struct dev_list *dl, int app_empty)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{ /* PC/SC readers. */
|
{ /* PC/SC readers. */
|
||||||
|
|
||||||
|
if (pcsc.context < 0)
|
||||||
|
if (pcsc_init () < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (app_empty && dl->idx == 0)
|
if (app_empty && dl->idx == 0)
|
||||||
{
|
{
|
||||||
dl->idx++;
|
dl->idx++;
|
||||||
@ -3299,6 +3316,9 @@ apdu_init (void)
|
|||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
pcsc.count = 0;
|
||||||
|
pcsc.context = -1;
|
||||||
|
|
||||||
if (npth_mutex_init (&reader_table_lock, NULL))
|
if (npth_mutex_init (&reader_table_lock, NULL))
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user