1 /*
2  * epsonds-cmd.c - Epson ESC/I-2 routines.
3  *
4  * Copyright (C) 2015 Tower Technologies
5  * Author: Alessandro Zummo <a.zummo@towertech.it>
6  *
7  * This file is part of the SANE package.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation, version 2.
12  */
13 
14 #define DEBUG_DECLARE_ONLY
15 
16 #include "sane/config.h"
17 #include <ctype.h>
18 #include <unistd.h>	     /* sleep */
19 
20 #include "epsonds.h"
21 #include "epsonds-io.h"
22 #include "epsonds-cmd.h"
23 #include "epsonds-ops.h"
24 #include "epsonds-net.h"
25 
26 static SANE_Status
esci2_parse_block(char *buf, int len, void *userdata, SANE_Status (*cb)(void *userdata, char *token, int len))27 esci2_parse_block(char *buf, int len, void *userdata, SANE_Status (*cb)(void *userdata, char *token, int len))
28 {
29 	SANE_Status status = SANE_STATUS_GOOD;
30 	SANE_Status delayed_status = SANE_STATUS_GOOD;
31 
32 
33 	char *start = buf;
34 	char *end = (buf + len) - 1;
35 
36 	/* 0  : #
37 	 * 1-3: param
38 	 * 4- : data
39 	*/
40 
41 	while (1) {
42 
43 		char param[4];
44 
45 		while (*start != '#' && start < end)
46 			start++;
47 
48 		if (*start != '#')
49 			break;
50 
51 		param[0] = *++start;
52 		param[1] = *++start;
53 		param[2] = *++start;
54 		param[3] = '\0';
55 
56 		if (strncmp("---", param, 3) == 0)
57 			break;
58 
59 		/* ugly hack to skip over GMT in RESA */
60 		if (strncmp("GMT", param, 3) == 0 && *(start + 5) == 'h') {
61 			start = start + 4 + 0x100;
62 			continue;
63 		}
64 
65 		/* find the end of the token */
66 		{
67 			int tlen;
68 			char *next = start;
69 
70 			while (*next != '#' && *next != 0x00 && next < end)
71 				next++;
72 
73 			tlen = next - start - 1;
74 
75 			if (cb) {
76 				status = cb(userdata, start - 2, tlen);
77 				if (status != SANE_STATUS_GOOD) {
78 					delayed_status = status;
79 				}
80 			}
81 
82 			start = next;
83 		}
84 	}
85 
86 	if (delayed_status != SANE_STATUS_GOOD)
87 		return delayed_status;
88 
89 	return status;
90 }
91 
92 static SANE_Bool
esci2_check_header(const char *cmd, const char *buf, unsigned int *more)93 esci2_check_header(const char *cmd, const char *buf, unsigned int *more)
94 {
95 	int err;
96 
97 	*more = 0;
98 
99 	if (strncmp(cmd, buf, 4) != 0) {
100 
101 		if (strncmp("UNKN", buf, 4) == 0) {
102 			DBG(1, "UNKN reply code received\n");
103 		} else if (strncmp("INVD", buf, 4) == 0) {
104 			DBG(1, "INVD reply code received\n");
105 		} else {
106 			DBG(1, "%c%c%c%c, unexpected reply code\n", buf[0], buf[1], buf[2], buf[3]);
107 		}
108 
109 		return 0;
110 	}
111 
112 	/* INFOx0000100#.... */
113 
114 	/* read the answer len */
115 	if (buf[4] != 'x') {
116 		DBG(1, "unknown type in header: %c\n", buf[4]);
117 		return 0;
118 	}
119 
120 	err = sscanf(&buf[5], "%7x#", more);
121 	if (err != 1) {
122 		DBG(1, "cannot decode length from header\n");
123 		return 0;
124 	}
125 
126 	return 1;
127 }
128 
esci2_cmd(epsonds_scanner* s, char *cmd, size_t len, char *payload, size_t plen, void *userdata, SANE_Status (*cb)(void *userdata, char *token, int len))129 static SANE_Status esci2_cmd(epsonds_scanner* s,
130 	char *cmd, size_t len,
131 	char *payload, size_t plen,
132 	void *userdata, SANE_Status (*cb)(void *userdata, char *token, int len))
133 {
134 	SANE_Status status;
135 	unsigned int more;
136 	char header[13], rbuf[64]; /* add one more byte for header buffer to correct buffer overflow issue,*/
137 	char *buf;
138 
139 	DBG(8, "%s: %4s len %lu, payload len: %lu\n", __func__, cmd, len, plen);
140 
141 	memset(header, 0x00, sizeof(header));
142 	memset(rbuf, 0x00, sizeof(rbuf));
143 
144 	// extra safety check, will not happen
145 	if (len != 12) {
146 		DBG(1, "%s: command has wrong size (%lu != 12)\n", __func__, len);
147 		return SANE_STATUS_INVAL;
148 	}
149 
150 	// merge ParameterBlock size
151 	sprintf(header, "%4.4sx%07x", cmd, (unsigned int)plen);
152 
153 	// send RequestBlock, request immediate response if there's no payload
154 	status = eds_txrx(s, header, len, rbuf, (plen > 0) ? 0 : 64);
155 
156 	/* pointer to the token's value */
157 	buf = rbuf + 12;
158 	/* nrd / nrdBUSY */
159 	DBG(8, "buf = %s\n",buf);
160 	if (strncmp("#nrd", buf, 4) == 0) {
161 		buf += 4;
162 			DBG(8, "buf = %s\n",buf);
163 		if (strncmp("BUSY", buf, 4) == 0) {
164 			DBG(8, "device busy\n");
165 			DBG(8, "SANE_STATUS:%d\n", SANE_STATUS_DEVICE_BUSY);
166 			return SANE_STATUS_DEVICE_BUSY;
167 		}
168 	}
169 
170 	if (status != SANE_STATUS_GOOD) {
171 		return status;
172 	}
173 
174 	/* send ParameterBlock, request response */
175 	if (plen) {
176 
177 		DBG(8, " %12.12s (%lu)\n", header, plen);
178 
179 		status = eds_txrx(s, payload, plen, rbuf, 64);
180 		if (status != SANE_STATUS_GOOD) {
181 			return status;
182 		}
183 	}
184 
185 	/* rxbuf holds the DataHeaderBlock, which should be
186 	 * parsed to know if we need to read more data
187 	 */
188 	if (!esci2_check_header(cmd, rbuf, &more)) {
189 		return SANE_STATUS_IO_ERROR;
190 	}
191 
192 	/* parse the received header block */
193 	if (cb) {
194 		status = esci2_parse_block(rbuf + 12, 64 - 12, userdata, cb);
195 		if (status != SANE_STATUS_GOOD && status != SANE_STATUS_DEVICE_BUSY) {
196 			DBG(1, "%s: %4s error while parsing received header\n", __func__, cmd);
197 		}
198 	}
199 
200 	/* header valid, get the data block if present */
201 	if (more) {
202 
203 		char *pbuf = malloc(more);
204 		if (pbuf) {
205 
206 			if (s->hw->connection == SANE_EPSONDS_NET) {
207 				epsonds_net_request_read(s, more);
208 			}
209 
210 			ssize_t read = eds_recv(s, pbuf, more, &status);
211 			if (read != more) {
212 				free(pbuf);
213 				return SANE_STATUS_IO_ERROR;
214 			}
215 
216 			/* parse the received data block */
217 			if (cb) {
218 				status = esci2_parse_block(pbuf, more, userdata, cb);
219 				if (status != SANE_STATUS_GOOD) {
220 					DBG(1, "%s: %4s error while parsing received data block\n", __func__, cmd);
221 				}
222 			}
223 
224 			free(pbuf);
225 
226 		} else {
227 			return SANE_STATUS_NO_MEM;
228 		}
229 	}
230 
231 	return status;
232 }
233 
esci2_cmd_simple(epsonds_scanner* s, char *cmd, SANE_Status (*cb)(void *userdata, char *token, int len))234 static SANE_Status esci2_cmd_simple(epsonds_scanner* s, char *cmd, SANE_Status (*cb)(void *userdata, char *token, int len))
235 {
236 	return esci2_cmd(s, cmd, 12, NULL, 0, s, cb);
237 }
238 
esci2_fin(epsonds_scanner *s)239 SANE_Status esci2_fin(epsonds_scanner *s)
240 {
241 	SANE_Status status;
242 
243 	DBG(5, "%s\n", __func__);
244 
245 	status = esci2_cmd_simple(s, "FIN x0000000", NULL);
246 
247 	for(int i = 0; i < 10; i++) {
248 
249 		if(status == SANE_STATUS_DEVICE_BUSY || status == SANE_STATUS_IO_ERROR) {
250 			status = esci2_cmd_simple(s, "FIN x0000000", NULL);
251 		}
252 		else {
253 			DBG(1, "break\n");
254 			break;
255 		}
256 		DBG(1, "sleep(5)\n");
257 		sleep(5);
258 
259 	}
260 
261 	s->locked = 0;
262 	return status;
263 }
264 
esci2_can(epsonds_scanner *s)265 SANE_Status esci2_can(epsonds_scanner *s)
266 {
267 	return esci2_cmd_simple(s, "CAN x0000000", NULL);
268 }
269 
decode_value(char *buf, int len)270 static int decode_value(char *buf, int len)
271 {
272 	char tmp[10];
273 
274 	memcpy(tmp, buf, len);
275 	tmp[len] = '\0';
276 
277 	if (buf[0] == 'd' && len == 4) {
278 		return strtol(buf + 1, NULL, 10);
279 	} else if (buf[0] == 'i' && len == 8) {
280 		return strtol(buf + 1, NULL, 10);
281 	} else if (buf[0] == 'x' && len == 8) {
282 		return strtol(buf + 1, NULL, 16);
283 	} else if (buf[0] == 'h' && len == 4) {
284 		return strtol(buf + 1, NULL, 16);
285 	}
286 
287 	return -1;
288 }
289 
290 /* h000 */
decode_binary(char *buf, int len)291 static char *decode_binary(char *buf, int len)
292 {
293 	char tmp[6];
294 	int hl;
295 
296 	memcpy(tmp, buf, 4);
297 	tmp[4] = '\0';
298 
299 	if (buf[0] != 'h')
300 		return NULL;
301 
302 	hl = strtol(tmp + 1, NULL, 16);
303 	if (hl > len)
304 		hl = len;
305 	if (hl) {
306 
307 		char *v = malloc(hl + 1);
308 		memcpy(v, buf + 4, hl);
309 		v[hl] = '\0';
310 
311 		return v;
312 	}
313 
314 	return NULL;
315 }
316 
decode_string(char *buf, int len)317 static char *decode_string(char *buf, int len)
318 {
319 	char *p, *s = decode_binary(buf, len);
320 	if (s == NULL)
321 		return NULL;
322 
323 	/* trim white space at the end */
324 	p = s + strlen(s);
325 	while (*--p == ' ')
326 		*p = '\0';
327 
328 	return s;
329 }
330 
debug_token(int level, const char *func, char *token, int len)331 static void debug_token(int level, const char *func, char *token, int len)
332 {
333 	char *tdata = malloc(len + 1);
334 	memcpy(tdata, token + 3, len);
335 	tdata[len] = '\0';
336 
337 	DBG(level, "%s: %3.3s / %s / %d\n", func, token, tdata, len);
338 
339 	free(tdata);
340 }
341 
info_cb(void *userdata, char *token, int len)342 static SANE_Status info_cb(void *userdata, char *token, int len)
343 {
344 	epsonds_scanner *s = (epsonds_scanner *)userdata;
345 	char *value;
346 
347 
348 	/* pointer to the token's value */
349 	value = token + 3;
350 
351 	/* nrd / nrdBUSY */
352 
353 	if (strncmp("nrd", token, 3) == 0) {
354 		if (strncmp("BUSY", value, 4) == 0) {
355 			return SANE_STATUS_DEVICE_BUSY;
356 		}
357 	}
358 
359 	if (strncmp("PRD", token, 3) == 0) {
360 		free(s->hw->model);
361 		s->hw->model = decode_string(value, len);
362 		s->hw->sane.model = s->hw->model;
363 		DBG(1, " product: %s\n", s->hw->model);
364 	}
365 
366 	if (strncmp("VER", token, 3) == 0) {
367 		char *v = decode_string(value, len);
368 		DBG(1, " version: %s\n", v);
369 		free(v);
370 	}
371 
372 	if (strncmp("S/N", token, 3) == 0) {
373 		char *v = decode_string(value, len);
374 		DBG(1, "  serial: %s\n", v);
375 		free(v);
376 	}
377 
378 	if (strncmp("ADF", token, 3) == 0) {
379 
380 		s->hw->has_adf = 1;
381 
382 		if (len == 8) {
383 
384 			if (strncmp("TYPEPAGE", value, len) == 0) {
385 				DBG(1, "     ADF: page type\n");
386 			}
387 
388 			if (strncmp("TYPEFEED", value, len) == 0) {
389 				DBG(1, "     ADF: sheet feed type\n");
390 			}
391 
392 			if (strncmp("DPLX1SCN", value, len) == 0) {
393 				DBG(1, "     ADF: duplex single pass\n");
394 				s->hw->adf_singlepass = 1;
395 			}
396 
397 			if (strncmp("DPLX2SCN", value, len) == 0) {
398 				DBG(1, "     ADF: duplex double pass\n");
399 				s->hw->adf_singlepass = 0;
400 			}
401 
402 			if (strncmp("FORDPF1N", value, len) == 0) {
403 				DBG(1, "     ADF: order is 1 to N\n");
404 			}
405 
406 			if (strncmp("FORDPFN1", value, len) == 0) {
407 				DBG(1, "     ADF: order is N to 1\n");
408 			}
409 
410 			if (strncmp("ALGNLEFT", value, len) == 0) {
411 				DBG(1, "     ADF: left aligned\n");
412 				s->hw->adf_alignment = 0;
413 			}
414 
415 			if (strncmp("ALGNCNTR", value, len) == 0) {
416 				DBG(1, "     ADF: center aligned\n");
417 				s->hw->adf_alignment = 1;
418 			}
419 
420 			if (strncmp("ALGNRIGT", value, len) == 0) {
421 				DBG(1, "     ADF: right aligned (not supported!)\n");
422 				s->hw->adf_alignment = 2;
423 			}
424 		}
425 
426 		if (len == 4) {
427 
428 			if (strncmp("PREF", value, len) == 0) {
429 				DBG(1, "     ADF: auto pre-feed\n");
430 			}
431 
432 			if (strncmp("ASCN", value, len) == 0) {
433 				DBG(1, "     ADF: auto scan\n");
434 			}
435 
436 			if (strncmp("RCVR", value, len) == 0) {
437 				DBG(1, "     ADF: auto recovery\n");
438 			}
439 		}
440 
441 		if (len == 20) {
442 
443 			/* ADFAREAi0000850i0001400 */
444 
445 			if (strncmp("AREA", value, 4) == 0) {
446 
447 				int min = decode_value(value + 4, 8);
448 				int max = decode_value(value + 4 + 8, 8);
449 
450 				DBG(1, "     ADF: area %dx%d @ 100dpi\n", min, max);
451 				eds_set_adf_area(s->hw,	min, max, 100);
452 			}
453 
454 			if (strncmp("AMIN", value, 4) == 0) {
455 
456 				int min = decode_value(value + 4, 8);
457 				int max = decode_value(value + 4 + 8, 8);
458 
459 				DBG(1, "     ADF: min %dx%d @ 100dpi\n", min, max);
460 			}
461 
462 			if (strncmp("AMAX", value, 4) == 0) {
463 
464 				int min = decode_value(value + 4, 8);
465 				int max = decode_value(value + 4 + 8, 8);
466 
467 				DBG(1, "     ADF: max %dx%d @ 100dpi\n", min, max);
468 			}
469 		}
470 
471 
472 
473 
474 
475 
476 		if (len == 16) {
477 
478 			if (strncmp("AREA", value, 4) == 0) {
479 
480 				int min = decode_value(value + 4, 4);
481 				int max = decode_value(value + 4 + 4, 8);
482 
483 				DBG(1, "     ADF: area %dx%d @ 100dpi\n", min, max);
484 
485 				eds_set_adf_area(s->hw,	min, max, 100);
486 			}
487 
488 			if (strncmp("AMAX", value, 4) == 0) {
489 
490 				// d
491 				int min = decode_value(value + 4, 4);
492 				// i
493 				int max = decode_value(value + 4 + 4, 8);
494 
495 				DBG(1, "     ADF: max %dx%d @ 100dpi\n", min, max);
496 			}
497 		}
498 
499 
500 
501 
502 		if (len == 12) {
503 
504 			/* RESOi0000600 */
505 
506 			if (strncmp("RESO", value, 4) == 0) {
507 
508 				int res = decode_value(value + 4, 8);
509 
510 				DBG(1, "     ADF: basic resolution is %d dpi\n", res);
511 			}
512 
513 			/* OVSNd025d035 */
514 
515 			if (strncmp("OVSN", value, 4) == 0) {
516 
517 				int x = decode_value(value + 4, 4);
518 				int y = decode_value(value + 4 + 4, 4);
519 
520 				DBG(1, "     ADF: overscan %dx%d @ 100dpi\n", x, y);
521 			}
522 		}
523 	}
524 
525 	if (strncmp("FB ", token, 3) == 0) {
526 
527 		s->hw->has_fb = 1;
528 
529 		if (len == 20) {
530 
531 			/* AREAi0000850i0001400 */
532 			if (strncmp("AREA", value, 4) == 0) {
533 
534 				int min = decode_value(value + 4, 8);
535 				int max = decode_value(value + 4 + 8, 8);
536 
537 				DBG(1, "      FB: area %dx%d @ 100dpi\n", min, max);
538 
539 				eds_set_fbf_area(s->hw,	min, max, 100);
540 			}
541 		}
542 
543 
544 		if (len == 16) {
545 
546 			/* AREAi0000850i0001400 */
547 			if (strncmp("AREA", value, 4) == 0) {
548 				//d
549 				int min = decode_value(value + 4, 4);
550 				//i
551 				int max = decode_value(value + 4 + 4, 8);
552 
553 				DBG(1, "      FB: area %dx%d @ 100dpi\n", min, max);
554 
555 				eds_set_fbf_area(s->hw,	min, max, 100);
556 			}
557 		}
558 
559 		if (len == 8) {
560 
561 			if (strncmp("ALGNLEFT", value, len) == 0) {
562 				DBG(1, "      FB: left aligned\n");
563 				s->hw->fbf_alignment = 0;
564 			}
565 
566 			if (strncmp("ALGNCNTR", value, len) == 0) {
567 				DBG(1, "      FB: center aligned\n");
568 				s->hw->fbf_alignment = 1;
569 			}
570 
571 			if (strncmp("ALGNRIGT", value, len) == 0) {
572 				DBG(1, "      FB: right aligned (not supported!)\n");
573 				s->hw->fbf_alignment = 2;
574 			}
575 		}
576 
577 		if (len == 12) {
578 
579 			/* RESOi0000600 */
580 
581 			if (strncmp("RESO", value, 4) == 0) {
582 
583 				int res = decode_value(value + 4, 8);
584 
585 				DBG(1, "      FB: basic resolution is %d dpi\n", res);
586 			}
587 
588 			/* OVSNd025d035 */
589 
590 			if (strncmp("OVSN", value, 4) == 0) {
591 
592 				int x = decode_value(value + 4, 4);
593 				int y = decode_value(value + 4 + 4, 4);
594 
595 				DBG(1, "      FB: overscan %dx%d @ 100dpi\n", x, y);
596 			}
597 		}
598 
599 		if (len == 4) {
600 
601 			if (strncmp("DETX", value, len) == 0) {
602 				DBG(1, "      FB: paper width detection\n");
603 			}
604 
605 			if (strncmp("DETY", value, len) == 0) {
606 				DBG(1, "      FB: paper height detection\n");
607 			}
608 		}
609 	}
610 
611 	return SANE_STATUS_GOOD;
612 }
613 
esci2_info(epsonds_scanner *s)614 SANE_Status esci2_info(epsonds_scanner *s)
615 {
616 	SANE_Status status;
617 	int i = 4;
618 
619 	DBG(1, "= gathering device information\n");
620 
621 	do {
622 		status = esci2_cmd_simple(s, "INFOx0000000", &info_cb);
623 		if (status == SANE_STATUS_DEVICE_BUSY) {
624 			sleep(2);
625 		}
626 
627 		i--;
628 
629 	} while (status == SANE_STATUS_DEVICE_BUSY && i);
630 
631 	return status;
632 }
633 
634 /* CAPA */
635 
capa_cb(void *userdata, char *token, int len)636 static SANE_Status capa_cb(void *userdata, char *token, int len)
637 {
638 	epsonds_scanner *s = (epsonds_scanner *)userdata;
639 
640 	char *value = token + 3;
641 
642 	if (DBG_LEVEL >= 11) {
643 		debug_token(DBG_LEVEL, __func__, token, len);
644 	}
645 
646 	if (len == 4) {
647 
648 		if (strncmp("ADFDPLX", token, 3 + 4) == 0) {
649 			DBG(1, "     ADF: duplex\n");
650 			s->hw->adf_is_duplex = 1;
651 		}
652 
653 		if (strncmp("ADFSKEW", token, 3 + 4) == 0) {
654 			DBG(1, "     ADF: skew correction\n");
655 			s->hw->adf_has_skew = 1;
656 		}
657 
658 		if (strncmp("ADFOVSN", token, 3 + 4) == 0) {
659 			DBG(1, "     ADF: overscan\n");
660 		}
661 
662 		if (strncmp("ADFPEDT", token, 3 + 4) == 0) {
663 			DBG(1, "     ADF: paper end detection\n");
664 		}
665 
666 		if (strncmp("ADFLOAD", token, 3 + 4) == 0) {
667 			DBG(1, "     ADF: paper load\n");
668 			s->hw->adf_has_load = 1;
669 		}
670 
671 		if (strncmp("ADFEJCT", token, 3 + 4) == 0) {
672 			DBG(1, "     ADF: paper eject\n");
673 			s->hw->adf_has_eject = 1;
674 		}
675 
676 		if (strncmp("ADFCRP ", token, 3 + 4) == 0) {
677 			DBG(1, "     ADF: image cropping\n");
678 			s->hw->adf_has_crp = 1;
679 		}
680 
681 		if (strncmp("ADFFAST", token, 3 + 4) == 0) {
682 			DBG(1, "     ADF: fast mode available\n");
683 		}
684 
685 		if (strncmp("ADFDFL1", token, 3 + 4) == 0) {
686 			DBG(1, "     ADF: double feed detection\n");
687 			s->hw->adf_has_dfd = 1;
688 		}
689 	}
690 
691 	if (len == 8 && strncmp("ADFDFL1DFL2", token, 3 + 4) == 0) {
692 		DBG(1, "     ADF: double feed detection (high sensitivity)\n");
693 		s->hw->adf_has_dfd = 2;
694 	}
695 
696 	if (strncmp("FMT", token, 3) == 0) {
697 
698 		/* a bit ugly... */
699 
700 		if (len >= 8) {
701 			if (strncmp("RAW ", value + 4, 4) == 0) {
702 				s->hw->has_raw = 1;
703 			}
704 		}
705 
706 		if (len >= 12) {
707 			if (strncmp("RAW ", value + 8, 4) == 0) {
708 				s->hw->has_raw = 1;
709 			}
710 		}
711 	}
712 
713 
714 	if (strncmp("COLLIST", token, 3 + 4) == 0)
715 	{
716 		char *p = token + 3 + 4;
717 		int count = (len - 4);
718 		int readBytes = 0;
719 		s->hw->has_mono = 0;
720 		while (readBytes < count) {
721 			if (strncmp(p, "M001", 4) == 0)
722 			{
723 				s->hw->has_mono = 1;
724 			}
725 			readBytes+=4;
726 			p+=4;
727 		}
728 	}
729 
730 	/* RSMRANGi0000050i0000600 */
731 
732 	if (strncmp("RSMRANG", token, 3 + 4) == 0) {
733 
734 		char *p = token + 3 + 4;
735 
736 		if (p[0] == 'i') {
737 
738 			int min = decode_value(p, 8);
739 			int max = decode_value(p + 8, 8);
740 
741 			eds_set_resolution_range(s->hw, min, max);
742 
743 			DBG(1, "resolution min/max %d/%d\n", min, max);
744 		}
745 	}
746 
747 	/* RSMLISTi0000300i0000600 */
748 
749 	if (strncmp("RSMLIST", token, 3 + 4) == 0) {
750 
751 		char *p = token + 3 + 4;
752 
753 
754 			int count = (len - 4);
755 			int readBytes = 0;
756 
757 			while (readBytes < count) {
758 			      if(*p == 'i')
759 		             {
760 				eds_add_resolution(s->hw, decode_value(p, 8));
761 				p += 8;
762 				readBytes += 8;
763 			     }else if(*p == 'd')
764 			    {
765 				eds_add_resolution(s->hw, decode_value(p, 4));
766 				p += 4;
767 				readBytes +=4;
768 			     }
769 			}
770 
771 	}
772 
773 	return SANE_STATUS_GOOD;
774 }
775 
esci2_capa(epsonds_scanner *s)776 SANE_Status esci2_capa(epsonds_scanner *s)
777 {
778 	return esci2_cmd_simple(s, "CAPAx0000000", &capa_cb);
779 }
780 
781 /* STAT */
782 
stat_cb(void *userdata, char *token, int len)783 static SANE_Status stat_cb(void *userdata, char *token, int len)
784 {
785 	char *value = token + 3;
786 
787 	(void) userdata;
788 
789 	if (DBG_LEVEL >= 11) {
790 		debug_token(DBG_LEVEL, __func__, token, len);
791 	}
792 
793 	if (strncmp("ERR", token, 3) == 0) {
794 		if (strncmp("ADF PE ", value, len) == 0) {
795 			DBG(1, "     PE : paper empty\n");
796 			return SANE_STATUS_NO_DOCS;
797 		}
798 
799 		if (strncmp("ADF OPN", value, len) == 0) {
800 			DBG(1, "     conver open\n");
801 			return SANE_STATUS_COVER_OPEN;
802 		}
803 	}
804 
805 	return SANE_STATUS_GOOD;
806 }
807 
esci2_stat(epsonds_scanner *s)808 SANE_Status esci2_stat(epsonds_scanner *s)
809 {
810 	return esci2_cmd_simple(s, "STATx0000000", &stat_cb);
811 }
812 
813 /* RESA */
814 
resa_cb(void *userdata, char *token, int len)815 static SANE_Status resa_cb(void *userdata, char *token, int len)
816 {
817 	/* epsonds_scanner *s = (epsonds_scanner *)userdata; */
818 
819 	(void) userdata;
820 
821 	if (DBG_LEVEL >= 11) {
822 		debug_token(DBG_LEVEL, __func__, token, len);
823 	}
824 
825 	return SANE_STATUS_GOOD;
826 }
827 
esci2_resa(epsonds_scanner *s)828 SANE_Status esci2_resa(epsonds_scanner *s)
829 {
830 	return esci2_cmd_simple(s, "RESAx0000000", &resa_cb);
831 }
832 
833 /* PARA */
834 
para_cb(void *userdata, char *token, int len)835 static SANE_Status para_cb(void *userdata, char *token, int len)
836 {
837 	if (DBG_LEVEL >= 11) {
838 		debug_token(DBG_LEVEL, __func__, token, len);
839 	}
840 
841 	(void) userdata;
842 
843 	if (strncmp("par", token, 3) == 0) {
844 		if (strncmp("FAIL", token + 3, 4) == 0) {
845 			DBG(1, "%s: parameter setting failed\n", __func__);
846 			return SANE_STATUS_INVAL;
847 		}
848 	}
849 
850 	return SANE_STATUS_GOOD;
851 }
852 
esci2_para(epsonds_scanner *s, char *parameters, int len)853 SANE_Status esci2_para(epsonds_scanner *s, char *parameters, int len)
854 {
855 	DBG(8, "%s: %s\n", __func__, parameters);
856 	return esci2_cmd(s, "PARAx0000000", 12, parameters, len, NULL, &para_cb);
857 }
858 
esci2_mech(epsonds_scanner *s, char *parameters)859 SANE_Status esci2_mech(epsonds_scanner *s, char *parameters)
860 {
861 	DBG(8, "%s: %s\n", __func__, parameters);
862 	return esci2_cmd(s, "MECHx0000000", 12, parameters, strlen(parameters), NULL, &para_cb);
863 }
864 
esci2_trdt(epsonds_scanner *s)865 SANE_Status esci2_trdt(epsonds_scanner *s)
866 {
867 	return esci2_cmd_simple(s, "TRDTx0000000", NULL);
868 }
869 
870 
img_cb(void *userdata, char *token, int len)871 static SANE_Status img_cb(void *userdata, char *token, int len)
872 {
873 	struct epsonds_scanner *s = userdata;
874 
875 	if (DBG_LEVEL >= 11) {
876 		debug_token(DBG_LEVEL, __func__, token, len);
877 	}
878 
879 	/* psti0000256i0000000i0000945 / 24 */
880 
881 	/* integer comparison first so it's faster */
882 	if (len == 24 && strncmp("pst", token, 3) == 0) {
883 
884 		s->dummy = decode_value(token + 3 + 8, 8);
885 
886 		DBG(10, "%s: pst width: %d, height: %d, dummy: %d\n",
887 			__func__,
888 			decode_value(token + 3, 8),
889 			decode_value(token + 3 + 8 + 8, 8),
890 			s->dummy);
891 
892 		return SANE_STATUS_GOOD;
893 	}
894 
895 	if (len == 12 && strncmp("pst", token, 3) == 0) {
896 
897 		s->dummy = decode_value(token + 3 + 4, 4);
898 
899 		DBG(10, "%s: pst width: %d, height: %d, dummy: %d\n",
900 			__func__,
901 			decode_value(token + 3, 4),
902 			decode_value(token + 3 + 4 + 4, 4),
903 			s->dummy);
904 
905 		return SANE_STATUS_GOOD;
906 	}
907 
908 	if (len == 16 && strncmp("pst", token, 3) == 0) {
909 
910 		s->dummy = decode_value(token + 3 + 4, 4);
911 
912 		DBG(10, "%s: pst width: %d, height: %d, dummy: %d\n",
913 			__func__,
914 			decode_value(token + 3, 4),
915 			decode_value(token + 3 + 4 + 4, 8),
916 			s->dummy);
917 
918 		return SANE_STATUS_GOOD;
919 	}
920 
921 	if (len == 20 && strncmp("pst", token, 3) == 0) {
922 
923 		s->dummy = decode_value(token + 3 + 8, 4);
924 
925 		DBG(10, "%s: pst width: %d, height: %d, dummy: %d\n",
926 			__func__,
927 			decode_value(token + 3, 8),
928 			decode_value(token + 3 + 8 + 4, 8),
929 			s->dummy);
930 
931 		return SANE_STATUS_GOOD;
932 	}
933 
934 
935 	// i0001696i0002347
936 	if (len == 16 && strncmp("pen", token, 3) == 0) {
937 		DBG(10, "%s: page end\n", __func__);
938 		s->eof = 1;
939 		if (s->isflatbedScan)
940 		{
941 			s->scanning = 0;
942 		}
943 		DBG(10, "%s: pen width: %d, height: %d, dummy: %d\n",
944 			__func__,
945 			decode_value(token + 3, 8),
946 			decode_value(token + 3 + 8, 8),
947 		s->dummy);
948 		s->width_temp = decode_value(token + 3, 8);
949 		s->height_temp = decode_value(token + 3 + 8, 8);
950 		return SANE_STATUS_EOF;
951 	}
952 
953 	// d696i0002347
954 	if (len == 12 && strncmp("pen", token, 3) == 0) {
955 		DBG(10, "%s: page end\n", __func__);
956 		s->eof = 1;
957 		if (s->isflatbedScan)
958 		{
959 			s->scanning = 0;
960 		}
961 
962 		DBG(10, "%s: pen width: %d, height: %d, dummy: %d\n",
963 			__func__,
964 			decode_value(token + 3, 4),
965 			decode_value(token + 3 + 4, 8),
966 			s->dummy);
967 
968 		s->width_temp = decode_value(token + 3, 4);
969 		s->height_temp = decode_value(token + 3 + 4, 8);
970 		return SANE_STATUS_EOF;
971 	}
972 
973 	// d696d2347
974 	if (len == 8 && strncmp("pen", token, 3) == 0) {
975 		DBG(10, "%s: page end\n", __func__);
976 		s->eof = 1;
977 		if (s->isflatbedScan)
978 		{
979 			s->scanning = 0;
980 		}
981 		DBG(10, "%s: pen width: %d, height: %d, dummy: %d\n",
982 			__func__,
983 			decode_value(token + 3, 4),
984 			decode_value(token + 3 + 4, 4),
985 			s->dummy);
986 
987 		s->width_temp = decode_value(token + 3, 4);
988 		s->height_temp = decode_value(token + 3 + 4, 4);
989 
990 		return SANE_STATUS_EOF;
991 	}
992 
993 
994 	/* typIMGA or typIMGB */
995 	if (len == 4 && strncmp("typ", token, 3) == 0) {
996 
997 		if (token[6] == 'B')
998 			s->backside = 1;
999 		else
1000 			s->backside = 0;
1001 
1002 		return SANE_STATUS_GOOD;
1003 	}
1004 
1005 	if (strncmp("err", token, 3) == 0) {
1006 
1007 		char *option = token + 3;	/* ADF, TPU, FB */
1008 		char *cause = token + 3 + 4;	/* OPN, PJ, PE, ERR, LTF, LOCK, DFED, DTCL, AUT, PERM */
1009 
1010 		s->scanning = 0;
1011 		s->scanEnd = 1;
1012 
1013 		DBG(1, "%s: error on option %3.3s, cause %4.4s\n",
1014 			__func__, option, cause);
1015 
1016 		if (cause[0] == 'P' && cause[1] == 'J')
1017 			return SANE_STATUS_JAMMED;
1018 
1019 		if (cause[0] == 'P' && cause[1] == 'E')
1020 			return SANE_STATUS_NO_DOCS;
1021 
1022 		if (cause[0] == 'O' && cause[1] == 'P' && cause[2] == 'N')
1023 			return SANE_STATUS_COVER_OPEN;
1024 
1025 		return SANE_STATUS_IO_ERROR;
1026 	}
1027 
1028 	if (len == 4 && strncmp("atnCAN ", token, 3 + 4) == 0) {
1029 		DBG(1, "%s: cancel request\n", __func__);
1030 		s->canceling = 1;
1031 		s->scanning = 0;
1032 		return SANE_STATUS_CANCELLED;
1033 	}
1034 
1035 	if (len == 4 && strncmp("lftd000", token, 3 + 4) == 0) {
1036 		DBG(1, "%s:lft ok\n", __func__);
1037 		s->scanEnd = 1;
1038 		s->scanning = 0;
1039 	}
1040 
1041 	return SANE_STATUS_GOOD;
1042 }
1043 
1044 
1045 SANE_Status
esci2_img(struct epsonds_scanner *s, SANE_Int *length)1046 esci2_img(struct epsonds_scanner *s, SANE_Int *length)
1047 {
1048 	SANE_Status status = SANE_STATUS_GOOD;
1049 	SANE_Status parse_status;
1050 	unsigned int more;
1051 	ssize_t read;
1052 
1053 	DBG(15, "esci2_img start\n");
1054 
1055 	*length = 0;
1056 
1057 	if (s->canceling)
1058 		return SANE_STATUS_CANCELLED;
1059 
1060 	/* request image data */
1061 	eds_send(s, "IMG x0000000", 12, &status, 64);
1062 	if (status != SANE_STATUS_GOOD) {
1063 		return status;
1064 	}
1065 	DBG(15, "request img OK\n");
1066 
1067 	/* receive DataHeaderBlock */
1068 	memset(s->buf, 0x00, 64);
1069 	eds_recv(s, s->buf, 64, &status);
1070 	if (status != SANE_STATUS_GOOD) {
1071 		return status;
1072 	}
1073 	DBG(15, "receive img OK\n");
1074 
1075 	/* check if we need to read any image data */
1076 	more = 0;
1077 	if (!esci2_check_header("IMG ", (char *)s->buf, &more)) {
1078 		return SANE_STATUS_IO_ERROR;
1079 	}
1080 
1081 	/* this handles eof and errors */
1082 	parse_status = esci2_parse_block((char *)s->buf + 12, 64 - 12, s, &img_cb);
1083 
1084 	if (s->backside)
1085 	{
1086 		s->width_back = s->width_temp;
1087 		s->height_back = s->height_temp;
1088 	}else{
1089 		s->width_front = s->width_temp;
1090 		s->height_front = s->height_temp;
1091 
1092 	}
1093 
1094 
1095 	/* no more data? return using the status of the esci2_parse_block
1096 	 * call, which might hold other error conditions.
1097 	 */
1098 	if (!more) {
1099 		return parse_status;
1100 	}
1101 
1102 	/* more data than was accounted for in s->buf */
1103 	if (more > s->bsz) {
1104 		return SANE_STATUS_IO_ERROR;
1105 	}
1106 	/* ALWAYS read image data */
1107 	if (s->hw->connection == SANE_EPSONDS_NET) {
1108 		epsonds_net_request_read(s, more);
1109 	}
1110 
1111 	read = eds_recv(s, s->buf, more, &status);
1112 	if (status != SANE_STATUS_GOOD) {
1113 		return status;
1114 	}
1115 
1116 	if (read != more) {
1117 		return SANE_STATUS_IO_ERROR;
1118 	}
1119 
1120 	/* handle esci2_parse_block errors */
1121 	if (parse_status != SANE_STATUS_GOOD) {
1122 		return parse_status;
1123 	}
1124 
1125 	DBG(15, "%s: read %lu bytes, status: %d\n", __func__, (unsigned long) read, status);
1126 
1127 	*length = read;
1128 
1129 	if (s->canceling) {
1130 		return SANE_STATUS_CANCELLED;
1131 	}
1132 
1133 	return SANE_STATUS_GOOD;
1134 }
1135