@@ -82,7 +82,7 @@ class Freenect2DeviceImpl : public Freenect2Device
82
82
Freenect2Device::IrCameraParams ir_camera_params_;
83
83
Freenect2Device::ColorCameraParams rgb_camera_params_;
84
84
public:
85
- Freenect2DeviceImpl (Freenect2Impl *context, libusb_device *usb_device, libusb_device_handle *usb_device_handle);
85
+ Freenect2DeviceImpl (Freenect2Impl *context, libusb_device *usb_device, libusb_device_handle *usb_device_handle, const std::string &serial );
86
86
virtual ~Freenect2DeviceImpl ();
87
87
88
88
bool isSameUsbDevice (libusb_device* other);
@@ -104,14 +104,32 @@ class Freenect2DeviceImpl : public Freenect2Device
104
104
virtual void close ();
105
105
};
106
106
107
+ struct PrintBusAndDevice
108
+ {
109
+ libusb_device *dev_;
110
+
111
+ PrintBusAndDevice (libusb_device *dev) : dev_(dev) {}
112
+ };
113
+
114
+ std::ostream &operator <<(std::ostream &out, const PrintBusAndDevice& dev)
115
+ {
116
+ out << " @" << int (libusb_get_bus_number (dev.dev_ )) << " :" << int (libusb_get_port_number (dev.dev_ ));
117
+ return out;
118
+ }
119
+
107
120
class Freenect2Impl
108
121
{
109
122
private:
110
123
bool managed_usb_context_;
111
124
libusb_context *usb_context_;
112
125
EventLoop usb_event_loop_;
113
126
public:
114
- typedef std::vector<libusb_device *> UsbDeviceVector;
127
+ struct UsbDeviceWithSerial
128
+ {
129
+ libusb_device *dev;
130
+ std::string serial;
131
+ };
132
+ typedef std::vector<UsbDeviceWithSerial> UsbDeviceVector;
115
133
typedef std::vector<Freenect2DeviceImpl *> DeviceVector;
116
134
117
135
bool has_device_enumeration_;
@@ -203,7 +221,7 @@ class Freenect2Impl
203
221
// free enumerated device pointers, this should not affect opened devices
204
222
for (UsbDeviceVector::iterator it = enumerated_devices_.begin (); it != enumerated_devices_.end (); ++it)
205
223
{
206
- libusb_unref_device (*it );
224
+ libusb_unref_device (it-> dev );
207
225
}
208
226
209
227
enumerated_devices_.clear ();
@@ -225,18 +243,57 @@ class Freenect2Impl
225
243
libusb_device *dev = device_list[idx];
226
244
libusb_device_descriptor dev_desc;
227
245
228
- int r = libusb_get_device_descriptor (dev, &dev_desc);
229
- // TODO: error handling
246
+ int r = libusb_get_device_descriptor (dev, &dev_desc); // this is always successful
230
247
231
248
if (dev_desc.idVendor == Freenect2Device::VendorId && (dev_desc.idProduct == Freenect2Device::ProductId || dev_desc.idProduct == Freenect2Device::ProductIdPreview))
232
249
{
233
- // valid Kinect v2
234
- enumerated_devices_.push_back (dev);
235
- }
236
- else
237
- {
238
- libusb_unref_device (dev);
250
+ Freenect2DeviceImpl *freenect2_dev;
251
+
252
+ // prevent error if device is already open
253
+ if (tryGetDevice (dev, &freenect2_dev))
254
+ {
255
+ UsbDeviceWithSerial dev_with_serial;
256
+ dev_with_serial.dev = dev;
257
+ dev_with_serial.serial = freenect2_dev->getSerialNumber ();
258
+
259
+ enumerated_devices_.push_back (dev_with_serial);
260
+ continue ;
261
+ }
262
+ else
263
+ {
264
+ libusb_device_handle *dev_handle;
265
+ r = libusb_open (dev, &dev_handle);
266
+
267
+ if (r == LIBUSB_SUCCESS)
268
+ {
269
+ unsigned char buffer[1024 ];
270
+ r = libusb_get_string_descriptor_ascii (dev_handle, dev_desc.iSerialNumber , buffer, sizeof (buffer));
271
+
272
+ if (r > LIBUSB_SUCCESS)
273
+ {
274
+ UsbDeviceWithSerial dev_with_serial;
275
+ dev_with_serial.dev = dev;
276
+ dev_with_serial.serial = std::string (reinterpret_cast <char *>(buffer), size_t (r));
277
+
278
+ std::cout << " [Freenect2Impl] found valid Kinect v2 " << PrintBusAndDevice (dev) << " with serial " << dev_with_serial.serial << std::endl;
279
+ // valid Kinect v2
280
+ enumerated_devices_.push_back (dev_with_serial);
281
+ continue ;
282
+ }
283
+ else
284
+ {
285
+ std::cout << " [Freenect2Impl] failed to get serial number of Kinect v2 " << PrintBusAndDevice (dev) << " !" << std::endl;
286
+ }
287
+
288
+ libusb_close (dev_handle);
289
+ }
290
+ else
291
+ {
292
+ std::cout << " [Freenect2Impl] failed to open Kinect v2 " << PrintBusAndDevice (dev) << " !" << std::endl;
293
+ }
294
+ }
239
295
}
296
+ libusb_unref_device (dev);
240
297
}
241
298
}
242
299
@@ -261,7 +318,7 @@ Freenect2Device::~Freenect2Device()
261
318
{
262
319
}
263
320
264
- Freenect2DeviceImpl::Freenect2DeviceImpl (Freenect2Impl *context, libusb_device *usb_device, libusb_device_handle *usb_device_handle) :
321
+ Freenect2DeviceImpl::Freenect2DeviceImpl (Freenect2Impl *context, libusb_device *usb_device, libusb_device_handle *usb_device_handle, const std::string &serial ) :
265
322
state_ (Created),
266
323
has_usb_interfaces_ (false ),
267
324
context_ (context),
@@ -276,7 +333,7 @@ Freenect2DeviceImpl::Freenect2DeviceImpl(Freenect2Impl *context, libusb_device *
276
333
depth_packet_processor_ (0 ),
277
334
rgb_packet_parser_ (&rgb_packet_processor_),
278
335
depth_packet_parser_ (&depth_packet_processor_),
279
- serial_ (" <unknown> " ),
336
+ serial_ (serial ),
280
337
firmware_ (" <unknown>" )
281
338
{
282
339
rgb_transfer_pool_.setCallback (&rgb_packet_parser_);
@@ -400,7 +457,12 @@ void Freenect2DeviceImpl::start()
400
457
std::cout << GenericResponse (result.data , result.length ).toString () << std::endl;
401
458
402
459
command_tx_.execute (ReadSerialNumberCommand (nextCommandSeq ()), serial_result);
403
- serial_ = SerialNumberResponse (serial_result.data , serial_result.length ).toString ();
460
+ std::string new_serial = SerialNumberResponse (serial_result.data , serial_result.length ).toString ();
461
+
462
+ if (serial_ != new_serial)
463
+ {
464
+ std::cout << " [Freenect2DeviceImpl] serial number reported by libusb " << serial_ << " differs from serial number " << new_serial << " in device protocol! " << std::endl;
465
+ }
404
466
405
467
command_tx_.execute (ReadDepthCameraParametersCommand (nextCommandSeq ()), result);
406
468
DepthCameraParamsResponse *ir_p = reinterpret_cast <DepthCameraParamsResponse *>(result.data );
@@ -561,7 +623,7 @@ int Freenect2::enumerateDevices()
561
623
562
624
std::string Freenect2::getDeviceSerialNumber (int idx)
563
625
{
564
- throw std::exception () ;
626
+ return impl_-> enumerated_devices_ [idx]. serial ;
565
627
}
566
628
567
629
std::string Freenect2::getDefaultDeviceSerialNumber ()
@@ -572,51 +634,68 @@ std::string Freenect2::getDefaultDeviceSerialNumber()
572
634
Freenect2Device *Freenect2::openDevice (int idx)
573
635
{
574
636
int num_devices = impl_->getNumDevices ();
637
+ Freenect2DeviceImpl *device = 0 ;
575
638
576
639
if (idx < num_devices)
577
640
{
578
- libusb_device * dev = impl_->enumerated_devices_ [idx];
641
+ Freenect2Impl::UsbDeviceWithSerial & dev = impl_->enumerated_devices_ [idx];
579
642
libusb_device_handle *dev_handle;
580
643
581
- Freenect2DeviceImpl *device;
582
-
583
- if (impl_->tryGetDevice (dev, &device))
584
- {
585
- return device;
586
- }
587
- else
644
+ if (!impl_->tryGetDevice (dev.dev , &device))
588
645
{
589
- int r = libusb_open (dev, &dev_handle);
590
- // TODO: error handling
591
-
592
- device = new Freenect2DeviceImpl (impl_, dev, dev_handle);
593
- impl_->addDevice (device);
646
+ int r = libusb_open (dev.dev , &dev_handle);
594
647
595
- if (device-> open () )
648
+ if (r == LIBUSB_SUCCESS )
596
649
{
597
- return device;
650
+ r = libusb_reset_device (dev_handle);
651
+
652
+ if (r == LIBUSB_SUCCESS)
653
+ {
654
+ device = new Freenect2DeviceImpl (impl_, dev.dev , dev_handle, dev.serial );
655
+ impl_->addDevice (device);
656
+
657
+ if (!device->open ())
658
+ {
659
+ delete device;
660
+ device = 0 ;
661
+
662
+ std::cout << " [Freenect2DeviceImpl] failed to open Kinect v2 " << PrintBusAndDevice (dev.dev ) << " !" << std::endl;
663
+ }
664
+ }
665
+ else
666
+ {
667
+ std::cout << " [Freenect2Impl] failed to reset Kinect v2 " << PrintBusAndDevice (dev.dev ) << " !" << std::endl;
668
+ }
598
669
}
599
670
else
600
671
{
601
- std::cout << " [Freenect2DeviceImpl] Unable to open device: " << idx << std::endl;
602
- delete device;
603
-
604
- // TODO: error handling
605
- return 0 ;
672
+ std::cout << " [Freenect2Impl] failed to open Kinect v2 " << PrintBusAndDevice (dev.dev ) << " !" << std::endl;
606
673
}
607
674
}
608
675
}
609
676
else
610
677
{
611
- std::cout << " [Freenect2DeviceImpl] Requested device " << idx << " is not connected!" << std::endl;
612
- // TODO: error handling
613
- return 0 ;
678
+ std::cout << " [Freenect2Impl] requested device " << idx << " is not connected!" << std::endl;
614
679
}
680
+
681
+ return device;
615
682
}
616
683
617
684
Freenect2Device *Freenect2::openDevice (const std::string &serial)
618
685
{
619
- throw std::exception ();
686
+ Freenect2Device *device = 0 ;
687
+ int num_devices = impl_->getNumDevices ();
688
+
689
+ for (int idx = 0 ; idx < num_devices; ++idx)
690
+ {
691
+ if (impl_->enumerated_devices_ [idx].serial == serial)
692
+ {
693
+ device = openDevice (idx);
694
+ break ;
695
+ }
696
+ }
697
+
698
+ return device;
620
699
}
621
700
622
701
Freenect2Device *Freenect2::openDefaultDevice ()
0 commit comments