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