Merge branch 'escl-fix-status-adf' into 'master'

Refactoring of the adf status.

See merge request sane-project/backends!434
merge-requests/463/merge
Ordissimo 2020-05-11 14:58:38 +00:00
commit 5ad7708381
4 zmienionych plików z 129 dodań i 72 usunięć

Wyświetl plik

@ -1144,23 +1144,33 @@ sane_read(SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *len)
} }
else { else {
SANE_Status status = SANE_STATUS_EOF; SANE_Status status = SANE_STATUS_EOF;
SANE_Status job = SANE_STATUS_UNSUPPORTED;
*len = 0; *len = 0;
free(handler->scanner->img_data); free(handler->scanner->img_data);
handler->scanner->img_data = NULL; handler->scanner->img_data = NULL;
if (handler->scanner->source != PLATEN) { if (handler->scanner->source != PLATEN) {
SANE_Bool next_page = SANE_FALSE;
SANE_Status st = escl_status(handler->device, SANE_Status st = escl_status(handler->device,
handler->scanner->source, handler->scanner->source,
handler->result); handler->result,
&job);
DBG(10, "eSCL : command returned status %s\n", sane_strstatus(st)); DBG(10, "eSCL : command returned status %s\n", sane_strstatus(st));
SANE_Bool next_page = // Thank's Alexander Pevzner (pzz@apevzner.com)
(SANE_STATUS_GOOD == st ? switch (st) {
SANE_TRUE : case SANE_STATUS_GOOD:
SANE_FALSE); case SANE_STATUS_UNSUPPORTED:
handler->scanner->work = next_page; case SANE_STATUS_DEVICE_BUSY:
handler->ps.last_frame = !next_page; DBG(10, "eSCL : next page\n");
if (handler->ps.last_frame == SANE_TRUE) if (job != SANE_STATUS_GOOD)
next_page = SANE_TRUE;
default:
break;
}
handler->scanner->work = next_page;
handler->ps.last_frame = !next_page;
if (handler->ps.last_frame == SANE_TRUE)
status = SANE_STATUS_NO_DOCS; status = SANE_STATUS_NO_DOCS;
else else
status = SANE_STATUS_EOF; status = SANE_STATUS_EOF;
} }
else else

Wyświetl plik

@ -181,7 +181,10 @@ enum
ESCL_Device *escl_devices(SANE_Status *status); ESCL_Device *escl_devices(SANE_Status *status);
SANE_Status escl_device_add(int port_nb, const char *model_name, SANE_Status escl_device_add(int port_nb, const char *model_name,
char *ip_address, char *type); char *ip_address, char *type);
SANE_Status escl_status(const ESCL_Device *device, int source, char *jobid); SANE_Status escl_status(const ESCL_Device *device,
int source,
const char* jobId,
SANE_Status *job);
capabilities_t *escl_capabilities(const ESCL_Device *device, SANE_Status *status); capabilities_t *escl_capabilities(const ESCL_Device *device, SANE_Status *status);
char *escl_newjob(capabilities_t *scanner, const ESCL_Device *device, char *escl_newjob(capabilities_t *scanner, const ESCL_Device *device,
SANE_Status *status); SANE_Status *status);

Wyświetl plik

@ -31,6 +31,15 @@
#include <curl/curl.h> #include <curl/curl.h>
static size_t
write_callback(void __sane_unused__*str,
size_t __sane_unused__ size,
size_t nmemb,
void __sane_unused__ *userp)
{
return nmemb;
}
/** /**
* \fn void escl_scanner(const ESCL_Device *device, char *result) * \fn void escl_scanner(const ESCL_Device *device, char *result)
* \brief Function that resets the scanner after each scan, using curl. * \brief Function that resets the scanner after each scan, using curl.
@ -54,13 +63,17 @@ CURL_CALL:
snprintf(scan_cmd, sizeof(scan_cmd), "%s%s%s", snprintf(scan_cmd, sizeof(scan_cmd), "%s%s%s",
scan_jobs, result, scanner_start); scan_jobs, result, scanner_start);
escl_curl_url(curl_handle, device, scan_cmd); escl_curl_url(curl_handle, device, scan_cmd);
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_callback);
if (curl_easy_perform(curl_handle) == CURLE_OK) { if (curl_easy_perform(curl_handle) == CURLE_OK) {
curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &answer); curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &answer);
i++; i++;
if (i >= 15) return; if (i >= 15) return;
} }
curl_easy_cleanup(curl_handle); curl_easy_cleanup(curl_handle);
if (SANE_STATUS_GOOD != escl_status(device, PLATEN, result)) if (SANE_STATUS_GOOD != escl_status(device,
PLATEN,
NULL,
NULL))
goto CURL_CALL; goto CURL_CALL;
} }
} }

Wyświetl plik

@ -85,8 +85,7 @@ find_nodes_s(xmlNode *node)
static void static void
print_xml_job_status(xmlNode *node, print_xml_job_status(xmlNode *node,
SANE_Status *processing, SANE_Status *job,
SANE_Status *complete,
int *image) int *image)
{ {
while (node) { while (node) {
@ -94,49 +93,33 @@ print_xml_job_status(xmlNode *node,
if (find_nodes_s(node)) { if (find_nodes_s(node)) {
if (strcmp((const char *)node->name, "JobState") == 0) { if (strcmp((const char *)node->name, "JobState") == 0) {
const char *state = (const char *)xmlNodeGetContent(node); const char *state = (const char *)xmlNodeGetContent(node);
if (!strcmp(state, "Processing")) { if (!strcmp(state, "Processing")) {
*processing = SANE_STATUS_GOOD; *job = SANE_STATUS_DEVICE_BUSY;
} DBG(10, "jobId Processing SANE_STATUS_DEVICE_BUSY\n");
if (!strcmp(state, "Completed")) { }
*complete = SANE_STATUS_GOOD; else if (!strcmp(state, "Completed")) {
} *job = SANE_STATUS_GOOD;
} DBG(10, "jobId Completed SANE_STATUS_GOOD\n");
else if (strcmp((const char *)node->name, "ImagesToTransfer") == 0) { }
const char *state = (const char *)xmlNodeGetContent(node); else if (strcmp((const char *)node->name, "ImagesToTransfer") == 0) {
*image = atoi(state); const char *state = (const char *)xmlNodeGetContent(node);
*image = atoi(state);
}
} }
} }
} }
print_xml_job_status(node->children, processing, complete, image); print_xml_job_status(node->children, job, image);
node = node->next; node = node->next;
} }
} }
static void static void
print_xml_feeder_status(xmlNode *node, print_xml_platen_and_adf_status(xmlNode *node,
const char *job, SANE_Status *platen,
SANE_Status *processing, SANE_Status *adf,
SANE_Status *complete, const char* jobId,
int *image) SANE_Status *job,
{ int *image)
while (node) {
if (node->type == XML_ELEMENT_NODE) {
if (find_nodes_s(node)) {
if (strcmp((const char *)node->name, "JobUri") == 0) {
if (strstr((const char *)xmlNodeGetContent(node), job)) {
print_xml_job_status(node, processing, complete, image);
return;
}
}
}
}
print_xml_feeder_status(node->children, job, processing, complete, image);
node = node->next;
}
}
static void
print_xml_platen_status(xmlNode *node, SANE_Status *status)
{ {
while (node) { while (node) {
if (node->type == XML_ELEMENT_NODE) { if (node->type == XML_ELEMENT_NODE) {
@ -145,19 +128,54 @@ print_xml_platen_status(xmlNode *node, SANE_Status *status)
printf ("State\t"); printf ("State\t");
const char *state = (const char *)xmlNodeGetContent(node); const char *state = (const char *)xmlNodeGetContent(node);
if (!strcmp(state, "Idle")) { if (!strcmp(state, "Idle")) {
printf("Idle SANE_STATUS_GOOD\n"); DBG(10, "Idle SANE_STATUS_GOOD\n");
*status = SANE_STATUS_GOOD; *platen = SANE_STATUS_GOOD;
} else if (!strcmp(state, "Processing")) { } else if (!strcmp(state, "Processing")) {
printf("Processing SANE_STATUS_DEVICE_BUSY\n"); DBG(10, "Processing SANE_STATUS_DEVICE_BUSY\n");
*status = SANE_STATUS_DEVICE_BUSY; *platen = SANE_STATUS_DEVICE_BUSY;
} else { } else {
printf("%s SANE_STATUS_UNSUPPORTED\n", state); DBG(10, "%s SANE_STATUS_UNSUPPORTED\n", state);
*status = SANE_STATUS_UNSUPPORTED; *platen = SANE_STATUS_UNSUPPORTED;
} }
} }
// Thank's Alexander Pevzner (pzz@apevzner.com)
else if (adf && strcmp((const char *)node->name, "AdfState") == 0) {
const char *state = (const char *)xmlNodeGetContent(node);
if (!strcmp(state, "ScannerAdfLoaded")){
DBG(10, "ScannerAdfLoaded SANE_STATUS_GOOD\n");
*adf = SANE_STATUS_GOOD;
} else if (!strcmp(state, "ScannerAdfJam")) {
DBG(10, "ScannerAdfJam SANE_STATUS_JAMMED\n");
*adf = SANE_STATUS_JAMMED;
} else if (!strcmp(state, "ScannerAdfDoorOpen")) {
DBG(10, "ScannerAdfDoorOpen SANE_STATUS_COVER_OPEN\n");
*adf = SANE_STATUS_COVER_OPEN;
} else if (!strcmp(state, "ScannerAdfProcessing")) {
/* Kyocera version */
DBG(10, "ScannerAdfProcessing SANE_STATUS_NO_DOC\n");
*adf = SANE_STATUS_NO_DOCS;
} else if (!strcmp(state, "ScannerAdfEmpty")) {
DBG(10, "ScannerAdfEmpty SANE_STATUS_NO_DOCS\n");
/* Cannon TR4500, EPSON XP-7100 */
*adf = SANE_STATUS_NO_DOCS;
} else {
DBG(10, "%s SANE_STATUS_NO_DOCS\n", state);
*adf = SANE_STATUS_UNSUPPORTED;
}
}
else if (jobId && job && strcmp((const char *)node->name, "JobUri") == 0) {
if (strstr((const char *)xmlNodeGetContent(node), jobId)) {
print_xml_job_status(node, job, image);
}
}
} }
} }
print_xml_platen_status(node->children, status); print_xml_platen_and_adf_status(node->children,
platen,
adf,
jobId,
job,
image);
node = node->next; node = node->next;
} }
} }
@ -171,17 +189,28 @@ print_xml_platen_status(xmlNode *node, SANE_Status *status)
* \return status (if everything is OK, status = SANE_STATUS_GOOD, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL) * \return status (if everything is OK, status = SANE_STATUS_GOOD, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL)
*/ */
SANE_Status SANE_Status
escl_status(const ESCL_Device *device, int source, char *jobid) escl_status(const ESCL_Device *device,
int source,
const char* jobId,
SANE_Status *job)
{ {
SANE_Status status; SANE_Status status = SANE_STATUS_DEVICE_BUSY;
SANE_Status platen= SANE_STATUS_DEVICE_BUSY;
SANE_Status adf= SANE_STATUS_DEVICE_BUSY;
CURL *curl_handle = NULL; CURL *curl_handle = NULL;
struct idle *var = NULL; struct idle *var = NULL;
xmlDoc *data = NULL; xmlDoc *data = NULL;
xmlNode *node = NULL; xmlNode *node = NULL;
const char *scanner_status = "/eSCL/ScannerStatus"; const char *scanner_status = "/eSCL/ScannerStatus";
int image = -1;
int pass = 0;
reload:
if (device == NULL) if (device == NULL)
return (SANE_STATUS_NO_MEM); return (SANE_STATUS_NO_MEM);
status = SANE_STATUS_DEVICE_BUSY;
platen= SANE_STATUS_DEVICE_BUSY;
adf= SANE_STATUS_DEVICE_BUSY;
var = (struct idle*)calloc(1, sizeof(struct idle)); var = (struct idle*)calloc(1, sizeof(struct idle));
if (var == NULL) if (var == NULL)
return (SANE_STATUS_NO_MEM); return (SANE_STATUS_NO_MEM);
@ -209,23 +238,16 @@ escl_status(const ESCL_Device *device, int source, char *jobid)
status = SANE_STATUS_NO_MEM; status = SANE_STATUS_NO_MEM;
goto clean; goto clean;
} }
status = SANE_STATUS_DEVICE_BUSY;
/* Decode Job status */ /* Decode Job status */
if (source == PLATEN) { // Thank's Alexander Pevzner (pzz@apevzner.com)
print_xml_platen_status(node, &status); print_xml_platen_and_adf_status(node, &platen, &adf, jobId, job, &image);
if (platen != SANE_STATUS_GOOD &&
platen != SANE_STATUS_UNSUPPORTED) {
status = platen;
} else if (source == PLATEN) {
status = platen;
} else { } else {
SANE_Status processing = SANE_STATUS_UNSUPPORTED; status = adf;
SANE_Status complete = SANE_STATUS_UNSUPPORTED;
int image = -1;
print_xml_feeder_status(node, jobid, &processing, &complete, &image);
if (processing == SANE_STATUS_GOOD && image == 0 &&
complete == SANE_STATUS_UNSUPPORTED)
status = SANE_STATUS_EOF;
else if (complete == SANE_STATUS_GOOD && image == -1 &&
processing == SANE_STATUS_UNSUPPORTED)
status = SANE_STATUS_EOF;
else
status = SANE_STATUS_GOOD;
} }
DBG (10, "STATUS : %s\n", sane_strstatus(status)); DBG (10, "STATUS : %s\n", sane_strstatus(status));
clean: clean:
@ -236,5 +258,14 @@ clean_data:
curl_easy_cleanup(curl_handle); curl_easy_cleanup(curl_handle);
free(var->memory); free(var->memory);
free(var); free(var);
if (pass == 0 &&
source != PLATEN &&
image == 0 &&
(status == SANE_STATUS_GOOD ||
status == SANE_STATUS_UNSUPPORTED ||
status == SANE_STATUS_DEVICE_BUSY)) {
pass = 1;
goto reload;
}
return (status); return (status);
} }