]> git.ipfire.org Git - thirdparty/cups.git/blame - backend/usb-libusb.c
Changelog.
[thirdparty/cups.git] / backend / usb-libusb.c
CommitLineData
bdb5a5c3 1/*
2 * "$Id$"
3 *
ec1bf980 4 * LIBUSB interface code for CUPS.
bdb5a5c3 5 *
5d86877b 6 * Copyright 2007-2013 by Apple Inc.
bdb5a5c3 7 *
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/".
13 *
14 * Contents:
15 *
779ec102 16 * list_devices() - List the available printers.
137fa46b 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.
2fa42ed2 25 * printer_class_soft_reset()' - Do the soft reset request specific to
26 * printers
27 * quirks() - Get the known quirks of a given printer model
137fa46b 28 * read_thread() - Thread to read the backchannel data on.
29 * sidechannel_thread() - Handle side-channel requests.
30 * soft_reset() - Send a soft reset to the device.
bdb5a5c3 31 */
32
33/*
34 * Include necessary headers...
35 */
36
ec1bf980 37#include <libusb.h>
2c7e4123 38#include <cups/cups-private.h>
137fa46b 39#include <pthread.h>
40#include <sys/select.h>
41#include <sys/types.h>
42#include <sys/stat.h>
43#include <sys/time.h>
44#include <unistd.h>
bdb5a5c3 45
46
ec1bf980 47/*
137fa46b 48 * WAIT_EOF_DELAY is number of seconds we'll wait for responses from
49 * the printer after we've finished sending all the data
ec1bf980 50 */
51
137fa46b 52#define WAIT_EOF 0
53#define WAIT_EOF_DELAY 7
54#define WAIT_SIDE_DELAY 3
55#define DEFAULT_TIMEOUT 5000L
ec1bf980 56
57
bdb5a5c3 58/*
59 * Local types...
60 */
61
62typedef struct usb_printer_s /**** USB Printer Data ****/
63{
ec1bf980 64 struct libusb_device *device; /* Device info */
bdb5a5c3 65 int conf, /* Configuration */
2fa42ed2 66 origconf, /* Original configuration */
bdb5a5c3 67 iface, /* Interface */
68 altset, /* Alternate setting */
69 write_endp, /* Write endpoint */
2fa42ed2 70 read_endp, /* Read endpoint */
137fa46b 71 protocol, /* Protocol: 1 = Uni-di, 2 = Bi-di. */
2fa42ed2 72 usblp_attached, /* "usblp" kernel module attached? */
8fa16503 73 reset_after_job; /* Set to 1 by print_device() */
2fa42ed2 74 unsigned int quirks; /* Quirks flags */
ec1bf980 75 struct libusb_device_handle *handle; /* Open handle to device */
bdb5a5c3 76} usb_printer_t;
77
a9800876 78typedef int (*usb_cb_t)(usb_printer_t *, const char *, const char *,
79 const void *);
bdb5a5c3 80
137fa46b 81typedef struct usb_globals_s
82{
83 usb_printer_t *printer; /* Printer */
84
85 pthread_mutex_t read_thread_mutex;
86 pthread_cond_t read_thread_cond;
87 int read_thread_stop;
88 int read_thread_done;
89
90 pthread_mutex_t readwrite_lock_mutex;
91 pthread_cond_t readwrite_lock_cond;
92 int readwrite_lock;
93
94 int print_fd; /* File descriptor to print */
95 ssize_t print_bytes; /* Print bytes read */
96
97 int wait_eof;
98 int drain_output; /* Drain all pending output */
99 int bidi_flag; /* 0=unidirectional, 1=bidirectional */
100
101 pthread_mutex_t sidechannel_thread_mutex;
102 pthread_cond_t sidechannel_thread_cond;
103 int sidechannel_thread_stop;
104 int sidechannel_thread_done;
105} usb_globals_t;
106
2fa42ed2 107/*
108 * Quirks: various printer quirks are handled by this table & its flags.
109 *
110 * This is copied from the usblp kernel module. So we can easily copy and paste
111 * new quirks from the module.
112 */
113
114struct quirk_printer_struct {
115 int vendorId;
116 int productId;
117 unsigned int quirks;
118};
119
120#define USBLP_QUIRK_BIDIR 0x1 /* reports bidir but requires
121 unidirectional mode (no INs/reads) */
122#define USBLP_QUIRK_USB_INIT 0x2 /* needs vendor USB init string */
123#define USBLP_QUIRK_BAD_CLASS 0x4 /* descriptor uses vendor-specific
124 Class or SubClass */
cff2b915 125#define USBLP_QUIRK_BLACKLIST 0x8 /* these printers do not conform to the USB print spec */
8fa16503 126#define USBLP_QUIRK_RESET 0x4000 /* After printing do a reset
127 for clean-up */
2fa42ed2 128#define USBLP_QUIRK_NO_REATTACH 0x8000 /* After printing we cannot re-attach
129 the usblp kernel module */
130
131static const struct quirk_printer_struct quirk_printers[] = {
132 { 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */
133 { 0x03f0, 0x0104, USBLP_QUIRK_BIDIR }, /* HP DeskJet 880C */
134 { 0x03f0, 0x0204, USBLP_QUIRK_BIDIR }, /* HP DeskJet 815C */
135 { 0x03f0, 0x0304, USBLP_QUIRK_BIDIR }, /* HP DeskJet 810C/812C */
136 { 0x03f0, 0x0404, USBLP_QUIRK_BIDIR }, /* HP DeskJet 830C */
137 { 0x03f0, 0x0504, USBLP_QUIRK_BIDIR }, /* HP DeskJet 885C */
138 { 0x03f0, 0x0604, USBLP_QUIRK_BIDIR }, /* HP DeskJet 840C */
139 { 0x03f0, 0x0804, USBLP_QUIRK_BIDIR }, /* HP DeskJet 816C */
140 { 0x03f0, 0x1104, USBLP_QUIRK_BIDIR }, /* HP Deskjet 959C */
141 { 0x0409, 0xefbe, USBLP_QUIRK_BIDIR }, /* NEC Picty900 (HP OEM) */
142 { 0x0409, 0xbef4, USBLP_QUIRK_BIDIR }, /* NEC Picty760 (HP OEM) */
143 { 0x0409, 0xf0be, USBLP_QUIRK_BIDIR }, /* NEC Picty920 (HP OEM) */
144 { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
610d39e0 145 { 0x043d, 0x00f3, USBLP_QUIRK_NO_REATTACH }, /* Lexmark International,
146 Inc. (e250d), https://bugs.launchpad.net/bugs/1084164 */
2fa42ed2 147 { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820,
148 by zut <kernel@zut.de> */
610d39e0 149 { 0x04a9, 0x1095, USBLP_QUIRK_BIDIR }, /* Canon, Inc. PIXMA iP6000D
150 Printer, https://bugs.launchpad.net/bugs/1160638 */
8fa16503 151 { 0x04a9, 0x10a2, USBLP_QUIRK_BIDIR }, /* Canon, Inc. PIXMA iP4200
152 Printer, http://www.cups.org/str.php?L4155 */
153 { 0x04a9, 0x10b6, USBLP_QUIRK_BIDIR }, /* Canon, Inc. PIXMA iP4300
154 Printer, https://bugs.launchpad.net/bugs/1032385 */
98e8b771 155 { 0x04a9, 0x1721, USBLP_QUIRK_BIDIR }, /* Canon, Inc. MP210
156 https://bugzilla.redhat.com/show_bug.cgi?id=847923#c53 */
a90b57c7 157 { 0x04a9, 0x170c, USBLP_QUIRK_BIDIR }, /* Canon, Inc. MP500
158 Printer, https://bugs.launchpad.net/bugs/1032456 */
159 { 0x04a9, 0x1717, USBLP_QUIRK_BIDIR }, /* Canon, Inc. MP510
160 Printer, https://bugs.launchpad.net/bugs/1050009 */
161 { 0x04a9, 0x173d, USBLP_QUIRK_BIDIR }, /* Canon, Inc. MP550
162 Printer, http://www.cups.org/str.php?L4155 */
163 { 0x04a9, 0x173e, USBLP_QUIRK_BIDIR }, /* Canon, Inc. MP560
164 Printer, http://www.cups.org/str.php?L4155 */
610d39e0 165 { 0x04a9, 0x26a3, USBLP_QUIRK_NO_REATTACH }, /* Canon, Inc. MF4150
166 Printer, https://bugs.launchpad.net/bugs/1160638 */
a90b57c7 167 { 0x04f9, 0x001a, USBLP_QUIRK_NO_REATTACH }, /* Brother Industries, Ltd
168 HL-1430 Laser Printer,
169 https://bugs.launchpad.net/bugs/1038695 */
2fa42ed2 170 { 0x04f9, 0x000d, USBLP_QUIRK_BIDIR |
171 USBLP_QUIRK_NO_REATTACH }, /* Brother Industries, Ltd
a90b57c7 172 HL-1440 Laser Printer,
173 https://bugs.launchpad.net/bugs/1000253 */
610d39e0 174 { 0x04f9, 0x000e, USBLP_QUIRK_BIDIR |
175 USBLP_QUIRK_NO_REATTACH }, /* Brother Industries, Ltd
176 HL-1450 Laser Printer,
177 https://bugs.launchpad.net/bugs/1000253 */
a90b57c7 178 { 0x06bc, 0x000b, USBLP_QUIRK_NO_REATTACH }, /* Oki Data Corp.
179 Okipage 14ex Printer,
180 https://bugs.launchpad.net/bugs/872483 */
181 { 0x06bc, 0x01c7, USBLP_QUIRK_NO_REATTACH }, /* Oki Data Corp. B410d,
182 https://bugs.launchpad.net/bugs/872483 */
610d39e0 183 { 0x04b8, 0x0001, USBLP_QUIRK_BIDIR |
184 USBLP_QUIRK_NO_REATTACH }, /* Seiko Epson Corp. Stylus Color 740 / Photo 750,
8d211539 185 http://bugs.debian.org/697970 */
610d39e0 186 { 0x04b8, 0x0005, USBLP_QUIRK_NO_REATTACH }, /* Seiko Epson Corp. Stylus Color 670,
187 https://bugs.launchpad.net/bugs/872483 */
2fa42ed2 188 { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt
189 Printer M129C */
190 { 0x067b, 0x2305, USBLP_QUIRK_BIDIR |
8fa16503 191 USBLP_QUIRK_NO_REATTACH |
192 USBLP_QUIRK_RESET },
610d39e0 193 /* Prolific Technology, Inc. PL2305 Parallel Port
194 (USB -> Parallel adapter), https://bugs.launchpad.net/bugs/987485 */
3fa69366 195 { 0x0924, 0x3ce9, USBLP_QUIRK_NO_REATTACH }, /* Xerox Phaser 3124
196 https://bugzilla.redhat.com/show_bug.cgi?id=867392 */
98e8b771 197 { 0x0924, 0x4293, USBLP_QUIRK_NO_REATTACH }, /* Xerox WorkCentre 3210
198 https://bugs.launchpad.net/bugs/1102470 */
610d39e0 199 { 0x1a86, 0x7584, USBLP_QUIRK_NO_REATTACH }, /* QinHeng Electronics
200 CH340S (USB -> Parallel adapter), https://bugs.launchpad.net/bugs/1000253 */
a90b57c7 201 { 0x04e8, 0x0000, USBLP_QUIRK_RESET }, /* All Samsung devices,
202 https://bugs.launchpad.net/bugs/1032456 */
203 { 0x0a5f, 0x0000, USBLP_QUIRK_BIDIR }, /* All Zebra devices,
204 https://bugs.launchpad.net/bugs/1001028 */
5d86877b 205 /* Canon */
206 { 0x04a9, 0x304a, USBLP_QUIRK_BLACKLIST }, /* Canon CP-10 */
207 { 0x04a9, 0x3063, USBLP_QUIRK_BLACKLIST }, /* Canon CP-100 */
208 { 0x04a9, 0x307c, USBLP_QUIRK_BLACKLIST }, /* Canon CP-200 */
209 { 0x04a9, 0x307d, USBLP_QUIRK_BLACKLIST }, /* Canon CP-300 */
210 { 0x04a9, 0x30bd, USBLP_QUIRK_BLACKLIST }, /* Canon CP-220 */
211 { 0x04a9, 0x30be, USBLP_QUIRK_BLACKLIST }, /* Canon CP-330 */
212 { 0x04a9, 0x30f6, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP400 */
213 { 0x04a9, 0x310b, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP600 */
214 { 0x04a9, 0x3127, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP710 */
215 { 0x04a9, 0x3128, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP510 */
216 { 0x04a9, 0x3141, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY ES1 */
217 { 0x04a9, 0x3142, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP730 */
218 { 0x04a9, 0x3143, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP720 */
219 { 0x04a9, 0x3170, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP750 */
220 { 0x04a9, 0x3171, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP740 */
221 { 0x04a9, 0x3185, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY ES2 */
222 { 0x04a9, 0x3186, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY ES20 */
223 { 0x04a9, 0x31aa, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP770 */
224 { 0x04a9, 0x31ab, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP760 */
225 { 0x04a9, 0x31b0, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY ES30 */
226 { 0x04a9, 0x31dd, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP780 */
227 { 0x04a9, 0x31ee, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY ES40 */
228 { 0x04a9, 0x3214, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP800 */
229 { 0x04a9, 0x3255, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP900 */
230 { 0x04a9, 0x3256, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP810 */
231 { 0x04a9, 0x30F5, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP500 */
232 { 0x04a9, 0x31AF, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY ES3 */
2904c202 233 { 0x04a9, 0x31DD, USBLP_QUIRK_BLACKLIST }, /* Canon SELPHY CP780 */
5d86877b 234 /* MISSING PIDs: CP520, CP530, CP790 */
2fa42ed2 235 { 0, 0 }
236};
237
137fa46b 238
239/*
240 * Globals...
241 */
242
243usb_globals_t g = { 0 }; /* Globals */
244libusb_device **list; /* List of connected USB devices */
245
bdb5a5c3 246
247/*
248 * Local functions...
249 */
250
251static int close_device(usb_printer_t *printer);
252static usb_printer_t *find_device(usb_cb_t cb, const void *data);
253static int get_device_id(usb_printer_t *printer, char *buffer,
254 size_t bufsize);
a9800876 255static int list_cb(usb_printer_t *printer, const char *device_uri,
256 const char *device_id, const void *data);
bdb5a5c3 257static char *make_device_uri(usb_printer_t *printer,
258 const char *device_id,
259 char *uri, size_t uri_size);
a9800876 260static int open_device(usb_printer_t *printer, int verbose);
261static int print_cb(usb_printer_t *printer, const char *device_uri,
262 const char *device_id, const void *data);
2fa42ed2 263static int printer_class_soft_reset(usb_printer_t *printer);
264static unsigned int quirks(int vendor, int product);
137fa46b 265static void *read_thread(void *reference);
266static void *sidechannel_thread(void *reference);
267static void soft_reset(void);
bdb5a5c3 268
269
270/*
271 * 'list_devices()' - List the available printers.
272 */
273
274void
275list_devices(void)
276{
277 fputs("DEBUG: list_devices\n", stderr);
278 find_device(list_cb, NULL);
279}
280
281
282/*
283 * 'print_device()' - Print a file to a USB device.
284 */
285
286int /* O - Exit status */
287print_device(const char *uri, /* I - Device URI */
288 const char *hostname, /* I - Hostname/manufacturer */
289 const char *resource, /* I - Resource/modelname */
290 char *options, /* I - Device options/serial number */
291 int print_fd, /* I - File descriptor to print */
292 int copies, /* I - Copies to print */
293 int argc, /* I - Number of command-line arguments (6 or 7) */
294 char *argv[]) /* I - Command-line arguments */
295{
137fa46b 296 int bytes; /* Bytes written */
297 ssize_t total_bytes; /* Total bytes written */
d11f579d 298 struct sigaction action; /* Actions for POSIX signals */
137fa46b 299 int status = CUPS_BACKEND_OK,
300 /* Function results */
301 iostatus; /* Current IO status */
302 pthread_t read_thread_id, /* Read thread */
303 sidechannel_thread_id; /* Side-channel thread */
2fa42ed2 304 int have_sidechannel = 0, /* Was the side-channel thread started? */
305 have_backchannel = 0; /* Do we have a back channel? */
137fa46b 306 struct stat sidechannel_info; /* Side-channel file descriptor info */
307 unsigned char print_buffer[8192], /* Print data buffer */
308 *print_ptr; /* Pointer into print data buffer */
309 fd_set input_set; /* Input set for select() */
310 int nfds; /* Number of file descriptors */
311 struct timeval *timeout, /* Timeout pointer */
312 tv; /* Time value */
313 struct timespec cond_timeout; /* pthread condition timeout */
2fa42ed2 314 int num_opts; /* Number of options */
315 cups_option_t *opts; /* Options */
316 const char *val; /* Option value */
137fa46b 317
a9800876 318
137fa46b 319 /*
320 * See if the side-channel descriptor is valid...
321 */
a9800876 322
137fa46b 323 have_sidechannel = !fstat(CUPS_SC_FD, &sidechannel_info) &&
324 S_ISSOCK(sidechannel_info.st_mode);
325
326 g.wait_eof = WAIT_EOF;
a9800876 327
d11f579d 328 /*
329 * Connect to the printer...
330 */
331
2fa42ed2 332 fprintf(stderr, "DEBUG: Printing on printer with URI: %s\n", uri);
137fa46b 333 while ((g.printer = find_device(print_cb, uri)) == NULL)
a9800876 334 {
2e3228ef 335 _cupsLangPrintFilter(stderr, "INFO",
bd2147fb 336 _("Waiting for printer to become available."));
a9800876 337 sleep(5);
338 }
339
137fa46b 340 g.print_fd = print_fd;
8fa16503 341
342 /*
343 * Some devices need a reset after finishing a job, these devices are
344 * marked with the USBLP_QUIRK_RESET quirk.
345 */
346 g.printer->reset_after_job = (g.printer->quirks & USBLP_QUIRK_RESET ? 1 : 0);
d11f579d 347
348 /*
349 * If we are printing data from a print driver on stdin, ignore SIGTERM
350 * so that the driver can finish out any page data, e.g. to eject the
351 * current page. We only do this for stdin printing as otherwise there
352 * is no way to cancel a raw print job...
353 */
354
355 if (!print_fd)
356 {
357 memset(&action, 0, sizeof(action));
358
359 sigemptyset(&action.sa_mask);
360 action.sa_handler = SIG_IGN;
361 sigaction(SIGTERM, &action, NULL);
362 }
363
137fa46b 364 /*
365 * Start the side channel thread if the descriptor is valid...
366 */
367
368 pthread_mutex_init(&g.readwrite_lock_mutex, NULL);
369 pthread_cond_init(&g.readwrite_lock_cond, NULL);
370 g.readwrite_lock = 1;
371
372 if (have_sidechannel)
373 {
374 g.sidechannel_thread_stop = 0;
375 g.sidechannel_thread_done = 0;
376
377 pthread_cond_init(&g.sidechannel_thread_cond, NULL);
378 pthread_mutex_init(&g.sidechannel_thread_mutex, NULL);
379
380 if (pthread_create(&sidechannel_thread_id, NULL, sidechannel_thread, NULL))
381 {
382 fprintf(stderr, "DEBUG: Fatal USB error.\n");
383 _cupsLangPrintFilter(stderr, "ERROR",
384 _("There was an unrecoverable USB error."));
385 fputs("DEBUG: Couldn't create side-channel thread.\n", stderr);
386 close_device(g.printer);
387 return (CUPS_BACKEND_STOP);
388 }
389 }
390
391 /*
2fa42ed2 392 * Debug mode: If option "usb-unidir" is given, always deactivate
393 * backchannel
137fa46b 394 */
395
2fa42ed2 396 num_opts = cupsParseOptions(argv[5], 0, &opts);
397 val = cupsGetOption("usb-unidir", num_opts, opts);
398 if (val && strcasecmp(val, "no") && strcasecmp(val, "off") &&
399 strcasecmp(val, "false"))
400 {
401 g.printer->read_endp = -1;
402 fprintf(stderr, "DEBUG: Forced uni-directional communication "
403 "via \"usb-unidir\" option.\n");
404 }
137fa46b 405
2fa42ed2 406 /*
407 * Debug mode: If option "usb-no-reattach" is given, do not re-attach
408 * the usblp kernel module after the job has completed.
409 */
137fa46b 410
2fa42ed2 411 val = cupsGetOption("usb-no-reattach", num_opts, opts);
412 if (val && strcasecmp(val, "no") && strcasecmp(val, "off") &&
413 strcasecmp(val, "false"))
137fa46b 414 {
2fa42ed2 415 g.printer->usblp_attached = 0;
416 fprintf(stderr, "DEBUG: Forced not re-attaching the usblp kernel module "
417 "after the job via \"usb-no-reattach\" option.\n");
137fa46b 418 }
419
2fa42ed2 420 /*
421 * Get the read thread going...
422 */
423
424 if (g.printer->read_endp != -1)
425 {
426 have_backchannel = 1;
427
428 g.read_thread_stop = 0;
429 g.read_thread_done = 0;
430
431 pthread_cond_init(&g.read_thread_cond, NULL);
432 pthread_mutex_init(&g.read_thread_mutex, NULL);
433
434 if (pthread_create(&read_thread_id, NULL, read_thread, NULL))
435 {
436 fprintf(stderr, "DEBUG: Fatal USB error.\n");
437 _cupsLangPrintFilter(stderr, "ERROR",
438 _("There was an unrecoverable USB error."));
439 fputs("DEBUG: Couldn't create read thread.\n", stderr);
440 close_device(g.printer);
441 return (CUPS_BACKEND_STOP);
442 }
443 }
444 else
445 fprintf(stderr, "DEBUG: Uni-directional device/mode, back channel "
446 "deactivated.\n");
447
137fa46b 448 /*
449 * The main thread sends the print file...
450 */
d11f579d 451
137fa46b 452 g.drain_output = 0;
453 g.print_bytes = 0;
454 total_bytes = 0;
455 print_ptr = print_buffer;
4828c388 456
137fa46b 457 while (status == CUPS_BACKEND_OK && copies-- > 0)
d11f579d 458 {
137fa46b 459 _cupsLangPrintFilter(stderr, "INFO", _("Sending data to printer."));
d11f579d 460
137fa46b 461 if (print_fd != STDIN_FILENO)
d11f579d 462 {
463 fputs("PAGE: 1 1\n", stderr);
464 lseek(print_fd, 0, SEEK_SET);
465 }
466
137fa46b 467 while (status == CUPS_BACKEND_OK)
d11f579d 468 {
137fa46b 469 FD_ZERO(&input_set);
470
471 if (!g.print_bytes)
472 FD_SET(print_fd, &input_set);
473
1ac626aa 474 /*
137fa46b 475 * Calculate select timeout...
476 * If we have data waiting to send timeout is 100ms.
477 * else if we're draining print_fd timeout is 0.
478 * else we're waiting forever...
1ac626aa 479 */
480
137fa46b 481 if (g.print_bytes)
482 {
483 tv.tv_sec = 0;
484 tv.tv_usec = 100000; /* 100ms */
485 timeout = &tv;
486 }
487 else if (g.drain_output)
488 {
489 tv.tv_sec = 0;
490 tv.tv_usec = 0;
491 timeout = &tv;
492 }
493 else
494 timeout = NULL;
495
496 /*
497 * I/O is unlocked around select...
498 */
499
500 pthread_mutex_lock(&g.readwrite_lock_mutex);
501 g.readwrite_lock = 0;
502 pthread_cond_signal(&g.readwrite_lock_cond);
503 pthread_mutex_unlock(&g.readwrite_lock_mutex);
504
505 nfds = select(print_fd + 1, &input_set, NULL, NULL, timeout);
506
507 /*
508 * Reacquire the lock...
509 */
510
511 pthread_mutex_lock(&g.readwrite_lock_mutex);
512 while (g.readwrite_lock)
513 pthread_cond_wait(&g.readwrite_lock_cond, &g.readwrite_lock_mutex);
514 g.readwrite_lock = 1;
515 pthread_mutex_unlock(&g.readwrite_lock_mutex);
516
517 if (nfds < 0)
d11f579d 518 {
137fa46b 519 if (errno == EINTR && total_bytes == 0)
4828c388 520 {
137fa46b 521 fputs("DEBUG: Received an interrupt before any bytes were "
522 "written, aborting.\n", stderr);
523 close_device(g.printer);
524 return (CUPS_BACKEND_OK);
525 }
526 else if (errno != EAGAIN && errno != EINTR)
527 {
528 _cupsLangPrintFilter(stderr, "ERROR",
529 _("Unable to read print data."));
530 perror("DEBUG: select");
531 close_device(g.printer);
532 return (CUPS_BACKEND_FAILED);
533 }
534 }
535
536 /*
537 * If drain output has finished send a response...
538 */
539
540 if (g.drain_output && !nfds && !g.print_bytes)
541 {
542 /* Send a response... */
543 cupsSideChannelWrite(CUPS_SC_CMD_DRAIN_OUTPUT, CUPS_SC_STATUS_OK, NULL, 0, 1.0);
544 g.drain_output = 0;
545 }
546
547 /*
548 * Check if we have print data ready...
549 */
550
551 if (FD_ISSET(print_fd, &input_set))
552 {
553 g.print_bytes = read(print_fd, print_buffer, sizeof(print_buffer));
554
555 if (g.print_bytes < 0)
556 {
557 /*
558 * Read error - bail if we don't see EAGAIN or EINTR...
559 */
560
561 if (errno != EAGAIN && errno != EINTR)
4828c388 562 {
2e3228ef 563 _cupsLangPrintFilter(stderr, "ERROR",
137fa46b 564 _("Unable to read print data."));
565 perror("DEBUG: read");
566 close_device(g.printer);
567 return (CUPS_BACKEND_FAILED);
4828c388 568 }
569
137fa46b 570 g.print_bytes = 0;
4828c388 571 }
137fa46b 572 else if (g.print_bytes == 0)
573 {
574 /*
575 * End of file, break out of the loop...
576 */
577
4828c388 578 break;
137fa46b 579 }
580
581 print_ptr = print_buffer;
582
583 fprintf(stderr, "DEBUG: Read %d bytes of print data...\n",
584 (int)g.print_bytes);
d11f579d 585 }
586
137fa46b 587 if (g.print_bytes)
588 {
589 iostatus = libusb_bulk_transfer(g.printer->handle,
590 g.printer->write_endp,
591 print_buffer, g.print_bytes,
592 &bytes, 60000);
593 /*
594 * Ignore timeout errors, but retain the number of bytes written to
595 * avoid sending duplicate data...
596 */
597
598 if (iostatus == LIBUSB_ERROR_TIMEOUT)
599 {
600 fputs("DEBUG: Got USB transaction timeout during write.\n", stderr);
601 iostatus = 0;
602 }
603
604 /*
605 * If we've stalled, retry the write...
606 */
607
608 else if (iostatus == LIBUSB_ERROR_PIPE)
609 {
610 fputs("DEBUG: Got USB pipe stalled during write.\n", stderr);
611
612 iostatus = libusb_bulk_transfer(g.printer->handle,
613 g.printer->write_endp,
614 print_buffer, g.print_bytes,
615 &bytes, 60000);
616 }
617
618 /*
619 * Retry a write after an aborted write since we probably just got
620 * SIGTERM...
621 */
622
623 else if (iostatus == LIBUSB_ERROR_INTERRUPTED)
624 {
625 fputs("DEBUG: Got USB return aborted during write.\n", stderr);
626
627 iostatus = libusb_bulk_transfer(g.printer->handle,
628 g.printer->write_endp,
629 print_buffer, g.print_bytes,
630 &bytes, 60000);
631 }
632
633 if (iostatus)
634 {
635 /*
636 * Write error - bail if we don't see an error we can retry...
637 */
638
639 _cupsLangPrintFilter(stderr, "ERROR",
640 _("Unable to send data to printer."));
641 fprintf(stderr, "DEBUG: libusb write operation returned %x.\n",
642 iostatus);
643
644 status = CUPS_BACKEND_FAILED;
645 break;
646 }
647 else if (bytes > 0)
648 {
649 fprintf(stderr, "DEBUG: Wrote %d bytes of print data...\n",
650 (int)bytes);
651
652 g.print_bytes -= bytes;
653 print_ptr += bytes;
654 total_bytes += bytes;
655 }
656 }
657
658 if (print_fd != 0 && status == CUPS_BACKEND_OK)
659 fprintf(stderr, "DEBUG: Sending print file, " CUPS_LLFMT " bytes...\n",
660 CUPS_LLCAST total_bytes);
661 }
662 }
663
664 fprintf(stderr, "DEBUG: Sent " CUPS_LLFMT " bytes...\n",
665 CUPS_LLCAST total_bytes);
666
667 /*
668 * Signal the side channel thread to exit...
669 */
670
671 if (have_sidechannel)
672 {
673 close(CUPS_SC_FD);
674 pthread_mutex_lock(&g.readwrite_lock_mutex);
675 g.readwrite_lock = 0;
676 pthread_cond_signal(&g.readwrite_lock_cond);
677 pthread_mutex_unlock(&g.readwrite_lock_mutex);
678
679 g.sidechannel_thread_stop = 1;
680 pthread_mutex_lock(&g.sidechannel_thread_mutex);
681
682 if (!g.sidechannel_thread_done)
683 {
684 gettimeofday(&tv, NULL);
685 cond_timeout.tv_sec = tv.tv_sec + WAIT_SIDE_DELAY;
686 cond_timeout.tv_nsec = tv.tv_usec * 1000;
687
688 while (!g.sidechannel_thread_done)
689 {
690 if (pthread_cond_timedwait(&g.sidechannel_thread_cond,
691 &g.sidechannel_thread_mutex,
692 &cond_timeout) != 0)
693 break;
694 }
695 }
696
697 pthread_mutex_unlock(&g.sidechannel_thread_mutex);
698 }
699
700 /*
701 * Signal the read thread to exit then wait 7 seconds for it to complete...
702 */
703
2fa42ed2 704 if (have_backchannel)
137fa46b 705 {
2fa42ed2 706 g.read_thread_stop = 1;
137fa46b 707
2fa42ed2 708 pthread_mutex_lock(&g.read_thread_mutex);
25d7dad9 709
137fa46b 710 if (!g.read_thread_done)
711 {
2fa42ed2 712 fputs("DEBUG: Waiting for read thread to exit...\n", stderr);
137fa46b 713
714 gettimeofday(&tv, NULL);
2fa42ed2 715 cond_timeout.tv_sec = tv.tv_sec + WAIT_EOF_DELAY;
137fa46b 716 cond_timeout.tv_nsec = tv.tv_usec * 1000;
25d7dad9 717
137fa46b 718 while (!g.read_thread_done)
a806b4ec 719 {
137fa46b 720 if (pthread_cond_timedwait(&g.read_thread_cond, &g.read_thread_mutex,
721 &cond_timeout) != 0)
722 break;
a806b4ec 723 }
2fa42ed2 724
725 /*
726 * If it didn't exit abort the pending read and wait an additional
727 * second...
728 */
a674809b 729
2fa42ed2 730 if (!g.read_thread_done)
731 {
a674809b 732 fputs("DEBUG: Read thread still active, aborting the pending read...\n",
2fa42ed2 733 stderr);
734
735 g.wait_eof = 0;
736
737 gettimeofday(&tv, NULL);
738 cond_timeout.tv_sec = tv.tv_sec + 1;
739 cond_timeout.tv_nsec = tv.tv_usec * 1000;
a674809b 740
2fa42ed2 741 while (!g.read_thread_done)
742 {
743 if (pthread_cond_timedwait(&g.read_thread_cond, &g.read_thread_mutex,
744 &cond_timeout) != 0)
745 break;
746 }
747 }
d11f579d 748 }
d11f579d 749
2fa42ed2 750 pthread_mutex_unlock(&g.read_thread_mutex);
751 }
137fa46b 752
d11f579d 753 /*
137fa46b 754 * Close the connection and input file and general clean up...
d11f579d 755 */
756
137fa46b 757 close_device(g.printer);
a9800876 758
ec1bf980 759 /*
760 * Clean up ....
761 */
762
763 libusb_free_device_list(list, 1);
764 libusb_exit(NULL);
765
137fa46b 766 return (status);
bdb5a5c3 767}
768
769
770/*
771 * 'close_device()' - Close the connection to the USB printer.
772 */
773
774static int /* I - 0 on success, -1 on failure */
775close_device(usb_printer_t *printer) /* I - Printer */
776{
ec1bf980 777 struct libusb_device_descriptor devdesc;
778 /* Current device descriptor */
779 struct libusb_config_descriptor *confptr;
780 /* Pointer to current configuration */
781
137fa46b 782
bdb5a5c3 783 if (printer->handle)
784 {
b5565217 785 /*
786 * Release interfaces before closing so that we know all data is written
787 * to the device...
788 */
789
5adb84f8 790 int errcode; /* Return value of libusb function */
2fa42ed2 791 int number1, /* Interface number */
792 number2; /* Configuration number */
137fa46b 793
779ec102 794 errcode =
2fa42ed2 795 libusb_get_config_descriptor(printer->device, printer->conf, &confptr);
5adb84f8 796 if (errcode >= 0)
797 {
2fa42ed2 798 number1 = confptr->interface[printer->iface].
5adb84f8 799 altsetting[printer->altset].bInterfaceNumber;
2fa42ed2 800 libusb_release_interface(printer->handle, number1);
801
802 number2 = confptr->bConfigurationValue;
803
804 libusb_free_config_descriptor(confptr);
805
806 /*
807 * If we have changed the configuration from one valid configuration
808 * to another, restore the old one
809 */
810 if (printer->origconf > 0 && printer->origconf != number2)
811 {
a674809b 812 fprintf(stderr, "DEBUG: Restoring USB device configuration: %d -> %d\n",
2fa42ed2 813 number2, printer->origconf);
814 if ((errcode = libusb_set_configuration(printer->handle,
815 printer->origconf)) < 0)
816 {
817 if (errcode != LIBUSB_ERROR_BUSY)
818 {
819 errcode =
820 libusb_get_device_descriptor (printer->device, &devdesc);
821 if (errcode < 0)
822 fprintf(stderr,
823 "DEBUG: Failed to set configuration %d\n",
824 printer->origconf);
825 else
826 fprintf(stderr,
827 "DEBUG: Failed to set configuration %d for %04x:%04x\n",
828 printer->origconf, devdesc.idVendor, devdesc.idProduct);
829 }
830 }
831 }
ec1bf980 832
5adb84f8 833 /*
834 * Re-attach "usblp" kernel module if it was attached before using this
835 * device
836 */
837 if (printer->usblp_attached == 1)
2fa42ed2 838 if (libusb_attach_kernel_driver(printer->handle, number1) < 0)
5adb84f8 839 {
840 errcode = libusb_get_device_descriptor (printer->device, &devdesc);
841 if (errcode < 0)
842 fprintf(stderr,
843 "DEBUG: Failed to re-attach \"usblp\" kernel module\n");
844 else
845 fprintf(stderr,
846 "DEBUG: Failed to re-attach \"usblp\" kernel module to "
847 "%04x:%04x\n", devdesc.idVendor, devdesc.idProduct);
848 }
2fa42ed2 849 }
850 else
851 fprintf(stderr,
852 "DEBUG: Failed to get configuration descriptor %d\n",
853 printer->conf);
137fa46b 854
2fa42ed2 855 /*
856 * Reset the device to clean up after the job
857 */
858
8fa16503 859 if (printer->reset_after_job == 1)
2fa42ed2 860 {
861 if ((errcode = libusb_reset_device(printer->handle)) < 0)
862 fprintf(stderr,
863 "DEBUG: Device reset failed, error code: %d\n",
864 errcode);
865 else
866 fprintf(stderr,
867 "DEBUG: Resetting printer.\n");
137fa46b 868 }
ec1bf980 869
b5565217 870 /*
871 * Close the interface and return...
872 */
873
ec1bf980 874 libusb_close(printer->handle);
bdb5a5c3 875 printer->handle = NULL;
876 }
877
878 return (0);
879}
880
881
882/*
883 * 'find_device()' - Find or enumerate USB printers.
884 */
885
886static usb_printer_t * /* O - Found printer */
887find_device(usb_cb_t cb, /* I - Callback function */
888 const void *data) /* I - User data for callback */
889{
ec1bf980 890 libusb_device **list; /* List of connected USB devices */
891 libusb_device *device = NULL; /* Current device */
892 struct libusb_device_descriptor devdesc;
893 /* Current device descriptor */
894 struct libusb_config_descriptor *confptr = NULL;
895 /* Pointer to current configuration */
896 const struct libusb_interface *ifaceptr = NULL;
897 /* Pointer to current interface */
898 const struct libusb_interface_descriptor *altptr = NULL;
bdb5a5c3 899 /* Pointer to current alternate setting */
ec1bf980 900 const struct libusb_endpoint_descriptor *endpptr = NULL;
bdb5a5c3 901 /* Pointer to current endpoint */
ec1bf980 902 ssize_t numdevs, /* number of connected devices */
903 i = 0;
904 uint8_t conf, /* Current configuration */
bdb5a5c3 905 iface, /* Current interface */
906 altset, /* Current alternate setting */
907 protocol, /* Current protocol */
908 endp, /* Current endpoint */
909 read_endp, /* Current read endpoint */
910 write_endp; /* Current write endpoint */
a9800876 911 char device_id[1024],/* IEEE-1284 device ID */
912 device_uri[1024];
913 /* Device URI */
bdb5a5c3 914 static usb_printer_t printer; /* Current printer */
915
916
917 /*
918 * Initialize libusb...
919 */
920
ec1bf980 921 libusb_init(NULL);
922 numdevs = libusb_get_device_list(NULL, &list);
923 fprintf(stderr, "DEBUG: libusb_get_device_list=%d\n", (int)numdevs);
bdb5a5c3 924
925 /*
926 * Then loop through the devices it found...
927 */
928
ec1bf980 929 if (numdevs > 0)
930 for (i = 0; i < numdevs; i++)
bdb5a5c3 931 {
ec1bf980 932 device = list[i];
933
bdb5a5c3 934 /*
935 * Ignore devices with no configuration data and anything that is not
936 * a printer...
937 */
938
2fa42ed2 939 if (libusb_get_device_descriptor(device, &devdesc) < 0)
5adb84f8 940 continue;
ec1bf980 941
942 if (!devdesc.bNumConfigurations || !devdesc.idVendor ||
943 !devdesc.idProduct)
bdb5a5c3 944 continue;
945
5d86877b 946 printer.quirks = quirks(devdesc.idVendor, devdesc.idProduct);
947
948 /*
949 * Ignore blacklisted printers...
950 */
951
952 if (printer.quirks & USBLP_QUIRK_BLACKLIST)
953 continue;
2fa42ed2 954
ec1bf980 955 for (conf = 0; conf < devdesc.bNumConfigurations; conf ++)
956 {
25d7dad9 957 if (libusb_get_config_descriptor(device, conf, &confptr) < 0)
ec1bf980 958 continue;
bdb5a5c3 959 for (iface = 0, ifaceptr = confptr->interface;
960 iface < confptr->bNumInterfaces;
961 iface ++, ifaceptr ++)
962 {
963 /*
964 * Some printers offer multiple interfaces...
965 */
966
967 protocol = 0;
968
969 for (altset = 0, altptr = ifaceptr->altsetting;
970 altset < ifaceptr->num_altsetting;
971 altset ++, altptr ++)
972 {
973 /*
974 * Currently we only support unidirectional and bidirectional
975 * printers. Future versions of this code will support the
976 * 1284.4 (packet mode) protocol as well.
977 */
978
2fa42ed2 979 if (((altptr->bInterfaceClass != LIBUSB_CLASS_PRINTER ||
a674809b 980 altptr->bInterfaceSubClass != 1) &&
2fa42ed2 981 ((printer.quirks & USBLP_QUIRK_BAD_CLASS) == 0)) ||
bdb5a5c3 982 (altptr->bInterfaceProtocol != 1 && /* Unidirectional */
983 altptr->bInterfaceProtocol != 2) || /* Bidirectional */
984 altptr->bInterfaceProtocol < protocol)
985 continue;
986
2fa42ed2 987 if (printer.quirks & USBLP_QUIRK_BAD_CLASS)
988 fprintf(stderr, "DEBUG: Printer does not report class 7 and/or "
989 "subclass 1 but works as a printer anyway\n");
990
bdb5a5c3 991 read_endp = -1;
992 write_endp = -1;
993
994 for (endp = 0, endpptr = altptr->endpoint;
995 endp < altptr->bNumEndpoints;
996 endp ++, endpptr ++)
ec1bf980 997 if ((endpptr->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) ==
998 LIBUSB_TRANSFER_TYPE_BULK)
bdb5a5c3 999 {
ec1bf980 1000 if (endpptr->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
bdb5a5c3 1001 read_endp = endp;
1002 else
1003 write_endp = endp;
1004 }
1005
1006 if (write_endp >= 0)
1007 {
1008 /*
1009 * Save the best match so far...
1010 */
1011
1012 protocol = altptr->bInterfaceProtocol;
1013 printer.altset = altset;
1014 printer.write_endp = write_endp;
2fa42ed2 1015 if (protocol > 1)
1016 printer.read_endp = read_endp;
1017 else
1018 printer.read_endp = -1;
bdb5a5c3 1019 }
1020 }
1021
1022 if (protocol > 0)
1023 {
137fa46b 1024 printer.device = device;
1025 printer.conf = conf;
1026 printer.iface = iface;
1027 printer.protocol = protocol;
1028 printer.handle = NULL;
bdb5a5c3 1029
a9800876 1030 if (!open_device(&printer, data != NULL))
bdb5a5c3 1031 {
ec1bf980 1032 get_device_id(&printer, device_id, sizeof(device_id));
1033 make_device_uri(&printer, device_id, device_uri,
1034 sizeof(device_uri));
a9800876 1035
2fa42ed2 1036 fprintf(stderr, "DEBUG2: Printer found with device ID: %s "
1037 "Device URI: %s\n",
1038 device_id, device_uri);
1039
ec1bf980 1040 if ((*cb)(&printer, device_uri, device_id, data))
1041 {
2fa42ed2 1042 fprintf(stderr, "DEBUG: Device protocol: %d\n",
1043 printer.protocol);
1044 if (printer.quirks & USBLP_QUIRK_BIDIR)
1045 {
1046 printer.read_endp = -1;
1047 fprintf(stderr, "DEBUG: Printer reports bi-di support "
1048 "but in reality works only uni-directionally\n");
1049 }
1050 if (printer.read_endp != -1)
1051 {
1052 printer.read_endp = confptr->interface[printer.iface].
1053 altsetting[printer.altset].
1054 endpoint[printer.read_endp].
1055 bEndpointAddress;
1056 }
1057 else
a674809b 1058 fprintf(stderr, "DEBUG: Uni-directional USB communication "
2fa42ed2 1059 "only!\n");
ec1bf980 1060 printer.write_endp = confptr->interface[printer.iface].
4828c388 1061 altsetting[printer.altset].
1062 endpoint[printer.write_endp].
1063 bEndpointAddress;
2fa42ed2 1064 if (printer.quirks & USBLP_QUIRK_NO_REATTACH)
1065 {
1066 printer.usblp_attached = 0;
1067 fprintf(stderr, "DEBUG: Printer does not like usblp "
1068 "kernel module to be re-attached after job\n");
1069 }
1070 libusb_free_config_descriptor(confptr);
ec1bf980 1071 return (&printer);
a9800876 1072 }
bdb5a5c3 1073
1074 close_device(&printer);
1075 }
1076 }
1077 }
ec1bf980 1078 libusb_free_config_descriptor(confptr);
1079 }
bdb5a5c3 1080 }
1081
1082 /*
1083 * If we get this far without returning, then we haven't found a printer
1084 * to print to...
1085 */
1086
ec1bf980 1087 /*
1088 * Clean up ....
1089 */
1090
1091 libusb_free_device_list(list, 1);
1092 libusb_exit(NULL);
1093
bdb5a5c3 1094 return (NULL);
1095}
1096
1097
1098/*
1099 * 'get_device_id()' - Get the IEEE-1284 device ID for the printer.
1100 */
1101
1102static int /* O - 0 on success, -1 on error */
1103get_device_id(usb_printer_t *printer, /* I - Printer */
1104 char *buffer, /* I - String buffer */
1105 size_t bufsize) /* I - Number of bytes in buffer */
1106{
1107 int length; /* Length of device ID */
1108
1109
ec1bf980 1110 if (libusb_control_transfer(printer->handle,
1111 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_ENDPOINT_IN |
1112 LIBUSB_RECIPIENT_INTERFACE,
1113 0, printer->conf,
1114 (printer->iface << 8) | printer->altset,
1115 (unsigned char *)buffer, bufsize, 5000) < 0)
bdb5a5c3 1116 {
1117 *buffer = '\0';
1118 return (-1);
1119 }
1120
1121 /*
1122 * Extract the length of the device ID string from the first two
1123 * bytes. The 1284 spec says the length is stored MSB first...
1124 */
1125
b529ea47 1126 length = (((unsigned)buffer[0] & 255) << 8) |
bdb5a5c3 1127 ((unsigned)buffer[1] & 255);
1128
1129 /*
b529ea47 1130 * Check to see if the length is larger than our buffer or less than 14 bytes
1131 * (the minimum valid device ID is "MFG:x;MDL:y;" with 2 bytes for the length).
1132 *
1133 * If the length is out-of-range, assume that the vendor incorrectly
1134 * implemented the 1284 spec and re-read the length as LSB first,..
bdb5a5c3 1135 */
1136
b529ea47 1137 if (length > bufsize || length < 14)
1138 length = (((unsigned)buffer[1] & 255) << 8) |
bdb5a5c3 1139 ((unsigned)buffer[0] & 255);
1140
b379a395 1141 if (length > bufsize)
1142 length = bufsize;
1143
b529ea47 1144 if (length < 14)
1145 {
1146 /*
1147 * Invalid device ID, clear it!
1148 */
1149
1150 *buffer = '\0';
1151 return (-1);
1152 }
1153
b379a395 1154 length -= 2;
bdb5a5c3 1155
1156 /*
1157 * Copy the device ID text to the beginning of the buffer and
1158 * nul-terminate.
1159 */
1160
1161 memmove(buffer, buffer + 2, length);
1162 buffer[length] = '\0';
1163
1164 return (0);
1165}
1166
1167
1168/*
1169 * 'list_cb()' - List USB printers for discovery.
1170 */
1171
1172static int /* O - 0 to continue, 1 to stop */
1173list_cb(usb_printer_t *printer, /* I - Printer */
a9800876 1174 const char *device_uri, /* I - Device URI */
bdb5a5c3 1175 const char *device_id, /* I - IEEE-1284 device ID */
1176 const void *data) /* I - User data (not used) */
1177{
a9800876 1178 char make_model[1024]; /* Make and model */
bdb5a5c3 1179
1180
1181 /*
1182 * Get the device URI and make/model strings...
1183 */
1184
ec1bf980 1185 if (backendGetMakeModel(device_id, make_model, sizeof(make_model)))
1186 strlcpy(make_model, "Unknown", sizeof(make_model));
bdb5a5c3 1187
1188 /*
1189 * Report the printer...
1190 */
1191
2317ac1e 1192 cupsBackendReport("direct", device_uri, make_model, make_model, device_id,
1193 NULL);
bdb5a5c3 1194
1195 /*
1196 * Keep going...
1197 */
1198
1199 return (0);
1200}
1201
1202
1203/*
1204 * 'make_device_uri()' - Create a device URI for a USB printer.
1205 */
1206
1207static char * /* O - Device URI */
1208make_device_uri(
1209 usb_printer_t *printer, /* I - Printer */
1210 const char *device_id, /* I - IEEE-1284 device ID */
1211 char *uri, /* I - Device URI buffer */
1212 size_t uri_size) /* I - Size of device URI buffer */
1213{
ec1bf980 1214 struct libusb_device_descriptor devdesc;
1215 /* Current device descriptor */
bdb5a5c3 1216 char options[1024]; /* Device URI options */
1217 int num_values; /* Number of 1284 parameters */
1218 cups_option_t *values; /* 1284 parameters */
1219 const char *mfg, /* Manufacturer */
1220 *mdl, /* Model */
ec1bf980 1221 *des = NULL, /* Description */
bdb5a5c3 1222 *sern; /* Serial number */
e12eaada 1223 size_t mfglen; /* Length of manufacturer string */
a9800876 1224 char tempmfg[256], /* Temporary manufacturer string */
1225 tempsern[256], /* Temporary serial number string */
bdb5a5c3 1226 *tempptr; /* Pointer into temp string */
1227
1228
1229 /*
1230 * Get the make, model, and serial numbers...
1231 */
1232
2256cc12 1233 num_values = _cupsGet1284Values(device_id, &values);
bdb5a5c3 1234
1235 if ((sern = cupsGetOption("SERIALNUMBER", num_values, values)) == NULL)
1236 if ((sern = cupsGetOption("SERN", num_values, values)) == NULL)
a10c87db 1237 if ((sern = cupsGetOption("SN", num_values, values)) == NULL &&
25d7dad9 1238 ((libusb_get_device_descriptor(printer->device, &devdesc) >= 0) &&
ec1bf980 1239 devdesc.iSerialNumber))
a9800876 1240 {
1241 /*
1242 * Try getting the serial number from the device itself...
1243 */
1244
ec1bf980 1245 int length =
1246 libusb_get_string_descriptor_ascii(printer->handle,
1247 devdesc.iSerialNumber,
1248 (unsigned char *)tempsern,
1249 sizeof(tempsern) - 1);
a9800876 1250 if (length > 0)
1251 {
1252 tempsern[length] = '\0';
1253 sern = tempsern;
1254 }
1255 }
bdb5a5c3 1256
1257 if ((mfg = cupsGetOption("MANUFACTURER", num_values, values)) == NULL)
1258 mfg = cupsGetOption("MFG", num_values, values);
1259
1260 if ((mdl = cupsGetOption("MODEL", num_values, values)) == NULL)
1261 mdl = cupsGetOption("MDL", num_values, values);
1262
a9800876 1263 /*
1264 * To maintain compatibility with the original character device backend on
1265 * Linux and *BSD, map manufacturer names...
1266 */
1267
bdb5a5c3 1268 if (mfg)
1269 {
c6fab96f 1270 if (!_cups_strcasecmp(mfg, "Hewlett-Packard"))
bdb5a5c3 1271 mfg = "HP";
c6fab96f 1272 else if (!_cups_strcasecmp(mfg, "Lexmark International"))
bdb5a5c3 1273 mfg = "Lexmark";
1274 }
1275 else
1276 {
1277 /*
1278 * No manufacturer? Use the model string or description...
1279 */
1280
1281 if (mdl)
a9800876 1282 _ppdNormalizeMakeAndModel(mdl, tempmfg, sizeof(tempmfg));
bdb5a5c3 1283 else if ((des = cupsGetOption("DESCRIPTION", num_values, values)) != NULL ||
1284 (des = cupsGetOption("DES", num_values, values)) != NULL)
a9800876 1285 _ppdNormalizeMakeAndModel(des, tempmfg, sizeof(tempmfg));
bdb5a5c3 1286 else
a9800876 1287 strlcpy(tempmfg, "Unknown", sizeof(tempmfg));
bdb5a5c3 1288
a9800876 1289 if ((tempptr = strchr(tempmfg, ' ')) != NULL)
bdb5a5c3 1290 *tempptr = '\0';
1291
a9800876 1292 mfg = tempmfg;
bdb5a5c3 1293 }
1294
ec1bf980 1295 if (!mdl)
1296 {
1297 /*
1298 * No model? Use description...
1299 */
1300 if (des)
1301 mdl = des; /* We remove the manufacturer name below */
1302 else if (!strncasecmp(mfg, "Unknown", 7))
1303 mdl = "Printer";
1304 else
1305 mdl = "Unknown Model";
1306 }
1307
e12eaada 1308 mfglen = strlen(mfg);
1309
1310 if (!strncasecmp(mdl, mfg, mfglen) && _cups_isspace(mdl[mfglen]))
1311 {
1312 mdl += mfglen + 1;
1313
1314 while (_cups_isspace(*mdl))
1315 mdl ++;
1316 }
1317
bdb5a5c3 1318 /*
1319 * Generate the device URI from the manufacturer, model, serial number,
1320 * and interface number...
1321 */
1322
1323 if (sern)
1324 {
1325 if (printer->iface > 0)
1326 snprintf(options, sizeof(options), "?serial=%s&interface=%d", sern,
1327 printer->iface);
1328 else
1329 snprintf(options, sizeof(options), "?serial=%s", sern);
1330 }
1331 else if (printer->iface > 0)
1332 snprintf(options, sizeof(options), "?interface=%d", printer->iface);
1333 else
1334 options[0] = '\0';
1335
1336 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, uri_size, "usb", NULL, mfg, 0,
1337 "/%s%s", mdl, options);
1338
1339 cupsFreeOptions(num_values, values);
1340
1341 return (uri);
1342}
1343
1344
1345/*
1346 * 'open_device()' - Open a connection to the USB printer.
1347 */
1348
1349static int /* O - 0 on success, -1 on error */
a9800876 1350open_device(usb_printer_t *printer, /* I - Printer */
1351 int verbose) /* I - Update connecting-to-device state? */
bdb5a5c3 1352{
ec1bf980 1353 struct libusb_device_descriptor devdesc;
137fa46b 1354 /* Current device descriptor */
ec1bf980 1355 struct libusb_config_descriptor *confptr = NULL;
137fa46b 1356 /* Pointer to current configuration */
ec1bf980 1357 int number1 = -1, /* Configuration/interface/altset */
137fa46b 1358 number2 = -1, /* numbers */
1359 errcode = 0;
b529ea47 1360 char current; /* Current configuration */
bdb5a5c3 1361
1362
1363 /*
1364 * Return immediately if we are already connected...
1365 */
1366
1367 if (printer->handle)
1368 return (0);
1369
1370 /*
1371 * Try opening the printer...
1372 */
1373
2fa42ed2 1374 if ((errcode = libusb_open(printer->device, &printer->handle)) < 0)
1375 {
1376 fprintf(stderr, "DEBUG: Failed to open device, code: %d\n",
1377 errcode);
bdb5a5c3 1378 return (-1);
2fa42ed2 1379 }
bdb5a5c3 1380
e1007334 1381 printer->usblp_attached = 0;
8fa16503 1382 printer->reset_after_job = 0;
e1007334 1383
b529ea47 1384 if (verbose)
1385 fputs("STATE: +connecting-to-device\n", stderr);
1386
2fa42ed2 1387 if ((errcode = libusb_get_device_descriptor(printer->device, &devdesc)) < 0)
e1007334 1388 {
1389 fprintf(stderr, "DEBUG: Failed to get device descriptor, code: %d\n",
1390 errcode);
1391 goto error;
1392 }
1393
1394 /*
1395 * Get the "usblp" kernel module out of the way. This backend only
1396 * works without the module attached.
1397 */
1398
1399 errcode = libusb_kernel_driver_active(printer->handle, printer->iface);
1400 if (errcode == 0)
1401 printer->usblp_attached = 0;
1402 else if (errcode == 1)
1403 {
1404 printer->usblp_attached = 1;
1405 if ((errcode =
1406 libusb_detach_kernel_driver(printer->handle, printer->iface)) < 0)
1407 {
1408 fprintf(stderr, "DEBUG: Failed to detach \"usblp\" module from %04x:%04x\n",
1409 devdesc.idVendor, devdesc.idProduct);
1410 goto error;
1411 }
1412 }
1413 else
1414 {
1415 printer->usblp_attached = 0;
2fa42ed2 1416 fprintf(stderr, "DEBUG: Failed to check whether %04x:%04x has the \"usblp\" kernel module attached\n",
1417 devdesc.idVendor, devdesc.idProduct);
1418 goto error;
e1007334 1419 }
1420
bdb5a5c3 1421 /*
b529ea47 1422 * Set the desired configuration, but only if it needs changing. Some
137fa46b 1423 * printers (e.g., Samsung) don't like libusb_set_configuration. It will
ec1bf980 1424 * succeed, but the following print job is sometimes silently lost by the
1425 * printer.
bdb5a5c3 1426 */
1427
ec1bf980 1428 if (libusb_control_transfer(printer->handle,
137fa46b 1429 LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_ENDPOINT_IN |
1430 LIBUSB_RECIPIENT_DEVICE,
1431 8, /* GET_CONFIGURATION */
1432 0, 0, (unsigned char *)&current, 1, 5000) < 0)
1433 current = 0; /* Assume not configured */
1434
2fa42ed2 1435 printer->origconf = current;
1436
a674809b 1437 if ((errcode =
5adb84f8 1438 libusb_get_config_descriptor (printer->device, printer->conf, &confptr))
1439 < 0)
1440 {
1441 fprintf(stderr, "DEBUG: Failed to get config descriptor for %04x:%04x\n",
1442 devdesc.idVendor, devdesc.idProduct);
1443 goto error;
1444 }
ec1bf980 1445 number1 = confptr->bConfigurationValue;
1446
1447 if (number1 != current)
bdb5a5c3 1448 {
a674809b 1449 fprintf(stderr, "DEBUG: Switching USB device configuration: %d -> %d\n",
2fa42ed2 1450 current, number1);
ec1bf980 1451 if ((errcode = libusb_set_configuration(printer->handle, number1)) < 0)
b529ea47 1452 {
1453 /*
1454 * If the set fails, chances are that the printer only supports a
1455 * single configuration. Technically these printers don't conform to
1456 * the USB printer specification, but otherwise they'll work...
1457 */
7e734dcc 1458
ec1bf980 1459 if (errcode != LIBUSB_ERROR_BUSY)
b529ea47 1460 fprintf(stderr, "DEBUG: Failed to set configuration %d for %04x:%04x\n",
137fa46b 1461 number1, devdesc.idVendor, devdesc.idProduct);
b529ea47 1462 }
bdb5a5c3 1463 }
1464
ec1bf980 1465 /*
1466 * Claim interfaces as needed...
1467 */
1468
1469 number1 = confptr->interface[printer->iface].
137fa46b 1470 altsetting[printer->altset].bInterfaceNumber;
ec1bf980 1471
1472 while ((errcode = libusb_claim_interface(printer->handle, number1)) < 0)
1473 {
1474 if (errcode != LIBUSB_ERROR_BUSY)
e1007334 1475 {
137fa46b 1476 fprintf(stderr,
1477 "DEBUG: Failed to claim interface %d for %04x:%04x: %s\n",
ec1bf980 1478 number1, devdesc.idVendor, devdesc.idProduct, strerror(errno));
bdb5a5c3 1479
e1007334 1480 goto error;
1481 }
bdb5a5c3 1482 }
1483
bdb5a5c3 1484 /*
137fa46b 1485 * Set alternate setting, but only if there is more than one option. Some
1486 * printers (e.g., Samsung) don't like usb_set_altinterface.
bdb5a5c3 1487 */
1488
ec1bf980 1489 if (confptr->interface[printer->iface].num_altsetting > 1)
bdb5a5c3 1490 {
ec1bf980 1491 number1 = confptr->interface[printer->iface].
137fa46b 1492 altsetting[printer->altset].bInterfaceNumber;
ec1bf980 1493 number2 = confptr->interface[printer->iface].
137fa46b 1494 altsetting[printer->altset].bAlternateSetting;
bdb5a5c3 1495
137fa46b 1496 while ((errcode =
1497 libusb_set_interface_alt_setting(printer->handle, number1, number2))
1498 < 0)
b529ea47 1499 {
ec1bf980 1500 if (errcode != LIBUSB_ERROR_BUSY)
e1007334 1501 {
b529ea47 1502 fprintf(stderr,
1503 "DEBUG: Failed to set alternate interface %d for %04x:%04x: "
137fa46b 1504 "%s\n",
1505 number2, devdesc.idVendor, devdesc.idProduct, strerror(errno));
b529ea47 1506
e1007334 1507 goto error;
1508 }
b529ea47 1509 }
bdb5a5c3 1510 }
137fa46b 1511
ec1bf980 1512 libusb_free_config_descriptor(confptr);
bdb5a5c3 1513
a9800876 1514 if (verbose)
1515 fputs("STATE: -connecting-to-device\n", stderr);
bdb5a5c3 1516
1517 return (0);
1518
1519 /*
1520 * If we get here, there was a hard error...
1521 */
1522
1523 error:
1524
a9800876 1525 if (verbose)
1526 fputs("STATE: -connecting-to-device\n", stderr);
bdb5a5c3 1527
ec1bf980 1528 libusb_close(printer->handle);
bdb5a5c3 1529 printer->handle = NULL;
a9800876 1530
bdb5a5c3 1531 return (-1);
1532}
1533
1534
1535/*
1536 * 'print_cb()' - Find a USB printer for printing.
1537 */
1538
1539static int /* O - 0 to continue, 1 to stop (found) */
1540print_cb(usb_printer_t *printer, /* I - Printer */
a9800876 1541 const char *device_uri, /* I - Device URI */
bdb5a5c3 1542 const char *device_id, /* I - IEEE-1284 device ID */
1543 const void *data) /* I - User data (make, model, S/N) */
1544{
e12eaada 1545 char requested_uri[1024], /* Requested URI */
1546 *requested_ptr, /* Pointer into requested URI */
1547 detected_uri[1024], /* Detected URI */
1548 *detected_ptr; /* Pointer into detected URI */
1549
1550
1551 /*
1552 * If we have an exact match, stop now...
1553 */
1554
1555 if (!strcmp((char *)data, device_uri))
1556 return (1);
1557
1558 /*
1559 * Work on copies of the URIs...
1560 */
1561
1562 strlcpy(requested_uri, (char *)data, sizeof(requested_uri));
1563 strlcpy(detected_uri, device_uri, sizeof(detected_uri));
1564
1565 /*
1566 * libusb-discovered URIs can have an "interface" specification and this
1567 * never happens for usblp-discovered URIs, so remove the "interface"
1568 * specification from the URI which we are checking currently. This way a
1569 * queue for a usblp-discovered printer can now be accessed via libusb.
1570 *
1571 * Similarly, strip "?serial=NNN...NNN" as needed.
1572 */
1573
b92232ef 1574 if ((requested_ptr = strstr(requested_uri, "?interface=")) == NULL)
1575 requested_ptr = strstr(requested_uri, "&interface=");
1576 if ((detected_ptr = strstr(detected_uri, "?interface=")) == NULL)
1577 detected_ptr = strstr(detected_uri, "&interface=");
1578
1579 if (!requested_ptr && detected_ptr)
e12eaada 1580 {
1581 /*
b92232ef 1582 * Strip "[?&]interface=nnn" from the detected printer.
e12eaada 1583 */
1584
1585 *detected_ptr = '\0';
1586 }
1587 else if (requested_ptr && !detected_ptr)
1588 {
1589 /*
b92232ef 1590 * Strip "[?&]interface=nnn" from the requested printer.
1591 */
1592
1593 *requested_ptr = '\0';
1594 }
1595
1596 if ((requested_ptr = strstr(requested_uri, "?serial=?")) != NULL)
1597 {
1598 /*
1599 * Strip "?serial=?" from the requested printer. This is a special
1600 * case, as "?serial=?" means no serial number and not the serial
1601 * number '?'. This is not covered by the checks below...
e12eaada 1602 */
1603
1604 *requested_ptr = '\0';
1605 }
1606
1607 if ((requested_ptr = strstr(requested_uri, "?serial=")) == NULL &&
1608 (detected_ptr = strstr(detected_uri, "?serial=")) != NULL)
1609 {
1610 /*
1611 * Strip "?serial=nnn" from the detected printer.
1612 */
1613
1614 *detected_ptr = '\0';
1615 }
1616 else if (requested_ptr && !detected_ptr)
1617 {
1618 /*
1619 * Strip "?serial=nnn" from the requested printer.
1620 */
1621
1622 *requested_ptr = '\0';
1623 }
1624
b92232ef 1625 return (!strcmp(requested_uri, detected_uri));
bdb5a5c3 1626}
1627
1628
2fa42ed2 1629/*
1630 * 'printer_class_soft_reset()' - Do the soft reset request specific to printers
1631 *
1632 * This soft reset is specific to the printer device class and is much less
1633 * invasive than the general USB reset libusb_reset_device(). Especially it
1634 * does never happen that the USB addressing and configuration changes. What
1635 * is actually done is that all buffers get flushed and the bulk IN and OUT
1636 * pipes get reset to their default states. This clears all stall conditions.
1637 * See http://cholla.mmto.org/computers/linux/usb/usbprint11.pdf
1638 */
1639
1640static int /* O - 0 on success, < 0 on error */
1641printer_class_soft_reset(usb_printer_t *printer) /* I - Printer */
1642{
1643 struct libusb_config_descriptor *confptr = NULL;
1644 /* Pointer to current configuration */
1645 int interface,
1646 errcode;
1647
1648 if (libusb_get_config_descriptor(printer->device, printer->conf, &confptr)
1649 < 0)
1650 interface = printer->iface;
1651 else
1652 interface = confptr->interface[printer->iface].
1653 altsetting[printer->altset].bInterfaceNumber;
1654 libusb_free_config_descriptor(confptr);
1655 if ((errcode = libusb_control_transfer(printer->handle,
1656 LIBUSB_REQUEST_TYPE_CLASS |
1657 LIBUSB_ENDPOINT_OUT |
1658 LIBUSB_RECIPIENT_OTHER,
1659 2, 0, interface, NULL, 0, 5000)) < 0)
1660 errcode = libusb_control_transfer(printer->handle,
1661 LIBUSB_REQUEST_TYPE_CLASS |
1662 LIBUSB_ENDPOINT_OUT |
1663 LIBUSB_RECIPIENT_INTERFACE,
1664 2, 0, interface, NULL, 0, 5000);
1665 return errcode;
1666}
1667
1668
1669/*
1670 * 'quirks()' - Get the known quirks of a given printer model
1671 */
1672
1673static unsigned int quirks(int vendor, int product)
1674{
1675 int i;
1676
1677 for (i = 0; quirk_printers[i].vendorId; i++)
1678 {
1679 if (vendor == quirk_printers[i].vendorId &&
8fa16503 1680 (quirk_printers[i].productId == 0x0000 ||
1681 product == quirk_printers[i].productId))
2fa42ed2 1682 return quirk_printers[i].quirks;
1683 }
1684 return 0;
1685}
1686
1687
4828c388 1688/*
137fa46b 1689 * 'read_thread()' - Thread to read the backchannel data on.
1690 */
1691
1692static void *read_thread(void *reference)
1693{
1694 unsigned char readbuffer[512];
1695 int rbytes;
1696 int readstatus;
1697 struct timeval now,
1698 delay,
1699 end,
1700 timeleft;
1701
1702
1703 (void)reference;
1704
1705 /*
1706 * Read frequency: once every 250 milliseconds.
1707 */
1708
1709 delay.tv_sec = 0;
1710 delay.tv_usec = 250000;
1711
1712 do
1713 {
1714 /*
1715 * Remember when we started so we can throttle the loop after the read
1716 * call...
1717 */
1718
1719 gettimeofday(&now, NULL);
1720
1721 /*
1722 * Calculate what 250 milliSeconds are in absolute time...
1723 */
1724
1725 timeradd(&now, &delay, &end);
1726
1727 rbytes = sizeof(readbuffer);
1728 readstatus = libusb_bulk_transfer(g.printer->handle,
1729 g.printer->read_endp,
1730 readbuffer, rbytes,
1731 &rbytes, 60000);
1732 if (readstatus == LIBUSB_SUCCESS && rbytes > 0)
1733 {
1734 fprintf(stderr, "DEBUG: Read %d bytes of back-channel data...\n",
1735 (int)rbytes);
1736 cupsBackChannelWrite((const char *)readbuffer, rbytes, 1.0);
1737 }
1738 else if (readstatus == LIBUSB_ERROR_TIMEOUT)
1739 fputs("DEBUG: Got USB transaction timeout during read.\n", stderr);
1740 else if (readstatus == LIBUSB_ERROR_PIPE)
1741 fputs("DEBUG: Got USB pipe stalled during read.\n", stderr);
1742 else if (readstatus == LIBUSB_ERROR_INTERRUPTED)
1743 fputs("DEBUG: Got USB return aborted during read.\n", stderr);
1744
1745 /*
1746 * Make sure this loop executes no more than once every 250 miliseconds...
1747 */
1748
1749 if ((readstatus != LIBUSB_SUCCESS || rbytes == 0) &&
1750 (g.wait_eof || !g.read_thread_stop))
1751 {
1752 gettimeofday(&now, NULL);
1753 if (timercmp(&now, &end, <))
1754 {
1755 timersub(&end, &now, &timeleft);
1756 usleep(1000000 * timeleft.tv_sec + timeleft.tv_usec);
1757 }
1758 }
1759 } while (g.wait_eof || !g.read_thread_stop);
1760
1761 /*
1762 * Let the main thread know that we have completed the read thread...
1763 */
1764
1765 pthread_mutex_lock(&g.read_thread_mutex);
1766 g.read_thread_done = 1;
1767 pthread_cond_signal(&g.read_thread_cond);
1768 pthread_mutex_unlock(&g.read_thread_mutex);
1769
1770 return (NULL);
1771}
1772
1773
1774/*
1775 * 'sidechannel_thread()' - Handle side-channel requests.
4828c388 1776 */
1777
137fa46b 1778static void*
1779sidechannel_thread(void *reference)
4828c388 1780{
4828c388 1781 cups_sc_command_t command; /* Request command */
1782 cups_sc_status_t status; /* Request/response status */
1783 char data[2048]; /* Request/response data */
1784 int datalen; /* Request/response data size */
1785
1786
137fa46b 1787 (void)reference;
4828c388 1788
137fa46b 1789 do
4828c388 1790 {
137fa46b 1791 datalen = sizeof(data);
4828c388 1792
137fa46b 1793 if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0))
1794 {
1795 if (status == CUPS_SC_STATUS_TIMEOUT)
1796 continue;
1797 else
1798 break;
1799 }
4828c388 1800
137fa46b 1801 switch (command)
1802 {
1803 case CUPS_SC_CMD_SOFT_RESET: /* Do a soft reset */
1804 fputs("DEBUG: CUPS_SC_CMD_SOFT_RESET received from driver...\n",
1805 stderr);
1806
1807 soft_reset();
1808 cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, NULL, 0, 1.0);
1809 fputs("DEBUG: Returning status CUPS_STATUS_OK with no bytes...\n",
1810 stderr);
1811 break;
1812
1813 case CUPS_SC_CMD_DRAIN_OUTPUT: /* Drain all pending output */
1814 fputs("DEBUG: CUPS_SC_CMD_DRAIN_OUTPUT received from driver...\n",
1815 stderr);
1816
1817 g.drain_output = 1;
1818 break;
1819
1820 case CUPS_SC_CMD_GET_BIDI: /* Is the connection bidirectional? */
1821 fputs("DEBUG: CUPS_SC_CMD_GET_BIDI received from driver...\n",
1822 stderr);
1823
1824 data[0] = (g.printer->protocol >= 2 ? 1 : 0);
1825 cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, data, 1, 1.0);
1826
1827 fprintf(stderr,
1828 "DEBUG: Returned CUPS_SC_STATUS_OK with 1 byte (%02X)...\n",
1829 data[0]);
1830 break;
1831
1832 case CUPS_SC_CMD_GET_DEVICE_ID: /* Return IEEE-1284 device ID */
1833 fputs("DEBUG: CUPS_SC_CMD_GET_DEVICE_ID received from driver...\n",
1834 stderr);
1835
1836 datalen = sizeof(data);
1837 if (get_device_id(g.printer, data, sizeof(data)))
1838 {
1839 status = CUPS_SC_STATUS_IO_ERROR;
1840 datalen = 0;
4828c388 1841 }
137fa46b 1842 else
1843 {
1844 status = CUPS_SC_STATUS_OK;
1845 datalen = strlen(data);
1846 }
1847 cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, data, datalen, 1.0);
4828c388 1848
137fa46b 1849 if (datalen < sizeof(data))
1850 data[datalen] = '\0';
1851 else
1852 data[sizeof(data) - 1] = '\0';
4828c388 1853
137fa46b 1854 fprintf(stderr,
1855 "DEBUG: Returning CUPS_SC_STATUS_OK with %d bytes (%s)...\n",
1856 datalen, data);
1857 break;
4828c388 1858
137fa46b 1859 case CUPS_SC_CMD_GET_STATE: /* Return device state */
1860 fputs("DEBUG: CUPS_SC_CMD_GET_STATE received from driver...\n",
1861 stderr);
4828c388 1862
137fa46b 1863 data[0] = CUPS_SC_STATE_ONLINE;
1864 cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, data, 1, 1.0);
1865
1866 fprintf(stderr,
1867 "DEBUG: Returned CUPS_SC_STATUS_OK with 1 byte (%02X)...\n",
1868 data[0]);
1869 break;
1870
1871 case CUPS_SC_CMD_GET_CONNECTED: /* Return whether device is
1872 connected */
1873 fputs("DEBUG: CUPS_SC_CMD_GET_CONNECTED received from driver...\n",
1874 stderr);
1875
1876 data[0] = (g.printer->handle ? 1 : 0);
1877 cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, data, 1, 1.0);
1878
1879 fprintf(stderr,
1880 "DEBUG: Returned CUPS_SC_STATUS_OK with 1 byte (%02X)...\n",
1881 data[0]);
1882 break;
1883
1884 default:
1885 fprintf(stderr, "DEBUG: Unknown side-channel command (%d) received "
1886 "from driver...\n", command);
4828c388 1887
137fa46b 1888 cupsSideChannelWrite(command, CUPS_SC_STATUS_NOT_IMPLEMENTED,
1889 NULL, 0, 1.0);
1890
1891 fputs("DEBUG: Returned CUPS_SC_STATUS_NOT_IMPLEMENTED with no bytes...\n",
1892 stderr);
1893 break;
1894 }
1895 }
1896 while (!g.sidechannel_thread_stop);
1897
1898 pthread_mutex_lock(&g.sidechannel_thread_mutex);
1899 g.sidechannel_thread_done = 1;
1900 pthread_cond_signal(&g.sidechannel_thread_cond);
1901 pthread_mutex_unlock(&g.sidechannel_thread_mutex);
1902
1903 return (NULL);
1904}
1905
1906
1907/*
1908 * 'soft_reset()' - Send a soft reset to the device.
1909 */
1910
1911static void soft_reset(void)
1912{
1913 fd_set input_set; /* Input set for select() */
1914 struct timeval tv; /* Time value */
1915 char buffer[2048]; /* Buffer */
1916 struct timespec cond_timeout; /* pthread condition timeout */
1917
1918 /*
1919 * Send an abort once a second until the I/O lock is released by the main
1920 * thread...
1921 */
1922
1923 pthread_mutex_lock(&g.readwrite_lock_mutex);
1924 while (g.readwrite_lock)
1925 {
1926 gettimeofday(&tv, NULL);
1927 cond_timeout.tv_sec = tv.tv_sec + 1;
1928 cond_timeout.tv_nsec = tv.tv_usec * 1000;
1929
1930 while (g.readwrite_lock)
1931 {
1932 if (pthread_cond_timedwait(&g.readwrite_lock_cond,
1933 &g.readwrite_lock_mutex,
1934 &cond_timeout) != 0)
4828c388 1935 break;
137fa46b 1936 }
4828c388 1937 }
1938
137fa46b 1939 g.readwrite_lock = 1;
1940 pthread_mutex_unlock(&g.readwrite_lock_mutex);
1941
1942 /*
1943 * Flush bytes waiting on print_fd...
1944 */
1945
1946 g.print_bytes = 0;
1947
1948 FD_ZERO(&input_set);
1949 FD_SET(g.print_fd, &input_set);
1950
1951 tv.tv_sec = 0;
1952 tv.tv_usec = 0;
1953
1954 while (select(g.print_fd+1, &input_set, NULL, NULL, &tv) > 0)
1955 if (read(g.print_fd, buffer, sizeof(buffer)) <= 0)
1956 break;
1957
1958 /*
1959 * Send the reset...
1960 */
1961
2fa42ed2 1962 printer_class_soft_reset(g.printer);
137fa46b 1963
1964 /*
1965 * Release the I/O lock...
1966 */
4828c388 1967
137fa46b 1968 pthread_mutex_lock(&g.readwrite_lock_mutex);
1969 g.readwrite_lock = 0;
1970 pthread_cond_signal(&g.readwrite_lock_cond);
1971 pthread_mutex_unlock(&g.readwrite_lock_mutex);
4828c388 1972}
1973
1974
bdb5a5c3 1975/*
1976 * End of "$Id$".
1977 */
1978