55
66
u_int16_t wDescriptorLength;
69
/* From usbutils: workaround libusb API goofs: "byte" should never be sign extended;
70
* using "char" is trouble. Likewise, sizes should never be negative.
73
static inline int typesafe_control_msg(usb_dev_handle *dev,
74
unsigned char requesttype, unsigned char request,
76
unsigned char *bytes, unsigned size, int timeout)
78
return usb_control_msg(dev, requesttype, request, value, index,
79
(char *) bytes, (int) size, timeout);
82
#define usb_control_msg typesafe_control_msg
58
84
/* return report descriptor on success, NULL otherwise */
59
int libusb_open(HIDDevice *curDevice, MatchFlags *flg, unsigned char *ReportDesc)
85
/* mode: MODE_OPEN for the 1rst time, MODE_REOPEN to skip getting
86
report descriptor (the longer part) */
87
int libusb_open(HIDDevice *curDevice, MatchFlags *flg, unsigned char *ReportDesc, int mode)
62
struct usb_device *dev;
64
struct my_usb_hid_descriptor *desc;
69
/* libusb base init */
74
for (bus = usb_busses; bus && !found; bus = bus->next) {
75
for (dev = bus->devices; dev && !found; dev = dev->next) {
78
TRACE(2, "Opening new device");
82
/* Check the VendorID for matching flag */
83
if ((flg->VendorID != -1) && (dev->descriptor.idVendor != flg->VendorID))
85
TRACE(2, "Found %x, not matching VendorID", dev->descriptor.idVendor);
90
TRACE(2, "Found %x, matching VendorID", dev->descriptor.idVendor);
91
curDevice->VendorID = dev->descriptor.idVendor;
94
/* Check the ProductID for matching flag */
95
if ((flg->ProductID != -1) && (dev->descriptor.idProduct != flg->ProductID))
97
TRACE(2, "Found %x, not matching ProductID", dev->descriptor.idProduct);
102
TRACE(2, "Found %x, matching ProductID", dev->descriptor.idProduct);
103
curDevice->ProductID = dev->descriptor.idProduct;
106
/* set default interface and claim it */
107
usb_set_altinterface(udev, 0);
108
usb_claim_interface(udev, 0);
110
/* Get HID descriptor */
111
desc = (struct my_usb_hid_descriptor *)buf;
112
/* res = usb_get_descriptor(udev, USB_DT_HID, 0, buf, 0x9); */
113
res = usb_control_msg(udev, USB_ENDPOINT_IN+1, USB_REQ_GET_DESCRIPTOR,
114
(USB_DT_HID << 8) + 0, 0, buf, 0x9, USB_TIMEOUT);
118
TRACE(2, "Not a HID device: Unable to get HID descriptor (%d)", res);
122
TRACE(2, "HID descriptor too short (expected %d, got %d)", 8, res);
125
/* USB_LE16_TO_CPU(desc->wDescriptorLength); */
126
desc->wDescriptorLength = buf[7] + (buf[8]<<8);
127
TRACE(2, "HID descriptor retrieved (Reportlen = %i)",
128
desc->wDescriptorLength);
131
if (dev->descriptor.iManufacturer) {
132
ret = usb_get_string_simple(udev, dev->descriptor.iManufacturer,
133
string, sizeof(string));
136
TRACE(2, "- Manufacturer : %s", string);
137
curDevice->Vendor = strdup(string);
138
curDevice->Name = curDevice->Vendor; /* FIXME: cat Vendor+Prod?! */
141
TRACE(2, "- Unable to fetch manufacturer string");
144
if (dev->descriptor.iProduct) {
145
ret = usb_get_string_simple(udev, dev->descriptor.iProduct,
146
string, sizeof(string));
148
TRACE(2, "- Product : %s", string);
149
curDevice->Product = strdup(string);
152
TRACE(2, "- Unable to fetch product string");
155
if (dev->descriptor.iSerialNumber) {
156
ret = usb_get_string_simple(udev, dev->descriptor.iSerialNumber,
157
string, sizeof(string));
160
TRACE(2, "- Serial Number: %s", string);
161
curDevice->Serial = strdup(string);
164
TRACE(2, "- Unable to fetch serial number string");
166
TRACE(2, "- No serial number string");
169
TRACE(2, " Couldn't retrieve descriptors");
173
/* usb_claim_interface(udev, 0); */
175
/* usb_fetch_and_parse_descriptors(udev); => already done by usb_find_devices() */
177
/* res = usb_get_descriptor(udev, USB_DT_REPORT, 0, bigbuf, desc->wDescriptorLength); */
178
res = usb_control_msg(udev, USB_ENDPOINT_IN+1, USB_REQ_GET_DESCRIPTOR,
179
(USB_DT_REPORT << 8) + 0, 0, ReportDesc,
180
desc->wDescriptorLength, USB_TIMEOUT);
181
if (res < desc->wDescriptorLength) {
183
TRACE(2, "Unable to get Report descriptor (%d)", res);
186
TRACE(2, "Report descriptor too short (expected %d, got %d)",
187
desc->wDescriptorLength, res);
193
TRACE(2, "Report descriptor retrieved (Reportlen = %i)",
194
desc->wDescriptorLength);
195
ret = desc->wDescriptorLength;
198
/* we can break there, and be sure there's a HID device */
204
TRACE(2, "found %i (%i)", found, ret);
90
#if LIBUSB_HAS_DETACH_KRNL_DRV
93
struct my_usb_hid_descriptor *desc;
96
unsigned char buf[20];
98
/* libusb base init */
104
for (bus = usb_busses; bus && !found; bus = bus->next) {
105
for (dev = bus->devices; dev && !found; dev = dev->next) {
108
TRACE(2, "Opening new device (%04X/%04X)",
109
dev->descriptor.idVendor, dev->descriptor.idProduct);
110
udev = usb_open(dev);
113
/* Check the VendorID for matching flag */
114
/* FIXME: temporary method, not generic/flexible enough */
115
if ((dev->descriptor.idVendor == MGE_UPS_SYSTEMS)
116
|| (dev->descriptor.idVendor == APC))
118
TRACE(2, "Found 0x%x", dev->descriptor.idVendor);
119
if (mode == MODE_REOPEN)
122
curDevice->VendorID = dev->descriptor.idVendor;
123
curDevice->iProduct = dev->descriptor.iProduct;
132
#if LIBUSB_HAS_DETACH_KRNL_DRV
133
/* this method requires libusb 0.1.8:
134
* it force device claiming by unbinding
135
* attached driver... From libhid */
136
while ((ret = usb_claim_interface(udev, 0)) != 0 && retries-- > 0) {
138
TRACE(2, "failed to claim USB device, trying %d more time(s)...", retries);
140
TRACE(2, "detaching kernel driver from USB device...");
141
if (usb_detach_kernel_driver_np(udev, 0) < 0) {
142
TRACE(2, "failed to detach kernel driver from USB device...");
145
TRACE(2, "trying again to claim USB device...");
148
if (usb_claim_interface(udev, 0) < 0)
149
TRACE(2, "failed to claim USB device...");
152
/* set default interface and claim it */
153
usb_set_altinterface(udev, 0);
155
if (dev->descriptor.iManufacturer) {
156
ret = usb_get_string_simple(udev, dev->descriptor.iManufacturer,
157
string, sizeof(string));
160
TRACE(2, "- Manufacturer : %s", string);
161
curDevice->Vendor = strdup(string);
162
curDevice->Name = curDevice->Vendor; /* FIXME: cat Vendor+Prod?! */
166
TRACE(2, "- Unable to fetch manufacturer string");
167
curDevice->Vendor = xmalloc(30);
168
snprintf(curDevice->Vendor, 30, "Unknown vendor (0x%04x)",
169
dev->descriptor.idVendor);
173
if (dev->descriptor.iProduct) {
174
ret = usb_get_string_simple(udev, dev->descriptor.iProduct,
175
string, sizeof(string));
177
TRACE(2, "- Product : %s", string);
178
curDevice->Product = strdup(string);
182
TRACE(2, "- Unable to fetch product string");
183
curDevice->Product = xmalloc(30);
184
snprintf(curDevice->Product, 30, "Unknown product (0x%04x)",
185
dev->descriptor.idProduct);
189
if (dev->descriptor.iSerialNumber) {
190
ret = usb_get_string_simple(udev, dev->descriptor.iSerialNumber,
191
string, sizeof(string));
194
TRACE(2, "- Serial Number: %s", string);
195
curDevice->Serial = strdup(string);
198
TRACE(2, "- Unable to fetch serial number string");
200
TRACE(2, "- No serial number string");
202
/* Get HID descriptor */
203
desc = (struct my_usb_hid_descriptor *)buf;
204
/* res = usb_get_descriptor(udev, USB_DT_HID, 0, buf, 0x9); */
205
res = usb_control_msg(udev, USB_ENDPOINT_IN+1, USB_REQ_GET_DESCRIPTOR,
206
(USB_DT_HID << 8) + 0, 0, buf, 0x9, USB_TIMEOUT);
210
TRACE(2, "Unable to get HID descriptor (%s)", usb_strerror());
216
TRACE(2, "HID descriptor too short (expected %d, got %d)", 8, res);
219
/* USB_LE16_TO_CPU(desc->wDescriptorLength); */
220
desc->wDescriptorLength = buf[7] | (buf[8] << 8);
221
TRACE(2, "HID descriptor retrieved (Reportlen = %5u)",
222
desc->wDescriptorLength);
226
TRACE(2, " Couldn't retrieve descriptors");
232
/* Skip getting Report descriptor upon reconnexion */
233
if (mode == MODE_OPEN)
235
/* res = usb_get_descriptor(udev, USB_DT_REPORT, 0, bigbuf, desc->wDescriptorLength); */
236
res = usb_control_msg(udev, USB_ENDPOINT_IN+1, USB_REQ_GET_DESCRIPTOR,
237
(USB_DT_REPORT << 8) + 0, 0, ReportDesc,
238
desc->wDescriptorLength, USB_TIMEOUT);
239
if (res < desc->wDescriptorLength) {
242
TRACE(2, "Unable to get Report descriptor (%d)", res);
246
TRACE(2, "Report descriptor too short (expected %d, got %d)",
247
desc->wDescriptorLength, res);
255
TRACE(2, "Report descriptor retrieved (Reportlen = %i)",
256
desc->wDescriptorLength);
257
ret = desc->wDescriptorLength;
261
/* we can break there, and be sure there's a HID device */
267
TRACE(2, "found %i (%i)", found, ret);
210
273
/* return the report of ID=type in report