kopia lustrzana https://gitlab.com/sane-project/backends
Merge branch 'escl-fix-status-adf' into 'master'
Refactoring of the adf status. See merge request sane-project/backends!434merge-requests/463/merge
commit
5ad7708381
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue