summaryrefslogtreecommitdiff
path: root/backend/epsonds-cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'backend/epsonds-cmd.c')
-rw-r--r--backend/epsonds-cmd.c254
1 files changed, 236 insertions, 18 deletions
diff --git a/backend/epsonds-cmd.c b/backend/epsonds-cmd.c
index 5141e07..6f0ec64 100644
--- a/backend/epsonds-cmd.c
+++ b/backend/epsonds-cmd.c
@@ -134,6 +134,7 @@ static SANE_Status esci2_cmd(epsonds_scanner* s,
SANE_Status status;
unsigned int more;
char header[13], rbuf[64]; /* add one more byte for header buffer to correct buffer overflow issue,*/
+ char *buf;
DBG(8, "%s: %4s len %lu, payload len: %lu\n", __func__, cmd, len, plen);
@@ -151,6 +152,21 @@ static SANE_Status esci2_cmd(epsonds_scanner* s,
// send RequestBlock, request immediate response if there's no payload
status = eds_txrx(s, header, len, rbuf, (plen > 0) ? 0 : 64);
+
+ /* pointer to the token's value */
+ buf = rbuf + 12;
+ /* nrd / nrdBUSY */
+ DBG(8, "buf = %s\n",buf);
+ if (strncmp("#nrd", buf, 4) == 0) {
+ buf += 4;
+ DBG(8, "buf = %s\n",buf);
+ if (strncmp("BUSY", buf, 4) == 0) {
+ DBG(8, "device busy\n");
+ DBG(8, "SANE_STATUS:%d\n", SANE_STATUS_DEVICE_BUSY);
+ return SANE_STATUS_DEVICE_BUSY;
+ }
+ }
+
if (status != SANE_STATUS_GOOD) {
return status;
}
@@ -227,6 +243,21 @@ SANE_Status esci2_fin(epsonds_scanner *s)
DBG(5, "%s\n", __func__);
status = esci2_cmd_simple(s, "FIN x0000000", NULL);
+
+ for(int i = 0; i < 10; i++) {
+
+ if(status == SANE_STATUS_DEVICE_BUSY || status == SANE_STATUS_IO_ERROR) {
+ status = esci2_cmd_simple(s, "FIN x0000000", NULL);
+ }
+ else {
+ DBG(1, "break\n");
+ break;
+ }
+ DBG(1, "sleep(5)\n");
+ sleep(5);
+
+ }
+
s->locked = 0;
return status;
}
@@ -264,13 +295,13 @@ static char *decode_binary(char *buf, int len)
memcpy(tmp, buf, 4);
tmp[4] = '\0';
- len -= 4;
if (buf[0] != 'h')
return NULL;
hl = strtol(tmp + 1, NULL, 16);
- if (hl > len) hl = len;
+ if (hl > len)
+ hl = len;
if (hl) {
char *v = malloc(hl + 1);
@@ -313,9 +344,6 @@ static SANE_Status info_cb(void *userdata, char *token, int len)
epsonds_scanner *s = (epsonds_scanner *)userdata;
char *value;
- if (DBG_LEVEL >= 11) {
- debug_token(DBG_LEVEL, __func__, token, len);
- }
/* pointer to the token's value */
value = token + 3;
@@ -333,7 +361,6 @@ static SANE_Status info_cb(void *userdata, char *token, int len)
s->hw->model = decode_string(value, len);
s->hw->sane.model = s->hw->model;
DBG(1, " product: %s\n", s->hw->model);
- /* we will free the string later */
}
if (strncmp("VER", token, 3) == 0) {
@@ -421,6 +448,7 @@ static SANE_Status info_cb(void *userdata, char *token, int len)
int max = decode_value(value + 4 + 8, 8);
DBG(1, " ADF: area %dx%d @ 100dpi\n", min, max);
+ eds_set_adf_area(s->hw, min, max, 100);
}
if (strncmp("AMIN", value, 4) == 0) {
@@ -437,11 +465,40 @@ static SANE_Status info_cb(void *userdata, char *token, int len)
int max = decode_value(value + 4 + 8, 8);
DBG(1, " ADF: max %dx%d @ 100dpi\n", min, max);
+ }
+ }
+
+
+
+
+
+
+ if (len == 16) {
+
+ if (strncmp("AREA", value, 4) == 0) {
+
+ int min = decode_value(value + 4, 4);
+ int max = decode_value(value + 4 + 4, 8);
+
+ DBG(1, " ADF: area %dx%d @ 100dpi\n", min, max);
eds_set_adf_area(s->hw, min, max, 100);
}
+
+ if (strncmp("AMAX", value, 4) == 0) {
+
+ // d
+ int min = decode_value(value + 4, 4);
+ // i
+ int max = decode_value(value + 4 + 4, 8);
+
+ DBG(1, " ADF: max %dx%d @ 100dpi\n", min, max);
+ }
}
+
+
+
if (len == 12) {
/* RESOi0000600 */
@@ -483,6 +540,22 @@ static SANE_Status info_cb(void *userdata, char *token, int len)
}
}
+
+ if (len == 16) {
+
+ /* AREAi0000850i0001400 */
+ if (strncmp("AREA", value, 4) == 0) {
+ //d
+ int min = decode_value(value + 4, 4);
+ //i
+ int max = decode_value(value + 4 + 4, 8);
+
+ DBG(1, " FB: area %dx%d @ 100dpi\n", min, max);
+
+ eds_set_fbf_area(s->hw, min, max, 100);
+ }
+ }
+
if (len == 8) {
if (strncmp("ALGNLEFT", value, len) == 0) {
@@ -602,6 +675,7 @@ static SANE_Status capa_cb(void *userdata, char *token, int len)
if (strncmp("ADFCRP ", token, 3 + 4) == 0) {
DBG(1, " ADF: image cropping\n");
+ s->hw->adf_has_crp = 1;
}
if (strncmp("ADFFAST", token, 3 + 4) == 0) {
@@ -636,6 +710,23 @@ static SANE_Status capa_cb(void *userdata, char *token, int len)
}
}
+
+ if (strncmp("COLLIST", token, 3 + 4) == 0)
+ {
+ char *p = token + 3 + 4;
+ int count = (len - 4);
+ int readBytes = 0;
+ s->hw->has_mono = 0;
+ while (readBytes < count) {
+ if (strncmp(p, "M001", 4) == 0)
+ {
+ s->hw->has_mono = 1;
+ }
+ readBytes+=4;
+ p+=4;
+ }
+ }
+
/* RSMRANGi0000050i0000600 */
if (strncmp("RSMRANG", token, 3 + 4) == 0) {
@@ -659,17 +750,24 @@ static SANE_Status capa_cb(void *userdata, char *token, int len)
char *p = token + 3 + 4;
- if (p[0] == 'i') {
-
- int i;
- int count = (len - 4) / 8;
- for (i = 0; i < count; i++) {
+ int count = (len - 4);
+ int readBytes = 0;
+ while (readBytes < count) {
+ if(*p == 'i')
+ {
eds_add_resolution(s->hw, decode_value(p, 8));
p += 8;
+ readBytes += 8;
+ }else if(*p == 'd')
+ {
+ eds_add_resolution(s->hw, decode_value(p, 4));
+ p += 4;
+ readBytes +=4;
+ }
}
- }
+
}
return SANE_STATUS_GOOD;
@@ -684,16 +782,26 @@ SANE_Status esci2_capa(epsonds_scanner *s)
static SANE_Status stat_cb(void *userdata, char *token, int len)
{
-/*
- epsonds_scanner *s = (epsonds_scanner *)userdata;
char *value = token + 3;
-*/
+
userdata = userdata;
if (DBG_LEVEL >= 11) {
debug_token(DBG_LEVEL, __func__, token, len);
}
+ if (strncmp("ERR", token, 3) == 0) {
+ if (strncmp("ADF PE ", value, len) == 0) {
+ DBG(1, " PE : paper empty\n");
+ return SANE_STATUS_NO_DOCS;
+ }
+
+ if (strncmp("ADF OPN", value, len) == 0) {
+ DBG(1, " conver open\n");
+ return SANE_STATUS_COVER_OPEN;
+ }
+ }
+
return SANE_STATUS_GOOD;
}
@@ -742,10 +850,10 @@ static SANE_Status para_cb(void *userdata, char *token, int len)
return SANE_STATUS_GOOD;
}
-SANE_Status esci2_para(epsonds_scanner *s, char *parameters)
+SANE_Status esci2_para(epsonds_scanner *s, char *parameters, int len)
{
DBG(8, "%s: %s\n", __func__, parameters);
- return esci2_cmd(s, "PARAx0000000", 12, parameters, strlen(parameters), NULL, &para_cb);
+ return esci2_cmd(s, "PARAx0000000", 12, parameters, len, NULL, &para_cb);
}
SANE_Status esci2_mech(epsonds_scanner *s, char *parameters)
@@ -784,12 +892,105 @@ static SANE_Status img_cb(void *userdata, char *token, int len)
return SANE_STATUS_GOOD;
}
+ if (len == 12 && strncmp("pst", token, 3) == 0) {
+
+ s->dummy = decode_value(token + 3 + 4, 4);
+
+ DBG(10, "%s: pst width: %d, height: %d, dummy: %d\n",
+ __func__,
+ decode_value(token + 3, 4),
+ decode_value(token + 3 + 4 + 4, 4),
+ s->dummy);
+
+ return SANE_STATUS_GOOD;
+ }
+
+ if (len == 16 && strncmp("pst", token, 3) == 0) {
+
+ s->dummy = decode_value(token + 3 + 4, 4);
+
+ DBG(10, "%s: pst width: %d, height: %d, dummy: %d\n",
+ __func__,
+ decode_value(token + 3, 4),
+ decode_value(token + 3 + 4 + 4, 8),
+ s->dummy);
+
+ return SANE_STATUS_GOOD;
+ }
+
+ if (len == 20 && strncmp("pst", token, 3) == 0) {
+
+ s->dummy = decode_value(token + 3 + 8, 4);
+
+ DBG(10, "%s: pst width: %d, height: %d, dummy: %d\n",
+ __func__,
+ decode_value(token + 3, 8),
+ decode_value(token + 3 + 8 + 4, 8),
+ s->dummy);
+
+ return SANE_STATUS_GOOD;
+ }
+
+
+ // i0001696i0002347
if (len == 16 && strncmp("pen", token, 3) == 0) {
DBG(10, "%s: page end\n", __func__);
s->eof = 1;
+ if (s->isflatbedScan)
+ {
+ s->scanning = 0;
+ }
+ DBG(10, "%s: pen width: %d, height: %d, dummy: %d\n",
+ __func__,
+ decode_value(token + 3, 8),
+ decode_value(token + 3 + 8, 8),
+ s->dummy);
+ s->width_temp = decode_value(token + 3, 8);
+ s->height_temp = decode_value(token + 3 + 8, 8);
return SANE_STATUS_EOF;
}
+ // d696i0002347
+ if (len == 12 && strncmp("pen", token, 3) == 0) {
+ DBG(10, "%s: page end\n", __func__);
+ s->eof = 1;
+ if (s->isflatbedScan)
+ {
+ s->scanning = 0;
+ }
+
+ DBG(10, "%s: pen width: %d, height: %d, dummy: %d\n",
+ __func__,
+ decode_value(token + 3, 4),
+ decode_value(token + 3 + 4, 8),
+ s->dummy);
+
+ s->width_temp = decode_value(token + 3, 4);
+ s->height_temp = decode_value(token + 3 + 4, 8);
+ return SANE_STATUS_EOF;
+ }
+
+ // d696d2347
+ if (len == 8 && strncmp("pen", token, 3) == 0) {
+ DBG(10, "%s: page end\n", __func__);
+ s->eof = 1;
+ if (s->isflatbedScan)
+ {
+ s->scanning = 0;
+ }
+ DBG(10, "%s: pen width: %d, height: %d, dummy: %d\n",
+ __func__,
+ decode_value(token + 3, 4),
+ decode_value(token + 3 + 4, 4),
+ s->dummy);
+
+ s->width_temp = decode_value(token + 3, 4);
+ s->height_temp = decode_value(token + 3 + 4, 4);
+
+ return SANE_STATUS_EOF;
+ }
+
+
/* typIMGA or typIMGB */
if (len == 4 && strncmp("typ", token, 3) == 0) {
@@ -807,6 +1008,7 @@ static SANE_Status img_cb(void *userdata, char *token, int len)
char *cause = token + 3 + 4; /* OPN, PJ, PE, ERR, LTF, LOCK, DFED, DTCL, AUT, PERM */
s->scanning = 0;
+ s->scanEnd = 1;
DBG(1, "%s: error on option %3.3s, cause %4.4s\n",
__func__, option, cause);
@@ -831,6 +1033,8 @@ static SANE_Status img_cb(void *userdata, char *token, int len)
}
if (len == 4 && strncmp("lftd000", token, 3 + 4) == 0) {
+ DBG(1, "%s:lft ok\n", __func__);
+ s->scanEnd = 1;
s->scanning = 0;
}
@@ -846,6 +1050,8 @@ esci2_img(struct epsonds_scanner *s, SANE_Int *length)
unsigned int more;
ssize_t read;
+ DBG(15, "esci2_img start\n");
+
*length = 0;
if (s->canceling)
@@ -856,6 +1062,7 @@ esci2_img(struct epsonds_scanner *s, SANE_Int *length)
if (status != SANE_STATUS_GOOD) {
return status;
}
+ DBG(15, "request img OK\n");
/* receive DataHeaderBlock */
memset(s->buf, 0x00, 64);
@@ -863,6 +1070,7 @@ esci2_img(struct epsonds_scanner *s, SANE_Int *length)
if (status != SANE_STATUS_GOOD) {
return status;
}
+ DBG(15, "receive img OK\n");
/* check if we need to read any image data */
more = 0;
@@ -873,6 +1081,17 @@ esci2_img(struct epsonds_scanner *s, SANE_Int *length)
/* this handles eof and errors */
parse_status = esci2_parse_block((char *)s->buf + 12, 64 - 12, s, &img_cb);
+ if (s->backside)
+ {
+ s->width_back = s->width_temp;
+ s->height_back = s->height_temp;
+ }else{
+ s->width_front = s->width_temp;
+ s->height_front = s->height_temp;
+
+ }
+
+
/* no more data? return using the status of the esci2_parse_block
* call, which might hold other error conditions.
*/
@@ -884,7 +1103,6 @@ esci2_img(struct epsonds_scanner *s, SANE_Int *length)
if (more > s->bsz) {
return SANE_STATUS_IO_ERROR;
}
-
/* ALWAYS read image data */
if (s->hw->connection == SANE_EPSONDS_NET) {
epsonds_net_request_read(s, more);