summaryrefslogtreecommitdiff
path: root/src/cups/dnpds40_print.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cups/dnpds40_print.c')
-rw-r--r--src/cups/dnpds40_print.c541
1 files changed, 321 insertions, 220 deletions
diff --git a/src/cups/dnpds40_print.c b/src/cups/dnpds40_print.c
index 16e8ab1..47ff498 100644
--- a/src/cups/dnpds40_print.c
+++ b/src/cups/dnpds40_print.c
@@ -44,6 +44,8 @@
#include <fcntl.h>
#include <signal.h>
+#define BACKEND dnpds40_backend
+
#include "backend_common.h"
#define USB_VID_CITIZEN 0x1343
@@ -82,6 +84,7 @@ struct dnpds40_ctx {
int cutter;
int can_rewind;
+ int manual_copies;
int supports_6x9;
int supports_2x6;
int supports_3x5x2;
@@ -90,6 +93,8 @@ struct dnpds40_ctx {
int supports_rewind;
int supports_standby;
int supports_6x4_5;
+ int supports_mqty_default;
+ int supports_iserial;
uint8_t *qty_offset;
uint8_t *buffctrl_offset;
@@ -328,6 +333,9 @@ static void dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
device = libusb_get_device(dev);
libusb_get_device_descriptor(device, &desc);
+ ctx->type = lookup_printer_type(&dnpds40_backend,
+ desc.idVendor, desc.idProduct);
+
{
/* Get Firmware Version */
struct dnpds40_cmd cmd;
@@ -343,7 +351,7 @@ static void dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
ctx->version = strdup((char*) resp);
/* Parse version */
- ptr = strtok((char*)resp, " .");
+ /* ptr = */ strtok((char*)resp, " .");
ptr = strtok(NULL, ".");
ctx->ver_major = atoi(ptr);
ptr = strtok(NULL, ".");
@@ -397,9 +405,8 @@ static void dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
#endif
/* Per-printer options */
- switch (desc.idProduct) {
- case USB_PID_DNP_DS40:
- ctx->type = P_DNP_DS40;
+ switch (ctx->type) {
+ case P_DNP_DS40:
ctx->supports_6x9 = 1;
if (FW_VER_CHECK(1,30))
ctx->supports_matte = 1;
@@ -410,31 +417,31 @@ static void dnpds40_attach(void *vctx, struct libusb_device_handle *dev,
if (FW_VER_CHECK(1,51))
ctx->supports_fullcut = 1;
break;
- case USB_PID_DNP_DS80:
- ctx->type = P_DNP_DS80;
+ case P_DNP_DS80:
if (FW_VER_CHECK(1,30))
ctx->supports_matte = 1;
break;
- case USB_PID_DNP_DSRX1:
- ctx->type = P_DNP_DSRX1;
+ case P_DNP_DSRX1:
ctx->supports_matte = 1;
+ ctx->supports_mqty_default = 1; // 1.10 does. Maybe older too?
if (FW_VER_CHECK(1,10))
ctx->supports_2x6 = 1;
break;
- case USB_PID_DNP_DS620:
- ctx->type = P_DNP_DS620;
+ case P_DNP_DS620:
ctx->supports_matte = 1;
ctx->supports_2x6 = 1;
ctx->supports_fullcut = 1;
- ctx->supports_rewind = 1; // XXX DS620 only, 620A does not.
+ ctx->supports_mqty_default = 1;
+ ctx->supports_rewind = 1;
ctx->supports_standby = 1;
+ ctx->supports_iserial = 1;
if (FW_VER_CHECK(0,30))
ctx->supports_3x5x2 = 1;
if (FW_VER_CHECK(1,10))
ctx->supports_6x9 = ctx->supports_6x4_5 = 1;
break;
default:
- ERROR("Unknown USB PID...\n");
+ ERROR("Unknown vid/pid %04x/%04x (%d)\n", desc.idVendor, desc.idProduct, ctx->type);
return;
}
}
@@ -491,6 +498,7 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
matte = 0;
dpi = 0;
cutter = 0;
+ ctx->manual_copies = 0;
ctx->multicut = 0;
ctx->buffctrl_offset = ctx->qty_offset = ctx->multicut_offset = 0;
@@ -603,7 +611,7 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
if (y_ppm != 1920) {
ERROR("Incorrect horizontal resolution (%d), aborting!\n", y_ppm);
return CUPS_BACKEND_CANCEL;
- }
+ }
}
}
@@ -616,8 +624,8 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
}
if (!ctx->datalen)
- return CUPS_BACKEND_CANCEL;
-
+ return CUPS_BACKEND_CANCEL;
+
/* Figure out the number of buffers we need. Most only need one. */
if (ctx->multicut) {
ctx->buf_needed = 1;
@@ -668,12 +676,14 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
}
break;
case 210: //"5x7 (2L)"
- ctx->can_rewind = 1;
if (ctx->multicut != 1 && ctx->multicut != 3 &&
ctx->multicut != 22 && ctx->multicut != 29) {
ERROR("Incorrect media for job loaded (%d vs %d)\n", ctx->media, ctx->multicut);
return CUPS_BACKEND_CANCEL;
}
+ /* Only 3.5x5 on 7x5 media can be rewound */
+ if (ctx->multicut == 1)
+ ctx->can_rewind = 1;
break;
case 300: //"6x4 (PC)"
if (ctx->multicut != 2) {
@@ -682,21 +692,27 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
}
break;
case 310: //"6x8 (A5)"
- ctx->can_rewind = 1;
if (ctx->multicut != 2 && ctx->multicut != 4 &&
- ctx->multicut != 27) {
+ ctx->multicut != 12 &&
+ ctx->multicut != 27 && ctx->multicut != 30) {
ERROR("Incorrect media for job loaded (%d vs %d)\n", ctx->media, ctx->multicut);
return CUPS_BACKEND_CANCEL;
}
+ /* Only 6x4 on 6x8 media can be rewound */
+ if (ctx->multicut == 2)
+ ctx->can_rewind = 1;
break;
case 400: //"6x9 (A5W)"
- ctx->can_rewind = 1;
if (ctx->multicut != 2 && ctx->multicut != 4 &&
- ctx->multicut != 5 && ctx->multicut != 27 &&
+ ctx->multicut != 5 && ctx->multicut != 12 &&
+ ctx->multicut != 27 &&
ctx->multicut != 30 && ctx->multicut != 31) {
ERROR("Incorrect media for job loaded (%d vs %d)\n", ctx->media, ctx->multicut);
return CUPS_BACKEND_CANCEL;
}
+ /* Only 6x4 or 6x4.5 on 6x9 media can be rewound */
+ if (ctx->multicut == 2 || ctx->multicut == 30)
+ ctx->can_rewind = 1;
break;
case 500: //"8x10"
if (ctx->multicut < 6 || ctx->multicut == 7 ||
@@ -749,6 +765,11 @@ static int dnpds40_read_parse(void *vctx, int data_fd) {
ERROR("Printer only supports 2-inch cuts on 4x6 or 8x6 jobs!");
return CUPS_BACKEND_CANCEL;
}
+
+ /* Work around firmware bug on DS40 where if we run out
+ of media, we can't resume the job without losing the
+ cutter setting. XXX add version test? */
+ ctx->manual_copies = 1;
}
if (ctx->matte && !ctx->supports_matte) {
@@ -768,65 +789,15 @@ static int dnpds40_main_loop(void *vctx, int copies) {
uint8_t *ptr;
char buf[9];
int status;
+ int buf_needed;
if (!ctx)
return CUPS_BACKEND_FAILED;
- /* Verify we have sufficient media for prints */
- {
- int i = 0;
-
- /* See if we can rewind to save media */
- if (ctx->can_rewind && ctx->supports_rewind &&
- (ctx->multicut == 1 || ctx->multicut == 2)) {
-
- /* Get Media remaining */
- dnpds40_build_cmd(&cmd, "INFO", "RQTY", 0);
-
- if (resp) free(resp);
- resp = dnpds40_resp_cmd(ctx, &cmd, &len);
- if (!resp)
- return CUPS_BACKEND_FAILED;
-
- dnpds40_cleanup_string((char*)resp, len);
- i = atoi((char*)resp);
-
- /* If the count is odd, we can rewind. */
- if (i & 1) {
- snprintf(buf, sizeof(buf), "%08d", ctx->multicut + 400);
- memcpy(ctx->multicut_offset, buf, 8);
- }
- }
-
- /* If we didn't succeed with RQTY, try MQTY */
- if (i == 0) {
- dnpds40_build_cmd(&cmd, "INFO", "MQTY", 0);
-
- if (resp) free(resp);
- resp = dnpds40_resp_cmd(ctx, &cmd, &len);
- if (!resp)
- return CUPS_BACKEND_FAILED;
-
- dnpds40_cleanup_string((char*)resp, len);
-
- i = atoi((char*)resp+4);
-
- /* For some reason all but the DS620 report 50 too high */
- if (ctx->type != P_DNP_DS620 && i > 0)
- i -= 50;
- }
-
- if (i < 1) {
- ERROR("Printer out of media, please correct!\n");
- return CUPS_BACKEND_STOP;
- }
- if (i < copies) {
- WARNING("Printer does not have sufficient remaining media to complete job..\n");
- }
- }
-
/* Update quantity offset with count */
- if (copies > 1) {
+ // XXX this breaks if ctx->manual_copies is set, but the job
+ // has a CNTRL QTY != 1
+ if (!ctx->manual_copies && copies > 1) {
snprintf(buf, sizeof(buf), "%07d\r", copies);
if (ctx->qty_offset) {
memcpy(ctx->qty_offset, buf, 8);
@@ -843,7 +814,7 @@ static int dnpds40_main_loop(void *vctx, int copies) {
if (ctx->supports_matte) {
snprintf(buf, sizeof(buf), "%08d", 1);
if (ctx->buffctrl_offset) {
- memcpy(ctx->qty_offset, buf, 8);
+ memcpy(ctx->buffctrl_offset, buf, 8);
} else {
dnpds40_build_cmd(&cmd, "CNTRL", "BUFFCNTRL", 8);
if ((ret = dnpds40_do_cmd(ctx, &cmd, (uint8_t*)buf, 8)))
@@ -866,9 +837,11 @@ static int dnpds40_main_loop(void *vctx, int copies) {
}
#endif
+ buf_needed = ctx->buf_needed;
+
#ifdef MATTE_GLOSSY_2BUF
if (ctx->matte != ctx->last_matte)
- ctx->buf_needed = 2; /* Switching needs both buffers */
+ buf_needed = 2; /* Switching needs both buffers */
#endif
ctx->last_matte = ctx->matte;
@@ -888,25 +861,23 @@ static int dnpds40_main_loop(void *vctx, int copies) {
top:
- if (resp) free(resp);
-
/* Query status */
dnpds40_build_cmd(&cmd, "STATUS", "", 0);
+ if (resp) free(resp);
resp = dnpds40_resp_cmd(ctx, &cmd, &len);
if (!resp)
return CUPS_BACKEND_FAILED;
dnpds40_cleanup_string((char*)resp, len);
status = atoi((char*)resp);
- free(resp);
/* Figure out what's going on */
switch(status) {
case 0: /* Idle; we can continue! */
- break;
case 1: /* Printing */
{
int bufs;
+ if (resp) free(resp);
/* Query buffer state */
dnpds40_build_cmd(&cmd, "INFO", "FREE_PBUFFER", 0);
resp = dnpds40_resp_cmd(ctx, &cmd, &len);
@@ -917,8 +888,8 @@ top:
dnpds40_cleanup_string((char*)resp, len);
/* Check to see if we have sufficient buffers */
bufs = atoi(((char*)resp)+3);
- if (bufs < ctx->buf_needed) {
- INFO("Insufficient printer buffers (%d vs %d), retrying...\n", bufs, ctx->buf_needed);
+ if (bufs < buf_needed) {
+ INFO("Insufficient printer buffers (%d vs %d), retrying...\n", bufs, buf_needed);
sleep(1);
goto top;
}
@@ -952,7 +923,56 @@ top:
ERROR("Fatal Printer Error: %d => %s, halting queue!\n", status, dnpds40_statuses(status));
return CUPS_BACKEND_HOLD;
}
-
+
+ /* Verify we have sufficient media for prints */
+ {
+ int i = 0;
+
+ /* See if we can rewind to save media */
+ if (ctx->can_rewind && ctx->supports_rewind) {
+ /* Tell the printer we want to rewind, if possible. */
+ snprintf(buf, sizeof(buf), "%08d", ctx->multicut + 400);
+ memcpy(ctx->multicut_offset, buf, 8);
+
+ /* Get Media remaining */
+ dnpds40_build_cmd(&cmd, "INFO", "RQTY", 0);
+
+ if (resp) free(resp);
+ resp = dnpds40_resp_cmd(ctx, &cmd, &len);
+ if (!resp)
+ return CUPS_BACKEND_FAILED;
+
+ dnpds40_cleanup_string((char*)resp, len);
+ i = atoi((char*)resp+4);
+ }
+
+ /* If we didn't succeed with RQTY, try MQTY */
+ if (i == 0) {
+ dnpds40_build_cmd(&cmd, "INFO", "MQTY", 0);
+
+ if (resp) free(resp);
+ resp = dnpds40_resp_cmd(ctx, &cmd, &len);
+ if (!resp)
+ return CUPS_BACKEND_FAILED;
+
+ dnpds40_cleanup_string((char*)resp, len);
+
+ i = atoi((char*)resp+4);
+
+ /* For some reason all but the DS620 report 50 too high */
+ if (ctx->type != P_DNP_DS620 && i > 0)
+ i -= 50;
+ }
+
+ if (i < 1) {
+ ERROR("Printer out of media, please correct!\n");
+ return CUPS_BACKEND_STOP;
+ }
+ if (i < copies) {
+ WARNING("Printer does not have sufficient remaining media to complete job..\n");
+ }
+ }
+
/* Send the stream over as individual data chunks */
ptr = ctx->databuf;
@@ -962,7 +982,6 @@ top:
memcpy(buf, ptr + 24, 8);
i = atoi(buf) + 32;
-
if ((ret = send_data(ctx->dev, ctx->endp_down,
ptr, i)))
return CUPS_BACKEND_FAILED;
@@ -973,27 +992,26 @@ top:
/* Clean up */
if (terminate)
copies = 1;
-
+
INFO("Print complete (%d copies remaining)\n", copies - 1);
if (copies && --copies) {
+#ifdef MATTE_GLOSSY_2BUF
+ /* No need to wait on buffers due to matte switching */
+ buf_needed = ctx->buf_needed;
+#endif
goto top;
}
return CUPS_BACKEND_OK;
}
-static int dnpds40_get_info(struct dnpds40_ctx *ctx)
+static int dnpds40_get_sensors(struct dnpds40_ctx *ctx)
{
struct dnpds40_cmd cmd;
uint8_t *resp;
int len = 0;
-
- /* Serial number already queried */
- INFO("Serial Number: '%s'\n", ctx->serno);
-
- /* Firmware version already queried */
- INFO("Firmware Version: '%s'\n", ctx->version);
+ char *tok;
/* Get Sensor Info */
dnpds40_build_cmd(&cmd, "INFO", "SENSOR", 0);
@@ -1003,33 +1021,72 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx)
return CUPS_BACKEND_FAILED;
dnpds40_cleanup_string((char*)resp, len);
- INFO("Sensor Info:\n");
- {
- char *tmp;
- tmp = strtok((char*)resp, "; ");
- do {
- // XXX parse the components?
- INFO(" %s\n", tmp);
- } while ((tmp = strtok(NULL, "; ")) != NULL);
- }
- free(resp);
+ tok = strtok((char*)resp, "; -");
+ do {
+ char *val = strtok(NULL, "; -");
+
+ if (!strcmp("HDT", tok)) {
+ INFO("Head Temperature : %s\n", val);
+ } else if (!strcmp("MDT", tok)) {
+ INFO("Media Temperature : %s\n", val);
+ } else if (!strcmp("PMK", tok)) {
+ INFO("Paper Mark : %s\n", val);
+ } else if (!strcmp("RML", tok)) {
+ INFO("Ribbon Mark Left : %s\n", val);
+ } else if (!strcmp("RMC", tok)) {
+ INFO("Ribbon Mark Right : %s\n", val);
+ } else if (!strcmp("RMR", tok)) {
+ INFO("Ribbon Mark Center : %s\n", val);
+ } else if (!strcmp("PSZ", tok)) {
+ INFO("Paper Size : %s\n", val);
+ } else if (!strcmp("PNT", tok)) {
+ INFO("Paper Notch : %s\n", val);
+ } else if (!strcmp("PJM", tok)) {
+ INFO("Paper Jam : %s\n", val);
+ } else if (!strcmp("PED", tok)) {
+ INFO("Paper End : %s\n", val);
+ } else if (!strcmp("PET", tok)) {
+ INFO("Paper Empty : %s\n", val);
+ } else if (!strcmp("HDV", tok)) {
+ INFO("Head Voltage : %s\n", val);
+ } else if (!strcmp("HMD", tok)) {
+ INFO("Humidity : %s\n", val);
+ } else if (!strcmp("RP1", tok)) {
+ INFO("Roll Paper End 1 : %s\n", val);
+ } else if (!strcmp("RP2", tok)) {
+ INFO("Roll Paper End 2 : %s\n", val);
+ } else if (!strcmp("GSR", tok)) {
+ INFO("Color Sensor Red : %s\n", val);
+ } else if (!strcmp("GSG", tok)) {
+ INFO("Color Sensor Green : %s\n", val);
+ } else if (!strcmp("GSB", tok)) {
+ INFO("Color Sensor Blue : %s\n", val);
+ } else {
+ INFO("Unknown Sensor: '%s' '%s'\n",
+ tok, val);
+ }
+ } while ((tok = strtok(NULL, "; -")) != NULL);
- /* Get Horizonal resolution */
- dnpds40_build_cmd(&cmd, "INFO", "RESOLUTION_H", 0);
+ free(resp);
- resp = dnpds40_resp_cmd(ctx, &cmd, &len);
- if (!resp)
- return CUPS_BACKEND_FAILED;
+ return CUPS_BACKEND_OK;
+}
- dnpds40_cleanup_string((char*)resp, len);
+static int dnpds40_get_info(struct dnpds40_ctx *ctx)
+{
+ struct dnpds40_cmd cmd;
+ uint8_t *resp;
+ int len = 0;
- INFO("Horizontal Resolution: '%s' dpi\n", (char*)resp + 3);
+ /* Serial number already queried */
+ INFO("Serial Number: '%s'\n", ctx->serno);
- free(resp);
+ /* Firmware version already queried */
+ INFO("Firmware Version: '%s'\n", ctx->version);
- /* Get Vertical resolution */
- dnpds40_build_cmd(&cmd, "INFO", "RESOLUTION_V", 0);
+ /* Get Media Color offset */
+ dnpds40_build_cmd(&cmd, "INFO", "MCOLOR", 0);
resp = dnpds40_resp_cmd(ctx, &cmd, &len);
if (!resp)
@@ -1037,12 +1094,13 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx)
dnpds40_cleanup_string((char*)resp, len);
- INFO("Vertical Resolution: '%s' dpi\n", (char*)resp + 3);
+ INFO("Media Color Offset: '%02x%02x%02x%02x'\n", *(resp+2), *(resp+3),
+ *(resp+4), *(resp+5));
free(resp);
- /* Get Media Color offset */
- dnpds40_build_cmd(&cmd, "INFO", "MCOLOR", 0);
+ /* Get Media Class */
+ dnpds40_build_cmd(&cmd, "INFO", "MEDIA_CLASS", 0);
resp = dnpds40_resp_cmd(ctx, &cmd, &len);
if (!resp)
@@ -1050,8 +1108,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx)
dnpds40_cleanup_string((char*)resp, len);
- INFO("Media Color Offset: '%02x%02x%02x%02x'\n", *(resp+2), *(resp+3),
- *(resp+4), *(resp+5));
+ INFO("Media Class: '%s'\n", (char*)resp);
free(resp);
@@ -1085,87 +1142,74 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx)
free(resp);
- if (ctx->type == P_DNP_DS620) {
- /* Loop through control data versions and checksums */
-
- /* 300 DPI */
- dnpds40_build_cmd(&cmd, "TBL_RD", "CWD300_Version", 0);
-
- resp = dnpds40_resp_cmd(ctx, &cmd, &len);
- if (!resp)
- return CUPS_BACKEND_FAILED;
-
- dnpds40_cleanup_string((char*)resp, len);
-
- INFO("300 DPI Color Data Version: '%s' ", (char*)resp);
-
- free(resp);
+ /* Get Ribbon ID code (?) */
+ dnpds40_build_cmd(&cmd, "MNT_RD", "RIBBON_ID_CODE", 0);
- dnpds40_build_cmd(&cmd, "TBL_RD", "CWD300_Checksum", 0);
+ resp = dnpds40_resp_cmd(ctx, &cmd, &len);
+ if (!resp)
+ return CUPS_BACKEND_FAILED;
- resp = dnpds40_resp_cmd(ctx, &cmd, &len);
- if (!resp)
- return CUPS_BACKEND_FAILED;
+ dnpds40_cleanup_string((char*)resp, len);
- dnpds40_cleanup_string((char*)resp, len);
+ INFO("Ribbon ID(?): '%s'\n", (char*)resp+4);
- INFO("Checksum: '%s'\n", (char*)resp);
+ free(resp);
- free(resp);
+ /* Figure out control data and checksums */
- /* 600 DPI */
- dnpds40_build_cmd(&cmd, "TBL_RD", "CWD600_Version", 0);
+ /* 300 DPI */
+ dnpds40_build_cmd(&cmd, "TBL_RD", "CWD300_Version", 0);
- resp = dnpds40_resp_cmd(ctx, &cmd, &len);
- if (!resp)
- return CUPS_BACKEND_FAILED;
+ resp = dnpds40_resp_cmd(ctx, &cmd, &len);
+ if (!resp)
+ return CUPS_BACKEND_FAILED;
- dnpds40_cleanup_string((char*)resp, len);
+ dnpds40_cleanup_string((char*)resp, len);
- INFO("600 DPI Color Data Version: '%s' ", (char*)resp);
+ INFO("300 DPI Color Data Version: '%s' ", (char*)resp);
- free(resp);
+ free(resp);
- dnpds40_build_cmd(&cmd, "TBL_RD", "CWD600_Checksum", 0);
+ dnpds40_build_cmd(&cmd, "TBL_RD", "CWD300_Checksum", 0);
- resp = dnpds40_resp_cmd(ctx, &cmd, &len);
- if (!resp)
- return CUPS_BACKEND_FAILED;
+ resp = dnpds40_resp_cmd(ctx, &cmd, &len);
+ if (!resp)
+ return CUPS_BACKEND_FAILED;
- dnpds40_cleanup_string((char*)resp, len);
+ dnpds40_cleanup_string((char*)resp, len);
- INFO("Checksum: '%s'\n", (char*)resp);
+ DEBUG2("Checksum: '%s'\n", (char*)resp);
- free(resp);
+ free(resp);
- /* "Low Speed" */
- dnpds40_build_cmd(&cmd, "TBL_RD", "CWD610_Version", 0);
+ /* 600 DPI */
+ dnpds40_build_cmd(&cmd, "TBL_RD", "CWD600_Version", 0);
- resp = dnpds40_resp_cmd(ctx, &cmd, &len);
- if (!resp)
- return CUPS_BACKEND_FAILED;
+ resp = dnpds40_resp_cmd(ctx, &cmd, &len);
+ if (!resp)
+ return CUPS_BACKEND_FAILED;
- dnpds40_cleanup_string((char*)resp, len);
+ dnpds40_cleanup_string((char*)resp, len);
- INFO("Low Speed Color Data Version: '%s' ", (char*)resp);
+ INFO("600 DPI Color Data Version: '%s' ", (char*)resp);
- free(resp);
+ free(resp);
- dnpds40_build_cmd(&cmd, "TBL_RD", "CWD610_Checksum", 0);
+ dnpds40_build_cmd(&cmd, "TBL_RD", "CWD600_Checksum", 0);
- resp = dnpds40_resp_cmd(ctx, &cmd, &len);
- if (!resp)
- return CUPS_BACKEND_FAILED;
+ resp = dnpds40_resp_cmd(ctx, &cmd, &len);
+ if (!resp)
+ return CUPS_BACKEND_FAILED;
- dnpds40_cleanup_string((char*)resp, len);
+ dnpds40_cleanup_string((char*)resp, len);
- INFO("Checksum: '%s'\n", (char*)resp);
+ DEBUG2("Checksum: '%s'\n", (char*)resp);
- free(resp);
+ free(resp);
- } else {
- /* Get Color Control Data Version */
- dnpds40_build_cmd(&cmd, "TBL_RD", "Version", 0);
+ if (ctx->type == P_DNP_DS620) {
+ /* "Low Speed" */
+ dnpds40_build_cmd(&cmd, "TBL_RD", "CWD610_Version", 0);
resp = dnpds40_resp_cmd(ctx, &cmd, &len);
if (!resp)
@@ -1173,12 +1217,11 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx)
dnpds40_cleanup_string((char*)resp, len);
- INFO("Color Data Version: '%s'\n", (char*)resp);
+ INFO("Low Speed Color Data Version: '%s' ", (char*)resp);
free(resp);
- /* Get Color Control Data Checksum */
- dnpds40_build_cmd(&cmd, "MNT_RD", "CTRLD_CHKSUM", 0);
+ dnpds40_build_cmd(&cmd, "TBL_RD", "CWD610_Checksum", 0);
resp = dnpds40_resp_cmd(ctx, &cmd, &len);
if (!resp)
@@ -1186,7 +1229,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx)
dnpds40_cleanup_string((char*)resp, len);
- INFO("Color Data Checksum: '%s'\n", (char*)resp);
+ DEBUG2("Checksum: '%s'\n", (char*)resp);
free(resp);
}
@@ -1217,7 +1260,9 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx)
INFO("Media End kept across power cycles: '%s'\n", (char*)resp);
free(resp);
+ }
+ if (ctx->supports_iserial) {
/* Get USB serial descriptor status */
dnpds40_build_cmd(&cmd, "MNT_RD", "USB_ISERI_SET", 0);
@@ -1284,7 +1329,7 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx)
/* Report media */
INFO("Media Type: '%s'\n", dnpds40_media_types(ctx->media));
- if (ctx->supports_rewind) {
+ if (ctx->supports_mqty_default) {
/* Get Media remaining */
dnpds40_build_cmd(&cmd, "INFO", "MQTY_DEFAULT", 0);
@@ -1460,6 +1505,38 @@ static int dnpds620_standby_mode(struct dnpds40_ctx *ctx, int delay)
return 0;
}
+static int dnpds620_media_keep_mode(struct dnpds40_ctx *ctx, int delay)
+{
+ struct dnpds40_cmd cmd;
+ char msg[9];
+ int ret;
+
+ /* Generate command */
+ dnpds40_build_cmd(&cmd, "MNT_WT", "END_KEEP_MODE", 4);
+ snprintf(msg, sizeof(msg), "%02d\r", delay);
+
+ if ((ret = dnpds40_do_cmd(ctx, &cmd, (uint8_t*)msg, 4)))
+ return ret;
+
+ return 0;
+}
+
+static int dnpds620_iserial_mode(struct dnpds40_ctx *ctx, int enable)
+{
+ struct dnpds40_cmd cmd;
+ char msg[9];
+ int ret;
+
+ /* Generate command */
+ dnpds40_build_cmd(&cmd, "MNT_WT", "USB_ISERI_SET", 4);
+ snprintf(msg, sizeof(msg), "%02d\r", enable);
+
+ if ((ret = dnpds40_do_cmd(ctx, &cmd, (uint8_t*)msg, 8)))
+ return ret;
+
+ return 0;
+}
+
static int dnpds40_set_counter_p(struct dnpds40_ctx *ctx, char *arg)
{
struct dnpds40_cmd cmd;
@@ -1480,12 +1557,14 @@ static int dnpds40_set_counter_p(struct dnpds40_ctx *ctx, char *arg)
static void dnpds40_cmdline(void)
{
DEBUG("\t\t[ -i ] # Query printer info\n");
+ DEBUG("\t\t[ -I ] # Query sensor info\n");
DEBUG("\t\t[ -s ] # Query status\n");
DEBUG("\t\t[ -n ] # Query counters\n");
DEBUG("\t\t[ -N A|B|M ] # Clear counter A/B/M\n");
DEBUG("\t\t[ -p num ] # Set counter P\n");
- DEBUG("\t\t[ -S num ] # Set standby time (1-99 minutes, 0 disables)\n");
-
+ DEBUG("\t\t[ -k num ] # Set standby time (1-99 minutes, 0 disables)\n");
+ DEBUG("\t\t[ -K num ] # Keep Media Status Across Power Cycles (1 on, 0 off)\n");
+ DEBUG("\t\t[ -x num ] # Set USB iSerialNumber Reporting (1 on, 0 off)\n");
}
static int dnpds40_cmdline_arg(void *vctx, int argc, char **argv)
@@ -1493,64 +1572,86 @@ static int dnpds40_cmdline_arg(void *vctx, int argc, char **argv)
struct dnpds40_ctx *ctx = vctx;
int i, j = 0;
+ if (!ctx)
+ return -1;
+
/* Reset arg parsing */
optind = 1;
opterr = 0;
- while ((i = getopt(argc, argv, "inN:p:sS:")) >= 0) {
+ while ((i = getopt(argc, argv, GETOPT_LIST_GLOBAL "iInN:p:sK:k:")) >= 0) {
switch(i) {
+ GETOPT_PROCESS_GLOBAL
case 'i':
- if (ctx) {
- j = dnpds40_get_info(ctx);
- break;
- }
- return 1;
+ j = dnpds40_get_info(ctx);
+ break;
+ case 'I':
+ j = dnpds40_get_sensors(ctx);
+ break;
case 'n':
- if (ctx) {
- j = dnpds40_get_counters(ctx);
- break;
- }
- return 1;
+ j = dnpds40_get_counters(ctx);
+ break;
case 'N':
if (optarg[0] != 'A' &&
optarg[0] != 'B' &&
optarg[0] != 'M')
return CUPS_BACKEND_FAILED;
- if (ctx) {
- if (!ctx->supports_matte) {
- ERROR("Printer FW does not support matte functions, please update!\n");
- return CUPS_BACKEND_FAILED;
- }
- j = dnpds40_clear_counter(ctx, optarg[0]);
- break;
+ if (!ctx->supports_matte) {
+ ERROR("Printer FW does not support matte functions, please update!\n");
+ return CUPS_BACKEND_FAILED;
}
- return 1;
+ j = dnpds40_clear_counter(ctx, optarg[0]);
+ break;
case 'p':
- if (ctx) {
- j = dnpds40_set_counter_p(ctx, optarg);
+ j = dnpds40_set_counter_p(ctx, optarg);
+ break;
+ case 's':
+ j = dnpds40_get_status(ctx);
+ break;
+ case 'k': {
+ int time = atoi(optarg);
+ if (!ctx->supports_standby) {
+ ERROR("Printer does not support standby\n");
+ j = -1;
break;
}
- return 1;
- case 's':
- if (ctx) {
- j = dnpds40_get_status(ctx);
+ if (time < 0 || time > 99) {
+ ERROR("Value out of range (0-99)");
+ j = -1;
break;
}
- return 1;
- case 'S':
- if (ctx) {
- int time = atoi(optarg);
- if (!ctx->supports_standby) {
- ERROR("Printer does not support standby\n");
- j = -1;
- break;
- }
- if (time < 0 || time > 99) {
- ERROR("Value out of range (0-99)");
- j = -1;
- break;
- }
- j = dnpds620_standby_mode(ctx, time);
+ j = dnpds620_standby_mode(ctx, time);
+ break;
+ }
+ case 'K': {
+ int keep = atoi(optarg);
+ if (!ctx->supports_standby) {
+ ERROR("Printer does not support media keep mode\n");
+ j = -1;
+ break;
+ }
+ if (keep < 0 || keep > 1) {
+ ERROR("Value out of range (0-1)");
+ j = -1;
+ break;
}
+ j = dnpds620_media_keep_mode(ctx, keep);
+ break;
+ }
+ case 'x': {
+ int enable = atoi(optarg);
+ if (!ctx->supports_iserial) {
+ ERROR("Printer does not support USB iSerialNumber reporting\n");
+ j = -1;
+ break;
+ }
+ if (enable < 0 || enable > 1) {
+ ERROR("Value out of range (0-1)");
+ j = -1;
+ break;
+ }
+ j = dnpds620_iserial_mode(ctx, enable);
+ break;
+ }
default:
break; /* Ignore completely */
}
@@ -1564,7 +1665,7 @@ static int dnpds40_cmdline_arg(void *vctx, int argc, char **argv)
/* Exported */
struct dyesub_backend dnpds40_backend = {
.name = "DNP DS40/DS80/DSRX1/DS620",
- .version = "0.51",
+ .version = "0.61",
.uri_prefix = "dnpds40",
.cmdline_usage = dnpds40_cmdline,
.cmdline_arg = dnpds40_cmdline_arg,