4 * Libusb interface code for the Common UNIX Printing System (CUPS).
6 * Copyright 2007-2009 by Apple Inc.
8 * These coded instructions, statements, and computer programs are the
9 * property of Apple Inc. and are protected by Federal copyright
10 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
11 * which should have been included with this file. If this file is
12 * file is missing or damaged, see the license at "http://www.cups.org/".
16 * list_devices() - List the available printers.
17 * print_device() - Print a file to a USB device.
18 * close_device() - Close the connection to the USB printer.
19 * find_device() - Find or enumerate USB printers.
20 * get_device_id() - Get the IEEE-1284 device ID for the printer.
21 * list_cb() - List USB printers for discovery.
22 * make_device_uri() - Create a device URI for a USB printer.
23 * open_device() - Open a connection to the USB printer.
24 * print_cb() - Find a USB printer for printing.
25 * side_cb() - Handle side-channel requests.
29 * Include necessary headers...
34 #include <cups/globals.h>
41 typedef struct usb_printer_s
/**** USB Printer Data ****/
43 struct usb_device
*device
; /* Device info */
44 int conf
, /* Configuration */
45 iface
, /* Interface */
46 altset
, /* Alternate setting */
47 write_endp
, /* Write endpoint */
48 read_endp
; /* Read endpoint */
49 struct usb_dev_handle
*handle
; /* Open handle to device */
52 typedef int (*usb_cb_t
)(usb_printer_t
*, const char *, const char *,
60 static int close_device(usb_printer_t
*printer
);
61 static usb_printer_t
*find_device(usb_cb_t cb
, const void *data
);
62 static int get_device_id(usb_printer_t
*printer
, char *buffer
,
64 static int list_cb(usb_printer_t
*printer
, const char *device_uri
,
65 const char *device_id
, const void *data
);
66 static char *make_device_uri(usb_printer_t
*printer
,
67 const char *device_id
,
68 char *uri
, size_t uri_size
);
69 static int open_device(usb_printer_t
*printer
, int verbose
);
70 static int print_cb(usb_printer_t
*printer
, const char *device_uri
,
71 const char *device_id
, const void *data
);
72 static ssize_t
side_cb(usb_printer_t
*printer
, int print_fd
);
76 * 'list_devices()' - List the available printers.
82 fputs("DEBUG: list_devices\n", stderr
);
83 find_device(list_cb
, NULL
);
88 * 'print_device()' - Print a file to a USB device.
91 int /* O - Exit status */
92 print_device(const char *uri
, /* I - Device URI */
93 const char *hostname
, /* I - Hostname/manufacturer */
94 const char *resource
, /* I - Resource/modelname */
95 char *options
, /* I - Device options/serial number */
96 int print_fd
, /* I - File descriptor to print */
97 int copies
, /* I - Copies to print */
98 int argc
, /* I - Number of command-line arguments (6 or 7) */
99 char *argv
[]) /* I - Command-line arguments */
101 usb_printer_t
*printer
; /* Printer */
102 ssize_t bytes
, /* Bytes read/written */
103 tbytes
; /* Total bytes written */
104 char buffer
[8192]; /* Print data buffer */
105 struct sigaction action
; /* Actions for POSIX signals */
106 struct pollfd pfds
[2]; /* Poll descriptors */
109 fputs("DEBUG: print_device\n", stderr
);
112 * Connect to the printer...
115 while ((printer
= find_device(print_cb
, uri
)) == NULL
)
117 _cupsLangPuts(stderr
,
118 _("INFO: Waiting for printer to become available...\n"));
124 * If we are printing data from a print driver on stdin, ignore SIGTERM
125 * so that the driver can finish out any page data, e.g. to eject the
126 * current page. We only do this for stdin printing as otherwise there
127 * is no way to cancel a raw print job...
132 memset(&action
, 0, sizeof(action
));
134 sigemptyset(&action
.sa_mask
);
135 action
.sa_handler
= SIG_IGN
;
136 sigaction(SIGTERM
, &action
, NULL
);
141 pfds
[0].fd
= print_fd
;
142 pfds
[0].events
= POLLIN
;
143 pfds
[1].fd
= CUPS_SC_FD
;
144 pfds
[1].events
= POLLIN
;
146 while (copies
> 0 && tbytes
>= 0)
152 fputs("PAGE: 1 1\n", stderr
);
153 lseek(print_fd
, 0, SEEK_SET
);
157 * TODO: Add back-channel support, along with better write error handling.
160 while (poll(pfds
, 2, -1) > 0)
163 * CUPS STR #3318: USB process hangs on end-of-file, making further
164 * printing impossible
166 * From a strict interpretation of POSIX poll(), POLLHUP should never be
167 * set without POLLIN, since POLLIN is the event you request. That said,
168 * it appears that some versions of Linux break this.
171 if (pfds
[0].revents
& (POLLIN
| POLLHUP
))
173 if ((bytes
= read(print_fd
, buffer
, sizeof(buffer
))) > 0)
175 if (usb_bulk_write(printer
->handle
, printer
->write_endp
, buffer
,
178 _cupsLangPrintf(stderr
,
179 _("ERROR: Unable to write %d bytes to printer\n"),
187 else if (bytes
== 0 || (bytes
< 0 && errno
!= EAGAIN
&& errno
!= EINTR
))
191 if (pfds
[1].revents
& (POLLIN
| POLLHUP
))
193 if ((bytes
= side_cb(printer
, print_fd
)) < 0)
194 pfds
[1].events
= 0; /* Filter has gone away... */
202 * Close our connection and return...
205 close_device(printer
);
207 return (CUPS_BACKEND_OK
);
212 * 'close_device()' - Close the connection to the USB printer.
215 static int /* I - 0 on success, -1 on failure */
216 close_device(usb_printer_t
*printer
) /* I - Printer */
221 * Release interfaces before closing so that we know all data is written
225 int number
= printer
->device
->config
[printer
->conf
].
226 interface
[printer
->iface
].
227 altsetting
[printer
->altset
].bInterfaceNumber
;
228 usb_release_interface(printer
->handle
, number
);
231 usb_release_interface(printer
->handle
, 0);
234 * Close the interface and return...
237 usb_close(printer
->handle
);
238 printer
->handle
= NULL
;
246 * 'find_device()' - Find or enumerate USB printers.
249 static usb_printer_t
* /* O - Found printer */
250 find_device(usb_cb_t cb
, /* I - Callback function */
251 const void *data
) /* I - User data for callback */
253 struct usb_bus
*bus
; /* Current bus */
254 struct usb_device
*device
; /* Current device */
255 struct usb_config_descriptor
*confptr
;/* Pointer to current configuration */
256 struct usb_interface
*ifaceptr
; /* Pointer to current interface */
257 struct usb_interface_descriptor
*altptr
;
258 /* Pointer to current alternate setting */
259 struct usb_endpoint_descriptor
*endpptr
;
260 /* Pointer to current endpoint */
261 int conf
, /* Current configuration */
262 iface
, /* Current interface */
263 altset
, /* Current alternate setting */
264 protocol
, /* Current protocol */
265 endp
, /* Current endpoint */
266 read_endp
, /* Current read endpoint */
267 write_endp
; /* Current write endpoint */
268 char device_id
[1024],/* IEEE-1284 device ID */
271 static usb_printer_t printer
; /* Current printer */
275 * Initialize libusb...
279 fprintf(stderr
, "DEBUG: usb_find_busses=%d\n", usb_find_busses());
280 fprintf(stderr
, "DEBUG: usb_find_devices=%d\n", usb_find_devices());
283 * Then loop through the devices it found...
286 for (bus
= usb_get_busses(); bus
; bus
= bus
->next
)
287 for (device
= bus
->devices
; device
; device
= device
->next
)
290 * Ignore devices with no configuration data and anything that is not
294 if (!device
->config
|| !device
->descriptor
.idVendor
||
295 !device
->descriptor
.idProduct
)
298 for (conf
= 0, confptr
= device
->config
;
299 conf
< device
->descriptor
.bNumConfigurations
;
301 for (iface
= 0, ifaceptr
= confptr
->interface
;
302 iface
< confptr
->bNumInterfaces
;
303 iface
++, ifaceptr
++)
306 * Some printers offer multiple interfaces...
311 for (altset
= 0, altptr
= ifaceptr
->altsetting
;
312 altset
< ifaceptr
->num_altsetting
;
313 altset
++, altptr
++)
316 * Currently we only support unidirectional and bidirectional
317 * printers. Future versions of this code will support the
318 * 1284.4 (packet mode) protocol as well.
321 if (altptr
->bInterfaceClass
!= USB_CLASS_PRINTER
||
322 altptr
->bInterfaceSubClass
!= 1 ||
323 (altptr
->bInterfaceProtocol
!= 1 && /* Unidirectional */
324 altptr
->bInterfaceProtocol
!= 2) || /* Bidirectional */
325 altptr
->bInterfaceProtocol
< protocol
)
331 for (endp
= 0, endpptr
= altptr
->endpoint
;
332 endp
< altptr
->bNumEndpoints
;
334 if ((endpptr
->bmAttributes
& USB_ENDPOINT_TYPE_MASK
) ==
335 USB_ENDPOINT_TYPE_BULK
)
337 if (endpptr
->bEndpointAddress
& USB_ENDPOINT_DIR_MASK
)
346 * Save the best match so far...
349 protocol
= altptr
->bInterfaceProtocol
;
350 printer
.altset
= altset
;
351 printer
.write_endp
= write_endp
;
352 printer
.read_endp
= read_endp
;
358 printer
.device
= device
;
360 printer
.iface
= iface
;
361 printer
.handle
= NULL
;
363 if (!open_device(&printer
, data
!= NULL
))
365 if (!get_device_id(&printer
, device_id
, sizeof(device_id
)))
367 make_device_uri(&printer
, device_id
, device_uri
,
370 if ((*cb
)(&printer
, device_uri
, device_id
, data
))
372 printer
.read_endp
= printer
.device
->config
[printer
.conf
].
373 interface
[printer
.iface
].
374 altsetting
[printer
.altset
].
375 endpoint
[printer
.read_endp
].
377 printer
.write_endp
= printer
.device
->config
[printer
.conf
].
378 interface
[printer
.iface
].
379 altsetting
[printer
.altset
].
380 endpoint
[printer
.write_endp
].
386 close_device(&printer
);
393 * If we get this far without returning, then we haven't found a printer
402 * 'get_device_id()' - Get the IEEE-1284 device ID for the printer.
405 static int /* O - 0 on success, -1 on error */
406 get_device_id(usb_printer_t
*printer
, /* I - Printer */
407 char *buffer
, /* I - String buffer */
408 size_t bufsize
) /* I - Number of bytes in buffer */
410 int length
; /* Length of device ID */
413 if (usb_control_msg(printer
->handle
,
414 USB_TYPE_CLASS
| USB_ENDPOINT_IN
| USB_RECIP_INTERFACE
,
415 0, printer
->conf
, printer
->iface
,
416 buffer
, bufsize
, 5000) < 0)
423 * Extract the length of the device ID string from the first two
424 * bytes. The 1284 spec says the length is stored MSB first...
427 length
= (((unsigned)buffer
[0] & 255) << 8) +
428 ((unsigned)buffer
[1] & 255);
431 * Check to see if the length is larger than our buffer; first
432 * assume that the vendor incorrectly implemented the 1284 spec,
433 * and then limit the length to the size of our buffer...
436 if (length
> bufsize
)
437 length
= (((unsigned)buffer
[1] & 255) << 8) +
438 ((unsigned)buffer
[0] & 255);
440 if (length
> bufsize
)
446 * Copy the device ID text to the beginning of the buffer and
450 memmove(buffer
, buffer
+ 2, length
);
451 buffer
[length
] = '\0';
458 * 'list_cb()' - List USB printers for discovery.
461 static int /* O - 0 to continue, 1 to stop */
462 list_cb(usb_printer_t
*printer
, /* I - Printer */
463 const char *device_uri
, /* I - Device URI */
464 const char *device_id
, /* I - IEEE-1284 device ID */
465 const void *data
) /* I - User data (not used) */
467 char make_model
[1024]; /* Make and model */
471 * Get the device URI and make/model strings...
474 backendGetMakeModel(device_id
, make_model
, sizeof(make_model
));
477 * Report the printer...
480 cupsBackendReport("direct", device_uri
, make_model
, make_model
, device_id
,
492 * 'make_device_uri()' - Create a device URI for a USB printer.
495 static char * /* O - Device URI */
497 usb_printer_t
*printer
, /* I - Printer */
498 const char *device_id
, /* I - IEEE-1284 device ID */
499 char *uri
, /* I - Device URI buffer */
500 size_t uri_size
) /* I - Size of device URI buffer */
502 char options
[1024]; /* Device URI options */
503 int num_values
; /* Number of 1284 parameters */
504 cups_option_t
*values
; /* 1284 parameters */
505 const char *mfg
, /* Manufacturer */
507 *des
, /* Description */
508 *sern
; /* Serial number */
509 char tempmfg
[256], /* Temporary manufacturer string */
510 tempsern
[256], /* Temporary serial number string */
511 *tempptr
; /* Pointer into temp string */
515 * Get the make, model, and serial numbers...
518 num_values
= _cupsGet1284Values(device_id
, &values
);
520 if ((sern
= cupsGetOption("SERIALNUMBER", num_values
, values
)) == NULL
)
521 if ((sern
= cupsGetOption("SERN", num_values
, values
)) == NULL
)
522 if ((sern
= cupsGetOption("SN", num_values
, values
)) == NULL
)
525 * Try getting the serial number from the device itself...
528 int length
= usb_get_string_simple(printer
->handle
,
529 printer
->device
->descriptor
.
531 tempsern
, sizeof(tempsern
) - 1);
534 tempsern
[length
] = '\0';
539 if ((mfg
= cupsGetOption("MANUFACTURER", num_values
, values
)) == NULL
)
540 mfg
= cupsGetOption("MFG", num_values
, values
);
542 if ((mdl
= cupsGetOption("MODEL", num_values
, values
)) == NULL
)
543 mdl
= cupsGetOption("MDL", num_values
, values
);
547 * To maintain compatibility with the original IOKit-based backend on Mac OS X,
548 * don't map manufacturer names...
555 * To maintain compatibility with the original character device backend on
556 * Linux and *BSD, map manufacturer names...
561 if (!strcasecmp(mfg
, "Hewlett-Packard"))
563 else if (!strcasecmp(mfg
, "Lexmark International"))
567 #endif /* __APPLE__ */
570 * No manufacturer? Use the model string or description...
574 _ppdNormalizeMakeAndModel(mdl
, tempmfg
, sizeof(tempmfg
));
575 else if ((des
= cupsGetOption("DESCRIPTION", num_values
, values
)) != NULL
||
576 (des
= cupsGetOption("DES", num_values
, values
)) != NULL
)
577 _ppdNormalizeMakeAndModel(des
, tempmfg
, sizeof(tempmfg
));
579 strlcpy(tempmfg
, "Unknown", sizeof(tempmfg
));
581 if ((tempptr
= strchr(tempmfg
, ' ')) != NULL
)
588 * Generate the device URI from the manufacturer, model, serial number,
589 * and interface number...
594 if (printer
->iface
> 0)
595 snprintf(options
, sizeof(options
), "?serial=%s&interface=%d", sern
,
598 snprintf(options
, sizeof(options
), "?serial=%s", sern
);
600 else if (printer
->iface
> 0)
601 snprintf(options
, sizeof(options
), "?interface=%d", printer
->iface
);
605 httpAssembleURIf(HTTP_URI_CODING_ALL
, uri
, uri_size
, "usb", NULL
, mfg
, 0,
606 "/%s%s", mdl
, options
);
608 cupsFreeOptions(num_values
, values
);
615 * 'open_device()' - Open a connection to the USB printer.
618 static int /* O - 0 on success, -1 on error */
619 open_device(usb_printer_t
*printer
, /* I - Printer */
620 int verbose
) /* I - Update connecting-to-device state? */
622 int number
; /* Configuration/interface/altset numbers */
626 * Return immediately if we are already connected...
633 * Try opening the printer...
636 if ((printer
->handle
= usb_open(printer
->device
)) == NULL
)
640 * Then set the desired configuration...
644 fputs("STATE: +connecting-to-device\n", stderr
);
646 number
= printer
->device
->config
[printer
->conf
].bConfigurationValue
;
648 if (usb_set_configuration(printer
->handle
, number
) < 0)
651 * If the set fails, chances are that the printer only supports a
652 * single configuration. Technically these printers don't conform to
653 * the USB printer specification, but otherwise they'll work...
657 fprintf(stderr
, "DEBUG: Failed to set configuration %d for %04x:%04x\n",
658 number
, printer
->device
->descriptor
.idVendor
,
659 printer
->device
->descriptor
.idProduct
);
663 * Claim interfaces as needed...
666 number
= printer
->device
->config
[printer
->conf
].interface
[printer
->iface
].
667 altsetting
[printer
->altset
].bInterfaceNumber
;
668 while (usb_claim_interface(printer
->handle
, number
) < 0)
671 fprintf(stderr
, "DEBUG: Failed to claim interface %d for %04x:%04x: %s\n",
672 number
, printer
->device
->descriptor
.idVendor
,
673 printer
->device
->descriptor
.idProduct
, strerror(errno
));
679 while (usb_claim_interface(printer
->handle
, 0) < 0)
682 fprintf(stderr
, "DEBUG: Failed to claim interface 0 for %04x:%04x: %s\n",
683 printer
->device
->descriptor
.idVendor
,
684 printer
->device
->descriptor
.idProduct
, strerror(errno
));
690 * Set alternate setting...
693 number
= printer
->device
->config
[printer
->conf
].interface
[printer
->iface
].
694 altsetting
[printer
->altset
].bAlternateSetting
;
695 while (usb_set_altinterface(printer
->handle
, number
) < 0)
699 "DEBUG: Failed to set alternate interface %d for %04x:%04x: %s\n",
700 number
, printer
->device
->descriptor
.idVendor
,
701 printer
->device
->descriptor
.idProduct
, strerror(errno
));
707 fputs("STATE: -connecting-to-device\n", stderr
);
712 * If we get here, there was a hard error...
718 fputs("STATE: -connecting-to-device\n", stderr
);
720 usb_close(printer
->handle
);
721 printer
->handle
= NULL
;
728 * 'print_cb()' - Find a USB printer for printing.
731 static int /* O - 0 to continue, 1 to stop (found) */
732 print_cb(usb_printer_t
*printer
, /* I - Printer */
733 const char *device_uri
, /* I - Device URI */
734 const char *device_id
, /* I - IEEE-1284 device ID */
735 const void *data
) /* I - User data (make, model, S/N) */
737 return (!strcmp((char *)data
, device_uri
));
742 * 'side_cb()' - Handle side-channel requests.
745 static ssize_t
/* O - Number of bytes written */
746 side_cb(usb_printer_t
*printer
, /* I - Printer */
747 int print_fd
) /* I - File to print */
749 ssize_t bytes
, /* Bytes read/written */
750 tbytes
; /* Total bytes written */
751 char buffer
[8192]; /* Print data buffer */
752 struct pollfd pfd
; /* Poll descriptor */
753 cups_sc_command_t command
; /* Request command */
754 cups_sc_status_t status
; /* Request/response status */
755 char data
[2048]; /* Request/response data */
756 int datalen
; /* Request/response data size */
760 datalen
= sizeof(data
);
762 if (cupsSideChannelRead(&command
, &status
, data
, &datalen
, 1.0))
767 case CUPS_SC_CMD_DRAIN_OUTPUT
:
771 while (poll(&pfd
, 1, 1000) > 0)
773 if ((bytes
= read(print_fd
, buffer
, sizeof(buffer
))) > 0)
775 while (usb_bulk_write(printer
->handle
, printer
->write_endp
, buffer
,
778 _cupsLangPrintf(stderr
,
779 _("ERROR: Unable to write %d bytes to printer\n"),
787 else if (bytes
< 0 && errno
!= EAGAIN
&& errno
!= EINTR
)
792 status
= CUPS_SC_STATUS_IO_ERROR
;
794 status
= CUPS_SC_STATUS_OK
;
799 case CUPS_SC_CMD_GET_BIDI
:
800 status
= CUPS_SC_STATUS_OK
;
801 data
[0] = 0; /* TODO: Change to 1 when read supported */
805 case CUPS_SC_CMD_GET_DEVICE_ID
:
806 if (get_device_id(printer
, data
, sizeof(data
)))
808 status
= CUPS_SC_STATUS_IO_ERROR
;
813 status
= CUPS_SC_STATUS_OK
;
814 datalen
= strlen(data
);
819 status
= CUPS_SC_STATUS_NOT_IMPLEMENTED
;
824 cupsSideChannelWrite(command
, status
, data
, datalen
, 1.0);