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