[Spice-commits] Branch 'usb-ccid' - hw/usb-ccid.c Makefile.objs

Alon Levy alon at kemper.freedesktop.org
Tue Jul 6 09:21:42 PDT 2010


 Makefile.objs |    2 -
 hw/usb-ccid.c |   82 ++++++++++++++++++++++++++++++++++++----------------------
 2 files changed, 52 insertions(+), 32 deletions(-)

New commits:
commit 1f9345369aaa1146088028c037094109e5c1f26f
Author: Alon Levy <alevy at redhat.com>
Date:   Tue Jul 6 19:21:25 2010 +0300

    usb-ccid: missing makefile, support multipacket bulk_out (packet size hardcoded to 64 bytes)

diff --git a/Makefile.objs b/Makefile.objs
index 1250d98..4075b95 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -72,7 +72,7 @@ common-obj-y += eeprom93xx.o
 common-obj-y += scsi-disk.o cdrom.o
 common-obj-y += scsi-generic.o scsi-bus.o
 common-obj-y += usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o
-common-obj-y += usb-serial.o usb-net.o usb-bus.o
+common-obj-y += usb-serial.o usb-ccid.o usb-net.o usb-bus.o
 common-obj-$(CONFIG_SSI) += ssi.o
 common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
 common-obj-$(CONFIG_SD) += sd.o
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index a59049d..acf5901 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -10,6 +10,13 @@
  * This code is licenced under the LGPL.
  */
 
+/* TODO
+ *
+ * Discard additional answers
+ * Don't change answer while sending a multiple packet BULK_IN (answer_len > single_packet_len == 64)
+ *
+ */
+
 #include "qemu-common.h"
 #include "qemu-error.h"
 #include "usb.h"
@@ -111,7 +118,7 @@ typedef struct __attribute__ ((__packed__)) {
 typedef struct __attribute__ ((__packed__)) {
     CCID_BULK_IN b;
     uint8_t      bChainParameter;
-    // here starts the data part
+    uint8_t      abData[0];
 } CCID_DataBlock;
 
 // 6.1.4 PC_to_RDR_XfrBlock
@@ -119,7 +126,7 @@ typedef struct __attribute__ ((__packed__)) {
     CCID_Header  hdr;
     uint8_t      bBWI; // Block Waiting Timeout
     uint16_t     wLevelParameter;
-    // here starts the data part
+    uint8_t      abData[0];
 } CCID_XferBlock;
 
 typedef struct __attribute__ ((__packed__)) {
@@ -508,7 +515,7 @@ static void ccid_write_data_block(USBCCIDState* s, uint8_t slot, uint8_t seq,
     p->b.hdr.bSeq = seq;
     p->b.bStatus = 0;
     p->b.bError = 0;
-    memcpy((char*)p+sizeof(*p), data, len);
+    memcpy(p->abData, data, len);
 }
 
 static void ccid_write_data_block_answer(USBCCIDState* s, const uint8_t* data, uint32_t len)
@@ -546,20 +553,56 @@ static void ccid_on_apdu_from_guest(USBCCIDState *s, CCID_XferBlock* recv)
     }
     s->answer_slot = recv->hdr.bSlot;
     s->answer_seq = recv->hdr.bSeq;
+    printf("usb-ccid: apdu_from_guest %d: len %d\n", recv->hdr.bSeq, recv->hdr.dwLength);
     scr_msg_header.type = SCard_APDU;
     scr_msg_header.nLength = recv->hdr.dwLength;
     qemu_chr_write(s->cs, (uint8_t*)&scr_msg_header, sizeof(SCRMsgHeader));
-    qemu_chr_write(s->cs, (uint8_t*)recv + sizeof(*recv), recv->hdr.dwLength);
+    qemu_chr_write(s->cs, recv->abData, recv->hdr.dwLength);
+}
+
+static void usb_ccid_handle_bulk_out(USBCCIDState *s, USBPacket *p)
+{
+    static uint8_t data[70000]; // TODO - set to correct max size of packet.
+    static uint32_t len = 0;
+    static CCID_Header* ccid_header = (CCID_Header*)data;
+
+    memcpy(data + len, p->data, p->len);
+    len += p->len;
+    if (p->len == 64) {
+        printf("usb-ccid: bulk_in: expecting more packets (%d/%d)\n",
+            len, ccid_header->dwLength);
+        return;
+    }
+    if (len < 10) {
+        DPRINTF("handle_data: bad USB_TOKEN_OUT length, should be at least 10 bytes\n");
+    } else {
+        switch (ccid_header->bMessageType) {
+            case CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus:
+                ccid_write_slot_status(s, ccid_header);
+                break;
+            case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOn:
+                // We need to send an ATR back
+                ccid_write_data_block_atr(s, ccid_header);
+                break;
+            case CCID_MESSAGE_TYPE_PC_to_RDR_XfrBlock:
+                ccid_on_apdu_from_guest(s, (CCID_XferBlock*)data);
+                break;
+            default:
+                DPRINTF("handle_data: ERROR: unhandled message type %Xh\n",
+                    ccid_header->bMessageType);
+                break;
+        }
+    }
+    len = 0;
 }
 
 static int usb_ccid_handle_data(USBDevice *dev, USBPacket *p)
 {
     USBCCIDState *s = (USBCCIDState *)dev;
     int ret = 0;
+    int first_len;
     uint8_t *data = p->data;
     int len = p->len;
-    int first_len;
-    CCID_Header* ccid_header;
 #ifdef DEBUG_CCID
     //int i;
 #endif
@@ -579,28 +622,7 @@ static int usb_ccid_handle_data(USBDevice *dev, USBPacket *p)
 
     switch (p->pid) {
     case USB_TOKEN_OUT:
-        // translate CCID to a APDU request, or handle here.
-        // right now all is handled here. (development only)
-        if (len < 10) {
-            DPRINTF("handle_data: bad USB_TOKEN_OUT length, should be at least 10 bytes\n");
-        } else {
-            ccid_header = (CCID_Header*)data;
-            switch (ccid_header->bMessageType) {
-                case CCID_MESSAGE_TYPE_PC_to_RDR_GetSlotStatus:
-                    ccid_write_slot_status(s, ccid_header);
-                    break;
-                case CCID_MESSAGE_TYPE_PC_to_RDR_IccPowerOn:
-                    // We need to send an ATR back
-                    ccid_write_data_block_atr(s, ccid_header);
-                    break;
-                case CCID_MESSAGE_TYPE_PC_to_RDR_XfrBlock:
-                    ccid_on_apdu_from_guest(s, (CCID_XferBlock*)data);
-                    break;
-                default:
-                    DPRINTF("handle_data: unhandled message type %d\n",
-                        ccid_header->bMessageType);
-            }
-        }
+        usb_ccid_handle_bulk_out(s, p);
         break;
 
     case USB_TOKEN_IN:
@@ -675,13 +697,11 @@ static void usb_ccid_read(void *opaque, const uint8_t *buf, int size)
     const uint8_t* data = readbuf + sizeof(SCRMsgHeader);
     uint32_t available = size + readpos;
 
-    printf("usb-ccid: chardev read %d\n", size);
+    assert(readpos + size <= sizeof(readbuf));
     memcpy(readbuf + readpos, buf, size);
     readpos += size;
 
     if (available - sizeof(SCRMsgHeader) < scr_msg_header->nLength) {
-        printf("usb-ccid: chardev read short, missing %ld\n",
-            scr_msg_header->nLength + sizeof(SCRMsgHeader) - available);
         return;
     }
 


More information about the Spice-commits mailing list