@@ -60,58 +60,149 @@ FN_INTERNAL int fnusb_num_devices(fnusb_ctx *ctx)
6060 return nr ;
6161}
6262
63+ // Returns 1 if `pid` identifies K4W audio, 0 otherwise
64+ FN_INTERNAL int fnusb_is_pid_k4w_audio (int pid )
65+ {
66+ return (pid == PID_K4W_AUDIO || pid == PID_K4W_AUDIO_ALT_1 || pid == PID_K4W_AUDIO_ALT_2 );
67+ }
68+
69+ FN_INTERNAL libusb_device * fnusb_find_connected_audio_device (libusb_device * camera , libusb_device * * deviceList , int cnt )
70+ {
71+ if (cnt <= 0 ) return NULL ;
72+
73+ int cameraBusNo = libusb_get_bus_number (camera );
74+ if (cameraBusNo < 0 ) return NULL ;
75+ libusb_device * cameraParent = libusb_get_parent (camera );
76+
77+ int i = 0 ;
78+ for (i = 0 ; i < cnt ; i ++ )
79+ {
80+ struct libusb_device_descriptor desc ;
81+ int res = libusb_get_device_descriptor (deviceList [i ], & desc );
82+ if (res < 0 )
83+ {
84+ continue ;
85+ }
86+
87+ if (desc .idVendor == VID_MICROSOFT )
88+ {
89+ // make sure its some type of Kinect audio device
90+ if ((desc .idProduct == PID_NUI_AUDIO || fnusb_is_pid_k4w_audio (desc .idProduct )))
91+ {
92+ int audioBusNo = libusb_get_bus_number (deviceList [i ]);
93+ if (audioBusNo == cameraBusNo )
94+ {
95+ // we have a match!
96+ // let's double check
97+ libusb_device * audioParent = libusb_get_parent (deviceList [i ]);
98+ if (cameraParent == audioParent )
99+ {
100+ return deviceList [i ];
101+ }
102+ }
103+ }
104+ }
105+ }
106+
107+ return NULL ;
108+ }
109+
63110FN_INTERNAL int fnusb_list_device_attributes (fnusb_ctx * ctx , struct freenect_device_attributes * * attribute_list )
64111{
112+ // todo: figure out how to log without freenect_context
113+
65114 * attribute_list = NULL ; // initialize some return value in case the user is careless.
66- libusb_device * * devs ;
67- //pointer to pointer of device, used to retrieve a list of devices
115+ libusb_device * * devs ; // pointer to pointer of device, used to retrieve a list of devices
68116 ssize_t count = libusb_get_device_list (ctx -> ctx , & devs );
69117 if (count < 0 )
118+ {
70119 return -1 ;
120+ }
71121
72- struct freenect_device_attributes * * camera_prev_next = attribute_list ;
122+ struct freenect_device_attributes * * next_attr = attribute_list ;
73123
74124 // Pass over the list. For each camera seen, if we already have a camera
75125 // for the newest_camera device, allocate a new one and append it to the list,
76- // incrementing num_devs. Likewise for each audio device.
77- struct libusb_device_descriptor desc ;
126+ // incrementing num_cams.
78127 int num_cams = 0 ;
79128 int i ;
80- for (i = 0 ; i < count ; i ++ ) {
81- int r = libusb_get_device_descriptor (devs [i ], & desc );
82- if (r < 0 )
129+ for (i = 0 ; i < count ; i ++ )
130+ {
131+ libusb_device * camera_device = devs [i ];
132+
133+ struct libusb_device_descriptor desc ;
134+ int res = libusb_get_device_descriptor (camera_device , & desc );
135+ if (res < 0 )
136+ {
83137 continue ;
84- if (desc .idVendor == VID_MICROSOFT && (desc .idProduct == PID_NUI_CAMERA || desc .idProduct == PID_K4W_CAMERA )) {
138+ }
139+
140+ if (desc .idVendor == VID_MICROSOFT && (desc .idProduct == PID_NUI_CAMERA || desc .idProduct == PID_K4W_CAMERA ))
141+ {
85142 // Verify that a serial number exists to query. If not, don't touch the device.
86- if (desc .iSerialNumber == 0 ) {
143+ if (desc .iSerialNumber == 0 )
144+ {
87145 continue ;
88146 }
89147
90- // Open device.
91- int res ;
92- libusb_device_handle * this_device ;
93- res = libusb_open (devs [i ], & this_device );
94- unsigned char string_desc [256 ]; // String descriptors are at most 256 bytes.
95- if (res != 0 ) {
148+ libusb_device_handle * camera_handle ;
149+ res = libusb_open (camera_device , & camera_handle );
150+ if (res != 0 )
151+ {
96152 continue ;
97153 }
98154
99155 // Read string descriptor referring to serial number.
100- res = libusb_get_string_descriptor_ascii (this_device , desc .iSerialNumber , string_desc , 256 );
101- libusb_close (this_device );
102- if (res < 0 ) {
156+ unsigned char serial [256 ]; // String descriptors are at most 256 bytes.
157+ res = libusb_get_string_descriptor_ascii (camera_handle , desc .iSerialNumber , serial , 256 );
158+ libusb_close (camera_handle );
159+ if (res < 0 )
160+ {
103161 continue ;
104162 }
105163
164+ // K4W and 1473 don't provide a camera serial; use audio serial instead.
165+ const char * const K4W_1473_SERIAL = "0000000000000000" ;
166+ if (strncmp ((const char * )serial , K4W_1473_SERIAL , 16 ) != 0 )
167+ {
168+ libusb_device * audio_device = fnusb_find_connected_audio_device (camera_device , devs , count );
169+
170+ if (audio_device != NULL )
171+ {
172+ struct libusb_device_descriptor audio_desc ;
173+ res = libusb_get_device_descriptor (audio_device , & audio_desc );
174+ if (res != 0 )
175+ {
176+ //FN_ERROR("Failed to get audio serial descriptors of K4W or 1473 device: %d\n", res);
177+ }
178+ else
179+ {
180+ libusb_device_handle * audio_handle = NULL ;
181+ res = libusb_open (audio_device , & audio_handle );
182+ if (res != 0 )
183+ {
184+ //FN_ERROR("Failed to open audio device for serial of K4W or 1473 device: %d\n", res);
185+ }
186+ else
187+ {
188+ res = libusb_get_string_descriptor_ascii (audio_handle , audio_desc .iSerialNumber , serial , 256 );
189+ libusb_close (audio_handle );
190+ if (res != 0 )
191+ {
192+ //FN_ERROR("Failed to get audio serial of K4W or 1473 device: %d\n", res);
193+ }
194+ }
195+ }
196+ }
197+ }
198+
106199 // Add item to linked list.
107- struct freenect_device_attributes * new_dev_attrs = (struct freenect_device_attributes * )malloc (sizeof (struct freenect_device_attributes ));
108- memset (new_dev_attrs , 0 , sizeof (* new_dev_attrs ));
109-
110- * camera_prev_next = new_dev_attrs ;
111- // Copy string with serial number
112- new_dev_attrs -> camera_serial = strdup ((char * )string_desc );
113- camera_prev_next = & (new_dev_attrs -> next );
114- // Increment number of cameras found
200+ struct freenect_device_attributes * current_attr = (struct freenect_device_attributes * )malloc (sizeof (struct freenect_device_attributes ));
201+ memset (current_attr , 0 , sizeof (* current_attr ));
202+
203+ current_attr -> camera_serial = strdup ((char * )serial );
204+ * next_attr = current_attr ;
205+ next_attr = & (current_attr -> next );
115206 num_cams ++ ;
116207 }
117208 }
@@ -161,46 +252,6 @@ FN_INTERNAL int fnusb_process_events_timeout(fnusb_ctx *ctx, struct timeval* tim
161252 return libusb_handle_events_timeout (ctx -> ctx , timeout );
162253}
163254
164- // Returns 1 if `pid` identifies K4W audio, 0 otherwise
165- FN_INTERNAL int fnusb_is_pid_k4w_audio (int pid )
166- {
167- return (pid == PID_K4W_AUDIO || pid == PID_K4W_AUDIO_ALT_1 || pid == PID_K4W_AUDIO_ALT_2 );
168- }
169-
170- FN_INTERNAL libusb_device * fnusb_find_connected_audio_device (libusb_device * camera , libusb_device * * deviceList , int cnt ){
171-
172- int cameraBusNo = libusb_get_bus_number (camera );
173- libusb_device * cameraParent = libusb_get_parent (camera );
174-
175- if ( cameraBusNo < 0 ) return NULL ;
176- if ( cnt <= 0 ) return NULL ;
177-
178- int i = 0 ;
179- struct libusb_device_descriptor desc ;
180-
181- for (i = 0 ; i < cnt ; i ++ ) {
182- int r = libusb_get_device_descriptor (deviceList [i ], & desc );
183- if (r < 0 ) continue ;
184- if (desc .idVendor != VID_MICROSOFT ) continue ;
185-
186- //make sure its some type of Kinect audio device
187- if ( (desc .idProduct == PID_NUI_AUDIO || fnusb_is_pid_k4w_audio (desc .idProduct ) ) ){
188-
189- int audioBusNo = libusb_get_bus_number (deviceList [i ]);
190- if ( audioBusNo == cameraBusNo ){
191- //we have a match!
192- //lets double check
193- libusb_device * audioParent = libusb_get_parent (deviceList [i ]);
194- if ( cameraParent == audioParent ){
195- return deviceList [i ];
196- }
197- }
198- }
199- }
200-
201- return NULL ;
202- }
203-
204255FN_INTERNAL int fnusb_open_subdevices (freenect_device * dev , int index )
205256{
206257 freenect_context * ctx = dev -> parent ;
0 commit comments