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