]> git.ipfire.org Git - thirdparty/cups.git/blame - backend/usb-libusb.c
Merge changes from CUPS 1.6svn-r10267.
[thirdparty/cups.git] / backend / usb-libusb.c
CommitLineData
75bd9771
MS
1/*
2 * "$Id$"
3 *
12f89d24 4 * LIBUSB interface code for CUPS.
75bd9771 5 *
12f89d24 6 * Copyright 2007-2012 by Apple Inc.
75bd9771
MS
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 *
12f89d24
MS
16 * list_devices() - List the available printers.
17 * print_device() - Print a file to a USB device.
18 * close_device() - Close the connection to the USB printer.
19 * find_device() - Find or enumerate USB printers.
20 * get_device_id() - Get the IEEE-1284 device ID for the printer.
21 * list_cb() - List USB printers for discovery.
22 * make_device_uri() - Create a device URI for a USB printer.
23 * open_device() - Open a connection to the USB printer.
24 * print_cb() - Find a USB printer for printing.
25 * read_thread() - Thread to read the backchannel data on.
26 * sidechannel_thread() - Handle side-channel requests.
27 * soft_reset() - Send a soft reset to the device.
75bd9771
MS
28 */
29
30/*
31 * Include necessary headers...
32 */
33
12f89d24 34#include <libusb.h>
39ff2fe7 35#include <cups/cups-private.h>
12f89d24
MS
36#include <pthread.h>
37#include <sys/select.h>
38#include <sys/types.h>
39#include <sys/stat.h>
40#include <sys/time.h>
41#include <unistd.h>
42
43
44/*
45 * WAIT_EOF_DELAY is number of seconds we'll wait for responses from
46 * the printer after we've finished sending all the data
47 */
48
49#define WAIT_EOF 0
50#define WAIT_EOF_DELAY 7
51#define WAIT_SIDE_DELAY 3
52#define DEFAULT_TIMEOUT 5000L
75bd9771
MS
53
54
55/*
56 * Local types...
57 */
58
59typedef struct usb_printer_s /**** USB Printer Data ****/
60{
12f89d24 61 struct libusb_device *device; /* Device info */
75bd9771
MS
62 int conf, /* Configuration */
63 iface, /* Interface */
64 altset, /* Alternate setting */
65 write_endp, /* Write endpoint */
12f89d24
MS
66 read_endp, /* Read endpoint */
67 protocol, /* Protocol: 1 = Uni-di, 2 = Bi-di. */
68 usblp_attached; /* Is the "usblp" kernel module
69 attached? */
70 struct libusb_device_handle *handle; /* Open handle to device */
75bd9771
MS
71} usb_printer_t;
72
73typedef int (*usb_cb_t)(usb_printer_t *, const char *, const char *,
74 const void *);
75
12f89d24
MS
76typedef struct usb_globals_s
77{
78 usb_printer_t *printer; /* Printer */
79
80 pthread_mutex_t read_thread_mutex;
81 pthread_cond_t read_thread_cond;
82 int read_thread_stop;
83 int read_thread_done;
84
85 pthread_mutex_t readwrite_lock_mutex;
86 pthread_cond_t readwrite_lock_cond;
87 int readwrite_lock;
88
89 int print_fd; /* File descriptor to print */
90 ssize_t print_bytes; /* Print bytes read */
91
92 int wait_eof;
93 int drain_output; /* Drain all pending output */
94 int bidi_flag; /* 0=unidirectional, 1=bidirectional */
95
96 pthread_mutex_t sidechannel_thread_mutex;
97 pthread_cond_t sidechannel_thread_cond;
98 int sidechannel_thread_stop;
99 int sidechannel_thread_done;
100} usb_globals_t;
101
102
103/*
104 * Globals...
105 */
106
107usb_globals_t g = { 0 }; /* Globals */
108libusb_device **list; /* List of connected USB devices */
109
75bd9771
MS
110
111/*
112 * Local functions...
113 */
114
115static int close_device(usb_printer_t *printer);
116static usb_printer_t *find_device(usb_cb_t cb, const void *data);
117static int get_device_id(usb_printer_t *printer, char *buffer,
118 size_t bufsize);
119static int list_cb(usb_printer_t *printer, const char *device_uri,
120 const char *device_id, const void *data);
121static char *make_device_uri(usb_printer_t *printer,
122 const char *device_id,
123 char *uri, size_t uri_size);
124static int open_device(usb_printer_t *printer, int verbose);
125static int print_cb(usb_printer_t *printer, const char *device_uri,
126 const char *device_id, const void *data);
12f89d24
MS
127static void *read_thread(void *reference);
128static void *sidechannel_thread(void *reference);
129static void soft_reset(void);
75bd9771
MS
130
131
132/*
133 * 'list_devices()' - List the available printers.
134 */
135
136void
137list_devices(void)
138{
139 fputs("DEBUG: list_devices\n", stderr);
140 find_device(list_cb, NULL);
141}
142
143
144/*
145 * 'print_device()' - Print a file to a USB device.
146 */
147
148int /* O - Exit status */
149print_device(const char *uri, /* I - Device URI */
150 const char *hostname, /* I - Hostname/manufacturer */
151 const char *resource, /* I - Resource/modelname */
152 char *options, /* I - Device options/serial number */
153 int print_fd, /* I - File descriptor to print */
154 int copies, /* I - Copies to print */
155 int argc, /* I - Number of command-line arguments (6 or 7) */
156 char *argv[]) /* I - Command-line arguments */
157{
12f89d24
MS
158 int bytes; /* Bytes written */
159 ssize_t total_bytes; /* Total bytes written */
75bd9771 160 struct sigaction action; /* Actions for POSIX signals */
12f89d24
MS
161 int status = CUPS_BACKEND_OK,
162 /* Function results */
163 iostatus; /* Current IO status */
164 pthread_t read_thread_id, /* Read thread */
165 sidechannel_thread_id; /* Side-channel thread */
166 int have_sidechannel = 0; /* Was the side-channel thread started? */
167 struct stat sidechannel_info; /* Side-channel file descriptor info */
168 unsigned char print_buffer[8192], /* Print data buffer */
169 *print_ptr; /* Pointer into print data buffer */
170 fd_set input_set; /* Input set for select() */
171 int nfds; /* Number of file descriptors */
172 struct timeval *timeout, /* Timeout pointer */
173 tv; /* Time value */
174 struct timespec cond_timeout; /* pthread condition timeout */
75bd9771
MS
175
176
12f89d24
MS
177 /*
178 * See if the side-channel descriptor is valid...
179 */
180
181 have_sidechannel = !fstat(CUPS_SC_FD, &sidechannel_info) &&
182 S_ISSOCK(sidechannel_info.st_mode);
183
184 g.wait_eof = WAIT_EOF;
75bd9771
MS
185
186 /*
187 * Connect to the printer...
188 */
189
12f89d24 190 while ((g.printer = find_device(print_cb, uri)) == NULL)
75bd9771 191 {
0837b7e8
MS
192 _cupsLangPrintFilter(stderr, "INFO",
193 _("Waiting for printer to become available."));
75bd9771
MS
194 sleep(5);
195 }
196
12f89d24 197 g.print_fd = print_fd;
75bd9771
MS
198
199 /*
200 * If we are printing data from a print driver on stdin, ignore SIGTERM
201 * so that the driver can finish out any page data, e.g. to eject the
202 * current page. We only do this for stdin printing as otherwise there
203 * is no way to cancel a raw print job...
204 */
205
206 if (!print_fd)
207 {
208 memset(&action, 0, sizeof(action));
209
210 sigemptyset(&action.sa_mask);
211 action.sa_handler = SIG_IGN;
212 sigaction(SIGTERM, &action, NULL);
213 }
214
12f89d24
MS
215 /*
216 * Start the side channel thread if the descriptor is valid...
217 */
218
219 pthread_mutex_init(&g.readwrite_lock_mutex, NULL);
220 pthread_cond_init(&g.readwrite_lock_cond, NULL);
221 g.readwrite_lock = 1;
222
223 if (have_sidechannel)
224 {
225 g.sidechannel_thread_stop = 0;
226 g.sidechannel_thread_done = 0;
227
228 pthread_cond_init(&g.sidechannel_thread_cond, NULL);
229 pthread_mutex_init(&g.sidechannel_thread_mutex, NULL);
230
231 if (pthread_create(&sidechannel_thread_id, NULL, sidechannel_thread, NULL))
232 {
233 fprintf(stderr, "DEBUG: Fatal USB error.\n");
234 _cupsLangPrintFilter(stderr, "ERROR",
235 _("There was an unrecoverable USB error."));
236 fputs("DEBUG: Couldn't create side-channel thread.\n", stderr);
237 close_device(g.printer);
238 return (CUPS_BACKEND_STOP);
239 }
240 }
241
242 /*
243 * Get the read thread going...
244 */
245
246 g.read_thread_stop = 0;
247 g.read_thread_done = 0;
248
249 pthread_cond_init(&g.read_thread_cond, NULL);
250 pthread_mutex_init(&g.read_thread_mutex, NULL);
251
252 if (pthread_create(&read_thread_id, NULL, read_thread, NULL))
253 {
254 fprintf(stderr, "DEBUG: Fatal USB error.\n");
255 _cupsLangPrintFilter(stderr, "ERROR",
256 _("There was an unrecoverable USB error."));
257 fputs("DEBUG: Couldn't create read thread.\n", stderr);
258 close_device(g.printer);
259 return (CUPS_BACKEND_STOP);
260 }
261
262 /*
263 * The main thread sends the print file...
264 */
75bd9771 265
12f89d24
MS
266 g.drain_output = 0;
267 g.print_bytes = 0;
268 total_bytes = 0;
269 print_ptr = print_buffer;
005dd1eb 270
12f89d24 271 while (status == CUPS_BACKEND_OK && copies-- > 0)
75bd9771 272 {
12f89d24 273 _cupsLangPrintFilter(stderr, "INFO", _("Sending data to printer."));
75bd9771 274
12f89d24 275 if (print_fd != STDIN_FILENO)
75bd9771
MS
276 {
277 fputs("PAGE: 1 1\n", stderr);
278 lseek(print_fd, 0, SEEK_SET);
279 }
280
12f89d24 281 while (status == CUPS_BACKEND_OK)
75bd9771 282 {
12f89d24
MS
283 FD_ZERO(&input_set);
284
285 if (!g.print_bytes)
286 FD_SET(print_fd, &input_set);
287
288 /*
289 * Calculate select timeout...
290 * If we have data waiting to send timeout is 100ms.
291 * else if we're draining print_fd timeout is 0.
292 * else we're waiting forever...
293 */
294
295 if (g.print_bytes)
296 {
297 tv.tv_sec = 0;
298 tv.tv_usec = 100000; /* 100ms */
299 timeout = &tv;
300 }
301 else if (g.drain_output)
302 {
303 tv.tv_sec = 0;
304 tv.tv_usec = 0;
305 timeout = &tv;
306 }
307 else
308 timeout = NULL;
309
310 /*
311 * I/O is unlocked around select...
312 */
313
314 pthread_mutex_lock(&g.readwrite_lock_mutex);
315 g.readwrite_lock = 0;
316 pthread_cond_signal(&g.readwrite_lock_cond);
317 pthread_mutex_unlock(&g.readwrite_lock_mutex);
318
319 nfds = select(print_fd + 1, &input_set, NULL, NULL, timeout);
320
321 /*
322 * Reacquire the lock...
323 */
324
325 pthread_mutex_lock(&g.readwrite_lock_mutex);
326 while (g.readwrite_lock)
327 pthread_cond_wait(&g.readwrite_lock_cond, &g.readwrite_lock_mutex);
328 g.readwrite_lock = 1;
329 pthread_mutex_unlock(&g.readwrite_lock_mutex);
330
331 if (nfds < 0)
332 {
333 if (errno == EINTR && total_bytes == 0)
334 {
335 fputs("DEBUG: Received an interrupt before any bytes were "
336 "written, aborting.\n", stderr);
337 close_device(g.printer);
338 return (CUPS_BACKEND_OK);
339 }
340 else if (errno != EAGAIN && errno != EINTR)
341 {
342 _cupsLangPrintFilter(stderr, "ERROR",
343 _("Unable to read print data."));
344 perror("DEBUG: select");
345 close_device(g.printer);
346 return (CUPS_BACKEND_FAILED);
347 }
348 }
349
350 /*
351 * If drain output has finished send a response...
352 */
353
354 if (g.drain_output && !nfds && !g.print_bytes)
355 {
356 /* Send a response... */
357 cupsSideChannelWrite(CUPS_SC_CMD_DRAIN_OUTPUT, CUPS_SC_STATUS_OK, NULL, 0, 1.0);
358 g.drain_output = 0;
359 }
360
18ecb428 361 /*
12f89d24 362 * Check if we have print data ready...
18ecb428
MS
363 */
364
12f89d24 365 if (FD_ISSET(print_fd, &input_set))
75bd9771 366 {
12f89d24
MS
367 g.print_bytes = read(print_fd, print_buffer, sizeof(print_buffer));
368
369 if (g.print_bytes < 0)
005dd1eb 370 {
12f89d24
MS
371 /*
372 * Read error - bail if we don't see EAGAIN or EINTR...
373 */
374
375 if (errno != EAGAIN && errno != EINTR)
005dd1eb 376 {
0837b7e8 377 _cupsLangPrintFilter(stderr, "ERROR",
12f89d24
MS
378 _("Unable to read print data."));
379 perror("DEBUG: read");
380 close_device(g.printer);
381 return (CUPS_BACKEND_FAILED);
005dd1eb
MS
382 }
383
12f89d24 384 g.print_bytes = 0;
005dd1eb 385 }
12f89d24
MS
386 else if (g.print_bytes == 0)
387 {
388 /*
389 * End of file, break out of the loop...
390 */
391
005dd1eb 392 break;
12f89d24
MS
393 }
394
395 print_ptr = print_buffer;
396
397 fprintf(stderr, "DEBUG: Read %d bytes of print data...\n",
398 (int)g.print_bytes);
75bd9771
MS
399 }
400
12f89d24 401 if (g.print_bytes)
18ecb428 402 {
12f89d24
MS
403 iostatus = libusb_bulk_transfer(g.printer->handle,
404 g.printer->write_endp,
405 print_buffer, g.print_bytes,
406 &bytes, 60000);
407 /*
408 * Ignore timeout errors, but retain the number of bytes written to
409 * avoid sending duplicate data...
410 */
411
412 if (iostatus == LIBUSB_ERROR_TIMEOUT)
413 {
414 fputs("DEBUG: Got USB transaction timeout during write.\n", stderr);
415 iostatus = 0;
416 }
417
418 /*
419 * If we've stalled, retry the write...
420 */
421
422 else if (iostatus == LIBUSB_ERROR_PIPE)
423 {
424 fputs("DEBUG: Got USB pipe stalled during write.\n", stderr);
425
426 iostatus = libusb_bulk_transfer(g.printer->handle,
427 g.printer->write_endp,
428 print_buffer, g.print_bytes,
429 &bytes, 60000);
430 }
431
432 /*
433 * Retry a write after an aborted write since we probably just got
434 * SIGTERM...
435 */
436
437 else if (iostatus == LIBUSB_ERROR_INTERRUPTED)
438 {
439 fputs("DEBUG: Got USB return aborted during write.\n", stderr);
440
441 iostatus = libusb_bulk_transfer(g.printer->handle,
442 g.printer->write_endp,
443 print_buffer, g.print_bytes,
444 &bytes, 60000);
445 }
446
447 if (iostatus)
448 {
449 /*
450 * Write error - bail if we don't see an error we can retry...
451 */
452
453 _cupsLangPrintFilter(stderr, "ERROR",
454 _("Unable to send data to printer."));
455 fprintf(stderr, "DEBUG: libusb write operation returned %x.\n",
456 iostatus);
457
458 status = CUPS_BACKEND_FAILED;
459 break;
460 }
461 else if (bytes > 0)
462 {
463 fprintf(stderr, "DEBUG: Wrote %d bytes of print data...\n",
464 (int)bytes);
465
466 g.print_bytes -= bytes;
467 print_ptr += bytes;
468 total_bytes += bytes;
469 }
18ecb428 470 }
12f89d24
MS
471
472 if (print_fd != 0 && status == CUPS_BACKEND_OK)
473 fprintf(stderr, "DEBUG: Sending print file, " CUPS_LLFMT " bytes...\n",
474 CUPS_LLCAST total_bytes);
75bd9771
MS
475 }
476 }
477
12f89d24
MS
478 fprintf(stderr, "DEBUG: Sent " CUPS_LLFMT " bytes...\n",
479 CUPS_LLCAST total_bytes);
480
75bd9771 481 /*
12f89d24 482 * Signal the side channel thread to exit...
75bd9771
MS
483 */
484
12f89d24
MS
485 if (have_sidechannel)
486 {
487 close(CUPS_SC_FD);
488 pthread_mutex_lock(&g.readwrite_lock_mutex);
489 g.readwrite_lock = 0;
490 pthread_cond_signal(&g.readwrite_lock_cond);
491 pthread_mutex_unlock(&g.readwrite_lock_mutex);
492
493 g.sidechannel_thread_stop = 1;
494 pthread_mutex_lock(&g.sidechannel_thread_mutex);
495
496 if (!g.sidechannel_thread_done)
497 {
498 gettimeofday(&tv, NULL);
499 cond_timeout.tv_sec = tv.tv_sec + WAIT_SIDE_DELAY;
500 cond_timeout.tv_nsec = tv.tv_usec * 1000;
75bd9771 501
12f89d24
MS
502 while (!g.sidechannel_thread_done)
503 {
504 if (pthread_cond_timedwait(&g.sidechannel_thread_cond,
505 &g.sidechannel_thread_mutex,
506 &cond_timeout) != 0)
507 break;
508 }
509 }
510
511 pthread_mutex_unlock(&g.sidechannel_thread_mutex);
512 }
513
514 /*
515 * Signal the read thread to exit then wait 7 seconds for it to complete...
516 */
517
518 g.read_thread_stop = 1;
519
520 pthread_mutex_lock(&g.read_thread_mutex);
521
522 if (!g.read_thread_done)
523 {
524 fputs("DEBUG: Waiting for read thread to exit...\n", stderr);
525
526 gettimeofday(&tv, NULL);
527 cond_timeout.tv_sec = tv.tv_sec + WAIT_EOF_DELAY;
528 cond_timeout.tv_nsec = tv.tv_usec * 1000;
529
530 while (!g.read_thread_done)
531 {
532 if (pthread_cond_timedwait(&g.read_thread_cond, &g.read_thread_mutex,
533 &cond_timeout) != 0)
534 break;
535 }
536
537 /*
538 * If it didn't exit abort the pending read and wait an additional second...
539 */
540
541 if (!g.read_thread_done)
542 {
543 fputs("DEBUG: Read thread still active, aborting the pending read...\n",
544 stderr);
545
546 g.wait_eof = 0;
547
548 gettimeofday(&tv, NULL);
549 cond_timeout.tv_sec = tv.tv_sec + 1;
550 cond_timeout.tv_nsec = tv.tv_usec * 1000;
551
552 while (!g.read_thread_done)
553 {
554 if (pthread_cond_timedwait(&g.read_thread_cond, &g.read_thread_mutex,
555 &cond_timeout) != 0)
556 break;
557 }
558 }
559 }
560
561 pthread_mutex_unlock(&g.read_thread_mutex);
562
563 if (print_fd)
564 close(print_fd);
565
566 /*
567 * Close the connection and input file and general clean up...
568 */
569
570 close_device(g.printer);
571
572 /*
573 * Clean up ....
574 */
575
576 libusb_free_device_list(list, 1);
577 libusb_exit(NULL);
578
579 return (status);
75bd9771
MS
580}
581
582
583/*
584 * 'close_device()' - Close the connection to the USB printer.
585 */
586
587static int /* I - 0 on success, -1 on failure */
588close_device(usb_printer_t *printer) /* I - Printer */
589{
12f89d24
MS
590 struct libusb_device_descriptor devdesc;
591 /* Current device descriptor */
592 struct libusb_config_descriptor *confptr;
593 /* Pointer to current configuration */
594
595
75bd9771
MS
596 if (printer->handle)
597 {
557dde9f
MS
598 /*
599 * Release interfaces before closing so that we know all data is written
600 * to the device...
601 */
602
12f89d24 603 int number; /* Interface number */
557dde9f 604
12f89d24
MS
605 libusb_get_device_descriptor (printer->device, &devdesc);
606 libusb_get_config_descriptor (printer->device, printer->conf, &confptr);
607 number = confptr->interface[printer->iface].
608 altsetting[printer->altset].bInterfaceNumber;
609 libusb_release_interface(printer->handle, number);
557dde9f 610 if (number != 0)
12f89d24
MS
611 libusb_release_interface(printer->handle, 0);
612
613 /*
614 * Re-attach "usblp" kernel module if it was attached before using this
615 * device
616 */
617
618 if (printer->usblp_attached == 1)
619 {
620 if (libusb_attach_kernel_driver(printer->handle, printer->iface) < 0)
621 fprintf(stderr,
622 "DEBUG: Failed to re-attach \"usblp\" kernel module to "
623 "%04x:%04x\n", devdesc.idVendor, devdesc.idProduct);
624 }
625
626 libusb_free_config_descriptor(confptr);
557dde9f
MS
627
628 /*
629 * Close the interface and return...
630 */
631
12f89d24 632 libusb_close(printer->handle);
75bd9771
MS
633 printer->handle = NULL;
634 }
635
636 return (0);
637}
638
639
640/*
641 * 'find_device()' - Find or enumerate USB printers.
642 */
643
644static usb_printer_t * /* O - Found printer */
645find_device(usb_cb_t cb, /* I - Callback function */
646 const void *data) /* I - User data for callback */
647{
12f89d24
MS
648 libusb_device **list; /* List of connected USB devices */
649 libusb_device *device = NULL; /* Current device */
650 struct libusb_device_descriptor devdesc;
651 /* Current device descriptor */
652 struct libusb_config_descriptor *confptr = NULL;
653 /* Pointer to current configuration */
654 const struct libusb_interface *ifaceptr = NULL;
655 /* Pointer to current interface */
656 const struct libusb_interface_descriptor *altptr = NULL;
75bd9771 657 /* Pointer to current alternate setting */
12f89d24 658 const struct libusb_endpoint_descriptor *endpptr = NULL;
75bd9771 659 /* Pointer to current endpoint */
12f89d24
MS
660 ssize_t numdevs, /* number of connected devices */
661 i = 0;
662 uint8_t conf, /* Current configuration */
75bd9771
MS
663 iface, /* Current interface */
664 altset, /* Current alternate setting */
665 protocol, /* Current protocol */
666 endp, /* Current endpoint */
667 read_endp, /* Current read endpoint */
668 write_endp; /* Current write endpoint */
669 char device_id[1024],/* IEEE-1284 device ID */
670 device_uri[1024];
671 /* Device URI */
672 static usb_printer_t printer; /* Current printer */
673
674
675 /*
676 * Initialize libusb...
677 */
678
12f89d24
MS
679 libusb_init(NULL);
680 numdevs = libusb_get_device_list(NULL, &list);
681 fprintf(stderr, "DEBUG: libusb_get_device_list=%d\n", (int)numdevs);
75bd9771
MS
682
683 /*
684 * Then loop through the devices it found...
685 */
686
12f89d24
MS
687 if (numdevs > 0)
688 for (i = 0; i < numdevs; i++)
75bd9771 689 {
12f89d24
MS
690 device = list[i];
691
75bd9771
MS
692 /*
693 * Ignore devices with no configuration data and anything that is not
694 * a printer...
695 */
696
12f89d24
MS
697 libusb_get_device_descriptor (device, &devdesc);
698
699 if (!devdesc.bNumConfigurations || !devdesc.idVendor ||
700 !devdesc.idProduct)
75bd9771
MS
701 continue;
702
12f89d24
MS
703 for (conf = 0; conf < devdesc.bNumConfigurations; conf ++)
704 {
705 if (libusb_get_config_descriptor (device, conf, &confptr) < 0)
706 continue;
75bd9771
MS
707 for (iface = 0, ifaceptr = confptr->interface;
708 iface < confptr->bNumInterfaces;
709 iface ++, ifaceptr ++)
710 {
711 /*
712 * Some printers offer multiple interfaces...
713 */
714
715 protocol = 0;
716
717 for (altset = 0, altptr = ifaceptr->altsetting;
718 altset < ifaceptr->num_altsetting;
719 altset ++, altptr ++)
720 {
721 /*
722 * Currently we only support unidirectional and bidirectional
723 * printers. Future versions of this code will support the
724 * 1284.4 (packet mode) protocol as well.
725 */
726
12f89d24 727 if (altptr->bInterfaceClass != LIBUSB_CLASS_PRINTER ||
75bd9771
MS
728 altptr->bInterfaceSubClass != 1 ||
729 (altptr->bInterfaceProtocol != 1 && /* Unidirectional */
730 altptr->bInterfaceProtocol != 2) || /* Bidirectional */
731 altptr->bInterfaceProtocol < protocol)
732 continue;
733
734 read_endp = -1;
735 write_endp = -1;
736
737 for (endp = 0, endpptr = altptr->endpoint;
738 endp < altptr->bNumEndpoints;
739 endp ++, endpptr ++)
12f89d24
MS
740 if ((endpptr->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) ==
741 LIBUSB_TRANSFER_TYPE_BULK)
75bd9771 742 {
12f89d24 743 if (endpptr->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
75bd9771
MS
744 read_endp = endp;
745 else
746 write_endp = endp;
747 }
748
749 if (write_endp >= 0)
750 {
751 /*
752 * Save the best match so far...
753 */
754
755 protocol = altptr->bInterfaceProtocol;
756 printer.altset = altset;
757 printer.write_endp = write_endp;
758 printer.read_endp = read_endp;
759 }
760 }
761
762 if (protocol > 0)
763 {
12f89d24
MS
764 printer.device = device;
765 printer.conf = conf;
766 printer.iface = iface;
767 printer.protocol = protocol;
768 printer.handle = NULL;
75bd9771
MS
769
770 if (!open_device(&printer, data != NULL))
771 {
12f89d24
MS
772 get_device_id(&printer, device_id, sizeof(device_id));
773 make_device_uri(&printer, device_id, device_uri,
774 sizeof(device_uri));
75bd9771 775
12f89d24
MS
776 if ((*cb)(&printer, device_uri, device_id, data))
777 {
778 printer.read_endp = confptr->interface[printer.iface].
005dd1eb
MS
779 altsetting[printer.altset].
780 endpoint[printer.read_endp].
781 bEndpointAddress;
12f89d24 782 printer.write_endp = confptr->interface[printer.iface].
005dd1eb
MS
783 altsetting[printer.altset].
784 endpoint[printer.write_endp].
785 bEndpointAddress;
12f89d24 786 return (&printer);
75bd9771
MS
787 }
788
789 close_device(&printer);
790 }
791 }
792 }
12f89d24
MS
793 libusb_free_config_descriptor(confptr);
794 }
75bd9771
MS
795 }
796
797 /*
798 * If we get this far without returning, then we haven't found a printer
799 * to print to...
800 */
801
12f89d24
MS
802 /*
803 * Clean up ....
804 */
805
806 libusb_free_device_list(list, 1);
807 libusb_exit(NULL);
808
75bd9771
MS
809 return (NULL);
810}
811
812
813/*
814 * 'get_device_id()' - Get the IEEE-1284 device ID for the printer.
815 */
816
817static int /* O - 0 on success, -1 on error */
818get_device_id(usb_printer_t *printer, /* I - Printer */
819 char *buffer, /* I - String buffer */
820 size_t bufsize) /* I - Number of bytes in buffer */
821{
822 int length; /* Length of device ID */
823
824
12f89d24
MS
825 if (libusb_control_transfer(printer->handle,
826 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_ENDPOINT_IN |
827 LIBUSB_RECIPIENT_INTERFACE,
828 0, printer->conf,
829 (printer->iface << 8) | printer->altset,
830 (unsigned char *)buffer, bufsize, 5000) < 0)
75bd9771
MS
831 {
832 *buffer = '\0';
833 return (-1);
834 }
835
836 /*
837 * Extract the length of the device ID string from the first two
838 * bytes. The 1284 spec says the length is stored MSB first...
839 */
840
12f89d24 841 length = (((unsigned)buffer[0] & 255) << 8) |
75bd9771
MS
842 ((unsigned)buffer[1] & 255);
843
844 /*
12f89d24
MS
845 * Check to see if the length is larger than our buffer or less than 14 bytes
846 * (the minimum valid device ID is "MFG:x;MDL:y;" with 2 bytes for the length).
847 *
848 * If the length is out-of-range, assume that the vendor incorrectly
849 * implemented the 1284 spec and re-read the length as LSB first,..
75bd9771
MS
850 */
851
12f89d24
MS
852 if (length > bufsize || length < 14)
853 length = (((unsigned)buffer[1] & 255) << 8) |
75bd9771
MS
854 ((unsigned)buffer[0] & 255);
855
ee6ddad2
MS
856 if (length > bufsize)
857 length = bufsize;
858
12f89d24
MS
859 if (length < 14)
860 {
861 /*
862 * Invalid device ID, clear it!
863 */
864
865 *buffer = '\0';
866 return (-1);
867 }
868
ee6ddad2 869 length -= 2;
75bd9771
MS
870
871 /*
872 * Copy the device ID text to the beginning of the buffer and
873 * nul-terminate.
874 */
875
876 memmove(buffer, buffer + 2, length);
877 buffer[length] = '\0';
878
879 return (0);
880}
881
882
883/*
884 * 'list_cb()' - List USB printers for discovery.
885 */
886
887static int /* O - 0 to continue, 1 to stop */
888list_cb(usb_printer_t *printer, /* I - Printer */
889 const char *device_uri, /* I - Device URI */
890 const char *device_id, /* I - IEEE-1284 device ID */
891 const void *data) /* I - User data (not used) */
892{
893 char make_model[1024]; /* Make and model */
894
895
896 /*
897 * Get the device URI and make/model strings...
898 */
899
12f89d24
MS
900 if (backendGetMakeModel(device_id, make_model, sizeof(make_model)))
901 strlcpy(make_model, "Unknown", sizeof(make_model));
75bd9771
MS
902
903 /*
904 * Report the printer...
905 */
906
749b1e90
MS
907 cupsBackendReport("direct", device_uri, make_model, make_model, device_id,
908 NULL);
75bd9771
MS
909
910 /*
911 * Keep going...
912 */
913
914 return (0);
915}
916
917
918/*
919 * 'make_device_uri()' - Create a device URI for a USB printer.
920 */
921
922static char * /* O - Device URI */
923make_device_uri(
924 usb_printer_t *printer, /* I - Printer */
925 const char *device_id, /* I - IEEE-1284 device ID */
926 char *uri, /* I - Device URI buffer */
927 size_t uri_size) /* I - Size of device URI buffer */
928{
12f89d24
MS
929 struct libusb_device_descriptor devdesc;
930 /* Current device descriptor */
75bd9771
MS
931 char options[1024]; /* Device URI options */
932 int num_values; /* Number of 1284 parameters */
933 cups_option_t *values; /* 1284 parameters */
934 const char *mfg, /* Manufacturer */
935 *mdl, /* Model */
12f89d24 936 *des = NULL, /* Description */
75bd9771 937 *sern; /* Serial number */
f99f3698 938 size_t mfglen; /* Length of manufacturer string */
75bd9771
MS
939 char tempmfg[256], /* Temporary manufacturer string */
940 tempsern[256], /* Temporary serial number string */
941 *tempptr; /* Pointer into temp string */
942
943
944 /*
945 * Get the make, model, and serial numbers...
946 */
947
f8b3a85b 948 num_values = _cupsGet1284Values(device_id, &values);
75bd9771
MS
949
950 if ((sern = cupsGetOption("SERIALNUMBER", num_values, values)) == NULL)
951 if ((sern = cupsGetOption("SERN", num_values, values)) == NULL)
7cf5915e 952 if ((sern = cupsGetOption("SN", num_values, values)) == NULL &&
12f89d24
MS
953 ((libusb_get_device_descriptor (printer->device, &devdesc) >= 0) &&
954 devdesc.iSerialNumber))
75bd9771
MS
955 {
956 /*
957 * Try getting the serial number from the device itself...
958 */
959
12f89d24
MS
960 int length =
961 libusb_get_string_descriptor_ascii(printer->handle,
962 devdesc.iSerialNumber,
963 (unsigned char *)tempsern,
964 sizeof(tempsern) - 1);
75bd9771
MS
965 if (length > 0)
966 {
967 tempsern[length] = '\0';
968 sern = tempsern;
969 }
970 }
971
972 if ((mfg = cupsGetOption("MANUFACTURER", num_values, values)) == NULL)
973 mfg = cupsGetOption("MFG", num_values, values);
974
975 if ((mdl = cupsGetOption("MODEL", num_values, values)) == NULL)
976 mdl = cupsGetOption("MDL", num_values, values);
977
75bd9771
MS
978 /*
979 * To maintain compatibility with the original character device backend on
980 * Linux and *BSD, map manufacturer names...
981 */
982
983 if (mfg)
984 {
88f9aafc 985 if (!_cups_strcasecmp(mfg, "Hewlett-Packard"))
75bd9771 986 mfg = "HP";
88f9aafc 987 else if (!_cups_strcasecmp(mfg, "Lexmark International"))
75bd9771
MS
988 mfg = "Lexmark";
989 }
990 else
75bd9771
MS
991 {
992 /*
993 * No manufacturer? Use the model string or description...
994 */
995
996 if (mdl)
997 _ppdNormalizeMakeAndModel(mdl, tempmfg, sizeof(tempmfg));
998 else if ((des = cupsGetOption("DESCRIPTION", num_values, values)) != NULL ||
999 (des = cupsGetOption("DES", num_values, values)) != NULL)
1000 _ppdNormalizeMakeAndModel(des, tempmfg, sizeof(tempmfg));
1001 else
1002 strlcpy(tempmfg, "Unknown", sizeof(tempmfg));
1003
1004 if ((tempptr = strchr(tempmfg, ' ')) != NULL)
1005 *tempptr = '\0';
1006
1007 mfg = tempmfg;
1008 }
1009
12f89d24
MS
1010 if (!mdl)
1011 {
1012 /*
1013 * No model? Use description...
1014 */
1015 if (des)
1016 mdl = des; /* We remove the manufacturer name below */
1017 else if (!strncasecmp(mfg, "Unknown", 7))
1018 mdl = "Printer";
1019 else
1020 mdl = "Unknown Model";
1021 }
1022
f99f3698
MS
1023 mfglen = strlen(mfg);
1024
1025 if (!strncasecmp(mdl, mfg, mfglen) && _cups_isspace(mdl[mfglen]))
1026 {
1027 mdl += mfglen + 1;
1028
1029 while (_cups_isspace(*mdl))
1030 mdl ++;
1031 }
1032
75bd9771
MS
1033 /*
1034 * Generate the device URI from the manufacturer, model, serial number,
1035 * and interface number...
1036 */
1037
1038 if (sern)
1039 {
1040 if (printer->iface > 0)
1041 snprintf(options, sizeof(options), "?serial=%s&interface=%d", sern,
1042 printer->iface);
1043 else
1044 snprintf(options, sizeof(options), "?serial=%s", sern);
1045 }
1046 else if (printer->iface > 0)
1047 snprintf(options, sizeof(options), "?interface=%d", printer->iface);
1048 else
1049 options[0] = '\0';
1050
1051 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, uri_size, "usb", NULL, mfg, 0,
1052 "/%s%s", mdl, options);
1053
1054 cupsFreeOptions(num_values, values);
1055
1056 return (uri);
1057}
1058
1059
1060/*
1061 * 'open_device()' - Open a connection to the USB printer.
1062 */
1063
1064static int /* O - 0 on success, -1 on error */
1065open_device(usb_printer_t *printer, /* I - Printer */
1066 int verbose) /* I - Update connecting-to-device state? */
1067{
12f89d24
MS
1068 struct libusb_device_descriptor devdesc;
1069 /* Current device descriptor */
1070 struct libusb_config_descriptor *confptr = NULL;
1071 /* Pointer to current configuration */
1072 int number1 = -1, /* Configuration/interface/altset */
1073 number2 = -1, /* numbers */
1074 errcode = 0;
1075 char current; /* Current configuration */
75bd9771
MS
1076
1077
1078 /*
1079 * Return immediately if we are already connected...
1080 */
1081
1082 if (printer->handle)
1083 return (0);
1084
1085 /*
1086 * Try opening the printer...
1087 */
1088
12f89d24 1089 if (libusb_open(printer->device, &printer->handle) < 0)
75bd9771
MS
1090 return (-1);
1091
12f89d24
MS
1092 if (verbose)
1093 fputs("STATE: +connecting-to-device\n", stderr);
1094
75bd9771 1095 /*
12f89d24
MS
1096 * Set the desired configuration, but only if it needs changing. Some
1097 * printers (e.g., Samsung) don't like libusb_set_configuration. It will
1098 * succeed, but the following print job is sometimes silently lost by the
1099 * printer.
75bd9771
MS
1100 */
1101
12f89d24
MS
1102 if (libusb_control_transfer(printer->handle,
1103 LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_ENDPOINT_IN |
1104 LIBUSB_RECIPIENT_DEVICE,
1105 8, /* GET_CONFIGURATION */
1106 0, 0, (unsigned char *)&current, 1, 5000) < 0)
1107 current = 0; /* Assume not configured */
75bd9771 1108
12f89d24
MS
1109 libusb_get_device_descriptor (printer->device, &devdesc);
1110 libusb_get_config_descriptor (printer->device, printer->conf, &confptr);
1111 number1 = confptr->bConfigurationValue;
e4572d57 1112
12f89d24 1113 if (number1 != current)
75bd9771 1114 {
12f89d24
MS
1115 if ((errcode = libusb_set_configuration(printer->handle, number1)) < 0)
1116 {
1117 /*
1118 * If the set fails, chances are that the printer only supports a
1119 * single configuration. Technically these printers don't conform to
1120 * the USB printer specification, but otherwise they'll work...
1121 */
e4572d57 1122
12f89d24
MS
1123 if (errcode != LIBUSB_ERROR_BUSY)
1124 fprintf(stderr, "DEBUG: Failed to set configuration %d for %04x:%04x\n",
1125 number1, devdesc.idVendor, devdesc.idProduct);
1126 }
75bd9771
MS
1127 }
1128
1129 /*
12f89d24
MS
1130 * Get the "usblp" kernel module out of the way. This backend only
1131 * works without the module attached.
75bd9771
MS
1132 */
1133
12f89d24
MS
1134 errcode = libusb_kernel_driver_active(printer->handle, printer->iface);
1135 if (errcode == 0)
1136 printer->usblp_attached = 0;
1137 else if (errcode == 1)
75bd9771 1138 {
12f89d24
MS
1139 printer->usblp_attached = 1;
1140 if ((errcode =
1141 libusb_detach_kernel_driver(printer->handle, printer->iface)) < 0)
75bd9771 1142 {
12f89d24
MS
1143 fprintf(stderr, "DEBUG: Failed to detach \"usblp\" module from %04x:%04x\n",
1144 devdesc.idVendor, devdesc.idProduct);
75bd9771
MS
1145 goto error;
1146 }
12f89d24
MS
1147 }
1148 else
1149 {
1150 printer->usblp_attached = 0;
1151 fprintf(stderr, "DEBUG: Failed to check whether %04x:%04x has the \"usblp\" kernel module attached\n",
1152 devdesc.idVendor, devdesc.idProduct);
1153 goto error;
1154 }
75bd9771
MS
1155
1156 /*
12f89d24 1157 * Claim interfaces as needed...
75bd9771
MS
1158 */
1159
12f89d24
MS
1160 number1 = confptr->interface[printer->iface].
1161 altsetting[printer->altset].bInterfaceNumber;
1162
1163 while ((errcode = libusb_claim_interface(printer->handle, number1)) < 0)
75bd9771 1164 {
12f89d24 1165 if (errcode != LIBUSB_ERROR_BUSY)
75bd9771 1166 fprintf(stderr,
12f89d24
MS
1167 "DEBUG: Failed to claim interface %d for %04x:%04x: %s\n",
1168 number1, devdesc.idVendor, devdesc.idProduct, strerror(errno));
75bd9771
MS
1169
1170 goto error;
1171 }
1172
12f89d24
MS
1173 /*
1174 * Set alternate setting, but only if there is more than one option. Some
1175 * printers (e.g., Samsung) don't like usb_set_altinterface.
1176 */
1177
1178 if (confptr->interface[printer->iface].num_altsetting > 1)
1179 {
1180 number1 = confptr->interface[printer->iface].
1181 altsetting[printer->altset].bInterfaceNumber;
1182 number2 = confptr->interface[printer->iface].
1183 altsetting[printer->altset].bAlternateSetting;
1184
1185 while ((errcode =
1186 libusb_set_interface_alt_setting(printer->handle, number1, number2))
1187 < 0)
1188 {
1189 if (errcode != LIBUSB_ERROR_BUSY)
1190 fprintf(stderr,
1191 "DEBUG: Failed to set alternate interface %d for %04x:%04x: "
1192 "%s\n",
1193 number2, devdesc.idVendor, devdesc.idProduct, strerror(errno));
1194
1195 goto error;
1196 }
1197 }
1198
1199 libusb_free_config_descriptor(confptr);
1200
75bd9771
MS
1201 if (verbose)
1202 fputs("STATE: -connecting-to-device\n", stderr);
1203
1204 return (0);
1205
1206 /*
1207 * If we get here, there was a hard error...
1208 */
1209
1210 error:
1211
1212 if (verbose)
1213 fputs("STATE: -connecting-to-device\n", stderr);
1214
12f89d24 1215 libusb_close(printer->handle);
75bd9771
MS
1216 printer->handle = NULL;
1217
1218 return (-1);
1219}
1220
1221
1222/*
1223 * 'print_cb()' - Find a USB printer for printing.
1224 */
1225
1226static int /* O - 0 to continue, 1 to stop (found) */
1227print_cb(usb_printer_t *printer, /* I - Printer */
1228 const char *device_uri, /* I - Device URI */
1229 const char *device_id, /* I - IEEE-1284 device ID */
1230 const void *data) /* I - User data (make, model, S/N) */
1231{
f99f3698
MS
1232 char requested_uri[1024], /* Requested URI */
1233 *requested_ptr, /* Pointer into requested URI */
1234 detected_uri[1024], /* Detected URI */
1235 *detected_ptr; /* Pointer into detected URI */
1236
1237
1238 /*
1239 * If we have an exact match, stop now...
1240 */
1241
1242 if (!strcmp((char *)data, device_uri))
1243 return (1);
1244
1245 /*
1246 * Work on copies of the URIs...
1247 */
1248
1249 strlcpy(requested_uri, (char *)data, sizeof(requested_uri));
1250 strlcpy(detected_uri, device_uri, sizeof(detected_uri));
1251
1252 /*
1253 * libusb-discovered URIs can have an "interface" specification and this
1254 * never happens for usblp-discovered URIs, so remove the "interface"
1255 * specification from the URI which we are checking currently. This way a
1256 * queue for a usblp-discovered printer can now be accessed via libusb.
1257 *
1258 * Similarly, strip "?serial=NNN...NNN" as needed.
1259 */
1260
1261 if ((requested_ptr = strstr(requested_uri, "?interface=")) == NULL)
1262 requested_ptr = strstr(requested_uri, "&interface=");
1263 if ((detected_ptr = strstr(detected_uri, "?interface=")) == NULL)
1264 detected_ptr = strstr(detected_uri, "&interface=");
1265
1266 if (!requested_ptr && detected_ptr)
1267 {
1268 /*
1269 * Strip "[?&]interface=nnn" from the detected printer.
1270 */
1271
1272 *detected_ptr = '\0';
1273 }
1274 else if (requested_ptr && !detected_ptr)
1275 {
1276 /*
1277 * Strip "[?&]interface=nnn" from the requested printer.
1278 */
1279
1280 *requested_ptr = '\0';
1281 }
1282
1283 if ((requested_ptr = strstr(requested_uri, "?serial=?")) != NULL)
1284 {
1285 /*
1286 * Strip "?serial=?" from the requested printer. This is a special
1287 * case, as "?serial=?" means no serial number and not the serial
1288 * number '?'. This is not covered by the checks below...
1289 */
1290
1291 *requested_ptr = '\0';
1292 }
1293
1294 if ((requested_ptr = strstr(requested_uri, "?serial=")) == NULL &&
1295 (detected_ptr = strstr(detected_uri, "?serial=")) != NULL)
1296 {
1297 /*
1298 * Strip "?serial=nnn" from the detected printer.
1299 */
1300
1301 *detected_ptr = '\0';
1302 }
1303 else if (requested_ptr && !detected_ptr)
1304 {
1305 /*
1306 * Strip "?serial=nnn" from the requested printer.
1307 */
1308
1309 *requested_ptr = '\0';
1310 }
1311
1312 return (!strcmp(requested_uri, detected_uri));
75bd9771
MS
1313}
1314
1315
005dd1eb 1316/*
12f89d24 1317 * 'read_thread()' - Thread to read the backchannel data on.
005dd1eb
MS
1318 */
1319
12f89d24
MS
1320static void *read_thread(void *reference)
1321{
1322 unsigned char readbuffer[512];
1323 int rbytes;
1324 int readstatus;
1325 struct timeval now,
1326 delay,
1327 end,
1328 timeleft;
1329
1330
1331 (void)reference;
1332
1333 /*
1334 * Read frequency: once every 250 milliseconds.
1335 */
1336
1337 delay.tv_sec = 0;
1338 delay.tv_usec = 250000;
1339
1340 do
1341 {
1342 /*
1343 * Remember when we started so we can throttle the loop after the read
1344 * call...
1345 */
1346
1347 gettimeofday(&now, NULL);
1348
1349 /*
1350 * Calculate what 250 milliSeconds are in absolute time...
1351 */
1352
1353 timeradd(&now, &delay, &end);
1354
1355 rbytes = sizeof(readbuffer);
1356 readstatus = libusb_bulk_transfer(g.printer->handle,
1357 g.printer->read_endp,
1358 readbuffer, rbytes,
1359 &rbytes, 60000);
1360 if (readstatus == LIBUSB_SUCCESS && rbytes > 0)
1361 {
1362 fprintf(stderr, "DEBUG: Read %d bytes of back-channel data...\n",
1363 (int)rbytes);
1364 cupsBackChannelWrite((const char *)readbuffer, rbytes, 1.0);
1365 }
1366 else if (readstatus == LIBUSB_ERROR_TIMEOUT)
1367 fputs("DEBUG: Got USB transaction timeout during read.\n", stderr);
1368 else if (readstatus == LIBUSB_ERROR_PIPE)
1369 fputs("DEBUG: Got USB pipe stalled during read.\n", stderr);
1370 else if (readstatus == LIBUSB_ERROR_INTERRUPTED)
1371 fputs("DEBUG: Got USB return aborted during read.\n", stderr);
1372
1373 /*
1374 * Make sure this loop executes no more than once every 250 miliseconds...
1375 */
1376
1377 if ((readstatus != LIBUSB_SUCCESS || rbytes == 0) &&
1378 (g.wait_eof || !g.read_thread_stop))
1379 {
1380 gettimeofday(&now, NULL);
1381 if (timercmp(&now, &end, <))
1382 {
1383 timersub(&end, &now, &timeleft);
1384 usleep(1000000 * timeleft.tv_sec + timeleft.tv_usec);
1385 }
1386 }
1387 } while (g.wait_eof || !g.read_thread_stop);
1388
1389 /*
1390 * Let the main thread know that we have completed the read thread...
1391 */
1392
1393 pthread_mutex_lock(&g.read_thread_mutex);
1394 g.read_thread_done = 1;
1395 pthread_cond_signal(&g.read_thread_cond);
1396 pthread_mutex_unlock(&g.read_thread_mutex);
1397
1398 return (NULL);
1399}
1400
1401
1402/*
1403 * 'sidechannel_thread()' - Handle side-channel requests.
1404 */
1405
1406static void*
1407sidechannel_thread(void *reference)
005dd1eb 1408{
005dd1eb
MS
1409 cups_sc_command_t command; /* Request command */
1410 cups_sc_status_t status; /* Request/response status */
1411 char data[2048]; /* Request/response data */
1412 int datalen; /* Request/response data size */
1413
1414
12f89d24 1415 (void)reference;
005dd1eb 1416
12f89d24 1417 do
005dd1eb 1418 {
12f89d24 1419 datalen = sizeof(data);
005dd1eb 1420
12f89d24
MS
1421 if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0))
1422 {
1423 if (status == CUPS_SC_STATUS_TIMEOUT)
1424 continue;
1425 else
1426 break;
1427 }
1428
1429 switch (command)
1430 {
1431 case CUPS_SC_CMD_SOFT_RESET: /* Do a soft reset */
1432 fputs("DEBUG: CUPS_SC_CMD_SOFT_RESET received from driver...\n",
1433 stderr);
1434
1435 soft_reset();
1436 cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, NULL, 0, 1.0);
1437 fputs("DEBUG: Returning status CUPS_STATUS_OK with no bytes...\n",
1438 stderr);
1439 break;
1440
1441 case CUPS_SC_CMD_DRAIN_OUTPUT: /* Drain all pending output */
1442 fputs("DEBUG: CUPS_SC_CMD_DRAIN_OUTPUT received from driver...\n",
1443 stderr);
1444
1445 g.drain_output = 1;
1446 break;
1447
1448 case CUPS_SC_CMD_GET_BIDI: /* Is the connection bidirectional? */
1449 fputs("DEBUG: CUPS_SC_CMD_GET_BIDI received from driver...\n",
1450 stderr);
1451
1452 data[0] = (g.printer->protocol >= 2 ? 1 : 0);
1453 cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, data, 1, 1.0);
1454
1455 fprintf(stderr,
1456 "DEBUG: Returned CUPS_SC_STATUS_OK with 1 byte (%02X)...\n",
1457 data[0]);
1458 break;
1459
1460 case CUPS_SC_CMD_GET_DEVICE_ID: /* Return IEEE-1284 device ID */
1461 fputs("DEBUG: CUPS_SC_CMD_GET_DEVICE_ID received from driver...\n",
1462 stderr);
005dd1eb 1463
12f89d24
MS
1464 datalen = sizeof(data);
1465 if (get_device_id(g.printer, data, sizeof(data)))
1466 {
1467 status = CUPS_SC_STATUS_IO_ERROR;
1468 datalen = 0;
005dd1eb 1469 }
12f89d24
MS
1470 else
1471 {
1472 status = CUPS_SC_STATUS_OK;
1473 datalen = strlen(data);
1474 }
1475 cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, data, datalen, 1.0);
005dd1eb 1476
12f89d24
MS
1477 if (datalen < sizeof(data))
1478 data[datalen] = '\0';
1479 else
1480 data[sizeof(data) - 1] = '\0';
005dd1eb 1481
12f89d24
MS
1482 fprintf(stderr,
1483 "DEBUG: Returning CUPS_SC_STATUS_OK with %d bytes (%s)...\n",
1484 datalen, data);
1485 break;
005dd1eb 1486
12f89d24
MS
1487 case CUPS_SC_CMD_GET_STATE: /* Return device state */
1488 fputs("DEBUG: CUPS_SC_CMD_GET_STATE received from driver...\n",
1489 stderr);
005dd1eb 1490
12f89d24
MS
1491 data[0] = CUPS_SC_STATE_ONLINE;
1492 cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, data, 1, 1.0);
005dd1eb 1493
12f89d24
MS
1494 fprintf(stderr,
1495 "DEBUG: Returned CUPS_SC_STATUS_OK with 1 byte (%02X)...\n",
1496 data[0]);
1497 break;
1498
1499 case CUPS_SC_CMD_GET_CONNECTED: /* Return whether device is
1500 connected */
1501 fputs("DEBUG: CUPS_SC_CMD_GET_CONNECTED received from driver...\n",
1502 stderr);
1503
1504 data[0] = (g.printer->handle ? 1 : 0);
1505 cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, data, 1, 1.0);
1506
1507 fprintf(stderr,
1508 "DEBUG: Returned CUPS_SC_STATUS_OK with 1 byte (%02X)...\n",
1509 data[0]);
1510 break;
1511
1512 default:
1513 fprintf(stderr, "DEBUG: Unknown side-channel command (%d) received "
1514 "from driver...\n", command);
1515
1516 cupsSideChannelWrite(command, CUPS_SC_STATUS_NOT_IMPLEMENTED,
1517 NULL, 0, 1.0);
1518
1519 fputs("DEBUG: Returned CUPS_SC_STATUS_NOT_IMPLEMENTED with no bytes...\n",
1520 stderr);
1521 break;
1522 }
1523 }
1524 while (!g.sidechannel_thread_stop);
1525
1526 pthread_mutex_lock(&g.sidechannel_thread_mutex);
1527 g.sidechannel_thread_done = 1;
1528 pthread_cond_signal(&g.sidechannel_thread_cond);
1529 pthread_mutex_unlock(&g.sidechannel_thread_mutex);
1530
1531 return (NULL);
1532}
1533
1534
1535/*
1536 * 'soft_reset()' - Send a soft reset to the device.
1537 */
1538
1539static void soft_reset(void)
1540{
1541 fd_set input_set; /* Input set for select() */
1542 struct timeval tv; /* Time value */
1543 char buffer[2048]; /* Buffer */
1544 struct timespec cond_timeout; /* pthread condition timeout */
1545
1546 /*
1547 * Send an abort once a second until the I/O lock is released by the main
1548 * thread...
1549 */
1550
1551 pthread_mutex_lock(&g.readwrite_lock_mutex);
1552 while (g.readwrite_lock)
1553 {
1554 gettimeofday(&tv, NULL);
1555 cond_timeout.tv_sec = tv.tv_sec + 1;
1556 cond_timeout.tv_nsec = tv.tv_usec * 1000;
1557
1558 while (g.readwrite_lock)
1559 {
1560 if (pthread_cond_timedwait(&g.readwrite_lock_cond,
1561 &g.readwrite_lock_mutex,
1562 &cond_timeout) != 0)
005dd1eb 1563 break;
12f89d24 1564 }
005dd1eb
MS
1565 }
1566
12f89d24
MS
1567 g.readwrite_lock = 1;
1568 pthread_mutex_unlock(&g.readwrite_lock_mutex);
1569
1570 /*
1571 * Flush bytes waiting on print_fd...
1572 */
1573
1574 g.print_bytes = 0;
1575
1576 FD_ZERO(&input_set);
1577 FD_SET(g.print_fd, &input_set);
1578
1579 tv.tv_sec = 0;
1580 tv.tv_usec = 0;
1581
1582 while (select(g.print_fd+1, &input_set, NULL, NULL, &tv) > 0)
1583 if (read(g.print_fd, buffer, sizeof(buffer)) <= 0)
1584 break;
1585
1586 /*
1587 * Send the reset...
1588 */
1589
1590 libusb_reset_device (g.printer->handle);
1591
1592 /*
1593 * Release the I/O lock...
1594 */
005dd1eb 1595
12f89d24
MS
1596 pthread_mutex_lock(&g.readwrite_lock_mutex);
1597 g.readwrite_lock = 0;
1598 pthread_cond_signal(&g.readwrite_lock_cond);
1599 pthread_mutex_unlock(&g.readwrite_lock_mutex);
005dd1eb
MS
1600}
1601
1602
75bd9771
MS
1603/*
1604 * End of "$Id$".
1605 */
1606