Skip to content

Commit 0dc3507

Browse files
committed
refactor: extract usb_get_serial()
Signed-off-by: Benn Snyder <[email protected]>
1 parent f6de60f commit 0dc3507

File tree

1 file changed

+85
-63
lines changed

1 file changed

+85
-63
lines changed

src/usb_libusb10.c

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

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+
154210
FN_INTERNAL int fnusb_list_device_attributes(freenect_context *ctx, struct freenect_device_attributes** attribute_list)
155211
{
156212
*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
161217
return (count >= INT_MIN) ? (int)count : -1;
162218
}
163219

220+
int res = 0;
164221
struct freenect_device_attributes** next_attr = attribute_list;
165222

166223
// 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
173230
libusb_device* camera_device = devs[i];
174231

175232
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) {
179235
continue;
180236
}
181237

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+
}
196241

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);
205243

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)
209250
{
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;
237255
}
238256
}
257+
}
239258

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;
248261
}
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++;
249271
}
250272

251273
libusb_free_device_list(devs, 1);

0 commit comments

Comments
 (0)