@@ -60,58 +60,149 @@ FN_INTERNAL int fnusb_num_devices(fnusb_ctx *ctx)
60
60
return nr ;
61
61
}
62
62
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
+
63
110
FN_INTERNAL int fnusb_list_device_attributes (fnusb_ctx * ctx , struct freenect_device_attributes * * attribute_list )
64
111
{
112
+ // todo: figure out how to log without freenect_context
113
+
65
114
* 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
68
116
ssize_t count = libusb_get_device_list (ctx -> ctx , & devs );
69
117
if (count < 0 )
118
+ {
70
119
return -1 ;
120
+ }
71
121
72
- struct freenect_device_attributes * * camera_prev_next = attribute_list ;
122
+ struct freenect_device_attributes * * next_attr = attribute_list ;
73
123
74
124
// Pass over the list. For each camera seen, if we already have a camera
75
125
// 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.
78
127
int num_cams = 0 ;
79
128
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
+ {
83
137
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
+ {
85
142
// 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
+ {
87
145
continue ;
88
146
}
89
147
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
+ {
96
152
continue ;
97
153
}
98
154
99
155
// 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
+ {
103
161
continue ;
104
162
}
105
163
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
+
106
199
// 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 );
115
206
num_cams ++ ;
116
207
}
117
208
}
@@ -161,46 +252,6 @@ FN_INTERNAL int fnusb_process_events_timeout(fnusb_ctx *ctx, struct timeval* tim
161
252
return libusb_handle_events_timeout (ctx -> ctx , timeout );
162
253
}
163
254
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
-
204
255
FN_INTERNAL int fnusb_open_subdevices (freenect_device * dev , int index )
205
256
{
206
257
freenect_context * ctx = dev -> parent ;
0 commit comments