Hello,
I've come across your project trying to implement something very similar, just in a different language. Your project has been a good reference for me so far, providing me with some basic guidance on how to approach such a project, so thank you for that.
However, when looking at the find_mouse()
function in find_mouse.c
, I've noticed something that I think could be a mistake in how you obtain the value for the interface
field.
Namely, you are using uid->iInterface
.
The interface
parameter is used then in loading_util.c
, where it is passed into the different libusb functions, which each take an "interface number".
According to this document on the HID spec on page 70, iInterface
is described as an "Index of string descriptor".
This would mean that instead of the actual interface number you are using something that would point to a string descriptor.
Now, the USB in a Nutshell Website writes the following on string descriptors:
String descriptors provide human readable information and are optional. If they are not used, any string index fields of descriptors must be set to zero indicating there is no string descriptor available.
This would then presumably explain why your current approach should work most of the time.
The default interface of interest is probably usually zero, why this will work most time, since the string descriptors are rarely used.
However, if the actual interface of interest has a number different from zero or the string descriptor is set, this will result in very much undefined behaviour.
As a fix, one should be able to use the bInterfaceNumber
field. From the HID spec: "Number of Interface". And from the USB in a Nutshell article:
bInterfaceNumber
indicates the index of the interface descriptor. This should be zero based, and incremented once for each new interface descriptor.
Another potential problem might be the use of the altsetting
field instead of the cur_altsetting
, though I am less sure about this. The Kernel Doc on the USB driver API writes the following about altsetting
:
array of interface structures, one for each alternate setting that may be selected. Each one includes a set of endpoint configurations. They will be in no particular order.
and about cur_altsetting
:
the current altsetting.
Note the sentence "They will be in no particular order.", which will mean that your code will just take the first element of the array and will break when there is a USB device which has multiple of these altsetting
s and the one that is currently used is not in the first position. I don't really know what the exact implications would be, but I think a solution would involve either using cur_altsetting
or looping over all elements of altsetting
, finding the desired one and setting it to the cur_altsetting
.
I hope I didn't overlook or misinterpret something, that is just how I understand the code and the spec. I am still relatively new to this kind of stuff. If I've made a mistake somewhere, please feel free to point me towards it and close this issue.