@@ -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+
154203FN_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