9949359c5212ff7b96a7ba0b24c91387fccffbc6
[gnuk/gnuk.git] / src / usb_prop.c
1 /*
2  * usb_prop.c - glue/interface code between Gnuk and USB-FS-Device_Lib
3  *
4  * Copyright (C) 2010 Free Software Initiative of Japan
5  * Author: NIIBE Yutaka <gniibe@fsij.org>
6  *
7  * This file is a part of Gnuk, a GnuPG USB Token implementation.
8  *
9  * Gnuk is free software: you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * Gnuk is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 /* Packet size of USB Bulk transfer for full speed */
25 #define GNUK_MAX_PACKET_SIZE 64
26
27 #include "config.h"
28 #include "usb_lib.h"
29 #include "usb_conf.h"
30 #include "usb_prop.h"
31 #include "usb_desc.h"
32 #include "usb_pwr.h"
33 #include "hw_config.h"
34
35 #ifdef ENABLE_VIRTUAL_COM_PORT
36 #include "usb-cdc-vport.c"
37 #endif
38
39 static void
40 gnuk_device_init (void)
41 {
42   pInformation->Current_Configuration = 0;
43
44   /* Connect the device */
45   PowerOn ();
46
47   /* Perform basic device initialization operations */
48   USB_SIL_Init ();
49
50   bDeviceState = UNCONNECTED;
51 }
52
53 static void
54 gnuk_device_reset (void)
55 {
56   /* Set DEVICE as not configured */
57   pInformation->Current_Configuration = 0;
58
59   /* Current Feature initialization */
60   pInformation->Current_Feature = Config_Descriptor.Descriptor[7];
61
62   /* Set DEVICE with the default Interface*/
63   pInformation->Current_Interface = 0;
64
65   SetBTABLE (BTABLE_ADDRESS);
66
67   /* Initialize Endpoint 0 */
68   SetEPType (ENDP0, EP_CONTROL);
69   SetEPTxStatus (ENDP0, EP_TX_STALL);
70   SetEPRxAddr (ENDP0, ENDP0_RXADDR);
71   SetEPTxAddr (ENDP0, ENDP0_TXADDR);
72   Clear_Status_Out (ENDP0);
73   SetEPRxCount (ENDP0, GNUK_MAX_PACKET_SIZE);
74   SetEPRxValid (ENDP0);
75
76   /* Initialize Endpoint 1 */
77   SetEPType (ENDP1, EP_BULK);
78   SetEPTxAddr (ENDP1, ENDP1_TXADDR);
79   SetEPTxStatus (ENDP1, EP_TX_NAK);
80   SetEPRxStatus (ENDP1, EP_RX_DIS);
81
82   /* Initialize Endpoint 2 */
83   SetEPType (ENDP2, EP_BULK);
84   SetEPRxAddr (ENDP2, ENDP2_RXADDR);
85   SetEPRxCount (ENDP2, GNUK_MAX_PACKET_SIZE);
86   SetEPRxStatus (ENDP2, EP_RX_VALID);
87   SetEPTxStatus (ENDP2, EP_TX_DIS);
88
89 #ifdef ENABLE_VIRTUAL_COM_PORT
90   /* Initialize Endpoint 3 */
91   SetEPType (ENDP3, EP_BULK);
92   SetEPTxAddr (ENDP3, ENDP3_TXADDR);
93   SetEPTxStatus (ENDP3, EP_TX_NAK);
94   SetEPRxStatus (ENDP3, EP_RX_DIS);
95
96   /* Initialize Endpoint 4 */
97   SetEPType (ENDP4, EP_INTERRUPT);
98   SetEPTxAddr (ENDP4, ENDP4_TXADDR);
99   SetEPTxStatus (ENDP4, EP_TX_NAK);
100   SetEPRxStatus (ENDP4, EP_RX_DIS);
101
102   /* Initialize Endpoint 5 */
103   SetEPType (ENDP5, EP_BULK);
104   SetEPRxAddr (ENDP5, ENDP5_RXADDR);
105   SetEPRxCount (ENDP5, VIRTUAL_COM_PORT_DATA_SIZE);
106   SetEPRxStatus (ENDP5, EP_RX_VALID);
107   SetEPTxStatus (ENDP5, EP_TX_DIS);
108 #endif
109
110   /* Set this device to response on default address */
111   SetDeviceAddress (0);
112
113   bDeviceState = ATTACHED;
114 }
115
116 static void
117 gnuk_device_SetConfiguration (void)
118 {
119   DEVICE_INFO *pInfo = &Device_Info;
120
121   if (pInfo->Current_Configuration != 0)
122     /* Device configured */
123     bDeviceState = CONFIGURED;
124 }
125
126 static void
127 gnuk_device_SetDeviceAddress (void)
128 {
129   bDeviceState = ADDRESSED;
130 }
131
132 /* IN from port 0 */
133 static void
134 gnuk_device_Status_In (void)
135 {
136 }
137
138 /* OUT to port 0 */
139 static void
140 gnuk_device_Status_Out (void)
141 {
142 }
143
144 static uint8_t *
145 gnuk_device_GetDeviceDescriptor (uint16_t Length)
146 {
147   return Standard_GetDescriptorData (Length,
148                                      (PONE_DESCRIPTOR)&Device_Descriptor);
149 }
150
151 static uint8_t *
152 gnuk_device_GetConfigDescriptor (uint16_t Length)
153 {
154   return Standard_GetDescriptorData (Length,
155                                      (PONE_DESCRIPTOR)&Config_Descriptor);
156 }
157
158 static uint8_t *
159 gnuk_device_GetStringDescriptor (uint16_t Length)
160 {
161   uint8_t wValue0 = pInformation->USBwValue0;
162
163   if (wValue0 > (sizeof (String_Descriptor) / sizeof (ONE_DESCRIPTOR)))
164     return NULL;
165   else
166     return Standard_GetDescriptorData (Length,
167                                        (PONE_DESCRIPTOR)&String_Descriptor[wValue0]);
168 }
169
170 static RESULT
171 gnuk_device_Get_Interface_Setting (uint8_t Interface, uint8_t AlternateSetting)
172 {
173   if (AlternateSetting > 0)
174     return USB_UNSUPPORT;
175   else if (Interface > 1)
176     return USB_UNSUPPORT;
177
178   return USB_SUCCESS;
179 }
180
181 #if !defined(ENABLE_VIRTUAL_COM_PORT)
182 static RESULT
183 gnuk_nothing_todo (uint8_t RequestNo)
184 {
185   (void)RequestNo;
186   return USB_UNSUPPORT;
187 }
188 #endif
189
190 /*
191  * Interface to USB core
192  */
193
194 const DEVICE_PROP Device_Property = {
195   gnuk_device_init,
196   gnuk_device_reset,
197   gnuk_device_Status_In,
198   gnuk_device_Status_Out,
199 #ifdef ENABLE_VIRTUAL_COM_PORT
200   Virtual_Com_Port_Data_Setup,
201   Virtual_Com_Port_NoData_Setup,
202 #else
203   gnuk_nothing_todo,
204   gnuk_nothing_todo,
205 #endif
206   gnuk_device_Get_Interface_Setting,
207   gnuk_device_GetDeviceDescriptor,
208   gnuk_device_GetConfigDescriptor,
209   gnuk_device_GetStringDescriptor,
210   0,
211   GNUK_MAX_PACKET_SIZE
212 };
213
214 const DEVICE Device_Table = {
215   EP_NUM,
216   1
217 };
218
219 const USER_STANDARD_REQUESTS User_Standard_Requests = {
220   NOP_Process,                  /* GetConfiguration */ 
221   gnuk_device_SetConfiguration,
222   NOP_Process,                  /* GetInterface */
223   NOP_Process,                  /* SetInterface */
224   NOP_Process,                  /* GetStatus */
225   NOP_Process,                  /* ClearFeature */
226   NOP_Process,                  /* SetEndPointFeature */
227   NOP_Process,                  /* SetDeviceFeature */
228   gnuk_device_SetDeviceAddress
229 };