Skip to content

Commit 6d7a8d6

Browse files
committed
extract fnusb_get_serial()
Signed-off-by: Benn Snyder <[email protected]>
1 parent 2386b37 commit 6d7a8d6

File tree

1 file changed

+78
-63
lines changed

1 file changed

+78
-63
lines changed

src/usb_libusb10.c

Lines changed: 78 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,55 @@ FN_INTERNAL libusb_device * fnusb_find_sibling_device(freenect_context* ctx, lib
151151
return NULL;
152152
}
153153

154+
FN_INTERNAL char* fnusb_get_serial(freenect_context* ctx, libusb_device* device, libusb_device_handle* handle)
155+
{
156+
if (ctx == NULL) return NULL;
157+
158+
if (device == NULL && handle != NULL) {
159+
device = libusb_get_device(handle); // no need to free or unref
160+
}
161+
162+
int res = 0;
163+
struct libusb_device_descriptor desc;
164+
165+
res = libusb_get_device_descriptor(device, &desc);
166+
if (res != 0) {
167+
FN_WARNING("Failed to get serial descriptor: %s\n", libusb_error_name(res));
168+
return NULL;
169+
}
170+
171+
// Verify that a serial number exists to query. If not, don't touch the device.
172+
if (desc.iSerialNumber == 0) {
173+
return NULL;
174+
}
175+
176+
libusb_device_handle* localHandle = NULL;
177+
178+
if (handle == NULL) {
179+
res = libusb_open(device, &localHandle);
180+
if (res != 0) {
181+
FN_WARNING("Failed to open device for serial: %s\n", libusb_error_name(res));
182+
return NULL;
183+
}
184+
handle = localHandle;
185+
}
186+
187+
// Read string descriptor referring to serial number.
188+
unsigned char serial[256]; // String descriptors are at most 256 bytes.
189+
res = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, serial, 256);
190+
191+
if (localHandle != NULL) {
192+
libusb_close(localHandle);
193+
}
194+
195+
if (res < 0) {
196+
FN_WARNING("Failed to get serial: %s\n", libusb_error_name(res));
197+
return NULL;
198+
}
199+
200+
return strdup(serial);
201+
}
202+
154203
FN_INTERNAL int fnusb_list_device_attributes(freenect_context *ctx, struct freenect_device_attributes** attribute_list)
155204
{
156205
*attribute_list = NULL; // initialize some return value in case the user is careless.
@@ -161,6 +210,7 @@ FN_INTERNAL int fnusb_list_device_attributes(freenect_context *ctx, struct freen
161210
return (count >= INT_MIN) ? (int)count : -1;
162211
}
163212

213+
int res = 0;
164214
struct freenect_device_attributes** next_attr = attribute_list;
165215

166216
// Pass over the list. For each camera seen, if we already have a camera
@@ -173,79 +223,44 @@ FN_INTERNAL int fnusb_list_device_attributes(freenect_context *ctx, struct freen
173223
libusb_device* camera_device = devs[i];
174224

175225
struct libusb_device_descriptor desc;
176-
int res = libusb_get_device_descriptor (camera_device, &desc);
177-
if (res < 0)
178-
{
226+
res = libusb_get_device_descriptor(camera_device, &desc);
227+
if (res < 0) {
179228
continue;
180229
}
181230

182-
if (desc.idVendor == VID_MICROSOFT && (desc.idProduct == PID_NUI_CAMERA || desc.idProduct == PID_K4W_CAMERA))
183-
{
184-
// Verify that a serial number exists to query. If not, don't touch the device.
185-
if (desc.iSerialNumber == 0)
186-
{
187-
continue;
188-
}
189-
190-
libusb_device_handle *camera_handle;
191-
res = libusb_open(camera_device, &camera_handle);
192-
if (res != 0)
193-
{
194-
continue;
195-
}
231+
if (!fnusb_is_camera(desc)) {
232+
continue;
233+
}
196234

197-
// Read string descriptor referring to serial number.
198-
unsigned char serial[256]; // String descriptors are at most 256 bytes.
199-
res = libusb_get_string_descriptor_ascii(camera_handle, desc.iSerialNumber, serial, 256);
200-
libusb_close(camera_handle);
201-
if (res < 0)
202-
{
203-
continue;
204-
}
235+
const char* serial = fnusb_get_serial(ctx, camera_device, NULL);
205236

206-
// K4W and 1473 don't provide a camera serial; use audio serial instead.
207-
const char* const K4W_1473_SERIAL = "0000000000000000";
208-
if (strncmp((const char*)serial, K4W_1473_SERIAL, 16) == 0)
237+
// K4W and 1473 don't provide a camera serial; use audio serial instead.
238+
const char* const K4W_1473_SERIAL = "0000000000000000";
239+
if (serial == NULL || strncmp((const char*)serial, K4W_1473_SERIAL, 16) == 0)
240+
{
241+
libusb_device* audio_device = fnusb_find_sibling_device(ctx, camera_device, devs, count, &fnusb_is_audio);
242+
if (audio_device != NULL)
209243
{
210-
libusb_device* audio_device = fnusb_find_sibling_device(ctx, camera_device, devs, count, &fnusb_is_audio);
211-
if (audio_device != NULL)
212-
{
213-
struct libusb_device_descriptor audio_desc;
214-
res = libusb_get_device_descriptor(audio_device, &audio_desc);
215-
if (res != 0)
216-
{
217-
FN_WARNING("Failed to get audio serial descriptors of K4W or 1473 device: %s\n", libusb_error_name(res));
218-
}
219-
else
220-
{
221-
libusb_device_handle * audio_handle = NULL;
222-
res = libusb_open(audio_device, &audio_handle);
223-
if (res != 0)
224-
{
225-
FN_WARNING("Failed to open audio device for serial of K4W or 1473 device: %s\n", libusb_error_name(res));
226-
}
227-
else
228-
{
229-
res = libusb_get_string_descriptor_ascii(audio_handle, audio_desc.iSerialNumber, serial, 256);
230-
libusb_close(audio_handle);
231-
if (res != 0)
232-
{
233-
FN_WARNING("Failed to get audio serial of K4W or 1473 device: %s\n", libusb_error_name(res));
234-
}
235-
}
236-
}
244+
const char* audio_serial = fnusb_get_serial(ctx, audio_device, NULL);
245+
if (audio_serial) {
246+
free(serial);
247+
serial = audio_serial;
237248
}
238249
}
250+
}
239251

240-
// Add item to linked list.
241-
struct freenect_device_attributes* current_attr = (struct freenect_device_attributes*)malloc(sizeof(struct freenect_device_attributes));
242-
memset(current_attr, 0, sizeof(*current_attr));
243-
244-
current_attr->camera_serial = strdup((char*)serial);
245-
*next_attr = current_attr;
246-
next_attr = &(current_attr->next);
247-
num_cams++;
252+
if (serial == NULL) {
253+
continue;
248254
}
255+
256+
// Add item to linked list.
257+
struct freenect_device_attributes* current_attr = (struct freenect_device_attributes*)malloc(sizeof(struct freenect_device_attributes));
258+
memset(current_attr, 0, sizeof(*current_attr));
259+
260+
current_attr->camera_serial = serial;
261+
*next_attr = current_attr;
262+
next_attr = &(current_attr->next);
263+
num_cams++;
249264
}
250265

251266
libusb_free_device_list(devs, 1);

0 commit comments

Comments
 (0)