Skip to content

Commit 3d7a011

Browse files
committed
Attempt to rework audio/firmware upload.
It turns out being way uglier and longer, but should behave slightly more correctly in the presence of multiple Kinects. That said, since there's no reliable way to tell for sure which motor, camera, and audio device belong to the same physical package, it's still a little bit of a guessing game. Signed-off-by: Drew Fisher <[email protected]>
1 parent c5c76fa commit 3d7a011

File tree

3 files changed

+92
-27
lines changed

3 files changed

+92
-27
lines changed

src/core.c

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -101,33 +101,6 @@ FREENECTAPI int freenect_open_device(freenect_context *ctx, freenect_device **de
101101
free(pdev);
102102
return res;
103103
}
104-
#ifdef BUILD_AUDIO
105-
if (pdev->usb_audio.dev) {
106-
res = fnusb_num_interfaces(&pdev->usb_audio);
107-
if (res == 1) {
108-
// Upload audio firmware, release devices, and reopen them
109-
res = upload_firmware(&pdev->usb_audio);
110-
if (res < 0) {
111-
FN_ERROR("upload_firmware failed: %d\n", res);
112-
free(pdev);
113-
return res;
114-
}
115-
116-
res = fnusb_close_subdevices(pdev);
117-
if (res < 0) {
118-
FN_ERROR("fnusb_close_subdevices failed: %d\n", res);
119-
free(pdev);
120-
return res;
121-
}
122-
sleep(1); // Give time for the device to reenumerate before trying to open it
123-
res = fnusb_open_subdevices(pdev, index);
124-
if (res < 0) {
125-
free(pdev);
126-
return res;
127-
}
128-
}
129-
}
130-
#endif
131104

132105
if (!ctx->first) {
133106
ctx->first = pdev;

src/usb_libusb10.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@
2828
#include <stdbool.h>
2929
#include <stdlib.h>
3030
#include <string.h>
31+
#include <unistd.h>
3132
#include <libusb-1.0/libusb.h>
3233
#include "freenect_internal.h"
34+
#include "loader.h"
3335

3436
int fnusb_num_devices(fnusb_ctx *ctx)
3537
{
@@ -199,6 +201,95 @@ int fnusb_open_subdevices(freenect_device *dev, int index)
199201
dev->usb_audio.dev = NULL;
200202
break;
201203
}
204+
// Using the device handle that we've claimed, see if this
205+
// device has already uploaded firmware (has 2 interfaces). If
206+
// not, save the serial number (by reading the appropriate
207+
// descriptor), upload the firmware, and then enter a loop
208+
// waiting for a device with the same serial number to
209+
// reappear.
210+
int num_interfaces = fnusb_num_interfaces(&dev->usb_audio);
211+
if (num_interfaces == 1) {
212+
// Read the serial number from the string descriptor and save it.
213+
unsigned char string_desc[256]; // String descriptors are at most 256 bytes
214+
res = libusb_get_string_descriptor_ascii(dev->usb_audio.dev, desc.iSerialNumber, string_desc, 256);
215+
if (res < 0) {
216+
FN_ERROR("Failed to retrieve serial number for audio device in bootloader state\n");
217+
break;
218+
}
219+
char* audio_serial = strdup((char*)string_desc);
220+
221+
FN_SPEW("Uploading firmware to audio device in bootloader state.\n");
222+
res = upload_firmware(&dev->usb_audio);
223+
if (res < 0) {
224+
FN_ERROR("upload_firmware failed: %d\n", res);
225+
break;
226+
}
227+
libusb_close(dev->usb_audio.dev);
228+
dev->usb_audio.dev = NULL;
229+
// Wait for the device to reappear.
230+
int loops = 0;
231+
for (loops = 0; loops < 10; loops++) { // Loop for at most 10 tries.
232+
FN_SPEW("Try %d: Looking for new audio device matching serial %s\n", loops, audio_serial);
233+
// Scan devices.
234+
libusb_device **new_dev_list;
235+
int dev_index;
236+
ssize_t num_new_devs = libusb_get_device_list(ctx->usb.ctx, &new_dev_list);
237+
for (dev_index = 0; dev_index < num_new_devs; ++dev_index) {
238+
struct libusb_device_descriptor new_dev_desc;
239+
int r;
240+
r = libusb_get_device_descriptor (new_dev_list[dev_index], &new_dev_desc);
241+
if (r < 0)
242+
continue;
243+
// If this dev is a Kinect audio device, open device, read serial, and compare.
244+
if (new_dev_desc.idVendor == VID_MICROSOFT && new_dev_desc.idProduct == PID_NUI_AUDIO) {
245+
FN_SPEW("Matched VID/PID!\n");
246+
libusb_device_handle* new_dev_handle;
247+
// Open device
248+
r = libusb_open(new_dev_list[dev_index], &new_dev_handle);
249+
if (r < 0)
250+
continue;
251+
// Read serial
252+
r = libusb_get_string_descriptor_ascii(new_dev_handle, new_dev_desc.iSerialNumber, string_desc, 256);
253+
if (r < 0) {
254+
FN_SPEW("Lost new audio device while fetching serial number.\n");
255+
libusb_close(new_dev_handle);
256+
continue;
257+
}
258+
// Compare to expected serial
259+
if (r == strlen(audio_serial) && strcmp((char*)string_desc, audio_serial) == 0) {
260+
// We found it!
261+
r = libusb_claim_interface(new_dev_handle, 0);
262+
if (r != 0) {
263+
// Ouch, found the device but couldn't claim the interface.
264+
FN_SPEW("Device with serial %s reappeared but couldn't claim interface 0\n", audio_serial);
265+
libusb_close(new_dev_handle);
266+
continue;
267+
}
268+
// Save the device handle.
269+
dev->usb_audio.dev = new_dev_handle;
270+
// Verify that we've actually found a device running the right firmware.
271+
if (fnusb_num_interfaces(&dev->usb_audio) != 2) {
272+
FN_SPEW("Opened audio with matching serial but too few interfaces.\n");
273+
dev->usb_audio.dev = NULL;
274+
libusb_close(new_dev_handle);
275+
continue;
276+
}
277+
break;
278+
} else {
279+
FN_SPEW("Got serial %s, expected serial %s\n", (char*)string_desc, audio_serial);
280+
}
281+
}
282+
}
283+
284+
libusb_free_device_list(new_dev_list, 1);
285+
// If we found the right device, break out of this loop.
286+
if (dev->usb_audio.dev)
287+
break;
288+
// Sleep for a second to give the device more time to reenumerate.
289+
sleep(1);
290+
}
291+
free(audio_serial);
292+
}
202293
} else {
203294
nr_audio++;
204295
}

src/usb_libusb10.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#ifndef USB_LIBUSB10
2828
#define USB_LIBUSB10
2929

30+
#include "libfreenect.h"
3031
#include <libusb-1.0/libusb.h>
3132

3233
#if defined(__APPLE__)

0 commit comments

Comments
 (0)