works better on windows
[gnuk/gnuk.git] / src / usb_desc.c
1 /*
2  * usb_desc.c - USB Descriptor
3  */
4
5 #include "config.h"
6 #include "usb_lib.h"
7 #include "usb_desc.h"
8
9 #define USB_ICC_INTERFACE_CLASS 0x0B
10 #define USB_ICC_INTERFACE_SUBCLASS 0x00
11 #define USB_ICC_INTERFACE_BULK_PROTOCOL 0x00
12 #define USB_ICC_DATA_SIZE 64
13
14 /* USB Standard Device Descriptor */
15 static const uint8_t gnukDeviceDescriptor[] = {
16   18,   /* bLength */
17   USB_DEVICE_DESCRIPTOR_TYPE,     /* bDescriptorType */
18   0x00, 0x02,   /* bcdUSB = 2.00 */
19   0x00,   /* bDeviceClass: 0 means deferred to interface */
20   0x00,   /* bDeviceSubClass */
21   0x00,   /* bDeviceProtocol */
22   0x40,   /* bMaxPacketSize0 */
23   0x4b, 0x23,   /* idVendor = 0x234b (FSIJ) */
24   0x00, 0x00,   /* idProduct = 0x0000 (FSIJ USB Token) */
25   0x00, 0x02,   /* bcdDevice = 2.00 */
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 #ifdef ENABLE_VIRTUAL_COM_PORT
33 #define W_TOTAL_LENGTH (9+9+54+7+7+9+5+5+4+5+7+9+7+7)
34 #define NUM_INTERFACES 3        /* two for CDC, one for GPG */
35 #else
36 #define W_TOTAL_LENGTH (9+9+54+7+7)
37 #define NUM_INTERFACES 1        /* GPG only */
38 #endif
39
40 /* Configuation Descriptor */
41 static const uint8_t gnukConfigDescriptor[] = {
42   9,                       /* bLength: Configuation Descriptor size */
43   USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* bDescriptorType: Configuration */
44   W_TOTAL_LENGTH, 0x00,   /* wTotalLength:no of returned bytes */
45   NUM_INTERFACES,   /* bNumInterfaces: */
46   0x01,   /* bConfigurationValue: Configuration value */
47   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
48 #if defined(USB_SELF_POWERED)
49   0xC0,   /* bmAttributes: self powered */
50 #else
51   0x80,   /* bmAttributes: bus powered */
52 #endif
53   50,     /* MaxPower 100 mA */
54
55   /* Interface Descriptor */
56   9,                          /* bLength: Interface Descriptor size */
57   USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
58   0,                             /* bInterfaceNumber: Index of this interface */
59   0,                        /* Alternate setting for this interface */
60   2,                        /* bNumEndpoints: Bulk-IN, Bulk-OUT */
61   USB_ICC_INTERFACE_CLASS,
62   USB_ICC_INTERFACE_SUBCLASS,
63   USB_ICC_INTERFACE_BULK_PROTOCOL,
64   0,                            /* string index for interface */
65
66   /* ICC Descriptor */
67   54,                     /* bLength: */
68   0x21,                   /* bDescriptorType: USBDESCR_ICC */
69   0x10, 0x01,             /* bcdCCID: revision 1.1 (of CCID) */
70   0,                      /* bMaxSlotIndex: */
71   1,                      /* bVoltageSupport: FIXED VALUE */
72   0x02, 0, 0, 0,          /* dwProtocols: T=1 */
73   0xf3, 0x0d, 0, 0,       /* dwDefaultClock: 3571 (non-ICCD): 3580 (ICCD) */
74   0xf3, 0x0d, 0, 0,       /* dwMaximumClock: 3571 (non-ICCD): 3580 (ICCD) */
75   1,                      /* bNumClockSupported: FIXED VALUE */
76   0x80, 0x25, 0, 0,       /* dwDataRate: 9600: FIXED VALUE */
77   0x80, 0x25, 0, 0,       /* dwMaxDataRate: 9600: FIXED VALUE */
78   1,                      /* bNumDataRateSupported: FIXED VALUE */
79   0xfe, 0, 0, 0,          /* dwMaxIFSD: 254 */
80   0, 0, 0, 0,             /* dwSynchProtocols: FIXED VALUE */
81   0, 0, 0, 0,             /* dwMechanical: FIXED VALUE */
82   /*
83    * According to Specification for USB ICCD (revision 1.0),
84    * dwFeatures should be 0x00040840.
85    *
86    * It is different now for better interaction to GPG's in-stock
87    * ccid-driver.
88    */
89   0x42, 0x08, 0x04, 0x00, /* dwFeatures (not ICCD):
90                            *  Short and extended APDU level: 0x40000 *
91                            *  (what? means ICCD?)          : 0x00800 *
92                            *  Automatic IFSD               : 0x00400
93                            *  NAD value other than 0x00    : 0x00200
94                            *  Can set ICC in clock stop    : 0x00100
95                            *  Automatic PPS CUR            : 0x00080
96                            *  Automatic PPS PROP           : 0x00040 *
97                            *  Auto baud rate change        : 0x00020
98                            *  Auto clock change            : 0x00010
99                            *  Auto voltage selection       : 0x00008
100                            *  Auto activaction of ICC      : 0x00004
101                            *  Automatic conf. based on ATR : 0x00002  g
102                            */
103   0x40, 0x01, 0, 0,       /* dwMaxCCIDMessageLength */
104   0xff,                   /* bClassGetResponse: */
105   0xff,                   /* bClassEnvelope: */
106   0, 0,                   /* wLCDLayout: FIXED VALUE */
107   0,                      /* bPinSupport: No PIN pad */
108   1,                      /* bMaxCCIDBusySlots: 1 */
109   /*Endpoint 1 Descriptor*/
110   7,                           /* bLength: Endpoint Descriptor size */
111   USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
112   0x81,                         /* bEndpointAddress: (IN1) */
113   0x02,                         /* bmAttributes: Bulk */
114   USB_ICC_DATA_SIZE, 0x00,      /* wMaxPacketSize: */
115   0x00,                         /* bInterval */
116   /*Endpoint 2 Descriptor*/
117   7,                           /* bLength: Endpoint Descriptor size */
118   USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
119   0x02,                         /* bEndpointAddress: (OUT2) */
120   0x02,                         /* bmAttributes: Bulk */
121   USB_ICC_DATA_SIZE, 0x00,      /* wMaxPacketSize: */
122   0x00,                         /* bInterval */
123 #ifdef ENABLE_VIRTUAL_COM_PORT
124   /* Interface Descriptor */
125   9,                          /* bLength: Interface Descriptor size */
126   USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
127   0x01,           /* bInterfaceNumber: Number of Interface */
128   0x00,           /* bAlternateSetting: Alternate setting */
129   0x01,           /* bNumEndpoints: One endpoints used */
130   0x02,           /* bInterfaceClass: Communication Interface Class */
131   0x02,           /* bInterfaceSubClass: Abstract Control Model */
132   0x01,           /* bInterfaceProtocol: Common AT commands */
133   0x00,           /* iInterface: */
134   /*Header Functional Descriptor*/
135   5,                        /* bLength: Endpoint Descriptor size */
136   0x24,                     /* bDescriptorType: CS_INTERFACE */
137   0x00,                     /* bDescriptorSubtype: Header Func Desc */
138   0x10,                     /* bcdCDC: spec release number */
139   0x01,
140   /*Call Managment Functional Descriptor*/
141   5,        /* bFunctionLength */
142   0x24,     /* bDescriptorType: CS_INTERFACE */
143   0x01,     /* bDescriptorSubtype: Call Management Func Desc */
144   0x03,     /* bmCapabilities: D0+D1 */
145   0x02,     /* bDataInterface: 2 */
146   /*ACM Functional Descriptor*/
147   4,        /* bFunctionLength */
148   0x24,     /* bDescriptorType: CS_INTERFACE */
149   0x02,     /* bDescriptorSubtype: Abstract Control Management desc */
150   0x02,     /* bmCapabilities */
151   /*Union Functional Descriptor*/
152   5,             /* bFunctionLength */
153   0x24,          /* bDescriptorType: CS_INTERFACE */
154   0x06,          /* bDescriptorSubtype: Union func desc */
155   0x01,          /* bMasterInterface: Communication class interface */
156   0x02,          /* bSlaveInterface0: Data Class Interface */
157   /*Endpoint 4 Descriptor*/
158   7,                           /* bLength: Endpoint Descriptor size */
159   USB_ENDPOINT_DESCRIPTOR_TYPE,    /* bDescriptorType: Endpoint */
160   0x84,                            /* bEndpointAddress: (IN4) */
161   0x03,                            /* bmAttributes: Interrupt */
162   VIRTUAL_COM_PORT_INT_SIZE, 0x00, /* wMaxPacketSize: */
163   0xFF,                            /* bInterval: */
164
165   /*Data class interface descriptor*/
166   9,                           /* bLength: Endpoint Descriptor size */
167   USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
168   0x02,                    /* bInterfaceNumber: Number of Interface */
169   0x00,                    /* bAlternateSetting: Alternate setting */
170   0x02,                    /* bNumEndpoints: Two endpoints used */
171   0x0A,                    /* bInterfaceClass: CDC */
172   0x00,                    /* bInterfaceSubClass: */
173   0x00,                    /* bInterfaceProtocol: */
174   0x00,                    /* iInterface: */
175   /*Endpoint 5 Descriptor*/
176   7,                           /* bLength: Endpoint Descriptor size */
177   USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType: Endpoint */
178   0x05,                             /* bEndpointAddress: (OUT5) */
179   0x02,                             /* bmAttributes: Bulk */
180   VIRTUAL_COM_PORT_DATA_SIZE, 0x00, /* wMaxPacketSize: */
181   0x00,                      /* bInterval: ignore for Bulk transfer */
182   /*Endpoint 3 Descriptor*/
183   7,                           /* bLength: Endpoint Descriptor size */
184   USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType: Endpoint */
185   0x83,                             /* bEndpointAddress: (IN3) */
186   0x02,                             /* bmAttributes: Bulk */
187   VIRTUAL_COM_PORT_DATA_SIZE, 0x00, /* wMaxPacketSize: */
188   0x00                              /* bInterval */
189 #endif
190 };
191
192
193 /* USB String Descriptors */
194 static const uint8_t gnukStringLangID[] = {
195   4,                            /* bLength */
196   USB_STRING_DESCRIPTOR_TYPE,
197   0x09, 0x04                    /* LangID = 0x0409: US-English */
198 };
199
200 static const uint8_t gnukStringVendor[] = {
201   33*2+2,                       /* bLength */
202   USB_STRING_DESCRIPTOR_TYPE,   /* bDescriptorType*/
203   /* Manufacturer: "Free Software Initiative of Japan" */
204   'F', 0, 'r', 0, 'e', 0, 'e', 0, ' ', 0, 'S', 0, 'o', 0, 'f', 0,
205   't', 0, 'w', 0, 'a', 0, 'r', 0, 'e', 0, ' ', 0, 'I', 0, 'n', 0,
206   'i', 0, 't', 0, 'i', 0, 'a', 0, 't', 0, 'i', 0, 'v', 0, 'e', 0,
207   ' ', 0, 'o', 0, 'f', 0, ' ', 0, 'J', 0, 'a', 0, 'p', 0, 'a', 0,
208   'n', 0
209 };
210
211 static const uint8_t gnukStringProduct[] = {
212   14*2+2,                       /* bLength */
213   USB_STRING_DESCRIPTOR_TYPE,   /* bDescriptorType */
214   /* Product name: "FSIJ USB Token" */
215   'F', 0, 'S', 0, 'I', 0, 'J', 0, ' ', 0, 'U', 0, 'S', 0, 'B', 0,
216   ' ', 0, 'T', 0, 'o', 0, 'k', 0, 'e', 0, 'n', 0
217 };
218
219 static const uint8_t gnukStringSerial[] = {
220   8*2+2,                        /* bLength */
221   USB_STRING_DESCRIPTOR_TYPE,   /* bDescriptorType */
222   '2', 0, '0', 0, '1', 0, '0', 0,
223   '1', 0, '1', 0, '1', 0, '2', 0
224 };
225
226 const ONE_DESCRIPTOR Device_Descriptor = {
227   (uint8_t*)gnukDeviceDescriptor,
228   sizeof (gnukDeviceDescriptor)
229 };
230
231 const ONE_DESCRIPTOR Config_Descriptor = {
232   (uint8_t*)gnukConfigDescriptor,
233   sizeof (gnukConfigDescriptor)
234 };
235
236 const ONE_DESCRIPTOR String_Descriptor[4] = {
237   {(uint8_t*)gnukStringLangID, sizeof (gnukStringLangID)},
238   {(uint8_t*)gnukStringVendor, sizeof (gnukStringVendor)},
239   {(uint8_t*)gnukStringProduct, sizeof (gnukStringProduct)},
240   {(uint8_t*)gnukStringSerial, sizeof (gnukStringSerial)},
241 };