diff --git a/hidapi/hidapi.h b/hidapi/hidapi.h index ab6219c04..fe0d19a21 100644 --- a/hidapi/hidapi.h +++ b/hidapi/hidapi.h @@ -100,6 +100,37 @@ extern "C" { struct hid_device_; typedef struct hid_device_ hid_device; /**< opaque hidapi structure */ + /** @brief HID underlying bus types. + + @ingroup API + */ + typedef enum { + /* Unknown bus type */ + HID_API_BUS_UNKNOWN = 0x00, + + /* USB bus + Specifications: + https://usb.org/hid */ + HID_API_BUS_USB = 0x01, + + /* Bluetooth or Bluetooth LE bus + Specifications: + https://www.bluetooth.com/specifications/specs/human-interface-device-profile-1-1-1/ + https://www.bluetooth.com/specifications/specs/hid-service-1-0/ + https://www.bluetooth.com/specifications/specs/hid-over-gatt-profile-1-0/ */ + HID_API_BUS_BLUETOOTH = 0x02, + + /* I2C bus + Specifications: + https://docs.microsoft.com/previous-versions/windows/hardware/design/dn642101(v=vs.85) */ + HID_API_BUS_I2C = 0x03, + + /* SPI bus + Specifications: + https://www.microsoft.com/download/details.aspx?id=103325 */ + HID_API_BUS_SPI = 0x04, + } hid_bus_type; + /** hidapi info structure */ struct hid_device_info { /** Platform-specific device path */ @@ -135,6 +166,11 @@ extern "C" { /** Pointer to the next device */ struct hid_device_info *next; + + /** Underlying bus type + Since version 0.13.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 13, 0) + */ + hid_bus_type bus_type; }; diff --git a/hidtest/test.c b/hidtest/test.c index 4d7a2c6bc..a3207c4a0 100644 --- a/hidtest/test.c +++ b/hidtest/test.c @@ -60,6 +60,7 @@ void print_device(struct hid_device_info *cur_dev) { printf(" Release: %hx\n", cur_dev->release_number); printf(" Interface: %d\n", cur_dev->interface_number); printf(" Usage (page): 0x%hx (0x%hx)\n", cur_dev->usage, cur_dev->usage_page); + printf(" Bus type: %d\n", cur_dev->bus_type); printf("\n"); } diff --git a/libusb/hid.c b/libusb/hid.c index d76db4df9..fade044f0 100644 --- a/libusb/hid.c +++ b/libusb/hid.c @@ -651,6 +651,8 @@ static struct hid_device_info * create_device_info_for_device(libusb_device *dev cur_dev->interface_number = interface_num; + cur_dev->bus_type = HID_API_BUS_USB; + cur_dev->path = make_path(device, config_number, interface_num); if (!handle) { diff --git a/linux/hid.c b/linux/hid.c index 9b2ceca87..35d936f5c 100644 --- a/linux/hid.c +++ b/linux/hid.c @@ -672,11 +672,11 @@ static struct hid_device_info * create_device_info_for_device(struct udev_device break; } - /* Manufacturer and Product strings */ cur_dev->manufacturer_string = copy_udev_string(usb_dev, "manufacturer"); cur_dev->product_string = copy_udev_string(usb_dev, "product"); - /* Release Number */ + cur_dev->bus_type = HID_API_BUS_USB; + str = udev_device_get_sysattr_value(usb_dev, "bcdDevice"); cur_dev->release_number = (str)? strtol(str, NULL, 16): 0x0; @@ -693,11 +693,18 @@ static struct hid_device_info * create_device_info_for_device(struct udev_device break; case BUS_BLUETOOTH: + cur_dev->manufacturer_string = wcsdup(L""); + cur_dev->product_string = utf8_to_wchar_t(product_name_utf8); + + cur_dev->bus_type = HID_API_BUS_BLUETOOTH; + + break; case BUS_I2C: - /* Manufacturer and Product strings */ cur_dev->manufacturer_string = wcsdup(L""); cur_dev->product_string = utf8_to_wchar_t(product_name_utf8); + cur_dev->bus_type = HID_API_BUS_I2C; + break; default: @@ -745,6 +752,7 @@ static struct hid_device_info * create_device_info_for_device(struct udev_device cur_dev->product_string = prev_dev->product_string? wcsdup(prev_dev->product_string): NULL; cur_dev->usage_page = page; cur_dev->usage = usage; + cur_dev->bus_type = prev_dev->bus_type; } } diff --git a/mac/hid.c b/mac/hid.c index 678c7bded..20d44f41f 100644 --- a/mac/hid.c +++ b/mac/hid.c @@ -378,6 +378,7 @@ static struct hid_device_info *create_device_info_with_usage(IOHIDDeviceRef dev, unsigned short dev_pid; int BUF_LEN = 256; wchar_t buf[BUF_LEN]; + CFTypeRef transport_prop; struct hid_device_info *cur_dev; io_object_t iokit_dev; @@ -456,6 +457,22 @@ static struct hid_device_info *create_device_info_with_usage(IOHIDDeviceRef dev, cur_dev->interface_number = -1; } + /* Bus Type */ + transport_prop = IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDTransportKey)); + + if (transport_prop != NULL && CFGetTypeID(transport_prop) == CFStringGetTypeID()) { + if (CFStringCompare((CFStringRef)transport_prop, CFSTR(kIOHIDTransportUSBValue), 0) == kCFCompareEqualTo) { + cur_dev->bus_type = HID_API_BUS_USB; + /* Match "Bluetooth", "BluetoothLowEnergy" and "Bluetooth Low Energy" strings */ + } else if (CFStringHasPrefix((CFStringRef)transport_prop, CFSTR(kIOHIDTransportBluetoothValue))) { + cur_dev->bus_type = HID_API_BUS_BLUETOOTH; + } else if (CFStringCompare((CFStringRef)transport_prop, CFSTR(kIOHIDTransportI2CValue), 0) == kCFCompareEqualTo) { + cur_dev->bus_type = HID_API_BUS_I2C; + } else if (CFStringCompare((CFStringRef)transport_prop, CFSTR(kIOHIDTransportSPIValue), 0) == kCFCompareEqualTo) { + cur_dev->bus_type = HID_API_BUS_SPI; + } + } + return cur_dev; } diff --git a/windows/hid.c b/windows/hid.c index dbde2fa0f..376927667 100644 --- a/windows/hid.c +++ b/windows/hid.c @@ -510,12 +510,43 @@ static void hid_internal_get_info(const wchar_t* interface_path, struct hid_devi /* Normalize to upper case */ for (wchar_t* p = compatible_id; *p; ++p) *p = towupper(*p); + /* USB devices + https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-support + https://docs.microsoft.com/windows-hardware/drivers/install/standard-usb-identifiers */ + if (wcsstr(compatible_id, L"USB") != NULL) { + dev->bus_type = HID_API_BUS_USB; + break; + } + + /* Bluetooth devices + https://docs.microsoft.com/windows-hardware/drivers/bluetooth/installing-a-bluetooth-device */ + if (wcsstr(compatible_id, L"BTHENUM") != NULL) { + dev->bus_type = HID_API_BUS_BLUETOOTH; + break; + } + /* Bluetooth LE devices */ if (wcsstr(compatible_id, L"BTHLEDEVICE") != NULL) { /* HidD_GetProductString/HidD_GetManufacturerString/HidD_GetSerialNumberString is not working for BLE HID devices Request this info via dev node properties instead. https://docs.microsoft.com/answers/questions/401236/hidd-getproductstring-with-ble-hid-device.html */ hid_internal_get_ble_info(dev, dev_node); + + dev->bus_type = HID_API_BUS_BLUETOOTH; + break; + } + + /* I2C devices + https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-support-and-power-management */ + if (wcsstr(compatible_id, L"PNP0C50") != NULL) { + dev->bus_type = HID_API_BUS_I2C; + break; + } + + /* SPI devices + https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-for-spi */ + if (wcsstr(compatible_id, L"PNP0C51") != NULL) { + dev->bus_type = HID_API_BUS_SPI; break; } }