4242int uvc_already_open (uvc_context_t * ctx , struct libusb_device * usb_dev );
4343void uvc_free_devh (uvc_device_handle_t * devh );
4444
45- uvc_error_t uvc_get_device_info (uvc_device_t * dev , uvc_device_info_t * * info );
45+ uvc_error_t uvc_get_device_info (uvc_device_handle_t * devh , uvc_device_info_t * * info );
4646void uvc_free_device_info (uvc_device_info_t * info );
4747
48- uvc_error_t uvc_scan_control (uvc_device_t * dev , uvc_device_info_t * info );
48+ uvc_error_t uvc_scan_control (uvc_device_handle_t * devh , uvc_device_info_t * info );
4949uvc_error_t uvc_parse_vc (uvc_device_t * dev ,
5050 uvc_device_info_t * info ,
5151 const unsigned char * block , size_t block_size );
@@ -263,6 +263,49 @@ uint8_t uvc_get_device_address(uvc_device_t *dev) {
263263 return libusb_get_device_address (dev -> usb_dev );
264264}
265265
266+ static uvc_error_t uvc_open_internal (uvc_device_t * dev , struct libusb_device_handle * usb_devh , uvc_device_handle_t * * devh );
267+
268+ #if LIBUSB_API_VERSION >= 0x01000107
269+ /** @brief Wrap a platform-specific system device handle and obtain a UVC device handle.
270+ * The handle allows you to use libusb to perform I/O on the device in question.
271+ *
272+ * On Linux, the system device handle must be a valid file descriptor opened on the device node.
273+ *
274+ * The system device handle must remain open until uvc_close() is called. The system device handle will not be closed by uvc_close().
275+ * @ingroup device
276+ *
277+ * @param sys_dev the platform-specific system device handle
278+ * @param context UVC context to prepare the device
279+ * @param[out] devh Handle on opened device
280+ * @return Error opening device or SUCCESS
281+ */
282+ uvc_error_t uvc_wrap (
283+ int sys_dev ,
284+ uvc_context_t * context ,
285+ uvc_device_handle_t * * devh ) {
286+ uvc_error_t ret ;
287+ struct libusb_device_handle * usb_devh ;
288+
289+ UVC_ENTER ();
290+
291+ uvc_device_t * dev = NULL ;
292+ int err = libusb_wrap_sys_device (context -> usb_ctx , sys_dev , & usb_devh );
293+ UVC_DEBUG ("libusb_wrap_sys_device() = %d" , err );
294+ if (err != LIBUSB_SUCCESS ) {
295+ UVC_EXIT (err );
296+ return err ;
297+ }
298+
299+ dev = calloc (1 , sizeof (uvc_device_t ));
300+ dev -> ctx = context ;
301+ dev -> usb_dev = libusb_get_device (usb_devh );
302+
303+ ret = uvc_open_internal (dev , usb_devh , devh );
304+ UVC_EXIT (ret );
305+ return ret ;
306+ }
307+ #endif
308+
266309/** @brief Open a UVC device
267310 * @ingroup device
268311 *
@@ -275,8 +318,6 @@ uvc_error_t uvc_open(
275318 uvc_device_handle_t * * devh ) {
276319 uvc_error_t ret ;
277320 struct libusb_device_handle * usb_devh ;
278- uvc_device_handle_t * internal_devh ;
279- struct libusb_device_descriptor desc ;
280321
281322 UVC_ENTER ();
282323
@@ -288,13 +329,28 @@ uvc_error_t uvc_open(
288329 return ret ;
289330 }
290331
332+ ret = uvc_open_internal (dev , usb_devh , devh );
333+ UVC_EXIT (ret );
334+ return ret ;
335+ }
336+
337+ static uvc_error_t uvc_open_internal (
338+ uvc_device_t * dev ,
339+ struct libusb_device_handle * usb_devh ,
340+ uvc_device_handle_t * * devh ) {
341+ uvc_error_t ret ;
342+ uvc_device_handle_t * internal_devh ;
343+ struct libusb_device_descriptor desc ;
344+
345+ UVC_ENTER ();
346+
291347 uvc_ref_device (dev );
292348
293349 internal_devh = calloc (1 , sizeof (* internal_devh ));
294350 internal_devh -> dev = dev ;
295351 internal_devh -> usb_devh = usb_devh ;
296352
297- ret = uvc_get_device_info (dev , & (internal_devh -> info ));
353+ ret = uvc_get_device_info (internal_devh , & (internal_devh -> info ));
298354
299355 if (ret != UVC_SUCCESS )
300356 goto fail ;
@@ -366,7 +422,7 @@ uvc_error_t uvc_open(
366422 * @param dev Device to parse descriptor for
367423 * @param info Where to store a pointer to the new info struct
368424 */
369- uvc_error_t uvc_get_device_info (uvc_device_t * dev ,
425+ uvc_error_t uvc_get_device_info (uvc_device_handle_t * devh ,
370426 uvc_device_info_t * * info ) {
371427 uvc_error_t ret ;
372428 uvc_device_info_t * internal_info ;
@@ -379,15 +435,15 @@ uvc_error_t uvc_get_device_info(uvc_device_t *dev,
379435 return UVC_ERROR_NO_MEM ;
380436 }
381437
382- if (libusb_get_config_descriptor (dev -> usb_dev ,
438+ if (libusb_get_config_descriptor (devh -> dev -> usb_dev ,
383439 0 ,
384440 & (internal_info -> config )) != 0 ) {
385441 free (internal_info );
386442 UVC_EXIT (UVC_ERROR_IO );
387443 return UVC_ERROR_IO ;
388444 }
389445
390- ret = uvc_scan_control (dev , internal_info );
446+ ret = uvc_scan_control (devh , internal_info );
391447 if (ret != UVC_SUCCESS ) {
392448 uvc_free_device_info (internal_info );
393449 UVC_EXIT (ret );
@@ -474,6 +530,53 @@ void uvc_free_device_info(uvc_device_info_t *info) {
474530 UVC_EXIT_VOID ();
475531}
476532
533+ static uvc_error_t get_device_descriptor (
534+ uvc_device_handle_t * devh ,
535+ uvc_device_descriptor_t * * desc ) {
536+ uvc_device_descriptor_t * desc_internal ;
537+ struct libusb_device_descriptor usb_desc ;
538+ struct libusb_device_handle * usb_devh = devh -> usb_devh ;
539+ uvc_error_t ret ;
540+
541+ UVC_ENTER ();
542+
543+ ret = libusb_get_device_descriptor (devh -> dev -> usb_dev , & usb_desc );
544+
545+ if (ret != UVC_SUCCESS ) {
546+ UVC_EXIT (ret );
547+ return ret ;
548+ }
549+
550+ desc_internal = calloc (1 , sizeof (* desc_internal ));
551+ desc_internal -> idVendor = usb_desc .idVendor ;
552+ desc_internal -> idProduct = usb_desc .idProduct ;
553+
554+ unsigned char buf [64 ];
555+
556+ int bytes = libusb_get_string_descriptor_ascii (
557+ usb_devh , usb_desc .iSerialNumber , buf , sizeof (buf ));
558+
559+ if (bytes > 0 )
560+ desc_internal -> serialNumber = strdup ((const char * ) buf );
561+
562+ bytes = libusb_get_string_descriptor_ascii (
563+ usb_devh , usb_desc .iManufacturer , buf , sizeof (buf ));
564+
565+ if (bytes > 0 )
566+ desc_internal -> manufacturer = strdup ((const char * ) buf );
567+
568+ bytes = libusb_get_string_descriptor_ascii (
569+ usb_devh , usb_desc .iProduct , buf , sizeof (buf ));
570+
571+ if (bytes > 0 )
572+ desc_internal -> product = strdup ((const char * ) buf );
573+
574+ * desc = desc_internal ;
575+
576+ UVC_EXIT (ret );
577+ return ret ;
578+ }
579+
477580/**
478581 * @brief Get a descriptor that contains the general information about
479582 * a device
@@ -943,7 +1046,7 @@ uvc_error_t uvc_release_if(uvc_device_handle_t *devh, int idx) {
9431046 * Find a device's VideoControl interface and process its descriptor
9441047 * @ingroup device
9451048 */
946- uvc_error_t uvc_scan_control (uvc_device_t * dev , uvc_device_info_t * info ) {
1049+ uvc_error_t uvc_scan_control (uvc_device_handle_t * devh , uvc_device_info_t * info ) {
9471050 const struct libusb_interface_descriptor * if_desc ;
9481051 uvc_error_t parse_ret , ret ;
9491052 int interface_idx ;
@@ -957,12 +1060,13 @@ uvc_error_t uvc_scan_control(uvc_device_t *dev, uvc_device_info_t *info) {
9571060
9581061 uvc_device_descriptor_t * dev_desc ;
9591062 int haveTISCamera = 0 ;
960- uvc_get_device_descriptor ( dev , & dev_desc );
961- if ( 0x199e == dev_desc -> idVendor && ( 0x8101 == dev_desc -> idProduct ||
962- 0x8102 == dev_desc -> idProduct )) {
963- haveTISCamera = 1 ;
1063+ if ( get_device_descriptor ( devh , & dev_desc ) == UVC_SUCCESS ) {
1064+ if ( 0x199e == dev_desc -> idVendor && ( 0x8101 == dev_desc -> idProduct ||
1065+ 0x8102 == dev_desc -> idProduct )) {
1066+ haveTISCamera = 1 ;
1067+ }
1068+ uvc_free_device_descriptor ( dev_desc );
9641069 }
965- uvc_free_device_descriptor ( dev_desc );
9661070
9671071 for (interface_idx = 0 ; interface_idx < info -> config -> bNumInterfaces ; ++ interface_idx ) {
9681072 if_desc = & info -> config -> interface [interface_idx ].altsetting [0 ];
@@ -991,7 +1095,7 @@ uvc_error_t uvc_scan_control(uvc_device_t *dev, uvc_device_info_t *info) {
9911095
9921096 while (buffer_left >= 3 ) { // parseX needs to see buf[0,2] = length,type
9931097 block_size = buffer [0 ];
994- parse_ret = uvc_parse_vc (dev , info , buffer , block_size );
1098+ parse_ret = uvc_parse_vc (devh -> dev , info , buffer , block_size );
9951099
9961100 if (parse_ret != UVC_SUCCESS ) {
9971101 ret = parse_ret ;
@@ -1029,8 +1133,10 @@ uvc_error_t uvc_parse_vc_header(uvc_device_t *dev,
10291133 switch (info -> ctrl_if .bcdUVC ) {
10301134 case 0x0100 :
10311135 info -> ctrl_if .dwClockFrequency = DW_TO_INT (block + 7 );
1136+ break ;
10321137 case 0x010a :
10331138 info -> ctrl_if .dwClockFrequency = DW_TO_INT (block + 7 );
1139+ break ;
10341140 case 0x0110 :
10351141 break ;
10361142 default :
0 commit comments