Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move libusb-based USB backend to libusb 1.0 #3477

Closed
michaelrsweet opened this issue Jan 13, 2010 · 7 comments
Closed

Move libusb-based USB backend to libusb 1.0 #3477

michaelrsweet opened this issue Jan 13, 2010 · 7 comments
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

@michaelrsweet michaelrsweet commented Jan 13, 2010

Version: 1.5-current
CUPS.org User: mike

Based on the number of reports of issues with various printers not showing up with the new libusb-based USB backend, we need to add more DEBUG: messages to the code so we can track down the issues and provide fixes.

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Jan 12, 2011

CUPS.org User: mike

Moving this to CUPS 1.5 and repurposing for libusb 1.0...

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Sep 12, 2011

CUPS.org User: jhathaway

Any chance of this making 1.6, as I understand it is a prerequisite for addressing #2890

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Jan 17, 2012

CUPS.org User: till.kamppeter

The attached patch (against current SVN state of CUPS 1.6.x, rev 10182) migrates the libusb-based "usb" CUPS backend (backend/usb-libusb.c) to libusb 1.0.x, including build system changes and also adds some more fixes.

Advantages of libusb 1.0.x migration:

  • Replace deprecated, unmaintained libusb 0.1.x by the up-to-date 1.0.x,
    getting library bugs fixed and security updates
  • Base for further development, especially bi-di support with the help
    of asynchronous API

