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