diff --git a/src/xrt/state_trackers/prober/CMakeLists.txt b/src/xrt/state_trackers/prober/CMakeLists.txt index 38fa3981c..56db9ffc1 100644 --- a/src/xrt/state_trackers/prober/CMakeLists.txt +++ b/src/xrt/state_trackers/prober/CMakeLists.txt @@ -37,13 +37,22 @@ if(BUILD_WITH_LIBUSB) ) endif() +# Add libuvc +if(BUILD_WITH_LIBUVC) + list(APPEND PROBER_SOURCE_FILES + p_libuvc.c + ) + list(APPEND PROBER_INCLUDES + ${LIBUVC_INCLUDES} + ) +endif() + # Use OBJECT to not create a archive, since it just gets in the way. add_library(st_prober OBJECT ${PROBER_SOURCE_FILES}) target_include_directories(st_prober PRIVATE ${PROBER_INCLUDES} - ${LIBUVC_INCLUDES} ) set_property(TARGET st_prober PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/src/xrt/state_trackers/prober/p_libuvc.c b/src/xrt/state_trackers/prober/p_libuvc.c new file mode 100644 index 000000000..70030e9e6 --- /dev/null +++ b/src/xrt/state_trackers/prober/p_libuvc.c @@ -0,0 +1,94 @@ +// Copyright 2019, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Prober code interfacing to libuvc. + * @author Jakob Bornecrantz + * @ingroup st_prober + */ + +#include "util/u_debug.h" +#include "util/u_misc.h" +#include "p_prober.h" + +#include +#include + + +int +p_libuvc_init(struct prober* p) +{ + return uvc_init(&p->uvc.ctx, p->usb.ctx); +} + +void +p_libuvc_teardown(struct prober* p) +{ + // Free all libuvc resources. + if (p->uvc.list != NULL) { + uvc_free_device_list(p->uvc.list, 1); + p->uvc.list = NULL; + } + + if (p->uvc.ctx != NULL) { + uvc_exit(p->uvc.ctx); + p->uvc.ctx = NULL; + } +} + +int +p_libuvc_probe(struct prober* p) +{ + int ret; + + // Free old list first. + if (p->uvc.list != NULL) { + uvc_free_device_list(p->uvc.list, 1); + p->uvc.list = NULL; + } + + ret = uvc_get_device_list(p->uvc.ctx, &p->uvc.list); + if (ret < 0) { + P_ERROR(p, "\tFailed to enumerate uvc devices\n"); + return -1; + } + + // Count the number of UVC devices. + while (p->uvc.list != NULL && p->uvc.list[p->uvc.count] != NULL) { + p->uvc.count++; + } + + for (ssize_t k = 0; k < p->uvc.count; k++) { + uvc_device_t* device = p->uvc.list[k]; + struct uvc_device_descriptor* desc; + struct prober_device* pdev = NULL; + + uvc_get_device_descriptor(device, &desc); + uint8_t bus = uvc_get_bus_number(device); + uint8_t addr = uvc_get_device_address(device); + uint16_t vendor = desc->idVendor; + uint16_t product = desc->idProduct; + uvc_free_device_descriptor(desc); + + ret = p_dev_get_usb_dev(p, bus, addr, vendor, product, &pdev); + + P_SPEW(p, + "libuvc\n" + "\t\tptr: %p (%i)\n" + "\t\tvendor_id: %04x\n" + "\t\tproduct_id: %04x\n" + "\t\tbus: %i\n" + "\t\taddr: %i", + (void*)pdev, ret, vendor, product, bus, addr); + + if (ret != 0) { + P_ERROR(p, "p_dev_get_usb_device failed!"); + continue; + } + + // Attach the libuvc device to it. + pdev->uvc.dev = p->uvc.list[k]; + } + + return 0; +} diff --git a/src/xrt/state_trackers/prober/p_prober.c b/src/xrt/state_trackers/prober/p_prober.c index af7a0d6d2..bc01aef1c 100644 --- a/src/xrt/state_trackers/prober/p_prober.c +++ b/src/xrt/state_trackers/prober/p_prober.c @@ -245,7 +245,7 @@ initialize(struct prober* p, struct xrt_prober_entry_lists* lists) #endif #ifdef XRT_HAVE_LIBUVC - ret = uvc_init(&p->uvc.ctx, p->usb.ctx); + ret = p_libuvc_init(p); if (ret != 0) { teardown(p); return -1; @@ -306,16 +306,7 @@ teardown(struct prober* p) teardown_devices(p); #ifdef XRT_HAVE_LIBUVC - // Free all libuvc resources. - if (p->uvc.list != NULL) { - uvc_free_device_list(p->uvc.list, 1); - p->uvc.list = NULL; - } - - if (p->uvc.ctx != NULL) { - uvc_exit(p->uvc.ctx); - p->uvc.ctx = NULL; - } + p_libuvc_teardown(p); #endif #ifdef XRT_HAVE_LIBUSB @@ -323,64 +314,6 @@ teardown(struct prober* p) #endif } -static int -p_libuvc_probe(struct prober* p) -{ -#ifdef XRT_HAVE_LIBUVC - int ret; - - // Free old list first. - if (p->uvc.list != NULL) { - uvc_free_device_list(p->uvc.list, 1); - p->uvc.list = NULL; - } - - ret = uvc_get_device_list(p->uvc.ctx, &p->uvc.list); - if (ret < 0) { - P_ERROR(p, "\tFailed to enumerate uvc devices\n"); - return -1; - } - - // Count the number of UVC devices. - while (p->uvc.list != NULL && p->uvc.list[p->uvc.count] != NULL) { - p->uvc.count++; - } - - for (ssize_t k = 0; k < p->uvc.count; k++) { - uvc_device_t* device = p->uvc.list[k]; - struct uvc_device_descriptor* desc; - struct prober_device* pdev = NULL; - - uvc_get_device_descriptor(device, &desc); - uint8_t bus = uvc_get_bus_number(device); - uint8_t addr = uvc_get_device_address(device); - uint16_t vendor = desc->idVendor; - uint16_t product = desc->idProduct; - uvc_free_device_descriptor(desc); - - ret = p_dev_get_usb_dev(p, bus, addr, vendor, product, &pdev); - - P_SPEW(p, - "libuvc\n" - "\t\tptr: %p (%i)\n" - "\t\tvendor_id: %04x\n" - "\t\tproduct_id: %04x\n" - "\t\tbus: %i\n" - "\t\taddr: %i", - (void*)pdev, ret, vendor, product, bus, addr); - - if (ret != 0) { - P_ERROR(p, "p_dev_get_usb_device failed!"); - continue; - } - - // Attach the libuvc device to it. - pdev->uvc.dev = p->uvc.list[k]; - } -#endif - return 0; -} - /* * @@ -405,11 +338,13 @@ probe(struct xrt_prober* xp) } #endif +#ifdef XRT_HAVE_LIBUVC ret = p_libuvc_probe(p); if (ret != 0) { P_ERROR(p, "Failed to enumerate libuvc devices\n"); return -1; } +#endif #ifdef XRT_HAVE_LIBUDEV ret = p_udev_probe(p); diff --git a/src/xrt/state_trackers/prober/p_prober.h b/src/xrt/state_trackers/prober/p_prober.h index 4ee671c1a..32dde56ef 100644 --- a/src/xrt/state_trackers/prober/p_prober.h +++ b/src/xrt/state_trackers/prober/p_prober.h @@ -188,6 +188,17 @@ int p_libusb_probe(struct prober* p); #endif +#ifdef XRT_HAVE_LIBUVC +int +p_libuvc_init(struct prober* p); + +void +p_libuvc_teardown(struct prober* p); + +int +p_libuvc_probe(struct prober* p); +#endif + #ifdef XRT_HAVE_LIBUDEV int p_udev_probe(struct prober* p);