@@ -206,6 +206,8 @@ int rval, i;
206
206
207
207
int usbhidOpenDevice (usbDevice_t * * device , int vendor , char * vendorName , int product , char * productName , int _usesReportIDs )
208
208
{
209
+ char drivername [2 ];
210
+ int detachrc ;
209
211
struct usb_bus * bus ;
210
212
struct usb_device * dev ;
211
213
usb_dev_handle * handle = NULL ;
@@ -229,6 +231,22 @@ static int didUsbInit = 0;
229
231
fprintf (stderr , "Warning: cannot open USB device: %s\n" , usb_strerror ());
230
232
continue ;
231
233
}
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
+
232
250
if (vendorName == NULL && productName == NULL ){ /* name does not matter */
233
251
break ;
234
252
}
@@ -281,21 +299,40 @@ void usbhidCloseDevice(usbDevice_t *device)
281
299
int usbhidSetReport (usbDevice_t * device , char * buffer , int len )
282
300
{
283
301
int bytesSent , reportId = buffer [0 ];
302
+ int claimrc , releaserc ;
284
303
285
304
if (!usesReportIDs ){
286
305
buffer ++ ; /* skip dummy report ID */
287
306
len -- ;
288
307
}
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
+
289
315
// original hiddata.h
290
316
// 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);
291
317
// modification by todbot, matches roughly what hiddata does
292
318
// change by tod to use USB_RECIP_INTERFACE instead of USB_RECIP_DEVICE
293
319
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 );
294
320
if (bytesSent != len ){
295
321
if (bytesSent < 0 )
322
+ {
296
323
fprintf (stderr , "Error sending message: %s\n" , usb_strerror ());
324
+ }
325
+
326
+ usb_release_interface ((void * )device , 0 );
297
327
return USBOPEN_ERR_IO ;
298
328
}
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
+
299
336
return 0 ;
300
337
}
301
338
@@ -304,24 +341,40 @@ int bytesSent, reportId = buffer[0];
304
341
int usbhidGetReport (usbDevice_t * device , int reportNumber , char * buffer , int * len )
305
342
{
306
343
int bytesReceived , maxLen = * len ;
344
+ int claimrc , releaserc ;
307
345
308
346
if (!usesReportIDs ){
309
347
buffer ++ ; /* make room for dummy report ID */
310
348
maxLen -- ;
311
349
}
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
+
312
357
// original hiddata.h
313
358
//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);
314
359
// change by tod to use USB_RECIP_INTERFACE instead of USB_RECIP_DEVICE
315
360
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 );
316
361
if (bytesReceived < 0 ){
317
362
fprintf (stderr , "Error sending message: %s\n" , usb_strerror ());
363
+ usb_release_interface ((void * )device , 0 );
318
364
return USBOPEN_ERR_IO ;
319
365
}
320
366
* len = bytesReceived ;
321
367
if (!usesReportIDs ){
322
368
buffer [-1 ] = reportNumber ; /* add dummy report ID */
323
369
(* len )++ ;
324
370
}
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
+
325
378
return 0 ;
326
379
}
327
380
0 commit comments