Extra fixes:

  • STR #3978: USB backend crashes from time to time
  • STR #3965: Some USB printers do not like set_configuration and
    set_interface
  • USB printers which do not report a device URI at all or which report
    only garbage as device URI (especially USB->Parallel adapters) work
    correctly now (https://bugs.launchpad.net/bugs/910272)
@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Jan 17, 2012

CUPS.org User: mike

Thanks Till, moving to 1.6.

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Feb 12, 2012

CUPS.org User: mike

Fixed in Subversion repository.

Updated patch attached; this will also be in the next 1.5.x update.

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Feb 12, 2012

"cups-1.6-usb-backend-libusb-1.0.x.patch":

Index: Makedefs.in

--- Makedefs.in (revision 10183)
+++ Makedefs.in (working copy)
@@ -86,6 +86,8 @@
LIBPAPER = @libpaper@
LIBGSSAPI = @LIBGSSAPI@
LIBUSB = @libusb@
+LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
+LIBUSB_LIBS = @LIBUSB_LIBS@
LIBWRAP = @LIBWRAP@
LIBZ = @libz@

@@ -122,7 +124,7 @@

ALL_CFLAGS = -I.. -D_CUPS_SOURCE $(CFLAGS) $(SSLFLAGS) \

  •       @LARGEFILE@ @PTHREAD_FLAGS@ $(OPTIONS)
    
  •       $(LIBUSB_CFLAGS) @LARGEFILE@ @PTHREAD_FLAGS@ $(OPTIONS)
    

    ALL_CXXFLAGS = -I.. -D_CUPS_SOURCE $(CXXFLAGS) $(SSLFLAGS)
    @LARGEFILE@ @PTHREAD_FLAGS@ $(OPTIONS)
    ARCHFLAGS = @ARCHFLAGS@
    Index: backend/usb-libusb.c

    --- backend/usb-libusb.c (revision 10183)
    +++ backend/usb-libusb.c (working copy)
    @@ -29,10 +29,11 @@
    • Include necessary headers...
      */

-#include <usb.h>
+#include <libusb.h>
#include <poll.h>
#include <cups/cups-private.h>

+libusb_device *list; / List of connected USB devices */

/*

  • Local types...
    @@ -40,13 +41,15 @@

    typedef struct usb_printer_s /**** USB Printer Data ****/
    {

    • struct usb_device device; / Device info */
    • struct libusb_device device; / Device info /
      int conf, /
      Configuration /
      iface, /
      Interface /
      altset, /
      Alternate setting /
      write_endp, /
      Write endpoint */
    •       read_endp;  /\* Read endpoint */
      
    • struct usb_dev_handle handle; / Open handle to device */
    •                    read_endp, /\* Read endpoint */
      
    •                    usblp_attached; /\* Is the "usblp" kernel module
      
    •                  attached? */
      
    • struct libusb_device_handle handle; / Open handle to device */
      } usb_printer_t;

    typedef int (usb_cb_t)(usb_printer_t *, const char *, const char *,
    @@ -99,9 +102,10 @@
    char *argv[]) /
    I - Command-line arguments /
    {
    usb_printer_t *printer; /
    Printer */

    • ssize_t bytes, /* Bytes read/written */
    • int bytes, /* Bytes to read/write */
    •   transferred,        /\* Bytes read/written _/
      
      tbytes; /_ Total bytes written */
    • char buffer[512]; /* Print data buffer */
    • unsigned char buffer[512]; /* Print data buffer /
      struct sigaction action; /
      Actions for POSIX signals /
      struct pollfd pfds[2]; /
      Poll descriptors */

@@ -172,8 +176,8 @@
{
if ((bytes = read(print_fd, buffer, sizeof(buffer))) > 0)
{

  • if (usb_bulk_write(printer->handle, printer->write_endp, buffer,
    
  •                       bytes, 3600000) < 0)
    
  • if (libusb_bulk_transfer(printer->handle, printer->write_endp, buffer,
    
  •              bytes, &transferred, 3600000) < 0)
    

    {
    _cupsLangPrintFilter(stderr, "ERROR",
    _("Unable to send data to printer."));
    @@ -203,6 +207,13 @@

    close_device(printer);

  • /*

  • * Clean up ....

  • */

  • libusb_free_device_list(list, 1);
  • libusb_exit(NULL);

return (CUPS_BACKEND_OK);
}

@@ -214,6 +225,11 @@
static int /* I - 0 on success, -1 on failure /
close_device(usb_printer_t *printer) /
I - Printer */
{

  • struct libusb_device_descriptor devdesc;

  •                                    /\* Current device descriptor */
    
  • struct libusb_config_descriptor *confptr;

  •                                    /* Pointer to current configuration */
    

    if (printer->handle)
    {
    /*
    @@ -221,19 +237,30 @@

    • to the device...
      */
  • int number = printer->device->config[printer->conf].

  •                 interface[printer->iface].
    
  •        altsetting[printer->altset].bInterfaceNumber;
    

- usb_release_interface(printer->handle, number);

  • libusb_get_device_descriptor (printer->device, &devdesc);

  • libusb_get_config_descriptor (printer->device, printer->conf, &confptr);

  • int number = confptr->interface[printer->iface].

  •  altsetting[printer->altset].bInterfaceNumber;
    
  • libusb_release_interface(printer->handle, number);
    if (number != 0)

  •  usb_release_interface(printer->handle, 0);
    
  •  libusb_release_interface(printer->handle, 0);
    

    /*

  • * Re-attach "usblp" kernel module if it was attached before using this

  • * device

  • */

  • if (printer->usblp_attached == 1)

  •  if (libusb_attach_kernel_driver(printer->handle, printer->iface) < 0)
    
  • fprintf(stderr, "DEBUG: Failed to re-attach "usblp" kernel module to %04x:%04x\n",

  •   devdesc.idVendor, devdesc.idProduct);
    
  • libusb_free_config_descriptor(confptr);

  • /*
  • Close the interface and return...
    */
  • usb_close(printer->handle);
  • libusb_close(printer->handle);
    printer->handle = NULL;
    }

@@ -249,15 +276,21 @@
find_device(usb_cb_t cb, /* I - Callback function /
const void *data) /
I - User data for callback */
{

  • struct usb_bus bus; / Current bus */
  • struct usb_device device; / Current device */
  • struct usb_config_descriptor confptr;/ Pointer to current configuration */
  • struct usb_interface ifaceptr; / Pointer to current interface */
  • struct usb_interface_descriptor *altptr;
  • libusb_device *list; / List of connected USB devices */
  • libusb_device device = NULL; / Current device */
  • struct libusb_device_descriptor devdesc;
  •                                    /\* Current device descriptor */
    
  • struct libusb_config_descriptor *confptr = NULL;
  •                                    /\* Pointer to current configuration */
    
  • const struct libusb_interface *ifaceptr = NULL;
  •                                    /\* Pointer to current interface */
    
  • const struct libusb_interface_descriptor altptr = NULL;
    /
    Pointer to current alternate setting */
  • struct usb_endpoint_descriptor *endpptr;
  • const struct libusb_endpoint_descriptor endpptr = NULL;
    /
    Pointer to current endpoint */
  • int conf, /* Current configuration */
  • ssize_t numdevs, /* number of connected devices */
  •                    i = 0;
    
  • uint8_t conf, /* Current configuration /
    iface, /
    Current interface /
    altset, /
    Current alternate setting /
    protocol, /
    Current protocol */
    @@ -274,29 +307,34 @@
  • Initialize libusb...
    */
  • usb_init();
  • fprintf(stderr, "DEBUG: usb_find_busses=%d\n", usb_find_busses());
  • fprintf(stderr, "DEBUG: usb_find_devices=%d\n", usb_find_devices());
  • libusb_init(NULL);
  • numdevs = libusb_get_device_list(NULL, &list);
  • fprintf(stderr, "DEBUG: libusb_get_device_list=%d\n", (int)numdevs);

/*

  • Then loop through the devices it found...
    */

  • for (bus = usb_get_busses(); bus; bus = bus->next)

  • for (device = bus->devices; device; device = device->next)

  • if (numdevs > 0)

  • for (i = 0; i < numdevs; i++)
    {

  •  device = list[i];
    
    • /*
    • Ignore devices with no configuration data and anything that is not
    • a printer...
      */
  •  if (!device->config || !device->descriptor.idVendor ||
    
  •      !device->descriptor.idProduct)
    
  •  libusb_get_device_descriptor (device, &devdesc);
    
  •  if (!devdesc.bNumConfigurations || !devdesc.idVendor ||
    
  •      !devdesc.idProduct)
    

    continue;

  •  for (conf = 0, confptr = device->config;
    
  •       conf < device->descriptor.bNumConfigurations;
    
  •  conf ++, confptr ++)
    
  •  for (conf = 0; conf < devdesc.bNumConfigurations; conf ++)
    
  •  {
    
  • if (libusb_get_config_descriptor (device, conf, &confptr) < 0)

  • continue;
     for (iface = 0, ifaceptr = confptr->interface;
     iface < confptr->bNumInterfaces;
     iface ++, ifaceptr ++)
    

    @@ -317,7 +355,7 @@
    * 1284.4 (packet mode) protocol as well.
    */

  •   if (altptr->bInterfaceClass != USB_CLASS_PRINTER ||
    
  •   if (altptr->bInterfaceClass != LIBUSB_CLASS_PRINTER ||
        altptr->bInterfaceSubClass != 1 ||
    (altptr->bInterfaceProtocol != 1 && /\* Unidirectional _/
     altptr->bInterfaceProtocol != 2) ||    /_ Bidirectional */
    

    @@ -330,10 +368,10 @@
    for (endp = 0, endpptr = altptr->endpoint;
    endp < altptr->bNumEndpoints;
    endp ++, endpptr ++)

  •          if ((endpptr->bmAttributes & USB_ENDPOINT_TYPE_MASK) ==
    
  •             USB_ENDPOINT_TYPE_BULK)
    
  •          if ((endpptr->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) ==
    
  •             LIBUSB_TRANSFER_TYPE_BULK)
      {
    
  •       if (endpptr->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
    
  •       if (endpptr->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
      read_endp = endp;
    else
      write_endp = endp;
    

    @@ -361,31 +399,29 @@

         if (!open_device(&printer, data != NULL))
    {
    
  •     if (!get_device_id(&printer, device_id, sizeof(device_id)))
    
  •     get_device_id(&printer, device_id, sizeof(device_id));
    
  •     make_device_uri(&printer, device_id, device_uri,
    
  •             sizeof(device_uri));
    
  •     if ((*cb)(&printer, device_uri, device_id, data))
      {
    
  •            make_device_uri(&printer, device_id, device_uri,
    

- sizeof(device_uri));

  •       if ((*cb)(&printer, device_uri, device_id, data))
    
  •   {
    
  •     printer.read_endp  = printer.device->config[printer.conf].
    
  •                      interface[printer.iface].
    
  •   printer.read_endp  = confptr->interface[printer.iface].
                   altsetting[printer.altset].
                   endpoint[printer.read_endp].
                   bEndpointAddress;
    
  •     printer.write_endp = printer.device->config[printer.conf].
    
  •                  interface[printer.iface].
    
  •   printer.write_endp = confptr->interface[printer.iface].
                   altsetting[printer.altset].
                   endpoint[printer.write_endp].
                   bEndpointAddress;
    
  •     return (&printer);
    
  •   }
    
  •   return (&printer);
           }
    
           close_device(&printer);
    }
    

    }
    }

  • libusb_free_config_descriptor(confptr);

  •  }
    

    }

    /*
    @@ -393,6 +429,13 @@

    • to print to...
      */
  • /*

  • * Clean up ....

  • */

  • libusb_free_device_list(list, 1);
  • libusb_exit(NULL);

return (NULL);
}

@@ -409,10 +452,12 @@
int length; /* Length of device ID */

  • if (usb_control_msg(printer->handle,
  •                  USB_TYPE_CLASS | USB_ENDPOINT_IN | USB_RECIP_INTERFACE,
    
  •         0, printer->conf, (printer->iface << 8) | printer->altset,
    
  •         buffer, bufsize, 5000) < 0)
    
  • if (libusb_control_transfer(printer->handle,
  •             LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_ENDPOINT_IN |
    
  •             LIBUSB_RECIPIENT_INTERFACE,
    
  •             0, printer->conf,
    
  •             (printer->iface << 8) | printer->altset,
    
  •             (unsigned char *)buffer, bufsize, 5000) < 0)
    
    {
    *buffer = '\0';
    return (-1);
    @@ -430,15 +475,26 @@
    • Check to see if the length is larger than our buffer; first
    • assume that the vendor incorrectly implemented the 1284 spec,
    • and then limit the length to the size of our buffer...
  • * Consider a length < 14 as too short, as the minimum valid device
  • * ID ("MFG:x;MDL:y;") is 12 bytes long and so we have at least 14
  • * bytes with the two length bytes...
  • * Especially the length in the memmove() call cannot get negative then,
    • causing the backend to segfault.
      */
  • if (length > bufsize)
  • if ((length > bufsize) || (length < 14))
    length = (((unsigned)buffer[1] & 255) << 8) +
    ((unsigned)buffer[0] & 255);

if (length > bufsize)
length = bufsize;

  • if (length < 14)
  • {
  • *buffer = '\0';
  • return (-1);
  • }

length -= 2;

/*
@@ -470,7 +526,8 @@

  • Get the device URI and make/model strings...
    */
  • backendGetMakeModel(device_id, make_model, sizeof(make_model));
  • if (backendGetMakeModel(device_id, make_model, sizeof(make_model)))
  • strlcpy(make_model, "Unknown", sizeof(make_model));

/*

  • Report the printer...
    @@ -498,12 +555,14 @@
    char uri, / I - Device URI buffer /
    size_t uri_size) /
    I - Size of device URI buffer */
    {

  • struct libusb_device_descriptor devdesc;

  •                                    /\* Current device descriptor _/
    

    char options[1024]; /_ Device URI options /
    int num_values; /
    Number of 1284 parameters /
    cups_option_t *values; /
    1284 parameters /
    const char *mfg, /
    Manufacturer /
    *mdl, /
    Model */

  •   _des,           /_ Description */
    
  •   _des = NULL,        /_ Description _/
    *sern;          /_ Serial number _/
    

    size_t mfglen; /_ Length of manufacturer string /
    char tempmfg[256], /
    Temporary manufacturer string */
    @@ -520,16 +579,18 @@
    if ((sern = cupsGetOption("SERIALNUMBER", num_values, values)) == NULL)
    if ((sern = cupsGetOption("SERN", num_values, values)) == NULL)
    if ((sern = cupsGetOption("SN", num_values, values)) == NULL &&

  •      printer->device->descriptor.iSerialNumber)
    
  • ((libusb_get_device_descriptor (printer->device, &devdesc) >= 0) &&
    
  •  devdesc.iSerialNumber))
    

    {
    /*
    * Try getting the serial number from the device itself...
    */

  •    int length = usb_get_string_simple(printer->handle,
    
  •                                  printer->device->descriptor.
    
  •                      iSerialNumber,
    
  •                      tempsern, sizeof(tempsern) - 1);
    
  •    int length =
    
  • libusb_get_string_descriptor_ascii(printer->handle,
    
  •                    devdesc.iSerialNumber,
    
  •                    (unsigned char *)tempsern,
    
  •                    sizeof(tempsern) - 1);
     if (length > 0)
    

    {
    tempsern[length] = '\0';
    @@ -585,6 +646,19 @@
    mfg = tempmfg;
    }

  • if (!mdl)

  • {

  • /*

  • * No model? Use description...

  • */

  • if (des)

  •  mdl = des; /\* We remove the manufacturer name below */
    
  • else if (!strncasecmp(mfg, "Unknown", 7))

  •  mdl = "Printer";
    
  • else

  •  mdl = "Unknown Model";
    
  • }

mfglen = strlen(mfg);

if (!strncasecmp(mdl, mfg, mfglen) && _cups_isspace(mdl[mfglen]))
@@ -630,7 +704,14 @@
open_device(usb_printer_t printer, / I - Printer /
int verbose) /
I - Update connecting-to-device state? */
{

  • int number; /* Configuration/interface/altset numbers */
  • struct libusb_device_descriptor devdesc;
  •                                    /\* Current device descriptor */
    
  • struct libusb_config_descriptor *confptr = NULL;
  •                                    /\* Pointer to current configuration */
    
  • int number1 = -1, /* Configuration/interface/altset */
  •    number2 = -1,          /\* numbers */
    
  •    errcode = 0;
    
  • char current_bConfiguration;

/*
@@ -644,78 +725,129 @@

  • Try opening the printer...
    */
  • if ((printer->handle = usb_open(printer->device)) == NULL)
  • if (libusb_open(printer->device, &printer->handle) < 0)
    return (-1);
  • /*
  • * Then set the desired configuration...
  • */

if (verbose)
fputs("STATE: +connecting-to-device\n", stderr);

  • number = printer->device->config[printer->conf].bConfigurationValue;
  • /*
  • * Set the desired configuration, but only if it needs changing. Some
  • * printers (e.g., Samsung) don't like libusb_set_configuration. It will
  • * succeed, but the following print job is sometimes silently lost by the
  • * printer.
  • */
  • if (libusb_control_transfer(printer->handle,
  •            LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_ENDPOINT_IN |
    
  •   LIBUSB_RECIPIENT_DEVICE,
    
  •            8, /\* GET_CONFIGURATION */
    
  •   0, 0, (unsigned char *)&current_bConfiguration, 1, 5000) < 0)
    
  • {
  • current_bConfiguration = 0; /* Failed. Assume not configured */
  • }
  • if (usb_set_configuration(printer->handle, number) < 0)
  • libusb_get_device_descriptor (printer->device, &devdesc);
  • libusb_get_config_descriptor (printer->device, printer->conf, &confptr);
  • number1 = confptr->bConfigurationValue;
  • if (number1 != current_bConfiguration)
    {
  • /*
  • * If the set fails, chances are that the printer only supports a
  • * single configuration. Technically these printers don't conform to
  • * the USB printer specification, but otherwise they'll work...
  • */
  • if (errno != EBUSY)
  •  fprintf(stderr, "DEBUG: Failed to set configuration %d for %04x:%04x\n",
    
  •          number, printer->device->descriptor.idVendor,
    
  •     printer->device->descriptor.idProduct);
    
  • if ((errcode = libusb_set_configuration(printer->handle, number1)) < 0)
  • {
  • /*
    
  •  \* If the set fails, chances are that the printer only supports a
    
  •  \* single configuration.  Technically these printers don't conform to
    
  •  \* the USB printer specification, but otherwise they'll work...
    
  •  */
    
  •  if (errcode != LIBUSB_ERROR_BUSY)
    
  •    fprintf(stderr, "DEBUG: Failed to set configuration %d for %04x:%04x\n",
    
  •            number1, devdesc.idVendor, devdesc.idProduct);
    
  • }
    }

/*

  • * Get the "usblp" kernel module out of the way. This backend only
  • * works without the module attached.
  • */
  • errcode = libusb_kernel_driver_active(printer->handle, printer->iface);
  • if (errcode == 0)
  • printer->usblp_attached = 0;
  • else if (errcode == 1)
  • {
  • printer->usblp_attached = 1;
  • if ((errcode =
  • libusb_detach_kernel_driver(printer->handle, printer->iface)) < 0)
  • {
  •  fprintf(stderr, "DEBUG: Failed to detach \"usblp\" module from %04x:%04x\n",
    
  •     devdesc.idVendor, devdesc.idProduct);
    
  •  goto error;
    
  • }
  • }
  • else
  • {
  • printer->usblp_attached = 0;
  • fprintf(stderr, "DEBUG: Failed to check whether %04x:%04x has the "usblp" kernel module attached\n",
  •     devdesc.idVendor, devdesc.idProduct);
    
  • goto error;
  • }
  • /*
    • Claim interfaces as needed...
      */
  • number = printer->device->config[printer->conf].interface[printer->iface].
  •           altsetting[printer->altset].bInterfaceNumber;
    
  • while (usb_claim_interface(printer->handle, number) < 0)
  • number1 = confptr->interface[printer->iface].
  • altsetting[printer->altset].bInterfaceNumber;
  • while ((errcode = libusb_claim_interface(printer->handle, number1)) < 0)
    {

  • if (errno != EBUSY)

  • if (errcode != LIBUSB_ERROR_BUSY)
    fprintf(stderr, "DEBUG: Failed to claim interface %d for %04x:%04x: %s\n",

  •          number, printer->device->descriptor.idVendor,
    
  •     printer->device->descriptor.idProduct, strerror(errno));
    
  •          number1, devdesc.idVendor, devdesc.idProduct, strerror(errno));
    

    goto error;
    }

    #if 0 /* STR #3801: Claiming interface 0 causes problems with some printers */

  • if (number != 0)

  • while (usb_claim_interface(printer->handle, 0) < 0)

  • if (number1 != 0)

  • while ((errcode = libusb_claim_interface(printer->handle, 0)) < 0)
    {

  •  if (errno != EBUSY)
    
  •  if (errcode != LIBUSB_ERROR_BUSY)
    

    fprintf(stderr, "DEBUG: Failed to claim interface 0 for %04x:%04x: %s\n",

  •   printer->device->descriptor.idVendor,
    
  •   printer->device->descriptor.idProduct, strerror(errno));
    
  •   devdesc.idVendor, devdesc.idProduct, strerror(errno));
    

    goto error;
    }
    #endif /* 0 */

    /*

  • * Set alternate setting...

  • * Set alternate setting, but only if there is more than one option.

  • * Some printers (e.g., Samsung) don't like usb_set_altinterface.
    */

  • number = printer->device->config[printer->conf].interface[printer->iface].

  •           altsetting[printer->altset].bAlternateSetting;
    
  • while (usb_set_altinterface(printer->handle, number) < 0)

  • if (confptr->interface[printer->iface].num_altsetting > 1)
    {

  • if (errno != EBUSY)

  •  fprintf(stderr,
    
  •          "DEBUG: Failed to set alternate interface %d for %04x:%04x: %s\n",
    
  •          number, printer->device->descriptor.idVendor,
    
  •     printer->device->descriptor.idProduct, strerror(errno));
    
  • number1 = confptr->interface[printer->iface].

  •             altsetting[printer->altset].bInterfaceNumber;
    
  • number2 = confptr->interface[printer->iface].

  •             altsetting[printer->altset].bAlternateSetting;
    
  • while ((errcode =

  •   libusb_set_interface_alt_setting(printer->handle, number1, number2))
    
  •  < 0)
    
  • {

  •  if (errcode != LIBUSB_ERROR_BUSY)
    
  •    fprintf(stderr,
    
  •            "DEBUG: Failed to set alternate interface %d for %04x:%04x: %s\n",
    
  •            number2, devdesc.idVendor, devdesc.idProduct, strerror(errno));
    
  • goto error;

  •  goto error;
    
  • }
    }

  • libusb_free_config_descriptor(confptr);

if (verbose)
fputs("STATE: -connecting-to-device\n", stderr);

@@ -730,7 +862,7 @@
if (verbose)
fputs("STATE: -connecting-to-device\n", stderr);

  • usb_close(printer->handle);
  • libusb_close(printer->handle);
    printer->handle = NULL;

return (-1);
@@ -839,9 +971,10 @@
side_cb(usb_printer_t printer, / I - Printer /
int print_fd) /
I - File to print */
{

  • ssize_t bytes, /* Bytes read/written */

  • int bytes, /* Bytes read/written */

  •                    transferred,
        tbytes;     /\* Total bytes written */
    
  • char buffer[512]; /* Print data buffer */

  • unsigned char buffer[512]; /* Print data buffer /
    struct pollfd pfd; /
    Poll descriptor /
    cups_sc_command_t command; /
    Request command /
    cups_sc_status_t status; /
    Request/response status */
    @@ -865,8 +998,9 @@
    {
    if ((bytes = read(print_fd, buffer, sizeof(buffer))) > 0)
    {

  •   while (usb_bulk_write(printer->handle, printer->write_endp, buffer,
    
  •             bytes, 5000) < 0)
    
  •   while (libusb_bulk_transfer(printer->handle, printer->write_endp,
    
  •               buffer,
    
  •               bytes, &transferred, 5000) < 0)
    {
      _cupsLangPrintFilter(stderr, "ERROR",
                   _("Unable to send data to printer."));
    

    Index: backend/Makefile

    --- backend/Makefile (revision 10183)
    +++ backend/Makefile (working copy)
    @@ -274,7 +274,7 @@

    usb: usb.o ../cups/$(LIBCUPS) libbackend.a
    echo Linking $@...

  • $(CC) $(LDFLAGS) -o usb usb.o libbackend.a $(LIBUSB) \

  • $(CC) $(LDFLAGS) -o usb usb.o libbackend.a $(LIBUSB_LIBS)
    $(BACKLIBS) $(LIBS)
    usb.o: usb.c usb-darwin.c usb-libusb.c usb-unix.c

Index: config-scripts/cups-common.m4

--- config-scripts/cups-common.m4 (revision 10183)
+++ config-scripts/cups-common.m4 (working copy)
@@ -212,8 +212,8 @@
dnl See if we have libusb...
AC_ARG_ENABLE(libusb, [ --enable-libusb use libusb for USB printing])

-LIBUSB=""
-AC_SUBST(LIBUSB)
+LIBUSB_CFLAGS=""
+LIBUSB_LIBS=""

if test x$enable_libusb = xyes; then
check_libusb=yes
@@ -224,12 +224,15 @@
fi

if test $check_libusb = yes; then

  • AC_CHECK_LIB(usb, usb_get_string_simple,[
  •   AC_CHECK_HEADER(usb.h,
    
  •       AC_DEFINE(HAVE_USB_H)
    
  •       LIBUSB="-lusb")])
    
  • PKG_CHECK_MODULES(LIBUSB, libusb-1.0 >= 1.0.0)
  • if test -n "$LIBUSB_LIBS"; then
  •   AC_DEFINE(HAVE_USB_H)
    
  • fi
    fi

+AC_SUBST(LIBUSB_CFLAGS)
+AC_SUBST(LIBUSB_LIBS)
+
dnl See if we have libwrap for TCP wrappers support...
AC_ARG_ENABLE(tcp_wrappers, [ --enable-tcp-wrappers use libwrap for TCP wrappers support])

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Feb 12, 2012

"str3477.patch":

Index: backend/usb-libusb.c

--- backend/usb-libusb.c (revision 10242)
+++ backend/usb-libusb.c (working copy)
@@ -1,7 +1,7 @@
/*

  • "$Id$"
    *
    • * Libusb interface code for CUPS.
    • * LIBUSB interface code for CUPS.
      *
  • Copyright 2007-2012 by Apple Inc.

@@ -29,24 +29,33 @@

  • Include necessary headers...
    */

-#include <usb.h>
+#include <libusb.h>
#include <poll.h>
#include <cups/cups-private.h>

/*

  • * Local globals...

  • _/
    +
    +static libusb_device *_list; /* List of connected USB devices /
    +
    +
    +/

    • Local types...
      */

    typedef struct usb_printer_s /**** USB Printer Data ****/
    {

  • struct usb_device device; / Device info */

  • struct libusb_device device; / Device info /
    int conf, /
    Configuration /
    iface, /
    Interface /
    altset, /
    Alternate setting /
    write_endp, /
    Write endpoint */

  •       read_endp;  /\* Read endpoint */
    
  • struct usb_dev_handle handle; / Open handle to device */

  •                    read_endp, /\* Read endpoint */
    
  •                    usblp_attached; /\* Is the "usblp" kernel module
    
  •                  attached? */
    
  • struct libusb_device_handle handle; / Open handle to device */
    } usb_printer_t;

typedef int (usb_cb_t)(usb_printer_t *, const char *, const char *,
@@ -99,9 +108,10 @@
char *argv[]) /
I - Command-line arguments /
{
usb_printer_t *printer; /
Printer */

  • ssize_t bytes, /* Bytes read/written */
  • int bytes, /* Bytes to read/write */
  •   transferred,        /\* Bytes read/written _/
    tbytes;         /_ Total bytes written */
    
  • char buffer[512]; /* Print data buffer */
  • unsigned char buffer[512]; /* Print data buffer /
    struct sigaction action; /
    Actions for POSIX signals /
    struct pollfd pfds[2]; /
    Poll descriptors */

@@ -172,8 +182,8 @@
{
if ((bytes = read(print_fd, buffer, sizeof(buffer))) > 0)
{

  • if (usb_bulk_write(printer->handle, printer->write_endp, buffer,
    
  •                       bytes, 3600000) < 0)
    
  • if (libusb_bulk_transfer(printer->handle, printer->write_endp, buffer,
    
  •              bytes, &transferred, 3600000) < 0)
    

    {
    _cupsLangPrintFilter(stderr, "ERROR",
    _("Unable to send data to printer."));
    @@ -203,6 +213,13 @@

    close_device(printer);

  • /*

  • * Clean up ....

  • */

  • libusb_free_device_list(list, 1);
  • libusb_exit(NULL);

return (CUPS_BACKEND_OK);
}

@@ -214,6 +231,11 @@
static int /* I - 0 on success, -1 on failure /
close_device(usb_printer_t *printer) /
I - Printer */
{

  • struct libusb_device_descriptor devdesc;

  •                                    /\* Current device descriptor */
    
  • struct libusb_config_descriptor *confptr;

  •                                    /* Pointer to current configuration */
    

    if (printer->handle)
    {
    /*
    @@ -221,19 +243,30 @@

    • to the device...
      */
  • int number = printer->device->config[printer->conf].

  •                 interface[printer->iface].
    
  •        altsetting[printer->altset].bInterfaceNumber;
    

- usb_release_interface(printer->handle, number);

  • libusb_get_device_descriptor (printer->device, &devdesc);

  • libusb_get_config_descriptor (printer->device, printer->conf, &confptr);

  • int number = confptr->interface[printer->iface].

  •  altsetting[printer->altset].bInterfaceNumber;
    
  • libusb_release_interface(printer->handle, number);
    if (number != 0)

  •  usb_release_interface(printer->handle, 0);
    
  •  libusb_release_interface(printer->handle, 0);
    

    /*

  • * Re-attach "usblp" kernel module if it was attached before using this

  • * device

  • */

  • if (printer->usblp_attached == 1)

  •  if (libusb_attach_kernel_driver(printer->handle, printer->iface) < 0)
    
  • fprintf(stderr, "DEBUG: Failed to re-attach "usblp" kernel module to %04x:%04x\n",

  •   devdesc.idVendor, devdesc.idProduct);
    
  • libusb_free_config_descriptor(confptr);

  • /*
  • Close the interface and return...
    */
  • usb_close(printer->handle);
  • libusb_close(printer->handle);
    printer->handle = NULL;
    }

@@ -249,15 +282,21 @@
find_device(usb_cb_t cb, /* I - Callback function /
const void *data) /
I - User data for callback */
{

  • struct usb_bus bus; / Current bus */
  • struct usb_device device; / Current device */
  • struct usb_config_descriptor confptr;/ Pointer to current configuration */
  • struct usb_interface ifaceptr; / Pointer to current interface */
  • struct usb_interface_descriptor *altptr;
  • libusb_device *list; / List of connected USB devices */
  • libusb_device device = NULL; / Current device */
  • struct libusb_device_descriptor devdesc;
  •                                    /\* Current device descriptor */
    
  • struct libusb_config_descriptor *confptr = NULL;
  •                                    /\* Pointer to current configuration */
    
  • const struct libusb_interface *ifaceptr = NULL;
  •                                    /\* Pointer to current interface */
    
  • const struct libusb_interface_descriptor altptr = NULL;
    /
    Pointer to current alternate setting */
  • struct usb_endpoint_descriptor *endpptr;
  • const struct libusb_endpoint_descriptor endpptr = NULL;
    /
    Pointer to current endpoint */
  • int conf, /* Current configuration */
  • ssize_t numdevs, /* number of connected devices */
  •                    i = 0;
    
  • uint8_t conf, /* Current configuration /
    iface, /
    Current interface /
    altset, /
    Current alternate setting /
    protocol, /
    Current protocol */
    @@ -274,29 +313,34 @@
  • Initialize libusb...
    */
  • usb_init();
  • fprintf(stderr, "DEBUG: usb_find_busses=%d\n", usb_find_busses());
  • fprintf(stderr, "DEBUG: usb_find_devices=%d\n", usb_find_devices());
  • libusb_init(NULL);
  • numdevs = libusb_get_device_list(NULL, &list);
  • fprintf(stderr, "DEBUG: libusb_get_device_list=%d\n", (int)numdevs);

/*

  • Then loop through the devices it found...
    */

  • for (bus = usb_get_busses(); bus; bus = bus->next)

  • for (device = bus->devices; device; device = device->next)

  • if (numdevs > 0)

  • for (i = 0; i < numdevs; i++)
    {

  •  device = list[i];
    
    • /*
    • Ignore devices with no configuration data and anything that is not
    • a printer...
      */
  •  if (!device->config || !device->descriptor.idVendor ||
    
  •      !device->descriptor.idProduct)
    
  •  libusb_get_device_descriptor (device, &devdesc);
    
  •  if (!devdesc.bNumConfigurations || !devdesc.idVendor ||
    
  •      !devdesc.idProduct)
    

    continue;

  •  for (conf = 0, confptr = device->config;
    
  •       conf < device->descriptor.bNumConfigurations;
    
  •  conf ++, confptr ++)
    
  •  for (conf = 0; conf < devdesc.bNumConfigurations; conf ++)
    
  •  {
    
  • if (libusb_get_config_descriptor (device, conf, &confptr) < 0)

  • continue;
     for (iface = 0, ifaceptr = confptr->interface;
     iface < confptr->bNumInterfaces;
     iface ++, ifaceptr ++)
    

    @@ -317,7 +361,7 @@
    * 1284.4 (packet mode) protocol as well.
    */

  •   if (altptr->bInterfaceClass != USB_CLASS_PRINTER ||
    
  •   if (altptr->bInterfaceClass != LIBUSB_CLASS_PRINTER ||
        altptr->bInterfaceSubClass != 1 ||
    (altptr->bInterfaceProtocol != 1 && /\* Unidirectional _/
     altptr->bInterfaceProtocol != 2) ||    /_ Bidirectional */
    

    @@ -330,10 +374,10 @@
    for (endp = 0, endpptr = altptr->endpoint;
    endp < altptr->bNumEndpoints;
    endp ++, endpptr ++)

  •          if ((endpptr->bmAttributes & USB_ENDPOINT_TYPE_MASK) ==
    
  •             USB_ENDPOINT_TYPE_BULK)
    
  •          if ((endpptr->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) ==
    
  •             LIBUSB_TRANSFER_TYPE_BULK)
      {
    
  •       if (endpptr->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
    
  •       if (endpptr->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
      read_endp = endp;
    else
      write_endp = endp;
    

    @@ -361,31 +405,29 @@

         if (!open_device(&printer, data != NULL))
    {
    
  •     if (!get_device_id(&printer, device_id, sizeof(device_id)))
    
  •     get_device_id(&printer, device_id, sizeof(device_id));
    
  •     make_device_uri(&printer, device_id, device_uri,
    
  •             sizeof(device_uri));
    
  •     if ((*cb)(&printer, device_uri, device_id, data))
      {
    
  •            make_device_uri(&printer, device_id, device_uri,
    

- sizeof(device_uri));

  •       if ((*cb)(&printer, device_uri, device_id, data))
    
  •   {
    
  •     printer.read_endp  = printer.device->config[printer.conf].
    
  •                      interface[printer.iface].
    
  •   printer.read_endp  = confptr->interface[printer.iface].
                   altsetting[printer.altset].
                   endpoint[printer.read_endp].
                   bEndpointAddress;
    
  •     printer.write_endp = printer.device->config[printer.conf].
    
  •                  interface[printer.iface].
    
  •   printer.write_endp = confptr->interface[printer.iface].
                   altsetting[printer.altset].
                   endpoint[printer.write_endp].
                   bEndpointAddress;
    
  •     return (&printer);
    
  •   }
    
  •   return (&printer);
           }
    
           close_device(&printer);
    }
    

    }
    }

  • libusb_free_config_descriptor(confptr);

  •  }
    

    }

    /*
    @@ -393,6 +435,13 @@

    • to print to...
      */
  • /*

  • * Clean up ....

  • */

  • libusb_free_device_list(list, 1);
  • libusb_exit(NULL);

return (NULL);
}

@@ -409,10 +458,12 @@
int length; /* Length of device ID */

  • if (usb_control_msg(printer->handle,

  •                  USB_TYPE_CLASS | USB_ENDPOINT_IN | USB_RECIP_INTERFACE,
    
  •         0, printer->conf, (printer->iface << 8) | printer->altset,
    
  •         buffer, bufsize, 5000) < 0)
    
  • if (libusb_control_transfer(printer->handle,

  •             LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_ENDPOINT_IN |
    
  •             LIBUSB_RECIPIENT_INTERFACE,
    
  •             0, printer->conf,
    
  •             (printer->iface << 8) | printer->altset,
    
  •             (unsigned char *)buffer, bufsize, 5000) < 0)
    

    {
    *buffer = '\0';
    return (-1);
    @@ -482,7 +533,8 @@

    • Get the device URI and make/model strings...
      */
  • backendGetMakeModel(device_id, make_model, sizeof(make_model));

  • if (backendGetMakeModel(device_id, make_model, sizeof(make_model)))

  • strlcpy(make_model, "Unknown", sizeof(make_model));

/*

  • Report the printer...
    @@ -510,12 +562,14 @@
    char uri, / I - Device URI buffer /
    size_t uri_size) /
    I - Size of device URI buffer */
    {

  • struct libusb_device_descriptor devdesc;

  •                                    /\* Current device descriptor _/
    

    char options[1024]; /_ Device URI options /
    int num_values; /
    Number of 1284 parameters /
    cups_option_t *values; /
    1284 parameters /
    const char *mfg, /
    Manufacturer /
    *mdl, /
    Model */

  •   _des,           /_ Description */
    
  •   _des = NULL,        /_ Description _/
    *sern;          /_ Serial number _/
    

    size_t mfglen; /_ Length of manufacturer string /
    char tempmfg[256], /
    Temporary manufacturer string */
    @@ -532,16 +586,18 @@
    if ((sern = cupsGetOption("SERIALNUMBER", num_values, values)) == NULL)
    if ((sern = cupsGetOption("SERN", num_values, values)) == NULL)
    if ((sern = cupsGetOption("SN", num_values, values)) == NULL &&

  •      printer->device->descriptor.iSerialNumber)
    
  • ((libusb_get_device_descriptor (printer->device, &devdesc) >= 0) &&
    
  •  devdesc.iSerialNumber))
    

    {
    /*
    * Try getting the serial number from the device itself...
    */

  •    int length = usb_get_string_simple(printer->handle,
    
  •                                  printer->device->descriptor.
    
  •                      iSerialNumber,
    
  •                      tempsern, sizeof(tempsern) - 1);
    
  •    int length =
    
  • libusb_get_string_descriptor_ascii(printer->handle,
    
  •                    devdesc.iSerialNumber,
    
  •                    (unsigned char *)tempsern,
    
  •                    sizeof(tempsern) - 1);
     if (length > 0)
    

    {
    tempsern[length] = '\0';
    @@ -597,6 +653,19 @@
    mfg = tempmfg;
    }

  • if (!mdl)

  • {

  • /*

  • * No model? Use description...

  • */

  • if (des)

  •  mdl = des; /\* We remove the manufacturer name below */
    
  • else if (!strncasecmp(mfg, "Unknown", 7))

  •  mdl = "Printer";
    
  • else

  •  mdl = "Unknown Model";
    
  • }

mfglen = strlen(mfg);

if (!strncasecmp(mdl, mfg, mfglen) && _cups_isspace(mdl[mfglen]))
@@ -642,7 +711,13 @@
open_device(usb_printer_t printer, / I - Printer /
int verbose) /
I - Update connecting-to-device state? */
{

  • int number; /* Configuration/interface/altset numbers */
  • struct libusb_device_descriptor devdesc;
  •               /\* Current device descriptor */
    
  • struct libusb_config_descriptor *confptr = NULL;
  •               /\* Pointer to current configuration */
    
  • int number1 = -1, /* Configuration/interface/altset */
  • number2 = -1, /* numbers */
  • errcode = 0; /* Current error /
    char current; /
    Current configuration */

@@ -657,7 +732,7 @@

  • Try opening the printer...
    */
  • if ((printer->handle = usb_open(printer->device)) == NULL)
  • if (libusb_open(printer->device, &printer->handle) < 0)
    return (-1);

if (verbose)
@@ -665,20 +740,32 @@

/*

  • Set the desired configuration, but only if it needs changing. Some
  • * printers (e.g., Samsung) don't like usb_set_configuration. It will succeed,
  • * but the following print job is sometimes silently lost by the printer.
  • * printers (e.g., Samsung) don't like libusb_set_configuration. It will
  • * succeed, but the following print job is sometimes silently lost by the
    • printer.
      */
  • if (usb_control_msg(printer->handle,
  •                  USB_TYPE_STANDARD | USB_ENDPOINT_IN | USB_RECIP_DEVICE,
    
  •                  8, /\* GET_CONFIGURATION */
    
  •                  0, 0, &current, 1, 5000) != 1)
    
  • current = 0; /* Assume not configured */
  • if (libusb_control_transfer(printer->handle,
  •             LIBUSB_REQUEST_TYPE_STANDARD |
    
  •                 LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_DEVICE,
    
  •             8, /\* GET_CONFIGURATION */
    
  •             0, 0, (unsigned char *)&current, 1, 5000) < 0)
    
  • {
  • /*
  • * Failed - assume not configured.
  • */
  • number = printer->device->config[printer->conf].bConfigurationValue;
  • if (number != current)
  • current = 0;
  • }
  • libusb_get_device_descriptor(printer->device, &devdesc);
  • libusb_get_config_descriptor(printer->device, printer->conf, &confptr);
  • number1 = confptr->bConfigurationValue;
  • if (number1 != current)
    {

  • if (usb_set_configuration(printer->handle, number) < 0)

  • if ((errcode = libusb_set_configuration(printer->handle, number1)) < 0)
    {
    /*

  • If the set fails, chances are that the printer only supports a
    @@ -686,52 +773,85 @@

  • the USB printer specification, but otherwise they'll work...
    */

  •  if (errno != EBUSY)
    
  •  if (errcode != LIBUSB_ERROR_BUSY)
     fprintf(stderr, "DEBUG: Failed to set configuration %d for %04x:%04x\n",
    
  •            number, printer->device->descriptor.idVendor,
    
  •       printer->device->descriptor.idProduct);
    
  •            number1, devdesc.idVendor, devdesc.idProduct);
    

    }
    }

    /*

  • * Claim interfaces as needed...

  • * Get the "usblp" kernel module out of the way. This backend only

    • works without the module attached.
      */
  • number = printer->device->config[printer->conf].interface[printer->iface].

  •           altsetting[printer->altset].bInterfaceNumber;
    
  • while (usb_claim_interface(printer->handle, number) < 0)

  • errcode = libusb_kernel_driver_active(printer->handle, printer->iface);

  • if (errcode == 0)

  • printer->usblp_attached = 0;

  • else if (errcode == 1)
    {

  • if (errno != EBUSY)

  • printer->usblp_attached = 1;

  • if ((errcode =

  • libusb_detach_kernel_driver(printer->handle, printer->iface)) < 0)

  • {
    fprintf(stderr,

  •          "DEBUG: Failed to claim interface %d for %04x:%04x: %s\n",
    
  •          number, printer->device->descriptor.idVendor,
    
  •     printer->device->descriptor.idProduct, strerror(errno));
    
  •          "DEBUG: Failed to detach \"usblp\" module from %04x:%04x\n",
    
  •     devdesc.idVendor, devdesc.idProduct);
    
  •  goto error;
    
  • }

  • }

  • else

  • {

  • printer->usblp_attached = 0;

  • fprintf(stderr,

  •        "DEBUG: Failed to check whether %04x:%04x has the \"usblp\" kernel "
    
  •        "module attached.\n", devdesc.idVendor, devdesc.idProduct);
    

    goto error;
    }

    /*

  • * Set alternate setting, but only if there is more than one option. Some

  • * printers (e.g., Samsung) don't like usb_set_altinterface.

    • Claim interfaces as needed...
      */
  • if (printer->device->config[printer->conf].interface[printer->iface].

  •      num_altsetting > 1)
    
  • number1 = confptr->interface[printer->iface].

  •            altsetting[printer->altset].bInterfaceNumber;
    
  • while ((errcode = libusb_claim_interface(printer->handle, number1)) < 0)
    {

  • number = printer->device->config[printer->conf].interface[printer->iface].

  •             altsetting[printer->altset].bAlternateSetting;
    
  • if (errcode != LIBUSB_ERROR_BUSY)

  •  fprintf(stderr, "DEBUG: Failed to claim interface %d for %04x:%04x: %s\n",
    
  •          number1, devdesc.idVendor, devdesc.idProduct, strerror(errno));
    
  • while (usb_set_altinterface(printer->handle, number) < 0)

  • goto error;

  • }

  • /*
  • * Set alternate setting, but only if there is more than one option.
  • * Some printers (e.g., Samsung) don't like libusb_set_interface_alt_setting.
  • */
  • if (confptr->interface[printer->iface].num_altsetting > 1)

  • {

  • number1 = confptr->interface[printer->iface].

  •              altsetting[printer->altset].bInterfaceNumber;
    
  • number2 = confptr->interface[printer->iface].

  •              altsetting[printer->altset].bAlternateSetting;
    
  • while ((errcode = libusb_set_interface_alt_setting(printer->handle, number1,

  •                                                   number2)) < 0)
    

    {

  •  if (errno != EBUSY)
    
  •  if (errcode != LIBUSB_ERROR_BUSY)
     fprintf(stderr,
             "DEBUG: Failed to set alternate interface %d for %04x:%04x: "
    
  •            "%s\n", number, printer->device->descriptor.idVendor,
    
  •       printer->device->descriptor.idProduct, strerror(errno));
    
  •            "%s\n", number2, devdesc.idVendor, devdesc.idProduct,
    
  •            strerror(errno));
    

    goto error;
    }
    }

  • libusb_free_config_descriptor(confptr);

if (verbose)
fputs("STATE: -connecting-to-device\n", stderr);
@@ -747,7 +867,7 @@
if (verbose)
fputs("STATE: -connecting-to-device\n", stderr);

  • usb_close(printer->handle);
  • libusb_close(printer->handle);
    printer->handle = NULL;

return (-1);
@@ -856,9 +976,10 @@
side_cb(usb_printer_t printer, / I - Printer /
int print_fd) /
I - File to print */
{

  • ssize_t bytes, /* Bytes read/written */
  • int bytes, /* Bytes read/written */
  •                    transferred,
        tbytes;     /\* Total bytes written */
    
  • char buffer[512]; /* Print data buffer */
  • unsigned char buffer[512]; /* Print data buffer /
    struct pollfd pfd; /
    Poll descriptor /
    cups_sc_command_t command; /
    Request command /
    cups_sc_status_t status; /
    Request/response status */
    @@ -882,8 +1003,9 @@
    {
    if ((bytes = read(print_fd, buffer, sizeof(buffer))) > 0)
    {
  •   while (usb_bulk_write(printer->handle, printer->write_endp, buffer,
    
  •             bytes, 5000) < 0)
    
  •   while (libusb_bulk_transfer(printer->handle, printer->write_endp,
    
  •               buffer,
    
  •               bytes, &transferred, 5000) < 0)
    {
      _cupsLangPrintFilter(stderr, "ERROR",
                   _("Unable to send data to printer."));
    

    Index: backend/usb.c

    --- backend/usb.c (revision 10242)
    +++ backend/usb.c (working copy)
    @@ -3,7 +3,7 @@
    *
    • USB port backend for CUPS.
  • * Copyright 2007-2011 by Apple Inc.
  • * Copyright 2007-2012 by Apple Inc.
    • Copyright 1997-2007 by Easy Software Products, all rights reserved.
    • These coded instructions, statements, and computer programs are the
      @@ -55,7 +55,7 @@
    • Include the vendor-specific USB implementation...
      */

-#ifdef HAVE_USB_H
+#ifdef HAVE_LIBUSB

include "usb-libusb.c"

#elif defined(APPLE)

include "usb-darwin.c"

@@ -118,7 +118,7 @@

return (CUPS_BACKEND_FAILED);
}
-#endif /* APPLE /
+#endif /
HAVE_LIBUSB */

/*

Index: config-scripts/cups-common.m4

--- config-scripts/cups-common.m4 (revision 10242)
+++ config-scripts/cups-common.m4 (working copy)
@@ -233,11 +233,16 @@
check_libusb=no
fi

-if test $check_libusb = yes; then

  • AC_CHECK_LIB(usb, usb_get_string_simple,[
  •   AC_CHECK_HEADER(usb.h,
    
  •       AC_DEFINE(HAVE_USB_H)
    
  •       LIBUSB="-lusb")])
    
    +if test $check_libusb = yes -a "x$PKGCONFIG" != x; then
  • AC_MSG_CHECKING(for libusb-1.0)
  • if $PKGCONFIG --exists libusb-1.0; then
  •   AC_MSG_RESULT(yes)
    
  •   AC_DEFINE(HAVE_LIBUSB)
    
  •   CFLAGS="$CFLAGS `$PKGCONFIG --cflags libusb-1.0`"
    
  •   LIBUSB="`$PKGCONFIG --libs libusb-1.0`"
    
  • else
  •   AC_MSG_RESULT(no)
    
  • fi
    fi

dnl See if we have libwrap for TCP wrappers support...

Index: config.h.in

--- config.h.in (revision 10242)
+++ config.h.in (working copy)
@@ -687,7 +687,7 @@

  • Do we have libusb?
    */

-#undef HAVE_USB_H
+#undef HAVE_LIBUSB

/*

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant