1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-03-26 22:29:58 +01:00

scd: Improve internal CCID driver.

* scd/ccid-driver.c (scan_or_find_usb_device): Fix return value.
Support device with multiple CCID interfaces.  Fix the case with
READERNO.  Support partial string match of "reader-port" like PC/SC
driver.

--

I don't know any device with multiple CCID interfaces, though.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2016-12-27 11:58:54 +09:00
parent d26c51825e
commit c7ec9c4224

View File

@ -952,10 +952,10 @@ parse_ccid_descriptor (ccid_driver_t handle,
lower than that: lower than that:
64 - 10 CCID header - 4 T1frame - 2 reserved = 48 64 - 10 CCID header - 4 T1frame - 2 reserved = 48
Product Ids: Product Ids:
0xe001 - SCR 331 0xe001 - SCR 331
0x5111 - SCR 331-DI 0x5111 - SCR 331-DI
0x5115 - SCR 335 0x5115 - SCR 335
0xe003 - SPR 532 0xe003 - SPR 532
The The
0x5117 - SCR 3320 USB ID-000 reader 0x5117 - SCR 3320 USB ID-000 reader
seems to be very slow but enabling this workaround boosts the seems to be very slow but enabling this workaround boosts the
@ -1117,7 +1117,7 @@ find_endpoint (const struct libusb_interface_descriptor *ifcdesc, int mode)
for other reasons. */ for other reasons. */
static int static int
scan_or_find_usb_device (int scan_mode, scan_or_find_usb_device (int scan_mode,
int *readerno, int *count, char **rid_list, int readerno, int *count, char **rid_list,
const char *readerid, const char *readerid,
struct libusb_device *dev, struct libusb_device *dev,
char **r_rid, char **r_rid,
@ -1133,12 +1133,12 @@ scan_or_find_usb_device (int scan_mode,
int set_no; int set_no;
const struct libusb_interface_descriptor *ifcdesc; const struct libusb_interface_descriptor *ifcdesc;
char *rid; char *rid;
libusb_device_handle *idev; libusb_device_handle *idev = NULL;
int err; int err;
err = libusb_get_device_descriptor (dev, desc); err = libusb_get_device_descriptor (dev, desc);
if (err < 0) if (err < 0)
return err; return 0;
*r_idev = NULL; *r_idev = NULL;
@ -1150,7 +1150,7 @@ scan_or_find_usb_device (int scan_mode,
if (err < 0) if (err < 0)
{ {
if (err == LIBUSB_ERROR_NO_MEM) if (err == LIBUSB_ERROR_NO_MEM)
return err; return 0;
continue; continue;
} }
@ -1176,6 +1176,11 @@ scan_or_find_usb_device (int scan_mode,
&& desc->idVendor == VENDOR_CHERRY && desc->idVendor == VENDOR_CHERRY
&& desc->idProduct == CHERRY_ST2000))) && desc->idProduct == CHERRY_ST2000)))
{ {
++*count;
if (!scan_mode
&& ((readerno > 0 && readerno != *count - 1)))
continue;
err = libusb_open (dev, &idev); err = libusb_open (dev, &idev);
if (err < 0) if (err < 0)
{ {
@ -1184,100 +1189,93 @@ scan_or_find_usb_device (int scan_mode,
continue; /* with next setting. */ continue; /* with next setting. */
} }
rid = make_reader_id (idev, rid = make_reader_id (idev, desc->idVendor, desc->idProduct,
desc->idVendor,
desc->idProduct,
desc->iSerialNumber); desc->iSerialNumber);
if (rid) if (!rid)
{ {
if (scan_mode) libusb_free_config_descriptor (config);
{ return 0;
char *p;
/* We are collecting infos about all
available CCID readers. Store them and
continue. */
DEBUGOUT_2 ("found CCID reader %d (ID=%s)\n",
*count, rid );
p = malloc ((*rid_list? strlen (*rid_list):0) + 1
+ strlen (rid) + 1);
if (p)
{
*p = 0;
if (*rid_list)
{
strcat (p, *rid_list);
free (*rid_list);
}
strcat (p, rid);
strcat (p, "\n");
*rid_list = p;
}
else /* Out of memory. */
free (rid);
rid = NULL;
++*count;
}
else if (!*readerno
|| (*readerno < 0
&& readerid
&& !strcmp (readerid, rid)))
{
/* We found the requested reader. */
if (ifcdesc_extra && ifcdesc_extra_len)
{
*ifcdesc_extra = malloc (ifcdesc
->extra_length);
if (!*ifcdesc_extra)
{
libusb_close (idev);
free (rid);
libusb_free_config_descriptor (config);
return 1; /* Out of core. */
}
memcpy (*ifcdesc_extra, ifcdesc->extra,
ifcdesc->extra_length);
*ifcdesc_extra_len = ifcdesc->extra_length;
}
if (interface_number)
*interface_number = (ifcdesc->bInterfaceNumber);
if (ep_bulk_out)
*ep_bulk_out = find_endpoint (ifcdesc, 0);
if (ep_bulk_in)
*ep_bulk_in = find_endpoint (ifcdesc, 1);
if (ep_intr)
*ep_intr = find_endpoint (ifcdesc, 2);
if (r_rid)
{
*r_rid = rid;
rid = NULL;
}
else
free (rid);
*r_idev = idev;
libusb_free_config_descriptor (config);
return 1; /* Found requested device. */
}
else
{
/* This is not yet the reader we want.
fixme: We should avoid the extra usb_open
in this case. */
if (*readerno >= 0)
--*readerno;
}
free (rid);
} }
if (!scan_mode && readerno == -1 && readerid
&& strncmp (rid, readerid, strlen (readerid)))
continue;
if (scan_mode)
{
char *p;
/* We are collecting infos about all
available CCID readers. Store them and
continue. */
DEBUGOUT_2 ("found CCID reader %d (ID=%s)\n",
*count, rid );
p = malloc ((*rid_list? strlen (*rid_list):0) + 1
+ strlen (rid) + 1);
if (p)
{
*p = 0;
if (*rid_list)
{
strcat (p, *rid_list);
free (*rid_list);
}
strcat (p, rid);
strcat (p, "\n");
*rid_list = p;
}
else /* Out of memory. */
{
libusb_free_config_descriptor (config);
free (rid);
return 0;
}
}
else
{
/* We found the requested reader. */
if (ifcdesc_extra && ifcdesc_extra_len)
{
*ifcdesc_extra = malloc (ifcdesc
->extra_length);
if (!*ifcdesc_extra)
{
libusb_close (idev);
free (rid);
libusb_free_config_descriptor (config);
return 1; /* Out of core. */
}
memcpy (*ifcdesc_extra, ifcdesc->extra,
ifcdesc->extra_length);
*ifcdesc_extra_len = ifcdesc->extra_length;
}
if (interface_number)
*interface_number = (ifcdesc->bInterfaceNumber);
if (ep_bulk_out)
*ep_bulk_out = find_endpoint (ifcdesc, 0);
if (ep_bulk_in)
*ep_bulk_in = find_endpoint (ifcdesc, 1);
if (ep_intr)
*ep_intr = find_endpoint (ifcdesc, 2);
if (r_rid)
{
*r_rid = rid;
rid = NULL;
}
else
free (rid);
*r_idev = idev;
libusb_free_config_descriptor (config);
return 1; /* Found requested device. */
}
free (rid);
libusb_close (idev); libusb_close (idev);
idev = NULL; idev = NULL;
libusb_free_config_descriptor (config);
return 0;
} }
} }
} }
@ -1371,7 +1369,7 @@ scan_or_find_devices (int readerno, const char *readerid,
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
dev = dev_list[i]; dev = dev_list[i];
if (scan_or_find_usb_device (scan_mode, &readerno, &count, &rid_list, if (scan_or_find_usb_device (scan_mode, readerno, &count, &rid_list,
readerid, readerid,
dev, dev,
r_rid, r_rid,
@ -1802,19 +1800,19 @@ bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen,
case PC_to_RDR_IccPowerOff: case PC_to_RDR_IccPowerOff:
print_p2r_iccpoweroff (msg, msglen); print_p2r_iccpoweroff (msg, msglen);
break; break;
case PC_to_RDR_GetSlotStatus: case PC_to_RDR_GetSlotStatus:
print_p2r_getslotstatus (msg, msglen); print_p2r_getslotstatus (msg, msglen);
break; break;
case PC_to_RDR_XfrBlock: case PC_to_RDR_XfrBlock:
print_p2r_xfrblock (msg, msglen); print_p2r_xfrblock (msg, msglen);
break; break;
case PC_to_RDR_GetParameters: case PC_to_RDR_GetParameters:
print_p2r_getparameters (msg, msglen); print_p2r_getparameters (msg, msglen);
break; break;
case PC_to_RDR_ResetParameters: case PC_to_RDR_ResetParameters:
print_p2r_resetparameters (msg, msglen); print_p2r_resetparameters (msg, msglen);
break; break;
case PC_to_RDR_SetParameters: case PC_to_RDR_SetParameters:
print_p2r_setparameters (msg, msglen); print_p2r_setparameters (msg, msglen);
break; break;
case PC_to_RDR_Escape: case PC_to_RDR_Escape:
@ -1823,7 +1821,7 @@ bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen,
case PC_to_RDR_IccClock: case PC_to_RDR_IccClock:
print_p2r_iccclock (msg, msglen); print_p2r_iccclock (msg, msglen);
break; break;
case PC_to_RDR_T0APDU: case PC_to_RDR_T0APDU:
print_p2r_to0apdu (msg, msglen); print_p2r_to0apdu (msg, msglen);
break; break;
case PC_to_RDR_Secure: case PC_to_RDR_Secure: