From afa0bbb891bf2b559ec00ecc2c82b2be65e62ac6 Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Tue, 1 Nov 2016 20:19:39 -0400 Subject: [PATCH] common: Only claim the interface once when probing. And only query IEEE1284 data on PRINTER class devices. --- backend_common.c | 93 +++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 49 deletions(-) diff --git a/backend_common.c b/backend_common.c index 1e2e284..64d67ea 100644 --- a/backend_common.c +++ b/backend_common.c @@ -27,7 +27,7 @@ #include "backend_common.h" -#define BACKEND_VERSION "0.68" +#define BACKEND_VERSION "0.69" #ifndef URI_PREFIX #error "Must Define URI_PREFIX" #endif @@ -63,11 +63,11 @@ static int backend_claim_interface(struct libusb_device_handle *dev, int iface) return ret; } +/* Interface **MUST** already be claimed! */ #define ID_BUF_SIZE 2048 -static char *get_device_id(struct libusb_device_handle *dev) +static char *get_device_id(struct libusb_device_handle *dev, int iface) { int length; - int iface = 0; char *buf = malloc(ID_BUF_SIZE + 1); if (!buf) { @@ -75,12 +75,6 @@ static char *get_device_id(struct libusb_device_handle *dev) return NULL; } - if (libusb_kernel_driver_active(dev, iface)) - libusb_detach_kernel_driver(dev, iface); - - if (backend_claim_interface(dev, iface)) - return NULL; - if (libusb_control_transfer(dev, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_INTERFACE, @@ -114,8 +108,6 @@ static char *get_device_id(struct libusb_device_handle *dev) buf[length] = '\0'; done: - libusb_release_interface(dev, iface); - return buf; } @@ -368,21 +360,32 @@ static int print_scan_output(struct libusb_device *device, struct libusb_device_handle *dev; char buf[256]; char *product = NULL, *serial = NULL, *manuf = NULL, *descr = NULL; - + int iface = 0; // XXX loop through interfaces int dlen = 0; struct deviceid_dict dict[MAX_DICT]; char *ieee_id = NULL; + DEBUG("Probing VID: %04X PID: %04x\n", desc->idVendor, desc->idProduct); + if (libusb_open(device, &dev)) { ERROR("Could not open device %04x:%04x (need to be root?)\n", desc->idVendor, desc->idProduct); found = -1; goto abort; } - ieee_id = get_device_id(dev); + if (libusb_kernel_driver_active(dev, iface)) + libusb_detach_kernel_driver(dev, iface); - /* Get IEEE1284 info */ - dlen = parse1284_data(ieee_id, dict); + if (backend_claim_interface(dev, iface)) { + found = -1; + goto abort_close; + } + + /* Query IEEE1284 info only if it's a PRINTER class */ + if (desc->bDeviceClass == LIBUSB_CLASS_PRINTER) { + ieee_id = get_device_id(dev, iface); + dlen = parse1284_data(ieee_id, dict); + } /* Look up mfg string. */ if (manuf2 && strlen(manuf2)) { @@ -459,37 +462,28 @@ static int print_scan_output(struct libusb_device *device, sanitize_string(buf); serial = url_encode(buf); } else if (backend->query_serno) { /* Get from backend hook */ - int iface = 0; - struct libusb_config_descriptor *config = NULL; - if (libusb_kernel_driver_active(dev, iface)) - libusb_detach_kernel_driver(dev, iface); - - /* Try to claim the printer, and handle transient failures */ - if (!backend_claim_interface(dev, iface)) { - int i; - uint8_t endp_up = 0, endp_down = 0; - libusb_get_active_config_descriptor(device, &config); - // XXX loop through interfaces and altettings! - for (i = 0 ; i < config->interface[0].altsetting[0].bNumEndpoints ; i++) { - if ((config->interface[0].altsetting[0].endpoint[i].bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK) { - if (config->interface[0].altsetting[0].endpoint[i].bEndpointAddress & LIBUSB_ENDPOINT_IN) - endp_up = config->interface[0].altsetting[0].endpoint[i].bEndpointAddress; - else - endp_down = config->interface[0].altsetting[0].endpoint[i].bEndpointAddress; - } - if (endp_up && endp_down) - break; + int i; + uint8_t endp_up = 0, endp_down = 0; + libusb_get_active_config_descriptor(device, &config); + // XXX loop through altsettings! + for (i = 0 ; i < config->interface[0].altsetting[0].bNumEndpoints ; i++) { + if ((config->interface[0].altsetting[0].endpoint[i].bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK) { + if (config->interface[0].altsetting[0].endpoint[i].bEndpointAddress & LIBUSB_ENDPOINT_IN) + endp_up = config->interface[0].altsetting[0].endpoint[i].bEndpointAddress; + else + endp_down = config->interface[0].altsetting[0].endpoint[i].bEndpointAddress; } - - buf[0] = 0; - /* Ignore result since a failure isn't critical here */ - backend->query_serno(dev, endp_up, endp_down, buf, STR_LEN_MAX); - libusb_release_interface(dev, iface); - serial = url_encode(buf); + if (endp_up && endp_down) + break; } + buf[0] = 0; + /* Ignore result since a failure isn't critical here */ + backend->query_serno(dev, endp_up, endp_down, buf, STR_LEN_MAX); + serial = url_encode(buf); + if (config) libusb_free_config_descriptor(config); } @@ -502,10 +496,6 @@ static int print_scan_output(struct libusb_device *device, serial = strdup("NONE_UNKNOWN"); } - if (dyesub_debug) - DEBUG("VID: %04X PID: %04X Manuf: '%s' Product: '%s' Serial: '%s'\n", - desc->idVendor, desc->idProduct, manuf, product, serial); - if (scan_only) { int k = 0; @@ -528,16 +518,21 @@ static int print_scan_output(struct libusb_device *device, found = -1; } + if (dyesub_debug) + DEBUG("VID: %04X PID: %04X Manuf: '%s' Product: '%s' Serial: '%s' found: %d\n", + desc->idVendor, desc->idProduct, manuf, product, serial, found); + /* Free things up */ if(serial) free(serial); if(manuf) free(manuf); if(product) free(product); if(descr) free(descr); - if (ieee_id) free(ieee_id); + if(ieee_id) free(ieee_id); + libusb_release_interface(dev, iface); +abort_close: libusb_close(dev); abort: - /* Clean up the dictionary */ while (dlen--) { free (dict[dlen].key); @@ -750,7 +745,7 @@ int main (int argc, char **argv) int claimed; int ret = CUPS_BACKEND_OK; - int iface = 0; + int iface = 0; // XXX loop through interfaces int found = -1; int jobid = 0; int current_page = 0; @@ -921,7 +916,7 @@ int main (int argc, char **argv) goto done_close; } - // XXX loop through interfaces and altettings! + // XXX loop through altsettings! for (i = 0 ; i < config->interface[0].altsetting[0].bNumEndpoints ; i++) { if ((config->interface[0].altsetting[0].endpoint[i].bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK) { if (config->interface[0].altsetting[0].endpoint[i].bEndpointAddress & LIBUSB_ENDPOINT_IN)