From 93976bb27667413f767f2d371512603a0ee94ef2 Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Fri, 21 Jun 2019 12:33:41 -0500 Subject: [PATCH] prober: Add ability to get string descriptors. Right now we can only use libusb to get this info. --- src/xrt/include/xrt/xrt_prober.h | 31 ++++++++++++++++ src/xrt/state_trackers/prober/p_libusb.c | 47 ++++++++++++++++++++++++ src/xrt/state_trackers/prober/p_prober.c | 30 +++++++++++++++ src/xrt/state_trackers/prober/p_prober.h | 7 ++++ 4 files changed, 115 insertions(+) diff --git a/src/xrt/include/xrt/xrt_prober.h b/src/xrt/include/xrt/xrt_prober.h index 6ecfe4a8c..dbde6ee20 100644 --- a/src/xrt/include/xrt/xrt_prober.h +++ b/src/xrt/include/xrt/xrt_prober.h @@ -94,6 +94,16 @@ enum xrt_bus_type XRT_BUS_TYPE_BLUETOOTH, }; +/*! + * String descriptor types + */ +enum xrt_prober_string +{ + XRT_PROBER_STRING_MANUFACTURER, + XRT_PROBER_STRING_PRODUCT, + XRT_PROBER_STRING_SERIAL_NUMBER, +}; + /*! * A probed device, may or may not be opened. * @@ -137,6 +147,11 @@ struct xrt_prober int (*list_video_devices)(struct xrt_prober *xp, xrt_prober_list_video_cb cb, void *ptr); + int (*get_string_descriptor)(struct xrt_prober *xp, + struct xrt_prober_device *xpdev, + enum xrt_prober_string which_string, + unsigned char *buffer, + int length); void (*destroy)(struct xrt_prober **xp_ptr); }; @@ -189,6 +204,22 @@ xrt_prober_open_hid_interface(struct xrt_prober *xp, return xp->open_hid_interface(xp, xpdev, interface, out_hid_dev); } +/*! + * Helper function for @ref xrt_prober::get_string_descriptor. + * + * @ingroup xrt_iface + */ +XRT_MAYBE_UNUSED static inline int +xrt_prober_get_string_descriptor(struct xrt_prober *xp, + struct xrt_prober_device *xpdev, + enum xrt_prober_string which_string, + unsigned char *buffer, + int length) +{ + return xp->get_string_descriptor(xp, xpdev, which_string, buffer, + length); +} + /*! * Helper function for @ref xrt_prober::list_video_devices. * diff --git a/src/xrt/state_trackers/prober/p_libusb.c b/src/xrt/state_trackers/prober/p_libusb.c index 7e9541170..d09a4a4ab 100644 --- a/src/xrt/state_trackers/prober/p_libusb.c +++ b/src/xrt/state_trackers/prober/p_libusb.c @@ -94,3 +94,50 @@ p_libusb_probe(struct prober *p) return 0; } + +int +p_libusb_get_string_descriptor(struct prober *p, + struct prober_device *pdev, + enum xrt_prober_string which_string, + unsigned char *buffer, + int length) +{ + + struct libusb_device_descriptor desc; + + libusb_device *usb_dev = pdev->usb.dev; + int result = libusb_get_device_descriptor(usb_dev, &desc); + if (result < 0) { + P_ERROR(p, "libusb_get_device_descriptor failed!"); + return result; + } + uint8_t which = 0; + switch (which_string) { + case XRT_PROBER_STRING_MANUFACTURER: which = desc.iManufacturer; break; + case XRT_PROBER_STRING_PRODUCT: which = desc.iProduct; break; + case XRT_PROBER_STRING_SERIAL_NUMBER: which = desc.iSerialNumber; break; + default: break; + } + P_SPEW(p, + "libusb\n" + "\t\tptr: %p\n" + "\t\trequested string index: %i", + (void *)pdev, which); + if (which == 0) { + // Not available? + return 0; + } + libusb_device_handle *dev_handle = NULL; + result = libusb_open(usb_dev, &dev_handle); + if (result < 0) { + P_ERROR(p, "libusb_open failed!"); + return result; + } + int string_length = libusb_get_string_descriptor_ascii( + dev_handle, which, buffer, length); + if (string_length < 0) { + P_ERROR(p, "libusb_get_string_descriptor_ascii failed!"); + } + libusb_close(dev_handle); + return string_length; +} diff --git a/src/xrt/state_trackers/prober/p_prober.c b/src/xrt/state_trackers/prober/p_prober.c index a4a6fba00..4473fcf22 100644 --- a/src/xrt/state_trackers/prober/p_prober.c +++ b/src/xrt/state_trackers/prober/p_prober.c @@ -57,6 +57,12 @@ static int list_video_devices(struct xrt_prober* xp, xrt_prober_list_video_cb cb, void* ptr); +static int +get_string_descriptor(struct xrt_prober* xp, + struct xrt_prober_device* xpdev, + enum xrt_prober_string which_string, + unsigned char* buffer, + int length); static void destroy(struct xrt_prober** xp); @@ -229,6 +235,7 @@ initialize(struct prober* p, struct xrt_prober_entry_lists* lists) p->base.select = select_device; p->base.open_hid_interface = open_hid_interface; p->base.list_video_devices = list_video_devices; + p->base.get_string_descriptor = get_string_descriptor; p->base.destroy = destroy; p->lists = lists; p->print_spew = debug_get_bool_option_prober_spew(); @@ -582,6 +589,29 @@ list_video_devices(struct xrt_prober* xp, return 0; } +static int +get_string_descriptor(struct xrt_prober* xp, + struct xrt_prober_device* xpdev, + enum xrt_prober_string which_string, + unsigned char* buffer, + int length) +{ + struct prober* p = (struct prober*)xp; + struct prober_device* pdev = (struct prober_device*)xpdev; + int ret; +#ifdef XRT_HAVE_LIBUSB + if (pdev->usb.dev != NULL) { + ret = p_libusb_get_string_descriptor(p, pdev, which_string, + buffer, length); + if (ret >= 0) { + return ret; + } + } +#endif + //! @todo add more backends + //! @todo make this unicode (utf-16)? utf-8 would be better... + return 0; +} static void destroy(struct xrt_prober** xp) { diff --git a/src/xrt/state_trackers/prober/p_prober.h b/src/xrt/state_trackers/prober/p_prober.h index d5faed82b..a11bbe6cd 100644 --- a/src/xrt/state_trackers/prober/p_prober.h +++ b/src/xrt/state_trackers/prober/p_prober.h @@ -201,6 +201,13 @@ p_libusb_teardown(struct prober* p); int p_libusb_probe(struct prober* p); + +int +p_libusb_get_string_descriptor(struct prober* p, + struct prober_device* pdev, + enum xrt_prober_string which_string, + unsigned char* buffer, + int length); #endif #ifdef XRT_HAVE_LIBUVC