9
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
1 /*
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
2 * In this module we implement the function that locates a USB device
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
3 * by matchspec structure: looking for specific VID/PID, possibly qualified
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
4 * by strings and/or index.
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
5 */
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
6
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
7 #include <stdio.h>
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
8 #include <stdlib.h>
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
9 #include <string.h>
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
10 #include <strings.h>
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
11 #include <usb.h>
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
12 #include "find_dev.h"
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
13 #include "prelim_init.h"
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
14
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
15 static void
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
16 get_string(usb_dev_handle *usbh, int index, char *buf, size_t buflen)
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
17 {
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
18 int rc;
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
19
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
20 rc = usb_get_string_simple(usbh, index, buf, buflen);
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
21 if (rc <= 0) {
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
22 fprintf(stderr, "error: USB string retrieval failed\n");
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
23 exit(1);
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
24 }
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
25 }
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
26
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
27 static int
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
28 is_match(struct usb_device *dev, const struct usbdev_matchspec *match)
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
29 {
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
30 struct usb_device_descriptor *desc = &dev->descriptor;
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
31 usb_dev_handle *usbh;
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
32 char strbuf[1024];
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
33
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
34 if (desc->idVendor != match->usb_vid)
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
35 return 0;
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
36 if (desc->idProduct != match->usb_pid)
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
37 return 0;
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
38 if (match->manuf_string || match->product_string || match->serial) {
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
39 usbh = usb_open(dev);
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
40 if (!usbh) {
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
41 fprintf(stderr, "error: usb_open() failed\n");
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
42 exit(1);
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
43 }
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
44 if (match->manuf_string) {
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
45 get_string(usbh, desc->iManufacturer,
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
46 strbuf, sizeof strbuf);
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
47 if (strncmp(match->manuf_string,
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
48 strbuf, sizeof strbuf)) {
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
49 usb_close(usbh);
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
50 return 0;
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
51 }
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
52 }
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
53 if (match->product_string) {
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
54 get_string(usbh, desc->iProduct, strbuf, sizeof strbuf);
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
55 if (strncmp(match->product_string,
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
56 strbuf, sizeof strbuf)) {
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
57 usb_close(usbh);
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
58 return 0;
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
59 }
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
60 }
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
61 if (match->serial) {
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
62 get_string(usbh, desc->iSerialNumber,
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
63 strbuf, sizeof strbuf);
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
64 if (strncmp(match->serial, strbuf, sizeof strbuf)) {
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
65 usb_close(usbh);
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
66 return 0;
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
67 }
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
68 }
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
69 usb_close(usbh);
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
70 }
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
71 return 1;
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
72 }
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
73
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
74 struct usb_device *
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
75 find_usbdev_by_matchspec(const struct usbdev_matchspec *match)
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
76 {
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
77 struct usb_bus *bus;
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
78 struct usb_device *dev;
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
79 unsigned index = match->index;
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
80
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
81 libusb_prelim_init();
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
82 for (bus = usb_get_busses(); bus; bus = bus->next) {
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
83 for (dev = bus->devices; dev; dev = dev->next) {
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
84 if (is_match(dev, match)) {
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
85 if (!index)
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
86 return dev;
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
87 index--;
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
88 }
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
89 }
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
90 }
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
91 return 0;
|
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
92 }
|