hidapi
hidapi copied to clipboard
Get vendorId & productId from hid_device or path
I maintain a couple of nodejs libraries (such as elgato-stream-deck) which use this library via node-hid.
In those I expose a method which takes in a path to the device and opens it (such as function openStreamDeck(devicePath: string): StreamDeck
), returning a class to interact with the device.
But to do this, I need to check the productId of the hid device to determine the model being opened. In this streamdeck library there are 6 models of compatible device, each with a slightly different protocol.
My current method for this is to do a hid_enumerate before opening the device to find the productId, but this is horribly inefficient.
Ideally there would be a method to get the hid_device_info
for a specific path, or be able to get the productId and vendorId from a hid_device
I might be able to achieve the same with hid_get_manufacturer_string
and hid_get_product_string
, but I suspect that two of the models will report the same name, even though their protocol is completely different.
I can try and implement one of these, but would like to discuss what the api should look like first.
It looks like for windows there is already a hid_device_info
stored inside hid_device
.
macos has the create_device_info_with_usage
function that could be used to create and store a hid_device_info
, and at the same time the hid_get_manufacturer_string
and related methods could be updated to copy off that struct like windows is doing.
linux looks like it will take a bit of work to refactor parts of hid_enumerate
to be reusable, but it doesnt look like there is anything stopping it from being done. As another bonus, get_device_string
could be removed.
libusb also looks like it will need a bit of refactoring to be compatible.
So as windows already has a hid_device_info
stored inside hid_device
, I think it makes sense to replicate this for all backends.
Then one of these methods could be added to access some more of the information it stores:
-
int HID_API_EXPORT HID_API_CALL hid_get_device_ids(hid_device *dev, unsigned short *vendor_id, unsinged short *product_id);
-
struct hid_device_info HID_API_EXPORT HID_API_CALL hid_get_device_info(hid_device *dev);
- or something else?
Thanks for the analysis.
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_get_device_info(hid_device *dev);
I think this would be the way to go - way more flexible in a long term.
libusb also looks like it will need a bit of refactoring to be compatible.
That should be almost trivial. libusb has all the API for it.
linux looks like it will take a bit of work
That I agree. Right now linux/hidraw backend uses udev
to gather all the information about the device, and I believe that long-term that is not a good approach. hidraw
is a kernel API, so we better use kernel API to gather the information on the device, i.e. sysfs
. The most difficulty is the variety of protocols (USB/Bluetooth/I2C/etc.) that needs to be tested with sysfs
, and personally I only have USB HID devices that I can reliebly test.