Wrap libusb_device
Introduce a structure to wrap a libusb_device and expose its descriptor data read during discovery. PR #2974 <https://github.com/Genymobile/scrcpy/pull/2974>
This commit is contained in:
parent
0ee9e2ff51
commit
d8b37fe189
3 changed files with 59 additions and 18 deletions
|
@ -432,16 +432,21 @@ scrcpy(struct scrcpy_options *options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(serial);
|
assert(serial);
|
||||||
libusb_device *device = sc_usb_find_device(&s->usb, serial);
|
struct sc_usb_device usb_device;
|
||||||
if (!device) {
|
ok = sc_usb_find_device(&s->usb, serial, &usb_device);
|
||||||
|
if (!ok) {
|
||||||
LOGE("Could not find USB device %s", serial);
|
LOGE("Could not find USB device %s", serial);
|
||||||
sc_usb_destroy(&s->usb);
|
sc_usb_destroy(&s->usb);
|
||||||
sc_acksync_destroy(&s->acksync);
|
sc_acksync_destroy(&s->acksync);
|
||||||
goto aoa_hid_end;
|
goto aoa_hid_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = sc_usb_connect(&s->usb, device);
|
LOGI("USB device: %s (%04" PRIx16 ":%04" PRIx16 ") %s %s",
|
||||||
libusb_unref_device(device);
|
usb_device.serial, usb_device.vid, usb_device.pid,
|
||||||
|
usb_device.manufacturer, usb_device.product);
|
||||||
|
|
||||||
|
ok = sc_usb_connect(&s->usb, usb_device.device);
|
||||||
|
sc_usb_device_destroy(&usb_device);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
LOGE("Failed to connect to USB device %s", serial);
|
LOGE("Failed to connect to USB device %s", serial);
|
||||||
sc_usb_destroy(&s->usb);
|
sc_usb_destroy(&s->usb);
|
||||||
|
|
|
@ -30,7 +30,8 @@ read_string(libusb_device_handle *handle, uint8_t desc_index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
accept_device(libusb_device *device, const char *serial) {
|
accept_device(libusb_device *device, const char *serial,
|
||||||
|
struct sc_usb_device *out) {
|
||||||
// Do not log any USB error in this function, it is expected that many USB
|
// Do not log any USB error in this function, it is expected that many USB
|
||||||
// devices available on the computer have permission restrictions
|
// devices available on the computer have permission restrictions
|
||||||
|
|
||||||
|
@ -47,39 +48,61 @@ accept_device(libusb_device *device, const char *serial) {
|
||||||
}
|
}
|
||||||
|
|
||||||
char *device_serial = read_string(handle, desc.iSerialNumber);
|
char *device_serial = read_string(handle, desc.iSerialNumber);
|
||||||
libusb_close(handle);
|
|
||||||
if (!device_serial) {
|
if (!device_serial) {
|
||||||
|
libusb_close(handle);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool matches = !strcmp(serial, device_serial);
|
bool matches = !strcmp(serial, device_serial);
|
||||||
free(device_serial);
|
if (!matches) {
|
||||||
return matches;
|
free(device_serial);
|
||||||
|
libusb_close(handle);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->device = libusb_ref_device(device);
|
||||||
|
out->serial = device_serial;
|
||||||
|
out->vid = desc.idVendor;
|
||||||
|
out->pid = desc.idProduct;
|
||||||
|
out->manufacturer = read_string(handle, desc.iManufacturer);
|
||||||
|
out->product = read_string(handle, desc.iProduct);
|
||||||
|
|
||||||
|
libusb_close(handle);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
libusb_device *
|
void
|
||||||
sc_usb_find_device(struct sc_usb *usb, const char *serial) {
|
sc_usb_device_destroy(struct sc_usb_device *usb_device) {
|
||||||
|
libusb_unref_device(usb_device->device);
|
||||||
|
free(usb_device->serial);
|
||||||
|
free(usb_device->manufacturer);
|
||||||
|
free(usb_device->product);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
sc_usb_find_device(struct sc_usb *usb, const char *serial,
|
||||||
|
struct sc_usb_device *out) {
|
||||||
assert(serial);
|
assert(serial);
|
||||||
|
|
||||||
libusb_device **list;
|
libusb_device **list;
|
||||||
libusb_device *result = NULL;
|
|
||||||
ssize_t count = libusb_get_device_list(usb->context, &list);
|
ssize_t count = libusb_get_device_list(usb->context, &list);
|
||||||
if (count < 0) {
|
if (count < 0) {
|
||||||
log_libusb_error((enum libusb_error) count);
|
log_libusb_error((enum libusb_error) count);
|
||||||
return NULL;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < (size_t) count; ++i) {
|
for (size_t i = 0; i < (size_t) count; ++i) {
|
||||||
libusb_device *device = list[i];
|
libusb_device *device = list[i];
|
||||||
|
|
||||||
if (accept_device(device, serial)) {
|
if (accept_device(device, serial, out)) {
|
||||||
result = libusb_ref_device(device);
|
libusb_free_device_list(list, 1);
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
libusb_free_device_list(list, 1);
|
libusb_free_device_list(list, 1);
|
||||||
return result;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static libusb_device_handle *
|
static libusb_device_handle *
|
||||||
|
|
|
@ -11,14 +11,27 @@ struct sc_usb {
|
||||||
libusb_device_handle *handle;
|
libusb_device_handle *handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sc_usb_device {
|
||||||
|
libusb_device *device;
|
||||||
|
char *serial;
|
||||||
|
char *manufacturer;
|
||||||
|
char *product;
|
||||||
|
uint16_t vid;
|
||||||
|
uint16_t pid;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_usb_device_destroy(struct sc_usb_device *usb_device);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sc_usb_init(struct sc_usb *usb);
|
sc_usb_init(struct sc_usb *usb);
|
||||||
|
|
||||||
void
|
void
|
||||||
sc_usb_destroy(struct sc_usb *usb);
|
sc_usb_destroy(struct sc_usb *usb);
|
||||||
|
|
||||||
libusb_device *
|
bool
|
||||||
sc_usb_find_device(struct sc_usb *usb, const char *serial);
|
sc_usb_find_device(struct sc_usb *usb, const char *serial,
|
||||||
|
struct sc_usb_device *out);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sc_usb_connect(struct sc_usb *usb, libusb_device *device);
|
sc_usb_connect(struct sc_usb *usb, libusb_device *device);
|
||||||
|
|
Loading…
Reference in a new issue