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