[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2] add option for a multislot usb ccid device
From: |
Ripke, Klaus |
Subject: |
[PATCH v2] add option for a multislot usb ccid device |
Date: |
Mon, 20 Mar 2023 15:23:55 +0000 |
Signed-off-by: Klaus Ripke <klaus.ripke@secunet.com>
hw/usb/dev-smartcard-reader.c:
add option for a multislot usb ccid device, similar to audio multi.
(v2 with slight formatting fix on " + ")
---
hw/usb/dev-smartcard-reader.c | 106 +++++++++++++++++++++++++++++++++-
1 file changed, 103 insertions(+), 3 deletions(-)
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-
reader.c
index be0a4fc3bc..30d8892b4e 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -90,10 +90,13 @@ OBJECT_DECLARE_SIMPLE_TYPE(USBCCIDState,
USB_CCID_DEV)
* usbccid.sys (winxp, others untested) is a class driver so it
doesn't care.
* linux has a number of class drivers, but openct filters based on
* vendor/product (/etc/openct.conf under fedora), hence Gemplus.
+ * Use a Omnikey/HID 3121 with multislot for distinction.
*/
#define CCID_VENDOR_ID 0x08e6
#define CCID_PRODUCT_ID 0x4433
#define CCID_DEVICE_VERSION 0x0000
+#define CCID_VENDOR_ID_MULTI 0x076b
+#define CCID_PRODUCT_ID_MULTI 0x3021
/*
* BULK_OUT messages from PC to Reader
@@ -312,7 +315,9 @@ struct USBCCIDState {
uint8_t bmSlotICCState;
uint8_t powered;
uint8_t notify_slot_change;
+ /* properties */
uint8_t debug;
+ bool multi;
};
/*
@@ -411,6 +416,34 @@ static const uint8_t qemu_ccid_descriptor[] = {
0x01, /* u8 bMaxCCIDBusySlots; */
};
+static const uint8_t qemu_ccid_descriptor_multi[] = {
+ /* Smart Card Device Class Descriptor */
+ 0x36, /* u8 bLength; */
+ 0x21, /* u8 bDescriptorType; Functional */
+ 0x10, 0x01, /* u16 bcdCCID; CCID Specification Release Number.
*/
+ 0x0e, /* u8 bMaxSlotIndex; 14, as 16 slots can cause
trouble. */
+ 0x07, /* u8 bVoltageSupport; 01h - 5.0v, 02h - 3.0, 03
- 1.8 */
+
+ 0x01, 0x00, /* u32 dwProtocols; RRRR PPPP. RRRR = 0000h.*/
+ 0x00, 0x00, /* PPPP: see above */
+ 0xa0, 0x0f, 0x00, 0x00, /* u32 dwMaximumClock; */
+ 0x00, 0x00, 0x01, 0x00,
+ 0x00, /* u8 bNumClockSupported; see above */
+ 0x80, 0x25, 0x00, 0x00, /* u32 dwMaxDataRate ; see above */
+ 0x00, 0xC2, 0x01, 0x00,
+ 0x00, /* u8 bNumDataRatesSupported; see above */
+ 0xfe, 0x00, 0x00, 0x00, /* u32 dwMaxIFSD; see above */
+ 0x00, 0x00, 0x00, 0x00, /* u32 dwSyncProtocols; see above */
+ 0x00, 0x00, 0x00, 0x00, /* u32 dwMechanical; see above */
+ 0xfe, 0x04, 0x04, 0x00, /* u32 dwFeatures; 400 for better
compat. */
+ 0x12, 0x00, 0x01, 0x00, /* u32 dwMaxCCIDMessageLength; see
above */
+ 0xFF, /* u8 bClassGetResponse; see above */
+ 0xFF, /* u8 bClassEnvelope; see above */
+ 0x00, 0x00, /* u16 wLcdLayout; see above */
+ 0x01, /* u8 bPINSupport; see above */
+ 0x0f, /* u8 bMaxCCIDBusySlots; modified from 1 */
+};
+
enum {
STR_MANUFACTURER = 1,
STR_PRODUCT,
@@ -457,6 +490,38 @@ static const USBDescIface desc_iface0 = {
}
};
+static const USBDescIface desc_iface0_multi = {
+ .bInterfaceNumber = 0,
+ .bNumEndpoints = 3,
+ .bInterfaceClass = USB_CLASS_CSCID,
+ .bInterfaceSubClass = USB_SUBCLASS_UNDEFINED,
+ .bInterfaceProtocol = 0x00,
+ .iInterface = STR_INTERFACE,
+ .ndesc = 1,
+ .descs = (USBDescOther[]) {
+ {
+ /* smartcard descriptor */
+ .data = qemu_ccid_descriptor_multi,
+ },
+ },
+ .eps = (USBDescEndpoint[]) {
+ {
+ .bEndpointAddress = USB_DIR_IN | CCID_INT_IN_EP,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .bInterval = 255,
+ .wMaxPacketSize = 64,
+ },{
+ .bEndpointAddress = USB_DIR_IN | CCID_BULK_IN_EP,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = 64,
+ },{
+ .bEndpointAddress = USB_DIR_OUT | CCID_BULK_OUT_EP,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = 64,
+ },
+ }
+};
+
static const USBDescDevice desc_device = {
.bcdUSB = 0x0110,
.bMaxPacketSize0 = 64,
@@ -474,6 +539,23 @@ static const USBDescDevice desc_device = {
},
};
+static const USBDescDevice desc_device_multi = {
+ .bcdUSB = 0x0110,
+ .bMaxPacketSize0 = 64,
+ .bNumConfigurations = 1,
+ .confs = (USBDescConfig[]) {
+ {
+ .bNumInterfaces = 1,
+ .bConfigurationValue = 1,
+ .bmAttributes = USB_CFG_ATT_ONE |
USB_CFG_ATT_SELFPOWER |
+ USB_CFG_ATT_WAKEUP,
+ .bMaxPower = 50,
+ .nif = 1,
+ .ifs = &desc_iface0_multi,
+ },
+ },
+};
+
static const USBDesc desc_ccid = {
.id = {
.idVendor = CCID_VENDOR_ID,
@@ -487,6 +569,19 @@ static const USBDesc desc_ccid = {
.str = desc_strings,
};
+static const USBDesc desc_ccid_multi = {
+ .id = {
+ .idVendor = CCID_VENDOR_ID_MULTI,
+ .idProduct = CCID_PRODUCT_ID_MULTI,
+ .bcdDevice = CCID_DEVICE_VERSION,
+ .iManufacturer = STR_MANUFACTURER,
+ .iProduct = STR_PRODUCT,
+ .iSerialNumber = STR_SERIALNUMBER,
+ },
+ .full = &desc_device_multi,
+ .str = desc_strings,
+};
+
static const uint8_t *ccid_card_get_atr(CCIDCardState *card, uint32_t
*len)
{
CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
@@ -1293,10 +1388,12 @@ static void ccid_card_realize(DeviceState
*qdev, Error **errp)
USBDevice *dev = USB_DEVICE(qdev->parent_bus->parent);
USBCCIDState *s = USB_CCID_DEV(dev);
Error *local_err = NULL;
+ const USBDesc *desc = usb_device_get_usb_desc(dev);
+ uint8_t bMaxSlotIndex = desc->full->confs[0].ifs-
>descs[0].data[4];
- if (card->slot != 0) {
- error_setg(errp, "usb-ccid supports one slot, can't add %d",
- card->slot);
+ if (card->slot > bMaxSlotIndex) {
+ error_setg(errp, "usb-ccid supports %d slots, can't add %d",
+ bMaxSlotIndex + 1, card->slot);
return;
}
if (s->card != NULL) {
@@ -1317,6 +1414,8 @@ static void ccid_realize(USBDevice *dev, Error
**errp)
{
USBCCIDState *s = USB_CCID_DEV(dev);
+ dev->usb_desc = s->multi ? &desc_ccid_multi : &desc_ccid;
+
usb_desc_create_serial(dev);
usb_desc_init(dev);
qbus_init(&s->bus, sizeof(s->bus), TYPE_CCID_BUS, DEVICE(dev),
NULL);
@@ -1433,6 +1532,7 @@ static const VMStateDescription ccid_vmstate = {
static Property ccid_properties[] = {
DEFINE_PROP_UINT8("debug", USBCCIDState, debug, 0),
+ DEFINE_PROP_BOOL("multi", USBCCIDState, multi, false),
DEFINE_PROP_END_OF_LIST(),
};
--
2.34.1
--
Klaus Ripke
Senior Developer
Public Authorities Division
secunet Security Networks AG
Telefon: +49 201 5454-2982
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH v2] add option for a multislot usb ccid device,
Ripke, Klaus <=