configure option --vidpid to specify USB device ID
[gnuk/gnuk.git] / src / usb_desc.c
1 /*
2  * usb_desc.c - USB Descriptor
3  */
4
5 #include "config.h"
6 #include "ch.h"
7 #include "usb_lld.h"
8 #include "usb_conf.h"
9 #include "usb-cdc.h"
10
11 #define USB_ICC_INTERFACE_CLASS 0x0B
12 #define USB_ICC_INTERFACE_SUBCLASS 0x00
13 #define USB_ICC_INTERFACE_BULK_PROTOCOL 0x00
14 #define USB_ICC_DATA_SIZE 64
15
16 /* USB Standard Device Descriptor */
17 static const uint8_t gnukDeviceDescriptor[] = {
18   18,   /* bLength */
19   USB_DEVICE_DESCRIPTOR_TYPE,     /* bDescriptorType */
20   0x10, 0x01,   /* bcdUSB = 1.1 */
21   0x00,   /* bDeviceClass: 0 means deferred to interface */
22   0x00,   /* bDeviceSubClass */
23   0x00,   /* bDeviceProtocol */
24   0x40,   /* bMaxPacketSize0 */
25 #include "usb-vid-pid-ver.c.inc"
26   1, /* Index of string descriptor describing manufacturer */
27   2, /* Index of string descriptor describing product */
28   3, /* Index of string descriptor describing the device's serial number */
29   0x01    /* bNumConfigurations */
30 };
31
32 #define ICC_TOTAL_LENGTH (9+9+54+7+7)
33 #define ICC_NUM_INTERFACES 1
34
35 #ifdef ENABLE_VIRTUAL_COM_PORT
36 #define VCOM_TOTAL_LENGTH (9+5+5+4+5+7+9+7+7)
37 #define VCOM_NUM_INTERFACES 2
38 #else
39 #define VCOM_TOTAL_LENGTH 0
40 #define VCOM_NUM_INTERFACES 0
41 #endif
42
43 #ifdef PINPAD_DND_SUPPORT
44 #define MSC_TOTAL_LENGTH (9+7+7)
45 #define MSC_NUM_INTERFACES 1
46 #else
47 #define MSC_TOTAL_LENGTH 0
48 #define MSC_NUM_INTERFACES 0
49 #endif
50
51 #define W_TOTAL_LENGTH (ICC_TOTAL_LENGTH+VCOM_TOTAL_LENGTH+MSC_TOTAL_LENGTH)
52 #define NUM_INTERFACES (ICC_NUM_INTERFACES+VCOM_NUM_INTERFACES+MSC_NUM_INTERFACES)
53
54
55 /* Configuation Descriptor */
56 static const uint8_t gnukConfigDescriptor[] = {
57   9,                       /* bLength: Configuation Descriptor size */
58   USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* bDescriptorType: Configuration */
59   W_TOTAL_LENGTH, 0x00,   /* wTotalLength:no of returned bytes */
60   NUM_INTERFACES,   /* bNumInterfaces: */
61   0x01,   /* bConfigurationValue: Configuration value */
62   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
63 #if defined(USB_SELF_POWERED)
64   0xC0,   /* bmAttributes: self powered */
65 #else
66   0x80,   /* bmAttributes: bus powered */
67 #endif
68   50,     /* MaxPower 100 mA */
69
70   /* Interface Descriptor */
71   9,                          /* bLength: Interface Descriptor size */
72   USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
73   0,                             /* bInterfaceNumber: Index of this interface */
74   0,                        /* Alternate setting for this interface */
75   2,                        /* bNumEndpoints: Bulk-IN, Bulk-OUT */
76   USB_ICC_INTERFACE_CLASS,
77   USB_ICC_INTERFACE_SUBCLASS,
78   USB_ICC_INTERFACE_BULK_PROTOCOL,
79   0,                            /* string index for interface */
80
81   /* ICC Descriptor */
82   54,                     /* bLength: */
83   0x21,                   /* bDescriptorType: USBDESCR_ICC */
84   0x10, 0x01,             /* bcdCCID: revision 1.1 (of CCID) */
85   0,                      /* bMaxSlotIndex: */
86   1,                      /* bVoltageSupport: FIXED VALUE */
87   0x02, 0, 0, 0,          /* dwProtocols: T=1 */
88   0xf3, 0x0d, 0, 0,       /* dwDefaultClock: 3571 (non-ICCD): 3580 (ICCD) */
89   0xf3, 0x0d, 0, 0,       /* dwMaximumClock: 3571 (non-ICCD): 3580 (ICCD) */
90   1,                      /* bNumClockSupported: FIXED VALUE */
91   0x80, 0x25, 0, 0,       /* dwDataRate: 9600: FIXED VALUE */
92   0x80, 0x25, 0, 0,       /* dwMaxDataRate: 9600: FIXED VALUE */
93   1,                      /* bNumDataRateSupported: FIXED VALUE */
94   0xfe, 0, 0, 0,          /* dwMaxIFSD: 254 */
95   0, 0, 0, 0,             /* dwSynchProtocols: FIXED VALUE */
96   0, 0, 0, 0,             /* dwMechanical: FIXED VALUE */
97   /*
98    * According to Specification for USB ICCD (revision 1.0),
99    * dwFeatures should be 0x00040840.
100    *
101    * It is different now for better interaction to GPG's in-stock
102    * ccid-driver.
103    */
104   0x42, 0x08, 0x02, 0x00, /* dwFeatures (not ICCD):
105                            *  Short APDU level             : 0x20000 *
106                            *  (what? means ICCD?)          : 0x00800 *
107                            *  Automatic IFSD               : 0x00400
108                            *  NAD value other than 0x00    : 0x00200
109                            *  Can set ICC in clock stop    : 0x00100
110                            *  Automatic PPS CUR            : 0x00080
111                            *  Automatic PPS PROP           : 0x00040 *
112                            *  Auto baud rate change        : 0x00020
113                            *  Auto clock change            : 0x00010
114                            *  Auto voltage selection       : 0x00008
115                            *  Auto activaction of ICC      : 0x00004
116                            *  Automatic conf. based on ATR : 0x00002  g
117                            */
118   0x0f, 0x01, 0, 0,       /* dwMaxCCIDMessageLength: 271 */
119   0xff,                   /* bClassGetResponse: */
120   0xff,                   /* bClassEnvelope: */
121   0, 0,                   /* wLCDLayout: FIXED VALUE */
122 #if defined(PINPAD_SUPPORT)
123 #if defined(PINPAD_CIR_SUPPORT) || defined(PINPAD_DND_SUPPORT)
124   1,                      /* bPinSupport: with PIN pad (verify) */
125 #elif defined(PINPAD_DIAL_SUPPORT)
126   3,                      /* bPinSupport: with PIN pad (verify, modify) */
127 #endif
128 #else
129   0,                      /* bPinSupport: No PIN pad */
130 #endif
131   1,                      /* bMaxCCIDBusySlots: 1 */
132   /*Endpoint 1 Descriptor*/
133   7,                           /* bLength: Endpoint Descriptor size */
134   USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
135   0x81,                         /* bEndpointAddress: (IN1) */
136   0x02,                         /* bmAttributes: Bulk */
137   USB_ICC_DATA_SIZE, 0x00,      /* wMaxPacketSize: */
138   0x00,                         /* bInterval */
139   /*Endpoint 2 Descriptor*/
140   7,                           /* bLength: Endpoint Descriptor size */
141   USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
142   0x02,                         /* bEndpointAddress: (OUT2) */
143   0x02,                         /* bmAttributes: Bulk */
144   USB_ICC_DATA_SIZE, 0x00,      /* wMaxPacketSize: */
145   0x00,                         /* bInterval */
146 #ifdef ENABLE_VIRTUAL_COM_PORT
147   /* Interface Descriptor */
148   9,                          /* bLength: Interface Descriptor size */
149   USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
150   0x01,           /* bInterfaceNumber: Number of Interface */
151   0x00,           /* bAlternateSetting: Alternate setting */
152   0x01,           /* bNumEndpoints: One endpoints used */
153   0x02,           /* bInterfaceClass: Communication Interface Class */
154   0x02,           /* bInterfaceSubClass: Abstract Control Model */
155   0x01,           /* bInterfaceProtocol: Common AT commands */
156   0x00,           /* iInterface: */
157   /*Header Functional Descriptor*/
158   5,                        /* bLength: Endpoint Descriptor size */
159   0x24,                     /* bDescriptorType: CS_INTERFACE */
160   0x00,                     /* bDescriptorSubtype: Header Func Desc */
161   0x10,                     /* bcdCDC: spec release number */
162   0x01,
163   /*Call Managment Functional Descriptor*/
164   5,        /* bFunctionLength */
165   0x24,     /* bDescriptorType: CS_INTERFACE */
166   0x01,     /* bDescriptorSubtype: Call Management Func Desc */
167   0x03,     /* bmCapabilities: D0+D1 */
168   0x02,     /* bDataInterface: 2 */
169   /*ACM Functional Descriptor*/
170   4,        /* bFunctionLength */
171   0x24,     /* bDescriptorType: CS_INTERFACE */
172   0x02,     /* bDescriptorSubtype: Abstract Control Management desc */
173   0x02,     /* bmCapabilities */
174   /*Union Functional Descriptor*/
175   5,             /* bFunctionLength */
176   0x24,          /* bDescriptorType: CS_INTERFACE */
177   0x06,          /* bDescriptorSubtype: Union func desc */
178   0x01,          /* bMasterInterface: Communication class interface */
179   0x02,          /* bSlaveInterface0: Data Class Interface */
180   /*Endpoint 4 Descriptor*/
181   7,                           /* bLength: Endpoint Descriptor size */
182   USB_ENDPOINT_DESCRIPTOR_TYPE,    /* bDescriptorType: Endpoint */
183   0x84,                            /* bEndpointAddress: (IN4) */
184   0x03,                            /* bmAttributes: Interrupt */
185   VIRTUAL_COM_PORT_INT_SIZE, 0x00, /* wMaxPacketSize: */
186   0xFF,                            /* bInterval: */
187
188   /*Data class interface descriptor*/
189   9,                           /* bLength: Endpoint Descriptor size */
190   USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
191   0x02,                    /* bInterfaceNumber: Number of Interface */
192   0x00,                    /* bAlternateSetting: Alternate setting */
193   0x02,                    /* bNumEndpoints: Two endpoints used */
194   0x0A,                    /* bInterfaceClass: CDC */
195   0x00,                    /* bInterfaceSubClass: */
196   0x00,                    /* bInterfaceProtocol: */
197   0x00,                    /* iInterface: */
198   /*Endpoint 5 Descriptor*/
199   7,                           /* bLength: Endpoint Descriptor size */
200   USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType: Endpoint */
201   0x05,                             /* bEndpointAddress: (OUT5) */
202   0x02,                             /* bmAttributes: Bulk */
203   VIRTUAL_COM_PORT_DATA_SIZE, 0x00, /* wMaxPacketSize: */
204   0x00,                      /* bInterval: ignore for Bulk transfer */
205   /*Endpoint 3 Descriptor*/
206   7,                           /* bLength: Endpoint Descriptor size */
207   USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType: Endpoint */
208   0x83,                             /* bEndpointAddress: (IN3) */
209   0x02,                             /* bmAttributes: Bulk */
210   VIRTUAL_COM_PORT_DATA_SIZE, 0x00, /* wMaxPacketSize: */
211   0x00,                             /* bInterval */
212 #endif
213 #ifdef PINPAD_DND_SUPPORT
214   /* Interface Descriptor.*/
215   9,                          /* bLength: Interface Descriptor size */
216   USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
217 #ifdef ENABLE_VIRTUAL_COM_PORT
218   0x03,                         /* bInterfaceNumber.                */
219 #else
220   0x01,                         /* bInterfaceNumber.                */
221 #endif
222   0x00,                         /* bAlternateSetting.               */
223   0x02,                         /* bNumEndpoints.                   */
224   0x08,                         /* bInterfaceClass (Mass Stprage).  */
225   0x06,                         /* bInterfaceSubClass (SCSI
226                                    transparent command set, MSCO
227                                    chapter 2).                      */
228   0x50,                         /* bInterfaceProtocol (Bulk-Only
229                                    Mass Storage, MSCO chapter 3).  */
230   0x00,                         /* iInterface.                      */
231   /* Endpoint Descriptor.*/
232   7,                           /* bLength: Endpoint Descriptor size */
233   USB_ENDPOINT_DESCRIPTOR_TYPE,    /* bDescriptorType: Endpoint */
234   0x86,                            /* bEndpointAddress: (IN6)   */
235   0x02,                         /* bmAttributes (Bulk).             */
236   0x40, 0x00,                   /* wMaxPacketSize.                  */
237   0x00,                         /* bInterval (ignored for bulk).    */
238   /* Endpoint Descriptor.*/
239   7,                           /* bLength: Endpoint Descriptor size */
240   USB_ENDPOINT_DESCRIPTOR_TYPE,    /* bDescriptorType: Endpoint */
241   0x07,                            /* bEndpointAddress: (OUT7)    */
242   0x02,                  /* bmAttributes (Bulk).             */
243   0x40, 0x00,            /* wMaxPacketSize.                  */
244   0x00,         /* bInterval (ignored for bulk).    */
245 #endif
246 };
247
248
249 /* USB String Descriptors */
250 static const uint8_t gnukStringLangID[] = {
251   4,                            /* bLength */
252   USB_STRING_DESCRIPTOR_TYPE,
253   0x09, 0x04                    /* LangID = 0x0409: US-English */
254 };
255
256 #include "usb-string-vender-product.c.inc"
257
258 const uint8_t gnukStringSerial[] = {
259   18*2+2,                       /* bLength */
260   USB_STRING_DESCRIPTOR_TYPE,   /* bDescriptorType */
261   'F', 0, 'S', 0, 'I', 0, 'J', 0, '-', 0, 
262   '0', 0, '.', 0, '1', 0, '7', 0, /* Version number of Gnuk */
263   '-', 0,
264   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
265   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
266 };
267
268
269 const struct Descriptor Device_Descriptor = {
270   gnukDeviceDescriptor,
271   sizeof (gnukDeviceDescriptor)
272 };
273
274 const struct Descriptor Config_Descriptor = {
275   gnukConfigDescriptor,
276   sizeof (gnukConfigDescriptor)
277 };
278
279 const struct Descriptor String_Descriptors[NUM_STRING_DESC] = {
280   {gnukStringLangID, sizeof (gnukStringLangID)},
281   {gnukStringVendor, sizeof (gnukStringVendor)},
282   {gnukStringProduct, sizeof (gnukStringProduct)},
283   {gnukStringSerial, sizeof (gnukStringSerial)},
284 };