diff options
Diffstat (limited to 'backend/epsonds-cmd.c')
| -rw-r--r-- | backend/epsonds-cmd.c | 254 | 
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, ¶_cb); +	return esci2_cmd(s, "PARAx0000000", 12, parameters, len, NULL, ¶_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); | 
