/* parse.c: parse CCID structure Copyright (C) 2003-2004 Ludovic Rousseau This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * $Id$ */ #include #include # ifdef S_SPLINT_S # include # endif #include #include #include "defs.h" #include "ccid_ifdhandler.h" #include "ccid.h" #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif static int ccid_parse_interface_descriptor(usb_dev_handle *handle, struct usb_device *dev); /***************************************************************************** * * main * ****************************************************************************/ int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[]) { status_t res; unsigned int channel; for (channel=0; channelbus->dirname, dev->filename); /* * Vendor/model name */ printf(" idVendor: 0x%04X\n", dev->descriptor.idVendor); if (usb_get_string_simple(handle, dev->descriptor.iManufacturer, buffer, sizeof(buffer)) < 0) printf(" Can't get iManufacturer string\n"); else printf(" iManufacturer: %s\n", buffer); printf(" idProduct: 0x%04X\n", dev->descriptor.idProduct); if (usb_get_string_simple(handle, dev->descriptor.iProduct, buffer, sizeof(buffer)) < 0) printf(" Can't get iProduct string\n"); else printf(" iProduct: %s\n", buffer); printf(" bcdDevice: %X.%02X (firmware release?)\n", dev->descriptor.bcdDevice >> 8, dev->descriptor.bcdDevice & 0xFF); usb_interface = get_ccid_usb_interface(dev)->altsetting; printf(" bLength: %d\n", usb_interface->bLength); printf(" bDescriptorType: %d\n", usb_interface->bDescriptorType); printf(" bInterfaceNumber: %d\n", usb_interface->bInterfaceNumber); printf(" bAlternateSetting: %d\n", usb_interface->bAlternateSetting); printf(" bNumEndpoints: %d\n", usb_interface->bNumEndpoints); printf(" bInterfaceClass: 0x%02X", usb_interface->bInterfaceClass); if (usb_interface->bInterfaceClass == 0x0b) printf(" [Chip Card Interface Device Class (CCID)]\n"); else { printf("\n NOT A CCID DEVICE\n"); if (usb_interface->bInterfaceClass != 0xFF) return TRUE; else printf(" Class is 0xFF (proprietary)\n"); } printf(" bInterfaceSubClass: %d\n", usb_interface->bInterfaceSubClass); if (usb_interface->bInterfaceSubClass) printf(" UNSUPPORTED SubClass\n"); printf(" bInterfaceProtocol: %d\n", usb_interface->bInterfaceProtocol); if (usb_interface->bInterfaceProtocol) printf(" UNSUPPORTED InterfaceProtocol\n"); printf(" iInterface: %d\n", usb_interface->iInterface); if (usb_interface->extralen < 54) { printf("USB extra length is too short: %d\n", usb_interface->extralen); printf("\n NOT A CCID DEVICE\n"); return TRUE; } /* * CCID Class Descriptor */ printf(" CCID Class Descriptor\n"); extra = usb_interface->extra; printf(" bLength: 0x%02X\n", extra[0]); if (extra[0] != 0x36) { printf(" UNSUPPORTED bLength\n"); return TRUE; } printf(" bDescriptorType: 0x%02X\n", extra[1]); if (extra[1] != 0x21) { if (0xFF == extra[1]) printf(" PROPRIETARY bDescriptorType\n"); else { printf(" UNSUPPORTED bDescriptorType\n"); return TRUE; } } printf(" bcdCCID: %X.%02X\n", extra[3], extra[2]); printf(" bMaxSlotIndex: 0x%02X\n", extra[4]); printf(" bVoltageSupport: 0x%02X\n", extra[5]); if (extra[5] & 0x01) printf(" 5.0V\n"); if (extra[5] & 0x02) printf(" 3.0V\n"); if (extra[5] & 0x04) printf(" 1.8V\n"); printf(" dwProtocols: 0x%02X%02X 0x%02X%02X\n", extra[9], extra[8], extra[7],extra[6]); if (extra[6] & 0x01) printf(" T=0\n"); if (extra[6] & 0x02) printf(" T=1\n"); printf(" dwDefaultClock: %.3f MHz\n", dw2i(extra, 10)/1000.0); printf(" dwMaximumClock: %.3f MHz\n", dw2i(extra, 14)/1000.0); printf(" bNumClockSupported: 0x%02X\n", extra[18]); { unsigned char buffer[256*sizeof(int)]; /* maximum is 256 records */ int n; /* See CCID 3.7.2 page 25 */ n = usb_control_msg(handle, 0xA1, /* request type */ 0x02, /* GET CLOCK FREQUENCIES */ 0x00, /* value */ usb_interface->bInterfaceNumber, /* interface */ (char *)buffer, sizeof(buffer), 2 * 1000); /* we got an error? */ if (n <= 0) printf(" IFD does not support GET CLOCK FREQUENCIES request\n"); else if (n % 4) /* not a multiple of 4 */ printf(" wrong size for GET CLOCK FREQUENCIES: %d\n", n); else { int i; /* we do not get the expected number of data rates */ if (n != extra[18]*4) { printf(" Got %d clock frequencies but was expecting %d\n", n/4, extra[18]); /* we got more data than expected */ if (n > extra[18]*4) n = extra[18]*4; } for (i=0; ibInterfaceNumber, /* interface */ (char *)buffer, sizeof(buffer), 2 * 1000); /* we got an error? */ if (n <= 0) printf(" IFD does not support GET_DATA_RATES request\n"); else if (n % 4) /* not a multiple of 4 */ printf(" wrong size for GET_DATA_RATES: %d\n", n); else { int i; /* we do not get the expected number of data rates */ if (n != extra[27]*4) { printf(" Got %d data rates but was expecting %d\n", n/4, extra[27]); /* we got more data than expected */ if (n > extra[27]*4) n = extra[27]*4; } for (i=0; i