Skip to content

Commit 89fae57

Browse files
committed
Merge pull request #186 from windelbouwman/master
Add claim and release to work with libusb
2 parents 38fcb52 + 2a1da8f commit 89fae57

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

commandline/blink1-mini-tool/hiddata.c

+53
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ int rval, i;
206206

207207
int usbhidOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int _usesReportIDs)
208208
{
209+
char drivername[2];
210+
int detachrc;
209211
struct usb_bus *bus;
210212
struct usb_device *dev;
211213
usb_dev_handle *handle = NULL;
@@ -229,6 +231,22 @@ static int didUsbInit = 0;
229231
fprintf(stderr, "Warning: cannot open USB device: %s\n", usb_strerror());
230232
continue;
231233
}
234+
235+
236+
// Likely no need to capture the return code. It will return an error if no driver is
237+
// attached, which is A-OK. Nothing will be detached in that case.
238+
usb_get_driver_np(handle, 0, drivername, sizeof(drivername));
239+
// If we have an empty then nothing is attached, otherwise will be something like "dummy".
240+
if(strlen(drivername) > 0){
241+
// Not doing this causes several issues writing control messages to the interface.
242+
detachrc = usb_detach_kernel_driver_np(handle, 0);
243+
if (detachrc != 0) {
244+
errorCode = USBOPEN_ERR_IO;
245+
fprintf(stderr, "Warning: cannot detach kernel driver from interface 0: %s\n", usb_strerror());
246+
continue;
247+
}
248+
}
249+
232250
if(vendorName == NULL && productName == NULL){ /* name does not matter */
233251
break;
234252
}
@@ -281,21 +299,40 @@ void usbhidCloseDevice(usbDevice_t *device)
281299
int usbhidSetReport(usbDevice_t *device, char *buffer, int len)
282300
{
283301
int bytesSent, reportId = buffer[0];
302+
int claimrc, releaserc;
284303

285304
if(!usesReportIDs){
286305
buffer++; /* skip dummy report ID */
287306
len--;
288307
}
308+
309+
claimrc = usb_claim_interface((void *)device, 0);
310+
if(claimrc != 0){
311+
fprintf(stderr, "Error claiming interface 0 before sending a control message: %s\n", usb_strerror());
312+
return USBOPEN_ERR_IO;
313+
}
314+
289315
// original hiddata.h
290316
// bytesSent = usb_control_msg((void *)device, USB_TYPE_CLASS | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USBRQ_HID_SET_REPORT, USB_HID_REPORT_TYPE_FEATURE << 8 | (reportId & 0xff), 0, buffer, len, 5000);
291317
// modification by todbot, matches roughly what hiddata does
292318
// change by tod to use USB_RECIP_INTERFACE instead of USB_RECIP_DEVICE
293319
bytesSent = usb_control_msg((void *)device, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_ENDPOINT_OUT, USBRQ_HID_SET_REPORT, USB_HID_REPORT_TYPE_FEATURE << 8 | (reportId & 0xff), 0, buffer, len, 5000);
294320
if(bytesSent != len){
295321
if(bytesSent < 0)
322+
{
296323
fprintf(stderr, "Error sending message: %s\n", usb_strerror());
324+
}
325+
326+
usb_release_interface((void *)device, 0);
297327
return USBOPEN_ERR_IO;
298328
}
329+
330+
releaserc = usb_release_interface((void *)device, 0);
331+
if(releaserc != 0){
332+
fprintf(stderr, "Error releasing interface 0 after sending a control message: %s\n", usb_strerror());
333+
return USBOPEN_ERR_IO;
334+
}
335+
299336
return 0;
300337
}
301338

@@ -304,24 +341,40 @@ int bytesSent, reportId = buffer[0];
304341
int usbhidGetReport(usbDevice_t *device, int reportNumber, char *buffer, int *len)
305342
{
306343
int bytesReceived, maxLen = *len;
344+
int claimrc, releaserc;
307345

308346
if(!usesReportIDs){
309347
buffer++; /* make room for dummy report ID */
310348
maxLen--;
311349
}
350+
351+
claimrc = usb_claim_interface((void *)device, 0);
352+
if(claimrc != 0){
353+
fprintf(stderr, "Error claiming interface 0 before sending a control message: %s\n", usb_strerror());
354+
return USBOPEN_ERR_IO;
355+
}
356+
312357
// original hiddata.h
313358
//bytesReceived = usb_control_msg((void *)device, USB_TYPE_CLASS | USB_RECIP_DEVICE | USB_ENDPOINT_IN, USBRQ_HID_GET_REPORT, USB_HID_REPORT_TYPE_FEATURE << 8 | reportNumber, 0, buffer, maxLen, 5000);
314359
// change by tod to use USB_RECIP_INTERFACE instead of USB_RECIP_DEVICE
315360
bytesReceived = usb_control_msg((void *)device, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_ENDPOINT_IN, USBRQ_HID_GET_REPORT, USB_HID_REPORT_TYPE_FEATURE << 8 | reportNumber, 0, buffer, maxLen, 5000);
316361
if(bytesReceived < 0){
317362
fprintf(stderr, "Error sending message: %s\n", usb_strerror());
363+
usb_release_interface((void *)device, 0);
318364
return USBOPEN_ERR_IO;
319365
}
320366
*len = bytesReceived;
321367
if(!usesReportIDs){
322368
buffer[-1] = reportNumber; /* add dummy report ID */
323369
(*len)++;
324370
}
371+
372+
releaserc = usb_release_interface((void *)device, 0);
373+
if(releaserc != 0){
374+
fprintf(stderr, "Error releasing interface 0 after sending a control message: %s\n", usb_strerror());
375+
return USBOPEN_ERR_IO;
376+
}
377+
325378
return 0;
326379
}
327380

0 commit comments

Comments
 (0)