[sane-devel] Allow users to specify the timeout of network operations (PIXMA)
Frederick Zhang
frederick888 at tsundere.moe
Tue Dec 27 21:15:54 UTC 2016
Hi SANE developers,
I'm using SANE to drive my Canon MG5765 and it is great except the
"select timed out" issue occurs quite often. My router is fairly
outdated and actually the machine itself lags a lot when scanning with
high DPI. I've created a simple patch (and tested) to allow specifying
the timeout limit in configuration file, not sure whether it would help
or not :)
diff --git a/backend/pixma.conf.in b/backend/pixma.conf.in
index a275b033..c60e4a07 100644
--- a/backend/pixma.conf.in
+++ b/backend/pixma.conf.in
@@ -11,4 +11,5 @@
# Example:
# bjnp://myscanner.my.domain:8612
# bjnp://printer-1.pheasant.org
+# bjnp://scanner.bad-network.org/timeout=1500
#
diff --git a/backend/pixma_bjnp.c b/backend/pixma_bjnp.c
index c62bd71a..9a1e698f 100644
--- a/backend/pixma_bjnp.c
+++ b/backend/pixma_bjnp.c
@@ -1412,7 +1412,7 @@ bjnp_recv_header (int devno, size_t *payload_size )
int attempt;
PDBG (bjnp_dbg
- (LOG_DEBUG, "bjnp_recv_header: receiving response header\n") );
+ (LOG_DEBUG, "bjnp_recv_header: receiving response header\n") );
fd = device[devno].tcp_socket;
*payload_size = 0;
@@ -1442,7 +1442,7 @@ bjnp_recv_header (int devno, size_t *payload_size )
{
terrno = errno;
PDBG (bjnp_dbg (LOG_CRIT,
- "bjnp_recv_header: ERROR - could not read response
header (select timed out)!\n" ) );
+ "bjnp_recv_header: ERROR - could not read response
header (select timed out, limit: %d)!\n", device[devno].bjnp_timeout ) );
errno = terrno;
return SANE_STATUS_IO_ERROR;
}
@@ -1502,7 +1502,7 @@ bjnp_recv_header (int devno, size_t *payload_size )
}
static int
-bjnp_init_device_structure(int dn, bjnp_sockaddr_t *sa,
bjnp_protocol_defs_t *protocol_defs)
+bjnp_init_device_structure(int dn, bjnp_sockaddr_t *sa,
bjnp_protocol_defs_t *protocol_defs, int min_timeout)
{
/* initialize device structure */
@@ -1524,7 +1524,8 @@ bjnp_init_device_structure(int dn, bjnp_sockaddr_t
*sa, bjnp_protocol_defs_t *pr
device[dn].address_level = get_scanner_name(sa, name);
device[dn].session_id = 0;
device[dn].serial = -1;
- device[dn].bjnp_timeout = 1000;
+ device[dn].bjnp_timeout = min_timeout;
+ device[dn].bjnp_min_timeout = min_timeout;
device[dn].scanner_data_left = 0;
device[dn].last_cmd = 0;
device[dn].blocksize = BJNP_BLOCKSIZE_START;
@@ -1617,7 +1618,7 @@ bjnp_recv_data (int devno, SANE_Byte * buffer,
size_t start_pos, size_t * len)
{
terrno = errno;
PDBG (bjnp_dbg (LOG_CRIT,
- "bjnp_recv_data: ERROR - could not read response payload
(select timed out)!\n") );
+ "bjnp_recv_data: ERROR - could not read response payload
(select timed out, limit: %d)!\n", device[devno].bjnp_timeout) );
errno = terrno;
*len = 0;
return SANE_STATUS_IO_ERROR;
@@ -1654,6 +1655,7 @@ bjnp_allocate_device (SANE_String_Const devname,
struct addrinfo hints;
int result;
int i;
+ int min_timeout = BJNP_TIMEOUT_MIN;
PDBG (bjnp_dbg (LOG_DEBUG, "bjnp_allocate_device(%s) %d\n", devname,
bjnp_no_devices));
@@ -1664,12 +1666,19 @@ bjnp_allocate_device (SANE_String_Const devname,
if (strlen (args) != 0)
{
- PDBG (bjnp_dbg
- (LOG_CRIT,
- "bjnp_allocate_device: ERROR - URI may not contain userid,
password or aguments: %s\n",
- devname));
+ if (strlen(args) > 8 && strncmp(args, "timeout=", 8) == 0)
+ {
+ min_timeout = atoi(args + 8);
+ if (min_timeout < BJNP_TIMEOUT_MIN)
+ min_timeout = BJNP_TIMEOUT_MIN;
+ } else {
+ PDBG (bjnp_dbg
+ (LOG_CRIT,
+ "bjnp_allocate_device: ERROR - URI may not contain userid,
password or aguments except timtout: %s\n",
+ devname));
- return BJNP_STATUS_INVAL;
+ return BJNP_STATUS_INVAL;
+ }
}
if ( (protocol_defs = get_protocol_by_method(method)) == NULL)
{
@@ -1721,7 +1730,7 @@ bjnp_allocate_device (SANE_String_Const devname,
return BJNP_STATUS_INVAL;
}
if (bjnp_init_device_structure( bjnp_no_devices,
(bjnp_sockaddr_t *)cur -> ai_addr,
- protocol_defs) != 0)
+ protocol_defs, min_timeout) != 0)
{
/* giving up on this address, try next one if any */
break;
@@ -1742,6 +1751,12 @@ bjnp_allocate_device (SANE_String_Const devname,
device[bjnp_no_devices].addr = NULL;
device[i].address_level =
device[bjnp_no_devices].address_level;
}
+ if (device[i].bjnp_min_timeout <
device[bjnp_no_devices].bjnp_min_timeout)
+ {
+ /* use the longer timeout as user wants */
+ device[i].bjnp_timeout =
device[bjnp_no_devices].bjnp_min_timeout;
+ device[i].bjnp_min_timeout =
device[bjnp_no_devices].bjnp_min_timeout;
+ }
freeaddrinfo(res);
*dn = i;
bjnp_free_device_structure( bjnp_no_devices);
@@ -2182,11 +2197,11 @@ sanei_bjnp_deactivate (SANE_Int dn)
extern void
sanei_bjnp_set_timeout (SANE_Int devno, SANE_Int timeout)
{
- if (timeout < BJNP_TIMEOUT_MIN)
+ if (timeout < device[devno].bjnp_min_timeout)
{
PDBG (bjnp_dbg (LOG_INFO, "bjnp_set_timeout to %d, but using
minimum value %d\n",
- timeout, BJNP_TIMEOUT_MIN));
- timeout = BJNP_TIMEOUT_MIN;
+ timeout, device[devno].bjnp_min_timeout));
+ timeout = device[devno].bjnp_min_timeout;
} else {
PDBG (bjnp_dbg (LOG_INFO, "bjnp_set_timeout to %d\n",
timeout));
diff --git a/backend/pixma_bjnp_private.h b/backend/pixma_bjnp_private.h
index a7870c68..50d215d8 100644
--- a/backend/pixma_bjnp_private.h
+++ b/backend/pixma_bjnp_private.h
@@ -370,6 +370,7 @@ typedef struct device_s
bjnp_sockaddr_t * addr; /* ip-address of the scanner */
int address_level; /* link local, public or has a FQDN */
int bjnp_timeout; /* timeout (msec) for next poll command */
+ int bjnp_min_timeout; /* device specific min timeout */
#ifdef PIXMA_BJNP_USE_STATUS
/* polling state information */
--
Best Regards,
Frederick Zhang
Home Page: https://onee3.org/
Email: Frederick888 at Tsundere.moe
More information about the sane-devel
mailing list