Skip to content

Commit

Permalink
RFC: Add HID bus type in hid_device_info (#308)
Browse files Browse the repository at this point in the history
  • Loading branch information
DJm00n authored Sep 10, 2022
1 parent ceb41e0 commit 0f2cf88
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 3 deletions.
36 changes: 36 additions & 0 deletions hidapi/hidapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
};


Expand Down
1 change: 1 addition & 0 deletions hidtest/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}

Expand Down
2 changes: 2 additions & 0 deletions libusb/hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
14 changes: 11 additions & 3 deletions linux/hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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:
Expand Down Expand Up @@ -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;
}
}

Expand Down
17 changes: 17 additions & 0 deletions mac/hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
31 changes: 31 additions & 0 deletions windows/hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down

0 comments on commit 0f2cf88

Please sign in to comment.