1 /* sane - Scanner Access Now Easy.
2 Copyright (C) 2001 - 2005 Henning Meier-Geinitz
3 Copyright (C) 2001 Frank Zago (sanei_usb_control_msg)
4 Copyright (C) 2003 Rene Rebe (sanei_read_int,sanei_set_timeout)
5 Copyright (C) 2005 Paul Smedley <paul@smedley.info> (OS/2 usbcalls)
6 Copyright (C) 2008 m. allan noah (bus rescan support, sanei_usb_clear_halt)
7 Copyright (C) 2009 Julien BLACHE <jb@jblache.org> (libusb-1.0)
8 Copyright (C) 2011 Reinhold Kainhofer <reinhold@kainhofer.com> (sanei_usb_set_endpoint)
9 This file is part of the SANE package.
10
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2 of the
14 License, or (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <https://www.gnu.org/licenses/>.
23
24 As a special exception, the authors of SANE give permission for
25 additional uses of the libraries contained in this release of SANE.
26
27 The exception is that, if you link a SANE library with other files
28 to produce an executable, this does not by itself cause the
29 resulting executable to be covered by the GNU General Public
30 License. Your use of that executable is in no way restricted on
31 account of linking the SANE library code into it.
32
33 This exception does not, however, invalidate any other reasons why
34 the executable file might be covered by the GNU General Public
35 License.
36
37 If you submit changes to SANE to the maintainers to be included in
38 a subsequent release, you agree by submitting the changes that
39 those changes may be distributed with this exception intact.
40
41 If you write modifications of your own for SANE, it is your choice
42 whether to permit this exception to apply to your modifications.
43 If you do not wish that, delete this exception notice.
44
45 This file provides a generic USB interface. */
46
47 #include "../include/sane/config.h"
48
49 #ifdef HAVE_STDINT_H
50 # include <stdint.h>
51 #endif
52 #include <stdlib.h>
53 #include <ctype.h>
54 #include <sys/types.h>
55 #include <sys/stat.h>
56 #include <fcntl.h>
57 #include <errno.h>
58 #include <string.h>
59 #include <unistd.h>
60 #ifdef HAVE_SYS_IOCTL_H
61 #include <sys/ioctl.h>
62 #endif
63 #include <stdio.h>
64 #include <dirent.h>
65 #include <time.h>
66
67 #if WITH_USB_RECORD_REPLAY
68 #include <libxml/parser.h>
69 #include <libxml/tree.h>
70 #endif
71
72 #ifdef HAVE_RESMGR
73 #include <resmgr.h>
74 #endif
75
76 #ifdef HAVE_LIBUSB_LEGACY
77 #ifdef HAVE_LUSB0_USB_H
78 #include <lusb0_usb.h>
79 #else
80 #include <usb.h>
81 #endif
82 #endif /* HAVE_LIBUSB_LEGACY */
83
84 #ifdef HAVE_LIBUSB
85 #include <libusb.h>
86 #endif /* HAVE_LIBUSB */
87
88 #ifdef HAVE_USBCALLS
89 #include <usb.h>
90 #include <os2.h>
91 #include <usbcalls.h>
92 #define MAX_RW 64000
93 static int usbcalls_timeout = 30 * 1000; /* 30 seconds */
94 USBHANDLE dh;
95 PHEV pUsbIrqStartHev=NULL;
96
97 static
98 struct usb_descriptor_header *
GetNextDescriptor(struct usb_descriptor_header * currHead,UCHAR * lastBytePtr)99 GetNextDescriptor( struct usb_descriptor_header *currHead, UCHAR *lastBytePtr)
100 {
101 UCHAR *currBytePtr, *nextBytePtr;
102
103 if (!currHead->bLength)
104 return (NULL);
105 currBytePtr=(UCHAR *)currHead;
106 nextBytePtr=currBytePtr+currHead->bLength;
107 if (nextBytePtr>=lastBytePtr)
108 return (NULL);
109 return ((struct usb_descriptor_header*)nextBytePtr);
110 }
111 #endif /* HAVE_USBCALLS */
112
113 #if (defined (__FreeBSD__) && (__FreeBSD_version < 800064))
114 #include <sys/param.h>
115 #include <dev/usb/usb.h>
116 #endif /* __FreeBSD__ */
117 #if defined (__DragonFly__)
118 #include <bus/usb/usb.h>
119 #endif
120
121 #define BACKEND_NAME sanei_usb
122 #include "../include/sane/sane.h"
123 #include "../include/sane/sanei_debug.h"
124 #include "../include/sane/sanei_usb.h"
125 #include "../include/sane/sanei_config.h"
126
127 typedef enum
128 {
129 sanei_usb_method_scanner_driver = 0, /* kernel scanner driver
130 (Linux, BSD) */
131 sanei_usb_method_libusb,
132
133 sanei_usb_method_usbcalls
134 }
135 sanei_usb_access_method_type;
136
137 typedef struct
138 {
139 SANE_Bool open;
140 sanei_usb_access_method_type method;
141 int fd;
142 SANE_String devname;
143 SANE_Int vendor;
144 SANE_Int product;
145 SANE_Int bulk_in_ep;
146 SANE_Int bulk_out_ep;
147 SANE_Int iso_in_ep;
148 SANE_Int iso_out_ep;
149 SANE_Int int_in_ep;
150 SANE_Int int_out_ep;
151 SANE_Int control_in_ep;
152 SANE_Int control_out_ep;
153 SANE_Int interface_nr;
154 SANE_Int alt_setting;
155 SANE_Int missing;
156 #ifdef HAVE_LIBUSB_LEGACY
157 usb_dev_handle *libusb_handle;
158 struct usb_device *libusb_device;
159 #endif /* HAVE_LIBUSB_LEGACY */
160 #ifdef HAVE_LIBUSB
161 libusb_device *lu_device;
162 libusb_device_handle *lu_handle;
163 #endif /* HAVE_LIBUSB */
164 }
165 device_list_type;
166
167 /**
168 * total number of devices that can be found at the same time */
169 #define MAX_DEVICES 100
170
171 /**
172 * per-device information, using the functions' parameters dn as index */
173 static device_list_type devices[MAX_DEVICES];
174
175 /**
176 * total number of detected devices in devices array */
177 static int device_number=0;
178
179 /**
180 * count number of time sanei_usb has been initialized */
181 static int initialized=0;
182
183 typedef enum
184 {
185 sanei_usb_testing_mode_disabled = 0,
186
187 sanei_usb_testing_mode_record, // records the communication with the slave
188 // but does not change the USB stack in any
189 // way
190 sanei_usb_testing_mode_replay, // replays the communication with the scanner
191 // recorded earlier
192 }
193 sanei_usb_testing_mode;
194
195 // Whether testing mode has been enabled
196 static sanei_usb_testing_mode testing_mode = sanei_usb_testing_mode_disabled;
197
198 #if WITH_USB_RECORD_REPLAY
199 static int testing_development_mode = 0;
200 static int testing_already_opened = 0;
201 static int testing_known_commands_input_failed = 0;
202 static unsigned testing_last_known_seq = 0;
203 static SANE_String testing_record_backend = NULL;
204 static xmlNode* testing_append_commands_node = NULL;
205
206 // XML file from which we read testing data
207 static SANE_String testing_xml_path = NULL;
208 static xmlDoc* testing_xml_doc = NULL;
209 static xmlNode* testing_xml_next_tx_node = NULL;
210 #endif // WITH_USB_RECORD_REPLAY
211
212 #if defined(HAVE_LIBUSB_LEGACY) || defined(HAVE_LIBUSB)
213 static int libusb_timeout = 30 * 1000; /* 30 seconds */
214 #endif /* HAVE_LIBUSB_LEGACY */
215
216 #ifdef HAVE_LIBUSB
217 static libusb_context *sanei_usb_ctx;
218 #endif /* HAVE_LIBUSB */
219
220 #if defined (__APPLE__)
221 /* macOS won't configure several USB scanners (i.e. ScanSnap 300M) because their
222 * descriptors are vendor specific. As a result the device will get configured
223 * later during sanei_usb_open making it safe to ignore the configuration check
224 * on these platforms. */
225 #define SANEI_ALLOW_UNCONFIGURED_DEVICES
226 #endif
227
228 #if defined (__linux__)
229 /* From /usr/src/linux/driver/usb/scanner.h */
230 #define SCANNER_IOCTL_VENDOR _IOR('U', 0x20, int)
231 #define SCANNER_IOCTL_PRODUCT _IOR('U', 0x21, int)
232 #define SCANNER_IOCTL_CTRLMSG _IOWR('U', 0x22, devrequest)
233 /* Older (unofficial) IOCTL numbers for Linux < v2.4.13 */
234 #define SCANNER_IOCTL_VENDOR_OLD _IOR('u', 0xa0, int)
235 #define SCANNER_IOCTL_PRODUCT_OLD _IOR('u', 0xa1, int)
236
237 /* From /usr/src/linux/include/linux/usb.h */
238 typedef struct
239 {
240 unsigned char requesttype;
241 unsigned char request;
242 unsigned short value;
243 unsigned short index;
244 unsigned short length;
245 }
246 devrequest;
247
248 /* From /usr/src/linux/driver/usb/scanner.h */
249 struct ctrlmsg_ioctl
250 {
251 devrequest req;
252 void *data;
253 }
254 cmsg;
255 #elif defined(__BEOS__)
256 #include <drivers/USB_scanner.h>
257 #include <kernel/OS.h>
258 #endif /* __linux__ */
259
260 /* Debug level from sanei_init_debug */
261 static SANE_Int debug_level;
262
263 static void
print_buffer(const SANE_Byte * buffer,SANE_Int size)264 print_buffer (const SANE_Byte * buffer, SANE_Int size)
265 {
266 #define NUM_COLUMNS 16
267 #define PRINT_BUFFER_SIZE (4 + NUM_COLUMNS * (3 + 1) + 1 + 1)
268 char line_str[PRINT_BUFFER_SIZE];
269 char *pp;
270 int column;
271 int line;
272
273 memset (line_str, 0, PRINT_BUFFER_SIZE);
274
275 for (line = 0; line < ((size + NUM_COLUMNS - 1) / NUM_COLUMNS); line++)
276 {
277 pp = line_str;
278 sprintf (pp, "%03X ", line * NUM_COLUMNS);
279 pp += 4;
280 for (column = 0; column < NUM_COLUMNS; column++)
281 {
282 if ((line * NUM_COLUMNS + column) < size)
283 sprintf (pp, "%02X ", buffer[line * NUM_COLUMNS + column]);
284 else
285 sprintf (pp, " ");
286 pp += 3;
287 }
288 for (column = 0; column < NUM_COLUMNS; column++)
289 {
290 if ((line * NUM_COLUMNS + column) < size)
291 sprintf (pp, "%c",
292 (buffer[line * NUM_COLUMNS + column] < 127) &&
293 (buffer[line * NUM_COLUMNS + column] > 31) ?
294 buffer[line * NUM_COLUMNS + column] : '.');
295 else
296 sprintf (pp, " ");
297 pp += 1;
298 }
299 DBG (11, "%s\n", line_str);
300 }
301 }
302
303 #if !defined(HAVE_LIBUSB_LEGACY) && !defined(HAVE_LIBUSB)
304 static void
kernel_get_vendor_product(int fd,const char * name,int * vendorID,int * productID)305 kernel_get_vendor_product (int fd, const char *name, int *vendorID, int *productID)
306 {
307 #if defined (__linux__)
308 /* read the vendor and product IDs via the IOCTLs */
309 if (ioctl (fd, SCANNER_IOCTL_VENDOR, vendorID) == -1)
310 {
311 if (ioctl (fd, SCANNER_IOCTL_VENDOR_OLD, vendorID) == -1)
312 DBG (3, "kernel_get_vendor_product: ioctl (vendor) "
313 "of device %s failed: %s\n", name, strerror (errno));
314 }
315 if (ioctl (fd, SCANNER_IOCTL_PRODUCT, productID) == -1)
316 {
317 if (ioctl (fd, SCANNER_IOCTL_PRODUCT_OLD, productID) == -1)
318 DBG (3, "sanei_usb_get_vendor_product: ioctl (product) "
319 "of device %s failed: %s\n", name, strerror (errno));
320 }
321 #elif defined(__BEOS__)
322 {
323 uint16 vendor, product;
324 if (ioctl (fd, B_SCANNER_IOCTL_VENDOR, &vendor) != B_OK)
325 DBG (3, "kernel_get_vendor_product: ioctl (vendor) "
326 "of device %d failed: %s\n", fd, strerror (errno));
327 if (ioctl (fd, B_SCANNER_IOCTL_PRODUCT, &product) != B_OK)
328 DBG (3, "sanei_usb_get_vendor_product: ioctl (product) "
329 "of device %d failed: %s\n", fd, strerror (errno));
330 /* copy from 16 to 32 bit value */
331 *vendorID = vendor;
332 *productID = product;
333 }
334 #elif (defined (__FreeBSD__) && __FreeBSD_version < 800064) || defined (__DragonFly__)
335 {
336 int controller;
337 int ctrl_fd;
338 char buf[40];
339 int dev;
340
341 for (controller = 0; ; controller++ )
342 {
343 snprintf (buf, sizeof (buf) - 1, "/dev/usb%d", controller);
344 ctrl_fd = open (buf, O_RDWR);
345
346 /* If we can not open the usb controller device, treat it
347 as the end of controller devices */
348 if (ctrl_fd < 0)
349 break;
350
351 /* Search for the scanner device on this bus */
352 for (dev = 1; dev < USB_MAX_DEVICES; dev++)
353 {
354 struct usb_device_info devInfo;
355 devInfo.udi_addr = dev;
356
357 if (ioctl (ctrl_fd, USB_DEVICEINFO, &devInfo) == -1)
358 break; /* Treat this as the end of devices for this controller */
359
360 snprintf (buf, sizeof (buf), "/dev/%s", devInfo.udi_devnames[0]);
361 if (strncmp (buf, name, sizeof (buf)) == 0)
362 {
363 *vendorID = (int) devInfo.udi_vendorNo;
364 *productID = (int) devInfo.udi_productNo;
365 close (ctrl_fd);
366 return;
367 }
368 }
369 close (ctrl_fd);
370 }
371 DBG (3, "kernel_get_vendor_product: Could not retrieve "
372 "vendor/product ID from device %s\n", name);
373 }
374 #endif /* defined (__linux__), defined(__BEOS__), ... */
375 /* put more os-dependant stuff ... */
376 }
377 #endif /* !defined(HAVE_LIBUSB_LEGACY) && !defined(HAVE_LIBUSB) */
378
379 /**
380 * store the given device in device list if it isn't already
381 * in it
382 * @param device device to store if new
383 */
384 static void
store_device(device_list_type device)385 store_device (device_list_type device)
386 {
387 int i = 0;
388 int pos = -1;
389
390 /* if there are already some devices present, check against
391 * them and leave if an equal one is found */
392 for (i = 0; i < device_number; i++)
393 {
394 if (devices[i].method == device.method
395 && !strcmp (devices[i].devname, device.devname)
396 && devices[i].vendor == device.vendor
397 && devices[i].product == device.product)
398 {
399 /*
400 * Need to update the LibUSB device pointer, since it might
401 * have changed after the latest USB scan.
402 */
403 #ifdef HAVE_LIBUSB_LEGACY
404 devices[i].libusb_device = device.libusb_device;
405 #endif
406 #ifdef HAVE_LIBUSB
407 devices[i].lu_device = device.lu_device;
408 #endif
409
410 devices[i].missing=0;
411 DBG (3, "store_device: not storing device %s\n", device.devname);
412
413 /* since devname has been created by strdup()
414 * we have to free it to avoid leaking memory */
415 free(device.devname);
416 return;
417 }
418 if (devices[i].missing >= 2)
419 pos = i;
420 }
421
422 /* reuse slot of a device now missing */
423 if(pos > -1){
424 DBG (3, "store_device: overwrite dn %d with %s\n", pos, device.devname);
425 /* we reuse the slot used by a now missing device
426 * so we free the allocated memory for the missing one */
427 if (devices[pos].devname) {
428 free(devices[pos].devname);
429 devices[pos].devname = NULL;
430 }
431 }
432 else{
433 if(device_number >= MAX_DEVICES){
434 DBG (3, "store_device: no room for %s\n", device.devname);
435 return;
436 }
437 pos = device_number;
438 device_number++;
439 DBG (3, "store_device: add dn %d with %s\n", pos, device.devname);
440 }
441 memcpy (&(devices[pos]), &device, sizeof (device));
442 devices[pos].open = SANE_FALSE;
443 }
444
445 #ifdef HAVE_LIBUSB
446 static char *
sanei_libusb_strerror(int errcode)447 sanei_libusb_strerror (int errcode)
448 {
449 /* Error codes & descriptions from the libusb-1.0 documentation */
450
451 switch (errcode)
452 {
453 case LIBUSB_SUCCESS:
454 return "Success (no error)";
455
456 case LIBUSB_ERROR_IO:
457 return "Input/output error";
458
459 case LIBUSB_ERROR_INVALID_PARAM:
460 return "Invalid parameter";
461
462 case LIBUSB_ERROR_ACCESS:
463 return "Access denied (insufficient permissions)";
464
465 case LIBUSB_ERROR_NO_DEVICE:
466 return "No such device (it may have been disconnected)";
467
468 case LIBUSB_ERROR_NOT_FOUND:
469 return "Entity not found";
470
471 case LIBUSB_ERROR_BUSY:
472 return "Resource busy";
473
474 case LIBUSB_ERROR_TIMEOUT:
475 return "Operation timed out";
476
477 case LIBUSB_ERROR_OVERFLOW:
478 return "Overflow";
479
480 case LIBUSB_ERROR_PIPE:
481 return "Pipe error";
482
483 case LIBUSB_ERROR_INTERRUPTED:
484 return "System call interrupted (perhaps due to signal)";
485
486 case LIBUSB_ERROR_NO_MEM:
487 return "Insufficient memory";
488
489 case LIBUSB_ERROR_NOT_SUPPORTED:
490 return "Operation not supported or unimplemented on this platform";
491
492 case LIBUSB_ERROR_OTHER:
493 return "Other error";
494
495 default:
496 return "Unknown libusb-1.0 error code";
497 }
498 }
499 #endif /* HAVE_LIBUSB */
500
501 #if WITH_USB_RECORD_REPLAY
sanei_usb_testing_enable_replay(SANE_String_Const path,int development_mode)502 SANE_Status sanei_usb_testing_enable_replay(SANE_String_Const path,
503 int development_mode)
504 {
505 testing_mode = sanei_usb_testing_mode_replay;
506 testing_development_mode = development_mode;
507
508 // TODO: we'll leak if no one ever inits sane_usb properly
509 testing_xml_path = strdup(path);
510 testing_xml_doc = xmlReadFile(testing_xml_path, NULL, 0);
511 if (!testing_xml_doc)
512 return SANE_STATUS_ACCESS_DENIED;
513
514 return SANE_STATUS_GOOD;
515 }
516
517 #define FAIL_TEST(func, ...) \
518 do { \
519 DBG(1, "%s: FAIL: ", func); \
520 DBG(1, __VA_ARGS__); \
521 fail_test(); \
522 } while (0)
523
524 #define FAIL_TEST_TX(func, node, ...) \
525 do { \
526 sanei_xml_print_seq_if_any(node, func); \
527 DBG(1, "%s: FAIL: ", func); \
528 DBG(1, __VA_ARGS__); \
529 fail_test(); \
530 } while (0)
531
fail_test()532 void fail_test()
533 {
534 }
535
sanei_usb_testing_enable_record(SANE_String_Const path,SANE_String_Const be_name)536 SANE_Status sanei_usb_testing_enable_record(SANE_String_Const path, SANE_String_Const be_name)
537 {
538 testing_mode = sanei_usb_testing_mode_record;
539 testing_record_backend = strdup(be_name);
540 testing_xml_path = strdup(path);
541
542 return SANE_STATUS_GOOD;
543 }
544
sanei_xml_find_first_child_with_name(xmlNode * parent,const char * name)545 static xmlNode* sanei_xml_find_first_child_with_name(xmlNode* parent,
546 const char* name)
547 {
548 xmlNode* curr_child = xmlFirstElementChild(parent);
549 while (curr_child != NULL)
550 {
551 if (xmlStrcmp(curr_child->name, (const xmlChar*)name) == 0)
552 return curr_child;
553 curr_child = xmlNextElementSibling(curr_child);
554 }
555 return NULL;
556 }
557
sanei_xml_find_next_child_with_name(xmlNode * child,const char * name)558 static xmlNode* sanei_xml_find_next_child_with_name(xmlNode* child,
559 const char* name)
560 {
561 xmlNode* curr_child = xmlNextElementSibling(child);
562 while (curr_child != NULL)
563 {
564 if (xmlStrcmp(curr_child->name, (const xmlChar*)name) == 0)
565 return curr_child;
566 curr_child = xmlNextElementSibling(curr_child);
567 }
568 return NULL;
569 }
570
571 // a wrapper to get rid of -Wpointer-sign warnings in a single place
sanei_xml_get_prop(xmlNode * node,const char * name)572 static char* sanei_xml_get_prop(xmlNode* node, const char* name)
573 {
574 return (char*)xmlGetProp(node, (const xmlChar*)name);
575 }
576
577 // returns -1 if attribute is not found
sanei_xml_get_prop_uint(xmlNode * node,const char * name)578 static int sanei_xml_get_prop_uint(xmlNode* node, const char* name)
579 {
580 char* attr = sanei_xml_get_prop(node, name);
581 if (attr == NULL)
582 {
583 return -1;
584 }
585
586 unsigned attr_uint = strtoul(attr, NULL, 0);
587 xmlFree(attr);
588 return attr_uint;
589 }
590
sanei_xml_print_seq_if_any(xmlNode * node,const char * parent_fun)591 static void sanei_xml_print_seq_if_any(xmlNode* node, const char* parent_fun)
592 {
593 char* attr = sanei_xml_get_prop(node, "seq");
594 if (attr == NULL)
595 return;
596
597 DBG(1, "%s: FAIL: in transaction with seq %s:\n", parent_fun, attr);
598 xmlFree(attr);
599 }
600
601 // Checks whether transaction should be ignored. We ignore set_configuration
602 // transactions, because set_configuration is called in sanei_usb_open outside test path.
sanei_xml_is_transaction_ignored(xmlNode * node)603 static int sanei_xml_is_transaction_ignored(xmlNode* node)
604 {
605 if (xmlStrcmp(node->name, (const xmlChar*)"control_tx") != 0)
606 return 0;
607
608 if (sanei_xml_get_prop_uint(node, "endpoint_number") != 0)
609 return 0;
610
611 int is_direction_in = 0;
612 int is_direction_out = 0;
613
614 char* attr = sanei_xml_get_prop(node, "direction");
615 if (attr == NULL)
616 return 0;
617
618 if (strcmp(attr, "IN") == 0)
619 is_direction_in = 1;
620 if (strcmp(attr, "OUT") == 0)
621 is_direction_out = 1;
622 xmlFree(attr);
623
624 unsigned bRequest = sanei_xml_get_prop_uint(node, "bRequest");
625 if (bRequest == USB_REQ_GET_DESCRIPTOR && is_direction_in)
626 {
627 if (sanei_xml_get_prop_uint(node, "bmRequestType") != 0x80)
628 return 0;
629 return 1;
630 }
631 if (bRequest == USB_REQ_SET_CONFIGURATION && is_direction_out)
632 return 1;
633
634 return 0;
635 }
636
sanei_xml_skip_non_tx_nodes(xmlNode * node)637 static xmlNode* sanei_xml_skip_non_tx_nodes(xmlNode* node)
638 {
639 const char* known_node_names[] = {
640 "control_tx", "bulk_tx", "interrupt_tx",
641 "get_descriptor", "debug", "known_commands_end"
642 };
643
644 while (node != NULL)
645 {
646 int found = 0;
647 for (unsigned i = 0; i < sizeof(known_node_names) /
648 sizeof(known_node_names[0]); ++i)
649 {
650 if (xmlStrcmp(node->name, (const xmlChar*) known_node_names[i]) == 0)
651 {
652 found = 1;
653 break;
654 }
655 }
656
657 if (found && sanei_xml_is_transaction_ignored(node) == 0)
658 {
659 break;
660 }
661
662 node = xmlNextElementSibling(node);
663 }
664 return node;
665 }
666
sanei_xml_is_known_commands_end(xmlNode * node)667 static int sanei_xml_is_known_commands_end(xmlNode* node)
668 {
669 if (!testing_development_mode || node == NULL)
670 return 0;
671 return xmlStrcmp(node->name, (const xmlChar*)"known_commands_end") == 0;
672 }
673
sanei_xml_peek_next_tx_node()674 static xmlNode* sanei_xml_peek_next_tx_node()
675 {
676 return testing_xml_next_tx_node;
677 }
678
sanei_xml_get_next_tx_node()679 static xmlNode* sanei_xml_get_next_tx_node()
680 {
681 xmlNode* next = testing_xml_next_tx_node;
682
683 if (sanei_xml_is_known_commands_end(next))
684 {
685 testing_append_commands_node = xmlPreviousElementSibling(next);
686 return next;
687 }
688
689 testing_xml_next_tx_node =
690 xmlNextElementSibling(testing_xml_next_tx_node);
691
692 testing_xml_next_tx_node =
693 sanei_xml_skip_non_tx_nodes(testing_xml_next_tx_node);
694
695 return next;
696 }
697
698 #define CHAR_TYPE_INVALID -1
699 #define CHAR_TYPE_SPACE -2
700
701 static int8_t sanei_xml_char_types[256] =
702 {
703 /* 0x00-0x0f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -1, -1,
704 /* 0x10-0x1f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
705 /* 0x20-0x2f */ -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
706 /* 0x30-0x3f */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
707 /* 0x40-0x4f */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
708 /* 0x50-0x5f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
709 /* 0x60-0x6f */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
710 /* 0x70-0x7f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
711 /* 0x80-0x8f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
712 /* 0x90-0x9f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
713 /* 0xa0-0xaf */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
714 /* 0xb0-0xbf */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
715 /* 0xc0-0xcf */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
716 /* 0xd0-0xdf */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
717 /* 0xe0-0xef */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
718 /* 0xf0-0xff */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
719 };
720
sanei_xml_get_hex_data_slow_path(xmlNode * node,xmlChar * content,xmlChar * cur_content,char * ret_data,char * cur_ret_data,size_t * size)721 static char* sanei_xml_get_hex_data_slow_path(xmlNode* node, xmlChar* content, xmlChar* cur_content,
722 char* ret_data, char* cur_ret_data, size_t* size)
723 {
724 int num_nibbles = 0;
725 unsigned cur_nibble = 0;
726
727 while (*cur_content != 0)
728 {
729 while (sanei_xml_char_types[(uint8_t)*cur_content] == CHAR_TYPE_SPACE)
730 cur_content++;
731
732 if (*cur_content == 0)
733 break;
734
735 // don't use stroul because it will parse in big-endian and data is in
736 // little endian
737 uint8_t c = *cur_content;
738 int8_t ci = sanei_xml_char_types[c];
739 if (ci == CHAR_TYPE_INVALID)
740 {
741 FAIL_TEST_TX(__func__, node, "unexpected character %c\n", c);
742 cur_content++;
743 continue;
744 }
745
746 cur_nibble = (cur_nibble << 4) | ci;
747 num_nibbles++;
748
749 if (num_nibbles == 2)
750 {
751 *cur_ret_data++ = cur_nibble;
752 cur_nibble = 0;
753 num_nibbles = 0;
754 }
755 cur_content++;
756 }
757 *size = cur_ret_data - ret_data;
758 xmlFree(content);
759 return ret_data;
760 }
761
762 // Parses hex data in XML text node in the format of '00 11 ab 3f', etc. to
763 // binary string. The size is returned as *size. The caller is responsible for
764 // freeing the returned value
sanei_xml_get_hex_data(xmlNode * node,size_t * size)765 static char* sanei_xml_get_hex_data(xmlNode* node, size_t* size)
766 {
767 xmlChar* content = xmlNodeGetContent(node);
768
769 // let's overallocate to simplify the implementation. We expect the string
770 // to be deallocated soon anyway
771 char* ret_data = malloc(strlen((const char*)content) / 2 + 2);
772 char* cur_ret_data = ret_data;
773
774 xmlChar* cur_content = content;
775
776 // the text to binary conversion takes most of the time spent in tests, so we
777 // take extra care to optimize it. We split the implementation into fast and
778 // slow path. The fast path utilizes the knowledge that there will be no spaces
779 // within bytes. When this assumption does not hold, we switch to the slow path.
780 while (*cur_content != 0)
781 {
782 // most of the time there will be 1 or 2 spaces between bytes. Give the CPU
783 // chance to predict this by partially unrolling the while loop.
784 if (sanei_xml_char_types[(uint8_t)*cur_content] == CHAR_TYPE_SPACE)
785 {
786 cur_content++;
787 if (sanei_xml_char_types[(uint8_t)*cur_content] == CHAR_TYPE_SPACE)
788 {
789 cur_content++;
790 while (sanei_xml_char_types[(uint8_t)*cur_content] == CHAR_TYPE_SPACE)
791 cur_content++;
792 }
793 }
794
795 if (*cur_content == 0)
796 break;
797
798 // don't use stroul because it will parse in big-endian and data is in
799 // little endian
800 int8_t ci1 = sanei_xml_char_types[(uint8_t)*cur_content];
801 int8_t ci2 = sanei_xml_char_types[(uint8_t)*(cur_content + 1)];
802
803 if (ci1 < 0 || ci2 < 0)
804 return sanei_xml_get_hex_data_slow_path(node, content, cur_content, ret_data, cur_ret_data,
805 size);
806
807 *cur_ret_data++ = ci1 << 4 | ci2;
808 cur_content += 2;
809 }
810 *size = cur_ret_data - ret_data;
811 xmlFree(content);
812 return ret_data;
813 }
814
815 // caller is responsible for freeing the returned pointer
sanei_binary_to_hex_data(const char * data,size_t size,size_t * out_size)816 static char* sanei_binary_to_hex_data(const char* data, size_t size,
817 size_t* out_size)
818 {
819 char* hex_data = malloc(size * 4);
820 size_t hex_size = 0;
821
822 for (size_t i = 0; i < size; ++i)
823 {
824 hex_size += snprintf(hex_data + hex_size, 3, "%02hhx", data[i]);
825 if (i + 1 != size)
826 {
827 if ((i + 1) % 32 == 0)
828 hex_data[hex_size++] = '\n';
829 else
830 hex_data[hex_size++] = ' ';
831 }
832 }
833 hex_data[hex_size] = 0;
834 if (out_size)
835 *out_size = hex_size;
836 return hex_data;
837 }
838
839
sanei_xml_set_data(xmlNode * node,const char * data)840 static void sanei_xml_set_data(xmlNode* node, const char* data)
841 {
842 // FIXME: remove existing children
843 xmlAddChild(node, xmlNewText((const xmlChar*)data));
844 }
845
846 // Writes binary data to XML node as a child text node in the hex format of
847 // '00 11 ab 3f'.
sanei_xml_set_hex_data(xmlNode * node,const char * data,size_t size)848 static void sanei_xml_set_hex_data(xmlNode* node, const char* data,
849 size_t size)
850 {
851 char* hex_data = sanei_binary_to_hex_data(data, size, NULL);
852 sanei_xml_set_data(node, hex_data);
853 free(hex_data);
854 }
855
sanei_xml_set_hex_attr(xmlNode * node,const char * attr_name,unsigned attr_value)856 static void sanei_xml_set_hex_attr(xmlNode* node, const char* attr_name,
857 unsigned attr_value)
858 {
859 const int buf_size = 128;
860 char buf[buf_size];
861 if (attr_value > 0xffffff)
862 snprintf(buf, buf_size, "0x%x", attr_value);
863 else if (attr_value > 0xffff)
864 snprintf(buf, buf_size, "0x%06x", attr_value);
865 else if (attr_value > 0xff)
866 snprintf(buf, buf_size, "0x%04x", attr_value);
867 else
868 snprintf(buf, buf_size, "0x%02x", attr_value);
869
870 xmlNewProp(node, (const xmlChar*)attr_name, (const xmlChar*)buf);
871 }
872
sanei_xml_set_uint_attr(xmlNode * node,const char * attr_name,unsigned attr_value)873 static void sanei_xml_set_uint_attr(xmlNode* node, const char* attr_name,
874 unsigned attr_value)
875 {
876 const int buf_size = 128;
877 char buf[buf_size];
878 snprintf(buf, buf_size, "%d", attr_value);
879 xmlNewProp(node, (const xmlChar*)attr_name, (const xmlChar*)buf);
880 }
881
sanei_xml_append_command(xmlNode * sibling,int indent,xmlNode * e_command)882 static xmlNode* sanei_xml_append_command(xmlNode* sibling,
883 int indent, xmlNode* e_command)
884 {
885 if (indent)
886 {
887 xmlNode* e_indent = xmlNewText((const xmlChar*)"\n ");
888 sibling = xmlAddNextSibling(sibling, e_indent);
889 }
890 return xmlAddNextSibling(sibling, e_command);
891 }
892
sanei_xml_command_common_props(xmlNode * node,int endpoint_number,const char * direction)893 static void sanei_xml_command_common_props(xmlNode* node, int endpoint_number,
894 const char* direction)
895 {
896 xmlNewProp(node, (const xmlChar*)"time_usec", (const xmlChar*)"0");
897 sanei_xml_set_uint_attr(node, "seq", ++testing_last_known_seq);
898 sanei_xml_set_uint_attr(node, "endpoint_number", endpoint_number);
899 xmlNewProp(node, (const xmlChar*)"direction", (const xmlChar*)direction);
900 }
901
sanei_xml_record_seq(xmlNode * node)902 static void sanei_xml_record_seq(xmlNode* node)
903 {
904 int seq = sanei_xml_get_prop_uint(node, "seq");
905 if (seq > 0)
906 testing_last_known_seq = seq;
907 }
908
sanei_xml_break()909 static void sanei_xml_break()
910 {
911 }
912
sanei_xml_break_if_needed(xmlNode * node)913 static void sanei_xml_break_if_needed(xmlNode* node)
914 {
915 char* attr = sanei_xml_get_prop(node, "debug_break");
916 if (attr != NULL)
917 {
918 sanei_xml_break();
919 xmlFree(attr);
920 }
921 }
922
923 // returns 1 on success
sanei_usb_check_attr(xmlNode * node,const char * attr_name,const char * expected,const char * parent_fun)924 static int sanei_usb_check_attr(xmlNode* node, const char* attr_name,
925 const char* expected, const char* parent_fun)
926 {
927 char* attr = sanei_xml_get_prop(node, attr_name);
928 if (attr == NULL)
929 {
930 FAIL_TEST_TX(parent_fun, node, "no %s attribute\n", attr_name);
931 return 0;
932 }
933
934 if (strcmp(attr, expected) != 0)
935 {
936 FAIL_TEST_TX(parent_fun, node, "unexpected %s attribute: %s, wanted %s\n",
937 attr_name, attr, expected);
938 xmlFree(attr);
939 return 0;
940 }
941 xmlFree(attr);
942 return 1;
943 }
944
945 // returns 1 on success
sanei_usb_attr_is(xmlNode * node,const char * attr_name,const char * expected)946 static int sanei_usb_attr_is(xmlNode* node, const char* attr_name,
947 const char* expected)
948 {
949 char* attr = sanei_xml_get_prop(node, attr_name);
950 if (attr == NULL)
951 return 0;
952
953 if (strcmp(attr, expected) != 0)
954 {
955 xmlFree(attr);
956 return 0;
957 }
958 xmlFree(attr);
959 return 1;
960 }
961
962 // returns 0 on success
sanei_usb_check_attr_uint(xmlNode * node,const char * attr_name,unsigned expected,const char * parent_fun)963 static int sanei_usb_check_attr_uint(xmlNode* node, const char* attr_name,
964 unsigned expected, const char* parent_fun)
965 {
966 char* attr = sanei_xml_get_prop(node, attr_name);
967 if (attr == NULL)
968 {
969 FAIL_TEST_TX(parent_fun, node, "no %s attribute\n", attr_name);
970 return 0;
971 }
972
973 unsigned attr_int = strtoul(attr, NULL, 0);
974 if (attr_int != expected)
975 {
976 FAIL_TEST_TX(parent_fun, node,
977 "unexpected %s attribute: %s, wanted 0x%x\n",
978 attr_name, attr, expected);
979 xmlFree(attr);
980 return 0;
981 }
982 xmlFree(attr);
983 return 1;
984 }
985
sanei_usb_attr_is_uint(xmlNode * node,const char * attr_name,unsigned expected)986 static int sanei_usb_attr_is_uint(xmlNode* node, const char* attr_name,
987 unsigned expected)
988 {
989 char* attr = sanei_xml_get_prop(node, attr_name);
990 if (attr == NULL)
991 return 0;
992
993 unsigned attr_int = strtoul(attr, NULL, 0);
994 if (attr_int != expected)
995 {
996 xmlFree(attr);
997 return 0;
998 }
999 xmlFree(attr);
1000 return 1;
1001 }
1002
1003 // returns 1 on data equality
sanei_usb_check_data_equal(xmlNode * node,const char * data,size_t data_size,const char * expected_data,size_t expected_size,const char * parent_fun)1004 static int sanei_usb_check_data_equal(xmlNode* node,
1005 const char* data,
1006 size_t data_size,
1007 const char* expected_data,
1008 size_t expected_size,
1009 const char* parent_fun)
1010 {
1011 if ((data_size == expected_size) &&
1012 (memcmp(data, expected_data, data_size) == 0))
1013 return 1;
1014
1015 char* data_hex = sanei_binary_to_hex_data(data, data_size, NULL);
1016 char* expected_hex = sanei_binary_to_hex_data(expected_data, expected_size,
1017 NULL);
1018
1019 if (data_size == expected_size)
1020 FAIL_TEST_TX(parent_fun, node, "data differs (size %lu):\n", data_size);
1021 else
1022 FAIL_TEST_TX(parent_fun, node,
1023 "data differs (got size %lu, expected %lu):\n",
1024 data_size, expected_size);
1025
1026 FAIL_TEST(parent_fun, "got: %s\n", data_hex);
1027 FAIL_TEST(parent_fun, "expected: %s\n", expected_hex);
1028 free(data_hex);
1029 free(expected_hex);
1030 return 0;
1031 }
1032
sanei_usb_testing_get_backend()1033 SANE_String sanei_usb_testing_get_backend()
1034 {
1035 if (testing_xml_doc == NULL)
1036 return NULL;
1037
1038 xmlNode* el_root = xmlDocGetRootElement(testing_xml_doc);
1039 if (xmlStrcmp(el_root->name, (const xmlChar*)"device_capture") != 0)
1040 {
1041 FAIL_TEST(__func__, "the given file is not USB capture\n");
1042 return NULL;
1043 }
1044
1045 char* attr = sanei_xml_get_prop(el_root, "backend");
1046 if (attr == NULL)
1047 {
1048 FAIL_TEST(__func__, "no backend attr in description node\n");
1049 return NULL;
1050 }
1051 // duplicate using strdup so that the caller can use free()
1052 char* ret = strdup(attr);
1053 xmlFree(attr);
1054 return ret;
1055 }
1056
sanei_usb_is_replay_mode_enabled()1057 SANE_Bool sanei_usb_is_replay_mode_enabled()
1058 {
1059 if (testing_mode == sanei_usb_testing_mode_replay)
1060 return SANE_TRUE;
1061
1062 return SANE_FALSE;
1063 }
1064
sanei_usb_record_debug_msg(xmlNode * node,SANE_String_Const message)1065 static void sanei_usb_record_debug_msg(xmlNode* node, SANE_String_Const message)
1066 {
1067 int node_was_null = node == NULL;
1068 if (node_was_null)
1069 node = testing_append_commands_node;
1070
1071 xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"debug");
1072 sanei_xml_set_uint_attr(e_tx, "seq", ++testing_last_known_seq);
1073 xmlNewProp(e_tx, (const xmlChar*)"message", (const xmlChar*)message);
1074
1075 node = sanei_xml_append_command(node, node_was_null, e_tx);
1076
1077 if (node_was_null)
1078 testing_append_commands_node = node;
1079 }
1080
sanei_usb_record_replace_debug_msg(xmlNode * node,SANE_String_Const message)1081 static void sanei_usb_record_replace_debug_msg(xmlNode* node, SANE_String_Const message)
1082 {
1083 if (!testing_development_mode)
1084 return;
1085
1086 testing_last_known_seq--;
1087 sanei_usb_record_debug_msg(node, message);
1088 xmlUnlinkNode(node);
1089 xmlFreeNode(node);
1090 }
1091
sanei_usb_replay_debug_msg(SANE_String_Const message)1092 static void sanei_usb_replay_debug_msg(SANE_String_Const message)
1093 {
1094 if (testing_known_commands_input_failed)
1095 return;
1096
1097 xmlNode* node = sanei_xml_get_next_tx_node();
1098 if (node == NULL)
1099 {
1100 FAIL_TEST(__func__, "no more transactions\n");
1101 return;
1102 }
1103
1104 if (sanei_xml_is_known_commands_end(node))
1105 {
1106 sanei_usb_record_debug_msg(NULL, message);
1107 return;
1108 }
1109
1110 sanei_xml_record_seq(node);
1111 sanei_xml_break_if_needed(node);
1112
1113 if (xmlStrcmp(node->name, (const xmlChar*)"debug") != 0)
1114 {
1115 FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n",
1116 (const char*) node->name);
1117 sanei_usb_record_replace_debug_msg(node, message);
1118 }
1119
1120 if (!sanei_usb_check_attr(node, "message", message, __func__))
1121 {
1122 sanei_usb_record_replace_debug_msg(node, message);
1123 }
1124 }
1125
sanei_usb_testing_record_clear()1126 extern void sanei_usb_testing_record_clear()
1127 {
1128 if (testing_mode != sanei_usb_testing_mode_record)
1129 return;
1130
1131 // we only need to indicate that we never opened a device and sanei_usb_record_open() will
1132 // reinitialize everything for us.
1133 testing_already_opened = 0;
1134 testing_known_commands_input_failed = 0;
1135 testing_last_known_seq = 0;
1136 testing_append_commands_node = NULL;
1137 }
1138
sanei_usb_testing_record_message(SANE_String_Const message)1139 extern void sanei_usb_testing_record_message(SANE_String_Const message)
1140 {
1141 if (testing_mode == sanei_usb_testing_mode_record)
1142 {
1143 sanei_usb_record_debug_msg(NULL, message);
1144 }
1145 if (testing_mode == sanei_usb_testing_mode_replay)
1146 {
1147 sanei_usb_replay_debug_msg(message);
1148 }
1149 }
1150
1151 static void sanei_usb_add_endpoint(device_list_type* device,
1152 SANE_Int transfer_type,
1153 SANE_Int ep_address,
1154 SANE_Int ep_direction);
1155
sanei_usb_testing_init()1156 static SANE_Status sanei_usb_testing_init()
1157 {
1158 DBG_INIT();
1159
1160 if (testing_mode == sanei_usb_testing_mode_record)
1161 {
1162 testing_xml_doc = xmlNewDoc((const xmlChar*)"1.0");
1163 return SANE_STATUS_GOOD;
1164 }
1165
1166 if (device_number != 0)
1167 return SANE_STATUS_INVAL; // already opened
1168
1169 xmlNode* el_root = xmlDocGetRootElement(testing_xml_doc);
1170 if (xmlStrcmp(el_root->name, (const xmlChar*)"device_capture") != 0)
1171 {
1172 DBG(1, "%s: the given file is not USB capture\n", __func__);
1173 return SANE_STATUS_INVAL;
1174 }
1175
1176 xmlNode* el_description =
1177 sanei_xml_find_first_child_with_name(el_root, "description");
1178 if (el_description == NULL)
1179 {
1180 DBG(1, "%s: could not find description node\n", __func__);
1181 return SANE_STATUS_INVAL;
1182 }
1183
1184 int device_id = sanei_xml_get_prop_uint(el_description, "id_vendor");
1185 if (device_id < 0)
1186 {
1187 DBG(1, "%s: no id_vendor attr in description node\n", __func__);
1188 return SANE_STATUS_INVAL;
1189 }
1190
1191 int product_id = sanei_xml_get_prop_uint(el_description, "id_product");
1192 if (product_id < 0)
1193 {
1194 DBG(1, "%s: no id_product attr in description node\n", __func__);
1195 return SANE_STATUS_INVAL;
1196 }
1197
1198 xmlNode* el_configurations =
1199 sanei_xml_find_first_child_with_name(el_description, "configurations");
1200 if (el_configurations == NULL)
1201 {
1202 DBG(1, "%s: could not find configurations node\n", __func__);
1203 return SANE_STATUS_INVAL;
1204 }
1205
1206 xmlNode* el_configuration =
1207 sanei_xml_find_first_child_with_name(el_configurations, "configuration");
1208 if (el_configuration == NULL)
1209 {
1210 DBG(1, "%s: no configuration nodes\n", __func__);
1211 return SANE_STATUS_INVAL;
1212 }
1213
1214 while (el_configuration != NULL)
1215 {
1216 xmlNode* el_interface =
1217 sanei_xml_find_first_child_with_name(el_configuration, "interface");
1218
1219 while (el_interface != NULL)
1220 {
1221 device_list_type device;
1222 memset(&device, 0, sizeof(device));
1223 device.devname = strdup(testing_xml_path);
1224
1225 // other code shouldn't depend on method because testing_mode is
1226 // sanei_usb_testing_mode_replay
1227 device.method = sanei_usb_method_libusb;
1228 device.vendor = device_id;
1229 device.product = product_id;
1230
1231 device.interface_nr = sanei_xml_get_prop_uint(el_interface, "number");
1232 if (device.interface_nr < 0)
1233 {
1234 DBG(1, "%s: no number attr in interface node\n", __func__);
1235 return SANE_STATUS_INVAL;
1236 }
1237
1238 xmlNode* el_endpoint =
1239 sanei_xml_find_first_child_with_name(el_interface, "endpoint");
1240
1241 while (el_endpoint != NULL)
1242 {
1243 char* transfer_attr = sanei_xml_get_prop(el_endpoint,
1244 "transfer_type");
1245 int address = sanei_xml_get_prop_uint(el_endpoint, "address");
1246 char* direction_attr = sanei_xml_get_prop(el_endpoint,
1247 "direction");
1248
1249 int direction_is_in = strcmp(direction_attr, "IN") == 0 ? 1 : 0;
1250 int transfer_type = -1;
1251 if (strcmp(transfer_attr, "INTERRUPT") == 0)
1252 transfer_type = USB_ENDPOINT_TYPE_INTERRUPT;
1253 else if (strcmp(transfer_attr, "BULK") == 0)
1254 transfer_type = USB_ENDPOINT_TYPE_BULK;
1255 else if (strcmp(transfer_attr, "ISOCHRONOUS") == 0)
1256 transfer_type = USB_ENDPOINT_TYPE_ISOCHRONOUS;
1257 else if (strcmp(transfer_attr, "CONTROL") == 0)
1258 transfer_type = USB_ENDPOINT_TYPE_CONTROL;
1259 else
1260 {
1261 DBG(3, "%s: unknown endpoint type %s\n",
1262 __func__, transfer_attr);
1263 }
1264
1265 if (transfer_type >= 0)
1266 {
1267 sanei_usb_add_endpoint(&device, transfer_type, address,
1268 direction_is_in);
1269 }
1270
1271 xmlFree(transfer_attr);
1272 xmlFree(direction_attr);
1273
1274 el_endpoint =
1275 sanei_xml_find_next_child_with_name(el_endpoint, "endpoint");
1276 }
1277 device.alt_setting = 0;
1278 device.missing = 0;
1279
1280 memcpy(&(devices[device_number]), &device, sizeof(device));
1281 device_number++;
1282
1283 el_interface = sanei_xml_find_next_child_with_name(el_interface,
1284 "interface");
1285 }
1286 el_configuration =
1287 sanei_xml_find_next_child_with_name(el_configurations,
1288 "configuration");
1289 }
1290
1291 xmlNode* el_transactions =
1292 sanei_xml_find_first_child_with_name(el_root, "transactions");
1293
1294 if (el_transactions == NULL)
1295 {
1296 DBG(1, "%s: could not find transactions node\n", __func__);
1297 return SANE_STATUS_INVAL;
1298 }
1299
1300 xmlNode* el_transaction = xmlFirstElementChild(el_transactions);
1301 el_transaction = sanei_xml_skip_non_tx_nodes(el_transaction);
1302
1303 if (el_transaction == NULL)
1304 {
1305 DBG(1, "%s: no transactions within capture\n", __func__);
1306 return SANE_STATUS_INVAL;
1307 }
1308
1309 testing_xml_next_tx_node = el_transaction;
1310
1311 return SANE_STATUS_GOOD;
1312 }
1313
sanei_usb_testing_exit()1314 static void sanei_usb_testing_exit()
1315 {
1316 if (testing_development_mode || testing_mode == sanei_usb_testing_mode_record)
1317 {
1318 if (testing_mode == sanei_usb_testing_mode_record)
1319 {
1320 xmlAddNextSibling(testing_append_commands_node, xmlNewText((const xmlChar*)"\n "));
1321 free(testing_record_backend);
1322 }
1323 xmlSaveFileEnc(testing_xml_path, testing_xml_doc, "UTF-8");
1324 }
1325 xmlFreeDoc(testing_xml_doc);
1326 free(testing_xml_path);
1327 xmlCleanupParser();
1328
1329 // reset testing-related all data to initial values
1330 testing_development_mode = 0;
1331 testing_already_opened = 0;
1332 testing_known_commands_input_failed = 0;
1333 testing_last_known_seq = 0;
1334 testing_record_backend = NULL;
1335 testing_append_commands_node = NULL;
1336
1337 testing_xml_path = NULL;
1338 testing_xml_doc = NULL;
1339 testing_xml_next_tx_node = NULL;
1340 }
1341 #else // WITH_USB_RECORD_REPLAY
sanei_usb_testing_enable_replay(SANE_String_Const path,int development_mode)1342 SANE_Status sanei_usb_testing_enable_replay(SANE_String_Const path,
1343 int development_mode)
1344 {
1345 (void) path;
1346 (void) development_mode;
1347
1348 DBG(1, "USB record-replay mode support is missing\n");
1349 return SANE_STATUS_UNSUPPORTED;
1350 }
1351
sanei_usb_testing_enable_record(SANE_String_Const path,SANE_String_Const be_name)1352 SANE_Status sanei_usb_testing_enable_record(SANE_String_Const path, SANE_String_Const be_name)
1353 {
1354 (void) path;
1355 (void) be_name;
1356
1357 DBG(1, "USB record-replay mode support is missing\n");
1358 return SANE_STATUS_UNSUPPORTED;
1359 }
1360
sanei_usb_testing_get_backend()1361 SANE_String sanei_usb_testing_get_backend()
1362 {
1363 return NULL;
1364 }
1365
sanei_usb_is_replay_mode_enabled()1366 SANE_Bool sanei_usb_is_replay_mode_enabled()
1367 {
1368 return SANE_FALSE;
1369 }
1370
sanei_usb_testing_record_clear()1371 void sanei_usb_testing_record_clear()
1372 {
1373 }
1374
sanei_usb_testing_record_message(SANE_String_Const message)1375 void sanei_usb_testing_record_message(SANE_String_Const message)
1376 {
1377 (void) message;
1378 }
1379 #endif // WITH_USB_RECORD_REPLAY
1380
1381 void
sanei_usb_init(void)1382 sanei_usb_init (void)
1383 {
1384 #ifdef HAVE_LIBUSB
1385 int ret;
1386 #endif /* HAVE_LIBUSB */
1387
1388 DBG_INIT ();
1389 #ifdef DBG_LEVEL
1390 debug_level = DBG_LEVEL;
1391 #else
1392 debug_level = 0;
1393 #endif
1394
1395 /* if no device yet, clean up memory */
1396 if(device_number==0)
1397 memset (devices, 0, sizeof (devices));
1398
1399 #if WITH_USB_RECORD_REPLAY
1400 if (testing_mode != sanei_usb_testing_mode_disabled)
1401 {
1402 if (initialized == 0)
1403 {
1404 if (sanei_usb_testing_init() != SANE_STATUS_GOOD)
1405 {
1406 DBG(1, "%s: failed initializing fake USB stack\n", __func__);
1407 return;
1408 }
1409 }
1410
1411 if (testing_mode == sanei_usb_testing_mode_replay)
1412 {
1413 initialized++;
1414 return;
1415 }
1416 }
1417 #endif
1418
1419 /* initialize USB with old libusb library */
1420 #ifdef HAVE_LIBUSB_LEGACY
1421 DBG (4, "%s: Looking for libusb devices\n", __func__);
1422 usb_init ();
1423 #ifdef DBG_LEVEL
1424 if (DBG_LEVEL > 4)
1425 usb_set_debug (255);
1426 #endif /* DBG_LEVEL */
1427 #endif /* HAVE_LIBUSB_LEGACY */
1428
1429
1430 /* initialize USB using libusb-1.0 */
1431 #ifdef HAVE_LIBUSB
1432 if (!sanei_usb_ctx)
1433 {
1434 DBG (4, "%s: initializing libusb-1.0\n", __func__);
1435 ret = libusb_init (&sanei_usb_ctx);
1436 if (ret < 0)
1437 {
1438 DBG (1,
1439 "%s: failed to initialize libusb-1.0, error %d\n", __func__,
1440 ret);
1441 return;
1442 }
1443 #ifdef DBG_LEVEL
1444 if (DBG_LEVEL > 4)
1445 #if LIBUSB_API_VERSION >= 0x01000106
1446 libusb_set_option (sanei_usb_ctx, LIBUSB_OPTION_LOG_LEVEL,
1447 LIBUSB_LOG_LEVEL_INFO);
1448 #else
1449 libusb_set_debug (sanei_usb_ctx, 3);
1450 #endif /* LIBUSB_API_VERSION */
1451 #endif /* DBG_LEVEL */
1452 }
1453 #endif /* HAVE_LIBUSB */
1454
1455 #if !defined(HAVE_LIBUSB_LEGACY) && !defined(HAVE_LIBUSB)
1456 DBG (4, "%s: SANE is built without support for libusb\n", __func__);
1457 #endif
1458
1459 /* sanei_usb is now initialized */
1460 initialized++;
1461
1462 /* do a first scan of USB buses to fill device list */
1463 sanei_usb_scan_devices();
1464 }
1465
1466 void
sanei_usb_exit(void)1467 sanei_usb_exit (void)
1468 {
1469 int i;
1470
1471 /* check we have really some work to do */
1472 if(initialized==0)
1473 {
1474 DBG (1, "%s: sanei_usb in not initialized!\n", __func__);
1475 return;
1476 }
1477
1478 /* decrement the use count */
1479 initialized--;
1480
1481 /* if we reach 0, free allocated resources */
1482 if(initialized==0)
1483 {
1484 #if WITH_USB_RECORD_REPLAY
1485 if (testing_mode != sanei_usb_testing_mode_disabled)
1486 {
1487 sanei_usb_testing_exit();
1488 }
1489 #endif // WITH_USB_RECORD_REPLAY
1490
1491 /* free allocated resources */
1492 DBG (4, "%s: freeing resources\n", __func__);
1493 for (i = 0; i < device_number; i++)
1494 {
1495 if (devices[i].devname != NULL)
1496 {
1497 DBG (5, "%s: freeing device %02d\n", __func__, i);
1498 free(devices[i].devname);
1499 devices[i].devname=NULL;
1500 }
1501 }
1502 #ifdef HAVE_LIBUSB
1503 if (sanei_usb_ctx)
1504 {
1505 libusb_exit (sanei_usb_ctx);
1506 /* reset libusb-1.0 context */
1507 sanei_usb_ctx=NULL;
1508 }
1509 #endif
1510 /* reset device_number */
1511 device_number=0;
1512 }
1513 else
1514 {
1515 DBG (4, "%s: not freeing resources since use count is %d\n", __func__, initialized);
1516 }
1517 return;
1518 }
1519
1520 #ifdef HAVE_USBCALLS
1521 /** scan for devices through usbcall method
1522 * Check for devices using OS/2 USBCALLS Interface
1523 */
usbcall_scan_devices(void)1524 static void usbcall_scan_devices(void)
1525 {
1526 SANE_Char devname[1024];
1527 device_list_type device;
1528 CHAR ucData[2048];
1529 struct usb_device_descriptor *pDevDesc;
1530 struct usb_config_descriptor *pCfgDesc;
1531
1532 APIRET rc;
1533 ULONG ulNumDev, ulDev, ulBufLen;
1534
1535 ulBufLen = sizeof(ucData);
1536 memset(&ucData,0,sizeof(ucData));
1537 rc = UsbQueryNumberDevices( &ulNumDev);
1538
1539 if(rc==0 && ulNumDev)
1540 {
1541 for (ulDev=1; ulDev<=ulNumDev; ulDev++)
1542 {
1543 UsbQueryDeviceReport(ulDev, &ulBufLen, ucData);
1544
1545 pDevDesc = (struct usb_device_descriptor*) ucData;
1546 pCfgDesc = (struct usb_config_descriptor*) (ucData+sizeof(struct usb_device_descriptor));
1547 int interface=0;
1548 SANE_Bool found;
1549 if (!pCfgDesc->bConfigurationValue)
1550 {
1551 DBG (1, "%s: device 0x%04x/0x%04x is not configured\n", __func__,
1552 pDevDesc->idVendor, pDevDesc->idProduct);
1553 continue;
1554 }
1555 if (pDevDesc->idVendor == 0 || pDevDesc->idProduct == 0)
1556 {
1557 DBG (5, "%s: device 0x%04x/0x%04x looks like a root hub\n", __func__,
1558 pDevDesc->idVendor, pDevDesc->idProduct);
1559 continue;
1560 }
1561 found = SANE_FALSE;
1562
1563 if (pDevDesc->bDeviceClass == USB_CLASS_VENDOR_SPEC)
1564 {
1565 found = SANE_TRUE;
1566 }
1567
1568 if (!found)
1569 {
1570 DBG (5, "%s: device 0x%04x/0x%04x: no suitable interfaces\n", __func__,
1571 pDevDesc->idVendor, pDevDesc->idProduct);
1572 continue;
1573 }
1574
1575 snprintf (devname, sizeof (devname), "usbcalls:%d", ulDev);
1576 memset (&device, 0, sizeof (device));
1577 device.devname = strdup (devname);
1578 device.fd = ulDev; /* store usbcalls device number */
1579 device.vendor = pDevDesc->idVendor;
1580 device.product = pDevDesc->idProduct;
1581 device.method = sanei_usb_method_usbcalls;
1582 device.interface_nr = interface;
1583 device.alt_setting = 0;
1584 DBG (4, "%s: found usbcalls device (0x%04x/0x%04x) as device number %s\n", __func__,
1585 pDevDesc->idVendor, pDevDesc->idProduct,device.devname);
1586 store_device(device);
1587 }
1588 }
1589 }
1590 #endif /* HAVE_USBCALLS */
1591
1592 #if !defined(HAVE_LIBUSB_LEGACY) && !defined(HAVE_LIBUSB)
1593 /** scan for devices using kernel device.
1594 * Check for devices using kernel device
1595 */
kernel_scan_devices(void)1596 static void kernel_scan_devices(void)
1597 {
1598 SANE_String *prefix;
1599 SANE_String prefixlist[] = {
1600 #if defined(__linux__)
1601 "/dev/", "usbscanner",
1602 "/dev/usb/", "scanner",
1603 #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined (__OpenBSD__) || defined (__DragonFly__)
1604 "/dev/", "uscanner",
1605 #elif defined(__BEOS__)
1606 "/dev/scanner/usb/", "",
1607 #endif
1608 0, 0
1609 };
1610 SANE_Int vendor, product;
1611 SANE_Char devname[1024];
1612 int fd;
1613 device_list_type device;
1614
1615 DBG (4, "%s: Looking for kernel scanner devices\n", __func__);
1616 /* Check for devices using the kernel scanner driver */
1617
1618 for (prefix = prefixlist; *prefix; prefix += 2)
1619 {
1620 SANE_String dir_name = *prefix;
1621 SANE_String base_name = *(prefix + 1);
1622 struct stat stat_buf;
1623 DIR *dir;
1624 struct dirent *dir_entry;
1625
1626 if (stat (dir_name, &stat_buf) < 0)
1627 {
1628 DBG (5, "%s: can't stat %s: %s\n", __func__, dir_name,
1629 strerror (errno));
1630 continue;
1631 }
1632 if (!S_ISDIR (stat_buf.st_mode))
1633 {
1634 DBG (5, "%s: %s is not a directory\n", __func__, dir_name);
1635 continue;
1636 }
1637 if ((dir = opendir (dir_name)) == 0)
1638 {
1639 DBG (5, "%s: cannot read directory %s: %s\n", __func__, dir_name,
1640 strerror (errno));
1641 continue;
1642 }
1643
1644 while ((dir_entry = readdir (dir)) != 0)
1645 {
1646 /* skip standard dir entries */
1647 if (strcmp (dir_entry->d_name, ".") == 0 || strcmp (dir_entry->d_name, "..") == 0)
1648 continue;
1649
1650 if (strncmp (base_name, dir_entry->d_name, strlen (base_name)) == 0)
1651 {
1652 if (strlen (dir_name) + strlen (dir_entry->d_name) + 1 >
1653 sizeof (devname))
1654 continue;
1655 sprintf (devname, "%s%s", dir_name, dir_entry->d_name);
1656 fd = -1;
1657 #ifdef HAVE_RESMGR
1658 fd = rsm_open_device (devname, O_RDWR);
1659 #endif
1660 if (fd == -1)
1661 fd = open (devname, O_RDWR);
1662 if (fd < 0)
1663 {
1664 DBG (5, "%s: couldn't open %s: %s\n", __func__, devname,
1665 strerror (errno));
1666 continue;
1667 }
1668 vendor = -1;
1669 product = -1;
1670 kernel_get_vendor_product (fd, devname, &vendor, &product);
1671 close (fd);
1672 memset (&device, 0, sizeof (device));
1673 device.devname = strdup (devname);
1674 if (!device.devname)
1675 {
1676 closedir (dir);
1677 return;
1678 }
1679 device.vendor = vendor;
1680 device.product = product;
1681 device.method = sanei_usb_method_scanner_driver;
1682 DBG (4,
1683 "%s: found kernel scanner device (0x%04x/0x%04x) at %s\n", __func__,
1684 vendor, product, devname);
1685 store_device(device);
1686 }
1687 }
1688 closedir (dir);
1689 }
1690 }
1691 #endif /* !defined(HAVE_LIBUSB_LEGACY) && !defined(HAVE_LIBUSB) */
1692
1693 #ifdef HAVE_LIBUSB_LEGACY
1694 /** scan for devices using old libusb
1695 * Check for devices using 0.1.x libusb
1696 */
libusb_scan_devices(void)1697 static void libusb_scan_devices(void)
1698 {
1699 struct usb_bus *bus;
1700 struct usb_device *dev;
1701 SANE_Char devname[1024];
1702 device_list_type device;
1703
1704 DBG (4, "%s: Looking for libusb devices\n", __func__);
1705
1706 usb_find_busses ();
1707 usb_find_devices ();
1708
1709 /* Check for the matching device */
1710 for (bus = usb_get_busses (); bus; bus = bus->next)
1711 {
1712 for (dev = bus->devices; dev; dev = dev->next)
1713 {
1714 int interface;
1715 SANE_Bool found = SANE_FALSE;
1716
1717 if (!dev->config)
1718 {
1719 DBG (1,
1720 "%s: device 0x%04x/0x%04x is not configured\n", __func__,
1721 dev->descriptor.idVendor, dev->descriptor.idProduct);
1722 continue;
1723 }
1724 if (dev->descriptor.idVendor == 0 || dev->descriptor.idProduct == 0)
1725 {
1726 DBG (5,
1727 "%s: device 0x%04x/0x%04x looks like a root hub\n", __func__,
1728 dev->descriptor.idVendor, dev->descriptor.idProduct);
1729 continue;
1730 }
1731
1732 for (interface = 0;
1733 interface < dev->config[0].bNumInterfaces && !found;
1734 interface++)
1735 {
1736 switch (dev->descriptor.bDeviceClass)
1737 {
1738 case USB_CLASS_VENDOR_SPEC:
1739 found = SANE_TRUE;
1740 break;
1741 case USB_CLASS_PER_INTERFACE:
1742 if (dev->config[0].interface[interface].num_altsetting == 0 ||
1743 !dev->config[0].interface[interface].altsetting)
1744 {
1745 DBG (1, "%s: device 0x%04x/0x%04x doesn't "
1746 "have an altsetting for interface %d\n", __func__,
1747 dev->descriptor.idVendor, dev->descriptor.idProduct,
1748 interface);
1749 continue;
1750 }
1751 switch (dev->config[0].interface[interface].altsetting[0].
1752 bInterfaceClass)
1753 {
1754 case USB_CLASS_VENDOR_SPEC:
1755 case USB_CLASS_PER_INTERFACE:
1756 case 6: /* imaging? */
1757 case 16: /* data? */
1758 found = SANE_TRUE;
1759 break;
1760 }
1761 break;
1762 }
1763 if (!found)
1764 DBG (5,
1765 "%s: device 0x%04x/0x%04x, interface %d "
1766 "doesn't look like a "
1767 "scanner (%d/%d)\n", __func__, dev->descriptor.idVendor,
1768 dev->descriptor.idProduct, interface,
1769 dev->descriptor.bDeviceClass,
1770 dev->config[0].interface[interface].num_altsetting != 0
1771 ? dev->config[0].interface[interface].altsetting[0].
1772 bInterfaceClass : -1);
1773 }
1774 interface--;
1775 if (!found)
1776 {
1777 DBG (5,
1778 "%s: device 0x%04x/0x%04x: no suitable interfaces\n", __func__,
1779 dev->descriptor.idVendor, dev->descriptor.idProduct);
1780 continue;
1781 }
1782
1783 memset (&device, 0, sizeof (device));
1784 device.libusb_device = dev;
1785 snprintf (devname, sizeof (devname), "libusb:%s:%s",
1786 dev->bus->dirname, dev->filename);
1787 device.devname = strdup (devname);
1788 if (!device.devname)
1789 return;
1790 device.vendor = dev->descriptor.idVendor;
1791 device.product = dev->descriptor.idProduct;
1792 device.method = sanei_usb_method_libusb;
1793 device.interface_nr = interface;
1794 device.alt_setting = 0;
1795 DBG (4,
1796 "%s: found libusb device (0x%04x/0x%04x) interface "
1797 "%d at %s\n", __func__,
1798 dev->descriptor.idVendor, dev->descriptor.idProduct, interface,
1799 devname);
1800 store_device(device);
1801 }
1802 }
1803 }
1804 #endif /* HAVE_LIBUSB_LEGACY */
1805
1806 #ifdef HAVE_LIBUSB
1807 /** scan for devices using libusb
1808 * Check for devices using libusb-1.0
1809 */
libusb_scan_devices(void)1810 static void libusb_scan_devices(void)
1811 {
1812 device_list_type device;
1813 SANE_Char devname[1024];
1814 libusb_device **devlist;
1815 ssize_t ndev;
1816 libusb_device *dev;
1817 libusb_device_handle *hdl;
1818 struct libusb_device_descriptor desc;
1819 struct libusb_config_descriptor *config0;
1820 unsigned short vid, pid;
1821 unsigned char busno, address;
1822 int config;
1823 int interface;
1824 int ret;
1825 int i;
1826
1827 DBG (4, "%s: Looking for libusb-1.0 devices\n", __func__);
1828
1829 ndev = libusb_get_device_list (sanei_usb_ctx, &devlist);
1830 if (ndev < 0)
1831 {
1832 DBG (1,
1833 "%s: failed to get libusb-1.0 device list, error %d\n", __func__,
1834 (int) ndev);
1835 return;
1836 }
1837
1838 for (i = 0; i < ndev; i++)
1839 {
1840 SANE_Bool found = SANE_FALSE;
1841
1842 dev = devlist[i];
1843
1844 busno = libusb_get_bus_number (dev);
1845 address = libusb_get_device_address (dev);
1846
1847 ret = libusb_get_device_descriptor (dev, &desc);
1848 if (ret < 0)
1849 {
1850 DBG (1,
1851 "%s: could not get device descriptor for device at %03d:%03d (err %d)\n", __func__,
1852 busno, address, ret);
1853 continue;
1854 }
1855
1856 vid = desc.idVendor;
1857 pid = desc.idProduct;
1858
1859 if ((vid == 0) || (pid == 0))
1860 {
1861 DBG (5,
1862 "%s: device 0x%04x/0x%04x at %03d:%03d looks like a root hub\n", __func__,
1863 vid, pid, busno, address);
1864 continue;
1865 }
1866
1867 ret = libusb_open (dev, &hdl);
1868 if (ret < 0)
1869 {
1870 DBG (1,
1871 "%s: skipping device 0x%04x/0x%04x at %03d:%03d: cannot open: %s\n", __func__,
1872 vid, pid, busno, address, sanei_libusb_strerror (ret));
1873
1874 continue;
1875 }
1876
1877 ret = libusb_get_configuration (hdl, &config);
1878
1879 libusb_close (hdl);
1880
1881 if (ret < 0)
1882 {
1883 DBG (1,
1884 "%s: could not get configuration for device 0x%04x/0x%04x at %03d:%03d (err %d)\n", __func__,
1885 vid, pid, busno, address, ret);
1886 continue;
1887 }
1888
1889 #if !defined(SANEI_ALLOW_UNCONFIGURED_DEVICES)
1890 if (config == 0)
1891 {
1892 DBG (1,
1893 "%s: device 0x%04x/0x%04x at %03d:%03d is not configured\n", __func__,
1894 vid, pid, busno, address);
1895 continue;
1896 }
1897 #endif
1898
1899 ret = libusb_get_config_descriptor (dev, 0, &config0);
1900 if (ret < 0)
1901 {
1902 DBG (1,
1903 "%s: could not get config[0] descriptor for device 0x%04x/0x%04x at %03d:%03d (err %d)\n", __func__,
1904 vid, pid, busno, address, ret);
1905 continue;
1906 }
1907
1908 for (interface = 0; (interface < config0->bNumInterfaces) && !found; interface++)
1909 {
1910 switch (desc.bDeviceClass)
1911 {
1912 case LIBUSB_CLASS_VENDOR_SPEC:
1913 found = SANE_TRUE;
1914 break;
1915
1916 case LIBUSB_CLASS_PER_INTERFACE:
1917 if ((config0->interface[interface].num_altsetting == 0)
1918 || !config0->interface[interface].altsetting)
1919 {
1920 DBG (1, "%s: device 0x%04x/0x%04x doesn't "
1921 "have an altsetting for interface %d\n", __func__,
1922 vid, pid, interface);
1923 continue;
1924 }
1925
1926 switch (config0->interface[interface].altsetting[0].bInterfaceClass)
1927 {
1928 case LIBUSB_CLASS_VENDOR_SPEC:
1929 case LIBUSB_CLASS_PER_INTERFACE:
1930 case LIBUSB_CLASS_PTP:
1931 case 16: /* data? */
1932 found = SANE_TRUE;
1933 break;
1934 }
1935 break;
1936 }
1937
1938 if (!found)
1939 DBG (5,
1940 "%s: device 0x%04x/0x%04x, interface %d "
1941 "doesn't look like a scanner (%d/%d)\n", __func__,
1942 vid, pid, interface, desc.bDeviceClass,
1943 (config0->interface[interface].num_altsetting != 0)
1944 ? config0->interface[interface].altsetting[0].bInterfaceClass : -1);
1945 }
1946
1947 libusb_free_config_descriptor (config0);
1948
1949 interface--;
1950
1951 if (!found)
1952 {
1953 DBG (5,
1954 "%s: device 0x%04x/0x%04x at %03d:%03d: no suitable interfaces\n", __func__,
1955 vid, pid, busno, address);
1956 continue;
1957 }
1958
1959 memset (&device, 0, sizeof (device));
1960 device.lu_device = libusb_ref_device(dev);
1961 snprintf (devname, sizeof (devname), "libusb:%03d:%03d",
1962 busno, address);
1963 device.devname = strdup (devname);
1964 if (!device.devname)
1965 return;
1966 device.vendor = vid;
1967 device.product = pid;
1968 device.method = sanei_usb_method_libusb;
1969 device.interface_nr = interface;
1970 device.alt_setting = 0;
1971 DBG (4,
1972 "%s: found libusb-1.0 device (0x%04x/0x%04x) interface "
1973 "%d at %s\n", __func__,
1974 vid, pid, interface, devname);
1975
1976 store_device (device);
1977 }
1978
1979 libusb_free_device_list (devlist, 1);
1980
1981 }
1982 #endif /* HAVE_LIBUSB */
1983
1984
1985 void
sanei_usb_scan_devices(void)1986 sanei_usb_scan_devices (void)
1987 {
1988 int count;
1989 int i;
1990
1991 /* check USB has been initialized first */
1992 if(initialized==0)
1993 {
1994 DBG (1, "%s: sanei_usb is not initialized!\n", __func__);
1995 return;
1996 }
1997
1998 if (testing_mode == sanei_usb_testing_mode_replay)
1999 {
2000 // device added in sanei_usb_testing_init()
2001 return;
2002 }
2003 /* we mark all already detected devices as missing */
2004 /* each scan method will reset this value to 0 (not missing)
2005 * when storing the device */
2006 DBG (4, "%s: marking existing devices\n", __func__);
2007 for (i = 0; i < device_number; i++)
2008 {
2009 devices[i].missing++;
2010 }
2011
2012 /* Check for devices using the kernel scanner driver */
2013 #if !defined(HAVE_LIBUSB_LEGACY) && !defined(HAVE_LIBUSB)
2014 kernel_scan_devices();
2015 #endif
2016
2017 #if defined(HAVE_LIBUSB_LEGACY) || defined(HAVE_LIBUSB)
2018 /* Check for devices using libusb (old or new)*/
2019 libusb_scan_devices();
2020 #endif
2021
2022 #ifdef HAVE_USBCALLS
2023 /* Check for devices using OS/2 USBCALLS Interface */
2024 usbcall_scan_devices();
2025 #endif
2026
2027 /* display found devices */
2028 if (debug_level > 5)
2029 {
2030 count=0;
2031 for (i = 0; i < device_number; i++)
2032 {
2033 if(!devices[i].missing)
2034 {
2035 count++;
2036 DBG (6, "%s: device %02d is %s\n", __func__, i, devices[i].devname);
2037 }
2038 }
2039 DBG (5, "%s: found %d devices\n", __func__, count);
2040 }
2041 }
2042
2043
2044
2045 /* This logically belongs to sanei_config.c but not every backend that
2046 uses sanei_config() wants to depend on sanei_usb. */
2047 void
sanei_usb_attach_matching_devices(const char * name,SANE_Status (* attach)(const char * dev))2048 sanei_usb_attach_matching_devices (const char *name,
2049 SANE_Status (*attach) (const char *dev))
2050 {
2051 char *vendor, *product;
2052
2053 if (strncmp (name, "usb", 3) == 0)
2054 {
2055 SANE_Word vendorID = 0, productID = 0;
2056
2057 name += 3;
2058
2059 name = sanei_config_skip_whitespace (name);
2060 if (*name)
2061 {
2062 name = sanei_config_get_string (name, &vendor);
2063 if (vendor)
2064 {
2065 vendorID = strtol (vendor, 0, 0);
2066 free (vendor);
2067 }
2068 name = sanei_config_skip_whitespace (name);
2069 }
2070
2071 name = sanei_config_skip_whitespace (name);
2072 if (*name)
2073 {
2074 name = sanei_config_get_string (name, &product);
2075 if (product)
2076 {
2077 productID = strtol (product, 0, 0);
2078 free (product);
2079 }
2080 }
2081 sanei_usb_find_devices (vendorID, productID, attach);
2082 }
2083 else
2084 (*attach) (name);
2085 }
2086
2087 SANE_Status
sanei_usb_get_vendor_product_byname(SANE_String_Const devname,SANE_Word * vendor,SANE_Word * product)2088 sanei_usb_get_vendor_product_byname (SANE_String_Const devname,
2089 SANE_Word * vendor, SANE_Word * product)
2090 {
2091 int i;
2092 SANE_Bool found = SANE_FALSE;
2093
2094 for (i = 0; i < device_number && devices[i].devname; i++)
2095 {
2096 if (!devices[i].missing && strcmp (devices[i].devname, devname) == 0)
2097 {
2098 found = SANE_TRUE;
2099 break;
2100 }
2101 }
2102
2103 if (!found)
2104 {
2105 DBG (1, "sanei_usb_get_vendor_product_byname: can't find device `%s' in list\n", devname);
2106 return SANE_STATUS_INVAL;
2107 }
2108
2109 if ((devices[i].vendor == 0) && (devices[i].product == 0))
2110 {
2111 DBG (1, "sanei_usb_get_vendor_product_byname: not support for this method\n");
2112 return SANE_STATUS_UNSUPPORTED;
2113 }
2114
2115 if (vendor)
2116 *vendor = devices[i].vendor;
2117
2118 if (product)
2119 *product = devices[i].product;
2120
2121 return SANE_STATUS_GOOD;
2122 }
2123
2124 SANE_Status
sanei_usb_get_vendor_product(SANE_Int dn,SANE_Word * vendor,SANE_Word * product)2125 sanei_usb_get_vendor_product (SANE_Int dn, SANE_Word * vendor,
2126 SANE_Word * product)
2127 {
2128 SANE_Word vendorID = 0;
2129 SANE_Word productID = 0;
2130
2131 if (dn >= device_number || dn < 0)
2132 {
2133 DBG (1, "sanei_usb_get_vendor_product: dn >= device number || dn < 0\n");
2134 return SANE_STATUS_INVAL;
2135 }
2136 if (devices[dn].missing >= 1)
2137 {
2138 DBG (1, "sanei_usb_get_vendor_product: dn=%d is missing!\n",dn);
2139 return SANE_STATUS_INVAL;
2140 }
2141
2142 /* kernel, usbcal and libusb methods store these when device scanning
2143 * is done, so we can use them directly */
2144 vendorID = devices[dn].vendor;
2145 productID = devices[dn].product;
2146
2147 if (vendor)
2148 *vendor = vendorID;
2149 if (product)
2150 *product = productID;
2151
2152 if (!vendorID || !productID)
2153 {
2154 DBG (3, "sanei_usb_get_vendor_product: device %d: Your OS doesn't "
2155 "seem to support detection of vendor+product ids\n", dn);
2156 return SANE_STATUS_UNSUPPORTED;
2157 }
2158 else
2159 {
2160 DBG (3, "sanei_usb_get_vendor_product: device %d: vendorID: 0x%04x, "
2161 "productID: 0x%04x\n", dn, vendorID, productID);
2162 return SANE_STATUS_GOOD;
2163 }
2164 }
2165
2166 SANE_Status
sanei_usb_find_devices(SANE_Int vendor,SANE_Int product,SANE_Status (* attach)(SANE_String_Const dev))2167 sanei_usb_find_devices (SANE_Int vendor, SANE_Int product,
2168 SANE_Status (*attach) (SANE_String_Const dev))
2169 {
2170 SANE_Int dn = 0;
2171
2172 DBG (3,
2173 "sanei_usb_find_devices: vendor=0x%04x, product=0x%04x\n",
2174 vendor, product);
2175
2176 while (devices[dn].devname && dn < device_number)
2177 {
2178 if (devices[dn].vendor == vendor
2179 && devices[dn].product == product
2180 && !devices[dn].missing
2181 && attach)
2182 attach (devices[dn].devname);
2183 dn++;
2184 }
2185 return SANE_STATUS_GOOD;
2186 }
2187
2188 void
sanei_usb_set_endpoint(SANE_Int dn,SANE_Int ep_type,SANE_Int ep)2189 sanei_usb_set_endpoint (SANE_Int dn, SANE_Int ep_type, SANE_Int ep)
2190 {
2191 if (dn >= device_number || dn < 0)
2192 {
2193 DBG (1, "sanei_usb_set_endpoint: dn >= device number || dn < 0\n");
2194 return;
2195 }
2196
2197 DBG (5, "sanei_usb_set_endpoint: Setting endpoint of type 0x%02x to 0x%02x\n", ep_type, ep);
2198 switch (ep_type)
2199 {
2200 case USB_DIR_IN|USB_ENDPOINT_TYPE_BULK:
2201 devices[dn].bulk_in_ep = ep;
2202 break;
2203 case USB_DIR_OUT|USB_ENDPOINT_TYPE_BULK:
2204 devices[dn].bulk_out_ep = ep;
2205 break;
2206 case USB_DIR_IN|USB_ENDPOINT_TYPE_ISOCHRONOUS:
2207 devices[dn].iso_in_ep = ep;
2208 break;
2209 case USB_DIR_OUT|USB_ENDPOINT_TYPE_ISOCHRONOUS:
2210 devices[dn].iso_out_ep = ep;
2211 break;
2212 case USB_DIR_IN|USB_ENDPOINT_TYPE_INTERRUPT:
2213 devices[dn].int_in_ep = ep;
2214 break;
2215 case USB_DIR_OUT|USB_ENDPOINT_TYPE_INTERRUPT:
2216 devices[dn].int_out_ep = ep;
2217 break;
2218 case USB_DIR_IN|USB_ENDPOINT_TYPE_CONTROL:
2219 devices[dn].control_in_ep = ep;
2220 break;
2221 case USB_DIR_OUT|USB_ENDPOINT_TYPE_CONTROL:
2222 devices[dn].control_out_ep = ep;
2223 break;
2224 }
2225 }
2226
2227 #if HAVE_LIBUSB_LEGACY || HAVE_LIBUSB || HAVE_USBCALLS || WITH_USB_RECORD_REPLAY
sanei_usb_transfer_type_desc(SANE_Int transfer_type)2228 static const char* sanei_usb_transfer_type_desc(SANE_Int transfer_type)
2229 {
2230 switch (transfer_type)
2231 {
2232 case USB_ENDPOINT_TYPE_INTERRUPT: return "interrupt";
2233 case USB_ENDPOINT_TYPE_BULK: return "bulk";
2234 case USB_ENDPOINT_TYPE_ISOCHRONOUS: return "isochronous";
2235 case USB_ENDPOINT_TYPE_CONTROL: return "control";
2236 }
2237 return NULL;
2238 }
2239
2240 // Similar sanei_usb_set_endpoint, but ignores duplicate endpoints
sanei_usb_add_endpoint(device_list_type * device,SANE_Int transfer_type,SANE_Int ep_address,SANE_Int ep_direction)2241 static void sanei_usb_add_endpoint(device_list_type* device,
2242 SANE_Int transfer_type,
2243 SANE_Int ep_address,
2244 SANE_Int ep_direction)
2245 {
2246 DBG(5, "%s: direction: %d, address: %d, transfer_type: %d\n",
2247 __func__, ep_direction, ep_address, transfer_type);
2248
2249 SANE_Int* ep_in = NULL;
2250 SANE_Int* ep_out = NULL;
2251 const char* transfer_type_msg = sanei_usb_transfer_type_desc(transfer_type);
2252
2253 switch (transfer_type)
2254 {
2255 case USB_ENDPOINT_TYPE_INTERRUPT:
2256 ep_in = &device->int_in_ep;
2257 ep_out = &device->int_out_ep;
2258 break;
2259 case USB_ENDPOINT_TYPE_BULK:
2260 ep_in = &device->bulk_in_ep;
2261 ep_out = &device->bulk_out_ep;
2262 break;
2263 case USB_ENDPOINT_TYPE_ISOCHRONOUS:
2264 ep_in = &device->iso_in_ep;
2265 ep_out = &device->iso_out_ep;
2266 break;
2267 case USB_ENDPOINT_TYPE_CONTROL:
2268 ep_in = &device->control_in_ep;
2269 ep_out = &device->control_out_ep;
2270 break;
2271 }
2272
2273 DBG(5, "%s: found %s-%s endpoint (address 0x%02x)\n",
2274 __func__, transfer_type_msg, ep_direction ? "in" : "out",
2275 ep_address);
2276
2277 if (ep_direction) // in
2278 {
2279 if (*ep_in)
2280 DBG(3, "%s: we already have a %s-in endpoint "
2281 "(address: 0x%02x), ignoring the new one\n",
2282 __func__, transfer_type_msg, *ep_in);
2283 else
2284 *ep_in = ep_address;
2285 }
2286 else
2287 {
2288 if (*ep_out)
2289 DBG(3, "%s: we already have a %s-out endpoint "
2290 "(address: 0x%02x), ignoring the new one\n",
2291 __func__, transfer_type_msg, *ep_out);
2292 else
2293 *ep_out = ep_address;
2294 }
2295 }
2296 #endif // HAVE_LIBUSB_LEGACY || HAVE_LIBUSB || HAVE_USBCALLS
2297
2298 SANE_Int
sanei_usb_get_endpoint(SANE_Int dn,SANE_Int ep_type)2299 sanei_usb_get_endpoint (SANE_Int dn, SANE_Int ep_type)
2300 {
2301 if (dn >= device_number || dn < 0)
2302 {
2303 DBG (1, "sanei_usb_get_endpoint: dn >= device number || dn < 0\n");
2304 return 0;
2305 }
2306
2307 switch (ep_type)
2308 {
2309 case USB_DIR_IN|USB_ENDPOINT_TYPE_BULK:
2310 return devices[dn].bulk_in_ep;
2311 case USB_DIR_OUT|USB_ENDPOINT_TYPE_BULK:
2312 return devices[dn].bulk_out_ep;
2313 case USB_DIR_IN|USB_ENDPOINT_TYPE_ISOCHRONOUS:
2314 return devices[dn].iso_in_ep;
2315 case USB_DIR_OUT|USB_ENDPOINT_TYPE_ISOCHRONOUS:
2316 return devices[dn].iso_out_ep;
2317 case USB_DIR_IN|USB_ENDPOINT_TYPE_INTERRUPT:
2318 return devices[dn].int_in_ep;
2319 case USB_DIR_OUT|USB_ENDPOINT_TYPE_INTERRUPT:
2320 return devices[dn].int_out_ep;
2321 case USB_DIR_IN|USB_ENDPOINT_TYPE_CONTROL:
2322 return devices[dn].control_in_ep;
2323 case USB_DIR_OUT|USB_ENDPOINT_TYPE_CONTROL:
2324 return devices[dn].control_out_ep;
2325 default:
2326 return 0;
2327 }
2328 }
2329
2330 #if WITH_USB_RECORD_REPLAY
sanei_xml_indent_child(xmlNode * parent,unsigned indent_count)2331 static void sanei_xml_indent_child(xmlNode* parent, unsigned indent_count)
2332 {
2333 indent_count *= 4;
2334
2335 xmlChar* indent_str = malloc(indent_count + 2);
2336 indent_str[0] = '\n';
2337 memset(indent_str + 1, ' ', indent_count);
2338 indent_str[indent_count + 1] = '\0';
2339
2340 xmlAddChild(parent, xmlNewText(indent_str));
2341 free(indent_str);
2342 }
2343
sanei_usb_record_open(SANE_Int dn)2344 static void sanei_usb_record_open(SANE_Int dn)
2345 {
2346 if (testing_already_opened)
2347 return;
2348
2349 xmlNode* e_root = xmlNewNode(NULL, (const xmlChar*) "device_capture");
2350 xmlDocSetRootElement(testing_xml_doc, e_root);
2351 xmlNewProp(e_root, (const xmlChar*)"backend", (const xmlChar*) testing_record_backend);
2352
2353 sanei_xml_indent_child(e_root, 1);
2354 xmlNode* e_description = xmlNewChild(e_root, NULL, (const xmlChar*) "description", NULL);
2355 sanei_xml_set_hex_attr(e_description, "id_vendor", devices[dn].vendor);
2356 sanei_xml_set_hex_attr(e_description, "id_product", devices[dn].product);
2357
2358 sanei_xml_indent_child(e_description, 2);
2359 xmlNode* e_configurations = xmlNewChild(e_description, NULL,
2360 (const xmlChar*) "configurations", NULL);
2361
2362 sanei_xml_indent_child(e_configurations, 3);
2363 xmlNode* e_configuration = xmlNewChild(e_configurations, NULL,
2364 (const xmlChar*) "configuration", NULL);
2365 sanei_xml_set_uint_attr(e_configuration, "number", 1);
2366
2367 sanei_xml_indent_child(e_configuration, 4);
2368 xmlNode* e_interface = xmlNewChild(e_configuration, NULL, (const xmlChar*) "interface", NULL);
2369 sanei_xml_set_uint_attr(e_interface, "number", devices[dn].interface_nr);
2370
2371 struct endpoint_data_desc {
2372 const char* transfer_type;
2373 const char* direction;
2374 SANE_Int ep_address;
2375 };
2376
2377 struct endpoint_data_desc endpoints[8] =
2378 {
2379 { "BULK", "IN", devices[dn].bulk_in_ep },
2380 { "BULK", "OUT", devices[dn].bulk_out_ep },
2381 { "ISOCHRONOUS", "IN", devices[dn].iso_in_ep },
2382 { "ISOCHRONOUS", "OUT", devices[dn].iso_out_ep },
2383 { "INTERRUPT", "IN", devices[dn].int_in_ep },
2384 { "INTERRUPT", "OUT", devices[dn].int_out_ep },
2385 { "CONTROL", "IN", devices[dn].control_in_ep },
2386 { "CONTROL", "OUT", devices[dn].control_out_ep }
2387 };
2388
2389 for (int i = 0; i < 8; ++i)
2390 {
2391 if (endpoints[i].ep_address)
2392 {
2393 sanei_xml_indent_child(e_interface, 5);
2394 xmlNode* e_endpoint = xmlNewChild(e_interface, NULL, (const xmlChar*)"endpoint", NULL);
2395 xmlNewProp(e_endpoint, (const xmlChar*)"transfer_type",
2396 (const xmlChar*) endpoints[i].transfer_type);
2397 sanei_xml_set_uint_attr(e_endpoint, "number", endpoints[i].ep_address & 0x0f);
2398 xmlNewProp(e_endpoint, (const xmlChar*)"direction",
2399 (const xmlChar*) endpoints[i].direction);
2400 sanei_xml_set_hex_attr(e_endpoint, "address", endpoints[i].ep_address);
2401 }
2402 }
2403 sanei_xml_indent_child(e_interface, 4);
2404 sanei_xml_indent_child(e_configuration, 3);
2405 sanei_xml_indent_child(e_configurations, 2);
2406 sanei_xml_indent_child(e_description, 1);
2407
2408 sanei_xml_indent_child(e_root, 1);
2409 xmlNode* e_transactions = xmlNewChild(e_root, NULL, (const xmlChar*)"transactions", NULL);
2410
2411 // add an empty node so that we have something to append to
2412 testing_append_commands_node = xmlAddChild(e_transactions, xmlNewText((const xmlChar*)""));
2413 testing_already_opened = 1;
2414 }
2415 #endif // WITH_USB_RECORD_REPLAY
2416
2417 SANE_Status
sanei_usb_open(SANE_String_Const devname,SANE_Int * dn)2418 sanei_usb_open (SANE_String_Const devname, SANE_Int * dn)
2419 {
2420 int devcount;
2421 SANE_Bool found = SANE_FALSE;
2422
2423 DBG (5, "sanei_usb_open: trying to open device `%s'\n", devname);
2424 if (!dn)
2425 {
2426 DBG (1, "sanei_usb_open: can't open `%s': dn == NULL\n", devname);
2427 return SANE_STATUS_INVAL;
2428 }
2429
2430 for (devcount = 0;
2431 devcount < device_number && devices[devcount].devname != 0;
2432 devcount++)
2433 {
2434 if (!devices[devcount].missing && strcmp (devices[devcount].devname, devname) == 0)
2435 {
2436 if (devices[devcount].open)
2437 {
2438 DBG (1, "sanei_usb_open: device `%s' already open\n", devname);
2439 return SANE_STATUS_INVAL;
2440 }
2441 found = SANE_TRUE;
2442 break;
2443 }
2444 }
2445
2446 if (!found)
2447 {
2448 DBG (1, "sanei_usb_open: can't find device `%s' in list\n", devname);
2449 return SANE_STATUS_INVAL;
2450 }
2451
2452 if (testing_mode == sanei_usb_testing_mode_replay)
2453 {
2454 DBG (1, "sanei_usb_open: opening fake USB device\n");
2455 // the device configuration has been already filled in
2456 // sanei_usb_testing_init()
2457 }
2458 else if (devices[devcount].method == sanei_usb_method_libusb)
2459 {
2460 #ifdef HAVE_LIBUSB_LEGACY
2461 struct usb_device *dev;
2462 struct usb_interface_descriptor *interface;
2463 int result, num;
2464 int c, i, a;
2465
2466 devices[devcount].libusb_handle =
2467 usb_open (devices[devcount].libusb_device);
2468 if (!devices[devcount].libusb_handle)
2469 {
2470 SANE_Status status = SANE_STATUS_INVAL;
2471
2472 DBG (1, "sanei_usb_open: can't open device `%s': %s\n",
2473 devname, strerror (errno));
2474 if (errno == EPERM || errno == EACCES)
2475 {
2476 DBG (1, "Make sure you run as root or set appropriate "
2477 "permissions\n");
2478 status = SANE_STATUS_ACCESS_DENIED;
2479 }
2480 else if (errno == EBUSY)
2481 {
2482 DBG (1, "Maybe the kernel scanner driver claims the "
2483 "scanner's interface?\n");
2484 status = SANE_STATUS_DEVICE_BUSY;
2485 }
2486 return status;
2487 }
2488
2489 dev = usb_device (devices[devcount].libusb_handle);
2490
2491 /* Set the configuration */
2492 if (!dev->config)
2493 {
2494 DBG (1, "sanei_usb_open: device `%s' not configured?\n", devname);
2495 return SANE_STATUS_INVAL;
2496 }
2497 if (dev->descriptor.bNumConfigurations > 1)
2498 {
2499 DBG (3, "sanei_usb_open: more than one "
2500 "configuration (%d), choosing first config (%d)\n",
2501 dev->descriptor.bNumConfigurations,
2502 dev->config[0].bConfigurationValue);
2503
2504 result = usb_set_configuration (devices[devcount].libusb_handle,
2505 dev->config[0].bConfigurationValue);
2506 if (result < 0)
2507 {
2508 SANE_Status status = SANE_STATUS_INVAL;
2509
2510 DBG (1, "sanei_usb_open: libusb complained: %s\n",
2511 usb_strerror ());
2512 if (errno == EPERM || errno == EACCES)
2513 {
2514 DBG (1, "Make sure you run as root or set appropriate "
2515 "permissions\n");
2516 status = SANE_STATUS_ACCESS_DENIED;
2517 }
2518 else if (errno == EBUSY)
2519 {
2520 DBG (3, "Maybe the kernel scanner driver or usblp claims the "
2521 "interface? Ignoring this error...\n");
2522 status = SANE_STATUS_GOOD;
2523 }
2524 if (status != SANE_STATUS_GOOD)
2525 {
2526 usb_close (devices[devcount].libusb_handle);
2527 return status;
2528 }
2529 }
2530 }
2531
2532 /* Claim the interface */
2533 result = usb_claim_interface (devices[devcount].libusb_handle,
2534 devices[devcount].interface_nr);
2535 if (result < 0)
2536 {
2537 SANE_Status status = SANE_STATUS_INVAL;
2538
2539 DBG (1, "sanei_usb_open: libusb complained: %s\n", usb_strerror ());
2540 if (errno == EPERM || errno == EACCES)
2541 {
2542 DBG (1, "Make sure you run as root or set appropriate "
2543 "permissions\n");
2544 status = SANE_STATUS_ACCESS_DENIED;
2545 }
2546 else if (errno == EBUSY)
2547 {
2548 DBG (1, "Maybe the kernel scanner driver claims the "
2549 "scanner's interface?\n");
2550 status = SANE_STATUS_DEVICE_BUSY;
2551 }
2552 usb_close (devices[devcount].libusb_handle);
2553 return status;
2554 }
2555
2556 /* Loop through all of the configurations */
2557 for (c = 0; c < dev->descriptor.bNumConfigurations; c++)
2558 {
2559 /* Loop through all of the interfaces */
2560 for (i = 0; i < dev->config[c].bNumInterfaces; i++)
2561 {
2562 /* Loop through all of the alternate settings */
2563 for (a = 0; a < dev->config[c].interface[i].num_altsetting; a++)
2564 {
2565 DBG (5, "sanei_usb_open: configuration nr: %d\n", c);
2566 DBG (5, "sanei_usb_open: interface nr: %d\n", i);
2567 DBG (5, "sanei_usb_open: alt_setting nr: %d\n", a);
2568
2569 /* Start by interfaces found in sanei_usb_init */
2570 if (c == 0 && i != devices[devcount].interface_nr)
2571 {
2572 DBG (5, "sanei_usb_open: interface %d not detected as "
2573 "a scanner by sanei_usb_init, ignoring.\n", i);
2574 continue;
2575 }
2576
2577 interface = &dev->config[c].interface[i].altsetting[a];
2578
2579 /* Now we look for usable endpoints */
2580 for (num = 0; num < interface->bNumEndpoints; num++)
2581 {
2582 struct usb_endpoint_descriptor *endpoint;
2583 int address, direction, transfer_type;
2584
2585 endpoint = &interface->endpoint[num];
2586 DBG (5, "sanei_usb_open: endpoint nr: %d\n", num);
2587 transfer_type =
2588 endpoint->bmAttributes & USB_ENDPOINT_TYPE_MASK;
2589 direction =
2590 endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
2591
2592 sanei_usb_add_endpoint(&devices[devcount], transfer_type,
2593 endpoint->bEndpointAddress,
2594 direction);
2595 }
2596 }
2597 }
2598 }
2599
2600 #elif defined(HAVE_LIBUSB) /* libusb-1.0 */
2601
2602 int config;
2603 libusb_device *dev;
2604 struct libusb_device_descriptor desc;
2605 struct libusb_config_descriptor *config0;
2606 int result, num;
2607 int c, i, a;
2608
2609 dev = devices[devcount].lu_device;
2610
2611 result = libusb_open (dev, &devices[devcount].lu_handle);
2612 if (result < 0)
2613 {
2614 SANE_Status status = SANE_STATUS_INVAL;
2615
2616 DBG (1, "sanei_usb_open: can't open device `%s': %s\n",
2617 devname, sanei_libusb_strerror (result));
2618 if (result == LIBUSB_ERROR_ACCESS)
2619 {
2620 DBG (1, "Make sure you run as root or set appropriate "
2621 "permissions\n");
2622 status = SANE_STATUS_ACCESS_DENIED;
2623 }
2624 else if (result == LIBUSB_ERROR_BUSY)
2625 {
2626 DBG (1, "Maybe the kernel scanner driver claims the "
2627 "scanner's interface?\n");
2628 status = SANE_STATUS_DEVICE_BUSY;
2629 }
2630 else if (result == LIBUSB_ERROR_NO_MEM)
2631 {
2632 status = SANE_STATUS_NO_MEM;
2633 }
2634 return status;
2635 }
2636
2637 result = libusb_get_configuration (devices[devcount].lu_handle, &config);
2638 if (result < 0)
2639 {
2640 DBG (1,
2641 "sanei_usb_open: could not get configuration for device `%s' (err %d)\n",
2642 devname, result);
2643 return SANE_STATUS_INVAL;
2644 }
2645
2646 #if !defined(SANEI_ALLOW_UNCONFIGURED_DEVICES)
2647 if (config == 0)
2648 {
2649 DBG (1, "sanei_usb_open: device `%s' not configured?\n", devname);
2650 return SANE_STATUS_INVAL;
2651 }
2652 #endif
2653
2654 result = libusb_get_device_descriptor (dev, &desc);
2655 if (result < 0)
2656 {
2657 DBG (1,
2658 "sanei_usb_open: could not get device descriptor for device `%s' (err %d)\n",
2659 devname, result);
2660 return SANE_STATUS_INVAL;
2661 }
2662
2663 result = libusb_get_config_descriptor (dev, 0, &config0);
2664 if (result < 0)
2665 {
2666 DBG (1,
2667 "sanei_usb_open: could not get config[0] descriptor for device `%s' (err %d)\n",
2668 devname, result);
2669 return SANE_STATUS_INVAL;
2670 }
2671
2672 /* Set the configuration */
2673 if (desc.bNumConfigurations > 1)
2674 {
2675 DBG (3, "sanei_usb_open: more than one "
2676 "configuration (%d), choosing first config (%d)\n",
2677 desc.bNumConfigurations,
2678 config0->bConfigurationValue);
2679
2680 result = 0;
2681 if (config != config0->bConfigurationValue)
2682 result = libusb_set_configuration (devices[devcount].lu_handle,
2683 config0->bConfigurationValue);
2684
2685 if (result < 0)
2686 {
2687 SANE_Status status = SANE_STATUS_INVAL;
2688
2689 DBG (1, "sanei_usb_open: libusb complained: %s\n",
2690 sanei_libusb_strerror (result));
2691 if (result == LIBUSB_ERROR_ACCESS)
2692 {
2693 DBG (1, "Make sure you run as root or set appropriate "
2694 "permissions\n");
2695 status = SANE_STATUS_ACCESS_DENIED;
2696 }
2697 else if (result == LIBUSB_ERROR_BUSY)
2698 {
2699 DBG (3, "Maybe the kernel scanner driver or usblp claims "
2700 "the interface? Ignoring this error...\n");
2701 status = SANE_STATUS_GOOD;
2702 }
2703
2704 if (status != SANE_STATUS_GOOD)
2705 {
2706 libusb_close (devices[devcount].lu_handle);
2707 libusb_free_config_descriptor (config0);
2708 return status;
2709 }
2710 }
2711 }
2712 libusb_free_config_descriptor (config0);
2713
2714 /* Claim the interface */
2715 result = libusb_claim_interface (devices[devcount].lu_handle,
2716 devices[devcount].interface_nr);
2717 if (result < 0)
2718 {
2719 SANE_Status status = SANE_STATUS_INVAL;
2720
2721 DBG (1, "sanei_usb_open: libusb complained: %s\n",
2722 sanei_libusb_strerror (result));
2723 if (result == LIBUSB_ERROR_ACCESS)
2724 {
2725 DBG (1, "Make sure you run as root or set appropriate "
2726 "permissions\n");
2727 status = SANE_STATUS_ACCESS_DENIED;
2728 }
2729 else if (result == LIBUSB_ERROR_BUSY)
2730 {
2731 DBG (1, "Maybe the kernel scanner driver claims the "
2732 "scanner's interface?\n");
2733 status = SANE_STATUS_DEVICE_BUSY;
2734 }
2735
2736 libusb_close (devices[devcount].lu_handle);
2737 return status;
2738 }
2739
2740 /* Loop through all of the configurations */
2741 for (c = 0; c < desc.bNumConfigurations; c++)
2742 {
2743 struct libusb_config_descriptor *config;
2744
2745 result = libusb_get_config_descriptor (dev, c, &config);
2746 if (result < 0)
2747 {
2748 DBG (1,
2749 "sanei_usb_open: could not get config[%d] descriptor for device `%s' (err %d)\n",
2750 c, devname, result);
2751 continue;
2752 }
2753
2754 /* Loop through all of the interfaces */
2755 for (i = 0; i < config->bNumInterfaces; i++)
2756 {
2757 /* Loop through all of the alternate settings */
2758 for (a = 0; a < config->interface[i].num_altsetting; a++)
2759 {
2760 const struct libusb_interface_descriptor *interface;
2761
2762 DBG (5, "sanei_usb_open: configuration nr: %d\n", c);
2763 DBG (5, "sanei_usb_open: interface nr: %d\n", i);
2764 DBG (5, "sanei_usb_open: alt_setting nr: %d\n", a);
2765
2766 /* Start by interfaces found in sanei_usb_init */
2767 if (c == 0 && i != devices[devcount].interface_nr)
2768 {
2769 DBG (5, "sanei_usb_open: interface %d not detected as "
2770 "a scanner by sanei_usb_init, ignoring.\n", i);
2771 continue;
2772 }
2773
2774 interface = &config->interface[i].altsetting[a];
2775
2776 /* Now we look for usable endpoints */
2777 for (num = 0; num < interface->bNumEndpoints; num++)
2778 {
2779 const struct libusb_endpoint_descriptor *endpoint;
2780 int direction, transfer_type, transfer_type_libusb;
2781
2782 endpoint = &interface->endpoint[num];
2783 DBG (5, "sanei_usb_open: endpoint nr: %d\n", num);
2784
2785 transfer_type_libusb =
2786 endpoint->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK;
2787 direction = endpoint->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK;
2788
2789 // don't rely on LIBUSB_TRANSFER_TYPE_* mapping to
2790 // USB_ENDPOINT_TYPE_* even though they'll most likely be
2791 // the same
2792 switch (transfer_type_libusb)
2793 {
2794 case LIBUSB_TRANSFER_TYPE_INTERRUPT:
2795 transfer_type = USB_ENDPOINT_TYPE_INTERRUPT;
2796 break;
2797 case LIBUSB_TRANSFER_TYPE_BULK:
2798 transfer_type = USB_ENDPOINT_TYPE_BULK;
2799 break;
2800 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
2801 transfer_type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS;
2802 break;
2803 case LIBUSB_TRANSFER_TYPE_CONTROL:
2804 transfer_type = USB_ENDPOINT_TYPE_CONTROL;
2805 break;
2806
2807 }
2808
2809 sanei_usb_add_endpoint(&devices[devcount],
2810 transfer_type,
2811 endpoint->bEndpointAddress,
2812 direction);
2813 }
2814 }
2815 }
2816
2817 libusb_free_config_descriptor (config);
2818 }
2819
2820 #else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
2821 DBG (1, "sanei_usb_open: can't open device `%s': "
2822 "libusb support missing\n", devname);
2823 return SANE_STATUS_UNSUPPORTED;
2824 #endif /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
2825 }
2826 else if (devices[devcount].method == sanei_usb_method_scanner_driver)
2827 {
2828 #ifdef FD_CLOEXEC
2829 long int flag;
2830 #endif
2831 /* Using kernel scanner driver */
2832 devices[devcount].fd = -1;
2833 #ifdef HAVE_RESMGR
2834 devices[devcount].fd = rsm_open_device (devname, O_RDWR);
2835 #endif
2836 if (devices[devcount].fd == -1)
2837 devices[devcount].fd = open (devname, O_RDWR);
2838 if (devices[devcount].fd < 0)
2839 {
2840 SANE_Status status = SANE_STATUS_INVAL;
2841
2842 if (errno == EACCES)
2843 status = SANE_STATUS_ACCESS_DENIED;
2844 else if (errno == ENOENT)
2845 {
2846 DBG (5, "sanei_usb_open: open of `%s' failed: %s\n",
2847 devname, strerror (errno));
2848 return status;
2849 }
2850 DBG (1, "sanei_usb_open: open of `%s' failed: %s\n",
2851 devname, strerror (errno));
2852 return status;
2853 }
2854 #ifdef FD_CLOEXEC
2855 flag = fcntl (devices[devcount].fd, F_GETFD);
2856 if (flag >= 0)
2857 {
2858 if (fcntl (devices[devcount].fd, F_SETFD, flag | FD_CLOEXEC) < 0)
2859 DBG (1, "sanei_usb_open: fcntl of `%s' failed: %s\n",
2860 devname, strerror (errno));
2861 }
2862 #endif
2863 }
2864 else if (devices[devcount].method == sanei_usb_method_usbcalls)
2865 {
2866 #ifdef HAVE_USBCALLS
2867 CHAR ucData[2048];
2868 struct usb_device_descriptor *pDevDesc;
2869 struct usb_config_descriptor *pCfgDesc;
2870 struct usb_interface_descriptor *interface;
2871 struct usb_endpoint_descriptor *endpoint;
2872 struct usb_descriptor_header *pDescHead;
2873
2874 ULONG ulBufLen;
2875 ulBufLen = sizeof(ucData);
2876 memset(&ucData,0,sizeof(ucData));
2877
2878 int result, rc;
2879 int address, direction, transfer_type;
2880
2881 DBG (5, "devname = %s, devcount = %d\n",devices[devcount].devname,devcount);
2882 DBG (5, "USBCalls device number to open = %d\n",devices[devcount].fd);
2883 DBG (5, "USBCalls Vendor/Product to open = 0x%04x/0x%04x\n",
2884 devices[devcount].vendor,devices[devcount].product);
2885
2886 rc = UsbOpen (&dh,
2887 devices[devcount].vendor,
2888 devices[devcount].product,
2889 USB_ANY_PRODUCTVERSION,
2890 USB_OPEN_FIRST_UNUSED);
2891 DBG (1, "sanei_usb_open: UsbOpen rc = %d\n",rc);
2892 if (rc!=0)
2893 {
2894 SANE_Status status = SANE_STATUS_INVAL;
2895 DBG (1, "sanei_usb_open: can't open device `%s': %s\n",
2896 devname, strerror (rc));
2897 return status;
2898 }
2899 rc = UsbQueryDeviceReport( devices[devcount].fd,
2900 &ulBufLen,
2901 ucData);
2902 DBG (1, "sanei_usb_open: UsbQueryDeviceReport rc = %d\n",rc);
2903 pDevDesc = (struct usb_device_descriptor*)ucData;
2904 pCfgDesc = (struct usb_config_descriptor*) (ucData+sizeof(struct usb_device_descriptor));
2905 UCHAR *pCurPtr = (UCHAR*) pCfgDesc;
2906 UCHAR *pEndPtr = pCurPtr+ pCfgDesc->wTotalLength;
2907 pDescHead = (struct usb_descriptor_header *) (pCurPtr+pCfgDesc->bLength);
2908 /* Set the configuration */
2909 if (pDevDesc->bNumConfigurations > 1)
2910 {
2911 DBG (3, "sanei_usb_open: more than one "
2912 "configuration (%d), choosing first config (%d)\n",
2913 pDevDesc->bNumConfigurations,
2914 pCfgDesc->bConfigurationValue);
2915 }
2916 DBG (5, "UsbDeviceSetConfiguration parameters: dh = %p, bConfigurationValue = %d\n",
2917 dh,pCfgDesc->bConfigurationValue);
2918 result = UsbDeviceSetConfiguration (dh,
2919 pCfgDesc->bConfigurationValue);
2920 DBG (1, "sanei_usb_open: UsbDeviceSetConfiguration rc = %d\n",result);
2921 if (result)
2922 {
2923 DBG (1, "sanei_usb_open: usbcalls complained on UsbDeviceSetConfiguration, rc= %d\n", result);
2924 UsbClose (dh);
2925 return SANE_STATUS_ACCESS_DENIED;
2926 }
2927
2928 /* Now we look for usable endpoints */
2929
2930 for (pDescHead = (struct usb_descriptor_header *) (pCurPtr+pCfgDesc->bLength);
2931 pDescHead;pDescHead = GetNextDescriptor(pDescHead,pEndPtr) )
2932 {
2933 switch(pDescHead->bDescriptorType)
2934 {
2935 case USB_DT_INTERFACE:
2936 interface = (struct usb_interface_descriptor *) pDescHead;
2937 DBG (5, "Found %d endpoints\n",interface->bNumEndpoints);
2938 DBG (5, "bAlternateSetting = %d\n",interface->bAlternateSetting);
2939 break;
2940 case USB_DT_ENDPOINT:
2941 endpoint = (struct usb_endpoint_descriptor*)pDescHead;
2942 direction = endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
2943 transfer_type = endpoint->bmAttributes & USB_ENDPOINT_TYPE_MASK;
2944
2945 if (transfer_type == USB_ENDPOINT_TYPE_INTERRUPT ||
2946 transfer_type == USB_ENDPOINT_TYPE_BULK)
2947 {
2948 sanei_usb_add_endpoint(&devices[devcount], transfer_type,
2949 endpoint->bEndpointAddress, direction);
2950 }
2951 /* ignore currently unsupported endpoints */
2952 else {
2953 DBG (5, "sanei_usb_open: ignoring %s-%s endpoint "
2954 "(address: %d)\n",
2955 sanei_usb_transfer_type_desc(transfer_type),
2956 direction ? "in" : "out", address);
2957 continue;
2958 }
2959 break;
2960 }
2961 }
2962 #else
2963 DBG (1, "sanei_usb_open: can't open device `%s': "
2964 "usbcalls support missing\n", devname);
2965 return SANE_STATUS_UNSUPPORTED;
2966 #endif /* HAVE_USBCALLS */
2967 }
2968 else
2969 {
2970 DBG (1, "sanei_usb_open: access method %d not implemented\n",
2971 devices[devcount].method);
2972 return SANE_STATUS_INVAL;
2973 }
2974
2975 if (testing_mode == sanei_usb_testing_mode_record)
2976 {
2977 #if WITH_USB_RECORD_REPLAY
2978 sanei_usb_record_open(devcount);
2979 #else
2980 DBG (1, "USB record-replay mode support is missing\n");
2981 return SANE_STATUS_UNSUPPORTED;
2982 #endif
2983 }
2984
2985 devices[devcount].open = SANE_TRUE;
2986 *dn = devcount;
2987 DBG (3, "sanei_usb_open: opened usb device `%s' (*dn=%d)\n",
2988 devname, devcount);
2989 return SANE_STATUS_GOOD;
2990 }
2991
2992 void
sanei_usb_close(SANE_Int dn)2993 sanei_usb_close (SANE_Int dn)
2994 {
2995 char *env;
2996 int workaround = 0;
2997
2998 DBG (5, "sanei_usb_close: evaluating environment variable SANE_USB_WORKAROUND\n");
2999 env = getenv ("SANE_USB_WORKAROUND");
3000 if (env)
3001 {
3002 workaround = atoi(env);
3003 DBG (5, "sanei_usb_close: workaround: %d\n", workaround);
3004 }
3005
3006 DBG (5, "sanei_usb_close: closing device %d\n", dn);
3007 if (dn >= device_number || dn < 0)
3008 {
3009 DBG (1, "sanei_usb_close: dn >= device number || dn < 0\n");
3010 return;
3011 }
3012 if (!devices[dn].open)
3013 {
3014 DBG (1, "sanei_usb_close: device %d already closed or never opened\n",
3015 dn);
3016 return;
3017 }
3018 if (testing_mode == sanei_usb_testing_mode_replay)
3019 {
3020 DBG (1, "sanei_usb_close: closing fake USB device\n");
3021 }
3022 else if (devices[dn].method == sanei_usb_method_scanner_driver)
3023 close (devices[dn].fd);
3024 else if (devices[dn].method == sanei_usb_method_usbcalls)
3025 {
3026 #ifdef HAVE_USBCALLS
3027 int rc;
3028 rc=UsbClose (dh);
3029 DBG (5,"rc of UsbClose = %d\n",rc);
3030 #else
3031 DBG (1, "sanei_usb_close: usbcalls support missing\n");
3032 #endif
3033 }
3034 else
3035 #ifdef HAVE_LIBUSB_LEGACY
3036 {
3037 /* This call seems to be required by Linux xhci driver
3038 * even though it should be a no-op. Without it, the
3039 * host or driver does not reset it's data toggle bit.
3040 * We intentionally ignore the return val */
3041 if (workaround)
3042 {
3043 sanei_usb_set_altinterface (dn, devices[dn].alt_setting);
3044 }
3045
3046 usb_release_interface (devices[dn].libusb_handle,
3047 devices[dn].interface_nr);
3048 usb_close (devices[dn].libusb_handle);
3049 }
3050 #elif defined(HAVE_LIBUSB)
3051 {
3052 /* This call seems to be required by Linux xhci driver
3053 * even though it should be a no-op. Without it, the
3054 * host or driver does not reset it's data toggle bit.
3055 * We intentionally ignore the return val */
3056 if (workaround)
3057 {
3058 sanei_usb_set_altinterface (dn, devices[dn].alt_setting);
3059 }
3060
3061 libusb_release_interface (devices[dn].lu_handle,
3062 devices[dn].interface_nr);
3063 libusb_close (devices[dn].lu_handle);
3064 }
3065 #else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
3066 DBG (1, "sanei_usb_close: libusb support missing\n");
3067 #endif
3068 devices[dn].open = SANE_FALSE;
3069 return;
3070 }
3071
3072 void
sanei_usb_set_timeout(SANE_Int __sane_unused__ timeout)3073 sanei_usb_set_timeout (SANE_Int __sane_unused__ timeout)
3074 {
3075 if (testing_mode == sanei_usb_testing_mode_replay)
3076 return;
3077
3078 #if defined(HAVE_LIBUSB_LEGACY) || defined(HAVE_LIBUSB)
3079 libusb_timeout = timeout;
3080 #else
3081 DBG (1, "sanei_usb_set_timeout: libusb support missing\n");
3082 #endif /* HAVE_LIBUSB_LEGACY || HAVE_LIBUSB */
3083 }
3084
3085 SANE_Status
sanei_usb_clear_halt(SANE_Int dn)3086 sanei_usb_clear_halt (SANE_Int dn)
3087 {
3088 char *env;
3089 int workaround = 0;
3090
3091 DBG (5, "sanei_usb_clear_halt: evaluating environment variable SANE_USB_WORKAROUND\n");
3092 env = getenv ("SANE_USB_WORKAROUND");
3093 if (env)
3094 {
3095 workaround = atoi(env);
3096 DBG (5, "sanei_usb_clear_halt: workaround: %d\n", workaround);
3097 }
3098
3099 if (dn >= device_number || dn < 0)
3100 {
3101 DBG (1, "sanei_usb_clear_halt: dn >= device number || dn < 0\n");
3102 return SANE_STATUS_INVAL;
3103 }
3104
3105 if (testing_mode == sanei_usb_testing_mode_replay)
3106 return SANE_STATUS_GOOD;
3107
3108 #ifdef HAVE_LIBUSB_LEGACY
3109 int ret;
3110
3111 /* This call seems to be required by Linux xhci driver
3112 * even though it should be a no-op. Without it, the
3113 * host or driver does not send the clear to the device.
3114 * We intentionally ignore the return val */
3115 if (workaround)
3116 {
3117 sanei_usb_set_altinterface (dn, devices[dn].alt_setting);
3118 }
3119
3120 ret = usb_clear_halt (devices[dn].libusb_handle, devices[dn].bulk_in_ep);
3121 if (ret){
3122 DBG (1, "sanei_usb_clear_halt: BULK_IN ret=%d\n", ret);
3123 return SANE_STATUS_INVAL;
3124 }
3125
3126 ret = usb_clear_halt (devices[dn].libusb_handle, devices[dn].bulk_out_ep);
3127 if (ret){
3128 DBG (1, "sanei_usb_clear_halt: BULK_OUT ret=%d\n", ret);
3129 return SANE_STATUS_INVAL;
3130 }
3131
3132 #elif defined(HAVE_LIBUSB)
3133 int ret;
3134
3135 /* This call seems to be required by Linux xhci driver
3136 * even though it should be a no-op. Without it, the
3137 * host or driver does not send the clear to the device.
3138 * We intentionally ignore the return val */
3139 if (workaround)
3140 {
3141 sanei_usb_set_altinterface (dn, devices[dn].alt_setting);
3142 }
3143
3144 ret = libusb_clear_halt (devices[dn].lu_handle, devices[dn].bulk_in_ep);
3145 if (ret){
3146 DBG (1, "sanei_usb_clear_halt: BULK_IN ret=%d\n", ret);
3147 return SANE_STATUS_INVAL;
3148 }
3149
3150 ret = libusb_clear_halt (devices[dn].lu_handle, devices[dn].bulk_out_ep);
3151 if (ret){
3152 DBG (1, "sanei_usb_clear_halt: BULK_OUT ret=%d\n", ret);
3153 return SANE_STATUS_INVAL;
3154 }
3155 #else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
3156 DBG (1, "sanei_usb_clear_halt: libusb support missing\n");
3157 #endif /* HAVE_LIBUSB_LEGACY || HAVE_LIBUSB */
3158
3159 return SANE_STATUS_GOOD;
3160 }
3161
3162 SANE_Status
sanei_usb_reset(SANE_Int __sane_unused__ dn)3163 sanei_usb_reset (SANE_Int __sane_unused__ dn)
3164 {
3165 if (testing_mode == sanei_usb_testing_mode_replay)
3166 return SANE_STATUS_GOOD;
3167
3168 #ifdef HAVE_LIBUSB_LEGACY
3169 int ret;
3170
3171 ret = usb_reset (devices[dn].libusb_handle);
3172 if (ret){
3173 DBG (1, "sanei_usb_reset: ret=%d\n", ret);
3174 return SANE_STATUS_INVAL;
3175 }
3176
3177 #elif defined(HAVE_LIBUSB)
3178 int ret;
3179
3180 ret = libusb_reset_device (devices[dn].lu_handle);
3181 if (ret){
3182 DBG (1, "sanei_usb_reset: ret=%d\n", ret);
3183 return SANE_STATUS_INVAL;
3184 }
3185
3186 #else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
3187 DBG (1, "sanei_usb_reset: libusb support missing\n");
3188 #endif /* HAVE_LIBUSB_LEGACY || HAVE_LIBUSB */
3189
3190 return SANE_STATUS_GOOD;
3191 }
3192
3193 #if WITH_USB_RECORD_REPLAY
3194 // returns non-negative value on success, -1 on failure
sanei_usb_replay_next_read_bulk_packet_size(SANE_Int dn)3195 static int sanei_usb_replay_next_read_bulk_packet_size(SANE_Int dn)
3196 {
3197 xmlNode* node = sanei_xml_peek_next_tx_node();
3198 if (node == NULL)
3199 return -1;
3200
3201 if (xmlStrcmp(node->name, (const xmlChar*)"bulk_tx") != 0)
3202 {
3203 return -1;
3204 }
3205
3206 if (!sanei_usb_attr_is(node, "direction", "IN"))
3207 return -1;
3208 if (!sanei_usb_attr_is_uint(node, "endpoint_number",
3209 devices[dn].bulk_in_ep & 0x0f))
3210 return -1;
3211
3212 size_t got_size = 0;
3213 char* got_data = sanei_xml_get_hex_data(node, &got_size);
3214 free(got_data);
3215 return got_size;
3216 }
3217
sanei_usb_record_read_bulk(xmlNode * node,SANE_Int dn,SANE_Byte * buffer,size_t size,ssize_t read_size)3218 static void sanei_usb_record_read_bulk(xmlNode* node, SANE_Int dn,
3219 SANE_Byte* buffer,
3220 size_t size, ssize_t read_size)
3221 {
3222 int node_was_null = node == NULL;
3223 if (node_was_null)
3224 node = testing_append_commands_node;
3225
3226 xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"bulk_tx");
3227 sanei_xml_command_common_props(e_tx, devices[dn].bulk_in_ep & 0x0f, "IN");
3228
3229 if (buffer == NULL)
3230 {
3231 const int buf_size = 128;
3232 char buf[buf_size];
3233 snprintf(buf, buf_size, "(unknown read of allowed size %ld)", size);
3234 xmlNode* e_content = xmlNewText((const xmlChar*)buf);
3235 xmlAddChild(e_tx, e_content);
3236 }
3237 else
3238 {
3239 if (read_size >= 0)
3240 {
3241 sanei_xml_set_hex_data(e_tx, (const char*)buffer, read_size);
3242 }
3243 else
3244 {
3245 xmlNewProp(e_tx, (const xmlChar*)"error", (const xmlChar*)"timeout");
3246 }
3247 }
3248
3249 node = sanei_xml_append_command(node, node_was_null, e_tx);
3250
3251 if (node_was_null)
3252 testing_append_commands_node = node;
3253 }
3254
sanei_usb_record_replace_read_bulk(xmlNode * node,SANE_Int dn,SANE_Byte * buffer,size_t size,size_t read_size)3255 static void sanei_usb_record_replace_read_bulk(xmlNode* node, SANE_Int dn,
3256 SANE_Byte* buffer,
3257 size_t size, size_t read_size)
3258 {
3259 if (!testing_development_mode)
3260 return;
3261 testing_known_commands_input_failed = 1;
3262 testing_last_known_seq--;
3263 sanei_usb_record_read_bulk(node, dn, buffer, size, read_size);
3264 xmlUnlinkNode(node);
3265 xmlFreeNode(node);
3266 }
3267
sanei_usb_replay_read_bulk(SANE_Int dn,SANE_Byte * buffer,size_t size)3268 static int sanei_usb_replay_read_bulk(SANE_Int dn, SANE_Byte* buffer,
3269 size_t size)
3270 {
3271 // libusb may potentially combine multiple IN packets into a single transfer.
3272 // We recontruct that by looking into the next packet. If it can be
3273 // included into the current transfer without
3274 size_t wanted_size = size;
3275 size_t total_got_size = 0;
3276 while (wanted_size > 0)
3277 {
3278 if (testing_known_commands_input_failed)
3279 return -1;
3280
3281 xmlNode* node = sanei_xml_get_next_tx_node();
3282 if (node == NULL)
3283 {
3284 FAIL_TEST(__func__, "no more transactions\n");
3285 return -1;
3286 }
3287
3288 if (sanei_xml_is_known_commands_end(node))
3289 {
3290 sanei_usb_record_read_bulk(NULL, dn, NULL, 0, size);
3291 testing_known_commands_input_failed = 1;
3292 return -1;
3293 }
3294
3295 sanei_xml_record_seq(node);
3296 sanei_xml_break_if_needed(node);
3297
3298 if (xmlStrcmp(node->name, (const xmlChar*)"bulk_tx") != 0)
3299 {
3300 FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n",
3301 (const char*) node->name);
3302 sanei_usb_record_replace_read_bulk(node, dn, NULL, 0, wanted_size);
3303 return -1;
3304 }
3305
3306 if (!sanei_usb_check_attr(node, "direction", "IN", __func__))
3307 {
3308 sanei_usb_record_replace_read_bulk(node, dn, NULL, 0, wanted_size);
3309 return -1;
3310 }
3311 if (!sanei_usb_check_attr_uint(node, "endpoint_number",
3312 devices[dn].bulk_in_ep & 0x0f,
3313 __func__))
3314 {
3315 sanei_usb_record_replace_read_bulk(node, dn, NULL, 0, wanted_size);
3316 return -1;
3317 }
3318
3319 size_t got_size = 0;
3320 char* got_data = sanei_xml_get_hex_data(node, &got_size);
3321
3322 if (got_size > wanted_size)
3323 {
3324 FAIL_TEST_TX(__func__, node,
3325 "got more data than wanted (%lu vs %lu)\n",
3326 got_size, wanted_size);
3327 free(got_data);
3328 sanei_usb_record_replace_read_bulk(node, dn, NULL, 0, wanted_size);
3329 return -1;
3330 }
3331
3332 memcpy(buffer + total_got_size, got_data, got_size);
3333 free(got_data);
3334 total_got_size += got_size;
3335 wanted_size -= got_size;
3336
3337 int next_size = sanei_usb_replay_next_read_bulk_packet_size(dn);
3338 if (next_size < 0)
3339 return total_got_size;
3340 if ((size_t) next_size > wanted_size)
3341 return total_got_size;
3342 }
3343 return total_got_size;
3344 }
3345 #endif // WITH_USB_RECORD_REPLAY
3346
3347 SANE_Status
sanei_usb_read_bulk(SANE_Int dn,SANE_Byte * buffer,size_t * size)3348 sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)
3349 {
3350 ssize_t read_size = 0;
3351
3352 if (!size)
3353 {
3354 DBG (1, "sanei_usb_read_bulk: size == NULL\n");
3355 return SANE_STATUS_INVAL;
3356 }
3357
3358 if (dn >= device_number || dn < 0)
3359 {
3360 DBG (1, "sanei_usb_read_bulk: dn >= device number || dn < 0\n");
3361 return SANE_STATUS_INVAL;
3362 }
3363 DBG (5, "sanei_usb_read_bulk: trying to read %lu bytes\n",
3364 (unsigned long) *size);
3365
3366 if (testing_mode == sanei_usb_testing_mode_replay)
3367 {
3368 #if WITH_USB_RECORD_REPLAY
3369 read_size = sanei_usb_replay_read_bulk(dn, buffer, *size);
3370 #else
3371 DBG(1, "%s: USB record-replay mode support missing\n", __func__);
3372 return SANE_STATUS_UNSUPPORTED;
3373 #endif
3374 }
3375 else if (devices[dn].method == sanei_usb_method_scanner_driver)
3376 {
3377 read_size = read (devices[dn].fd, buffer, *size);
3378
3379 if (read_size < 0)
3380 DBG (1, "sanei_usb_read_bulk: read failed: %s\n",
3381 strerror (errno));
3382 }
3383 else if (devices[dn].method == sanei_usb_method_libusb)
3384 #ifdef HAVE_LIBUSB_LEGACY
3385 {
3386 if (devices[dn].bulk_in_ep)
3387 {
3388 read_size = usb_bulk_read (devices[dn].libusb_handle,
3389 devices[dn].bulk_in_ep, (char *) buffer,
3390 (int) *size, libusb_timeout);
3391
3392 if (read_size < 0)
3393 DBG (1, "sanei_usb_read_bulk: read failed: %s\n",
3394 strerror (errno));
3395 }
3396 else
3397 {
3398 DBG (1, "sanei_usb_read_bulk: can't read without a bulk-in "
3399 "endpoint\n");
3400 return SANE_STATUS_INVAL;
3401 }
3402 }
3403 #elif defined(HAVE_LIBUSB)
3404 {
3405 if (devices[dn].bulk_in_ep)
3406 {
3407 int ret, rsize;
3408 ret = libusb_bulk_transfer (devices[dn].lu_handle,
3409 devices[dn].bulk_in_ep, buffer,
3410 (int) *size, &rsize,
3411 libusb_timeout);
3412
3413 if (ret < 0)
3414 {
3415 DBG (1, "sanei_usb_read_bulk: read failed (still got %d bytes): %s\n",
3416 rsize, sanei_libusb_strerror (ret));
3417
3418 read_size = -1;
3419 }
3420 else
3421 {
3422 read_size = rsize;
3423 }
3424 }
3425 else
3426 {
3427 DBG (1, "sanei_usb_read_bulk: can't read without a bulk-in "
3428 "endpoint\n");
3429 return SANE_STATUS_INVAL;
3430 }
3431 }
3432 #else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
3433 {
3434 DBG (1, "sanei_usb_read_bulk: libusb support missing\n");
3435 return SANE_STATUS_UNSUPPORTED;
3436 }
3437 #endif /* not HAVE_LIBUSB_LEGACY */
3438 else if (devices[dn].method == sanei_usb_method_usbcalls)
3439 {
3440 #ifdef HAVE_USBCALLS
3441 int rc;
3442 char* buffer_ptr = (char*) buffer;
3443 size_t requested_size = *size;
3444 while (requested_size)
3445 {
3446 ULONG ulToRead = (requested_size>MAX_RW)?MAX_RW:requested_size;
3447 ULONG ulNum = ulToRead;
3448 DBG (5, "Entered usbcalls UsbBulkRead with dn = %d\n",dn);
3449 DBG (5, "Entered usbcalls UsbBulkRead with dh = %p\n",dh);
3450 DBG (5, "Entered usbcalls UsbBulkRead with bulk_in_ep = 0x%02x\n",devices[dn].bulk_in_ep);
3451 DBG (5, "Entered usbcalls UsbBulkRead with interface_nr = %d\n",devices[dn].interface_nr);
3452 DBG (5, "Entered usbcalls UsbBulkRead with usbcalls_timeout = %d\n",usbcalls_timeout);
3453
3454 if (devices[dn].bulk_in_ep){
3455 rc = UsbBulkRead (dh, devices[dn].bulk_in_ep, devices[dn].interface_nr,
3456 &ulToRead, buffer_ptr, usbcalls_timeout);
3457 DBG (1, "sanei_usb_read_bulk: rc = %d\n",rc);}
3458 else
3459 {
3460 DBG (1, "sanei_usb_read_bulk: can't read without a bulk-in endpoint\n");
3461 return SANE_STATUS_INVAL;
3462 }
3463 if (rc || (ulNum!=ulToRead)) return SANE_STATUS_INVAL;
3464 requested_size -=ulToRead;
3465 buffer_ptr += ulToRead;
3466 read_size += ulToRead;
3467 }
3468 #else /* not HAVE_USBCALLS */
3469 {
3470 DBG (1, "sanei_usb_read_bulk: usbcalls support missing\n");
3471 return SANE_STATUS_UNSUPPORTED;
3472 }
3473 #endif /* not HAVE_USBCALLS */
3474 }
3475 else
3476 {
3477 DBG (1, "sanei_usb_read_bulk: access method %d not implemented\n",
3478 devices[dn].method);
3479 return SANE_STATUS_INVAL;
3480 }
3481
3482 if (testing_mode == sanei_usb_testing_mode_record)
3483 {
3484 #if WITH_USB_RECORD_REPLAY
3485 sanei_usb_record_read_bulk(NULL, dn, buffer, *size, read_size);
3486 #else
3487 DBG (1, "USB record-replay mode support is missing\n");
3488 return SANE_STATUS_UNSUPPORTED;
3489 #endif
3490 }
3491
3492 if (read_size < 0)
3493 {
3494 *size = 0;
3495 if (testing_mode != sanei_usb_testing_mode_disabled)
3496 return SANE_STATUS_IO_ERROR;
3497
3498 #ifdef HAVE_LIBUSB_LEGACY
3499 if (devices[dn].method == sanei_usb_method_libusb)
3500 usb_clear_halt (devices[dn].libusb_handle, devices[dn].bulk_in_ep);
3501 #elif defined(HAVE_LIBUSB)
3502 if (devices[dn].method == sanei_usb_method_libusb)
3503 libusb_clear_halt (devices[dn].lu_handle, devices[dn].bulk_in_ep);
3504 #endif
3505 return SANE_STATUS_IO_ERROR;
3506 }
3507 if (read_size == 0)
3508 {
3509 DBG (3, "sanei_usb_read_bulk: read returned EOF\n");
3510 *size = 0;
3511 return SANE_STATUS_EOF;
3512 }
3513 if (debug_level > 10)
3514 print_buffer (buffer, read_size);
3515 DBG (5, "sanei_usb_read_bulk: wanted %lu bytes, got %ld bytes\n",
3516 (unsigned long) *size, (unsigned long) read_size);
3517 *size = read_size;
3518
3519 return SANE_STATUS_GOOD;
3520 }
3521
3522 #if WITH_USB_RECORD_REPLAY
sanei_usb_record_write_bulk(xmlNode * node,SANE_Int dn,const SANE_Byte * buffer,size_t size,size_t write_size)3523 static int sanei_usb_record_write_bulk(xmlNode* node, SANE_Int dn,
3524 const SANE_Byte* buffer,
3525 size_t size, size_t write_size)
3526 {
3527 int node_was_null = node == NULL;
3528 if (node_was_null)
3529 node = testing_append_commands_node;
3530
3531 xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"bulk_tx");
3532 sanei_xml_command_common_props(e_tx, devices[dn].bulk_out_ep & 0x0f, "OUT");
3533 sanei_xml_set_hex_data(e_tx, (const char*)buffer, size);
3534 // FIXME: output write_size
3535
3536 node = sanei_xml_append_command(node, node_was_null, e_tx);
3537
3538 if (node_was_null)
3539 testing_append_commands_node = node;
3540 return write_size;
3541 }
3542
sanei_usb_record_replace_write_bulk(xmlNode * node,SANE_Int dn,const SANE_Byte * buffer,size_t size,size_t write_size)3543 static void sanei_usb_record_replace_write_bulk(xmlNode* node, SANE_Int dn,
3544 const SANE_Byte* buffer,
3545 size_t size, size_t write_size)
3546 {
3547 if (!testing_development_mode)
3548 return;
3549 testing_last_known_seq--;
3550 sanei_usb_record_write_bulk(node, dn, buffer, size, write_size);
3551 xmlUnlinkNode(node);
3552 xmlFreeNode(node);
3553 }
3554
3555 // returns non-negative value on success, -1 on failure
sanei_usb_replay_next_write_bulk_packet_size(SANE_Int dn)3556 static int sanei_usb_replay_next_write_bulk_packet_size(SANE_Int dn)
3557 {
3558 xmlNode* node = sanei_xml_peek_next_tx_node();
3559 if (node == NULL)
3560 return -1;
3561
3562 if (xmlStrcmp(node->name, (const xmlChar*)"bulk_tx") != 0)
3563 {
3564 return -1;
3565 }
3566
3567 if (!sanei_usb_attr_is(node, "direction", "OUT"))
3568 return -1;
3569 if (!sanei_usb_attr_is_uint(node, "endpoint_number",
3570 devices[dn].bulk_out_ep & 0x0f))
3571 return -1;
3572
3573 size_t got_size = 0;
3574 char* got_data = sanei_xml_get_hex_data(node, &got_size);
3575 free(got_data);
3576 return got_size;
3577 }
3578
sanei_usb_replay_write_bulk(SANE_Int dn,const SANE_Byte * buffer,size_t size)3579 static int sanei_usb_replay_write_bulk(SANE_Int dn, const SANE_Byte* buffer,
3580 size_t size)
3581 {
3582 size_t wanted_size = size;
3583 size_t total_wrote_size = 0;
3584 while (wanted_size > 0)
3585 {
3586 if (testing_known_commands_input_failed)
3587 return -1;
3588
3589 xmlNode* node = sanei_xml_get_next_tx_node();
3590 if (node == NULL)
3591 {
3592 FAIL_TEST(__func__, "no more transactions\n");
3593 return -1;
3594 }
3595
3596 if (sanei_xml_is_known_commands_end(node))
3597 {
3598 sanei_usb_record_write_bulk(NULL, dn, buffer, size, size);
3599 return size;
3600 }
3601
3602 sanei_xml_record_seq(node);
3603 sanei_xml_break_if_needed(node);
3604
3605 if (xmlStrcmp(node->name, (const xmlChar*)"bulk_tx") != 0)
3606 {
3607 FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n",
3608 (const char*) node->name);
3609 sanei_usb_record_replace_write_bulk(node, dn, buffer, size, size);
3610 return -1;
3611 }
3612
3613 if (!sanei_usb_check_attr(node, "direction", "OUT", __func__))
3614 {
3615 sanei_usb_record_replace_write_bulk(node, dn, buffer, size, size);
3616 return -1;
3617 }
3618 if (!sanei_usb_check_attr_uint(node, "endpoint_number",
3619 devices[dn].bulk_out_ep & 0x0f,
3620 __func__))
3621 {
3622 sanei_usb_record_replace_write_bulk(node, dn, buffer, size, size);
3623 return -1;
3624 }
3625
3626 size_t wrote_size = 0;
3627 char* wrote_data = sanei_xml_get_hex_data(node, &wrote_size);
3628
3629 if (wrote_size > wanted_size)
3630 {
3631 FAIL_TEST_TX(__func__, node,
3632 "wrote more data than wanted (%lu vs %lu)\n",
3633 wrote_size, wanted_size);
3634 if (!testing_development_mode)
3635 {
3636 free(wrote_data);
3637 return -1;
3638 }
3639 sanei_usb_record_replace_write_bulk(node, dn, buffer, size, size);
3640 wrote_size = size;
3641 }
3642 else if (!sanei_usb_check_data_equal(node,
3643 ((const char*) buffer) +
3644 total_wrote_size,
3645 wrote_size,
3646 wrote_data, wrote_size,
3647 __func__))
3648 {
3649 if (!testing_development_mode)
3650 {
3651 free(wrote_data);
3652 return -1;
3653 }
3654 sanei_usb_record_replace_write_bulk(node, dn, buffer, size,
3655 size);
3656 wrote_size = size;
3657 }
3658
3659 free(wrote_data);
3660 if (wrote_size < wanted_size &&
3661 sanei_usb_replay_next_write_bulk_packet_size(dn) < 0)
3662 {
3663 FAIL_TEST_TX(__func__, node,
3664 "wrote less data than wanted (%lu vs %lu)\n",
3665 wrote_size, wanted_size);
3666 if (!testing_development_mode)
3667 {
3668 return -1;
3669 }
3670 sanei_usb_record_replace_write_bulk(node, dn, buffer, size,
3671 size);
3672 wrote_size = size;
3673 }
3674 total_wrote_size += wrote_size;
3675 wanted_size -= wrote_size;
3676 }
3677 return total_wrote_size;
3678 }
3679 #endif
3680
3681 SANE_Status
sanei_usb_write_bulk(SANE_Int dn,const SANE_Byte * buffer,size_t * size)3682 sanei_usb_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size)
3683 {
3684 ssize_t write_size = 0;
3685
3686 if (!size)
3687 {
3688 DBG (1, "sanei_usb_write_bulk: size == NULL\n");
3689 return SANE_STATUS_INVAL;
3690 }
3691
3692 if (dn >= device_number || dn < 0)
3693 {
3694 DBG (1, "sanei_usb_write_bulk: dn >= device number || dn < 0\n");
3695 return SANE_STATUS_INVAL;
3696 }
3697 DBG (5, "sanei_usb_write_bulk: trying to write %lu bytes\n",
3698 (unsigned long) *size);
3699 if (debug_level > 10)
3700 print_buffer (buffer, *size);
3701
3702 if (testing_mode == sanei_usb_testing_mode_replay)
3703 {
3704 #if WITH_USB_RECORD_REPLAY
3705 write_size = sanei_usb_replay_write_bulk(dn, buffer, *size);
3706 #else
3707 DBG (1, "USB record-replay mode support is missing\n");
3708 return SANE_STATUS_UNSUPPORTED;
3709 #endif
3710 }
3711 else if (devices[dn].method == sanei_usb_method_scanner_driver)
3712 {
3713 write_size = write (devices[dn].fd, buffer, *size);
3714
3715 if (write_size < 0)
3716 DBG (1, "sanei_usb_write_bulk: write failed: %s\n",
3717 strerror (errno));
3718 }
3719 else if (devices[dn].method == sanei_usb_method_libusb)
3720 #ifdef HAVE_LIBUSB_LEGACY
3721 {
3722 if (devices[dn].bulk_out_ep)
3723 {
3724 write_size = usb_bulk_write (devices[dn].libusb_handle,
3725 devices[dn].bulk_out_ep,
3726 (const char *) buffer,
3727 (int) *size, libusb_timeout);
3728 if (write_size < 0)
3729 DBG (1, "sanei_usb_write_bulk: write failed: %s\n",
3730 strerror (errno));
3731 }
3732 else
3733 {
3734 DBG (1, "sanei_usb_write_bulk: can't write without a bulk-out "
3735 "endpoint\n");
3736 return SANE_STATUS_INVAL;
3737 }
3738 }
3739 #elif defined(HAVE_LIBUSB)
3740 {
3741 if (devices[dn].bulk_out_ep)
3742 {
3743 int ret;
3744 int trans_bytes;
3745 ret = libusb_bulk_transfer (devices[dn].lu_handle,
3746 devices[dn].bulk_out_ep,
3747 (unsigned char *) buffer,
3748 (int) *size, &trans_bytes,
3749 libusb_timeout);
3750 if (ret < 0)
3751 {
3752 DBG (1, "sanei_usb_write_bulk: write failed: %s\n",
3753 sanei_libusb_strerror (ret));
3754
3755 write_size = -1;
3756 }
3757 else
3758 write_size = trans_bytes;
3759 }
3760 else
3761 {
3762 DBG (1, "sanei_usb_write_bulk: can't write without a bulk-out "
3763 "endpoint\n");
3764 return SANE_STATUS_INVAL;
3765 }
3766 }
3767 #else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
3768 {
3769 DBG (1, "sanei_usb_write_bulk: libusb support missing\n");
3770 return SANE_STATUS_UNSUPPORTED;
3771 }
3772 #endif /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
3773 else if (devices[dn].method == sanei_usb_method_usbcalls)
3774 {
3775 #ifdef HAVE_USBCALLS
3776 int rc;
3777 DBG (5, "Entered usbcalls UsbBulkWrite with dn = %d\n",dn);
3778 DBG (5, "Entered usbcalls UsbBulkWrite with dh = %p\n",dh);
3779 DBG (5, "Entered usbcalls UsbBulkWrite with bulk_out_ep = 0x%02x\n",devices[dn].bulk_out_ep);
3780 DBG (5, "Entered usbcalls UsbBulkWrite with interface_nr = %d\n",devices[dn].interface_nr);
3781 DBG (5, "Entered usbcalls UsbBulkWrite with usbcalls_timeout = %d\n",usbcalls_timeout);
3782 size_t requested_size = *size;
3783 while (requested_size)
3784 {
3785 ULONG ulToWrite = (requested_size>MAX_RW)?MAX_RW:requested_size;
3786
3787 DBG (5, "size requested to write = %lu, ulToWrite = %lu\n",(unsigned long) requested_size,ulToWrite);
3788 if (devices[dn].bulk_out_ep){
3789 rc = UsbBulkWrite (dh, devices[dn].bulk_out_ep, devices[dn].interface_nr,
3790 ulToWrite, (char*) buffer, usbcalls_timeout);
3791 DBG (1, "sanei_usb_write_bulk: rc = %d\n",rc);
3792 }
3793 else
3794 {
3795 DBG (1, "sanei_usb_write_bulk: can't read without a bulk-out endpoint\n");
3796 return SANE_STATUS_INVAL;
3797 }
3798 if (rc) return SANE_STATUS_INVAL;
3799 requested_size -=ulToWrite;
3800 buffer += ulToWrite;
3801 write_size += ulToWrite;
3802 DBG (5, "size = %d, write_size = %d\n", requested_size, write_size);
3803 }
3804 #else /* not HAVE_USBCALLS */
3805 {
3806 DBG (1, "sanei_usb_write_bulk: usbcalls support missing\n");
3807 return SANE_STATUS_UNSUPPORTED;
3808 }
3809 #endif /* not HAVE_USBCALLS */
3810 }
3811 else
3812 {
3813 DBG (1, "sanei_usb_write_bulk: access method %d not implemented\n",
3814 devices[dn].method);
3815 return SANE_STATUS_INVAL;
3816 }
3817
3818 if (testing_mode == sanei_usb_testing_mode_record)
3819 {
3820 #if WITH_USB_RECORD_REPLAY
3821 sanei_usb_record_write_bulk(NULL, dn, buffer, *size, write_size);
3822 #else
3823 DBG (1, "USB record-replay mode support is missing\n");
3824 return SANE_STATUS_UNSUPPORTED;
3825 #endif
3826 }
3827
3828 if (write_size < 0)
3829 {
3830 *size = 0;
3831 if (testing_mode != sanei_usb_testing_mode_disabled)
3832 return SANE_STATUS_IO_ERROR;
3833
3834 #ifdef HAVE_LIBUSB_LEGACY
3835 if (devices[dn].method == sanei_usb_method_libusb)
3836 usb_clear_halt (devices[dn].libusb_handle, devices[dn].bulk_out_ep);
3837 #elif defined(HAVE_LIBUSB)
3838 if (devices[dn].method == sanei_usb_method_libusb)
3839 libusb_clear_halt (devices[dn].lu_handle, devices[dn].bulk_out_ep);
3840 #endif
3841 return SANE_STATUS_IO_ERROR;
3842 }
3843 DBG (5, "sanei_usb_write_bulk: wanted %lu bytes, wrote %ld bytes\n",
3844 (unsigned long) *size, (unsigned long) write_size);
3845 *size = write_size;
3846 return SANE_STATUS_GOOD;
3847 }
3848
3849 #if WITH_USB_RECORD_REPLAY
3850 static void
sanei_usb_record_control_msg(xmlNode * node,SANE_Int dn,SANE_Int rtype,SANE_Int req,SANE_Int value,SANE_Int index,SANE_Int len,const SANE_Byte * data)3851 sanei_usb_record_control_msg(xmlNode* node,
3852 SANE_Int dn, SANE_Int rtype, SANE_Int req,
3853 SANE_Int value, SANE_Int index, SANE_Int len,
3854 const SANE_Byte* data)
3855 {
3856 (void) dn;
3857
3858 int node_was_null = node == NULL;
3859 if (node_was_null)
3860 node = testing_append_commands_node;
3861
3862 xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"control_tx");
3863
3864 int direction_is_in = (rtype & 0x80) == 0x80;
3865 sanei_xml_command_common_props(e_tx, rtype & 0x1f,
3866 direction_is_in ? "IN" : "OUT");
3867 sanei_xml_set_hex_attr(e_tx, "bmRequestType", rtype);
3868 sanei_xml_set_hex_attr(e_tx, "bRequest", req);
3869 sanei_xml_set_hex_attr(e_tx, "wValue", value);
3870 sanei_xml_set_hex_attr(e_tx, "wIndex", index);
3871 sanei_xml_set_hex_attr(e_tx, "wLength", len);
3872
3873 if (direction_is_in && data == NULL)
3874 {
3875 const int buf_size = 128;
3876 char buf[buf_size];
3877 snprintf(buf, buf_size, "(unknown read of size %d)", len);
3878 xmlNode* e_content = xmlNewText((const xmlChar*)buf);
3879 xmlAddChild(e_tx, e_content);
3880 }
3881 else
3882 {
3883 sanei_xml_set_hex_data(e_tx, (const char*)data, len);
3884 }
3885
3886 node = sanei_xml_append_command(node, node_was_null, e_tx);
3887
3888 if (node_was_null)
3889 testing_append_commands_node = node;
3890 }
3891
3892
3893 static SANE_Status
sanei_usb_record_replace_control_msg(xmlNode * node,SANE_Int dn,SANE_Int rtype,SANE_Int req,SANE_Int value,SANE_Int index,SANE_Int len,const SANE_Byte * data)3894 sanei_usb_record_replace_control_msg(xmlNode* node,
3895 SANE_Int dn, SANE_Int rtype, SANE_Int req,
3896 SANE_Int value, SANE_Int index, SANE_Int len,
3897 const SANE_Byte* data)
3898 {
3899 if (!testing_development_mode)
3900 return SANE_STATUS_IO_ERROR;
3901
3902 SANE_Status ret = SANE_STATUS_GOOD;
3903 int direction_is_in = (rtype & 0x80) == 0x80;
3904 if (direction_is_in)
3905 {
3906 testing_known_commands_input_failed = 1;
3907 ret = SANE_STATUS_IO_ERROR;
3908 }
3909
3910 testing_last_known_seq--;
3911 sanei_usb_record_control_msg(node, dn, rtype, req, value, index, len, data);
3912 xmlUnlinkNode(node);
3913 xmlFreeNode(node);
3914 return ret;
3915 }
3916
3917 static SANE_Status
sanei_usb_replay_control_msg(SANE_Int dn,SANE_Int rtype,SANE_Int req,SANE_Int value,SANE_Int index,SANE_Int len,SANE_Byte * data)3918 sanei_usb_replay_control_msg(SANE_Int dn, SANE_Int rtype, SANE_Int req,
3919 SANE_Int value, SANE_Int index, SANE_Int len,
3920 SANE_Byte* data)
3921 {
3922 (void) dn;
3923
3924 if (testing_known_commands_input_failed)
3925 return SANE_STATUS_IO_ERROR;
3926
3927 xmlNode* node = sanei_xml_get_next_tx_node();
3928 if (node == NULL)
3929 {
3930 FAIL_TEST(__func__, "no more transactions\n");
3931 return SANE_STATUS_IO_ERROR;
3932 }
3933
3934 int direction_is_in = (rtype & 0x80) == 0x80;
3935 SANE_Byte* rdata = direction_is_in ? NULL : data;
3936
3937 if (sanei_xml_is_known_commands_end(node))
3938 {
3939 sanei_usb_record_control_msg(NULL, dn, rtype, req, value, index, len,
3940 rdata);
3941 if (direction_is_in)
3942 {
3943 testing_known_commands_input_failed = 1;
3944 return SANE_STATUS_IO_ERROR;
3945 }
3946 return SANE_STATUS_GOOD;
3947 }
3948
3949 sanei_xml_record_seq(node);
3950 sanei_xml_break_if_needed(node);
3951
3952 if (xmlStrcmp(node->name, (const xmlChar*)"control_tx") != 0)
3953 {
3954 FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n",
3955 (const char*) node->name);
3956 return sanei_usb_record_replace_control_msg(node, dn, rtype, req, value,
3957 index, len, rdata);
3958 }
3959
3960 if (!sanei_usb_check_attr(node, "direction", direction_is_in ? "IN" : "OUT",
3961 __func__) ||
3962 !sanei_usb_check_attr_uint(node, "bmRequestType", rtype, __func__) ||
3963 !sanei_usb_check_attr_uint(node, "bRequest", req, __func__) ||
3964 !sanei_usb_check_attr_uint(node, "wValue", value, __func__) ||
3965 !sanei_usb_check_attr_uint(node, "wIndex", index, __func__) ||
3966 !sanei_usb_check_attr_uint(node, "wLength", len, __func__))
3967 {
3968 return sanei_usb_record_replace_control_msg(node, dn, rtype, req, value,
3969 index, len, rdata);
3970 }
3971
3972 size_t tx_data_size = 0;
3973 char* tx_data = sanei_xml_get_hex_data(node, &tx_data_size);
3974
3975 if (direction_is_in)
3976 {
3977 if (tx_data_size != (size_t)len)
3978 {
3979 FAIL_TEST_TX(__func__, node,
3980 "got different amount of data than wanted (%lu vs %lu)\n",
3981 tx_data_size, (size_t)len);
3982 free(tx_data);
3983 return sanei_usb_record_replace_control_msg(node, dn, rtype, req,
3984 value, index, len, rdata);
3985 }
3986 memcpy(data, tx_data, tx_data_size);
3987 }
3988 else
3989 {
3990 if (!sanei_usb_check_data_equal(node,
3991 (const char*)data, len,
3992 tx_data, tx_data_size, __func__))
3993 {
3994 free(tx_data);
3995 return sanei_usb_record_replace_control_msg(node, dn, rtype, req,
3996 value, index, len, rdata);
3997 }
3998 }
3999 free(tx_data);
4000 return SANE_STATUS_GOOD;
4001 }
4002 #endif
4003
4004 SANE_Status
sanei_usb_control_msg(SANE_Int dn,SANE_Int rtype,SANE_Int req,SANE_Int value,SANE_Int index,SANE_Int len,SANE_Byte * data)4005 sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,
4006 SANE_Int value, SANE_Int index, SANE_Int len,
4007 SANE_Byte * data)
4008 {
4009 if (dn >= device_number || dn < 0)
4010 {
4011 DBG (1, "sanei_usb_control_msg: dn >= device number || dn < 0, dn=%d\n",
4012 dn);
4013 return SANE_STATUS_INVAL;
4014 }
4015
4016 DBG (5, "sanei_usb_control_msg: rtype = 0x%02x, req = %d, value = %d, "
4017 "index = %d, len = %d\n", rtype, req, value, index, len);
4018 if (!(rtype & 0x80) && debug_level > 10)
4019 print_buffer (data, len);
4020
4021 if (testing_mode == sanei_usb_testing_mode_replay)
4022 {
4023 #if WITH_USB_RECORD_REPLAY
4024 return sanei_usb_replay_control_msg(dn, rtype, req, value, index, len,
4025 data);
4026 #else
4027 DBG (1, "USB record-replay mode support is missing\n");
4028 return SANE_STATUS_UNSUPPORTED;
4029 #endif
4030 }
4031 if (devices[dn].method == sanei_usb_method_scanner_driver)
4032 {
4033 #if defined(__linux__)
4034 struct ctrlmsg_ioctl c;
4035
4036 c.req.requesttype = rtype;
4037 c.req.request = req;
4038 c.req.value = value;
4039 c.req.index = index;
4040 c.req.length = len;
4041 c.data = data;
4042
4043 if (ioctl (devices[dn].fd, SCANNER_IOCTL_CTRLMSG, &c) < 0)
4044 {
4045 DBG (5, "sanei_usb_control_msg: SCANNER_IOCTL_CTRLMSG error - %s\n",
4046 strerror (errno));
4047 return SANE_STATUS_IO_ERROR;
4048 }
4049 if ((rtype & 0x80) && debug_level > 10)
4050 print_buffer (data, len);
4051 #elif defined(__BEOS__)
4052 struct usb_scanner_ioctl_ctrlmsg c;
4053
4054 c.req.request_type = rtype;
4055 c.req.request = req;
4056 c.req.value = value;
4057 c.req.index = index;
4058 c.req.length = len;
4059 c.data = data;
4060
4061 if (ioctl (devices[dn].fd, B_SCANNER_IOCTL_CTRLMSG, &c) < 0)
4062 {
4063 DBG (5, "sanei_usb_control_msg: SCANNER_IOCTL_CTRLMSG error - %s\n",
4064 strerror (errno));
4065 return SANE_STATUS_IO_ERROR;
4066 }
4067 if ((rtype & 0x80) && debug_level > 10)
4068 print_buffer (data, len);
4069 #else /* not __linux__ */
4070 DBG (5, "sanei_usb_control_msg: not supported on this OS\n");
4071 return SANE_STATUS_UNSUPPORTED;
4072 #endif /* not __linux__ */
4073 }
4074 else if (devices[dn].method == sanei_usb_method_libusb)
4075 #ifdef HAVE_LIBUSB_LEGACY
4076 {
4077 int result;
4078
4079 result = usb_control_msg (devices[dn].libusb_handle, rtype, req,
4080 value, index, (char *) data, len,
4081 libusb_timeout);
4082 if (result < 0)
4083 {
4084 DBG (1, "sanei_usb_control_msg: libusb complained: %s\n",
4085 usb_strerror ());
4086 return SANE_STATUS_INVAL;
4087 }
4088 if ((rtype & 0x80) && debug_level > 10)
4089 print_buffer (data, len);
4090 }
4091 #elif defined(HAVE_LIBUSB)
4092 {
4093 int result;
4094
4095 result = libusb_control_transfer (devices[dn].lu_handle, rtype, req,
4096 value, index, data, len,
4097 libusb_timeout);
4098 if (result < 0)
4099 {
4100 DBG (1, "sanei_usb_control_msg: libusb complained: %s\n",
4101 sanei_libusb_strerror (result));
4102 return SANE_STATUS_INVAL;
4103 }
4104 if ((rtype & 0x80) && debug_level > 10)
4105 print_buffer (data, len);
4106 }
4107 #else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB*/
4108 {
4109 DBG (1, "sanei_usb_control_msg: libusb support missing\n");
4110 return SANE_STATUS_UNSUPPORTED;
4111 }
4112 #endif /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
4113 else if (devices[dn].method == sanei_usb_method_usbcalls)
4114 {
4115 #ifdef HAVE_USBCALLS
4116 int result;
4117
4118 result = UsbCtrlMessage (dh, rtype, req,
4119 value, index, len, (char *) data,
4120 usbcalls_timeout);
4121 DBG (5, "rc of usb_control_msg = %d\n",result);
4122 if (result < 0)
4123 {
4124 DBG (1, "sanei_usb_control_msg: usbcalls complained: %d\n",result);
4125 return SANE_STATUS_INVAL;
4126 }
4127 if ((rtype & 0x80) && debug_level > 10)
4128 print_buffer (data, len);
4129 #else /* not HAVE_USBCALLS */
4130 {
4131 DBG (1, "sanei_usb_control_msg: usbcalls support missing\n");
4132 return SANE_STATUS_UNSUPPORTED;
4133 }
4134 #endif /* not HAVE_USBCALLS */
4135 }
4136 else
4137 {
4138 DBG (1, "sanei_usb_control_msg: access method %d not implemented\n",
4139 devices[dn].method);
4140 return SANE_STATUS_UNSUPPORTED;
4141 }
4142
4143 if (testing_mode == sanei_usb_testing_mode_record)
4144 {
4145 #if WITH_USB_RECORD_REPLAY
4146 // TODO: record in the error code path too
4147 sanei_usb_record_control_msg(NULL, dn, rtype, req, value, index, len,
4148 data);
4149 #else
4150 DBG (1, "USB record-replay mode support is missing\n");
4151 return SANE_STATUS_UNSUPPORTED;
4152 #endif
4153 }
4154 return SANE_STATUS_GOOD;
4155 }
4156
4157 #if WITH_USB_RECORD_REPLAY
sanei_usb_record_read_int(xmlNode * node,SANE_Int dn,SANE_Byte * buffer,size_t size,ssize_t read_size)4158 static void sanei_usb_record_read_int(xmlNode* node,
4159 SANE_Int dn, SANE_Byte* buffer,
4160 size_t size, ssize_t read_size)
4161 {
4162 (void) size;
4163
4164 int node_was_null = node == NULL;
4165 if (node_was_null)
4166 node = testing_append_commands_node;
4167
4168 xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"interrupt_tx");
4169
4170 sanei_xml_command_common_props(e_tx, devices[dn].int_in_ep & 0x0f, "IN");
4171
4172 if (buffer == NULL)
4173 {
4174 const int buf_size = 128;
4175 char buf[buf_size];
4176 snprintf(buf, buf_size, "(unknown read of wanted size %ld)", read_size);
4177 xmlNode* e_content = xmlNewText((const xmlChar*)buf);
4178 xmlAddChild(e_tx, e_content);
4179 }
4180 else
4181 {
4182 if (read_size >= 0)
4183 {
4184 sanei_xml_set_hex_data(e_tx, (const char*)buffer, read_size);
4185 }
4186 else
4187 {
4188 xmlNewProp(e_tx, (const xmlChar*)"error", (const xmlChar*)"timeout");
4189 }
4190 }
4191
4192 node = sanei_xml_append_command(node, node_was_null, e_tx);
4193
4194 if (node_was_null)
4195 testing_append_commands_node = node;
4196 }
4197
sanei_usb_record_replace_read_int(xmlNode * node,SANE_Int dn,SANE_Byte * buffer,size_t size,size_t read_size)4198 static void sanei_usb_record_replace_read_int(xmlNode* node,
4199 SANE_Int dn, SANE_Byte* buffer,
4200 size_t size, size_t read_size)
4201 {
4202 if (!testing_development_mode)
4203 return;
4204 testing_known_commands_input_failed = 1;
4205 testing_last_known_seq--;
4206 sanei_usb_record_read_int(node, dn, buffer, size, read_size);
4207 xmlUnlinkNode(node);
4208 xmlFreeNode(node);
4209 }
4210
sanei_usb_replay_read_int(SANE_Int dn,SANE_Byte * buffer,size_t size)4211 static int sanei_usb_replay_read_int(SANE_Int dn, SANE_Byte* buffer,
4212 size_t size)
4213 {
4214 if (testing_known_commands_input_failed)
4215 return -1;
4216
4217 size_t wanted_size = size;
4218
4219 xmlNode* node = sanei_xml_get_next_tx_node();
4220 if (node == NULL)
4221 {
4222 FAIL_TEST(__func__, "no more transactions\n");
4223 return -1;
4224 }
4225
4226 if (sanei_xml_is_known_commands_end(node))
4227 {
4228 sanei_usb_record_read_int(NULL, dn, NULL, 0, size);
4229 testing_known_commands_input_failed = 1;
4230 return -1;
4231 }
4232
4233 sanei_xml_record_seq(node);
4234 sanei_xml_break_if_needed(node);
4235
4236 if (xmlStrcmp(node->name, (const xmlChar*)"interrupt_tx") != 0)
4237 {
4238 FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n",
4239 (const char*) node->name);
4240 sanei_usb_record_replace_read_int(node, dn, NULL, 0, size);
4241 return -1;
4242 }
4243
4244 if (!sanei_usb_check_attr(node, "direction", "IN", __func__))
4245 {
4246 sanei_usb_record_replace_read_int(node, dn, NULL, 0, size);
4247 return -1;
4248 }
4249
4250 if (!sanei_usb_check_attr_uint(node, "endpoint_number",
4251 devices[dn].int_in_ep & 0x0f,
4252 __func__))
4253 {
4254 sanei_usb_record_replace_read_int(node, dn, NULL, 0, size);
4255 return -1;
4256 }
4257
4258 if (sanei_usb_check_attr(node, "error", "timeout", __func__))
4259 {
4260 return -1;
4261 }
4262
4263 size_t tx_data_size = 0;
4264 char* tx_data = sanei_xml_get_hex_data(node, &tx_data_size);
4265
4266 if (tx_data_size > wanted_size)
4267 {
4268 FAIL_TEST_TX(__func__, node,
4269 "got more data than wanted (%lu vs %lu)\n",
4270 tx_data_size, wanted_size);
4271 sanei_usb_record_replace_read_int(node, dn, NULL, 0, size);
4272 free(tx_data);
4273 return -1;
4274 }
4275
4276 memcpy((char*) buffer, tx_data, tx_data_size);
4277 free(tx_data);
4278 return tx_data_size;
4279 }
4280 #endif // WITH_USB_RECORD_REPLAY
4281
4282 SANE_Status
sanei_usb_read_int(SANE_Int dn,SANE_Byte * buffer,size_t * size)4283 sanei_usb_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size)
4284 {
4285 ssize_t read_size = 0;
4286 #if defined(HAVE_LIBUSB_LEGACY) || defined(HAVE_LIBUSB)
4287 SANE_Bool stalled = SANE_FALSE;
4288 #endif
4289
4290 if (!size)
4291 {
4292 DBG (1, "sanei_usb_read_int: size == NULL\n");
4293 return SANE_STATUS_INVAL;
4294 }
4295
4296 if (dn >= device_number || dn < 0)
4297 {
4298 DBG (1, "sanei_usb_read_int: dn >= device number || dn < 0\n");
4299 return SANE_STATUS_INVAL;
4300 }
4301
4302 DBG (5, "sanei_usb_read_int: trying to read %lu bytes\n",
4303 (unsigned long) *size);
4304 if (testing_mode == sanei_usb_testing_mode_replay)
4305 {
4306 #if WITH_USB_RECORD_REPLAY
4307 read_size = sanei_usb_replay_read_int(dn, buffer, *size);
4308 #else
4309 DBG (1, "USB record-replay mode support is missing\n");
4310 return SANE_STATUS_UNSUPPORTED;
4311 #endif
4312 }
4313 else if (devices[dn].method == sanei_usb_method_scanner_driver)
4314 {
4315 DBG (1, "sanei_usb_read_int: access method %d not implemented\n",
4316 devices[dn].method);
4317 return SANE_STATUS_INVAL;
4318 }
4319 else if (devices[dn].method == sanei_usb_method_libusb)
4320 #ifdef HAVE_LIBUSB_LEGACY
4321 {
4322 if (devices[dn].int_in_ep)
4323 {
4324 read_size = usb_interrupt_read (devices[dn].libusb_handle,
4325 devices[dn].int_in_ep,
4326 (char *) buffer, (int) *size,
4327 libusb_timeout);
4328
4329 if (read_size < 0)
4330 DBG (1, "sanei_usb_read_int: read failed: %s\n",
4331 strerror (errno));
4332
4333 stalled = (read_size == -EPIPE);
4334 }
4335 else
4336 {
4337 DBG (1, "sanei_usb_read_int: can't read without an int "
4338 "endpoint\n");
4339 return SANE_STATUS_INVAL;
4340 }
4341 }
4342 #elif defined(HAVE_LIBUSB)
4343 {
4344 if (devices[dn].int_in_ep)
4345 {
4346 int ret;
4347 int trans_bytes;
4348 ret = libusb_interrupt_transfer (devices[dn].lu_handle,
4349 devices[dn].int_in_ep,
4350 buffer, (int) *size,
4351 &trans_bytes, libusb_timeout);
4352
4353 if (ret < 0)
4354 read_size = -1;
4355 else
4356 read_size = trans_bytes;
4357
4358 stalled = (ret == LIBUSB_ERROR_PIPE);
4359 }
4360 else
4361 {
4362 DBG (1, "sanei_usb_read_int: can't read without an int "
4363 "endpoint\n");
4364 return SANE_STATUS_INVAL;
4365 }
4366 }
4367 #else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
4368 {
4369 DBG (1, "sanei_usb_read_int: libusb support missing\n");
4370 return SANE_STATUS_UNSUPPORTED;
4371 }
4372 #endif /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
4373 else if (devices[dn].method == sanei_usb_method_usbcalls)
4374 {
4375 #ifdef HAVE_USBCALLS
4376 int rc;
4377 USHORT usNumBytes=*size;
4378 DBG (5, "Entered usbcalls UsbIrqStart with dn = %d\n",dn);
4379 DBG (5, "Entered usbcalls UsbIrqStart with dh = %p\n",dh);
4380 DBG (5, "Entered usbcalls UsbIrqStart with int_in_ep = 0x%02x\n",devices[dn].int_in_ep);
4381 DBG (5, "Entered usbcalls UsbIrqStart with interface_nr = %d\n",devices[dn].interface_nr);
4382 DBG (5, "Entered usbcalls UsbIrqStart with bytes to read = %u\n",usNumBytes);
4383
4384 if (devices[dn].int_in_ep){
4385 rc = UsbIrqStart (dh,devices[dn].int_in_ep,devices[dn].interface_nr,
4386 usNumBytes, (char *) buffer, pUsbIrqStartHev);
4387 DBG (5, "rc of UsbIrqStart = %d\n",rc);
4388 }
4389 else
4390 {
4391 DBG (1, "sanei_usb_read_int: can't read without an int "
4392 "endpoint\n");
4393 return SANE_STATUS_INVAL;
4394 }
4395 if (rc) return SANE_STATUS_INVAL;
4396 read_size += usNumBytes;
4397 #else
4398 DBG (1, "sanei_usb_read_int: usbcalls support missing\n");
4399 return SANE_STATUS_UNSUPPORTED;
4400 #endif /* HAVE_USBCALLS */
4401 }
4402 else
4403 {
4404 DBG (1, "sanei_usb_read_int: access method %d not implemented\n",
4405 devices[dn].method);
4406 return SANE_STATUS_INVAL;
4407 }
4408
4409 if (testing_mode == sanei_usb_testing_mode_record)
4410 {
4411 #if WITH_USB_RECORD_REPLAY
4412 sanei_usb_record_read_int(NULL, dn, buffer, *size, read_size);
4413 #else
4414 DBG (1, "USB record-replay mode support is missing\n");
4415 return SANE_STATUS_UNSUPPORTED;
4416 #endif
4417 }
4418
4419 if (read_size < 0)
4420 {
4421 *size = 0;
4422 if (testing_mode != sanei_usb_testing_mode_disabled)
4423 return SANE_STATUS_IO_ERROR;
4424
4425 #ifdef HAVE_LIBUSB_LEGACY
4426 if (devices[dn].method == sanei_usb_method_libusb)
4427 if (stalled)
4428 usb_clear_halt (devices[dn].libusb_handle, devices[dn].int_in_ep);
4429 #elif defined(HAVE_LIBUSB)
4430 if (devices[dn].method == sanei_usb_method_libusb)
4431 if (stalled)
4432 libusb_clear_halt (devices[dn].lu_handle, devices[dn].int_in_ep);
4433 #endif
4434 return SANE_STATUS_IO_ERROR;
4435 }
4436 if (read_size == 0)
4437 {
4438 DBG (3, "sanei_usb_read_int: read returned EOF\n");
4439 *size = 0;
4440 return SANE_STATUS_EOF;
4441 }
4442 DBG (5, "sanei_usb_read_int: wanted %lu bytes, got %ld bytes\n",
4443 (unsigned long) *size, (unsigned long) read_size);
4444 *size = read_size;
4445 if (debug_level > 10)
4446 print_buffer (buffer, read_size);
4447
4448 return SANE_STATUS_GOOD;
4449 }
4450
4451 #if WITH_USB_RECORD_REPLAY
sanei_usb_replay_set_configuration(SANE_Int dn,SANE_Int configuration)4452 static SANE_Status sanei_usb_replay_set_configuration(SANE_Int dn,
4453 SANE_Int configuration)
4454 {
4455 (void) dn;
4456
4457 xmlNode* node = sanei_xml_get_next_tx_node();
4458 if (node == NULL)
4459 {
4460 FAIL_TEST(__func__, "no more transactions\n");
4461 return SANE_STATUS_IO_ERROR;
4462 }
4463
4464 sanei_xml_record_seq(node);
4465 sanei_xml_break_if_needed(node);
4466
4467 if (xmlStrcmp(node->name, (const xmlChar*)"control_tx") != 0)
4468 {
4469 FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n",
4470 (const char*) node->name);
4471 return SANE_STATUS_IO_ERROR;
4472 }
4473
4474 if (!sanei_usb_check_attr(node, "direction", "OUT", __func__))
4475 return SANE_STATUS_IO_ERROR;
4476
4477 if (!sanei_usb_check_attr_uint(node, "bmRequestType", 0, __func__))
4478 return SANE_STATUS_IO_ERROR;
4479
4480 if (!sanei_usb_check_attr_uint(node, "bRequest", 9, __func__))
4481 return SANE_STATUS_IO_ERROR;
4482
4483 if (!sanei_usb_check_attr_uint(node, "wValue", configuration, __func__))
4484 return SANE_STATUS_IO_ERROR;
4485
4486 if (!sanei_usb_check_attr_uint(node, "wIndex", 0, __func__))
4487 return SANE_STATUS_IO_ERROR;
4488
4489 if (!sanei_usb_check_attr_uint(node, "wLength", 0, __func__))
4490 return SANE_STATUS_IO_ERROR;
4491
4492 return SANE_STATUS_GOOD;
4493 }
4494
sanei_usb_record_set_configuration(SANE_Int dn,SANE_Int configuration)4495 static void sanei_usb_record_set_configuration(SANE_Int dn,
4496 SANE_Int configuration)
4497 {
4498 (void) dn; (void) configuration;
4499 // TODO
4500 }
4501 #endif // WITH_USB_RECORD_REPLAY
4502
4503 SANE_Status
sanei_usb_set_configuration(SANE_Int dn,SANE_Int configuration)4504 sanei_usb_set_configuration (SANE_Int dn, SANE_Int configuration)
4505 {
4506 if (dn >= device_number || dn < 0)
4507 {
4508 DBG (1,
4509 "sanei_usb_set_configuration: dn >= device number || dn < 0, dn=%d\n",
4510 dn);
4511 return SANE_STATUS_INVAL;
4512 }
4513
4514 DBG (5, "sanei_usb_set_configuration: configuration = %d\n", configuration);
4515
4516 if (testing_mode == sanei_usb_testing_mode_record)
4517 {
4518 #if WITH_USB_RECORD_REPLAY
4519 sanei_usb_record_set_configuration(dn, configuration);
4520 #else
4521 DBG (1, "USB record-replay mode support is missing\n");
4522 return SANE_STATUS_UNSUPPORTED;
4523 #endif
4524 }
4525
4526 if (testing_mode == sanei_usb_testing_mode_replay)
4527 {
4528 #if WITH_USB_RECORD_REPLAY
4529 return sanei_usb_replay_set_configuration(dn, configuration);
4530 #else
4531 DBG (1, "USB record-replay mode support is missing\n");
4532 return SANE_STATUS_UNSUPPORTED;
4533 #endif
4534 }
4535 else if (devices[dn].method == sanei_usb_method_scanner_driver)
4536 {
4537 #if defined(__linux__)
4538 return SANE_STATUS_GOOD;
4539 #else /* not __linux__ */
4540 DBG (5, "sanei_usb_set_configuration: not supported on this OS\n");
4541 return SANE_STATUS_UNSUPPORTED;
4542 #endif /* not __linux__ */
4543 }
4544 else if (devices[dn].method == sanei_usb_method_libusb)
4545 #ifdef HAVE_LIBUSB_LEGACY
4546 {
4547 int result;
4548
4549 result =
4550 usb_set_configuration (devices[dn].libusb_handle, configuration);
4551 if (result < 0)
4552 {
4553 DBG (1, "sanei_usb_set_configuration: libusb complained: %s\n",
4554 usb_strerror ());
4555 return SANE_STATUS_INVAL;
4556 }
4557 return SANE_STATUS_GOOD;
4558 }
4559 #elif defined(HAVE_LIBUSB)
4560 {
4561 int result;
4562
4563 result = libusb_set_configuration (devices[dn].lu_handle, configuration);
4564 if (result < 0)
4565 {
4566 DBG (1, "sanei_usb_set_configuration: libusb complained: %s\n",
4567 sanei_libusb_strerror (result));
4568 return SANE_STATUS_INVAL;
4569 }
4570 return SANE_STATUS_GOOD;
4571 }
4572 #else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
4573 {
4574 DBG (1, "sanei_usb_set_configuration: libusb support missing\n");
4575 return SANE_STATUS_UNSUPPORTED;
4576 }
4577 #endif /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
4578 else
4579 {
4580 DBG (1,
4581 "sanei_usb_set_configuration: access method %d not implemented\n",
4582 devices[dn].method);
4583 return SANE_STATUS_UNSUPPORTED;
4584 }
4585 }
4586
4587 SANE_Status
sanei_usb_claim_interface(SANE_Int dn,SANE_Int interface_number)4588 sanei_usb_claim_interface (SANE_Int dn, SANE_Int interface_number)
4589 {
4590 if (dn >= device_number || dn < 0)
4591 {
4592 DBG (1,
4593 "sanei_usb_claim_interface: dn >= device number || dn < 0, dn=%d\n",
4594 dn);
4595 return SANE_STATUS_INVAL;
4596 }
4597 if (devices[dn].missing)
4598 {
4599 DBG (1, "sanei_usb_claim_interface: device dn=%d is missing\n", dn);
4600 return SANE_STATUS_INVAL;
4601 }
4602
4603 DBG (5, "sanei_usb_claim_interface: interface_number = %d\n", interface_number);
4604
4605 if (testing_mode == sanei_usb_testing_mode_replay)
4606 {
4607 return SANE_STATUS_GOOD;
4608 }
4609 else if (devices[dn].method == sanei_usb_method_scanner_driver)
4610 {
4611 #if defined(__linux__)
4612 return SANE_STATUS_GOOD;
4613 #else /* not __linux__ */
4614 DBG (5, "sanei_usb_claim_interface: not supported on this OS\n");
4615 return SANE_STATUS_UNSUPPORTED;
4616 #endif /* not __linux__ */
4617 }
4618 else if (devices[dn].method == sanei_usb_method_libusb)
4619 #ifdef HAVE_LIBUSB_LEGACY
4620 {
4621 int result;
4622
4623 result = usb_claim_interface (devices[dn].libusb_handle, interface_number);
4624 if (result < 0)
4625 {
4626 DBG (1, "sanei_usb_claim_interface: libusb complained: %s\n",
4627 usb_strerror ());
4628 return SANE_STATUS_INVAL;
4629 }
4630 return SANE_STATUS_GOOD;
4631 }
4632 #elif defined(HAVE_LIBUSB)
4633 {
4634 int result;
4635
4636 result = libusb_claim_interface (devices[dn].lu_handle, interface_number);
4637 if (result < 0)
4638 {
4639 DBG (1, "sanei_usb_claim_interface: libusb complained: %s\n",
4640 sanei_libusb_strerror (result));
4641 return SANE_STATUS_INVAL;
4642 }
4643 return SANE_STATUS_GOOD;
4644 }
4645 #else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
4646 {
4647 DBG (1, "sanei_usb_claim_interface: libusb support missing\n");
4648 return SANE_STATUS_UNSUPPORTED;
4649 }
4650 #endif /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
4651 else
4652 {
4653 DBG (1, "sanei_usb_claim_interface: access method %d not implemented\n",
4654 devices[dn].method);
4655 return SANE_STATUS_UNSUPPORTED;
4656 }
4657 }
4658
4659 SANE_Status
sanei_usb_release_interface(SANE_Int dn,SANE_Int interface_number)4660 sanei_usb_release_interface (SANE_Int dn, SANE_Int interface_number)
4661 {
4662 if (dn >= device_number || dn < 0)
4663 {
4664 DBG (1,
4665 "sanei_usb_release_interface: dn >= device number || dn < 0, dn=%d\n",
4666 dn);
4667 return SANE_STATUS_INVAL;
4668 }
4669 if (devices[dn].missing)
4670 {
4671 DBG (1, "sanei_usb_release_interface: device dn=%d is missing\n", dn);
4672 return SANE_STATUS_INVAL;
4673 }
4674 DBG (5, "sanei_usb_release_interface: interface_number = %d\n", interface_number);
4675
4676 if (testing_mode == sanei_usb_testing_mode_replay)
4677 {
4678 return SANE_STATUS_GOOD;
4679 }
4680 else if (devices[dn].method == sanei_usb_method_scanner_driver)
4681 {
4682 #if defined(__linux__)
4683 return SANE_STATUS_GOOD;
4684 #else /* not __linux__ */
4685 DBG (5, "sanei_usb_release_interface: not supported on this OS\n");
4686 return SANE_STATUS_UNSUPPORTED;
4687 #endif /* not __linux__ */
4688 }
4689 else if (devices[dn].method == sanei_usb_method_libusb)
4690 #ifdef HAVE_LIBUSB_LEGACY
4691 {
4692 int result;
4693
4694 result = usb_release_interface (devices[dn].libusb_handle, interface_number);
4695 if (result < 0)
4696 {
4697 DBG (1, "sanei_usb_release_interface: libusb complained: %s\n",
4698 usb_strerror ());
4699 return SANE_STATUS_INVAL;
4700 }
4701 return SANE_STATUS_GOOD;
4702 }
4703 #elif defined(HAVE_LIBUSB)
4704 {
4705 int result;
4706
4707 result = libusb_release_interface (devices[dn].lu_handle, interface_number);
4708 if (result < 0)
4709 {
4710 DBG (1, "sanei_usb_release_interface: libusb complained: %s\n",
4711 sanei_libusb_strerror (result));
4712 return SANE_STATUS_INVAL;
4713 }
4714 return SANE_STATUS_GOOD;
4715 }
4716 #else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
4717 {
4718 DBG (1, "sanei_usb_release_interface: libusb support missing\n");
4719 return SANE_STATUS_UNSUPPORTED;
4720 }
4721 #endif /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
4722 else
4723 {
4724 DBG (1,
4725 "sanei_usb_release_interface: access method %d not implemented\n",
4726 devices[dn].method);
4727 return SANE_STATUS_UNSUPPORTED;
4728 }
4729 }
4730
4731 SANE_Status
sanei_usb_set_altinterface(SANE_Int dn,SANE_Int alternate)4732 sanei_usb_set_altinterface (SANE_Int dn, SANE_Int alternate)
4733 {
4734 if (dn >= device_number || dn < 0)
4735 {
4736 DBG (1,
4737 "sanei_usb_set_altinterface: dn >= device number || dn < 0, dn=%d\n",
4738 dn);
4739 return SANE_STATUS_INVAL;
4740 }
4741
4742 DBG (5, "sanei_usb_set_altinterface: alternate = %d\n", alternate);
4743
4744 devices[dn].alt_setting = alternate;
4745
4746 if (testing_mode == sanei_usb_testing_mode_replay)
4747 {
4748 return SANE_STATUS_GOOD;
4749 }
4750 else if (devices[dn].method == sanei_usb_method_scanner_driver)
4751 {
4752 #if defined(__linux__)
4753 return SANE_STATUS_GOOD;
4754 #else /* not __linux__ */
4755 DBG (5, "sanei_usb_set_altinterface: not supported on this OS\n");
4756 return SANE_STATUS_UNSUPPORTED;
4757 #endif /* not __linux__ */
4758 }
4759 else if (devices[dn].method == sanei_usb_method_libusb)
4760 #ifdef HAVE_LIBUSB_LEGACY
4761 {
4762 int result;
4763
4764 result = usb_set_altinterface (devices[dn].libusb_handle, alternate);
4765 if (result < 0)
4766 {
4767 DBG (1, "sanei_usb_set_altinterface: libusb complained: %s\n",
4768 usb_strerror ());
4769 return SANE_STATUS_INVAL;
4770 }
4771 return SANE_STATUS_GOOD;
4772 }
4773 #elif defined(HAVE_LIBUSB)
4774 {
4775 int result;
4776
4777 result = libusb_set_interface_alt_setting (devices[dn].lu_handle,
4778 devices[dn].interface_nr, alternate);
4779 if (result < 0)
4780 {
4781 DBG (1, "sanei_usb_set_altinterface: libusb complained: %s\n",
4782 sanei_libusb_strerror (result));
4783 return SANE_STATUS_INVAL;
4784 }
4785 return SANE_STATUS_GOOD;
4786 }
4787 #else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
4788 {
4789 DBG (1, "sanei_set_altinterface: libusb support missing\n");
4790 return SANE_STATUS_UNSUPPORTED;
4791 }
4792 #endif /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
4793 else
4794 {
4795 DBG (1,
4796 "sanei_usb_set_altinterface: access method %d not implemented\n",
4797 devices[dn].method);
4798 return SANE_STATUS_UNSUPPORTED;
4799 }
4800 }
4801
4802 #if WITH_USB_RECORD_REPLAY
4803
4804 static SANE_Status
sanei_usb_replay_get_descriptor(SANE_Int dn,struct sanei_usb_dev_descriptor * desc)4805 sanei_usb_replay_get_descriptor(SANE_Int dn,
4806 struct sanei_usb_dev_descriptor *desc)
4807 {
4808 (void) dn;
4809
4810 if (testing_known_commands_input_failed)
4811 return SANE_STATUS_IO_ERROR;
4812
4813 xmlNode* node = sanei_xml_get_next_tx_node();
4814 if (node == NULL)
4815 {
4816 FAIL_TEST(__func__, "no more transactions\n");
4817 return SANE_STATUS_IO_ERROR;
4818 }
4819
4820 if (sanei_xml_is_known_commands_end(node))
4821 {
4822 testing_known_commands_input_failed = 1;
4823 return SANE_STATUS_IO_ERROR;
4824 }
4825
4826 sanei_xml_record_seq(node);
4827 sanei_xml_break_if_needed(node);
4828
4829 if (xmlStrcmp(node->name, (const xmlChar*)"get_descriptor") != 0)
4830 {
4831 FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n",
4832 (const char*) node->name);
4833 testing_known_commands_input_failed = 1;
4834 return SANE_STATUS_IO_ERROR;
4835 }
4836
4837 int desc_type = sanei_xml_get_prop_uint(node, "descriptor_type");
4838 int bcd_usb = sanei_xml_get_prop_uint(node, "bcd_usb");
4839 int bcd_dev = sanei_xml_get_prop_uint(node, "bcd_device");
4840 int dev_class = sanei_xml_get_prop_uint(node, "device_class");
4841 int dev_sub_class = sanei_xml_get_prop_uint(node, "device_sub_class");
4842 int dev_protocol = sanei_xml_get_prop_uint(node, "device_protocol");
4843 int max_packet_size = sanei_xml_get_prop_uint(node, "max_packet_size");
4844
4845 if (desc_type < 0 || bcd_usb < 0 || bcd_dev < 0 || dev_class < 0 ||
4846 dev_sub_class < 0 || dev_protocol < 0 || max_packet_size < 0)
4847 {
4848 FAIL_TEST_TX(__func__, node, "get_descriptor recorded block is missing attributes\n");
4849 testing_known_commands_input_failed = 1;
4850 return SANE_STATUS_IO_ERROR;
4851 }
4852
4853 desc->desc_type = desc_type;
4854 desc->bcd_usb = bcd_usb;
4855 desc->bcd_dev = bcd_dev;
4856 desc->dev_class = dev_class;
4857 desc->dev_sub_class = dev_sub_class;
4858 desc->dev_protocol = dev_protocol;
4859 desc->max_packet_size = max_packet_size;
4860
4861 return SANE_STATUS_GOOD;
4862 }
4863
4864 static void
sanei_usb_record_get_descriptor(SANE_Int dn,struct sanei_usb_dev_descriptor * desc)4865 sanei_usb_record_get_descriptor(SANE_Int dn,
4866 struct sanei_usb_dev_descriptor *desc)
4867 {
4868 (void) dn;
4869
4870 xmlNode* node = testing_append_commands_node;
4871
4872 xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"get_descriptor");
4873
4874 xmlNewProp(e_tx, (const xmlChar*)"time_usec", (const xmlChar*)"0");
4875 sanei_xml_set_uint_attr(node, "seq", ++testing_last_known_seq);
4876
4877 sanei_xml_set_hex_attr(e_tx, "descriptor_type", desc->desc_type);
4878 sanei_xml_set_hex_attr(e_tx, "bcd_usb", desc->bcd_usb);
4879 sanei_xml_set_hex_attr(e_tx, "bcd_device", desc->bcd_dev);
4880 sanei_xml_set_hex_attr(e_tx, "device_class", desc->dev_class);
4881 sanei_xml_set_hex_attr(e_tx, "device_sub_class", desc->dev_sub_class);
4882 sanei_xml_set_hex_attr(e_tx, "device_protocol", desc->dev_protocol);
4883 sanei_xml_set_hex_attr(e_tx, "max_packet_size", desc->max_packet_size);
4884
4885 node = sanei_xml_append_command(node, 1, e_tx);
4886 testing_append_commands_node = node;
4887 }
4888
4889 #endif // WITH_USB_RECORD_REPLAY
4890
4891 extern SANE_Status
sanei_usb_get_descriptor(SANE_Int dn,struct sanei_usb_dev_descriptor __sane_unused__ * desc)4892 sanei_usb_get_descriptor( SANE_Int dn,
4893 struct sanei_usb_dev_descriptor __sane_unused__
4894 *desc )
4895 {
4896 if (dn >= device_number || dn < 0)
4897 {
4898 DBG (1,
4899 "sanei_usb_get_descriptor: dn >= device number || dn < 0, dn=%d\n",
4900 dn);
4901 return SANE_STATUS_INVAL;
4902 }
4903
4904 if (testing_mode == sanei_usb_testing_mode_replay)
4905 {
4906 #if WITH_USB_RECORD_REPLAY
4907 return sanei_usb_replay_get_descriptor(dn, desc);
4908 #else
4909 DBG (1, "USB record-replay mode support is missing\n");
4910 return SANE_STATUS_UNSUPPORTED;
4911 #endif
4912 }
4913
4914 DBG (5, "sanei_usb_get_descriptor\n");
4915 #ifdef HAVE_LIBUSB_LEGACY
4916 {
4917 struct usb_device_descriptor *usb_descr;
4918
4919 usb_descr = &(devices[dn].libusb_device->descriptor);
4920 desc->desc_type = usb_descr->bDescriptorType;
4921 desc->bcd_usb = usb_descr->bcdUSB;
4922 desc->bcd_dev = usb_descr->bcdDevice;
4923 desc->dev_class = usb_descr->bDeviceClass;
4924
4925 desc->dev_sub_class = usb_descr->bDeviceSubClass;
4926 desc->dev_protocol = usb_descr->bDeviceProtocol;
4927 desc->max_packet_size = usb_descr->bMaxPacketSize0;
4928 }
4929 #elif defined(HAVE_LIBUSB)
4930 {
4931 struct libusb_device_descriptor lu_desc;
4932 int ret;
4933
4934 ret = libusb_get_device_descriptor (devices[dn].lu_device, &lu_desc);
4935 if (ret < 0)
4936 {
4937 DBG (1,
4938 "sanei_usb_get_descriptor: libusb error: %s\n",
4939 sanei_libusb_strerror (ret));
4940
4941 return SANE_STATUS_INVAL;
4942 }
4943
4944 desc->desc_type = lu_desc.bDescriptorType;
4945 desc->bcd_usb = lu_desc.bcdUSB;
4946 desc->bcd_dev = lu_desc.bcdDevice;
4947 desc->dev_class = lu_desc.bDeviceClass;
4948
4949 desc->dev_sub_class = lu_desc.bDeviceSubClass;
4950 desc->dev_protocol = lu_desc.bDeviceProtocol;
4951 desc->max_packet_size = lu_desc.bMaxPacketSize0;
4952 }
4953 #else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
4954 {
4955 DBG (1, "sanei_usb_get_descriptor: libusb support missing\n");
4956 return SANE_STATUS_UNSUPPORTED;
4957 }
4958 #endif /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
4959
4960 if (testing_mode == sanei_usb_testing_mode_record)
4961 {
4962 #if WITH_USB_RECORD_REPLAY
4963 sanei_usb_record_get_descriptor(dn, desc);
4964 #else
4965 DBG (1, "USB record-replay mode support is missing\n");
4966 return SANE_STATUS_UNSUPPORTED;
4967 #endif
4968 }
4969
4970 return SANE_STATUS_GOOD;
4971 }
4972