@@ -151,6 +151,62 @@ FN_INTERNAL libusb_device * fnusb_find_sibling_device(freenect_context* ctx, lib
151
151
return NULL ;
152
152
}
153
153
154
+ FN_INTERNAL char * usb_get_serial (freenect_context * ctx , libusb_device * device , libusb_device_handle * handle , struct libusb_device_descriptor * desc )
155
+ {
156
+ if (ctx == NULL ) return NULL ;
157
+
158
+ if (device == NULL ) {
159
+ if (handle == NULL ) {
160
+ FN_WARNING ("No handle or device for serial\n" );
161
+ return NULL ;
162
+ }
163
+ device = libusb_get_device (handle ); // no need to free or unref
164
+ }
165
+
166
+ int res = 0 ;
167
+ struct libusb_device_descriptor localDesc ;
168
+
169
+ if (desc == NULL ) {
170
+ res = libusb_get_device_descriptor (device , & localDesc );
171
+ if (res != 0 ) {
172
+ FN_WARNING ("Failed to get serial descriptor: %s\n" , libusb_error_name (res ));
173
+ return NULL ;
174
+ }
175
+ desc = & localDesc ;
176
+ }
177
+
178
+ // Verify that a serial number exists to query. If not, don't touch the device.
179
+ if (desc -> iSerialNumber == 0 ) {
180
+ FN_WARNING ("Device has no serial number\n" );
181
+ return NULL ;
182
+ }
183
+
184
+ libusb_device_handle * localHandle = NULL ;
185
+
186
+ if (handle == NULL ) {
187
+ res = libusb_open (device , & localHandle );
188
+ if (res != 0 ) {
189
+ FN_WARNING ("Failed to open device for serial: %s\n" , libusb_error_name (res ));
190
+ return NULL ;
191
+ }
192
+ handle = localHandle ;
193
+ }
194
+
195
+ unsigned char serial [256 ]; // String descriptors are at most 256 bytes.
196
+ res = libusb_get_string_descriptor_ascii (handle , desc -> iSerialNumber , serial , sizeof (serial ));
197
+
198
+ if (localHandle != NULL ) {
199
+ libusb_close (localHandle );
200
+ }
201
+
202
+ if (res < 0 ) {
203
+ FN_WARNING ("Failed to get serial: %s\n" , libusb_error_name (res ));
204
+ return NULL ;
205
+ }
206
+
207
+ return strndup ((const char * )serial , sizeof (serial ));
208
+ }
209
+
154
210
FN_INTERNAL int fnusb_list_device_attributes (freenect_context * ctx , struct freenect_device_attributes * * attribute_list )
155
211
{
156
212
* attribute_list = NULL ; // initialize some return value in case the user is careless.
@@ -161,6 +217,7 @@ FN_INTERNAL int fnusb_list_device_attributes(freenect_context *ctx, struct freen
161
217
return (count >= INT_MIN ) ? (int )count : -1 ;
162
218
}
163
219
220
+ int res = 0 ;
164
221
struct freenect_device_attributes * * next_attr = attribute_list ;
165
222
166
223
// Pass over the list. For each camera seen, if we already have a camera
@@ -173,79 +230,44 @@ FN_INTERNAL int fnusb_list_device_attributes(freenect_context *ctx, struct freen
173
230
libusb_device * camera_device = devs [i ];
174
231
175
232
struct libusb_device_descriptor desc ;
176
- int res = libusb_get_device_descriptor (camera_device , & desc );
177
- if (res < 0 )
178
- {
233
+ res = libusb_get_device_descriptor (camera_device , & desc );
234
+ if (res < 0 ) {
179
235
continue ;
180
236
}
181
237
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
- }
238
+ if (!fnusb_is_camera (desc )) {
239
+ continue ;
240
+ }
196
241
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
- }
242
+ char * serial = usb_get_serial (ctx , camera_device , NULL , & desc );
205
243
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 )
244
+ // K4W and 1473 don't provide a camera serial; use audio serial instead.
245
+ const char * const K4W_1473_SERIAL = "0000000000000000" ;
246
+ if (serial == NULL || strncmp ((const char * )serial , K4W_1473_SERIAL , 16 ) == 0 )
247
+ {
248
+ libusb_device * audio_device = fnusb_find_sibling_device (ctx , camera_device , devs , count , & fnusb_is_audio );
249
+ if (audio_device != NULL )
209
250
{
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
- }
251
+ char * audio_serial = usb_get_serial (ctx , audio_device , NULL , & desc );
252
+ if (audio_serial ) {
253
+ free (serial );
254
+ serial = audio_serial ;
237
255
}
238
256
}
257
+ }
239
258
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 ++ ;
259
+ if (serial == NULL ) {
260
+ continue ;
248
261
}
262
+
263
+ // Add item to linked list.
264
+ struct freenect_device_attributes * current_attr = (struct freenect_device_attributes * )malloc (sizeof (struct freenect_device_attributes ));
265
+ memset (current_attr , 0 , sizeof (* current_attr ));
266
+
267
+ current_attr -> camera_serial = serial ;
268
+ * next_attr = current_attr ;
269
+ next_attr = & (current_attr -> next );
270
+ num_cams ++ ;
249
271
}
250
272
251
273
libusb_free_device_list (devs , 1 );
0 commit comments