Skip to content

Commit

Permalink
libusb backend: stabilize device path
Browse files Browse the repository at this point in the history
format the path like the linux kernel does:
<busnum>-<port[.port]>…:<config num>.<interface num>

See also #117

Closes: #117
  • Loading branch information
bearsh committed Jun 25, 2021
1 parent 6fcb0bb commit d03f799
Showing 1 changed file with 24 additions and 10 deletions.
34 changes: 24 additions & 10 deletions libusb/hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,15 +484,29 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
return str;
}

static char *make_path(libusb_device *dev, int interface_number)
static char *make_path(libusb_device *dev, int interface_number, int config_number)
{
char str[64];
snprintf(str, sizeof(str), "%04x:%04x:%02x",
libusb_get_bus_number(dev),
libusb_get_device_address(dev),
interface_number);
str[sizeof(str)-1] = '\0';

char str[64]; /* max length "000-000.000.000.000.000.000.000:000.000" */
/* Note that USB3 port count limit is 7; use 8 here for alignment */
uint8_t port_numbers[8] = {0, 0, 0, 0, 0, 0, 0, 0};
int num_ports = libusb_get_port_numbers(dev, port_numbers, 8);

if (num_ports > 0) {
int n = snprintf(str, sizeof("000-000"), "%u-%u", libusb_get_bus_number(dev), port_numbers[0]);
for (uint8_t i = 1; i < num_ports; i++) {
n += snprintf(&str[n], sizeof(".000"), ".%u", port_numbers[i]);
}
n += snprintf(&str[n], sizeof(":000.000"), ":%u.%u", (uint8_t)config_number, (uint8_t)interface_number);
str[n] = '\0';
} else {
/* USB3.0 specs limit number of ports to 7 and buffer size here is 8 */
if (num_ports == LIBUSB_ERROR_OVERFLOW) {
LOG("make_path() failed. buffer overflow error\n");
} else {
LOG("make_path() failed. unknown error\n");
}
str[0] = '\0';
}
return strdup(str);
}

Expand Down Expand Up @@ -590,7 +604,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,

/* Fill out the record */
cur_dev->next = NULL;
cur_dev->path = make_path(dev, interface_num);
cur_dev->path = make_path(dev, interface_num, conf_desc->bConfigurationValue);

res = libusb_open(dev, &handle);

Expand Down Expand Up @@ -926,7 +940,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path)
const struct libusb_interface_descriptor *intf_desc;
intf_desc = &intf->altsetting[k];
if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) {
char *dev_path = make_path(usb_dev, intf_desc->bInterfaceNumber);
char *dev_path = make_path(usb_dev, intf_desc->bInterfaceNumber, conf_desc->bConfigurationValue);
if (!strcmp(dev_path, path)) {
/* Matched Paths. Open this device */

Expand Down

0 comments on commit d03f799

Please sign in to comment.