-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathusbhelper.c
129 lines (112 loc) · 4.28 KB
/
usbhelper.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
* USBHELPER.C
* based on vusbdevice.c
*
* This is version 20150808T1200ZSB
*
* Stephan Baerwolf ([email protected]), Schwansee 2015
* for http://matrixstorm.com/avr/tinyusbboard/
* (please contact me at least before commercial use)
*/
#define __USBHELPER_C_e25922918d5d40bc99895958f02024b4 1
#include "usbhelper.h"
static long initialize_count = 0;
int usbhelper_initialize(void) {
if (initialize_count==0L) {
usb_init();
}
initialize_count++;
return 0;
}
int usbhelper_finalize(void) {
if (initialize_count>0L) {
initialize_count--;
} else return USB_ERROR_NOINIT;
return 0;
}
int usbGetStringAscii(usb_dev_handle *dev, int index, int langid, char *buf, size_t buflen) {
char buffer[256];
int rval, i;
if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, langid, buffer, sizeof(buffer), 1000)) < 0)
return rval;
if(buffer[1] != USB_DT_STRING)
return 0;
if((unsigned char)buffer[0] < rval)
rval = (unsigned char)buffer[0];
rval /= 2;
/* lossy conversion to ISO Latin1 */
for(i=1;i<rval;i++){
if(i > buflen) /* destination buffer overflow */
break;
buf[i-1] = buffer[2 * i];
if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
buf[i-1] = '?';
}
buf[i-1] = 0;
return i-1;
}
int usbScanDevice(usb_dev_handle **device, const uint32_t busID, const uint8_t deviceID, const uint16_t idvendor, const uint16_t idproduct, usbhelper_devicecallback_t mapfunc, void* userparameter) {
struct usb_bus *bus;
struct usb_device *dev;
usb_dev_handle *handle = NULL;
int result = 0;
static int didUsbInit = 0;
if (!mapfunc) return result;
usb_find_busses();
usb_find_devices();
for (bus=usb_get_busses(); bus; bus=bus->next) {
for (dev=bus->devices; dev; dev=dev->next) {
if (((bus->location==busID) || (busID>=(uint32_t)0xffffffff)) && ((dev->devnum==deviceID) || (deviceID>=(uint8_t)0xff))) {
if ((dev->descriptor.idVendor == idvendor) && (dev->descriptor.idProduct == idproduct)) {
handle = usb_open(dev); /* we need to open the device in order to query strings */
if (handle) {
char vendorstr[256], productstr[256], serialstr[256];
int vendorlen, productlen, seriallen;
vendorlen = usbGetStringAscii(handle, dev->descriptor.iManufacturer, 0x0409, vendorstr, sizeof(vendorstr));
if (vendorlen>0) {
productlen = usbGetStringAscii(handle, dev->descriptor.iProduct, 0x0409, productstr, sizeof(productstr));
if (productlen>0) {
seriallen = usbGetStringAscii(handle, dev->descriptor.iSerialNumber, 0x0409, serialstr, sizeof(serialstr));
if (seriallen==0) serialstr[0]=0;
if (seriallen>=0) {
result=mapfunc(bus, dev, handle, dev->descriptor.idVendor, dev->descriptor.idProduct, vendorstr, productstr, serialstr, userparameter);
}
}
}
if (result<0) {
usb_close(handle);
handle=NULL;
}
if (result) {
*device = handle;
return result;
}
} /* end: valid handle */
} /* vendor and product ok */
} /* right bus and device location */
}
}
return result;
}
struct __usbOpenDeviceMAPdata {
const char *vendorName;
const char *productName;
const char *serial;
};
static int __usbOpenDeviceMAP(const struct usb_bus *bus, const struct usb_device *dev, const usb_dev_handle *handle, const uint16_t vendor, const uint16_t product, const char *vendorName, const char *productName, const char *serial, void* userparameter) {
struct __usbOpenDeviceMAPdata *data=userparameter;
if (strcmp(data->vendorName, vendorName) == 0)
if (strcmp(data->productName, productName) == 0)
if ((strlen(data->serial)==0) || (strcmp(data->serial, serial) == 0)) return 1;
return 0;
}
int usbOpenDevice(usb_dev_handle **device, const uint32_t busID, const uint8_t deviceID, const uint16_t idvendor, const uint16_t idproduct, const char *vendorName, const char *productName, const char *serial) {
struct __usbOpenDeviceMAPdata params;
params.vendorName=vendorName;
params.productName=productName;
params.serial=serial;
if (usbScanDevice(device, busID, deviceID, idvendor, idproduct, __usbOpenDeviceMAP, ¶ms)>0) {
return 0;
}
return USB_ERROR_NOTFOUND;
}