• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SANE - Scanner Access Now Easy.
2 
3    Copyright (C) 2008 by Louis Lagendijk
4 
5    This file is part of the SANE package.
6 
7    Data structures and definitions for
8    bjnp backend for the Common UNIX Printing System (CUPS).
9 
10    These coded instructions, statements, and computer programs are the
11    property of Louis Lagendijk and are protected by Federal copyright
12    law.  Distribution and use rights are outlined in the file "LICENSE.txt"
13    "LICENSE" which should have been included with this file.  If this
14    file is missing or damaged, see the license at "http://www.cups.org/".
15 
16    This file is subject to the Apple OS-Developed Software exception.
17 
18    SANE is free software; you can redistribute it and/or modify it
19    under the terms of the GNU General Public License as published by
20    the Free Software Foundation; either version 2 of the License, or
21    (at your option) any later version.
22 
23    SANE is distributed in the hope that it will be useful, but WITHOUT
24    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
26    License for more details.
27 
28    You should have received a copy of the GNU General Public License
29    along with sane; see the file COPYING.
30    If not, see <https://www.gnu.org/licenses/>.
31 
32    As a special exception, the authors of SANE give permission for
33    additional uses of the libraries contained in this release of SANE.
34 
35    The exception is that, if you link a SANE library with other files
36    to produce an executable, this does not by itself cause the
37    resulting executable to be covered by the GNU General Public
38    License.  Your use of that executable is in no way restricted on
39    account of linking the SANE library code into it.
40 
41    This exception does not, however, invalidate any other reasons why
42    the executable file might be covered by the GNU General Public
43    License.
44 
45    If you submit changes to SANE to the maintainers to be included in
46    a subsequent release, you agree by submitting the changes that
47    those changes may be distributed with this exception intact.
48 
49    If you write modifications of your own for SANE, it is your choice
50    whether to permit this exception to apply to your modifications.
51    If you do not wish that, delete this exception notice.
52 */
53 
54 /*
55  *  BJNP definitions
56  */
57 
58 /* selection of options */
59 /* This works now, disable when it gives you problems */
60 #define PIXMA_BJNP_USE_STATUS 1
61 
62 /* sizes */
63 
64 #define BJNP_PRINTBUF_MAX 1400		/* size of printbuffer */
65 #define BJNP_CMD_MAX 2048		/* size of BJNP response buffer */
66 #define BJNP_RESP_MAX 2048		/* size of BJNP response buffer */
67 #define BJNP_SOCK_MAX 256		/* maximum number of open sockets */
68 #define BJNP_MODEL_MAX 64		/* max allowed size for make&model */
69 #define BJNP_STATUS_MAX 256		/* max size for status string */
70 #define BJNP_IEEE1284_MAX 1024		/* max. allowed size of IEEE1284 id */
71 #define BJNP_METHOD_MAX 16		/* max length of method */
72 #define BJNP_HOST_MAX 128       	/* max length of hostname or address */
73 #define BJNP_PORT_MAX 64		/* max length of port string */
74 #define BJNP_ARGS_MAX 128		/* max length of argument string */
75 #define BJNP_SERIAL_MAX 16		/* maximum length of serial number */
76 #define BJNP_NO_DEVICES 16		/* max number of open devices */
77 #define BJNP_SCAN_BUF_MAX 65536		/* size of scanner data intermediate buffer */
78 #define BJNP_BLOCKSIZE_START 512	/* startsize for last block detection */
79 
80 /* timers */
81 #define BJNP_BROADCAST_INTERVAL 10 	/* ms between broadcasts */
82 #define BJNP_BC_RESPONSE_TIMEOUT 500  	/* waiting time for broadc. responses */
83 #define BJNP_TIMEOUT_DEFAULT 10000	/* minimum timeout value for network operations */
84 #define BJNP_TIMEOUT_TCP_CONNECT 2000   /* timeout for tcp connect attempts in ms */
85 #define BJNP_USLEEP_MS 1000          	/* sleep for 1 msec */
86 #define BJNP_TCP_CONNECT_INTERVAL 100   /* TCP retry interval in ms */
87 
88 /* retries */
89 #define BJNP_MAX_SELECT_ATTEMPTS 3   	/* max nr of retries on select (EINTR) */
90 #define BJNP_MAX_BROADCAST_ATTEMPTS 2	/* number of broadcast packets to be sent */
91 #define BJNP_UDP_RETRY_MAX 3		/* max nt of retries on a udp command */
92 
93 #define bjnp_dbg DBG
94 #include "../include/sane/sanei_debug.h"
95 
96 /* loglevel definitions */
97 
98 #define LOG_CRIT 0
99 #define LOG_NOTICE 1
100 #define LOG_INFO 2
101 #define LOG_DEBUG 3
102 #define LOG_DEBUG2 4
103 #define LOG_DEBUG3 5
104 
105 #define BJNP_RESTART_POLL -1
106 
107 /*************************************/
108 /* BJNP protocol related definitions */
109 /*************************************/
110 
111 /* port numbers */
112 typedef enum bjnp_port_e
113 {
114   MFNP_PORT_SCAN = 8610,
115   BJNP_PORT_PRINT = 8611,
116   BJNP_PORT_SCAN = 8612,
117   BJNP_PORT_3 = 8613,
118   BJNP_PORT_4 = 8614
119 } bjnp_port_t;
120 
121 typedef enum
122 {
123   PROTOCOL_BJNP = 0,
124   PROTOCOL_MFNP = 1,
125   PROTOCOL_NONE =2
126 } bjnp_protocol_t;
127 
128 typedef struct
129 {
130   bjnp_protocol_t protocol_version;
131   int default_port;
132   char * proto_string;
133   char * method_string;
134   int single_tcp_session;
135 } bjnp_protocol_defs_t;
136 
137 bjnp_protocol_defs_t bjnp_protocol_defs[] =
138 {
139   {PROTOCOL_BJNP, BJNP_PORT_SCAN,"BJNP", "bjnp", SANE_FALSE},
140   {PROTOCOL_MFNP, MFNP_PORT_SCAN,"MFNP", "mfnp", SANE_TRUE},
141   {PROTOCOL_NONE, -1, NULL, NULL, SANE_FALSE}
142 };
143 
144 /* commands */
145 typedef enum bjnp_cmd_e
146 {
147   CMD_UDP_DISCOVER = 0x01,	/* discover if service type is listening at this port */
148   CMD_UDP_START_SCAN = 0x02,	/* start scan pressed, sent from scanner to 224.0.0.1 */
149   CMD_UDP_JOB_DETAILS = 0x10,	/* send print/ scanner job owner details */
150   CMD_UDP_CLOSE = 0x11,		/* request connection closure */
151   CMD_UDP_GET_STATUS = 0x20,	/* get printer status  */
152   CMD_TCP_REQ = 0x20,		/* read data from device */
153   CMD_TCP_SEND = 0x21,		/* send data to device */
154   CMD_UDP_GET_ID = 0x30,	/* get printer identity */
155   CMD_UDP_POLL = 0x32		/* poll scanner for button status */
156 } bjnp_cmd_t;
157 
158 /* command type */
159 
160 typedef enum uint8_t
161 {
162   BJNP_CMD_PRINT = 0x1,		/* printer command */
163   BJNP_CMD_SCAN = 0x2,		/* scanner command */
164   BJNP_RES_PRINT = 0x81,	/* printer response */
165   BJNP_RES_SCAN = 0x82		/* scanner response */
166 } bjnp_cmd_type_t;
167 
168 /***************************/
169 /* BJNP protocol structure */
170 /***************************/
171 
172 /* The common protocol header */
173 
174 struct  __attribute__ ((__packed__)) BJNP_command
175 {
176   char BJNP_id[4];		/* string: BJNP */
177   uint8_t dev_type;		/* 1 = printer, 2 = scanner */
178                                 /* responses have MSB set */
179   uint8_t cmd_code;		/* command code/response code */
180   int16_t unknown1;		/* unknown, always 0? */
181   int16_t seq_no;		/* sequence number */
182   uint16_t session_id;		/* session id for printing */
183   uint32_t payload_len;		/* length of command buffer */
184 };
185 
186 /* Layout of the init response buffer */
187 
188 struct  __attribute__ ((__packed__)) DISCOVER_RESPONSE
189 {
190   struct BJNP_command response;	/* response header */
191   char unknown1[4];		/* 00 01 08 00 */
192   char mac_len;			/* length of mac address */
193   char addr_len;		/* length of address field */
194   unsigned char mac_addr[6];	/* printers mac address */
195   union  {
196     struct __attribute__ ((__packed__)) {
197        unsigned char ipv4_addr[4];
198      } ipv4;
199      struct  __attribute__ ((__packed__)) {
200        unsigned char ipv6_addr_1[16];
201        unsigned char ipv6_addr_2[16];
202      } ipv6;
203   } addresses;
204 };
205 
206 /* layout of payload for the JOB_DETAILS command */
207 
208 struct  __attribute__ ((__packed__)) JOB_DETAILS
209 {
210   struct BJNP_command cmd;	/* command header */
211   char unknown[8];		/* don't know what these are for */
212   char hostname[64];		/* hostname of sender */
213   char username[64];		/* username */
214   char jobtitle[256];		/* job title */
215 };
216 
217 /* layout of the poll command, not everything is complete */
218 
219 struct  __attribute__ ((__packed__)) POLL_DETAILS
220 {
221   struct BJNP_command cmd;      /* command header */
222   uint16_t type;                /* 0, 1, 2 or 5 */
223                                 /* 05 = reset status */
224   union {
225     struct  __attribute__ ((__packed__)) {
226 	char empty0[78];	/* type 0 has only 0 */
227       } type0;			/* length = 80 */
228 
229     struct __attribute__ ((__packed__)) {
230       char empty1[6];		/* 0 */
231       char user_host[64];       /* unicode user <space> <space> hostname */
232       uint64_t emtpy2;		/* 0 */
233     } type1;			/* length = 80 */
234 
235     struct __attribute__ ((__packed__)) {
236       uint16_t empty_1;         /* 00 00 */
237       uint32_t dialog;          /* constant dialog id, from previous response */
238       char user_host[64];       /* unicode user <space> <space> hostname */
239       uint32_t unknown_1;	/* 00 00 00 14 */
240       uint32_t empty_2[5];      /* only 0 */
241       uint32_t unknown_2;	/* 00 00 00 10 */
242       char ascii_date[16];      /* YYYYMMDDHHMMSS  only for type 2 */
243     } type2;			/* length = 116 */
244 
245     struct __attribute__ ((__packed__)) {
246       uint16_t empty_1;         /* 00 00 */
247       uint32_t dialog;          /* constant dialog id, from previous response */
248       char user_host[64];       /* unicode user <space> <space> hostname */
249       uint32_t unknown_1;	/* 00 00 00 14 */
250       uint32_t key;		/* copied from key field in status msg */
251       uint32_t unknown_3[5];    /* only 0 */
252     } type5;			/* length = 100 */
253 
254   } extensions;
255 };
256 
257 /* the poll response layout */
258 
259 struct  __attribute__ ((__packed__)) POLL_RESPONSE
260 {
261   struct BJNP_command cmd;	/* command header */
262 
263   unsigned char result[4];	/* unknown stuff, result[2] = 80 -> status is available*/
264                                 /* result[8] is dialog, size? */
265   uint32_t dialog;		/* to be returned in next request */
266   uint32_t unknown_2;		/* returns the 00 00 00 14 from unknown_2 in request */
267   uint32_t key;			/* to be returned in type 5 status reset */
268   unsigned char status[20];	/* interrupt status */
269 };
270 
271 /* Layout of ID and status responses */
272 
273 struct  __attribute__ ((__packed__)) IDENTITY
274 {
275   struct BJNP_command cmd;
276   union  __attribute__ ((__packed__))
277     {
278       struct __attribute__ ((__packed__)) payload_s
279         {
280           uint16_t id_len;		/* length of identity */
281           char id[BJNP_IEEE1284_MAX];	/* identity */
282         } bjnp;
283       struct __attribute__ ((__packed__)) mfnp
284         {
285           char id[BJNP_IEEE1284_MAX];
286          } mfnp;
287     } payload;
288 };
289 
290 
291 /* response to TCP print command */
292 
293 struct  __attribute__ ((__packed__)) SCAN_BUF
294 {
295   struct BJNP_command cmd;
296   char scan_data[65536];
297 };
298 
299 /**************************/
300 /* Local enum definitions */
301 /**************************/
302 
303 typedef enum bjnp_paper_status_e
304 {
305   BJNP_PAPER_UNKNOWN = -1,
306   BJNP_PAPER_OK = 0,
307   BJNP_PAPER_OUT = 1
308 } bjnp_paper_status_t;
309 
310 typedef enum
311 {
312   BJNP_STATUS_GOOD,
313   BJNP_STATUS_INVAL,
314   BJNP_STATUS_ALREADY_ALLOCATED
315 } BJNP_Status;
316 
317 /* button polling */
318 
319 typedef enum
320 {
321   BJNP_POLL_STOPPED = 0,
322   BJNP_POLL_STARTED = 1,
323   BJNP_POLL_STATUS_RECEIVED = 2
324 } BJNP_polling_status_e;
325 
326 typedef union
327 {
328   struct sockaddr_storage storage;
329   struct sockaddr addr;
330   struct sockaddr_in ipv4;
331   struct sockaddr_in6 ipv6;
332 } bjnp_sockaddr_t;
333 
334 typedef enum
335 {
336   BJNP_ADDRESS_IS_LINK_LOCAL = 0,
337   BJNP_ADDRESS_IS_GLOBAL = 1,
338   BJNP_ADDRESS_HAS_FQDN = 2
339 } bjnp_address_type_t;
340 
341 
342 /*
343  * Device information for opened devices
344  */
345 
346 typedef struct device_s
347 {
348   int open;			/* connection to scanner is opened */
349 
350   /* protocol information */
351   int protocol;
352   char *protocol_string;
353   char single_tcp_session;
354 
355   /* sockets */
356 
357   int tcp_socket;		/* open tcp socket for communication to scannner */
358   int16_t serial;		/* sequence number of command */
359 
360   /* communication state */
361 
362   int session_id;		/* session id used in bjnp protocol for TCP packets */
363   int last_cmd;			/* last command sent */
364 
365   /* TCP bulk read state information */
366 
367   size_t blocksize;		/* size of (TCP) blocks returned by the scanner */
368   size_t scanner_data_left;	/* TCP data left from last read request */
369   char last_block;		/* last TCP read command was shorter than blocksize */
370 
371   /* device information */
372   char mac_address[BJNP_HOST_MAX];
373  		 		/* mac-address, used as device serial no */
374   bjnp_sockaddr_t * addr;	/* ip-address of the scanner */
375   int address_level;		/* link local, public or has a FQDN */
376   int bjnp_scanner_timeout;	/* timeout (msec) for next poll command */
377   int bjnp_ip_timeout;		/* device specific min timeout for the IP-protocol */
378 
379 #ifdef PIXMA_BJNP_USE_STATUS
380   /* polling state information */
381 
382   char polling_status;		/* status polling ongoing */
383   uint32_t dialog;		/* poll dialog */
384   uint32_t status_key;		/* key of last received status message */
385 #endif
386 } bjnp_device_t;
387