1141cc406Sopenharmony_ci#include "../../include/sane/config.h"
2141cc406Sopenharmony_ci
3141cc406Sopenharmony_ci#include <errno.h>
4141cc406Sopenharmony_ci#include <string.h>
5141cc406Sopenharmony_ci#include <stdlib.h>
6141cc406Sopenharmony_ci#include <stdio.h>
7141cc406Sopenharmony_ci#include <unistd.h>
8141cc406Sopenharmony_ci#include <math.h>
9141cc406Sopenharmony_ci#include <stddef.h>
10141cc406Sopenharmony_ci#ifdef HAVE_SYS_TIME_H
11141cc406Sopenharmony_ci#include <sys/time.h>
12141cc406Sopenharmony_ci#endif
13141cc406Sopenharmony_ci#ifdef HAVE_SYS_TYPES_H
14141cc406Sopenharmony_ci#include <sys/types.h>
15141cc406Sopenharmony_ci#endif
16141cc406Sopenharmony_ci#ifdef HAVE_MKDIR
17141cc406Sopenharmony_ci#include <sys/stat.h>
18141cc406Sopenharmony_ci#include <sys/types.h>
19141cc406Sopenharmony_ci#endif
20141cc406Sopenharmony_ci
21141cc406Sopenharmony_ci#include <assert.h>
22141cc406Sopenharmony_ci
23141cc406Sopenharmony_ci#define BACKEND_NAME	sanei_usb
24141cc406Sopenharmony_ci
25141cc406Sopenharmony_ci#include "../../include/sane/sane.h"
26141cc406Sopenharmony_ci#include "../../include/sane/sanei.h"
27141cc406Sopenharmony_ci#include "../../include/sane/saneopts.h"
28141cc406Sopenharmony_ci
29141cc406Sopenharmony_ci#include "../../include/sane/sanei_backend.h"
30141cc406Sopenharmony_ci#include "../../include/sane/sanei_usb.h"
31141cc406Sopenharmony_ci
32141cc406Sopenharmony_ci#include "../../include/_stdint.h"
33141cc406Sopenharmony_ci
34141cc406Sopenharmony_ci/*
35141cc406Sopenharmony_ci * In order to avoid modifying sanei_usb.c to allow for unit tests
36141cc406Sopenharmony_ci * we include it so we can use its private variables and structures
37141cc406Sopenharmony_ci * and still test the code.
38141cc406Sopenharmony_ci */
39141cc406Sopenharmony_ci#include "../../sanei/sanei_usb.c"
40141cc406Sopenharmony_ci
41141cc406Sopenharmony_ci
42141cc406Sopenharmony_ci/** test sanei_usb_init()
43141cc406Sopenharmony_ci * calls sanei_usb_init
44141cc406Sopenharmony_ci * @param expected expected use count
45141cc406Sopenharmony_ci * @return 1 on success, else 0
46141cc406Sopenharmony_ci */
47141cc406Sopenharmony_cistatic int
48141cc406Sopenharmony_citest_init (int expected)
49141cc406Sopenharmony_ci{
50141cc406Sopenharmony_ci  /* initialize USB */
51141cc406Sopenharmony_ci  printf ("%s starting ...\n", __func__);
52141cc406Sopenharmony_ci  sanei_usb_init ();
53141cc406Sopenharmony_ci  if (initialized == 0)
54141cc406Sopenharmony_ci    {
55141cc406Sopenharmony_ci      printf ("ERROR: sanei_usb not initialized!\n");
56141cc406Sopenharmony_ci      return 0;
57141cc406Sopenharmony_ci    }
58141cc406Sopenharmony_ci  if (initialized != expected)
59141cc406Sopenharmony_ci    {
60141cc406Sopenharmony_ci      printf ("ERROR: incorrect use count, expected %d, got %d!\n", expected,
61141cc406Sopenharmony_ci	      initialized);
62141cc406Sopenharmony_ci      return 0;
63141cc406Sopenharmony_ci    }
64141cc406Sopenharmony_ci
65141cc406Sopenharmony_ci  printf ("sanei_usb initialized, use count is %d ...\n", initialized);
66141cc406Sopenharmony_ci  printf ("%s success\n\n", __func__);
67141cc406Sopenharmony_ci  return 1;
68141cc406Sopenharmony_ci}
69141cc406Sopenharmony_ci
70141cc406Sopenharmony_ci/** test sanei_usb_exit()
71141cc406Sopenharmony_ci * calls sanei_usb_exit
72141cc406Sopenharmony_ci * @param expected use count after exit call
73141cc406Sopenharmony_ci * @return 1 on success, else 0
74141cc406Sopenharmony_ci */
75141cc406Sopenharmony_cistatic int
76141cc406Sopenharmony_citest_exit (int expected)
77141cc406Sopenharmony_ci{
78141cc406Sopenharmony_ci  printf ("%s starting ...\n", __func__);
79141cc406Sopenharmony_ci
80141cc406Sopenharmony_ci  /* end of USB use test */
81141cc406Sopenharmony_ci  sanei_usb_exit ();
82141cc406Sopenharmony_ci  if (initialized != expected)
83141cc406Sopenharmony_ci    {
84141cc406Sopenharmony_ci      printf ("ERROR: incorrect use count, expected %d, got %d!\n", expected,
85141cc406Sopenharmony_ci	      initialized);
86141cc406Sopenharmony_ci      return 0;
87141cc406Sopenharmony_ci    }
88141cc406Sopenharmony_ci
89141cc406Sopenharmony_ci  printf ("%s success\n\n", __func__);
90141cc406Sopenharmony_ci  return 1;
91141cc406Sopenharmony_ci}
92141cc406Sopenharmony_ci
93141cc406Sopenharmony_ci
94141cc406Sopenharmony_ci/** count detected devices
95141cc406Sopenharmony_ci * count all detected devices and check it against expected value
96141cc406Sopenharmony_ci * @param expected detected count
97141cc406Sopenharmony_ci * @return 1 on success, else 0
98141cc406Sopenharmony_ci */
99141cc406Sopenharmony_cistatic int
100141cc406Sopenharmony_cicount_detected (int expected)
101141cc406Sopenharmony_ci{
102141cc406Sopenharmony_ci  int num = 0;
103141cc406Sopenharmony_ci  int i;
104141cc406Sopenharmony_ci
105141cc406Sopenharmony_ci  for (i = 0; i < device_number; i++)
106141cc406Sopenharmony_ci    {
107141cc406Sopenharmony_ci      if (devices[i].missing == 0 && devices[i].devname != NULL)
108141cc406Sopenharmony_ci	{
109141cc406Sopenharmony_ci	  num++;
110141cc406Sopenharmony_ci	}
111141cc406Sopenharmony_ci    }
112141cc406Sopenharmony_ci  if (num != expected)
113141cc406Sopenharmony_ci    {
114141cc406Sopenharmony_ci      printf ("ERROR: %d detected devices, expected %d!\n", num, expected);
115141cc406Sopenharmony_ci      return 0;
116141cc406Sopenharmony_ci    }
117141cc406Sopenharmony_ci  printf ("%d devices still detected.\n", num);
118141cc406Sopenharmony_ci  return 1;
119141cc406Sopenharmony_ci}
120141cc406Sopenharmony_ci
121141cc406Sopenharmony_ci/** create mock device
122141cc406Sopenharmony_ci * create a mock device entry
123141cc406Sopenharmony_ci * @param device device pointer to fill with mock data
124141cc406Sopenharmony_ci * @return nothing
125141cc406Sopenharmony_ci */
126141cc406Sopenharmony_cistatic void
127141cc406Sopenharmony_cicreate_mock_device (char *devname, device_list_type * device)
128141cc406Sopenharmony_ci{
129141cc406Sopenharmony_ci  memset (device, 0, sizeof (device_list_type));
130141cc406Sopenharmony_ci  device->devname = strdup (devname);
131141cc406Sopenharmony_ci  device->vendor = 0xdead;
132141cc406Sopenharmony_ci  device->product = 0xbeef;
133141cc406Sopenharmony_ci#if defined(HAVE_LIBUSB_LEGACY) || defined(HAVE_LIBUSB)
134141cc406Sopenharmony_ci  device->method = sanei_usb_method_libusb;
135141cc406Sopenharmony_ci#endif
136141cc406Sopenharmony_ci#ifdef HAVE_USBCALLS
137141cc406Sopenharmony_ci  device->method = sanei_usb_method_usbcalls;
138141cc406Sopenharmony_ci#endif
139141cc406Sopenharmony_ci#if !defined(HAVE_LIBUSB_LEGACY) && !defined(HAVE_LIBUSB) && !defined(HAVE_USBCALLS)
140141cc406Sopenharmony_ci  device->method == sanei_usb_method_scanner_driver;
141141cc406Sopenharmony_ci#endif
142141cc406Sopenharmony_ci}
143141cc406Sopenharmony_ci
144141cc406Sopenharmony_ci/** test store_device
145141cc406Sopenharmony_ci * test store_device for corner cases not covered by the
146141cc406Sopenharmony_ci * other regular use by sanei_usb_scan_devices
147141cc406Sopenharmony_ci * the startiing situation is that the mock device has never
148141cc406Sopenharmony_ci * put into device list.
149141cc406Sopenharmony_ci * @return 1 on success, else 0
150141cc406Sopenharmony_ci */
151141cc406Sopenharmony_cistatic int
152141cc406Sopenharmony_citest_store_device (void)
153141cc406Sopenharmony_ci{
154141cc406Sopenharmony_ci  int current_number;
155141cc406Sopenharmony_ci  int expected;
156141cc406Sopenharmony_ci  int i;
157141cc406Sopenharmony_ci  int found;
158141cc406Sopenharmony_ci  device_list_type mock;
159141cc406Sopenharmony_ci
160141cc406Sopenharmony_ci  create_mock_device ("mock", &mock);
161141cc406Sopenharmony_ci
162141cc406Sopenharmony_ci  /* first test store when there is no more room
163141cc406Sopenharmony_ci   * to store device */
164141cc406Sopenharmony_ci  current_number = device_number;
165141cc406Sopenharmony_ci  device_number = MAX_DEVICES;
166141cc406Sopenharmony_ci  /* give unused devices a name so strcmp() won't crash. */
167141cc406Sopenharmony_ci  for (i = current_number; i < MAX_DEVICES; i++)
168141cc406Sopenharmony_ci    devices[i].devname = "";
169141cc406Sopenharmony_ci
170141cc406Sopenharmony_ci  store_device (mock);
171141cc406Sopenharmony_ci  /* there should be no more devices */
172141cc406Sopenharmony_ci  if (device_number > MAX_DEVICES)
173141cc406Sopenharmony_ci    {
174141cc406Sopenharmony_ci      printf ("ERROR: store past end of device list!\n");
175141cc406Sopenharmony_ci      return 0;
176141cc406Sopenharmony_ci    }
177141cc406Sopenharmony_ci  /* walk device list to be sure mock device hasn't been stored */
178141cc406Sopenharmony_ci  for (i = 0; i < MAX_DEVICES; i++)
179141cc406Sopenharmony_ci    {
180141cc406Sopenharmony_ci      if (devices[i].devname && !strcmp (devices[i].devname, mock.devname))
181141cc406Sopenharmony_ci	{
182141cc406Sopenharmony_ci	  printf
183141cc406Sopenharmony_ci	    ("ERROR: device stored although there were no place for it!\n");
184141cc406Sopenharmony_ci	  return 0;
185141cc406Sopenharmony_ci	}
186141cc406Sopenharmony_ci    }
187141cc406Sopenharmony_ci
188141cc406Sopenharmony_ci  /* restore device_number */
189141cc406Sopenharmony_ci  device_number = current_number;
190141cc406Sopenharmony_ci  /* reset unused devnames to NULL */
191141cc406Sopenharmony_ci  for (i = current_number; i < MAX_DEVICES; i++)
192141cc406Sopenharmony_ci    devices[i].devname = NULL;
193141cc406Sopenharmony_ci  expected = device_number + 1;
194141cc406Sopenharmony_ci
195141cc406Sopenharmony_ci  /* store mock device */
196141cc406Sopenharmony_ci  store_device (mock);
197141cc406Sopenharmony_ci  found = 0;
198141cc406Sopenharmony_ci  for (i = 0; i < MAX_DEVICES && !found; i++)
199141cc406Sopenharmony_ci    {
200141cc406Sopenharmony_ci      if (devices[i].devname && !strcmp (devices[i].devname, mock.devname))
201141cc406Sopenharmony_ci	{
202141cc406Sopenharmony_ci	  found = 1;
203141cc406Sopenharmony_ci	}
204141cc406Sopenharmony_ci    }
205141cc406Sopenharmony_ci  if (device_number != expected || !found)
206141cc406Sopenharmony_ci    {
207141cc406Sopenharmony_ci      printf ("ERROR: mock device not stored !\n");
208141cc406Sopenharmony_ci      return 0;
209141cc406Sopenharmony_ci    }
210141cc406Sopenharmony_ci
211141cc406Sopenharmony_ci  /* scan devices should mark it as missing, and device_number should decrease */
212141cc406Sopenharmony_ci  sanei_usb_scan_devices ();
213141cc406Sopenharmony_ci  found = 0;
214141cc406Sopenharmony_ci  for (i = 0; i < MAX_DEVICES && !found; i++)
215141cc406Sopenharmony_ci    {
216141cc406Sopenharmony_ci      if (devices[i].devname
217141cc406Sopenharmony_ci	  && devices[i].missing == 1
218141cc406Sopenharmony_ci	  && !strcmp (devices[i].devname, mock.devname))
219141cc406Sopenharmony_ci	{
220141cc406Sopenharmony_ci	  found = 1;
221141cc406Sopenharmony_ci	}
222141cc406Sopenharmony_ci    }
223141cc406Sopenharmony_ci  if (device_number != expected || !found)
224141cc406Sopenharmony_ci    {
225141cc406Sopenharmony_ci      printf ("ERROR: mock device still present !\n");
226141cc406Sopenharmony_ci      return 0;
227141cc406Sopenharmony_ci    }
228141cc406Sopenharmony_ci
229141cc406Sopenharmony_ci  /* second scan devices should mark missing to 2 */
230141cc406Sopenharmony_ci  sanei_usb_scan_devices ();
231141cc406Sopenharmony_ci  found = 0;
232141cc406Sopenharmony_ci  for (i = 0; i < MAX_DEVICES && !found; i++)
233141cc406Sopenharmony_ci    {
234141cc406Sopenharmony_ci      if (devices[i].devname
235141cc406Sopenharmony_ci	  && devices[i].missing == 2
236141cc406Sopenharmony_ci	  && !strcmp (devices[i].devname, mock.devname))
237141cc406Sopenharmony_ci	{
238141cc406Sopenharmony_ci	  found = 1;
239141cc406Sopenharmony_ci	}
240141cc406Sopenharmony_ci    }
241141cc406Sopenharmony_ci  if (device_number != expected || !found)
242141cc406Sopenharmony_ci    {
243141cc406Sopenharmony_ci      printf ("ERROR: mock device slot not reusable !\n");
244141cc406Sopenharmony_ci      return 0;
245141cc406Sopenharmony_ci    }
246141cc406Sopenharmony_ci
247141cc406Sopenharmony_ci  /* store mock device again, slot in devices should be reused
248141cc406Sopenharmony_ci   * and device_number shouldn't change */
249141cc406Sopenharmony_ci  create_mock_device ("mock2", &mock);
250141cc406Sopenharmony_ci  store_device (mock);
251141cc406Sopenharmony_ci  found = 0;
252141cc406Sopenharmony_ci  for (i = 0; i < MAX_DEVICES && !found; i++)
253141cc406Sopenharmony_ci    {
254141cc406Sopenharmony_ci      if (devices[i].devname && !strcmp (devices[i].devname, mock.devname))
255141cc406Sopenharmony_ci	{
256141cc406Sopenharmony_ci	  found = 1;
257141cc406Sopenharmony_ci	}
258141cc406Sopenharmony_ci    }
259141cc406Sopenharmony_ci  if (device_number != expected || !found)
260141cc406Sopenharmony_ci    {
261141cc406Sopenharmony_ci      printf ("ERROR: mock device not stored !\n");
262141cc406Sopenharmony_ci      return 0;
263141cc406Sopenharmony_ci    }
264141cc406Sopenharmony_ci
265141cc406Sopenharmony_ci  /* last rescan to wipe mock device out */
266141cc406Sopenharmony_ci  sanei_usb_scan_devices ();
267141cc406Sopenharmony_ci
268141cc406Sopenharmony_ci  return 1;
269141cc406Sopenharmony_ci}
270141cc406Sopenharmony_ci
271141cc406Sopenharmony_ci/** return count of opened devices
272141cc406Sopenharmony_ci * @return count of opened devices
273141cc406Sopenharmony_ci */
274141cc406Sopenharmony_cistatic int
275141cc406Sopenharmony_ciget_opened (void)
276141cc406Sopenharmony_ci{
277141cc406Sopenharmony_ci  int num = 0;
278141cc406Sopenharmony_ci  int i;
279141cc406Sopenharmony_ci
280141cc406Sopenharmony_ci  for (i = 0; i < device_number; i++)
281141cc406Sopenharmony_ci    {
282141cc406Sopenharmony_ci      if (devices[i].missing == 0 && devices[i].devname != NULL
283141cc406Sopenharmony_ci	  && devices[i].open == SANE_TRUE)
284141cc406Sopenharmony_ci	{
285141cc406Sopenharmony_ci	  num++;
286141cc406Sopenharmony_ci	}
287141cc406Sopenharmony_ci    }
288141cc406Sopenharmony_ci  return num;
289141cc406Sopenharmony_ci}
290141cc406Sopenharmony_ci
291141cc406Sopenharmony_ci/** count opened devices
292141cc406Sopenharmony_ci * count all opended devices and check it against expected value
293141cc406Sopenharmony_ci * @param expected use opened count
294141cc406Sopenharmony_ci * @return 1 on success, else 0
295141cc406Sopenharmony_ci */
296141cc406Sopenharmony_cistatic int
297141cc406Sopenharmony_cicount_opened (int expected)
298141cc406Sopenharmony_ci{
299141cc406Sopenharmony_ci  int num = get_opened();
300141cc406Sopenharmony_ci
301141cc406Sopenharmony_ci  if (num != expected)
302141cc406Sopenharmony_ci    {
303141cc406Sopenharmony_ci      printf ("ERROR: %d opened devices, expected %d!\n", num, expected);
304141cc406Sopenharmony_ci      return 0;
305141cc406Sopenharmony_ci    }
306141cc406Sopenharmony_ci  printf ("%d devices still opened.\n", num);
307141cc406Sopenharmony_ci  return 1;
308141cc406Sopenharmony_ci}
309141cc406Sopenharmony_ci
310141cc406Sopenharmony_ci/** open all devices
311141cc406Sopenharmony_ci * loop on all existing devices and open them
312141cc406Sopenharmony_ci * @param dn array to store opened device number
313141cc406Sopenharmony_ci * @param expected number of devices to be opened
314141cc406Sopenharmony_ci * @return 1 on success, else 0
315141cc406Sopenharmony_ci */
316141cc406Sopenharmony_cistatic int
317141cc406Sopenharmony_citest_open_all (SANE_Int * dn, int expected)
318141cc406Sopenharmony_ci{
319141cc406Sopenharmony_ci  int opened = 0;
320141cc406Sopenharmony_ci  int i;
321141cc406Sopenharmony_ci  int last;
322141cc406Sopenharmony_ci  SANE_Status status;
323141cc406Sopenharmony_ci
324141cc406Sopenharmony_ci  /* loop on detected devices and open them */
325141cc406Sopenharmony_ci  last = -1;
326141cc406Sopenharmony_ci  for (i = 0; i < device_number; i++)
327141cc406Sopenharmony_ci    {
328141cc406Sopenharmony_ci      if (devices[i].missing == 0 && devices[i].devname != NULL)
329141cc406Sopenharmony_ci	{
330141cc406Sopenharmony_ci	  /* open device */
331141cc406Sopenharmony_ci	  status = sanei_usb_open (devices[i].devname, dn + opened);
332141cc406Sopenharmony_ci	  if (status == SANE_STATUS_GOOD)
333141cc406Sopenharmony_ci	    {
334141cc406Sopenharmony_ci	      opened++;
335141cc406Sopenharmony_ci	      last = i;
336141cc406Sopenharmony_ci	    }
337141cc406Sopenharmony_ci	  else
338141cc406Sopenharmony_ci	    {
339141cc406Sopenharmony_ci              if (status == SANE_STATUS_ACCESS_DENIED ||
340141cc406Sopenharmony_ci                  status == SANE_STATUS_DEVICE_BUSY)
341141cc406Sopenharmony_ci                {
342141cc406Sopenharmony_ci                  expected--;
343141cc406Sopenharmony_ci                }
344141cc406Sopenharmony_ci              else
345141cc406Sopenharmony_ci                {
346141cc406Sopenharmony_ci	          printf ("ERROR: couldn't open device %s!\n",
347141cc406Sopenharmony_ci                          devices[i].devname);
348141cc406Sopenharmony_ci	          return 0;
349141cc406Sopenharmony_ci                }
350141cc406Sopenharmony_ci	    }
351141cc406Sopenharmony_ci	}
352141cc406Sopenharmony_ci    }
353141cc406Sopenharmony_ci  printf ("opened %d devices\n", opened);
354141cc406Sopenharmony_ci
355141cc406Sopenharmony_ci  /* try to reopen an opened device when there is one */
356141cc406Sopenharmony_ci  if (last >= 0)
357141cc406Sopenharmony_ci    {
358141cc406Sopenharmony_ci      status = sanei_usb_open (devices[last].devname, dn + opened);
359141cc406Sopenharmony_ci      if (status == SANE_STATUS_GOOD)
360141cc406Sopenharmony_ci	{
361141cc406Sopenharmony_ci	  printf ("ERROR: unexpected success when opening %s twice!\n",
362141cc406Sopenharmony_ci		  devices[last].devname);
363141cc406Sopenharmony_ci	  return 0;
364141cc406Sopenharmony_ci	}
365141cc406Sopenharmony_ci    }
366141cc406Sopenharmony_ci
367141cc406Sopenharmony_ci  /* there should be as many opened devices than detected devices */
368141cc406Sopenharmony_ci  return count_opened (expected);
369141cc406Sopenharmony_ci}
370141cc406Sopenharmony_ci
371141cc406Sopenharmony_ci/** test opening invalid device
372141cc406Sopenharmony_ci * try to open an non existing device
373141cc406Sopenharmony_ci * @return 1 on success, else 0
374141cc406Sopenharmony_ci */
375141cc406Sopenharmony_cistatic int
376141cc406Sopenharmony_citest_open_invalid (void)
377141cc406Sopenharmony_ci{
378141cc406Sopenharmony_ci  SANE_Status status;
379141cc406Sopenharmony_ci  SANE_Int dn;
380141cc406Sopenharmony_ci
381141cc406Sopenharmony_ci  status = sanei_usb_open ("invalid device", &dn);
382141cc406Sopenharmony_ci  if (status == SANE_STATUS_GOOD)
383141cc406Sopenharmony_ci    {
384141cc406Sopenharmony_ci      printf ("ERROR: unexpected success opening invalid device!\n");
385141cc406Sopenharmony_ci      return 0;
386141cc406Sopenharmony_ci    }
387141cc406Sopenharmony_ci  return 1;
388141cc406Sopenharmony_ci}
389141cc406Sopenharmony_ci
390141cc406Sopenharmony_ci/** close all devices
391141cc406Sopenharmony_ci * loop on all opened devices and close them
392141cc406Sopenharmony_ci * @param dn array of opened device number
393141cc406Sopenharmony_ci * @param expected number of devices to be closed
394141cc406Sopenharmony_ci * @return 1 on success, else 0
395141cc406Sopenharmony_ci */
396141cc406Sopenharmony_cistatic int
397141cc406Sopenharmony_citest_close_all (SANE_Int * dn, int expected)
398141cc406Sopenharmony_ci{
399141cc406Sopenharmony_ci  int closed = 0;
400141cc406Sopenharmony_ci  int i;
401141cc406Sopenharmony_ci
402141cc406Sopenharmony_ci  /* loop on detected devices and open them */
403141cc406Sopenharmony_ci  for (i = 0; i < expected; i++)
404141cc406Sopenharmony_ci    {
405141cc406Sopenharmony_ci      /* close device */
406141cc406Sopenharmony_ci      sanei_usb_close (dn[i]);
407141cc406Sopenharmony_ci      closed++;
408141cc406Sopenharmony_ci    }
409141cc406Sopenharmony_ci  printf ("closed %d devices\n", closed);
410141cc406Sopenharmony_ci
411141cc406Sopenharmony_ci  /* there should be any more opened devices */
412141cc406Sopenharmony_ci  return count_opened (0);
413141cc406Sopenharmony_ci}
414141cc406Sopenharmony_ci
415141cc406Sopenharmony_ci
416141cc406Sopenharmony_ci/** claim all open devices
417141cc406Sopenharmony_ci * loop on all opened devices and claim interface 0
418141cc406Sopenharmony_ci * @param dn array of opened device number
419141cc406Sopenharmony_ci * @param expected number of devices to be claimed
420141cc406Sopenharmony_ci * @return 1 on success, else 0
421141cc406Sopenharmony_ci */
422141cc406Sopenharmony_cistatic int
423141cc406Sopenharmony_citest_claim_all (SANE_Int * dn, int expected)
424141cc406Sopenharmony_ci{
425141cc406Sopenharmony_ci  int claimed = 0;
426141cc406Sopenharmony_ci  int i;
427141cc406Sopenharmony_ci  SANE_Status status;
428141cc406Sopenharmony_ci  device_list_type mock;
429141cc406Sopenharmony_ci
430141cc406Sopenharmony_ci  claimed = 0;
431141cc406Sopenharmony_ci  for (i = 0; i < expected; i++)
432141cc406Sopenharmony_ci    {
433141cc406Sopenharmony_ci      status = sanei_usb_claim_interface (dn[i], devices[dn[i]].interface_nr);
434141cc406Sopenharmony_ci      if (status != SANE_STATUS_GOOD)
435141cc406Sopenharmony_ci	{
436141cc406Sopenharmony_ci	  printf ("ERROR: couldn't claim interface 0 on device %d!\n", dn[i]);
437141cc406Sopenharmony_ci	}
438141cc406Sopenharmony_ci      else
439141cc406Sopenharmony_ci	{
440141cc406Sopenharmony_ci	  claimed++;
441141cc406Sopenharmony_ci	}
442141cc406Sopenharmony_ci    }
443141cc406Sopenharmony_ci  if (claimed != expected)
444141cc406Sopenharmony_ci    {
445141cc406Sopenharmony_ci      printf ("ERROR: expected %d claimed interfaces, got %d!\n", expected,
446141cc406Sopenharmony_ci	      claimed);
447141cc406Sopenharmony_ci      return 0;
448141cc406Sopenharmony_ci    }
449141cc406Sopenharmony_ci  printf ("%d devices claimed...\n\n", claimed);
450141cc406Sopenharmony_ci
451141cc406Sopenharmony_ci  /* try to claim invalid device entry */
452141cc406Sopenharmony_ci  status = sanei_usb_claim_interface (device_number, 0);
453141cc406Sopenharmony_ci  if (status == SANE_STATUS_GOOD)
454141cc406Sopenharmony_ci    {
455141cc406Sopenharmony_ci      printf ("ERROR: could claim interface 0 on invalid device!\n");
456141cc406Sopenharmony_ci      return 0;
457141cc406Sopenharmony_ci    }
458141cc406Sopenharmony_ci
459141cc406Sopenharmony_ci  /* create a mock device and make it missing by rescanning */
460141cc406Sopenharmony_ci  create_mock_device ("mock", &mock);
461141cc406Sopenharmony_ci  store_device (mock);
462141cc406Sopenharmony_ci  sanei_usb_scan_devices ();
463141cc406Sopenharmony_ci
464141cc406Sopenharmony_ci  /* try to claim interface on missing device */
465141cc406Sopenharmony_ci  status = sanei_usb_claim_interface (device_number - 1, 0);
466141cc406Sopenharmony_ci  if (status == SANE_STATUS_GOOD)
467141cc406Sopenharmony_ci    {
468141cc406Sopenharmony_ci      printf ("ERROR: could claim interface 0 on invalid device!\n");
469141cc406Sopenharmony_ci      return 0;
470141cc406Sopenharmony_ci    }
471141cc406Sopenharmony_ci
472141cc406Sopenharmony_ci  /* remove mock device */
473141cc406Sopenharmony_ci  device_number--;
474141cc406Sopenharmony_ci  free (devices[device_number].devname);
475141cc406Sopenharmony_ci  devices[device_number].devname = NULL;
476141cc406Sopenharmony_ci
477141cc406Sopenharmony_ci  return 1;
478141cc406Sopenharmony_ci}
479141cc406Sopenharmony_ci
480141cc406Sopenharmony_ci
481141cc406Sopenharmony_ci/** release all claimed devices
482141cc406Sopenharmony_ci * loop on all opened devices and claim interface 0
483141cc406Sopenharmony_ci * @param dn array of opened device number
484141cc406Sopenharmony_ci * @param expected number of devices to be claimed
485141cc406Sopenharmony_ci * @return 1 on success, else 0
486141cc406Sopenharmony_ci */
487141cc406Sopenharmony_cistatic int
488141cc406Sopenharmony_citest_release_all (SANE_Int * dn, int expected)
489141cc406Sopenharmony_ci{
490141cc406Sopenharmony_ci  int released = 0;
491141cc406Sopenharmony_ci  int i;
492141cc406Sopenharmony_ci  SANE_Status status;
493141cc406Sopenharmony_ci  device_list_type mock;
494141cc406Sopenharmony_ci
495141cc406Sopenharmony_ci  released = 0;
496141cc406Sopenharmony_ci  for (i = 0; i < expected; i++)
497141cc406Sopenharmony_ci    {
498141cc406Sopenharmony_ci      status =
499141cc406Sopenharmony_ci	sanei_usb_release_interface (dn[i], devices[dn[i]].interface_nr);
500141cc406Sopenharmony_ci      if (status != SANE_STATUS_GOOD)
501141cc406Sopenharmony_ci	{
502141cc406Sopenharmony_ci	  printf ("ERROR: couldn't release interface 0 on device %d!\n",
503141cc406Sopenharmony_ci		  dn[i]);
504141cc406Sopenharmony_ci	}
505141cc406Sopenharmony_ci      else
506141cc406Sopenharmony_ci	{
507141cc406Sopenharmony_ci	  released++;
508141cc406Sopenharmony_ci	}
509141cc406Sopenharmony_ci    }
510141cc406Sopenharmony_ci  if (released != expected)
511141cc406Sopenharmony_ci    {
512141cc406Sopenharmony_ci      printf ("ERROR: expected %d released interfaces, got %d!\n", expected,
513141cc406Sopenharmony_ci	      released);
514141cc406Sopenharmony_ci      return 0;
515141cc406Sopenharmony_ci    }
516141cc406Sopenharmony_ci  printf ("%d devices released...\n\n", released);
517141cc406Sopenharmony_ci
518141cc406Sopenharmony_ci  /* try to release invalid device entry */
519141cc406Sopenharmony_ci  status = sanei_usb_release_interface (device_number, 0);
520141cc406Sopenharmony_ci  if (status == SANE_STATUS_GOOD)
521141cc406Sopenharmony_ci    {
522141cc406Sopenharmony_ci      printf ("ERROR: could release interface 0 on invalid device!\n");
523141cc406Sopenharmony_ci      return 0;
524141cc406Sopenharmony_ci    }
525141cc406Sopenharmony_ci
526141cc406Sopenharmony_ci  /* create a mock device and make it missing by rescanning */
527141cc406Sopenharmony_ci  create_mock_device ("mock", &mock);
528141cc406Sopenharmony_ci  store_device (mock);
529141cc406Sopenharmony_ci  sanei_usb_scan_devices ();
530141cc406Sopenharmony_ci
531141cc406Sopenharmony_ci  /* try to claim interface on missing device */
532141cc406Sopenharmony_ci  status = sanei_usb_release_interface (device_number - 1, 0);
533141cc406Sopenharmony_ci  if (status == SANE_STATUS_GOOD)
534141cc406Sopenharmony_ci    {
535141cc406Sopenharmony_ci      printf ("ERROR: could release interface 0 on invalid device!\n");
536141cc406Sopenharmony_ci      return 0;
537141cc406Sopenharmony_ci    }
538141cc406Sopenharmony_ci
539141cc406Sopenharmony_ci  /* remove mock device */
540141cc406Sopenharmony_ci  device_number--;
541141cc406Sopenharmony_ci  free (devices[device_number].devname);
542141cc406Sopenharmony_ci  devices[device_number].devname = NULL;
543141cc406Sopenharmony_ci
544141cc406Sopenharmony_ci  return 1;
545141cc406Sopenharmony_ci}
546141cc406Sopenharmony_ci
547141cc406Sopenharmony_ci/** get id for all devices names
548141cc406Sopenharmony_ci * loop on all existing devices and get vendor
549141cc406Sopenharmony_ci * and product id by name.
550141cc406Sopenharmony_ci * @param expected count
551141cc406Sopenharmony_ci * @return 1 on success, else 0
552141cc406Sopenharmony_ci */
553141cc406Sopenharmony_cistatic int
554141cc406Sopenharmony_citest_vendor_by_devname (void)
555141cc406Sopenharmony_ci{
556141cc406Sopenharmony_ci  int i;
557141cc406Sopenharmony_ci  SANE_Status status;
558141cc406Sopenharmony_ci  SANE_Word vendor, product;
559141cc406Sopenharmony_ci  device_list_type mock;
560141cc406Sopenharmony_ci
561141cc406Sopenharmony_ci  /* loop on detected devices and open them */
562141cc406Sopenharmony_ci  for (i = 0; i < device_number; i++)
563141cc406Sopenharmony_ci    {
564141cc406Sopenharmony_ci      if (devices[i].missing == 0 && devices[i].devname != NULL)
565141cc406Sopenharmony_ci	{
566141cc406Sopenharmony_ci	  /* get device id */
567141cc406Sopenharmony_ci	  status = sanei_usb_get_vendor_product_byname (devices[i].devname,
568141cc406Sopenharmony_ci							&vendor, &product);
569141cc406Sopenharmony_ci	  if (status != SANE_STATUS_GOOD)
570141cc406Sopenharmony_ci	    {
571141cc406Sopenharmony_ci	      printf ("ERROR: couldn't query device %s!\n",
572141cc406Sopenharmony_ci		      devices[i].devname);
573141cc406Sopenharmony_ci	      return 0;
574141cc406Sopenharmony_ci	    }
575141cc406Sopenharmony_ci	  if (vendor == 0 || product == 0)
576141cc406Sopenharmony_ci	    {
577141cc406Sopenharmony_ci	      printf ("ERROR: incomplete device id for %s!\n",
578141cc406Sopenharmony_ci		      devices[i].devname);
579141cc406Sopenharmony_ci	      return 0;
580141cc406Sopenharmony_ci	    }
581141cc406Sopenharmony_ci	  printf ("%s is %04x:%04x\n", devices[i].devname, vendor, product);
582141cc406Sopenharmony_ci	}
583141cc406Sopenharmony_ci    }
584141cc406Sopenharmony_ci
585141cc406Sopenharmony_ci  /* add mock device */
586141cc406Sopenharmony_ci  create_mock_device ("mock", &mock);
587141cc406Sopenharmony_ci  store_device (mock);
588141cc406Sopenharmony_ci  status = sanei_usb_get_vendor_product_byname ("mock", &vendor, &product);
589141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
590141cc406Sopenharmony_ci    {
591141cc406Sopenharmony_ci      printf ("ERROR: getting vendor for mock devname!\n");
592141cc406Sopenharmony_ci      return 0;
593141cc406Sopenharmony_ci    }
594141cc406Sopenharmony_ci  if (vendor != mock.vendor || product != mock.product)
595141cc406Sopenharmony_ci    {
596141cc406Sopenharmony_ci      printf ("ERROR: wrong vendor/product for mock devname!\n");
597141cc406Sopenharmony_ci      return 0;
598141cc406Sopenharmony_ci    }
599141cc406Sopenharmony_ci  /* remove mock device */
600141cc406Sopenharmony_ci  device_number--;
601141cc406Sopenharmony_ci  free (devices[device_number].devname);
602141cc406Sopenharmony_ci  devices[device_number].devname = NULL;
603141cc406Sopenharmony_ci
604141cc406Sopenharmony_ci  /* try go get id for an invalid devname */
605141cc406Sopenharmony_ci  status = sanei_usb_get_vendor_product_byname ("invalid devname",
606141cc406Sopenharmony_ci						&vendor, &product);
607141cc406Sopenharmony_ci  if (status == SANE_STATUS_GOOD)
608141cc406Sopenharmony_ci    {
609141cc406Sopenharmony_ci      printf ("ERROR: unexpected success getting id for invalid devname!\n");
610141cc406Sopenharmony_ci      return 0;
611141cc406Sopenharmony_ci    }
612141cc406Sopenharmony_ci
613141cc406Sopenharmony_ci  printf ("\n");
614141cc406Sopenharmony_ci  return 1;
615141cc406Sopenharmony_ci}
616141cc406Sopenharmony_ci
617141cc406Sopenharmony_ci/** get vendor for all devices id
618141cc406Sopenharmony_ci * loop on all existing devices and get vendor
619141cc406Sopenharmony_ci * and product id.
620141cc406Sopenharmony_ci * @param expected count
621141cc406Sopenharmony_ci * @return 1 on success, else 0
622141cc406Sopenharmony_ci */
623141cc406Sopenharmony_cistatic int
624141cc406Sopenharmony_citest_vendor_by_id (void)
625141cc406Sopenharmony_ci{
626141cc406Sopenharmony_ci  int i;
627141cc406Sopenharmony_ci  SANE_Status status;
628141cc406Sopenharmony_ci  SANE_Word vendor, product;
629141cc406Sopenharmony_ci  device_list_type mock;
630141cc406Sopenharmony_ci
631141cc406Sopenharmony_ci  /* loop on detected devices and open them */
632141cc406Sopenharmony_ci  for (i = 0; i < device_number; i++)
633141cc406Sopenharmony_ci    {
634141cc406Sopenharmony_ci      if (devices[i].missing == 0 && devices[i].devname != NULL)
635141cc406Sopenharmony_ci	{
636141cc406Sopenharmony_ci	  /* get device id */
637141cc406Sopenharmony_ci	  status = sanei_usb_get_vendor_product (i, &vendor, &product);
638141cc406Sopenharmony_ci	  if (status != SANE_STATUS_GOOD)
639141cc406Sopenharmony_ci	    {
640141cc406Sopenharmony_ci	      printf ("ERROR: couldn't query device %d!\n", i);
641141cc406Sopenharmony_ci	      return 0;
642141cc406Sopenharmony_ci	    }
643141cc406Sopenharmony_ci	  if (vendor == 0 || product == 0)
644141cc406Sopenharmony_ci	    {
645141cc406Sopenharmony_ci	      printf ("ERROR: incomplete device id for %d!\n", i);
646141cc406Sopenharmony_ci	      return 0;
647141cc406Sopenharmony_ci	    }
648141cc406Sopenharmony_ci	  printf ("%d is %04x:%04x\n", i, vendor, product);
649141cc406Sopenharmony_ci	}
650141cc406Sopenharmony_ci    }
651141cc406Sopenharmony_ci
652141cc406Sopenharmony_ci  /* add mock device */
653141cc406Sopenharmony_ci  create_mock_device ("mock", &mock);
654141cc406Sopenharmony_ci  store_device (mock);
655141cc406Sopenharmony_ci  status =
656141cc406Sopenharmony_ci    sanei_usb_get_vendor_product (device_number - 1, &vendor, &product);
657141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
658141cc406Sopenharmony_ci    {
659141cc406Sopenharmony_ci      printf ("ERROR: getting vendor for mock devname!\n");
660141cc406Sopenharmony_ci      return 0;
661141cc406Sopenharmony_ci    }
662141cc406Sopenharmony_ci  if (vendor != mock.vendor || product != mock.product)
663141cc406Sopenharmony_ci    {
664141cc406Sopenharmony_ci      printf ("ERROR: wrong vendor/product for mock devname!\n");
665141cc406Sopenharmony_ci      return 0;
666141cc406Sopenharmony_ci    }
667141cc406Sopenharmony_ci  /* remove mock device */
668141cc406Sopenharmony_ci  device_number--;
669141cc406Sopenharmony_ci  free (devices[device_number].devname);
670141cc406Sopenharmony_ci  devices[device_number].devname = NULL;
671141cc406Sopenharmony_ci
672141cc406Sopenharmony_ci  /* try go get id for an invalid id */
673141cc406Sopenharmony_ci  status =
674141cc406Sopenharmony_ci    sanei_usb_get_vendor_product (device_number + 1, &vendor, &product);
675141cc406Sopenharmony_ci  if (status == SANE_STATUS_GOOD)
676141cc406Sopenharmony_ci    {
677141cc406Sopenharmony_ci      printf
678141cc406Sopenharmony_ci	("ERROR: unexpected success getting vendor for invalid devname!\n");
679141cc406Sopenharmony_ci      return 0;
680141cc406Sopenharmony_ci    }
681141cc406Sopenharmony_ci
682141cc406Sopenharmony_ci  printf ("\n");
683141cc406Sopenharmony_ci  return 1;
684141cc406Sopenharmony_ci}
685141cc406Sopenharmony_ci
686141cc406Sopenharmony_ci/** test timeout functions : libusb only
687141cc406Sopenharmony_ci * @return 1 on success, else 0
688141cc406Sopenharmony_ci */
689141cc406Sopenharmony_cistatic int
690141cc406Sopenharmony_citest_timeout (void)
691141cc406Sopenharmony_ci{
692141cc406Sopenharmony_ci#if defined(HAVE_LIBUSB_LEGACY) || defined(HAVE_LIBUSB)
693141cc406Sopenharmony_ci  int timeout = libusb_timeout;
694141cc406Sopenharmony_ci
695141cc406Sopenharmony_ci  sanei_usb_set_timeout (5000);
696141cc406Sopenharmony_ci  if (libusb_timeout != 5000)
697141cc406Sopenharmony_ci    {
698141cc406Sopenharmony_ci      printf ("ERROR: failed to set timeout\n");
699141cc406Sopenharmony_ci      return 1;
700141cc406Sopenharmony_ci    }
701141cc406Sopenharmony_ci  sanei_usb_set_timeout (timeout);
702141cc406Sopenharmony_ci#endif
703141cc406Sopenharmony_ci  return 1;
704141cc406Sopenharmony_ci}
705141cc406Sopenharmony_ci
706141cc406Sopenharmony_ci/** test device scanning
707141cc406Sopenharmony_ci * call sanei_usb_scan_devices, since it has no return code, no real
708141cc406Sopenharmony_ci * assert can be done, but at least we can test it doesn't break
709141cc406Sopenharmony_ci * other functions or don't leak memory
710141cc406Sopenharmony_ci * @return always 1
711141cc406Sopenharmony_ci */
712141cc406Sopenharmony_cistatic int
713141cc406Sopenharmony_citest_scan_devices (int detected, int opened)
714141cc406Sopenharmony_ci{
715141cc406Sopenharmony_ci  int rc;
716141cc406Sopenharmony_ci
717141cc406Sopenharmony_ci  printf ("rescanning for devices ...\n");
718141cc406Sopenharmony_ci  sanei_usb_scan_devices ();
719141cc406Sopenharmony_ci  rc = count_detected (detected);
720141cc406Sopenharmony_ci  if (!rc)
721141cc406Sopenharmony_ci    {
722141cc406Sopenharmony_ci      printf ("ERROR: scanning devices change detected count!\n");
723141cc406Sopenharmony_ci      return 0;
724141cc406Sopenharmony_ci    }
725141cc406Sopenharmony_ci  rc = count_opened (opened);
726141cc406Sopenharmony_ci  if (!rc)
727141cc406Sopenharmony_ci    {
728141cc406Sopenharmony_ci      printf ("ERROR: scanning devices change opened count!\n");
729141cc406Sopenharmony_ci      return 0;
730141cc406Sopenharmony_ci    }
731141cc406Sopenharmony_ci  printf ("\n");
732141cc406Sopenharmony_ci  return 1;
733141cc406Sopenharmony_ci}
734141cc406Sopenharmony_ci
735141cc406Sopenharmony_ci
736141cc406Sopenharmony_ci/**
737141cc406Sopenharmony_ci * flag for dummy attach
738141cc406Sopenharmony_ci */
739141cc406Sopenharmony_cistatic int dummy_flag;
740141cc406Sopenharmony_ci
741141cc406Sopenharmony_ci/**
742141cc406Sopenharmony_ci * expected device name during attach
743141cc406Sopenharmony_ci */
744141cc406Sopenharmony_cistatic char *expected_device;
745141cc406Sopenharmony_ci
746141cc406Sopenharmony_ci/** dummy attach function
747141cc406Sopenharmony_ci * dummy attach function
748141cc406Sopenharmony_ci * @return return SANE_STATUS_GOOD
749141cc406Sopenharmony_ci */
750141cc406Sopenharmony_cistatic SANE_Status
751141cc406Sopenharmony_cidummy_attach (const char *dev)
752141cc406Sopenharmony_ci{
753141cc406Sopenharmony_ci  dummy_flag = (strcmp (expected_device, dev) == 0);
754141cc406Sopenharmony_ci  if (dummy_flag)
755141cc406Sopenharmony_ci    {
756141cc406Sopenharmony_ci      printf ("success attaching to %s...\n", dev);
757141cc406Sopenharmony_ci    }
758141cc406Sopenharmony_ci  else
759141cc406Sopenharmony_ci    {
760141cc406Sopenharmony_ci      printf ("failed attaching to %s...\n", dev);
761141cc406Sopenharmony_ci    }
762141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
763141cc406Sopenharmony_ci}
764141cc406Sopenharmony_ci
765141cc406Sopenharmony_ci/** test attaching usb device
766141cc406Sopenharmony_ci * create a mock device and attach to it, checking
767141cc406Sopenharmony_ci * if it is ok
768141cc406Sopenharmony_ci * @return 1 on success, else 0
769141cc406Sopenharmony_ci */
770141cc406Sopenharmony_cistatic int
771141cc406Sopenharmony_citest_attach (void)
772141cc406Sopenharmony_ci{
773141cc406Sopenharmony_ci  device_list_type mock;
774141cc406Sopenharmony_ci
775141cc406Sopenharmony_ci  /* add mock device and try to attach to it */
776141cc406Sopenharmony_ci  dummy_flag = 0;
777141cc406Sopenharmony_ci  create_mock_device ("mock", &mock);
778141cc406Sopenharmony_ci  expected_device = mock.devname;
779141cc406Sopenharmony_ci  store_device (mock);
780141cc406Sopenharmony_ci  sanei_usb_attach_matching_devices ("usb 0xdead 0xbeef", dummy_attach);
781141cc406Sopenharmony_ci
782141cc406Sopenharmony_ci  /* flag must be set */
783141cc406Sopenharmony_ci  if (dummy_flag != 1)
784141cc406Sopenharmony_ci    {
785141cc406Sopenharmony_ci      printf ("ERROR: couldn't attach to 'usb xdead 0xbeef' device!\n");
786141cc406Sopenharmony_ci      return 0;
787141cc406Sopenharmony_ci    }
788141cc406Sopenharmony_ci
789141cc406Sopenharmony_ci  /* attach by devname */
790141cc406Sopenharmony_ci  dummy_flag = 0;
791141cc406Sopenharmony_ci  sanei_usb_attach_matching_devices (mock.devname, dummy_attach);
792141cc406Sopenharmony_ci  /* flag must be set */
793141cc406Sopenharmony_ci  if (dummy_flag != 1)
794141cc406Sopenharmony_ci    {
795141cc406Sopenharmony_ci      printf ("ERROR: couldn't attach to 'mock' device!\n");
796141cc406Sopenharmony_ci      return 0;
797141cc406Sopenharmony_ci    }
798141cc406Sopenharmony_ci
799141cc406Sopenharmony_ci  /* attach to bogus device */
800141cc406Sopenharmony_ci  dummy_flag = 0;
801141cc406Sopenharmony_ci  sanei_usb_attach_matching_devices ("usb 0x0001 0x0001", dummy_attach);
802141cc406Sopenharmony_ci
803141cc406Sopenharmony_ci  /* flag must not be set */
804141cc406Sopenharmony_ci  if (dummy_flag != 0)
805141cc406Sopenharmony_ci    {
806141cc406Sopenharmony_ci      printf ("ERROR: shouldn't be attached to bogus device!\n");
807141cc406Sopenharmony_ci      return 0;
808141cc406Sopenharmony_ci    }
809141cc406Sopenharmony_ci
810141cc406Sopenharmony_ci  /* attach by bogus devname */
811141cc406Sopenharmony_ci  sanei_usb_attach_matching_devices ("bogus", dummy_attach);
812141cc406Sopenharmony_ci
813141cc406Sopenharmony_ci  /* flag must not be set */
814141cc406Sopenharmony_ci  if (dummy_flag != 0)
815141cc406Sopenharmony_ci    {
816141cc406Sopenharmony_ci      printf ("ERROR: shouldn't be attached to bogus device!\n");
817141cc406Sopenharmony_ci      return 0;
818141cc406Sopenharmony_ci    }
819141cc406Sopenharmony_ci
820141cc406Sopenharmony_ci  /* remove mock device */
821141cc406Sopenharmony_ci  device_number--;
822141cc406Sopenharmony_ci  free (devices[device_number].devname);
823141cc406Sopenharmony_ci  devices[device_number].devname = NULL;
824141cc406Sopenharmony_ci  dummy_flag = 0;
825141cc406Sopenharmony_ci
826141cc406Sopenharmony_ci  return 1;
827141cc406Sopenharmony_ci}
828141cc406Sopenharmony_ci
829141cc406Sopenharmony_ciint
830141cc406Sopenharmony_cimain (int __sane_unused__ argc, char **argv)
831141cc406Sopenharmony_ci{
832141cc406Sopenharmony_ci  int detected, opened, i;
833141cc406Sopenharmony_ci  SANE_Int dn[MAX_DEVICES];
834141cc406Sopenharmony_ci
835141cc406Sopenharmony_ci#ifdef HAVE_LIBUSB_LEGACY
836141cc406Sopenharmony_ci  printf ("\n%s built with old libusb\n\n", argv[0]);
837141cc406Sopenharmony_ci#endif
838141cc406Sopenharmony_ci#ifdef HAVE_LIBUSB
839141cc406Sopenharmony_ci  printf ("\n%s built with libusb-1.0\n\n", argv[0]);
840141cc406Sopenharmony_ci#endif
841141cc406Sopenharmony_ci#ifdef HAVE_USBCALLS
842141cc406Sopenharmony_ci  printf ("\n%s built with usbcalls\n\n", argv[0]);
843141cc406Sopenharmony_ci#endif
844141cc406Sopenharmony_ci#if !defined(HAVE_LIBUSB_LEGACY) && !defined(HAVE_LIBUSB) && !defined(HAVE_USBCALLS)
845141cc406Sopenharmony_ci  printf ("\n%s relying on deprecated scanner kernel module\n", argv[0]);
846141cc406Sopenharmony_ci#endif
847141cc406Sopenharmony_ci
848141cc406Sopenharmony_ci  /* start sanei_usb */
849141cc406Sopenharmony_ci  assert (test_init (1));
850141cc406Sopenharmony_ci
851141cc406Sopenharmony_ci  /* test timeout function */
852141cc406Sopenharmony_ci  assert (test_timeout ());
853141cc406Sopenharmony_ci
854141cc406Sopenharmony_ci  /* count available devices */
855141cc406Sopenharmony_ci  detected = 0;
856141cc406Sopenharmony_ci  for (i = 0; i < device_number; i++)
857141cc406Sopenharmony_ci    {
858141cc406Sopenharmony_ci      if (devices[i].missing == 0 && devices[i].devname != NULL)
859141cc406Sopenharmony_ci	{
860141cc406Sopenharmony_ci	  detected++;
861141cc406Sopenharmony_ci	}
862141cc406Sopenharmony_ci    }
863141cc406Sopenharmony_ci  printf ("%d devices found.\n", detected);
864141cc406Sopenharmony_ci
865141cc406Sopenharmony_ci  /* rescan devices : detected count shouldn't change */
866141cc406Sopenharmony_ci  assert (test_scan_devices (detected, 0));
867141cc406Sopenharmony_ci
868141cc406Sopenharmony_ci  /* test corner cases with mock device */
869141cc406Sopenharmony_ci  assert (test_store_device ());
870141cc406Sopenharmony_ci
871141cc406Sopenharmony_ci  /* get vendor/product id for all available devices devname */
872141cc406Sopenharmony_ci  assert (test_vendor_by_devname ());
873141cc406Sopenharmony_ci
874141cc406Sopenharmony_ci  /* get vendor/product id for all available devices id */
875141cc406Sopenharmony_ci  assert (test_vendor_by_id ());
876141cc406Sopenharmony_ci
877141cc406Sopenharmony_ci  /* open all available devices */
878141cc406Sopenharmony_ci  assert (test_open_all (dn, detected));
879141cc406Sopenharmony_ci
880141cc406Sopenharmony_ci  opened = get_opened();
881141cc406Sopenharmony_ci
882141cc406Sopenharmony_ci  /* rescan devices : detected and opened count shouldn't change */
883141cc406Sopenharmony_ci  assert (test_scan_devices (detected, opened));
884141cc406Sopenharmony_ci
885141cc406Sopenharmony_ci  /* try to open an inexisting device */
886141cc406Sopenharmony_ci  assert (test_open_invalid ());
887141cc406Sopenharmony_ci
888141cc406Sopenharmony_ci  /* increase sanei _sub use count */
889141cc406Sopenharmony_ci  assert (test_init (2));
890141cc406Sopenharmony_ci
891141cc406Sopenharmony_ci  /* there should be still as many detected devices */
892141cc406Sopenharmony_ci  assert (count_detected (detected));
893141cc406Sopenharmony_ci
894141cc406Sopenharmony_ci  /* there should be still as many opened devices */
895141cc406Sopenharmony_ci  assert (count_opened (opened));
896141cc406Sopenharmony_ci
897141cc406Sopenharmony_ci  assert (test_exit (1));
898141cc406Sopenharmony_ci
899141cc406Sopenharmony_ci  /* there should be still as many opened devices */
900141cc406Sopenharmony_ci  assert (count_opened (opened));
901141cc406Sopenharmony_ci
902141cc406Sopenharmony_ci  /* count devices again , sanei_usb_exit() shouldn't have
903141cc406Sopenharmony_ci   * change the count */
904141cc406Sopenharmony_ci  assert (count_detected (detected));
905141cc406Sopenharmony_ci
906141cc406Sopenharmony_ci  /* claim all available devices */
907141cc406Sopenharmony_ci  assert (test_claim_all (dn, opened));
908141cc406Sopenharmony_ci
909141cc406Sopenharmony_ci  /* then release them all */
910141cc406Sopenharmony_ci  assert (test_release_all (dn, opened));
911141cc406Sopenharmony_ci
912141cc406Sopenharmony_ci  /* close all opened devices */
913141cc406Sopenharmony_ci  assert (test_close_all (dn, opened));
914141cc406Sopenharmony_ci
915141cc406Sopenharmony_ci  /* check there is no opened device */
916141cc406Sopenharmony_ci  assert (count_opened (0));
917141cc406Sopenharmony_ci
918141cc406Sopenharmony_ci  /* finally free resources */
919141cc406Sopenharmony_ci  assert (test_exit (0));
920141cc406Sopenharmony_ci
921141cc406Sopenharmony_ci  /* check there is no more devices */
922141cc406Sopenharmony_ci  assert (count_detected (0));
923141cc406Sopenharmony_ci
924141cc406Sopenharmony_ci  /* test attach matching device with a mock */
925141cc406Sopenharmony_ci  assert (test_attach ());
926141cc406Sopenharmony_ci
927141cc406Sopenharmony_ci  /* try to call sanei_usb_exit() when it not initialized */
928141cc406Sopenharmony_ci  assert (test_exit (0));
929141cc406Sopenharmony_ci
930141cc406Sopenharmony_ci  /* scan devices when sanei usb is not initialized */
931141cc406Sopenharmony_ci  assert (test_scan_devices (0, 0));
932141cc406Sopenharmony_ci
933141cc406Sopenharmony_ci  /* we re start use of sanei usb so we check we have left it
934141cc406Sopenharmony_ci   * it he correct state after "closing" it. */
935141cc406Sopenharmony_ci  printf ("\n============================================================\n");
936141cc406Sopenharmony_ci  printf ("restart use of sanei usb after having freed all resources...\n\n");
937141cc406Sopenharmony_ci  assert (test_init (1));
938141cc406Sopenharmony_ci
939141cc406Sopenharmony_ci  /* we should have the same initial count of detected devices */
940141cc406Sopenharmony_ci  assert (count_detected (detected));
941141cc406Sopenharmony_ci
942141cc406Sopenharmony_ci  /* finally free resources */
943141cc406Sopenharmony_ci  assert (test_exit (0));
944141cc406Sopenharmony_ci
945141cc406Sopenharmony_ci  /* all the tests are OK ! */
946141cc406Sopenharmony_ci  return 0;
947141cc406Sopenharmony_ci}
948141cc406Sopenharmony_ci
949141cc406Sopenharmony_ci/* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */
950