179
typedef struct __attribute__ ((__packed__)) CCID_Header {
180
typedef struct QEMU_PACKED CCID_Header {
180
181
uint8_t bMessageType;
181
182
uint32_t dwLength;
186
typedef struct __attribute__ ((__packed__)) CCID_BULK_IN {
187
typedef struct QEMU_PACKED CCID_BULK_IN {
188
189
uint8_t bStatus; /* Only used in BULK_IN */
189
190
uint8_t bError; /* Only used in BULK_IN */
192
typedef struct __attribute__ ((__packed__)) CCID_SlotStatus {
193
typedef struct QEMU_PACKED CCID_SlotStatus {
194
195
uint8_t bClockStatus;
195
196
} CCID_SlotStatus;
197
typedef struct __attribute__ ((__packed__)) CCID_Parameter {
198
typedef struct QEMU_PACKED CCID_Parameter {
199
200
uint8_t bProtocolNum;
200
201
uint8_t abProtocolDataStructure[0];
201
202
} CCID_Parameter;
203
typedef struct __attribute__ ((__packed__)) CCID_DataBlock {
204
typedef struct QEMU_PACKED CCID_DataBlock {
205
206
uint8_t bChainParameter;
206
207
uint8_t abData[0];
207
208
} CCID_DataBlock;
209
210
/* 6.1.4 PC_to_RDR_XfrBlock */
210
typedef struct __attribute__ ((__packed__)) CCID_XferBlock {
211
typedef struct QEMU_PACKED CCID_XferBlock {
212
213
uint8_t bBWI; /* Block Waiting Timeout */
213
214
uint16_t wLevelParameter; /* XXX currently unused */
214
215
uint8_t abData[0];
215
216
} CCID_XferBlock;
217
typedef struct __attribute__ ((__packed__)) CCID_IccPowerOn {
218
typedef struct QEMU_PACKED CCID_IccPowerOn {
219
220
uint8_t bPowerSelect;
221
222
} CCID_IccPowerOn;
223
typedef struct __attribute__ ((__packed__)) CCID_IccPowerOff {
224
typedef struct QEMU_PACKED CCID_IccPowerOff {
226
227
} CCID_IccPowerOff;
228
typedef struct __attribute__ ((__packed__)) CCID_SetParameters {
229
typedef struct QEMU_PACKED CCID_SetParameters {
230
231
uint8_t bProtocolNum;
306
307
* 0dc3:1004 Athena Smartcard Solutions, Inc.
309
static const uint8_t qemu_ccid_dev_descriptor[] = {
310
0x12, /* u8 bLength; */
311
USB_DT_DEVICE, /* u8 bDescriptorType; Device */
312
0x10, 0x01, /* u16 bcdUSB; v1.1 */
314
0x00, /* u8 bDeviceClass; */
315
0x00, /* u8 bDeviceSubClass; */
316
0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
317
0x40, /* u8 bMaxPacketSize0; 8 Bytes (valid: 8,16,32,64) */
319
/* Vendor and product id are arbitrary. */
321
CCID_VENDOR_ID & 0xff, CCID_VENDOR_ID >> 8,
323
CCID_PRODUCT_ID & 0xff, CCID_PRODUCT_ID >> 8,
325
CCID_DEVICE_VERSION & 0xff, CCID_DEVICE_VERSION >> 8,
326
0x01, /* u8 iManufacturer; */
327
0x02, /* u8 iProduct; */
328
0x03, /* u8 iSerialNumber; */
329
0x01, /* u8 bNumConfigurations; */
332
static const uint8_t qemu_ccid_config_descriptor[] = {
334
/* one configuration */
335
0x09, /* u8 bLength; */
336
USB_DT_CONFIG, /* u8 bDescriptorType; Configuration */
337
0x5d, 0x00, /* u16 wTotalLength; 9+9+54+7+7+7 */
338
0x01, /* u8 bNumInterfaces; (1) */
339
0x01, /* u8 bConfigurationValue; */
340
0x00, /* u8 iConfiguration; */
341
0xe0, /* u8 bmAttributes;
346
100/2, /* u8 MaxPower; 50 == 100mA */
349
0x09, /* u8 if_bLength; */
350
USB_DT_INTERFACE, /* u8 if_bDescriptorType; Interface */
351
0x00, /* u8 if_bInterfaceNumber; */
352
0x00, /* u8 if_bAlternateSetting; */
353
0x03, /* u8 if_bNumEndpoints; */
354
0x0b, /* u8 if_bInterfaceClass; Smart Card Device Class */
355
0x00, /* u8 if_bInterfaceSubClass; Subclass code */
356
0x00, /* u8 if_bInterfaceProtocol; Protocol code */
357
0x04, /* u8 if_iInterface; Index of string descriptor */
310
static const uint8_t qemu_ccid_descriptor[] = {
359
311
/* Smart Card Device Class Descriptor */
360
312
0x36, /* u8 bLength; */
361
313
0x21, /* u8 bDescriptorType; Functional */
439
391
* 02h PIN Modification
441
393
0x01, /* u8 bMaxCCIDBusySlots; */
443
/* Interrupt-IN endpoint */
444
0x07, /* u8 ep_bLength; */
445
/* u8 ep_bDescriptorType; Endpoint */
447
/* u8 ep_bEndpointAddress; IN Endpoint 1 */
448
0x80 | CCID_INT_IN_EP,
449
0x03, /* u8 ep_bmAttributes; Interrupt */
450
/* u16 ep_wMaxPacketSize; */
451
CCID_MAX_PACKET_SIZE & 0xff, (CCID_MAX_PACKET_SIZE >> 8),
452
0xff, /* u8 ep_bInterval; */
454
/* Bulk-In endpoint */
455
0x07, /* u8 ep_bLength; */
456
/* u8 ep_bDescriptorType; Endpoint */
458
/* u8 ep_bEndpointAddress; IN Endpoint 2 */
459
0x80 | CCID_BULK_IN_EP,
460
0x02, /* u8 ep_bmAttributes; Bulk */
461
0x40, 0x00, /* u16 ep_wMaxPacketSize; */
462
0x00, /* u8 ep_bInterval; */
464
/* Bulk-Out endpoint */
465
0x07, /* u8 ep_bLength; */
466
/* u8 ep_bDescriptorType; Endpoint */
468
/* u8 ep_bEndpointAddress; OUT Endpoint 3 */
470
0x02, /* u8 ep_bmAttributes; Bulk */
471
0x40, 0x00, /* u16 ep_wMaxPacketSize; */
472
0x00, /* u8 ep_bInterval; */
397
STR_MANUFACTURER = 1,
403
static const USBDescStrings desc_strings = {
404
[STR_MANUFACTURER] = "QEMU " QEMU_VERSION,
405
[STR_PRODUCT] = "QEMU USB CCID",
406
[STR_SERIALNUMBER] = "1",
407
[STR_INTERFACE] = "CCID Interface",
410
static const USBDescIface desc_iface0 = {
411
.bInterfaceNumber = 0,
413
.bInterfaceClass = 0x0b,
414
.bInterfaceSubClass = 0x00,
415
.bInterfaceProtocol = 0x00,
416
.iInterface = STR_INTERFACE,
418
.descs = (USBDescOther[]) {
420
/* smartcard descriptor */
421
.data = qemu_ccid_descriptor,
424
.eps = (USBDescEndpoint[]) {
426
.bEndpointAddress = USB_DIR_IN | CCID_INT_IN_EP,
427
.bmAttributes = USB_ENDPOINT_XFER_INT,
429
.wMaxPacketSize = 64,
431
.bEndpointAddress = USB_DIR_IN | CCID_BULK_IN_EP,
432
.bmAttributes = USB_ENDPOINT_XFER_BULK,
433
.wMaxPacketSize = 64,
435
.bEndpointAddress = USB_DIR_OUT | CCID_BULK_OUT_EP,
436
.bmAttributes = USB_ENDPOINT_XFER_BULK,
437
.wMaxPacketSize = 64,
442
static const USBDescDevice desc_device = {
444
.bMaxPacketSize0 = 64,
445
.bNumConfigurations = 1,
446
.confs = (USBDescConfig[]) {
449
.bConfigurationValue = 1,
450
.bmAttributes = 0xa0,
458
static const USBDesc desc_ccid = {
460
.idVendor = CCID_VENDOR_ID,
461
.idProduct = CCID_PRODUCT_ID,
462
.bcdDevice = CCID_DEVICE_VERSION,
463
.iManufacturer = STR_MANUFACTURER,
464
.iProduct = STR_PRODUCT,
465
.iSerialNumber = STR_SERIALNUMBER,
467
.full = &desc_device,
476
471
static bool ccid_has_pending_answers(USBCCIDState *s)
612
607
DPRINTF(s, 1, "got control %x, value %x\n", request, value);
608
ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
613
613
switch (request) {
614
case DeviceRequest | USB_REQ_GET_STATUS:
615
data[0] = (1 << USB_DEVICE_SELF_POWERED) |
616
(dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
620
case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
621
if (value == USB_DEVICE_REMOTE_WAKEUP) {
622
dev->remote_wakeup = 0;
628
case DeviceOutRequest | USB_REQ_SET_FEATURE:
629
if (value == USB_DEVICE_REMOTE_WAKEUP) {
630
dev->remote_wakeup = 1;
636
case DeviceOutRequest | USB_REQ_SET_ADDRESS:
640
case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
641
switch (value >> 8) {
643
memcpy(data, qemu_ccid_dev_descriptor,
644
sizeof(qemu_ccid_dev_descriptor));
645
ret = sizeof(qemu_ccid_dev_descriptor);
648
memcpy(data, qemu_ccid_config_descriptor,
649
sizeof(qemu_ccid_config_descriptor));
650
ret = sizeof(qemu_ccid_config_descriptor);
653
switch (value & 0xff) {
663
/* vendor description */
664
ret = set_usb_string(data, CCID_VENDOR_DESCRIPTION);
667
/* product description */
668
ret = set_usb_string(data, CCID_PRODUCT_DESCRIPTION);
672
ret = set_usb_string(data, CCID_SERIAL_NUMBER_STRING);
676
ret = set_usb_string(data, CCID_INTERFACE_NAME);
686
case DeviceRequest | USB_REQ_GET_CONFIGURATION:
690
case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
691
/* Only one configuration - we just ignore the request */
694
614
case DeviceRequest | USB_REQ_GET_INTERFACE:
935
852
CCID_Header *ccid_header;
937
if (p->len + s->bulk_out_pos > BULK_OUT_DATA_SIZE) {
854
if (p->iov.size + s->bulk_out_pos > BULK_OUT_DATA_SIZE) {
938
855
return USB_RET_STALL;
940
857
ccid_header = (CCID_Header *)s->bulk_out_data;
941
memcpy(s->bulk_out_data + s->bulk_out_pos, p->data, p->len);
942
s->bulk_out_pos += p->len;
943
if (p->len == CCID_MAX_PACKET_SIZE) {
858
usb_packet_copy(p, s->bulk_out_data + s->bulk_out_pos, p->iov.size);
859
s->bulk_out_pos += p->iov.size;
860
if (p->iov.size == CCID_MAX_PACKET_SIZE) {
944
861
DPRINTF(s, D_VERBOSE,
945
"usb-ccid: bulk_in: expecting more packets (%d/%d)\n",
946
p->len, ccid_header->dwLength);
862
"usb-ccid: bulk_in: expecting more packets (%zd/%d)\n",
863
p->iov.size, ccid_header->dwLength);
949
866
if (s->bulk_out_pos < 10) {
1009
static int ccid_bulk_in_copy_to_guest(USBCCIDState *s, uint8_t *data, int len)
926
static int ccid_bulk_in_copy_to_guest(USBCCIDState *s, USBPacket *p)
930
assert(p->iov.size > 0);
1014
931
ccid_bulk_in_get(s);
1015
932
if (s->current_bulk_in != NULL) {
1016
ret = MIN(s->current_bulk_in->len - s->current_bulk_in->pos, len);
1017
memcpy(data, s->current_bulk_in->data + s->current_bulk_in->pos, ret);
933
ret = MIN(s->current_bulk_in->len - s->current_bulk_in->pos,
935
usb_packet_copy(p, s->current_bulk_in->data +
936
s->current_bulk_in->pos, ret);
1018
937
s->current_bulk_in->pos += ret;
1019
938
if (s->current_bulk_in->pos == s->current_bulk_in->len) {
1020
939
ccid_bulk_in_release(s);
1027
946
DPRINTF(s, D_MORE_INFO,
1028
"%s: %d/%d req/act to guest (BULK_IN)\n", __func__, len, ret);
947
"%s: %zd/%d req/act to guest (BULK_IN)\n",
948
__func__, p->iov.size, ret);
1030
if (ret != USB_RET_NAK && ret < len) {
950
if (ret != USB_RET_NAK && ret < p->iov.size) {
1032
"%s: returning short (EREMOTEIO) %d < %d\n", __func__, ret, len);
952
"%s: returning short (EREMOTEIO) %d < %zd\n",
953
__func__, ret, p->iov.size);
1049
969
case USB_TOKEN_IN:
1050
970
switch (p->devep & 0xf) {
1051
971
case CCID_BULK_IN_EP:
1053
973
ret = USB_RET_NAK;
1055
ret = ccid_bulk_in_copy_to_guest(s, data, len);
975
ret = ccid_bulk_in_copy_to_guest(s, p);
1058
978
case CCID_INT_IN_EP:
1059
979
if (s->notify_slot_change) {
1060
980
/* page 56, RDR_to_PC_NotifySlotChange */
1061
data[0] = CCID_MESSAGE_TYPE_RDR_to_PC_NotifySlotChange;
1062
data[1] = s->bmSlotICCState;
981
buf[0] = CCID_MESSAGE_TYPE_RDR_to_PC_NotifySlotChange;
982
buf[1] = s->bmSlotICCState;
983
usb_packet_copy(p, buf, 2);
1064
985
s->notify_slot_change = false;
1065
986
s->bmSlotICCState &= ~SLOT_0_CHANGED_MASK;
1066
987
DPRINTF(s, D_INFO,
1067
988
"handle_data: int_in: notify_slot_change %X, "
1068
"requested len %d\n",
1069
s->bmSlotICCState, len);
989
"requested len %zd\n",
990
s->bmSlotICCState, p->iov.size);
1073
994
DPRINTF(s, 1, "Bad endpoint\n");