updneo: Major fixes for Sony UP-D898MD
* Add USB PID * Validate job parameters against printer's max reported dimensions * Serial numbers reported correctly * Handle two more status marker types * Better media status reporting * Printer-generated copies * Issue USB Reset between printsmaster
parent
30a8bf2d65
commit
a3dea1d400
4
README
4
README
|
@ -68,6 +68,7 @@
|
|||
Sony UP-DR200
|
||||
Sony UP-D895
|
||||
Sony UP-D897
|
||||
Sony UP-D898 series
|
||||
Stryker SDP1000
|
||||
|
||||
Work-in-progress Printers:
|
||||
|
@ -96,7 +97,6 @@
|
|||
Shinko CHC-S6145-5A (aka Sinfonia CS2-c)
|
||||
Shinko CHC-S6245 (aka Sinfonia CE1)
|
||||
Sony UP-CR20L (aka DNP DS-SL20)
|
||||
Sony UP-D898 series
|
||||
Sony UP-DR80
|
||||
|
||||
***************************************************************************
|
||||
|
@ -893,6 +893,7 @@
|
|||
|
||||
Sony UP-DR80MD
|
||||
Stryker SDP1000
|
||||
Sony UP-D898 / UP-X898
|
||||
|
||||
Work-in-progress printers
|
||||
|
||||
|
@ -900,7 +901,6 @@
|
|||
|
||||
Work-in-progress printers (Lack USB PIDs)
|
||||
|
||||
Sony UP-D898 / UP-X898
|
||||
Sony UP-CR20L
|
||||
DNP DS-SL20
|
||||
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
|
||||
/* Private data structures */
|
||||
struct updneo_printjob {
|
||||
size_t jobsize;
|
||||
int copies;
|
||||
|
||||
uint8_t *databuf;
|
||||
int datalen;
|
||||
uint8_t *hdrbuf;
|
||||
|
@ -37,10 +40,6 @@ struct updneo_printjob {
|
|||
uint8_t *ftrbuf;
|
||||
int ftrlen;
|
||||
|
||||
// int copies_offset; // XXX eventually implement
|
||||
|
||||
int copies;
|
||||
|
||||
uint16_t rows;
|
||||
uint16_t cols;
|
||||
};
|
||||
|
@ -59,13 +58,15 @@ struct updneo_sts {
|
|||
uint16_t scmde;
|
||||
uint8_t scmce;
|
||||
char scjbi[17]; /* 16 char string, unknown */
|
||||
char scsyi[31]; /* 30 char string, unknown */
|
||||
char scsyi[31]; /* 30 char string, max resolution? */
|
||||
uint32_t scsvi[2]; /* 2* 6char numbers */
|
||||
uint32_t scmni[2]; /* 2* 6char numbers */
|
||||
char sccai[15]; /* 14 char string, unknown */
|
||||
uint16_t scgai;
|
||||
uint8_t scgsi;
|
||||
uint32_t scmdi;
|
||||
uint32_t scqti;
|
||||
uint32_t spuqi;
|
||||
};
|
||||
|
||||
struct updneo_ctx {
|
||||
|
@ -92,6 +93,8 @@ static const char* updneo_decode_errors(uint16_t mde, uint8_t mce, uint8_t sye)
|
|||
return "No paper loaded";
|
||||
if (mde == 0x0002)
|
||||
return "No ribbon loaded";
|
||||
if (mde == 0x0300)
|
||||
return "No media loaded";
|
||||
if (mde == 0x2000)
|
||||
return "Job does not match installed media";
|
||||
|
||||
|
@ -109,6 +112,19 @@ static void* updneo_init(void)
|
|||
return ctx;
|
||||
}
|
||||
|
||||
static const char *updneo_medias(uint32_t mdi)
|
||||
{
|
||||
mdi >>= 16;
|
||||
mdi &= 0xff;
|
||||
|
||||
switch(mdi) {
|
||||
case 0x11: return "UPC-R81MD (Letter)";
|
||||
// UPC-R80MD (A4)
|
||||
case 0x20: return "UPP-110 Roll";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static int updneo_attach(void *vctx, struct dyesub_connection *conn, uint8_t jobid)
|
||||
{
|
||||
struct updneo_ctx *ctx = vctx;
|
||||
|
@ -122,14 +138,22 @@ static int updneo_attach(void *vctx, struct dyesub_connection *conn, uint8_t job
|
|||
if ((ret = updneo_get_status(ctx))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Needed by the UP-D898! But should be safe for
|
||||
all models */
|
||||
libusb_reset_device(ctx->conn->dev);
|
||||
}
|
||||
|
||||
if (test_mode >= TEST_MODE_NOATTACH && getenv("MEDIA_CODE"))
|
||||
ctx->marker.numtype = atoi(getenv("MEDIA_CODE"));
|
||||
else
|
||||
ctx->marker.numtype = (ctx->sts.scmdi >> 16) & 0xff;
|
||||
|
||||
ctx->marker.name = updneo_medias(ctx->sts.scmdi);
|
||||
|
||||
if (ctx->conn->type == P_SONY_UPD898) {
|
||||
ctx->marker.color = "#000000"; /* Ie black! */
|
||||
ctx->native_bpp = 1;
|
||||
|
||||
ctx->marker.name = "Unknown";
|
||||
ctx->marker.numtype = -1;
|
||||
ctx->marker.levelmax = CUPS_MARKER_UNAVAILABLE;
|
||||
ctx->marker.levelnow = CUPS_MARKER_UNKNOWN;
|
||||
} else {
|
||||
|
@ -138,15 +162,6 @@ static int updneo_attach(void *vctx, struct dyesub_connection *conn, uint8_t job
|
|||
ctx->marker.levelmax = 50;
|
||||
ctx->marker.numtype = (ctx->sts.scmdi >> 16) & 0xff;
|
||||
ctx->marker.levelnow = ctx->sts.scmds[4];
|
||||
|
||||
if (test_mode >= TEST_MODE_NOATTACH && getenv("MEDIA_CODE"))
|
||||
ctx->marker.numtype = atoi(getenv("MEDIA_CODE"));
|
||||
|
||||
if (ctx->marker.numtype == 0x11) { /* UP-DR80MD */
|
||||
ctx->marker.name = "UPC-R81MD (Letter)"; // vs UPC-R80MD (A4)
|
||||
} else {
|
||||
ctx->marker.name = "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
return CUPS_BACKEND_OK;
|
||||
|
@ -307,11 +322,37 @@ static int updneo_read_parse(void *vctx, const void **vjob, int data_fd, int cop
|
|||
}
|
||||
|
||||
/* Sanity check job parameters */
|
||||
// XXX rows * cols lines up with imgsize, and others?
|
||||
// Check vs loaded media type (ctx->marker.numtype, plus scsyi)
|
||||
|
||||
// set job copies to max(job, parameter)
|
||||
// job->copies = copies;
|
||||
/* Validate against max print size in SCSYI */
|
||||
{
|
||||
char w[5], h[5];
|
||||
uint16_t mw, mh;
|
||||
uint16_t jw, jh;
|
||||
memcpy(h, ctx->sts.scsyi, 4);
|
||||
h[4] = 0;
|
||||
memcpy(w, ctx->sts.scsyi + 4, 4);
|
||||
w[4] = 0;
|
||||
mw = strtol(w, NULL, 16);
|
||||
mh = strtol(h, NULL, 16);
|
||||
|
||||
memcpy(&jw, job->databuf + 40, 2);
|
||||
memcpy(&jh, job->databuf + 40 + 2, 2);
|
||||
|
||||
jw = be16_to_cpu(jw);
|
||||
jh = be16_to_cpu(jh);
|
||||
|
||||
if (jw > mw || jh > mh) {
|
||||
ERROR("Job (%dx%d) exceeds max dimensions(%d/%d)\n",
|
||||
jw,jh,mw,mh);
|
||||
updneo_cleanup_job(job);
|
||||
return CUPS_BACKEND_CANCEL;
|
||||
}
|
||||
}
|
||||
|
||||
// XXX Check vs loaded media type (ctx->marker.numtype?)
|
||||
|
||||
// XXX set job copies to max(job, parameter)
|
||||
job->databuf[28] = job->copies;
|
||||
job->copies = 1; /* Printer makes copies */
|
||||
UNUSED(copies);
|
||||
|
||||
|
@ -346,6 +387,14 @@ static int updneo_get_status(struct updneo_ctx *ctx)
|
|||
ctx->sts.scsyv = strtol(dict[i].val, NULL, 16);
|
||||
} else if (!strcmp("SCSNO", dict[i].key)) {
|
||||
strncpy(ctx->sts.scsno, dict[i].val, sizeof(ctx->sts.scsno) - 1);
|
||||
|
||||
/* Trim trailing '-'s off of serial number (UP-D898)*/
|
||||
for (int i = 0; i < (int) sizeof(ctx->sts.scsno); i++) {
|
||||
if (ctx->sts.scsno[i] == '-') {
|
||||
ctx->sts.scsno[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp("SCSYS", dict[i].key)) {
|
||||
strncpy(ctx->sts.scsys, dict[i].val, sizeof(ctx->sts.scsys) - 1);
|
||||
} else if (!strcmp("SCMDS", dict[i].key)) {
|
||||
|
@ -398,15 +447,18 @@ static int updneo_get_status(struct updneo_ctx *ctx)
|
|||
ctx->sts.scgsi = strtol(dict[i].val, NULL, 16);
|
||||
} else if (!strcmp("SCMDI", dict[i].key)) {
|
||||
ctx->sts.scmdi = strtol(dict[i].val, NULL, 16);
|
||||
} else if (!strcmp("SCQTI", dict[i].key)) {
|
||||
ctx->sts.scqti = strtol(dict[i].val, NULL, 16);
|
||||
} else if (!strcmp("SPUQI", dict[i].key)) {
|
||||
ctx->sts.spuqi = strtol(dict[i].val, NULL, 16);
|
||||
} else if (!strcmp("MFG", dict[i].key) ||
|
||||
!strcmp("MDL", dict[i].key) ||
|
||||
!strcmp("DES", dict[i].key) ||
|
||||
!strcmp("CMD", dict[i].key) ||
|
||||
!strcmp("CLS", dict[i].key))
|
||||
{
|
||||
!strcmp("CLS", dict[i].key)) {
|
||||
/* Ignore standard IEEE1284 attributes! */
|
||||
} else {
|
||||
if (!strncmp("SC", dict[i].key, 2))
|
||||
if (!strncmp("SC", dict[i].key, 2) && !strncmp("SP", dict[i].key, 2))
|
||||
DEBUG("Extra/Unknown IEEE1284 field '%s' = '%s'\n",
|
||||
dict[i].key, dict[i].val);
|
||||
}
|
||||
|
@ -423,7 +475,7 @@ static int updneo_get_status(struct updneo_ctx *ctx)
|
|||
return CUPS_BACKEND_OK;
|
||||
}
|
||||
|
||||
static void updneo_dump_status(struct updneo_sts *sts)
|
||||
static void updneo_dump_status(struct updneo_ctx *ctx, struct updneo_sts *sts)
|
||||
{
|
||||
/* Dump status */
|
||||
INFO("Serial Number: %s\n", sts->scsno);
|
||||
|
@ -432,8 +484,11 @@ static void updneo_dump_status(struct updneo_sts *sts)
|
|||
(sts->scsyv >> 16) & 0xff,
|
||||
(sts->scsyv >> 8) & 0xff,
|
||||
(sts->scsyv >> 0) & 0xff);
|
||||
INFO("Media type: %s\n", sts->scmdi == 0x110154 ? "UPC-R81MD (Letter)" : "Unknown");
|
||||
INFO("Remaining prints: %u/50\n", sts->scmds[4]);
|
||||
INFO("Media type: %s\n", updneo_medias(sts->scmdi));
|
||||
|
||||
if (ctx->conn->type == P_SONY_UPDR80)
|
||||
INFO("Remaining prints: %u/50\n", sts->scmds[4]);
|
||||
|
||||
INFO("Print count: %u\n", sts->scsvi[0]);
|
||||
|
||||
/* If the printer reports an error, pass it on */
|
||||
|
@ -528,6 +583,10 @@ retry:
|
|||
goto top;
|
||||
}
|
||||
|
||||
/* Needed by the UP-D898! But should be safe for
|
||||
all models */
|
||||
libusb_reset_device(ctx->conn->dev);
|
||||
|
||||
return CUPS_BACKEND_OK;
|
||||
}
|
||||
|
||||
|
@ -550,7 +609,7 @@ static int updneo_cmdline_arg(void *vctx, int argc, char **argv)
|
|||
case 's':
|
||||
j = updneo_get_status(ctx);
|
||||
if (!j)
|
||||
updneo_dump_status(&ctx->sts);
|
||||
updneo_dump_status(ctx, &ctx->sts);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -567,7 +626,6 @@ static int updneo_query_serno(struct dyesub_connection *conn, char *buf, int buf
|
|||
struct updneo_ctx ctx = {
|
||||
.conn = conn,
|
||||
};
|
||||
|
||||
if ((ret = updneo_get_status(&ctx))) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -575,7 +633,6 @@ static int updneo_query_serno(struct dyesub_connection *conn, char *buf, int buf
|
|||
while (*ptr == 0x30) ptr++;
|
||||
strncpy(buf, ptr, buf_len);
|
||||
buf[buf_len-1] = 0;
|
||||
|
||||
return CUPS_BACKEND_OK;
|
||||
}
|
||||
|
||||
|
@ -606,8 +663,8 @@ static const char *sonyupdneo_prefixes[] = {
|
|||
};
|
||||
|
||||
/* Exported */
|
||||
#define USB_VID_SONY 0x054C
|
||||
#define USB_PID_SONY_UPD898MD 0xabcd // 0x589a?
|
||||
#define USB_VID_SONY 0x054C
|
||||
#define USB_PID_SONY_UPD898MD 0x0877 // 0x589a?
|
||||
#define USB_PID_SONY_UPCR20L 0xbcde
|
||||
#define USB_PID_SONY_UPDR80MD 0x03c3
|
||||
#define USB_PID_STRYKER_SDP1000 0x03c4
|
||||
|
@ -616,7 +673,8 @@ static const char *sonyupdneo_prefixes[] = {
|
|||
|
||||
const struct dyesub_backend sonyupdneo_backend = {
|
||||
.name = "Sony UP-D Neo",
|
||||
.version = "0.11",
|
||||
.version = "0.12",
|
||||
.flags = BACKEND_FLAG_BADISERIAL, /* UP-D898MD at least */
|
||||
.uri_prefixes = sonyupdneo_prefixes,
|
||||
.cmdline_arg = updneo_cmdline_arg,
|
||||
.cmdline_usage = updneo_cmdline,
|
||||
|
@ -833,6 +891,12 @@ const struct dyesub_backend sonyupdneo_backend = {
|
|||
|
||||
[ Notable difference is SCSYI ]
|
||||
|
||||
UP-DR898MD
|
||||
|
||||
MFG:Sony;MDL:UP-D898MD_X898MD;DES:Sony UP-D898MD_X898MD;CMD:SPJL-DS,SPDL-DS2;CLS:PRINTER;SCDIV:0100;SCSYV:01010000;SCSYS:0000001000010000000000;SCMDS:00000500000100000000;SCSYE:00;SCMDE:0000;SCMCE:00;SCSYI:100005001000050000000000014500;SCSVI:000204000204;SCMDI:200406;SCSNO:7100886---------;SCJBS:0000;SCCAI:00000000000000;SCGSI:01;SCQTI:0001;SPUQI:0000
|
||||
|
||||
[ This adds SCQTI; SCSNO is formatted differently, no SCPRS/SCJBI ]
|
||||
|
||||
Breakdown:
|
||||
|
||||
(+) means referenced by their Windows driver
|
||||
|
@ -857,6 +921,8 @@ Breakdown:
|
|||
SCGAI
|
||||
SCGSI
|
||||
+SCMDI # MeDiaInfo: 110154 OK w/UPD-R81MD(Letter), 1100FF with no paper, 000154 with no ribbon
|
||||
SCQTI # QT Info (898MD)
|
||||
SPUQI # UQ Info (898MD)
|
||||
|
||||
Guess:
|
||||
|
||||
|
|
Loading…
Reference in New Issue