@@ -76,7 +76,7 @@ class Freenect2DeviceImpl : public Freenect2Device
76
76
Freenect2Device::IrCameraParams ir_camera_params_;
77
77
Freenect2Device::ColorCameraParams rgb_camera_params_;
78
78
public:
79
- Freenect2DeviceImpl (Freenect2Impl *context, const PacketPipeline *pipeline, libusb_device *usb_device, libusb_device_handle *usb_device_handle);
79
+ Freenect2DeviceImpl (Freenect2Impl *context, const PacketPipeline *pipeline, libusb_device *usb_device, libusb_device_handle *usb_device_handle, const std::string &serial );
80
80
virtual ~Freenect2DeviceImpl ();
81
81
82
82
bool isSameUsbDevice (libusb_device* other);
@@ -98,14 +98,32 @@ class Freenect2DeviceImpl : public Freenect2Device
98
98
virtual void close ();
99
99
};
100
100
101
+ struct PrintBusAndDevice
102
+ {
103
+ libusb_device *dev_;
104
+
105
+ PrintBusAndDevice (libusb_device *dev) : dev_(dev) {}
106
+ };
107
+
108
+ std::ostream &operator <<(std::ostream &out, const PrintBusAndDevice& dev)
109
+ {
110
+ out << " @" << int (libusb_get_bus_number (dev.dev_ )) << " :" << int (libusb_get_port_number (dev.dev_ ));
111
+ return out;
112
+ }
113
+
101
114
class Freenect2Impl
102
115
{
103
116
private:
104
117
bool managed_usb_context_;
105
118
libusb_context *usb_context_;
106
119
EventLoop usb_event_loop_;
107
120
public:
108
- typedef std::vector<libusb_device *> UsbDeviceVector;
121
+ struct UsbDeviceWithSerial
122
+ {
123
+ libusb_device *dev;
124
+ std::string serial;
125
+ };
126
+ typedef std::vector<UsbDeviceWithSerial> UsbDeviceVector;
109
127
typedef std::vector<Freenect2DeviceImpl *> DeviceVector;
110
128
111
129
bool has_device_enumeration_;
@@ -197,7 +215,7 @@ class Freenect2Impl
197
215
// free enumerated device pointers, this should not affect opened devices
198
216
for (UsbDeviceVector::iterator it = enumerated_devices_.begin (); it != enumerated_devices_.end (); ++it)
199
217
{
200
- libusb_unref_device (*it );
218
+ libusb_unref_device (it-> dev );
201
219
}
202
220
203
221
enumerated_devices_.clear ();
@@ -219,18 +237,57 @@ class Freenect2Impl
219
237
libusb_device *dev = device_list[idx];
220
238
libusb_device_descriptor dev_desc;
221
239
222
- int r = libusb_get_device_descriptor (dev, &dev_desc);
223
- // TODO: error handling
240
+ int r = libusb_get_device_descriptor (dev, &dev_desc); // this is always successful
224
241
225
242
if (dev_desc.idVendor == Freenect2Device::VendorId && (dev_desc.idProduct == Freenect2Device::ProductId || dev_desc.idProduct == Freenect2Device::ProductIdPreview))
226
243
{
227
- // valid Kinect v2
228
- enumerated_devices_.push_back (dev);
229
- }
230
- else
231
- {
232
- libusb_unref_device (dev);
244
+ Freenect2DeviceImpl *freenect2_dev;
245
+
246
+ // prevent error if device is already open
247
+ if (tryGetDevice (dev, &freenect2_dev))
248
+ {
249
+ UsbDeviceWithSerial dev_with_serial;
250
+ dev_with_serial.dev = dev;
251
+ dev_with_serial.serial = freenect2_dev->getSerialNumber ();
252
+
253
+ enumerated_devices_.push_back (dev_with_serial);
254
+ continue ;
255
+ }
256
+ else
257
+ {
258
+ libusb_device_handle *dev_handle;
259
+ r = libusb_open (dev, &dev_handle);
260
+
261
+ if (r == LIBUSB_SUCCESS)
262
+ {
263
+ unsigned char buffer[1024 ];
264
+ r = libusb_get_string_descriptor_ascii (dev_handle, dev_desc.iSerialNumber , buffer, sizeof (buffer));
265
+
266
+ if (r > LIBUSB_SUCCESS)
267
+ {
268
+ UsbDeviceWithSerial dev_with_serial;
269
+ dev_with_serial.dev = dev;
270
+ dev_with_serial.serial = std::string (reinterpret_cast <char *>(buffer), size_t (r));
271
+
272
+ std::cout << " [Freenect2Impl] found valid Kinect v2 " << PrintBusAndDevice (dev) << " with serial " << dev_with_serial.serial << std::endl;
273
+ // valid Kinect v2
274
+ enumerated_devices_.push_back (dev_with_serial);
275
+ continue ;
276
+ }
277
+ else
278
+ {
279
+ std::cout << " [Freenect2Impl] failed to get serial number of Kinect v2 " << PrintBusAndDevice (dev) << " !" << std::endl;
280
+ }
281
+
282
+ libusb_close (dev_handle);
283
+ }
284
+ else
285
+ {
286
+ std::cout << " [Freenect2Impl] failed to open Kinect v2 " << PrintBusAndDevice (dev) << " !" << std::endl;
287
+ }
288
+ }
233
289
}
290
+ libusb_unref_device (dev);
234
291
}
235
292
}
236
293
@@ -255,7 +312,7 @@ Freenect2Device::~Freenect2Device()
255
312
{
256
313
}
257
314
258
- Freenect2DeviceImpl::Freenect2DeviceImpl (Freenect2Impl *context, const PacketPipeline *pipeline, libusb_device *usb_device, libusb_device_handle *usb_device_handle) :
315
+ Freenect2DeviceImpl::Freenect2DeviceImpl (Freenect2Impl *context, const PacketPipeline *pipeline, libusb_device *usb_device, libusb_device_handle *usb_device_handle, const std::string &serial ) :
259
316
state_ (Created),
260
317
has_usb_interfaces_ (false ),
261
318
context_ (context),
@@ -267,7 +324,7 @@ Freenect2DeviceImpl::Freenect2DeviceImpl(Freenect2Impl *context, const PacketPip
267
324
command_tx_ (usb_device_handle_, 0x81 , 0x02 ),
268
325
command_seq_ (0 ),
269
326
pipeline_ (pipeline),
270
- serial_ (" <unknown> " ),
327
+ serial_ (serial ),
271
328
firmware_ (" <unknown>" )
272
329
{
273
330
rgb_transfer_pool_.setCallback (pipeline_->getRgbPacketParser ());
@@ -391,7 +448,12 @@ void Freenect2DeviceImpl::start()
391
448
std::cout << GenericResponse (result.data , result.length ).toString () << std::endl;
392
449
393
450
command_tx_.execute (ReadSerialNumberCommand (nextCommandSeq ()), serial_result);
394
- serial_ = SerialNumberResponse (serial_result.data , serial_result.length ).toString ();
451
+ std::string new_serial = SerialNumberResponse (serial_result.data , serial_result.length ).toString ();
452
+
453
+ if (serial_ != new_serial)
454
+ {
455
+ std::cout << " [Freenect2DeviceImpl] serial number reported by libusb " << serial_ << " differs from serial number " << new_serial << " in device protocol! " << std::endl;
456
+ }
395
457
396
458
command_tx_.execute (ReadDepthCameraParametersCommand (nextCommandSeq ()), result);
397
459
DepthCameraParamsResponse *ir_p = reinterpret_cast <DepthCameraParamsResponse *>(result.data );
@@ -556,7 +618,7 @@ int Freenect2::enumerateDevices()
556
618
557
619
std::string Freenect2::getDeviceSerialNumber (int idx)
558
620
{
559
- throw std::exception () ;
621
+ return impl_-> enumerated_devices_ [idx]. serial ;
560
622
}
561
623
562
624
std::string Freenect2::getDefaultDeviceSerialNumber ()
@@ -572,46 +634,51 @@ Freenect2Device *Freenect2::openDevice(int idx)
572
634
Freenect2Device *Freenect2::openDevice (int idx, const PacketPipeline *pipeline)
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_, pipeline, 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_, pipeline, 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)
@@ -621,7 +688,19 @@ Freenect2Device *Freenect2::openDevice(const std::string &serial)
621
688
622
689
Freenect2Device *Freenect2::openDevice (const std::string &serial, const PacketPipeline *pipeline)
623
690
{
624
- throw std::exception ();
691
+ Freenect2Device *device = 0 ;
692
+ int num_devices = impl_->getNumDevices ();
693
+
694
+ for (int idx = 0 ; idx < num_devices; ++idx)
695
+ {
696
+ if (impl_->enumerated_devices_ [idx].serial == serial)
697
+ {
698
+ device = openDevice (idx, pipeline);
699
+ break ;
700
+ }
701
+ }
702
+
703
+ return device;
625
704
}
626
705
627
706
Freenect2Device *Freenect2::openDefaultDevice ()
0 commit comments