3005ec745e2df074fb82ed1f513bfad9c9ba7cb8
[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,                             /* 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   0x00, 0x01,             /* bcdCCID: revision 1.0 */
70   0,                      /* bMaxSlotIndex: */
71   1,                      /* bVoltageSupport: FIXED VALUE */
72   0x02, 0, 0, 0,          /* dwProtocols: T=1 */
73   0xfc, 0x0d, 0, 0,       /* dwDefaultClock: FIXED VALUE */
74   0xfc, 0x0d, 0, 0,       /* dwMaximumClock: FIXED VALUE*/
75   1,                      /* bNumClockSupported: FIXED VALUE*/
76   0x80, 0x25, 0, 0,       /* dwDataRate: FIXED VALUE */
77   0x80, 0x25, 0, 0,       /* dwMaxDataRate: FIXED VALUE */
78   1,                      /* bNumDataRateSupported: FIXED VALUE */
79   0xfe, 0, 0, 0,          /* dwMaxIFSD:  */
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 #ifdef DEBUG
90   0x82, 0x04, 0x04, 0x00, /* dwFeatures:
91                            *  Short and extended APDU level: 0x40000
92                            *  Automatic IFSD               : 0x00400
93                            *  Automatic PPS CUR            : 0x00080
94                            *
95                            *  Automatic conf. based on ATR : 0x00002
96                            */
97 #else
98   0x42, 0x00, 0x04, 0x00, /* dwFeatures:
99                            *  Short and extended APDU level: 0x40000
100                            *  Automatic PPS PROP           : 0x00040
101                            *
102                            *  Automatic conf. based on ATR : 0x00002
103                            */
104 #endif
105   0x40, 0x01, 0, 0,       /* dwMaxCCIDMessageLength */
106   0xff,                   /* bClassGetResponse: */
107   0xff,                   /* bClassEnvelope: */
108   0, 0,                   /* wLCDLayout: FIXED VALUE */
109   0,                      /* bPinSupport: No PIN pad */
110   1,                      /* bMaxCCIDBusySlots: 1 */
111   /*Endpoint 1 Descriptor*/
112   7,                           /* bLength: Endpoint Descriptor size */
113   USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
114   0x81,                         /* bEndpointAddress: (IN1) */
115   0x02,                         /* bmAttributes: Bulk */
116   USB_ICC_DATA_SIZE, 0x00,      /* wMaxPacketSize: */
117   0x00,                         /* bInterval */
118   /*Endpoint 2 Descriptor*/
119   7,                           /* bLength: Endpoint Descriptor size */
120   USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
121   0x02,                         /* bEndpointAddress: (OUT2) */
122   0x02,                         /* bmAttributes: Bulk */
123   USB_ICC_DATA_SIZE, 0x00,      /* wMaxPacketSize: */
124   0x00,                         /* bInterval */
125 #ifdef ENABLE_VIRTUAL_COM_PORT
126   /* Interface Descriptor */
127   9,                          /* bLength: Interface Descriptor size */
128   USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
129   0x01,           /* bInterfaceNumber: Number of Interface */
130   0x00,           /* bAlternateSetting: Alternate setting */
131   0x01,           /* bNumEndpoints: One endpoints used */
132   0x02,           /* bInterfaceClass: Communication Interface Class */
133   0x02,           /* bInterfaceSubClass: Abstract Control Model */
134   0x01,           /* bInterfaceProtocol: Common AT commands */
135   0x00,           /* iInterface: */
136   /*Header Functional Descriptor*/
137   5,                        /* bLength: Endpoint Descriptor size */
138   0x24,                     /* bDescriptorType: CS_INTERFACE */
139   0x00,                     /* bDescriptorSubtype: Header Func Desc */
140   0x10,                     /* bcdCDC: spec release number */
141   0x01,
142   /*Call Managment Functional Descriptor*/
143   5,        /* bFunctionLength */
144   0x24,     /* bDescriptorType: CS_INTERFACE */
145   0x01,     /* bDescriptorSubtype: Call Management Func Desc */
146   0x03,     /* bmCapabilities: D0+D1 */
147   0x02,     /* bDataInterface: 2 */
148   /*ACM Functional Descriptor*/
149   4,        /* bFunctionLength */
150   0x24,     /* bDescriptorType: CS_INTERFACE */
151   0x02,     /* bDescriptorSubtype: Abstract Control Management desc */
152   0x02,     /* bmCapabilities */
153   /*Union Functional Descriptor*/
154   5,             /* bFunctionLength */
155   0x24,          /* bDescriptorType: CS_INTERFACE */
156   0x06,          /* bDescriptorSubtype: Union func desc */
157   0x01,          /* bMasterInterface: Communication class interface */
158   0x02,          /* bSlaveInterface0: Data Class Interface */
159   /*Endpoint 4 Descriptor*/
160   7,                           /* bLength: Endpoint Descriptor size */
161   USB_ENDPOINT_DESCRIPTOR_TYPE,    /* bDescriptorType: Endpoint */
162   0x84,                            /* bEndpointAddress: (IN4) */
163   0x03,                            /* bmAttributes: Interrupt */
164   VIRTUAL_COM_PORT_INT_SIZE, 0x00, /* wMaxPacketSize: */
165   0xFF,                            /* bInterval: */
166
167   /*Data class interface descriptor*/
168   9,                           /* bLength: Endpoint Descriptor size */
169   USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
170   0x02,                    /* bInterfaceNumber: Number of Interface */
171   0x00,                    /* bAlternateSetting: Alternate setting */
172   0x02,                    /* bNumEndpoints: Two endpoints used */
173   0x0A,                    /* bInterfaceClass: CDC */
174   0x00,                    /* bInterfaceSubClass: */
175   0x00,                    /* bInterfaceProtocol: */
176   0x00,                    /* iInterface: */
177   /*Endpoint 5 Descriptor*/
178   7,                           /* bLength: Endpoint Descriptor size */
179   USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType: Endpoint */
180   0x05,                             /* bEndpointAddress: (OUT5) */
181   0x02,                             /* bmAttributes: Bulk */
182   VIRTUAL_COM_PORT_DATA_SIZE, 0x00, /* wMaxPacketSize: */
183   0x00,                      /* bInterval: ignore for Bulk transfer */
184   /*Endpoint 3 Descriptor*/
185   7,                           /* bLength: Endpoint Descriptor size */
186   USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType: Endpoint */
187   0x83,                             /* bEndpointAddress: (IN3) */
188   0x02,                             /* bmAttributes: Bulk */
189   VIRTUAL_COM_PORT_DATA_SIZE, 0x00, /* wMaxPacketSize: */
190   0x00                              /* bInterval */
191 #endif
192 };
193
194
195 /* USB String Descriptors */
196 static const uint8_t gnukStringLangID[] = {
197   4,                            /* bLength */
198   USB_STRING_DESCRIPTOR_TYPE,
199   0x09, 0x04                    /* LangID = 0x0409: US-English */
200 };
201
202 static const uint8_t gnukStringVendor[] = {
203   33*2+2,                       /* bLength */
204   USB_STRING_DESCRIPTOR_TYPE,   /* bDescriptorType*/
205   /* Manufacturer: "Free Software Initiative of Japan" */
206   'F', 0, 'r', 0, 'e', 0, 'e', 0, ' ', 0, 'S', 0, 'o', 0, 'f', 0,
207   't', 0, 'w', 0, 'a', 0, 'r', 0, 'e', 0, ' ', 0, 'I', 0, 'n', 0,
208   'i', 0, 't', 0, 'i', 0, 'a', 0, 't', 0, 'i', 0, 'v', 0, 'e', 0,
209   ' ', 0, 'o', 0, 'f', 0, ' ', 0, 'J', 0, 'a', 0, 'p', 0, 'a', 0,
210   'n', 0
211 };
212
213 static const uint8_t gnukStringProduct[] = {
214   14*2+2,                       /* bLength */
215   USB_STRING_DESCRIPTOR_TYPE,   /* bDescriptorType */
216   /* Product name: "FSIJ USB Token" */
217   'F', 0, 'S', 0, 'I', 0, 'J', 0, ' ', 0, 'U', 0, 'S', 0, 'B', 0,
218   ' ', 0, 'T', 0, 'o', 0, 'k', 0, 'e', 0, 'n', 0
219 };
220
221 static const uint8_t gnukStringSerial[] = {
222   8*2+2,                        /* bLength */
223   USB_STRING_DESCRIPTOR_TYPE,   /* bDescriptorType */
224   '2', 0, '0', 0, '1', 0, '0', 0,
225   '1', 0, '1', 0, '1', 0, '2', 0
226 };
227
228 const ONE_DESCRIPTOR Device_Descriptor = {
229   (uint8_t*)gnukDeviceDescriptor,
230   sizeof (gnukDeviceDescriptor)
231 };
232
233 const ONE_DESCRIPTOR Config_Descriptor = {
234   (uint8_t*)gnukConfigDescriptor,
235   sizeof (gnukConfigDescriptor)
236 };
237
238 const ONE_DESCRIPTOR String_Descriptor[4] = {
239   {(uint8_t*)gnukStringLangID, sizeof (gnukStringLangID)},
240   {(uint8_t*)gnukStringVendor, sizeof (gnukStringVendor)},
241   {(uint8_t*)gnukStringProduct, sizeof (gnukStringProduct)},
242   {(uint8_t*)gnukStringSerial, sizeof (gnukStringSerial)},
243 };