diff options
Diffstat (limited to 'backend/pixma/pixma_bjnp.c')
-rw-r--r-- | backend/pixma/pixma_bjnp.c | 201 |
1 files changed, 118 insertions, 83 deletions
diff --git a/backend/pixma/pixma_bjnp.c b/backend/pixma/pixma_bjnp.c index 34ba918..4e83714 100644 --- a/backend/pixma/pixma_bjnp.c +++ b/backend/pixma/pixma_bjnp.c @@ -109,6 +109,13 @@ #ifndef SSIZE_MAX # define SSIZE_MAX LONG_MAX #endif +#ifndef HOST_NAME_MAX +# ifdef _POSIX_HOST_NAME_MAX +# define HOST_NAME_MAX _POSIX_HOST_NAME_MAX +# else +# define HOST_NAME_MAX 255 +# endif +#endif /* static data */ static bjnp_device_t device[BJNP_NO_DEVICES]; @@ -454,69 +461,6 @@ determine_scanner_serial (const char *hostname, const char * mac_address, char * } static int -bjnp_open_tcp (int devno) -{ - int sock; - int val; - bjnp_sockaddr_t *addr = device[devno].addr; - char host[BJNP_HOST_MAX]; - int port; - int connect_timeout = BJNP_TIMEOUT_TCP_CONNECT; - - get_address_info( addr, host, &port); - PDBG (bjnp_dbg (LOG_DEBUG, "bjnp_open_tcp: Setting up a TCP socket, dest: %s port %d\n", - host, port ) ); - - if ((sock = socket (get_protocol_family( addr ) , SOCK_STREAM, 0)) < 0) - { - PDBG (bjnp_dbg (LOG_CRIT, "bjnp_open_tcp: ERROR - Can not create socket: %s\n", - strerror (errno))); - return -1; - } - - val = 1; - setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof (val)); - -#if 0 - val = 1; - setsockopt (sock, SOL_SOCKET, SO_REUSEPORT, &val, sizeof (val)); - - val = 1; -#endif - - /* - * Using TCP_NODELAY improves responsiveness, especially on systems - * with a slow loopback interface... - */ - - val = 1; - setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val)); - -/* - * Close this socket when starting another process... - */ - - fcntl (sock, F_SETFD, FD_CLOEXEC); - - while (connect_timeout > 0) - { - if (connect - (sock, &(addr->addr), sa_size(device[devno].addr)) == 0) - { - device[devno].tcp_socket = sock; - return 0; - } - PDBG (bjnp_dbg( LOG_INFO, "bjnp_open_tcp: INFO - Can not yet connect over TCP to scanner: %s, retrying\n", - strerror(errno))); - usleep(BJNP_TCP_CONNECT_INTERVAL * BJNP_USLEEP_MS); - connect_timeout = connect_timeout - BJNP_TCP_CONNECT_INTERVAL; - } - PDBG (bjnp_dbg - (LOG_CRIT, "bjnp_open_tcp: ERROR - Can not connect to scanner, giving up!")); - return -1; -} - -static int split_uri (const char *devname, char *method, char *host, char *port, char *args) { @@ -1565,6 +1509,7 @@ bjnp_init_device_structure(int dn, bjnp_sockaddr_t *sa, bjnp_protocol_defs_t *pr #endif device[dn].protocol = protocol_defs->protocol_version; device[dn].protocol_string = protocol_defs->proto_string; + device[dn].single_tcp_session = protocol_defs->single_tcp_session; device[dn].tcp_socket = -1; device[dn].addr = (bjnp_sockaddr_t *) malloc(sizeof ( bjnp_sockaddr_t) ); @@ -1694,6 +1639,98 @@ bjnp_recv_data (int devno, SANE_Byte * buffer, size_t start_pos, size_t * len) return SANE_STATUS_GOOD; } +static int +bjnp_open_tcp (int devno) +{ + int sock; + int val; + char my_hostname[HOST_NAME_MAX]; + char pid_str[64]; + bjnp_sockaddr_t *addr = device[devno].addr; + char host[BJNP_HOST_MAX]; + int port; + int connect_timeout = BJNP_TIMEOUT_TCP_CONNECT; + + if (device[devno].tcp_socket != -1) + { + PDBG (bjnp_dbg( LOG_DEBUG, "bjnp_open_tcp: socket alreeady opened, nothing to do\n")); + return 0; + } + get_address_info( addr, host, &port); + PDBG (bjnp_dbg (LOG_DEBUG, "bjnp_open_tcp: Setting up a TCP socket, dest: %s port %d\n", + host, port ) ); + + gethostname (my_hostname, HOST_NAME_MAX); + my_hostname[HOST_NAME_MAX - 1] = '\0'; + sprintf (pid_str, "Process ID = %d", getpid ()); + bjnp_send_job_details (devno, my_hostname, getusername (), pid_str); + + if ((sock = socket (get_protocol_family( addr ) , SOCK_STREAM, 0)) < 0) + { + PDBG (bjnp_dbg (LOG_CRIT, "bjnp_open_tcp: ERROR - Can not create socket: %s\n", + strerror (errno))); + return -1; + } + + val = 1; + setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof (val)); + +#if 0 + val = 1; + setsockopt (sock, SOL_SOCKET, SO_REUSEPORT, &val, sizeof (val)); + + val = 1; +#endif + + /* + * Using TCP_NODELAY improves responsiveness, especially on systems + * with a slow loopback interface... + */ + + val = 1; + setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &val, sizeof (val)); + +/* + * Close this socket when starting another process... + */ + + fcntl (sock, F_SETFD, FD_CLOEXEC); + + while (connect_timeout > 0) + { + if (connect + (sock, &(addr->addr), sa_size(device[devno].addr)) == 0) + { + device[devno].tcp_socket = sock; + PDBG( bjnp_dbg(LOG_INFO, "bjnp_open_tcp: created socket %d\n", sock)); + return 0; + } + PDBG (bjnp_dbg( LOG_INFO, "bjnp_open_tcp: INFO - Can not yet connect over TCP to scanner: %s, retrying\n", + strerror(errno))); + usleep(BJNP_TCP_CONNECT_INTERVAL * BJNP_USLEEP_MS); + connect_timeout = connect_timeout - BJNP_TCP_CONNECT_INTERVAL; + } + PDBG (bjnp_dbg + (LOG_CRIT, "bjnp_open_tcp: ERROR - Can not connect to scanner, giving up!")); + return -1; +} + +static void bjnp_close_tcp(int devno) +{ + if ( device[devno].tcp_socket != -1) + { + PDBG( bjnp_dbg( LOG_INFO, "bjnp_close_tcp - closing tcp-socket %d\n", device[devno].tcp_socket)); + bjnp_finish_job (devno); + close (device[devno].tcp_socket); + device[devno].tcp_socket = -1; + } + else + { + PDBG( bjnp_dbg( LOG_INFO, "bjnp_close_tcp: socket not open, nothing to do.\n")); + } + device[devno].open = 0; +} + static BJNP_Status bjnp_allocate_device (SANE_String_Const devname, SANE_Int * dn, char *resulting_host) @@ -1762,7 +1799,7 @@ bjnp_allocate_device (SANE_String_Const devname, if (result != 0 ) { PDBG (bjnp_dbg (LOG_CRIT, "bjnp_allocate_device: ERROR - Cannot resolve host: %s port %s\n", host, port)); - return SANE_STATUS_INVAL; + return BJNP_STATUS_INVAL; } /* Check if a device number is already allocated to any of the scanner's addresses */ @@ -2273,6 +2310,13 @@ sanei_bjnp_open (SANE_String_Const devname, SANE_Int * dn) if ( (result != BJNP_STATUS_GOOD) && (result != BJNP_STATUS_ALREADY_ALLOCATED ) ) { return SANE_STATUS_INVAL; } + + if (device[*dn].single_tcp_session && bjnp_open_tcp (*dn) != 0) + { + PDBG (bjnp_dbg (LOG_INFO, "sanei_bjnp_opening TCP connection failed.\n\n")); + return SANE_STATUS_INVAL; + } + PDBG (bjnp_dbg (LOG_INFO, "sanei_bjnp_open done.\n\n")); return SANE_STATUS_GOOD; } @@ -2286,8 +2330,8 @@ sanei_bjnp_close (SANE_Int dn) { PDBG (bjnp_dbg (LOG_INFO, "sanei_bjnp_close(%d):\n", dn)); - device[dn].open = 0; - sanei_bjnp_deactivate(dn); + bjnp_close_tcp( dn ); + PDBG (bjnp_dbg (LOG_INFO, "sanei_bjnp_close done.\n\n")); } /** Activate BJNP device connection @@ -2298,21 +2342,13 @@ sanei_bjnp_close (SANE_Int dn) SANE_Status sanei_bjnp_activate (SANE_Int dn) { - char hostname[256]; - char pid_str[64]; - PDBG (bjnp_dbg (LOG_INFO, "sanei_bjnp_activate (%d)\n", dn)); - gethostname (hostname, 256); - hostname[255] = '\0'; - sprintf (pid_str, "Process ID = %d", getpid ()); - - bjnp_send_job_details (dn, hostname, getusername (), pid_str); - - if (bjnp_open_tcp (dn) != 0) + if (!(device[dn].single_tcp_session) && bjnp_open_tcp (dn) != 0) { + PDBG (bjnp_dbg (LOG_INFO, "sanei_bjnp_activate: open TCP connection failed.\n\n")); return SANE_STATUS_INVAL; } - + PDBG (bjnp_dbg (LOG_INFO, "sanei_bjnp_activate done.\n\n")); return SANE_STATUS_GOOD; } @@ -2325,12 +2361,11 @@ SANE_Status sanei_bjnp_deactivate (SANE_Int dn) { PDBG (bjnp_dbg (LOG_INFO, "sanei_bjnp_deactivate (%d)\n", dn)); - if ( device[dn].tcp_socket != -1) - { - bjnp_finish_job (dn); - close (device[dn].tcp_socket); - device[dn].tcp_socket = -1; - } + if (!device[dn].single_tcp_session) + { + bjnp_close_tcp(dn); + } + PDBG (bjnp_dbg (LOG_INFO, "sanei_bjnp_deactivate done.\n\n")); return SANE_STATUS_GOOD; } |