OSDN Git Service

77299421465ac5abe33e5c0604ab6987b7114e64
[unagi/old-svn-converted.git] / client / tag / 0.6.2 / usb_device.c
1 /* Name: opendevice.c -> renamed as usb_device.[ch]
2  * Project: V-USB host-side library
3  * Author: Christian Starkjohann
4  * Creation Date: 2008-04-10
5  * Tabsize: 4
6  * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7  * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8  * This Revision: $Id: opendevice.c 740 2009-04-13 18:23:31Z cs $
9  */
10 #include <stdio.h>
11 #include "usb_device.h"
12
13 enum{
14         MATCH_SUCCESS = 1,
15         MATCH_FAILED = 0,
16         MATCH_ABORT = -1
17 };
18 /* private interface: match text and p, return MATCH_SUCCESS, MATCH_FAILED, or MATCH_ABORT. */
19 static int  _shellStyleMatch(char *text, char *p)
20 {
21         int last, matched, reverse;
22
23     for(; *p; text++, p++){
24         if(*text == 0 && *p != '*')
25             return MATCH_ABORT;
26         switch(*p){
27         case '\\':
28             /* Literal match with following character. */
29             p++;
30             /* FALLTHROUGH */
31         default:
32             if(*text != *p)
33                 return MATCH_FAILED;
34             continue;
35         case '?':
36             /* Match anything. */
37             continue;
38         case '*':
39             while(*++p == '*')
40                 /* Consecutive stars act just like one. */
41                 continue;
42             if(*p == 0)
43                 /* Trailing star matches everything. */
44                 return MATCH_SUCCESS;
45             while(*text)
46                 if((matched = _shellStyleMatch(text++, p)) != MATCH_FAILED)
47                     return matched;
48             return MATCH_ABORT;
49         case '[':
50             reverse = p[1] == '^';
51             if(reverse) /* Inverted character class. */
52                 p++;
53             matched = MATCH_FAILED;
54             if(p[1] == ']' || p[1] == '-')
55                 if(*++p == *text)
56                     matched = MATCH_SUCCESS;
57             for(last = *p; *++p && *p != ']'; last = *p)
58                 if (*p == '-' && p[1] != ']' ? *text <= *++p && *text >= last : *text == *p)
59                     matched = MATCH_SUCCESS;
60             if(matched == reverse)
61                 return MATCH_FAILED;
62             continue;
63         }
64     }
65     return *text == 0;
66 }
67
68 /* public interface for shell style matching: returns 0 if fails, 1 if matches */
69 static int shellStyleMatch(char *text, char *pattern)
70 {
71     if(pattern == NULL) /* NULL pattern is synonymous to "*" */
72         return 1;
73     return _shellStyleMatch(text, pattern) == MATCH_SUCCESS;
74 }
75
76 /* ------------------------------------------------------------------------- */
77
78 int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen)
79 {
80 char    buffer[256];
81 int     rval, i;
82
83     if((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use libusb version if it works */
84         return rval;
85     if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, 0x0409, buffer, sizeof(buffer), 5000)) < 0)
86         return rval;
87     if(buffer[1] != USB_DT_STRING){
88         *buf = 0;
89         return 0;
90     }
91     if((unsigned char)buffer[0] < rval)
92         rval = (unsigned char)buffer[0];
93     rval /= 2;
94     /* lossy conversion to ISO Latin1: */
95     for(i=1;i<rval;i++){
96         if(i > buflen)              /* destination buffer overflow */
97             break;
98         buf[i-1] = buffer[2 * i];
99         if(buffer[2 * i + 1] != 0)  /* outside of ISO Latin1 range */
100             buf[i-1] = '?';
101     }
102     buf[i-1] = 0;
103     return i-1;
104 }
105
106 /* ------------------------------------------------------------------------- */
107
108 int usbOpenDevice(
109         usb_dev_handle **device, int vendorID, char *vendorNamePattern,
110         int productID, char *productNamePattern, 
111         char *serialNamePattern, FILE *printMatchingDevicesFp, 
112         FILE *warningsFp
113 )
114 {
115         struct usb_bus *bus;
116         struct usb_device *dev;
117         usb_dev_handle *handle = NULL;
118         int errorCode = USBOPEN_ERR_NOTFOUND;
119
120     usb_init();
121     usb_find_busses();
122     usb_find_devices();
123     for(bus = usb_get_busses(); bus; bus = bus->next){
124         for(dev = bus->devices; dev; dev = dev->next){  /* iterate over all devices on all busses */
125             if((vendorID == 0 || dev->descriptor.idVendor == vendorID)
126                         && (productID == 0 || dev->descriptor.idProduct == productID)){
127                 char    vendor[256], product[256], serial[256];
128                 int     len;
129                 handle = usb_open(dev); /* we need to open the device in order to query strings */
130                 if(!handle){
131                     errorCode = USBOPEN_ERR_ACCESS;
132                     if(warningsFp != NULL)
133                         fprintf(warningsFp, "Warning: cannot open VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror());
134                     continue;
135                 }
136                 /* now check whether the names match: */
137                 len = vendor[0] = 0;
138                 if(dev->descriptor.iManufacturer > 0){
139                     len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, vendor, sizeof(vendor));
140                 }
141                 if(len < 0){
142                     errorCode = USBOPEN_ERR_ACCESS;
143                     if(warningsFp != NULL)
144                         fprintf(warningsFp, "Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror());
145                 }else{
146                     errorCode = USBOPEN_ERR_NOTFOUND;
147                     /* printf("seen device from vendor ->%s<-\n", vendor); */
148                     if(shellStyleMatch(vendor, vendorNamePattern)){
149                         len = product[0] = 0;
150                         if(dev->descriptor.iProduct > 0){
151                             len = usbGetStringAscii(handle, dev->descriptor.iProduct, product, sizeof(product));
152                         }
153                         if(len < 0){
154                             errorCode = USBOPEN_ERR_ACCESS;
155                             if(warningsFp != NULL)
156                                 fprintf(warningsFp, "Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror());
157                         }else{
158                             errorCode = USBOPEN_ERR_NOTFOUND;
159                             /* printf("seen product ->%s<-\n", product); */
160                             if(shellStyleMatch(product, productNamePattern)){
161                                 len = serial[0] = 0;
162                                 if(dev->descriptor.iSerialNumber > 0){
163                                     len = usbGetStringAscii(handle, dev->descriptor.iSerialNumber, serial, sizeof(serial));
164                                 }
165                                 if(len < 0){
166                                     errorCode = USBOPEN_ERR_ACCESS;
167                                     if(warningsFp != NULL)
168                                         fprintf(warningsFp, "Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror());
169                                 }
170                                 if(shellStyleMatch(serial, serialNamePattern)){
171                                     if(printMatchingDevicesFp != NULL){
172                                         if(serial[0] == 0){
173                                             fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product);
174                                         }else{
175                                             fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product, serial);
176                                         }
177                                     }else{
178                                         break;
179                                     }
180                                 }
181                             }
182                         }
183                     }
184                 }
185                 usb_close(handle);
186                 handle = NULL;
187             }
188         }
189         if(handle)  /* we have found a deice */
190             break;
191     }
192     if(handle != NULL){
193         errorCode = 0;
194         *device = handle;
195     }
196     if(printMatchingDevicesFp != NULL)  /* never return an error for listing only */
197         errorCode = 0;
198     return errorCode;
199 }
200