/[pcsclite]/trunk/Drivers/ccid/src/ccid_usb.c
ViewVC logotype

Contents of /trunk/Drivers/ccid/src/ccid_usb.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 525 - (show annotations) (download)
Tue Oct 28 18:18:11 2003 UTC (9 years, 7 months ago) by rousseau
File MIME type: text/plain
File size: 11096 byte(s)
correctly use the device name in a debug message instead of a not yet initialised field.
1 /*
2 ccid_usb.c: USB access routines using the libusb library
3 Copyright (C) 2003 Ludovic Rousseau
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 /*
21 * $Id$
22 */
23
24 #define __CCID_USB__
25
26 #include <stdio.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <usb.h>
30
31 #include "pcscdefines.h"
32 #include "config.h"
33 #include "debug.h"
34 #include "utils.h"
35 #include "parser.h"
36 #include "ccid.h"
37
38
39 #define USB_TIMEOUT (60 * 1000) /* 1 minute timeout */
40
41 #define BUS_DEVICE_STRSIZE 32
42
43 typedef struct
44 {
45 usb_dev_handle *handle;
46 struct usb_device *dev;
47
48 /*
49 * Used to store device name string %s/%s like:
50 * 001/002 (Linux)
51 * /dev/usb0//dev/ (FreeBSD)
52 * /dev/usb0//dev/ugen0 (OpenBSD)
53 */
54 char device_name[BUS_DEVICE_STRSIZE];
55
56 /*
57 * Endpoints
58 */
59 int bulk_in;
60 int bulk_out;
61
62 /*
63 * CCID infos common to USB and serial
64 */
65 _ccid_descriptor ccid;
66
67 } _usbDevice;
68
69 /* The _usbDevice structure must be defined before including ccid_usb.h */
70 #include "ccid_usb.h"
71
72 static _usbDevice usbDevice[PCSCLITE_MAX_READERS] = {
73 [ 0 ... (PCSCLITE_MAX_READERS-1) ] = { NULL, NULL, "", 0, 0 }
74 };
75
76 #define PCSCLITE_MANUKEY_NAME "ifdVendorID"
77 #define PCSCLITE_PRODKEY_NAME "ifdProductID"
78 #define PCSCLITE_NAMEKEY_NAME "ifdFriendlyName"
79
80 /*****************************************************************************
81 *
82 * OpenUSB
83 *
84 ****************************************************************************/
85 status_t OpenUSB(int lun, int Channel)
86 {
87 static struct usb_bus *busses = NULL;
88 int reader = LunToReaderIndex(lun);
89 int alias = 0;
90 struct usb_bus *bus;
91 struct usb_dev_handle *dev_handle;
92 char keyValue[TOKEN_MAX_VALUE_SIZE];
93 int vendorID, productID;
94 char infofile[FILENAME_MAX];
95
96 DEBUG_COMM3("OpenUSB: Lun: %X, Channel: %X", lun, Channel);
97
98 if (busses == NULL)
99 {
100 usb_init();
101 }
102
103 usb_find_busses();
104 usb_find_devices();
105
106 busses = usb_get_busses();
107
108 if (busses == NULL)
109 {
110 DEBUG_CRITICAL("No USB busses found");
111 return STATUS_UNSUCCESSFUL;
112 }
113
114 /* is the lun already used? */
115 if (usbDevice[reader].handle != NULL)
116 {
117 DEBUG_CRITICAL2("USB driver with lun %X already in use", lun);
118 return STATUS_UNSUCCESSFUL;
119 }
120
121 /* Info.plist full patch filename */
122 snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",
123 PCSCLITE_HP_DROPDIR, BUNDLE);
124
125 /* general driver info */
126 if (!LTPBundleFindValueWithKey(infofile, "ifdManufacturerString", keyValue, 0))
127 DEBUG_CRITICAL2("Manufacturer: %s", keyValue);
128 else
129 {
130 DEBUG_CRITICAL2("LTPBundleFindValueWithKey error. Can't find %s?",
131 infofile);
132 return STATUS_UNSUCCESSFUL;
133 }
134 if (!LTPBundleFindValueWithKey(infofile, "ifdProductString", keyValue, 0))
135 DEBUG_CRITICAL2("ProductString: %s", keyValue);
136 else
137 return STATUS_UNSUCCESSFUL;
138 if (!LTPBundleFindValueWithKey(infofile, "Copyright", keyValue, 0))
139 DEBUG_CRITICAL2("Copyright: %s", keyValue);
140 else
141 return STATUS_UNSUCCESSFUL;
142 vendorID = strlen(keyValue);
143 alias = 0x1D;
144 for (; vendorID--;)
145 alias ^= keyValue[vendorID];
146
147 /* for any supported reader */
148 while (LTPBundleFindValueWithKey(infofile, PCSCLITE_MANUKEY_NAME, keyValue, alias) == 0)
149 {
150 vendorID = strtoul(keyValue, 0, 16);
151
152 if (LTPBundleFindValueWithKey(infofile, PCSCLITE_PRODKEY_NAME, keyValue, alias))
153 goto end;
154 productID = strtoul(keyValue, 0, 16);
155
156 if (LTPBundleFindValueWithKey(infofile, PCSCLITE_NAMEKEY_NAME, keyValue, alias))
157 goto end;
158
159 /* on any USB buses */
160 for (bus = busses; bus; bus = bus->next)
161 {
162 struct usb_device *dev;
163
164 /* any device on this bus */
165 for (dev = bus->devices; dev; dev = dev->next)
166 {
167 if (dev->descriptor.idVendor == vendorID
168 && dev->descriptor.idProduct == productID)
169 {
170 int r, already_used;
171 char device_name[BUS_DEVICE_STRSIZE];
172
173 if (snprintf(device_name, BUS_DEVICE_STRSIZE, "%s/%s",
174 bus->dirname, dev->filename) < 0)
175 {
176 DEBUG_CRITICAL2("Device name too long: %s", device_name);
177 return STATUS_UNSUCCESSFUL;
178 }
179
180 /* is it already opened? */
181 already_used = FALSE;
182 for (r=0; r<PCSCLITE_MAX_READERS; r++)
183 {
184 if (usbDevice[r].dev)
185 {
186 DEBUG_COMM3("Checking new device '%s' against old '%s'",
187 device_name, usbDevice[r].device_name);
188 if (strcmp(usbDevice[r].device_name, device_name) == 0)
189 already_used = TRUE;
190 }
191 }
192
193 if (!already_used)
194 {
195 DEBUG_COMM2("Trying to open USB bus/device: %s",
196 device_name);
197
198 dev_handle = usb_open(dev);
199 if (dev_handle)
200 {
201 int interface;
202
203 if (dev->config == NULL)
204 {
205 DEBUG_CRITICAL2("No dev->config found for %s",
206 device_name);
207 return STATUS_UNSUCCESSFUL;
208 }
209
210 interface = dev->config->interface->altsetting->bInterfaceNumber;
211 if (usb_claim_interface(dev_handle, interface) < 0)
212 {
213 DEBUG_CRITICAL3("Can't claim interface %s: %s",
214 device_name, strerror(errno));
215 return STATUS_UNSUCCESSFUL;
216 }
217
218 DEBUG_INFO4("Found Vendor/Product: %04X/%04X (%s)",
219 dev->descriptor.idVendor,
220 dev->descriptor.idProduct, keyValue);
221 DEBUG_INFO2("Using USB bus/device: %s",
222 device_name);
223
224 /* Get Endpoints values*/
225 get_end_points(dev, &usbDevice[reader]);
226
227 /* store device information */
228 usbDevice[reader].handle = dev_handle;
229 usbDevice[reader].dev = dev;
230 strncpy(usbDevice[reader].device_name,
231 device_name, BUS_DEVICE_STRSIZE);
232
233 /* CCID common informations */
234 usbDevice[reader].ccid.bSeq = 1;
235 usbDevice[reader].ccid.readerID =
236 (dev->descriptor.idVendor << 16) +
237 dev->descriptor.idProduct;
238 usbDevice[reader].ccid.dwFeatures = dw2i(dev->config->interface->altsetting->extra, 40);
239 usbDevice[reader].ccid.dwMaxCCIDMessageLength = dw2i(dev->config->interface->altsetting->extra, 44);
240
241 /* Maybe we have a special treatment
242 * for this reader */
243 ccid_open_hack(lun);
244
245 goto end;
246 }
247 else
248 DEBUG_CRITICAL3("Can't usb_open(%s): %s",
249 device_name,
250 strerror(errno));
251 }
252 else
253 {
254 DEBUG_INFO2("USB device %s already in use. Checking next one.",
255 device_name);
256 }
257 }
258 }
259 }
260
261 /* go to next supported reader */
262 alias++;
263 }
264 end:
265 if (usbDevice[reader].handle == NULL)
266 return STATUS_UNSUCCESSFUL;
267
268 return STATUS_SUCCESS;
269 } /* OpenUSB */
270
271
272 /*****************************************************************************
273 *
274 * WriteUSB
275 *
276 ****************************************************************************/
277 status_t WriteUSB(int lun, int length, unsigned char *buffer)
278 {
279 int rv;
280 int reader = LunToReaderIndex(lun);
281 #ifdef DEBUG_LEVEL_COMM
282 char debug_header[] = "-> 121234 ";
283
284 sprintf(debug_header, "-> %06X ", (int)lun);
285 #endif
286
287 #ifdef DEBUG_LEVEL_COMM
288 DEBUG_XXD(debug_header, buffer, length);
289 #endif
290
291 rv = usb_bulk_write(usbDevice[reader].handle, usbDevice[reader].bulk_out, buffer, length, USB_TIMEOUT);
292
293 if (rv < 0)
294 {
295 DEBUG_CRITICAL3("usb_bulk_write(%s): %s",
296 usbDevice[reader].device_name, strerror(errno));
297 return STATUS_UNSUCCESSFUL;
298 }
299
300 return STATUS_SUCCESS;
301 } /* WriteUSB */
302
303
304 /*****************************************************************************
305 *
306 * ReadUSB
307 *
308 ****************************************************************************/
309 status_t ReadUSB(int lun, int * length, unsigned char *buffer)
310 {
311 int rv;
312 int reader = LunToReaderIndex(lun);
313 #ifdef DEBUG_LEVEL_COMM
314 char debug_header[] = "<- 121234 ";
315
316 sprintf(debug_header, "<- %06X ", (int)lun);
317 #endif
318
319
320 rv = usb_bulk_read(usbDevice[reader].handle, usbDevice[reader].bulk_in, buffer, *length, USB_TIMEOUT);
321 *length = rv;
322
323 if (rv < 0)
324 {
325 DEBUG_CRITICAL3("usb_bulk_read(%s): %s",
326 usbDevice[reader].device_name, strerror(errno));
327 return STATUS_UNSUCCESSFUL;
328 }
329
330 #ifdef DEBUG_LEVEL_COMM
331 DEBUG_XXD(debug_header, buffer, *length);
332 #endif
333
334 return STATUS_SUCCESS;
335 } /* ReadUSB */
336
337
338 /*****************************************************************************
339 *
340 * CloseUSB
341 *
342 ****************************************************************************/
343 status_t CloseUSB(int lun)
344 {
345 int reader = LunToReaderIndex(lun);
346
347 /* device not opened */
348 if (usbDevice[reader].dev == NULL)
349 return STATUS_UNSUCCESSFUL;
350
351 DEBUG_COMM2("Closing USB device: %s", usbDevice[reader].device_name);
352
353 usb_release_interface(usbDevice[reader].handle, usbDevice[reader].dev->config->interface->altsetting->bInterfaceNumber);
354
355 usb_close(usbDevice[reader].handle);
356
357 /* mark the resource unused */
358 usbDevice[reader].handle = NULL;
359 usbDevice[reader].dev = NULL;
360 usbDevice[reader].device_name[0] = '\0';
361
362 return STATUS_SUCCESS;
363 } /* CloseUSB */
364
365
366 /*****************************************************************************
367 *
368 * get_ccid_descriptor
369 *
370 ****************************************************************************/
371 _ccid_descriptor *get_ccid_descriptor(int lun)
372 {
373 return &usbDevice[LunToReaderIndex(lun)].ccid;
374 } /* get_ccid_descriptor */
375
376
377 /*****************************************************************************
378 *
379 * get_desc
380 *
381 ****************************************************************************/
382 int get_desc(int channel, char *device_name[], usb_dev_handle **handle, struct
383 usb_device **dev)
384 {
385 if (channel < 0 || channel > PCSCLITE_MAX_READERS)
386 return 1;
387
388 *device_name = usbDevice[channel].device_name;
389 *handle = usbDevice[channel].handle;
390 *dev = usbDevice[channel].dev;
391
392 return 0;
393 } /* get_desc */
394
395 /*****************************************************************************
396 *
397 * get_end_points
398 *
399 ****************************************************************************/
400 int get_end_points(struct usb_device *dev, _usbDevice *usb_device)
401 {
402 int i;
403 int bEndpointAddress;
404
405 /*
406 * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
407 */
408 for (i=0; i<3; i++)
409 {
410 if (dev->config->interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK)
411 continue;
412
413 bEndpointAddress = dev->config->interface->altsetting->endpoint[i].bEndpointAddress;
414
415 if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)
416 usb_device->bulk_in = bEndpointAddress;
417
418 if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)
419 usb_device->bulk_out = bEndpointAddress;
420 }
421
422 return 0;
423 } /* get_end_points */
424

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.5