udev-rules: Fix typo
[pub/pl2303-ft232-gpio.git] / usb.c
1
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <errno.h>
6 #include <usb.h>
7
8 static int did_usb_init = 0;
9
10
11 static int usb_get_string_ascii(usb_dev_handle *dev, int index, int langid, char *buf, int buflen)
12 {
13 char buffer[256];
14 int rval, i;
15
16 if((rval = usb_control_msg(dev,
17 USB_ENDPOINT_IN,
18 USB_REQ_GET_DESCRIPTOR,
19 (USB_DT_STRING << 8) + index,
20 langid, buffer, sizeof(buffer),
21 1000)) < 0)
22 return rval;
23 if(buffer[1] != USB_DT_STRING)
24 return 0;
25 if((unsigned char)buffer[0] < rval)
26 rval = (unsigned char)buffer[0];
27 rval /= 2;
28 /* lossy conversion to ISO Latin1 */
29 for(i=1; i<rval; i++) {
30 if(i > buflen) /* destination buffer overflow */
31 break;
32 buf[i-1] = buffer[2 * i];
33 if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
34 buf[i-1] = '?';
35 }
36 buf[i-1] = 0;
37 return i-1;
38 }
39
40
41 int usb_match_string(usb_dev_handle *handle, int index, char* string)
42 {
43 char tmp[256];
44 if (string == NULL)
45 return 1; /* NULL matches anything */
46 usb_get_string_ascii(handle, index, 0x409, tmp, 256);
47 return (strcmp(string,tmp)==0);
48 }
49
50 usb_dev_handle *usb_check_device(struct usb_device *dev,
51 char *vendor_name,
52 char *product_name,
53 char *serial)
54 {
55 usb_dev_handle *handle = usb_open(dev);
56 if(!handle) {
57 fprintf(stderr, "Warning: cannot open USB device: %s\n", usb_strerror());
58 return NULL;
59 }
60 if (
61 usb_match_string(handle, dev->descriptor.iManufacturer, vendor_name) &&
62 usb_match_string(handle, dev->descriptor.iProduct, product_name) &&
63 usb_match_string(handle, dev->descriptor.iSerialNumber, serial)
64 ) {
65 return handle;
66 }
67 usb_close(handle);
68 return NULL;
69
70 }
71
72 usb_dev_handle *nc_usb_open(int vendor, int product, char *vendor_name, char *product_name, char *serial)
73 {
74 struct usb_bus *bus;
75 struct usb_device *dev;
76 usb_dev_handle *handle = NULL;
77
78 if(!did_usb_init++)
79 usb_init();
80
81 usb_find_busses();
82 usb_find_devices();
83
84 for(bus=usb_get_busses(); bus; bus=bus->next) {
85 for(dev=bus->devices; dev; dev=dev->next) {
86 if(dev->descriptor.idVendor == vendor &&
87 dev->descriptor.idProduct == product) {
88 handle = usb_check_device(dev, vendor_name, product_name, serial);
89 if (handle)
90 return handle;
91 }
92 }
93 }
94 return NULL;
95 }
96