kopia lustrzana https://gitlab.com/sane-project/backends
2009-03-06 Louis Lagendijk <llagendijk-guest at users.alioth.debian.org>
* backend/pixma_bjnp.c backend/pixma_bjnp.h backend/pixma_bjnp_private.h backend/pixma_io_sanei.c: Make bjnp protocol more resilient against packet loss and corruption Changed timeout for all responses to be at least 10 seconds Send all broadcasts for scanner detection 5 times Made sure scanners are added to device list only once Changed device-id for bjnp so it uses scanner hostname/ip-address instead of mac address as this is more human friendly. To make room, use scanner model instead of USB-id (which is bogus for network scannersmerge-requests/1/head
rodzic
dd3db8d510
commit
0086173dd3
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
2009-03-06 Louis Lagendijk <llagendijk-guest at users.alioth.debian.org>
|
||||
* backend/pixma_bjnp.c backend/pixma_bjnp.h
|
||||
backend/pixma_bjnp_private.h backend/pixma_io_sanei.c:
|
||||
Make bjnp protocol more resilient against packet loss and corruption
|
||||
Changed timeout for all responses to be at least 10 seconds
|
||||
Send all broadcasts for scanner detection 5 times
|
||||
Made sure scanners are added to device list only once
|
||||
Changed device-id for bjnp so it uses scanner hostname/ip-address
|
||||
instead of mac address as this is more human friendly.
|
||||
To make room, use scanner model instead of USB-id (which is bogus
|
||||
for network scanners
|
||||
|
||||
2009-03-17 m. allan noah <kitno455 a t gmail d o t com>
|
||||
* doc/desc/gt68xx.desc, backend/gt68xx.conf.in: add NeatReceipts
|
||||
Mobile Scanner (from Kelly Price)
|
||||
|
|
|
@ -181,6 +181,26 @@ static char *getusername(void)
|
|||
return noname;
|
||||
}
|
||||
|
||||
|
||||
static char *truncate_hostname(char *hostname, char *short_hostname)
|
||||
{
|
||||
char *dot;
|
||||
|
||||
/* determine a short hostname (max HOSTNAME_SHORT_MAX chars */
|
||||
|
||||
strncpy(short_hostname, hostname, SHORT_HOSTNAME_MAX);
|
||||
short_hostname[SHORT_HOSTNAME_MAX -1] = '\0';
|
||||
|
||||
if (strlen(hostname) > SHORT_HOSTNAME_MAX)
|
||||
{
|
||||
/* this is a hostname, not an ip-address, so remove domain part of the name */
|
||||
|
||||
if ((dot = index(short_hostname, '.')) != NULL )
|
||||
*dot = '\0';
|
||||
}
|
||||
return short_hostname;
|
||||
}
|
||||
|
||||
static int
|
||||
bjnp_open_tcp (int devno)
|
||||
{
|
||||
|
@ -290,7 +310,7 @@ split_uri (const char *devname, char *method, char *hostname, int *port,
|
|||
*/
|
||||
|
||||
if (next != ':')
|
||||
port = 0;
|
||||
*port = 0;
|
||||
else
|
||||
{
|
||||
i = 0;
|
||||
|
@ -334,15 +354,16 @@ set_cmd (int devno, struct BJNP_command *cmd, char cmd_code, int payload_len)
|
|||
strncpy (cmd->BJNP_id, BJNP_STRING, sizeof (cmd->BJNP_id));
|
||||
cmd->dev_type = BJNP_CMD_SCAN;
|
||||
cmd->cmd_code = cmd_code;
|
||||
cmd->unknown1 = htons(0);
|
||||
if (devno == -1)
|
||||
{
|
||||
/* device not opened, use 0 for serial and session) */
|
||||
cmd->seq_no = 0;
|
||||
cmd->session_id = 0;
|
||||
cmd->seq_no = htons(0);
|
||||
cmd->session_id = htons(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->seq_no = htonl (device[devno].serial++);
|
||||
cmd->seq_no = htons (++(device[devno].serial));
|
||||
cmd->session_id = htons (device[devno].session_id);
|
||||
}
|
||||
cmd->payload_len = htonl (payload_len);
|
||||
|
@ -367,14 +388,14 @@ udp_command (const int dev_no, char *command, int cmd_len, char *response,
|
|||
int result;
|
||||
int try, attempt;
|
||||
|
||||
PDBG (pixma_dbg (LOG_DEBUG, "Sending UDP command to %s:%d\n",
|
||||
PDBG (pixma_dbg (LOG_DEBUG, "udp_command: Sending UDP command to %s:%d\n",
|
||||
inet_ntoa (device[dev_no].addr.sin_addr),
|
||||
ntohs (device[dev_no].addr.sin_port)));
|
||||
|
||||
if ((sockfd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT, "udp_command: sockfd - %s\n", strerror (errno)));
|
||||
(LOG_CRIT, "udp_command: can not open socket - %s\n", strerror (errno)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -383,7 +404,7 @@ udp_command (const int dev_no, char *command, int cmd_len, char *response,
|
|||
(socklen_t) sizeof (struct sockaddr_in)) != 0)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT, "udp_command: connect - %s\n", strerror (errno)));
|
||||
(LOG_CRIT, "udp_command: connect failed- %s\n", strerror (errno)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -392,8 +413,8 @@ udp_command (const int dev_no, char *command, int cmd_len, char *response,
|
|||
if ((numbytes = send (sockfd, command, cmd_len, 0)) != cmd_len)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT, "udp_command: Sent only %d bytes of packet",
|
||||
numbytes));
|
||||
(LOG_CRIT, "udp_command: Sent only 0x%x = %d bytes of packet",
|
||||
numbytes, numbytes));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -412,7 +433,7 @@ udp_command (const int dev_no, char *command, int cmd_len, char *response,
|
|||
if (result <= 0)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT, "udpcommand: No data received (select): %s\n",
|
||||
(LOG_CRIT, "udp_command: No data received (select): %s\n",
|
||||
result == 0 ? "timed out" : strerror (errno)));
|
||||
continue;
|
||||
}
|
||||
|
@ -434,11 +455,11 @@ udp_command (const int dev_no, char *command, int cmd_len, char *response,
|
|||
}
|
||||
|
||||
static int
|
||||
get_scanner_id (const int dev_no, char *model, char *IEEE1284_id)
|
||||
get_scanner_id (const int dev_no, char *model)
|
||||
{
|
||||
/*
|
||||
* get scanner identity
|
||||
* Sets model (make and model) and IEEE1284_id
|
||||
* Sets model (make and model)
|
||||
* Return 0 on success, -1 in case of errors
|
||||
*/
|
||||
|
||||
|
@ -452,7 +473,6 @@ get_scanner_id (const int dev_no, char *model, char *IEEE1284_id)
|
|||
/* set defaults */
|
||||
|
||||
strcpy (model, "Unidentified scanner");
|
||||
strcpy (IEEE1284_id, "");
|
||||
|
||||
set_cmd (dev_no, &cmd, CMD_UDP_GET_ID, 0);
|
||||
|
||||
|
@ -472,22 +492,13 @@ get_scanner_id (const int dev_no, char *model, char *IEEE1284_id)
|
|||
|
||||
id = (struct IDENTITY *) resp_buf;
|
||||
|
||||
/* truncate string to be safe */
|
||||
id->id[BJNP_IEEE1284_MAX -1] = '\0';
|
||||
id_len = ntohs (id->id_len) - sizeof (id->id_len);
|
||||
|
||||
/* restrict length to size of buffer */
|
||||
strcpy(scanner_id, id->id);
|
||||
|
||||
if (id_len >= BJNP_IEEE1284_MAX)
|
||||
id_len = BJNP_IEEE1284_MAX - 1;
|
||||
|
||||
/* set IEEE1284_id */
|
||||
|
||||
strncpy (scanner_id, id->id, id_len);
|
||||
scanner_id[id_len + 1] = '\0';
|
||||
|
||||
PDBG (pixma_dbg (LOG_INFO, "Identity = %s\n", scanner_id));
|
||||
|
||||
if (IEEE1284_id != NULL)
|
||||
strcpy (IEEE1284_id, scanner_id);
|
||||
PDBG (pixma_dbg (LOG_INFO, "Scanner identity string = %s\n", scanner_id));
|
||||
|
||||
/* get make&model from IEEE1284 id */
|
||||
|
||||
|
@ -563,7 +574,7 @@ parse_scanner_address (char *resp_buf, char *address, char *serial)
|
|||
}
|
||||
|
||||
static int
|
||||
bjnp_send_broadcast (struct in_addr local_addr, struct in_addr broadcast_addr,
|
||||
bjnp_send_broadcast (struct in_addr local_addr, int local_port, struct in_addr broadcast_addr,
|
||||
struct BJNP_command cmd, int size)
|
||||
{
|
||||
/*
|
||||
|
@ -578,7 +589,7 @@ bjnp_send_broadcast (struct in_addr local_addr, struct in_addr broadcast_addr,
|
|||
if ((sockfd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT, "discover_scanner: sockfd - %s", strerror (errno)));
|
||||
(LOG_CRIT, "bjnp_send_broadcast: can not open socket - %s", strerror (errno)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -589,7 +600,7 @@ bjnp_send_broadcast (struct in_addr local_addr, struct in_addr broadcast_addr,
|
|||
sizeof (broadcast)) != 0)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT, "discover_scanner: setsockopts - %s",
|
||||
(LOG_CRIT, "bjnp_send_broadcast: setting socket options failed - %s",
|
||||
strerror (errno)));
|
||||
close (sockfd);
|
||||
return -1;
|
||||
|
@ -598,7 +609,7 @@ bjnp_send_broadcast (struct in_addr local_addr, struct in_addr broadcast_addr,
|
|||
/* Bind to local address, use BJNP port */
|
||||
|
||||
sendaddr.sin_family = AF_INET;
|
||||
sendaddr.sin_port = htons (BJNP_PORT_SCAN);
|
||||
sendaddr.sin_port = htons (local_port);
|
||||
sendaddr.sin_addr = local_addr;
|
||||
memset (sendaddr.sin_zero, '\0', sizeof sendaddr.sin_zero);
|
||||
|
||||
|
@ -607,7 +618,7 @@ bjnp_send_broadcast (struct in_addr local_addr, struct in_addr broadcast_addr,
|
|||
(socklen_t) sizeof (sendaddr)) != 0)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT, "discover_scanner: bind - %s\n", strerror (errno)));
|
||||
(LOG_CRIT, "bjnp_send_broadcast: bind socket to local address failed - %s\n", strerror (errno)));
|
||||
close (sockfd);
|
||||
return -1;
|
||||
}
|
||||
|
@ -626,9 +637,9 @@ bjnp_send_broadcast (struct in_addr local_addr, struct in_addr broadcast_addr,
|
|||
(struct sockaddr *) &sendaddr,
|
||||
sizeof (sendaddr))) != size)
|
||||
{
|
||||
PDBG (pixma_dbg (LOG_NOTICE,
|
||||
"discover_scanners: Sent only %d bytes of packet, error = %s\n",
|
||||
numbytes, strerror (errno)));
|
||||
PDBG (pixma_dbg (LOG_CRIT,
|
||||
"bjnp_send_broadcasts: Sent only %x = %d bytes of packet, error = %s\n",
|
||||
numbytes, numbytes, strerror (errno)));
|
||||
/* not allowed, skip this interface */
|
||||
|
||||
close (sockfd);
|
||||
|
@ -660,7 +671,7 @@ bjnp_finish_job (int devno)
|
|||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT,
|
||||
"Received %d characters on close command, expected %d\n",
|
||||
"Received %d characters on close scanjob command, expected %d\n",
|
||||
resp_len, (int) sizeof (struct BJNP_command)));
|
||||
return;
|
||||
}
|
||||
|
@ -819,14 +830,16 @@ bjnp_write (int devno, const SANE_Byte * buf, size_t count)
|
|||
struct SCAN_BUF bjnp_buf;
|
||||
|
||||
if (device[devno].scanner_data_left)
|
||||
PDBG (pixma_dbg (LOG_CRIT, "bjnp_write: ERROR scanner data left = %lx\n",
|
||||
(long) device[devno].scanner_data_left));
|
||||
PDBG (pixma_dbg (LOG_CRIT, "bjnp_write: ERROR scanner data left = 0x%lx = %ld\n",
|
||||
(long) device[devno].scanner_data_left,
|
||||
(long) device[devno].scanner_data_left));
|
||||
|
||||
/* set BJNP command header */
|
||||
|
||||
set_cmd (devno, (struct BJNP_command *) &bjnp_buf, CMD_TCP_SEND, count);
|
||||
memcpy (bjnp_buf.scan_data, buf, count);
|
||||
PDBG (pixma_dbg (LOG_DEBUG, "bjnp_write: sending %d bytes\n", (int) count);
|
||||
PDBG (pixma_dbg (LOG_DEBUG, "bjnp_write: sending 0x%lx = %ld bytes\n",
|
||||
(long) count, (long) count);
|
||||
PDBG( pixma_hexdump (LOG_DEBUG2, (char *) &bjnp_buf,
|
||||
sizeof (struct BJNP_command) + count)));
|
||||
|
||||
|
@ -865,14 +878,15 @@ bjnp_send_read_request (int devno)
|
|||
|
||||
if (device[devno].scanner_data_left)
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT, "bjnp_send_request: ERROR scanner data left = %lx\n",
|
||||
(LOG_CRIT, "bjnp_send_read_request: ERROR scanner data left = 0x%lx = %ld\n",
|
||||
(long) device[devno].scanner_data_left,
|
||||
(long) device[devno].scanner_data_left));
|
||||
|
||||
/* set BJNP command header */
|
||||
|
||||
set_cmd (devno, (struct BJNP_command *) &bjnp_buf, CMD_TCP_REQ, 0);
|
||||
|
||||
PDBG (pixma_dbg (LOG_DEBUG, "bjnp_send_req sending command\n"));
|
||||
PDBG (pixma_dbg (LOG_DEBUG, "bjnp_send_read_req sending command\n"));
|
||||
PDBG(pixma_hexdump (LOG_DEBUG2, (char *) &bjnp_buf,
|
||||
sizeof (struct BJNP_command)));
|
||||
|
||||
|
@ -883,7 +897,7 @@ bjnp_send_read_request (int devno)
|
|||
/* return result from write */
|
||||
terrno = errno;
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT, "bjnp_send_request: Could not send data!\n"));
|
||||
(LOG_CRIT, "bjnp_send_read_request: Could not send data!\n"));
|
||||
errno = terrno;
|
||||
return -1;
|
||||
}
|
||||
|
@ -915,7 +929,8 @@ bjnp_recv_header (int devno)
|
|||
|
||||
if (device[devno].scanner_data_left)
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT, "bjnp_send_request: ERROR scanner data left = %lx\n",
|
||||
(LOG_CRIT, "bjnp_send_request: ERROR scanner data left = 0x%lx = %ld\n",
|
||||
(long) device[devno].scanner_data_left,
|
||||
(long) device[devno].scanner_data_left));
|
||||
|
||||
attempt = 0;
|
||||
|
@ -931,15 +946,24 @@ bjnp_recv_header (int devno)
|
|||
while (((result = select (fd + 1, &input, NULL, NULL, &timeout)) == -1) &&
|
||||
(errno == EINTR) && (attempt++ < MAX_SELECT_ATTEMPTS));
|
||||
|
||||
if (result <= 0)
|
||||
if (result < 0)
|
||||
{
|
||||
terrno = (result == 0) ? EAGAIN : errno;
|
||||
terrno = errno;
|
||||
PDBG (pixma_dbg (LOG_CRIT,
|
||||
"bjnp_recv_header: could not read response header (select): %s!\n",
|
||||
strerror (terrno)));
|
||||
errno = terrno;
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
else if (result == 0)
|
||||
{
|
||||
terrno = errno;
|
||||
PDBG (pixma_dbg (LOG_CRIT,
|
||||
"bjnp_recv_header: could not read response header (select timed out): %s!\n",
|
||||
strerror (terrno)));
|
||||
errno = terrno;
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
/* get response header */
|
||||
|
||||
|
@ -963,11 +987,20 @@ bjnp_recv_header (int devno)
|
|||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT,
|
||||
"ERROR: Received response has cmd code %d, expected %d\n",
|
||||
"bjnp_recv_header:ERROR, Received response has cmd code %d, expected %d\n",
|
||||
resp_buf.cmd_code, device[devno].last_cmd));
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
if (ntohs(resp_buf.seq_no) != (uint16_t) device[devno].serial)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT,
|
||||
"bjnp_recv_header:ERROR, Received response has serial %d, expected %d\n",
|
||||
(int) ntohs(resp_buf.seq_no), (int)device[devno].serial));
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
/* got response header back, retrieve length of scanner data */
|
||||
|
||||
|
||||
|
@ -1000,7 +1033,7 @@ bjnp_recv_data (int devno, SANE_Byte * buffer, size_t * len)
|
|||
fd = device[devno].fd;
|
||||
|
||||
PDBG (pixma_dbg
|
||||
(LOG_DEBUG, "bjnp_recv_data: read response payload (%ld bytes)\n",
|
||||
(LOG_DEBUG, "bjnp_recv_data: read response payload (%ld bytes max)\n",
|
||||
(long) *len));
|
||||
|
||||
attempt = 0;
|
||||
|
@ -1016,9 +1049,9 @@ bjnp_recv_data (int devno, SANE_Byte * buffer, size_t * len)
|
|||
while (((result = select (fd + 1, &input, NULL, NULL, &timeout)) == -1) &&
|
||||
(errno == EINTR) && (attempt++ < MAX_SELECT_ATTEMPTS));
|
||||
|
||||
if (result <= 0)
|
||||
if (result < 0)
|
||||
{
|
||||
terrno = (result == 0) ? EAGAIN : errno;
|
||||
terrno = errno;
|
||||
PDBG (pixma_dbg (LOG_CRIT,
|
||||
"bjnp_recv_data: could not read response payload (select): %s!\n",
|
||||
strerror (errno)));
|
||||
|
@ -1026,6 +1059,16 @@ bjnp_recv_data (int devno, SANE_Byte * buffer, size_t * len)
|
|||
*len = 0;
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
else if (result == 0)
|
||||
{
|
||||
terrno = errno;
|
||||
PDBG (pixma_dbg (LOG_CRIT,
|
||||
"bjnp_recv_data: could not read response payload (select timed out): %s!\n",
|
||||
strerror (terrno)));
|
||||
errno = terrno;
|
||||
*len = 0;
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
if ((recv_bytes = recv (fd, buffer, *len, 0)) < 0)
|
||||
{
|
||||
|
@ -1048,8 +1091,8 @@ bjnp_recv_data (int devno, SANE_Byte * buffer, size_t * len)
|
|||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
sanei_bjnp_attach (SANE_String_Const devname, SANE_Int * dn)
|
||||
static BJNP_Status
|
||||
bjnp_allocate_device (SANE_String_Const devname, SANE_Int * dn, char *res_hostname)
|
||||
{
|
||||
char method[256];
|
||||
char hostname[256];
|
||||
|
@ -1057,34 +1100,30 @@ sanei_bjnp_attach (SANE_String_Const devname, SANE_Int * dn)
|
|||
char args[256];
|
||||
struct hostent *result;
|
||||
struct in_addr *addr_list;
|
||||
int i;
|
||||
|
||||
PDBG (pixma_dbg (LOG_DEBUG, "bjnp_allocate_device(%s)", devname ));
|
||||
|
||||
if (split_uri (devname, method, hostname, &port, args) != 0)
|
||||
{
|
||||
PDBG (pixma_dbg (LOG_CRIT, "Can not parse scanner URI: %s", devname));
|
||||
return SANE_STATUS_INVAL;
|
||||
return BJNP_STATUS_INVAL;
|
||||
}
|
||||
|
||||
if (strlen (args) != 0)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT, "URI may not contain userid, password or aguments: %s",
|
||||
(LOG_CRIT, "URI may not contain userid, password or aguments: %s\n",
|
||||
devname));
|
||||
return SANE_STATUS_INVAL;
|
||||
|
||||
return BJNP_STATUS_INVAL;
|
||||
}
|
||||
if (strcmp (method, BJNP_METHOD) != 0)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT, "URI %s contains invalid method: %s", devname,
|
||||
(LOG_CRIT, "URI %s contains invalid method: %s\n", devname,
|
||||
method));
|
||||
return SANE_STATUS_INVAL;
|
||||
return BJNP_STATUS_INVAL;
|
||||
}
|
||||
*dn = first_free_device;
|
||||
first_free_device++;
|
||||
|
||||
/*
|
||||
* fill device structure
|
||||
* TODO: implement scanning of ALL returned addressess
|
||||
*/
|
||||
|
||||
result = gethostbyname (hostname);
|
||||
if ((result == NULL) || result->h_addrtype != AF_INET)
|
||||
|
@ -1097,6 +1136,38 @@ sanei_bjnp_attach (SANE_String_Const devname, SANE_Int * dn)
|
|||
port = BJNP_PORT_SCAN;
|
||||
}
|
||||
|
||||
addr_list = (struct in_addr *) *result->h_addr_list;
|
||||
|
||||
/* Check if a device number is already allocated */
|
||||
|
||||
for (i = 0; i < first_free_device; i++)
|
||||
{
|
||||
/* check address, AF_INET is assumed */
|
||||
|
||||
if ((device[i].addr.sin_port == htons (port)) &&
|
||||
(device[i].addr.sin_addr.s_addr == addr_list[0].s_addr))
|
||||
{
|
||||
*dn = i;
|
||||
return BJNP_STATUS_ALREADY_ALLOCATED;
|
||||
}
|
||||
}
|
||||
|
||||
/* return hostname if required */
|
||||
|
||||
if (res_hostname != NULL)
|
||||
strcpy(res_hostname, hostname);
|
||||
|
||||
/*
|
||||
* No existing device structure found, fill new device structure
|
||||
*/
|
||||
|
||||
if (first_free_device == BJNP_NO_DEVICES)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT, "Too many devices, ran out of device structures, can not add %s\n", devname));
|
||||
return BJNP_STATUS_INVAL;
|
||||
}
|
||||
*dn = first_free_device++;
|
||||
device[*dn].open = 1;
|
||||
device[*dn].active = 0;
|
||||
#ifdef PIXMA_BJNP_STATUS
|
||||
|
@ -1104,24 +1175,24 @@ sanei_bjnp_attach (SANE_String_Const devname, SANE_Int * dn)
|
|||
device[*dn].dialogue = 0;
|
||||
#endif
|
||||
device[*dn].fd = -1;
|
||||
addr_list = (struct in_addr *) *result->h_addr_list;
|
||||
device[*dn].addr.sin_family = AF_INET;
|
||||
device[*dn].addr.sin_port = htons (port);
|
||||
device[*dn].addr.sin_addr = addr_list[0];
|
||||
|
||||
device[*dn].session_id = 0;
|
||||
device[*dn].serial = 0;
|
||||
device[*dn].serial = -1;
|
||||
device[*dn].bjnp_timeout_sec = 1;
|
||||
device[*dn].bjnp_timeout_msec = 0;
|
||||
device[*dn].scanner_data_left = 0;
|
||||
device[*dn].last_cmd = 0;
|
||||
/* we make a worst case guess on blocksize, will be corrected to max size
|
||||
|
||||
/* we make a pessimistic guess on blocksize, will be corrected to max size
|
||||
* of received block when we read data */
|
||||
|
||||
device[*dn].blocksize = 1024;
|
||||
device[*dn].short_read = 0;
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
return BJNP_STATUS_GOOD;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1159,20 +1230,19 @@ sanei_bjnp_find_devices (const char **conf_devices,
|
|||
{
|
||||
int numbytes = 0;
|
||||
struct BJNP_command cmd;
|
||||
int num_scanners = 0;
|
||||
char resp_buf[2048];
|
||||
int socket_fd[BJNP_SOCK_MAX];
|
||||
int no_sockets;
|
||||
int i;
|
||||
int attempt;
|
||||
int last_socketfd = 0;
|
||||
fd_set fdset;
|
||||
fd_set active_fdset;
|
||||
struct timeval timeout;
|
||||
char hostname[256];
|
||||
char short_hostname[SHORT_HOSTNAME_MAX];
|
||||
char makemodel[BJNP_IEEE1284_MAX];
|
||||
char IEEE1284_id[BJNP_IEEE1284_MAX];
|
||||
char uri[256];
|
||||
int result;
|
||||
int dev_no;
|
||||
char serial[13];
|
||||
#ifdef HAVE_IFADDRS_H
|
||||
|
@ -1184,6 +1254,53 @@ sanei_bjnp_find_devices (const char **conf_devices,
|
|||
#endif
|
||||
|
||||
PDBG (pixma_dbg (LOG_INFO, "sanei_bjnp_find_devices:\n"));
|
||||
first_free_device = 0;
|
||||
|
||||
/* First add devices from config file */
|
||||
|
||||
for (i = 0; conf_devices[i] != NULL; i++)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_DEBUG, "Adding configured scanner: %s\n",
|
||||
conf_devices[i]));
|
||||
|
||||
/* Allocate device structure for scanner and read its model */
|
||||
switch (bjnp_allocate_device (conf_devices[i], &dev_no, hostname))
|
||||
{
|
||||
case BJNP_STATUS_GOOD:
|
||||
if (get_scanner_id (dev_no, makemodel) != 0)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT,
|
||||
"Cannot read scanner make & model: %s\n", uri));
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* inform caller of found scanner
|
||||
*/
|
||||
|
||||
truncate_hostname(hostname, short_hostname);
|
||||
attach_bjnp (conf_devices[i], makemodel,
|
||||
short_hostname, pixma_devices);
|
||||
}
|
||||
break;
|
||||
case BJNP_STATUS_ALREADY_ALLOCATED:
|
||||
PDBG (pixma_dbg
|
||||
(LOG_NOTICE,
|
||||
"Scanner at %s defined in configuration file, but it was added before, good!\n",
|
||||
uri));
|
||||
break;
|
||||
|
||||
case BJNP_STATUS_INVAL:
|
||||
PDBG (pixma_dbg
|
||||
(LOG_NOTICE,
|
||||
"Scanner at %s defined in configuration file, but can not add it\n",
|
||||
uri));
|
||||
break;
|
||||
}
|
||||
}
|
||||
PDBG (pixma_dbg (LOG_DEBUG, "Added all configured scanners, now do auto detection...\n"));
|
||||
|
||||
/*
|
||||
* Send UDP broadcast to discover scanners and return the list of scanners found
|
||||
|
@ -1194,10 +1311,15 @@ sanei_bjnp_find_devices (const char **conf_devices,
|
|||
set_cmd (-1, &cmd, CMD_UDP_DISCOVER, 0);
|
||||
|
||||
#ifdef HAVE_IFADDRS_H
|
||||
no_sockets = 0;
|
||||
getifaddrs (&interfaces);
|
||||
|
||||
/* send MAX_SELECT_ATTEMPTS broadcasts on each suitable interface */
|
||||
for (attempt = 0; attempt < MAX_SELECT_ATTEMPTS; attempt++)
|
||||
{
|
||||
interface = interfaces;
|
||||
|
||||
for (no_sockets = 0; (no_sockets < BJNP_SOCK_MAX) && (interface != NULL);)
|
||||
while ((no_sockets < BJNP_SOCK_MAX) && (interface != NULL))
|
||||
{
|
||||
/* send broadcast packet to each suitable interface */
|
||||
|
||||
|
@ -1221,7 +1343,8 @@ sanei_bjnp_find_devices (const char **conf_devices,
|
|||
|
||||
if ((socket_fd[no_sockets] =
|
||||
bjnp_send_broadcast (((struct sockaddr_in *) interface->
|
||||
ifa_addr)->sin_addr,
|
||||
ifa_addr)->sin_addr,
|
||||
BJNP_PORT_BROADCAST_BASE + attempt,
|
||||
((struct sockaddr_in *) interface->
|
||||
ifa_broadaddr)->sin_addr,
|
||||
cmd, sizeof (cmd))) != -1)
|
||||
|
@ -1238,7 +1361,9 @@ sanei_bjnp_find_devices (const char **conf_devices,
|
|||
}
|
||||
interface = interface->ifa_next;
|
||||
}
|
||||
|
||||
/* wait for some time between broadcast packets */
|
||||
usleep (100 * USLEEP_MS);
|
||||
}
|
||||
freeifaddrs (interfaces);
|
||||
#else
|
||||
/* we have no easy way to find interfaces with their broadcast addresses, use global broadcast */
|
||||
|
@ -1247,24 +1372,29 @@ sanei_bjnp_find_devices (const char **conf_devices,
|
|||
broadcast.s_addr = htonl(INADDR_BROADCAST);
|
||||
local.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if ((socket_fd[no_sockets] =
|
||||
bjnp_send_broadcast (local, broadcast, cmd, sizeof (cmd))) != -1)
|
||||
for (attempt = 0; attempt < MAX_SELECT_ATTEMPTS; attempt++)
|
||||
{
|
||||
if (socket_fd[no_sockets] > last_socketfd)
|
||||
{
|
||||
/* track highest used socket for use in select */
|
||||
if ((socket_fd[no_sockets] =
|
||||
bjnp_send_broadcast (local, BJNP_PORT_BROADCAST_BASE + attempt, broadcast, cmd, sizeof (cmd))) != -1)
|
||||
{
|
||||
if (socket_fd[no_sockets] > last_socketfd)
|
||||
{
|
||||
/* track highest used socket for use in select */
|
||||
|
||||
last_socketfd = socket_fd[no_sockets];
|
||||
}
|
||||
FD_SET (socket_fd[no_sockets], &fdset);
|
||||
no_sockets++;
|
||||
last_socketfd = socket_fd[no_sockets];
|
||||
}
|
||||
FD_SET (socket_fd[no_sockets], &fdset);
|
||||
no_sockets++;
|
||||
}
|
||||
/* wait for some time between broadcast packets */
|
||||
usleep (100 * USLEEP_MS);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* wait for up to 1 second for a UDP response */
|
||||
/* wait for up to 0.5 second for a UDP response */
|
||||
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 500 * USLEEP_MS;
|
||||
|
||||
active_fdset = fdset;
|
||||
|
||||
|
@ -1281,7 +1411,7 @@ sanei_bjnp_find_devices (const char **conf_devices,
|
|||
0)) == -1)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT, "discover_scanners: no data received"));
|
||||
(LOG_CRIT, "bjnp_send_broadcasts: no data received"));
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
@ -1293,7 +1423,7 @@ sanei_bjnp_find_devices (const char **conf_devices,
|
|||
if ((numbytes != sizeof (struct DISCOVER_RESPONSE))
|
||||
|| (strncmp ("BJNP", resp_buf, 4) != 0))
|
||||
{
|
||||
/* scanner not found */
|
||||
/* not a valid response, assume not a scanner */
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -1306,28 +1436,42 @@ sanei_bjnp_find_devices (const char **conf_devices,
|
|||
BJNP_PORT_SCAN);
|
||||
|
||||
/* Test scanner connection by attaching it and reading its IEEE1284 id */
|
||||
if ((result =
|
||||
sanei_bjnp_attach (uri, &dev_no)) != SANE_STATUS_GOOD)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
|
||||
switch (bjnp_allocate_device (uri, &dev_no, NULL))
|
||||
{
|
||||
case BJNP_STATUS_GOOD:
|
||||
if (get_scanner_id (dev_no, makemodel) != 0)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT,
|
||||
"Scanner not added: Cannot read scanner make & model: %s\n", uri));
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* inform caller of found scanner
|
||||
*/
|
||||
|
||||
truncate_hostname(hostname, short_hostname);
|
||||
attach_bjnp (uri, makemodel, short_hostname,
|
||||
pixma_devices);
|
||||
}
|
||||
break;
|
||||
|
||||
case BJNP_STATUS_INVAL:
|
||||
PDBG (pixma_dbg
|
||||
(LOG_NOTICE,
|
||||
"Found scanner at %s, but can not open it\n", uri));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (get_scanner_id (dev_no, makemodel, IEEE1284_id) != 0)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT,
|
||||
"Cannot read scanner make & model: %s\n", uri));
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
/*
|
||||
* inform caller of found scanner
|
||||
*/
|
||||
attach_bjnp (uri, makemodel, serial, pixma_devices);
|
||||
num_scanners++;
|
||||
}
|
||||
break;
|
||||
|
||||
case BJNP_STATUS_ALREADY_ALLOCATED:
|
||||
/* already allocated before, no action required */
|
||||
PDBG (pixma_dbg
|
||||
(LOG_NOTICE,
|
||||
"Scanner at %s detected, but it was added before, good!\n",
|
||||
uri));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
active_fdset = fdset;
|
||||
|
@ -1339,38 +1483,6 @@ sanei_bjnp_find_devices (const char **conf_devices,
|
|||
for (i = 0; i < no_sockets; i++)
|
||||
close (socket_fd[i]);
|
||||
|
||||
/* add pre-configured devices */
|
||||
|
||||
for (i = 0; conf_devices[i] != NULL; i++)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_DEBUG, "Adding pre-configured scanner: %s\n",
|
||||
conf_devices[i]));
|
||||
|
||||
/* Test scanner connection by attaching it and reading its IEEE1284 id */
|
||||
if ((result = sanei_bjnp_attach (conf_devices[i], &dev_no)) != SANE_STATUS_GOOD)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_NOTICE,
|
||||
"Scanner at %s defined in configuration file, but can not open it\n",
|
||||
uri));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (get_scanner_id (dev_no, makemodel, IEEE1284_id) != 0)
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_CRIT,
|
||||
"Cannot read scanner make & model: %s\n", uri));
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
/*
|
||||
* inform caller of found scanner
|
||||
*/
|
||||
attach_bjnp (conf_devices[i], makemodel, serial, pixma_devices);
|
||||
num_scanners++;
|
||||
}
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
|
@ -1400,21 +1512,20 @@ extern SANE_Status
|
|||
sanei_bjnp_open (SANE_String_Const devname, SANE_Int * dn)
|
||||
{
|
||||
char pid_str[64];
|
||||
char hostname[256];
|
||||
char my_hostname[256];
|
||||
char *login;
|
||||
|
||||
PDBG (pixma_dbg (LOG_INFO, "sanei_bjnp_open(%s, %d):\n", devname, *dn));
|
||||
|
||||
/* TODO: check result of sanei_bjnp_attach! */
|
||||
|
||||
sanei_bjnp_attach (devname, dn);
|
||||
if (bjnp_allocate_device (devname, dn, NULL) == BJNP_STATUS_INVAL)
|
||||
return SANE_STATUS_INVAL;
|
||||
|
||||
login = getusername ();
|
||||
gethostname (hostname, 256);
|
||||
hostname[255] = '\0';
|
||||
gethostname (my_hostname, 256);
|
||||
my_hostname[255] = '\0';
|
||||
sprintf (pid_str, "Process ID = %d", getpid ());
|
||||
|
||||
bjnp_send_job_details (*dn, hostname, login, pid_str);
|
||||
bjnp_send_job_details (*dn, my_hostname, login, pid_str);
|
||||
|
||||
if (bjnp_open_tcp (*dn) != 0)
|
||||
return SANE_STATUS_INVAL;
|
||||
|
@ -1484,12 +1595,17 @@ SANE_Status sanei_bjnp_deactivate(SANE_Int dn)
|
|||
extern void
|
||||
sanei_bjnp_set_timeout (SANE_Int devno, SANE_Int timeout)
|
||||
{
|
||||
/* timeout must be at least 1 second */
|
||||
if (timeout < 1000)
|
||||
timeout = 1000;
|
||||
PDBG (pixma_dbg (LOG_INFO, "bjnp_set_timeout(%d):\n", timeout));
|
||||
device[devno].bjnp_timeout_sec = timeout / 1000;
|
||||
device[devno].bjnp_timeout_msec = timeout % 1000;
|
||||
int my_timeout = timeout;
|
||||
|
||||
/* timeout must be at least 10 second */
|
||||
|
||||
if (my_timeout < 10000)
|
||||
my_timeout = 10000;
|
||||
PDBG (pixma_dbg (LOG_INFO, "bjnp_set_timeout(requested %d, set %d):\n",
|
||||
timeout, my_timeout));
|
||||
|
||||
device[devno].bjnp_timeout_sec = my_timeout / 1000;
|
||||
device[devno].bjnp_timeout_msec = my_timeout % 1000;
|
||||
}
|
||||
|
||||
/** Initiate a bulk transfer read.
|
||||
|
@ -1509,8 +1625,6 @@ sanei_bjnp_set_timeout (SANE_Int devno, SANE_Int timeout)
|
|||
*
|
||||
*/
|
||||
|
||||
#define USLEEP_MS 1000
|
||||
|
||||
extern SANE_Status
|
||||
sanei_bjnp_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)
|
||||
{
|
||||
|
@ -1521,25 +1635,39 @@ sanei_bjnp_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)
|
|||
size_t left;
|
||||
|
||||
PDBG (pixma_dbg
|
||||
(LOG_INFO, "bjnp_read_bulk(%d, bufferptr, %lx)\n", dn, (long) *size));
|
||||
(LOG_DEBUG, "bjnp_read_bulk(%d, bufferptr, 0x%lx = %ld)\n", dn,
|
||||
(long) *size, (long) size));
|
||||
|
||||
recvd = 0;
|
||||
left = *size;
|
||||
|
||||
if (!device[dn].scanner_data_left)
|
||||
device[dn].short_read = 0;
|
||||
if ((device[dn].scanner_data_left == 0) && (device[dn].short_read != 0))
|
||||
{
|
||||
/* new read, but we have no data queued from scanner, last read was short, */
|
||||
/* so scanner needs first a high level read command. This is not an error */
|
||||
|
||||
PDBG (pixma_dbg
|
||||
(LOG_DEBUG, "Scanner has no more data available, return immediately!\n"));
|
||||
*size = 0;
|
||||
return SANE_STATUS_EOF;
|
||||
}
|
||||
|
||||
PDBG (pixma_dbg
|
||||
(LOG_DEBUG, "bjnp_read_bulk: %lx bytes available at start\n",
|
||||
(long) device[dn].scanner_data_left));
|
||||
(LOG_DEBUG, "bjnp_read_bulk: 0x%lx = %ld bytes available at start, "
|
||||
"Short block = %d blocksize = 0x%lx = %ld\n",
|
||||
(long) device[dn].scanner_data_left,
|
||||
(long) device[dn].scanner_data_left,
|
||||
(int) device[dn].short_read,
|
||||
(long) device[dn].blocksize,
|
||||
(long) device[dn].blocksize));
|
||||
|
||||
while ((recvd < *size)
|
||||
&& (!device[dn].short_read || device[dn].scanner_data_left))
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(LOG_DEBUG,
|
||||
"So far received %lx bytes, need %lx\n",
|
||||
(long) recvd, (long) *size));
|
||||
"So far received 0x%lx bytes = %ld, need 0x%lx = %ld\n",
|
||||
(long) recvd, (long) recvd, (long) *size, (long) *size));
|
||||
|
||||
if (device[dn].scanner_data_left == 0)
|
||||
{
|
||||
|
@ -1552,12 +1680,19 @@ sanei_bjnp_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)
|
|||
(LOG_DEBUG, "No (more) scanner data available, requesting more\n"));
|
||||
|
||||
if ((error = bjnp_send_read_request (dn)) != SANE_STATUS_GOOD)
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
{
|
||||
*size = recvd;
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
if ((error = bjnp_recv_header (dn)) != SANE_STATUS_GOOD)
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
|
||||
{
|
||||
*size = recvd;
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
PDBG (pixma_dbg
|
||||
(LOG_DEBUG, "Scanner reports %lx bytes available\n", (long) device[dn].scanner_data_left));
|
||||
(LOG_DEBUG, "Scanner reports 0x%lx = %ld bytes available\n",
|
||||
(long) device[dn].scanner_data_left,
|
||||
(long) device[dn].scanner_data_left));
|
||||
|
||||
/* correct blocksize if more data is sent by scanner than current blocksize assumption */
|
||||
|
||||
|
@ -1572,8 +1707,10 @@ sanei_bjnp_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)
|
|||
|
||||
more = left;
|
||||
|
||||
PDBG (pixma_dbg (LOG_DEBUG, "reading %lx (of %ld) bytes more\n",
|
||||
(long) more, device[dn].scanner_data_left));
|
||||
PDBG (pixma_dbg (LOG_DEBUG, "reading 0x%lx = %ld (of max 0x%lx = %ld) bytes more\n",
|
||||
device[dn].scanner_data_left,
|
||||
device[dn].scanner_data_left,
|
||||
(long) more, (long) more ));
|
||||
result = bjnp_recv_data (dn, buffer, &more);
|
||||
if (result != SANE_STATUS_GOOD)
|
||||
{
|
||||
|
@ -1612,7 +1749,8 @@ sanei_bjnp_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size)
|
|||
uint32_t buf;
|
||||
|
||||
PDBG (pixma_dbg
|
||||
(LOG_INFO, "bjnp_write_bulk(%d, bufferptr, %d):\n", dn, (int) *size));
|
||||
(LOG_INFO, "bjnp_write_bulk(%d, bufferptr, 0x%lx = %ld)\n", dn,
|
||||
(long) *size, (long)*size));
|
||||
sent = bjnp_write (dn, buffer, *size);
|
||||
if (sent < 0)
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
|
@ -1632,7 +1770,8 @@ sanei_bjnp_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size)
|
|||
if (device[dn].scanner_data_left != 4)
|
||||
{
|
||||
PDBG(pixma_dbg (LOG_CRIT,
|
||||
"Scanner length of write confirmation = %ld bytes, expected %d!!\n",
|
||||
"Scanner length of write confirmation = 0x%lx bytes = %ld, expected %d!!\n",
|
||||
(long) device[dn].scanner_data_left,
|
||||
(long) device[dn].scanner_data_left, 4));
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
@ -1651,6 +1790,11 @@ sanei_bjnp_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size)
|
|||
(long) recvd, (long) *size));
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
/* we sent a new command, so reset end of block indication */
|
||||
|
||||
device[dn].short_read = 0;
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
|
@ -1676,7 +1820,9 @@ sanei_bjnp_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size)
|
|||
{
|
||||
#ifndef PIXMA_BJNP_STATUS
|
||||
PDBG (pixma_dbg
|
||||
(LOG_INFO, "bjnp_read_int(%d, bufferptr, %d):\n", dn, (int) *size));
|
||||
(LOG_INFO, "bjnp_read_int(%d, bufferptr, 0x%lx = %ld):\n", dn,
|
||||
(long) *size,
|
||||
(long) *size));
|
||||
memset (buffer, 0, *size);
|
||||
sleep (1);
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
|
@ -1686,7 +1832,8 @@ sanei_bjnp_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size)
|
|||
int i;
|
||||
|
||||
PDBG (pixma_dbg
|
||||
(LOG_INFO, "bjnp_read_int(%d, bufferptr, %d):\n", dn, (int) *size));
|
||||
(LOG_INFO, "bjnp_read_int(%d, bufferptr, %lx = %ld):\n", dn,
|
||||
(long) *size, (long) *size));
|
||||
|
||||
gethostname (hostname, 32);
|
||||
hostname[32] = '\0';
|
||||
|
|
|
@ -66,13 +66,17 @@ extern void sanei_bjnp_init (void);
|
|||
/** Find scanners responding to a BJNP broadcast.
|
||||
*
|
||||
* The function attach is called for every device which has been found.
|
||||
*
|
||||
* Serial is the address of the pinter in himan readable form of max
|
||||
* SHORT_HOSTNAME_MAX characters
|
||||
* @param conf_devices lsit of pre-configures device URI's to attach
|
||||
* @param attach attach function
|
||||
* @param pixma_devices device informatio needed by attach function
|
||||
*
|
||||
* @return SANE_STATUS_GOOD - on success (even if no scanner was found)
|
||||
*/
|
||||
|
||||
#define SHORT_HOSTNAME_MAX 16
|
||||
|
||||
extern SANE_Status
|
||||
sanei_bjnp_find_devices (const char **conf_devices,
|
||||
SANE_Status (*attach_bjnp)
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#define BJNP_NO_DEVICES 16 /* max number of open devices */
|
||||
#define SCAN_BUF_MAX 65536 /* size of scanner data intermediate buffer */
|
||||
#define MAX_SELECT_ATTEMPTS 5 /* max nr of retries on select (EINTR) */
|
||||
#define USLEEP_MS 1000 /* sleep for 1 msec */
|
||||
|
||||
/* Do not yet use this, it does not work */
|
||||
/* #define PIXMA_BJNP_STATUS 1 */
|
||||
|
@ -85,6 +86,7 @@
|
|||
/* port numbers */
|
||||
typedef enum bjnp_port_e
|
||||
{
|
||||
BJNP_PORT_BROADCAST_BASE = 8610,
|
||||
BJNP_PORT_PRINT = 8611,
|
||||
BJNP_PORT_SCAN = 8612,
|
||||
BJNP_PORT_3 = 8613,
|
||||
|
@ -123,7 +125,8 @@ struct BJNP_command
|
|||
char BJNP_id[4]; /* string: BJNP */
|
||||
uint8_t dev_type; /* 1 = printer, 2 = scanner */
|
||||
uint8_t cmd_code; /* command code/response code */
|
||||
uint32_t seq_no; /* sequence number */
|
||||
int16_t unknown1; /* unknown, always 0? */
|
||||
int16_t seq_no; /* sequence number */
|
||||
uint16_t session_id; /* session id for printing */
|
||||
uint32_t payload_len; /* length of command buffer */
|
||||
} __attribute__ ((__packed__));
|
||||
|
@ -199,6 +202,13 @@ typedef enum bjnp_paper_status_e
|
|||
BJNP_PAPER_OUT = 1
|
||||
} bjnp_paper_status_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BJNP_STATUS_GOOD,
|
||||
BJNP_STATUS_INVAL,
|
||||
BJNP_STATUS_ALREADY_ALLOCATED
|
||||
} BJNP_Status;
|
||||
|
||||
/*
|
||||
* Device information for opened devices
|
||||
*/
|
||||
|
@ -210,7 +220,7 @@ typedef struct device_s
|
|||
int fd; /* file descriptor */
|
||||
struct sockaddr_in addr;
|
||||
int session_id; /* session id used in bjnp protocol for TCP packets */
|
||||
uint32_t serial; /* sequence number of command */
|
||||
int16_t serial; /* sequence number of command */
|
||||
int bjnp_timeout_sec; /* timeout (seconds) for next command */
|
||||
int bjnp_timeout_msec; /* timeout (msec) for next command */
|
||||
size_t scanner_data_left; /* TCP data left from last read request */
|
||||
|
|
|
@ -164,7 +164,7 @@ attach_bjnp (SANE_String_Const devname, SANE_String_Const makemodel,
|
|||
if ((cfg = lookup_scanner(makemodel, pixma_devices)) == (struct pixma_config_t *)NULL)
|
||||
return SANE_STATUS_INVAL;
|
||||
si->cfg = cfg;
|
||||
sprintf(si->serial, "%04x%04x_%s", (unsigned int) cfg->vid, (unsigned int) cfg->pid, serial);
|
||||
sprintf(si->serial, "%s_%s", cfg->model, serial);
|
||||
si -> interface = INT_BJNP;
|
||||
si->next = first_scanner;
|
||||
first_scanner = si;
|
||||
|
|
Ładowanie…
Reference in New Issue