/** test attaching usb device * create a mock device and attach to it, checking * if it is ok * @return 1 on success, else 0 */ static int test_attach (void) { device_list_type mock; /* add mock device and try ot attach to it */ dummy_flag = 0; create_mock_device ("mock", &mock); expected_device = mock.devname; store_device (mock); sanei_usb_attach_matching_devices ("usb 0xdead 0xbeef", dummy_attach); /* flag must be set */ if (dummy_flag != 1) { printf ("ERROR: couldn't attach to 'usb xdead 0xbeef' device!\n"); return 0; } /* attach by devname */ dummy_flag = 0; sanei_usb_attach_matching_devices (mock.devname, dummy_attach); /* flag must be set */ if (dummy_flag != 1) { printf ("ERROR: couldn't attach to 'mock' device!\n"); return 0; } /* attach to bogus device */ dummy_flag = 0; sanei_usb_attach_matching_devices ("usb 0x0001 0x0001", dummy_attach); /* flag must not be set */ if (dummy_flag != 0) { printf ("ERROR: shouldn't be attached to bogus device!\n"); return 0; } /* attach by bogus devname */ sanei_usb_attach_matching_devices ("bogus", dummy_attach); /* flag must not be set */ if (dummy_flag != 0) { printf ("ERROR: shouldn't be attached to bogus device!\n"); return 0; } /* remove mock device */ device_number--; free (devices[device_number].devname); devices[device_number].devname = NULL; dummy_flag = 0; return 1; }
/* SANE API ignores return code of this callback */ SANE_Status usb_configure_device (const char *devname, SANE_Status (*attach) (const char *dev)) { sanei_usb_set_timeout (1000); sanei_usb_attach_matching_devices (devname, attach); sanei_usb_set_timeout (30000); return SANE_STATUS_GOOD; }
/* Get all supported scanners, and store into g_devlist */ SANE_Status kv_usb_enum_devices (void) { int cnt = 0; int i; PKV_DEV pd; char usb_str[18]; DBG (DBG_proc, "kv_usb_enum_devices: enter\n"); sanei_usb_init(); sprintf(usb_str,"usb %#04x %#04x",VENDOR_ID,KV_S1020C); sanei_usb_attach_matching_devices(usb_str, attach_scanner_usb); sprintf(usb_str,"usb %#04x %#04x",VENDOR_ID,KV_S1025C); sanei_usb_attach_matching_devices(usb_str, attach_scanner_usb); sprintf(usb_str,"usb %#04x %#04x",VENDOR_ID,KV_S1045C); sanei_usb_attach_matching_devices(usb_str, attach_scanner_usb); for (pd = g_devices; pd; pd=pd->next) { cnt++; } g_devlist = (const SANE_Device **) malloc (sizeof (SANE_Device *) * (cnt + 1)); if (g_devlist == NULL) { DBG (DBG_proc, "kv_usb_enum_devices: leave on error " " --out of memory\n"); return SANE_STATUS_NO_MEM; } pd = g_devices; for (i = 0; i < cnt; i++) { g_devlist[i] = (const SANE_Device *) &pd->sane; pd = pd->next; } g_devlist[cnt] = 0; DBG (DBG_proc, "kv_usb_enum_devices: leave with %d devices.\n", cnt); return SANE_STATUS_GOOD; }
/* Find our devices */ SANE_Status sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) { char config_line[PATH_MAX]; size_t len; FILE *fp; DBG_INIT (); #if 0 DBG_LEVEL = 10; #endif DBG (2, "sane_init: version_code %s 0, authorize %s 0\n", version_code == 0 ? "=" : "!=", authorize == 0 ? "=" : "!="); DBG (1, "sane_init: SANE Canon630u backend version %d.%d.%d from %s\n", SANE_CURRENT_MAJOR, V_MINOR, BUILD, PACKAGE_STRING); if (version_code) *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, V_MINOR, BUILD); sanei_usb_init (); fp = sanei_config_open (CANONUSB_CONFIG_FILE); if (!fp) { /* no config-file: try these */ attach_scanner ("/dev/scanner", 0); attach_scanner ("/dev/usbscanner", 0); attach_scanner ("/dev/usb/scanner", 0); return SANE_STATUS_GOOD; } DBG (3, "reading configure file %s\n", CANONUSB_CONFIG_FILE); while (sanei_config_read (config_line, sizeof (config_line), fp)) { if (config_line[0] == '#') continue; /* ignore line comments */ len = strlen (config_line); if (!len) continue; /* ignore empty lines */ DBG (4, "attach_matching_devices(%s)\n", config_line); sanei_usb_attach_matching_devices (config_line, attach_one); } DBG (4, "finished reading configure file\n"); fclose (fp); return SANE_STATUS_GOOD; }
/* * Called by SANE to find out about supported devices. * * From the SANE spec: * This function can be used to query the list of devices that are * available. If the function executes successfully, it stores a * pointer to a NULL terminated array of pointers to SANE_Device * structures in *device_list. The returned list is guaranteed to * remain unchanged and valid until (a) another call to this function * is performed or (b) a call to sane_exit() is performed. This * function can be called repeatedly to detect when new devices become * available. If argument local_only is true, only local devices are * returned (devices directly attached to the machine that SANE is * running on). If it is false, the device list includes all remote * devices that are accessible to the SANE library. * * SANE does not require that this function is called before a * sane_open() call is performed. A device name may be specified * explicitly by a user which would make it unnecessary and * undesirable to call this function first. * * Read the config file, find scanners with help from sanei_* * store in global device structs */ SANE_Status sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only) { struct scanner *dev; char line[PATH_MAX]; const char *lp; FILE *fp; int num_devices=0; int i=0; local_only = local_only; /* get rid of compiler warning */ DBG (10, "sane_get_devices: start\n"); global_has_cal_buffer = 1; global_lines_per_block = 16; fp = sanei_config_open (CONFIG_FILE); if (fp) { DBG (15, "sane_get_devices: reading config file %s\n", CONFIG_FILE); while (sanei_config_read (line, PATH_MAX, fp)) { lp = line; /* ignore comments */ if (*lp == '#') continue; /* skip empty lines */ if (*lp == 0) continue; if ((strncmp ("usb", lp, 3) == 0) && isspace (lp[3])) { DBG (15, "sane_get_devices: looking for '%s'\n", lp); sanei_usb_attach_matching_devices(lp, attach_one); } else if (!strncmp(lp, "has_cal_buffer", 14) && isspace (lp[14])) { int buf; lp += 14; lp = sanei_config_skip_whitespace (lp); buf = atoi (lp); if(buf){ global_has_cal_buffer = 1; } else{ global_has_cal_buffer = 0; } DBG (15, "sane_get_devices: setting \"has_cal_buffer\" to %d\n", global_has_cal_buffer); } else if (!strncmp(lp, "lines_per_block", 15) && isspace (lp[15])) { int buf; lp += 15; lp = sanei_config_skip_whitespace (lp); buf = atoi (lp); if(buf < 1 || buf > 32){ DBG (15, "sane_get_devices: \"lines_per_block\"=%d\n out of range", buf ); continue; } DBG (15, "sane_get_devices: \"lines_per_block\" is %d\n", buf); global_lines_per_block = buf; } else{ DBG (5, "sane_get_devices: config line \"%s\" ignored.\n", lp); } } fclose (fp); } else { DBG (5, "sane_get_devices: no config file '%s', using defaults\n", CONFIG_FILE); DBG (15, "sane_get_devices: looking for 'usb 0x08F0 0x0005'\n"); sanei_usb_attach_matching_devices("usb 0x08F0 0x0005", attach_one); } for (dev = scanner_devList; dev; dev=dev->next) { DBG (15, "sane_get_devices: found scanner %s\n",dev->device_name); num_devices++; } DBG (15, "sane_get_devices: found %d scanner(s)\n",num_devices); sane_devArray = calloc (num_devices + 1, sizeof (SANE_Device*)); if (!sane_devArray) return SANE_STATUS_NO_MEM; for (dev = scanner_devList; dev; dev=dev->next) { sane_devArray[i++] = (SANE_Device *)&dev->sane; } sane_devArray[i] = 0; *device_list = sane_devArray; DBG (10, "sane_get_devices: finish\n"); return SANE_STATUS_GOOD; }
SANE_Status sane_init (SANE_Int * piVersion, SANE_Auth_Callback pfnAuth) { FILE *conf_fp; /* Config file stream */ SANE_Char line[PATH_MAX]; SANE_Char *str = NULL; SANE_String_Const proper_str; int nline = 0; /* prevent compiler from complaing about unused parameters */ pfnAuth = pfnAuth; strcpy(usb_devfile, "/dev/usb/scanner0"); _pFirstSaneDev = 0; iNumSaneDev = 0; InitHp5400_internal(); DBG_INIT (); HP5400_DBG (DBG_MSG, "sane_init: SANE hp5400 backend version %d.%d-%d (from %s)\n", SANE_CURRENT_MAJOR, V_MINOR, BUILD, PACKAGE_STRING); sanei_usb_init (); conf_fp = sanei_config_open (HP5400_CONFIG_FILE); iNumSaneDev = 0; if (conf_fp) { HP5400_DBG (DBG_MSG, "Reading config file\n"); while (sanei_config_read (line, sizeof (line), conf_fp)) { ++nline; if (str) { free (str); } proper_str = sanei_config_get_string (line, &str); /* Discards white lines and comments */ if (!str || proper_str == line || str[0] == '#') { HP5400_DBG (DBG_MSG, "Discarding line %d\n", nline); } else { /* If line's not blank or a comment, then it's the device * filename or a usb directive. */ HP5400_DBG (DBG_MSG, "Trying to attach %s\n", line); sanei_usb_attach_matching_devices (line, attach_one_device); } } /* while */ fclose (conf_fp); } else { HP5400_DBG (DBG_ERR, "Unable to read config file \"%s\": %s\n", HP5400_CONFIG_FILE, strerror (errno)); HP5400_DBG (DBG_MSG, "Using default built-in values\n"); attach_one_device (usb_devfile); } if (piVersion != NULL) { *piVersion = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, V_MINOR, BUILD); } return SANE_STATUS_GOOD; }
SANE_Status sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) { SANE_Char line[PATH_MAX]; SANE_Char *word, *end; SANE_String_Const cp; SANE_Int linenumber; FILE *fp; DBG_INIT (); DBG (2, "SANE Mustek USB backend version %d.%d build %d from %s\n", SANE_CURRENT_MAJOR, V_MINOR, BUILD, PACKAGE_STRING); if (version_code) *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, V_MINOR, BUILD); DBG (5, "sane_init: authorize %s null\n", authorize ? "!=" : "=="); num_devices = 0; first_dev = 0; first_handle = 0; devlist = 0; new_dev = 0; new_dev_len = 0; new_dev_alloced = 0; sanei_usb_init (); fp = sanei_config_open (MUSTEK_USB_CONFIG_FILE); if (!fp) { /* default to /dev/usb/scanner instead of insisting on config file */ DBG (3, "sane_init: couldn't open config file `%s': %s. Using " "/dev/usb/scanner directly\n", MUSTEK_USB_CONFIG_FILE, strerror (errno)); attach ("/dev/usb/scanner", 0, SANE_FALSE); return SANE_STATUS_GOOD; } linenumber = 0; DBG (4, "sane_init: reading config file `%s'\n", MUSTEK_USB_CONFIG_FILE); while (sanei_config_read (line, sizeof (line), fp)) { word = 0; linenumber++; cp = sanei_config_get_string (line, &word); if (!word || cp == line) { DBG (5, "sane_init: config file line %d: ignoring empty line\n", linenumber); if (word) free (word); continue; } if (word[0] == '#') { DBG (5, "sane_init: config file line %d: ignoring comment line\n", linenumber); free (word); continue; } if (strcmp (word, "option") == 0) { free (word); word = 0; cp = sanei_config_get_string (cp, &word); if (!word) { DBG (1, "sane_init: config file line %d: missing quotation mark?\n", linenumber); continue; } if (strcmp (word, "max_block_size") == 0) { free (word); word = 0; cp = sanei_config_get_string (cp, &word); if (!word) { DBG (1, "sane_init: config file line %d: missing quotation mark?\n", linenumber); continue; } errno = 0; max_block_size = strtol (word, &end, 0); if (end == word) { DBG (3, "sane-init: config file line %d: max_block_size " "must have a parameter; using 8192 bytes\n", linenumber); max_block_size = 8192; } if (errno) { DBG (3, "sane-init: config file line %d: max_block_size `%s' " "is invalid (%s); using 8192 bytes\n", linenumber, word, strerror (errno)); max_block_size = 8192; } else { DBG (3, "sane_init: config file line %d: max_block_size set " "to %d bytes\n", linenumber, max_block_size); } if (word) free (word); word = 0; } else if (strcmp (word, "1200ub") == 0) { if (new_dev_len > 0) { /* this is a 1200 UB */ new_dev[new_dev_len - 1]->chip->scanner_type = MT_1200UB; new_dev[new_dev_len - 1]->sane.model = "1200 UB"; DBG (3, "sane_init: config file line %d: `%s' is a Mustek " "1200 UB\n", linenumber, new_dev[new_dev_len - 1]->sane.name); } else { DBG (3, "sane_init: config file line %d: option " "1200ub ignored, was set before any device " "name\n", linenumber); } if (word) free (word); word = 0; } else if (strcmp (word, "1200cu") == 0) { if (new_dev_len > 0) { /* this is a 1200 CU */ new_dev[new_dev_len - 1]->chip->scanner_type = MT_1200CU; new_dev[new_dev_len - 1]->sane.model = "1200 CU"; DBG (3, "sane_init: config file line %d: `%s' is a Mustek " "1200 CU\n", linenumber, new_dev[new_dev_len - 1]->sane.name); } else { DBG (3, "sane_init: config file line %d: option " "1200cu ignored, was set before any device " "name\n", linenumber); } if (word) free (word); word = 0; } else if (strcmp (word, "1200cu_plus") == 0) { if (new_dev_len > 0) { /* this is a 1200 CU Plus */ new_dev[new_dev_len - 1]->chip->scanner_type = MT_1200CU_PLUS; new_dev[new_dev_len - 1]->sane.model = "1200 CU Plus"; DBG (3, "sane_init: config file line %d: `%s' is a Mustek " "1200 CU Plus\n", linenumber, new_dev[new_dev_len - 1]->sane.name); } else { DBG (3, "sane_init: config file line %d: option " "1200cu_plus ignored, was set before any device " "name\n", linenumber); } if (word) free (word); word = 0; } else if (strcmp (word, "600cu") == 0) { if (new_dev_len > 0) { /* this is a 600 CU */ new_dev[new_dev_len - 1]->chip->scanner_type = MT_600CU; new_dev[new_dev_len - 1]->sane.model = "600 CU"; DBG (3, "sane_init: config file line %d: `%s' is a Mustek " "600 CU\n", linenumber, new_dev[new_dev_len - 1]->sane.name); } else { DBG (3, "sane_init: config file line %d: option " "600cu ignored, was set before any device " "name\n", linenumber); } if (word) free (word); word = 0; } else { DBG (3, "sane_init: config file line %d: option " "%s is unknown\n", linenumber, word); if (word) free (word); word = 0; } } else { new_dev_len = 0; DBG (4, "sane_init: config file line %d: trying to attach `%s'\n", linenumber, line); sanei_usb_attach_matching_devices (line, attach_one_device); if (word) free (word); word = 0; } } if (new_dev_alloced > 0) { new_dev_len = new_dev_alloced = 0; free (new_dev); } fclose (fp); DBG (5, "sane_init: exit\n"); return SANE_STATUS_GOOD; }