• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *	SANE backend for
3  *		Samsung SCX-4500W
4  *
5  *	Network Scanners Support
6  *	Copyright 2010 Alexander Kuznetsov <acca(at)cpan.org>
7  *
8  * This program is licensed under GPL + SANE exception.
9  * More info at http://www.sane-project.org/license.html
10  *
11  */
12 
13 #undef	BACKEND_NAME
14 #define	BACKEND_NAME xerox_mfp
15 #define DEBUG_DECLARE_ONLY
16 #define DEBUG_NOT_STATIC
17 
18 #include "sane/config.h"
19 
20 
21 #include <limits.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <ctype.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <errno.h>
29 #include <sys/time.h>
30 #include <sys/types.h>
31 #ifdef HAVE_SYS_SOCKET_H
32 #include <sys/socket.h>
33 #endif
34 
35 #include "sane/saneopts.h"
36 #include "sane/sanei_scsi.h"
37 #include "sane/sanei_usb.h"
38 #include "sane/sanei_pio.h"
39 #include "sane/sanei_tcp.h"
40 #include "sane/sanei_udp.h"
41 #include "sane/sanei_backend.h"
42 #include "sane/sanei_config.h"
43 
44 #include "xerox_mfp.h"
45 
46 
47 #define	RECV_TIMEOUT	1	/*	seconds		*/
48 extern int sanei_debug_xerox_mfp;
49 
tcp_dev_request(struct device * dev,SANE_Byte * cmd,size_t cmdlen,SANE_Byte * resp,size_t * resplen)50 int	tcp_dev_request(struct device *dev,
51                     SANE_Byte *cmd, size_t cmdlen,
52                     SANE_Byte *resp, size_t *resplen)
53 {
54     size_t	bytes_recv = 0;
55     ssize_t	rc = 1;
56     size_t	len;
57 
58 
59     /* Send request, if any */
60     if (cmd && cmdlen) {
61         len = (size_t)sanei_tcp_write(dev->dn, cmd, cmdlen);
62         if (len != cmdlen) {
63             DBG(1, "%s: sent only %lu bytes of %lu\n",
64                 __func__, (u_long)len, (u_long)cmdlen);
65             return SANE_STATUS_IO_ERROR;
66         }
67     }
68 
69     /* Receive response, if expected */
70     if (resp && resplen) {
71         DBG(3, "%s: wait for %i bytes\n", __func__, (int)*resplen);
72 
73         while (bytes_recv < *resplen && rc > 0) {
74             rc = recv(dev->dn, resp+bytes_recv, *resplen-bytes_recv, 0);
75 
76             if (rc > 0)	bytes_recv += rc;
77             else {
78                 DBG(1, "%s: error %s, bytes requested: %i, bytes read: %i\n",
79                     __func__, strerror(errno), (int)*resplen, (int)bytes_recv);
80                 *resplen = bytes_recv;
81                 /*
82                     TODO:
83                 	do something smarter than that!
84                 */
85                 return SANE_STATUS_GOOD;
86                 return SANE_STATUS_IO_ERROR;
87             }
88         }
89     }
90 
91     *resplen = bytes_recv;
92 
93     return SANE_STATUS_GOOD;
94 }
95 
tcp_dev_open(struct device * dev)96 SANE_Status	tcp_dev_open(struct device *dev)
97 {
98     SANE_Status 	status;
99     char		*strhost;
100     char		*strport;
101     int			port;
102     struct		servent *sp;
103     struct		timeval tv;
104     SANE_String_Const	devname;
105 
106 
107     devname = dev->sane.name;
108     DBG(3, "%s: open %s\n", __func__, devname);
109 
110     if (strncmp(devname, "tcp", 3) != 0)	return SANE_STATUS_INVAL;
111     devname += 3;
112     devname = sanei_config_skip_whitespace(devname);
113     if (!*devname)	return SANE_STATUS_INVAL;
114 
115     devname = sanei_config_get_string(devname, &strhost);
116     devname = sanei_config_skip_whitespace(devname);
117 
118     if (*devname)
119         devname = sanei_config_get_string(devname, &strport);
120     else
121         strport = "9400";
122 
123 
124     if (isdigit(*strport)) {
125         port = atoi(strport);
126     } else {
127         if ((sp = getservbyname(strport, "tcp"))) {
128             port = ntohs(sp->s_port);
129         } else {
130             DBG(1, "%s: unknown TCP service %s\n", __func__, strport);
131             return SANE_STATUS_IO_ERROR;
132         }
133     }
134 
135     status = sanei_tcp_open(strhost, port, &dev->dn);
136     if (status == SANE_STATUS_GOOD) {
137         tv.tv_sec  = RECV_TIMEOUT;
138         tv.tv_usec = 0;
139         if (setsockopt(dev->dn, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv) < 0) {
140             DBG(1, "%s: setsockopts %s", __func__, strerror(errno));
141         }
142     }
143 
144     return status;
145 }
146 
147 void
tcp_dev_close(struct device * dev)148 tcp_dev_close(struct device *dev)
149 {
150     if (!dev)	return;
151 
152     DBG(3, "%s: closing dev %p\n", __func__, (void *)dev);
153 
154     /* finish all operations */
155     if (dev->scanning) {
156         dev->cancel = 1;
157         /* flush READ_IMAGE data */
158         if (dev->reading)	sane_read(dev, NULL, 1, NULL);
159         /* send cancel if not sent before */
160         if (dev->state != SANE_STATUS_CANCELLED)
161             ret_cancel(dev, 0);
162     }
163 
164     sanei_tcp_close(dev->dn);
165     dev->dn = -1;
166 }
167 
168 
169 SANE_Status
tcp_configure_device(const char * devname,SANE_Status (* list_one)(SANE_String_Const devname))170 tcp_configure_device(const char *devname, SANE_Status(*list_one)(SANE_String_Const devname))
171 {
172     /*
173         TODO:	LAN scanners multicast discovery.
174     		devname would contain "tcp auto"
175 
176     		We find new devnames and feed them to
177     		`list_one_device' one by one
178     */
179     return list_one(devname);
180 }
181 
182 /* xerox_mfp-tcp.c */
183