~ubuntu-branches/ubuntu/wily/cups/wily

« back to all changes in this revision

Viewing changes to .pc/usb-backend-do-not-crash-if-usb-disabled-in-bios.patch/backend/usb-libusb.c

  • Committer: Package Import Robot
  • Author(s): Didier Raboud
  • Date: 2013-05-03 11:30:59 UTC
  • mfrom: (100.1.11 experimental)
  • Revision ID: package-import@ubuntu.com-20130503113059-u4vwqd3op51vu7o7
Update the patch adding libusb error handling to also discard its
errors in the counting of warning messages; this should make the
error-suite succeed in more cases.

Show diffs side-by-side

added added

removed removed

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