common: Introduce a common USB connection object, and use it!

This commit is contained in:
Solomon Peachy 2020-08-11 20:27:26 -04:00
parent 1bd14cff80
commit 322ad8d7b7
22 changed files with 518 additions and 692 deletions

View file

@ -542,10 +542,7 @@ struct canonselphy_printjob {
};
struct canonselphy_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
int type;
struct dyesub_connection *conn;
struct printer_data *printer;
struct marker marker;
@ -559,13 +556,13 @@ static int canonselphy_get_status(struct canonselphy_ctx *ctx)
int ret, num;
/* Read in the printer status, twice. */
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) rdbuf, READBACK_LEN, &num);
ret = read_data(ctx->conn,
(uint8_t*) rdbuf, READBACK_LEN, &num);
if (ret < 0)
return CUPS_BACKEND_FAILED;
ret = read_data(ctx->dev, ctx->endp_up,
(uint8_t*) rdbuf, READBACK_LEN, &num);
ret = read_data(ctx->conn,
(uint8_t*) rdbuf, READBACK_LEN, &num);
if (ret < 0)
return CUPS_BACKEND_FAILED;
@ -583,8 +580,8 @@ static int canonselphy_send_reset(struct canonselphy_ctx *ctx)
0x00, 0x00, 0x00, 0x00 };
int ret;
if ((ret = send_data(ctx->dev, ctx->endp_down,
rstcmd, sizeof(rstcmd))))
if ((ret = send_data(ctx->conn,
rstcmd, sizeof(rstcmd))))
return CUPS_BACKEND_FAILED;
return CUPS_BACKEND_OK;
@ -605,27 +602,21 @@ static void *canonselphy_init(void)
return ctx;
}
static int canonselphy_attach(void *vctx, struct libusb_device_handle *dev, int type,
uint8_t endp_up, uint8_t endp_down, int iface, uint8_t jobid)
static int canonselphy_attach(void *vctx, struct dyesub_connection *conn, uint8_t jobid)
{
struct canonselphy_ctx *ctx = vctx;
int i, num;
uint8_t rdbuf[READBACK_LEN];
UNUSED(jobid);
UNUSED(iface);
ctx->dev = dev;
ctx->endp_up = endp_up;
ctx->endp_down = endp_down;
ctx->type = type;
ctx->conn = conn;
if (ctx->type == P_CP900) {
ctx->type = P_CP_XXX;
if (ctx->conn->type == P_CP900) {
ctx->conn->type = P_CP_XXX;
ctx->cp900 = 1;
}
for (i = 0 ; selphy_printers[i].type != -1; i++) {
if (selphy_printers[i].type == ctx->type) {
if (selphy_printers[i].type == ctx->conn->type) {
ctx->printer = &selphy_printers[i];
}
}
@ -640,12 +631,12 @@ static int canonselphy_attach(void *vctx, struct libusb_device_handle *dev, int
if (test_mode < TEST_MODE_NOATTACH) {
/* Read printer status. Twice. */
i = read_data(ctx->dev, ctx->endp_up,
i = read_data(ctx->conn,
rdbuf, READBACK_LEN, &num);
if (i < 0)
return CUPS_BACKEND_FAILED;
i = read_data(ctx->dev, ctx->endp_up,
i = read_data(ctx->conn,
rdbuf, READBACK_LEN, &num);
if (i < 0)
return CUPS_BACKEND_FAILED;
@ -743,14 +734,14 @@ static int canonselphy_read_parse(void *vctx, const void **vjob, int data_fd, in
printer_type = parse_printjob(rdbuf, &job->bw_mode, &job->plane_len);
/* Special cases for some models */
if (printer_type == P_ES40_CP790) {
if (ctx->type == P_CP790)
if (ctx->conn->type == P_CP790)
printer_type = P_CP790;
else
printer_type = P_ES40;
}
if (printer_type != ctx->type) {
ERROR("Printer/Job mismatch (%d/%d/%d)\n", ctx->type, ctx->printer->type, printer_type);
if (printer_type != ctx->conn->type) {
ERROR("Printer/Job mismatch (%d/%d/%d)\n", ctx->conn->type, ctx->printer->type, printer_type);
canonselphy_cleanup_job(job);
return CUPS_BACKEND_CANCEL;
}
@ -853,7 +844,7 @@ static int canonselphy_main_loop(void *vctx, const void *vjob) {
copies = job->copies;
/* Read in the printer status to clear last state */
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
rdbuf, READBACK_LEN, &num);
if (ret < 0)
@ -866,7 +857,7 @@ top:
}
/* Read in the printer status */
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
rdbuf, READBACK_LEN, &num);
if (ret < 0)
return CUPS_BACKEND_FAILED;
@ -881,7 +872,7 @@ top:
dump_markers(&ctx->marker, 1, 0);
if (ctx->printer->clear_error_len)
/* Try to clear error state */
if ((ret = send_data(ctx->dev, ctx->endp_down, ctx->printer->clear_error, ctx->printer->clear_error_len)))
if ((ret = send_data(ctx->conn, ctx->printer->clear_error, ctx->printer->clear_error_len)))
return CUPS_BACKEND_FAILED;
return CUPS_BACKEND_HOLD;
}
@ -903,7 +894,7 @@ top:
/* Make sure paper/ribbon is correct */
if (job->paper_code != -1) {
if (ctx->type == P_CP_XXX) {
if (ctx->conn->type == P_CP_XXX) {
uint8_t pc = rdbuf[ctx->printer->paper_code_offset];
if (((pc >> 4) & 0xf) != (job->paper_code & 0x0f)) {
@ -934,7 +925,7 @@ top:
return CUPS_BACKEND_HOLD; /* Hold this job, don't stop queue */
}
}
} else if (ctx->type == P_CP790) {
} else if (ctx->conn->type == P_CP790) {
uint8_t ribbon = rdbuf[4] >> 4;
uint8_t paper = rdbuf[5];
@ -959,7 +950,7 @@ top:
case S_PRINTER_READY:
INFO("Printing started; Sending init sequence\n");
/* Send printer init */
if ((ret = send_data(ctx->dev, ctx->endp_down, job->header, ctx->printer->init_length)))
if ((ret = send_data(ctx->conn, job->header, ctx->printer->init_length)))
return CUPS_BACKEND_FAILED;
state = S_PRINTER_INIT_SENT;
@ -975,7 +966,7 @@ top:
else
INFO("Sending YELLOW plane\n");
if ((ret = send_data(ctx->dev, ctx->endp_down, job->plane_y, job->plane_len)))
if ((ret = send_data(ctx->conn, job->plane_y, job->plane_len)))
return CUPS_BACKEND_FAILED;
state = S_PRINTER_Y_SENT;
@ -991,7 +982,7 @@ top:
case S_PRINTER_READY_M:
INFO("Sending MAGENTA plane\n");
if ((ret = send_data(ctx->dev, ctx->endp_down, job->plane_m, job->plane_len)))
if ((ret = send_data(ctx->conn, job->plane_m, job->plane_len)))
return CUPS_BACKEND_FAILED;
state = S_PRINTER_M_SENT;
@ -1004,7 +995,7 @@ top:
case S_PRINTER_READY_C:
INFO("Sending CYAN plane\n");
if ((ret = send_data(ctx->dev, ctx->endp_down, job->plane_c, job->plane_len)))
if ((ret = send_data(ctx->conn, job->plane_c, job->plane_len)))
return CUPS_BACKEND_FAILED;
state = S_PRINTER_C_SENT;
@ -1021,7 +1012,7 @@ top:
uint32_t empty = 0;
INFO("Sending CP900 Footer\n");
if ((ret = send_data(ctx->dev, ctx->endp_down,
if ((ret = send_data(ctx->conn,
(uint8_t*)&empty, sizeof(empty))))
return CUPS_BACKEND_FAILED;
@ -1032,7 +1023,7 @@ top:
if (ctx->printer->foot_length) {
INFO("Cleaning up\n");
if ((ret = send_data(ctx->dev, ctx->endp_down, job->footer, ctx->printer->foot_length)))
if ((ret = send_data(ctx->conn, job->footer, ctx->printer->foot_length)))
return CUPS_BACKEND_FAILED;
}
state = S_FINISHED;
@ -1096,12 +1087,12 @@ static int canonselphy_query_markers(void *vctx, struct marker **markers, int *c
int ret, num;
/* Read in the printer status, twice. */
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
(uint8_t*) rdbuf, READBACK_LEN, &num);
if (ret < 0)
return CUPS_BACKEND_FAILED;
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
(uint8_t*) rdbuf, READBACK_LEN, &num);
if (ret < 0)
@ -1134,7 +1125,7 @@ static const char *canonselphy_prefixes[] = {
struct dyesub_backend canonselphy_backend = {
.name = "Canon SELPHY CP/ES (legacy)",
.version = "0.105",
.version = "0.106",
.uri_prefixes = canonselphy_prefixes,
.cmdline_usage = canonselphy_cmdline,
.cmdline_arg = canonselphy_cmdline_arg,

View file

@ -57,10 +57,7 @@ struct selphyneo_printjob {
};
struct selphyneo_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
int type;
struct dyesub_connection *conn;
struct marker marker;
};
@ -134,7 +131,7 @@ static int selphyneo_send_reset(struct selphyneo_ctx *ctx)
0x00, 0x00, 0x00, 0x00 };
int ret;
if ((ret = send_data(ctx->dev, ctx->endp_down,
if ((ret = send_data(ctx->conn,
rstcmd, sizeof(rstcmd))))
return CUPS_BACKEND_FAILED;
@ -147,14 +144,14 @@ static int selphyneo_get_status(struct selphyneo_ctx *ctx)
int ret, num;
/* Read in the printer status to clear last state */
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
(uint8_t*) &rdback, sizeof(rdback), &num);
if (ret < 0)
return CUPS_BACKEND_FAILED;
/* And again, for the markers */
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
(uint8_t*) &rdback, sizeof(rdback), &num);
if (ret < 0)
@ -183,31 +180,26 @@ static void *selphyneo_init(void)
extern struct dyesub_backend selphyneo_backend;
static int selphyneo_attach(void *vctx, struct libusb_device_handle *dev, int type,
uint8_t endp_up, uint8_t endp_down, int iface, uint8_t jobid)
static int selphyneo_attach(void *vctx, struct dyesub_connection *conn, uint8_t jobid)
{
struct selphyneo_ctx *ctx = vctx;
struct selphyneo_readback rdback;
int ret, num;
UNUSED(jobid);
UNUSED(iface);
ctx->dev = dev;
ctx->endp_up = endp_up;
ctx->endp_down = endp_down;
ctx->type = type;
ctx->conn = conn;
if (test_mode < TEST_MODE_NOATTACH) {
/* Read in the printer status to clear last state */
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
(uint8_t*) &rdback, sizeof(rdback), &num);
if (ret < 0)
return CUPS_BACKEND_FAILED;
/* And again, for the markers */
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
(uint8_t*) &rdback, sizeof(rdback), &num);
if (ret < 0)
@ -336,7 +328,7 @@ static int selphyneo_main_loop(void *vctx, const void *vjob) {
copies = job->copies;
/* Read in the printer status to clear last state */
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
(uint8_t*) &rdback, sizeof(rdback), &num);
if (ret < 0)
@ -346,7 +338,7 @@ top:
INFO("Waiting for printer idle\n");
do {
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
(uint8_t*) &rdback, sizeof(rdback), &num);
if (ret < 0)
@ -383,7 +375,7 @@ top:
int chunk = 256*1024;
int sent = 0;
while (chunk > 0) {
if ((ret = send_data(ctx->dev, ctx->endp_down,
if ((ret = send_data(ctx->conn,
job->databuf + sent, chunk)))
return CUPS_BACKEND_FAILED;
sent += chunk;
@ -394,7 +386,7 @@ top:
}
/* Read in the printer status to clear last state */
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
(uint8_t*) &rdback, sizeof(rdback), &num);
if (ret < 0)
@ -402,7 +394,7 @@ top:
INFO("Waiting for printer acknowledgement\n");
do {
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
(uint8_t*) &rdback, sizeof(rdback), &num);
if (ret < 0)
@ -487,14 +479,14 @@ static int selphyneo_query_markers(void *vctx, struct marker **markers, int *cou
int ret, num;
/* Read in the printer status to clear last state */
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
(uint8_t*) &rdback, sizeof(rdback), &num);
if (ret < 0)
return CUPS_BACKEND_FAILED;
/* And again, for the markers */
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
(uint8_t*) &rdback, sizeof(rdback), &num);
if (ret < 0)
@ -520,7 +512,7 @@ static const char *canonselphyneo_prefixes[] = {
struct dyesub_backend canonselphyneo_backend = {
.name = "Canon SELPHY CP (new)",
.version = "0.20",
.version = "0.21",
.uri_prefixes = canonselphyneo_prefixes,
.cmdline_usage = selphyneo_cmdline,
.cmdline_arg = selphyneo_cmdline_arg,

View file

@ -29,7 +29,7 @@
#include <signal.h>
#include <strings.h> /* For strncasecmp */
#define BACKEND_VERSION "0.107"
#define BACKEND_VERSION "0.108"
#ifndef URI_PREFIX
#error "Must Define URI_PREFIX"
#endif
@ -226,22 +226,22 @@ char *dict_find(const char *key, int dlen, struct deviceid_dict* dict)
}
/* I/O functions */
int read_data(struct libusb_device_handle *dev, uint8_t endp,
uint8_t *buf, int buflen, int *readlen)
int read_data(struct dyesub_connection *conn, uint8_t *buf, int buflen, int *readlen)
{
int ret;
/* Clear buffer */
memset(buf, 0, buflen);
ret = libusb_bulk_transfer(dev, endp,
ret = libusb_bulk_transfer(conn->dev, conn->endp_up,
buf,
buflen,
readlen,
xfer_timeout);
if (ret < 0) {
ERROR("Failure to receive data from printer (libusb error %d: (%d/%d from 0x%02x))\n", ret, *readlen, buflen, endp);
ERROR("Failure to receive data from printer (libusb error %d: (%d/%d from 0x%02x))\n", ret, *readlen, buflen, conn->endp_up);
goto done;
}
@ -270,8 +270,7 @@ done:
return ret;
}
int send_data(struct libusb_device_handle *dev, uint8_t endp,
const uint8_t *buf, int len)
int send_data(struct dyesub_connection *conn, const uint8_t *buf, int len)
{
int num = 0;
@ -299,12 +298,12 @@ int send_data(struct libusb_device_handle *dev, uint8_t endp,
DEBUG2("\n");
}
int ret = libusb_bulk_transfer(dev, endp,
int ret = libusb_bulk_transfer(conn->dev, conn->endp_down,
(uint8_t*) buf, len2,
&num, xfer_timeout);
if (ret < 0) {
ERROR("Failure to send data to printer (libusb error %d: (%d/%d to 0x%02x))\n", ret, num, len2, endp);
ERROR("Failure to send data to printer (libusb error %d: (%d/%d to 0x%02x))\n", ret, num, len2, conn->endp_down);
return ret;
}
len -= num;
@ -405,8 +404,7 @@ static int probe_device(struct libusb_device *device,
const char *prefix, const char *manuf_override,
int found, int num_claim_attempts,
int scan_only, const char *match_serno,
uint8_t *r_iface, uint8_t *r_altset,
uint8_t *r_endp_up, uint8_t *r_endp_down,
struct dyesub_connection *conn,
struct dyesub_backend *backend)
{
struct libusb_device_handle *dev;
@ -613,9 +611,13 @@ candidate:
sanitize_string(buf);
serial = url_encode(buf);
} else if (backend->query_serno) { /* Get from backend hook */
buf[0] = 0;
/* Ignore result since a failure isn't critical here */
backend->query_serno(dev, endp_up, endp_down, iface, buf, STR_LEN_MAX);
struct dyesub_connection c2;
c2.dev = dev;
c2.iface = iface;
c2.altset = altset;
c2.endp_up = endp_up;
c2.endp_down = endp_down;
backend->query_serno(&c2, buf, STR_LEN_MAX);
serial = url_encode(buf);
}
@ -660,11 +662,11 @@ candidate:
DEBUG("VID: %04X PID: %04X Manuf: '%s' Product: '%s' Serial: '%s' found: %d\n",
desc->idVendor, desc->idProduct, manuf, product, serial, found);
if (found != -1) {
if (r_iface) *r_iface = iface;
if (r_altset) *r_altset = altset;
if (r_endp_up) *r_endp_up = endp_up;
if (r_endp_up) *r_endp_down = endp_down;
if (found != -1 && conn) {
conn->iface = iface;
conn->altset = altset;
conn->endp_up = endp_up;
conn->endp_down = endp_down;
}
/* Free things up */
@ -751,19 +753,18 @@ static int find_and_enumerate(struct libusb_context *ctx,
const char *match_serno,
const char *prefix,
int scan_only, int num_claim_attempts,
uint8_t *r_iface, uint8_t *r_altset,
uint8_t *r_endp_up, uint8_t *r_endp_down)
struct dyesub_connection *conn)
{
int num;
int i, j = 0, k;
int found = -1;
if (test_mode >= TEST_MODE_NOATTACH) {
if (test_mode >= TEST_MODE_NOATTACH && conn) {
found = 1;
*r_endp_up = 0x82;
*r_endp_down = 0x01;
*r_iface = 0;
*r_altset = 0;
conn->endp_up = 0x82;
conn->endp_down = 0x01;
conn->iface = 0;
conn->altset = 0;
return found;
}
@ -835,8 +836,7 @@ static int find_and_enumerate(struct libusb_context *ctx,
URI_PREFIX, backends[k]->devices[j].manuf_str,
found, num_claim_attempts,
scan_only, match_serno,
r_iface, r_altset,
r_endp_up, r_endp_down,
conn,
backends[k]);
foundprefix = NULL;
if (found != -1 && !scan_only)
@ -1068,8 +1068,8 @@ void print_help(const char *argv0, const struct dyesub_backend *backend)
DEBUG("\t[ -d copies ] [ infile | - ]\n");
}
/* Probe for printers */
find_and_enumerate(ctx, &list, backend, NULL, ptr, 1, 1, NULL, NULL, NULL, NULL);
/* Scan for all printers for the specified backend */
find_and_enumerate(ctx, &list, backend, NULL, ptr, 1, 1, NULL);
libusb_free_device_list(list, 1);
}
@ -1250,13 +1250,11 @@ int main (int argc, char **argv)
{
struct libusb_context *ctx = NULL;
struct libusb_device **list = NULL;
struct libusb_device_handle *dev = NULL;
struct dyesub_backend *backend = NULL;
void * backend_ctx = NULL;
uint8_t endp_up, endp_down;
uint8_t iface, altset;
struct dyesub_connection conn;
int ret = CUPS_BACKEND_OK;
@ -1269,7 +1267,6 @@ int main (int argc, char **argv)
const char *fname = NULL;
char *use_serno = NULL;
const char *backend_str = NULL;
int printer_type;
logger = stderr;
@ -1438,7 +1435,7 @@ int main (int argc, char **argv)
}
/* Enumerate devices */
found = find_and_enumerate(ctx, &list, backend, use_serno, backend_str, 0, NUM_CLAIM_ATTEMPTS, &iface, &altset, &endp_up, &endp_down);
found = find_and_enumerate(ctx, &list, backend, use_serno, backend_str, 0, NUM_CLAIM_ATTEMPTS, &conn);
if (found == -1) {
ERROR("Printer open failure (No matching printers found!)\n");
@ -1453,7 +1450,7 @@ int main (int argc, char **argv)
}
/* Open an appropriate device */
ret = libusb_open(list[found], &dev);
ret = libusb_open(list[found], &conn.dev);
if (ret) {
ERROR("Printer open failure (Need to be root?) (%d)\n", ret);
ret = CUPS_BACKEND_RETRY_CURRENT;
@ -1461,8 +1458,8 @@ int main (int argc, char **argv)
}
/* Detach the kernel driver */
if (libusb_kernel_driver_active(dev, iface)) {
ret = libusb_detach_kernel_driver(dev, iface);
if (libusb_kernel_driver_active(conn.dev, conn.iface)) {
ret = libusb_detach_kernel_driver(conn.dev, conn.iface);
if (ret && (ret != LIBUSB_ERROR_NOT_SUPPORTED)) {
ERROR("Printer open failure (Could not detach printer from kernel) (%d)\n", ret);
ret = CUPS_BACKEND_RETRY_CURRENT;
@ -1471,7 +1468,7 @@ int main (int argc, char **argv)
}
/* Claim the interface so we can start using this! */
ret = backend_claim_interface(dev, iface, NUM_CLAIM_ATTEMPTS);
ret = backend_claim_interface(conn.dev, conn.iface, NUM_CLAIM_ATTEMPTS);
if (ret) {
ERROR("Printer open failure (Unable to claim interface) (%d)\n", ret);
ret = CUPS_BACKEND_RETRY;
@ -1479,8 +1476,8 @@ int main (int argc, char **argv)
}
/* Use the appropriate altesetting! */
if (altset != 0) {
ret = libusb_set_interface_alt_setting(dev, iface, altset);
if (conn.altset != 0) {
ret = libusb_set_interface_alt_setting(conn.dev, conn.iface, conn.altset);
if (ret) {
ERROR("Printer open failure (Unable to issue altsettinginterface) (%d)\n", ret);
ret = CUPS_BACKEND_RETRY;
@ -1498,24 +1495,25 @@ bypass:
struct libusb_device *device;
struct libusb_device_descriptor desc;
device = libusb_get_device(dev);
device = libusb_get_device(conn.dev);
libusb_get_device_descriptor(device, &desc);
printer_type = lookup_printer_type(backend,
desc.idVendor, desc.idProduct);
conn.type = lookup_printer_type(backend,
desc.idVendor, desc.idProduct);
} else {
printer_type = lookup_printer_type(backend,
extra_vid, extra_pid);
conn.type = lookup_printer_type(backend,
extra_vid, extra_pid);
}
if (printer_type <= P_UNKNOWN) {
if (conn.type <= P_UNKNOWN) {
ERROR("Unable to lookup printer type\n");
ret = CUPS_BACKEND_FAILED;
goto done_claimed;
}
/* Attach backend to device */ // XXX pass backend_str?
if (backend->attach(backend_ctx, dev, printer_type, endp_up, endp_down, iface, jobid)) {
ret = backend->attach(backend_ctx, &conn, jobid);
if (ret) {
ERROR("Unable to attach to printer!\n");
ret = CUPS_BACKEND_FAILED;
goto done_claimed;
@ -1553,11 +1551,11 @@ bypass:
done_claimed:
if (test_mode < TEST_MODE_NOATTACH)
libusb_release_interface(dev, iface);
libusb_release_interface(conn.dev, conn.iface);
done_close:
if (test_mode < TEST_MODE_NOATTACH)
libusb_close(dev);
libusb_close(conn.dev);
done:
if (backend && backend_ctx) {

View file

@ -193,6 +193,18 @@ struct printerstats {
int32_t cnt_life[DECKS_MAX]; /* Lifetime prints */
};
struct dyesub_connection {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
uint8_t iface;
uint8_t altset;
// TODO: mutex/lock
int type; /* P_XXXX */
};
#define DYESUB_MAX_JOB_ENTRIES 3
struct dyesub_joblist {
@ -212,10 +224,9 @@ struct dyesub_job_common {
};
/* Exported functions */
int send_data(struct libusb_device_handle *dev, uint8_t endp,
const uint8_t *buf, int len);
int read_data(struct libusb_device_handle *dev, uint8_t endp,
uint8_t *buf, int buflen, int *readlen);
int send_data(struct dyesub_connection *conn, const uint8_t *buf, int len);
int read_data(struct dyesub_connection *conn,
uint8_t *buf, int buflen, int *readlen);
void dump_markers(const struct marker *markers, int marker_count, int full);
@ -254,8 +265,7 @@ struct dyesub_backend {
const uint32_t flags;
void (*cmdline_usage)(void); /* Optional */
void *(*init)(void);
int (*attach)(void *ctx, struct libusb_device_handle *dev, int type,
uint8_t endp_up, uint8_t endp_down, int iface, uint8_t jobid);
int (*attach)(void *ctx, struct dyesub_connection *conn, uint8_t jobid);
void (*teardown)(void *ctx);
int (*cmdline_arg)(void *ctx, int argc, char **argv);
int (*read_parse)(void *ctx, const void **job, int data_fd, int copies);
@ -263,7 +273,7 @@ struct dyesub_backend {
void *(*combine_jobs)(const void *job1, const void *job2);
int (*job_polarity)(void *ctx);
int (*main_loop)(void *ctx, const void *job);
int (*query_serno)(struct libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, int iface, char *buf, int buf_len); /* Optional */
int (*query_serno)(struct dyesub_connection *conn, char *buf, int buf_len); /* Optional */
int (*query_markers)(void *ctx, struct marker **markers, int *count);
int (*query_stats)(void *ctx, struct printerstats *stats); /* Optional */
const struct device_id devices[];

View file

@ -66,12 +66,8 @@ struct dnpds40_printjob {
};
struct dnpds40_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
int iface;
struct dyesub_connection *conn;
int type;
int mfg; /* 0 for dnp, 1 citizen, 2 other */
/* Version and whatnot */
@ -635,12 +631,12 @@ static int dnpds40_do_cmd(struct dnpds40_ctx *ctx,
{
int ret;
if ((ret = send_data(ctx->dev, ctx->endp_down,
if ((ret = send_data(ctx->conn,
(uint8_t*)cmd, sizeof(*cmd))))
return ret;
if (data && len)
if ((ret = send_data(ctx->dev, ctx->endp_down,
if ((ret = send_data(ctx->conn,
data, len)))
return ret;
@ -663,7 +659,7 @@ static uint8_t *dnpds40_resp_cmd2(struct dnpds40_ctx *ctx,
return NULL;
/* Read in the response header */
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
(uint8_t*)tmp, 8, &num);
if (ret < 0)
return NULL;
@ -682,7 +678,7 @@ static uint8_t *dnpds40_resp_cmd2(struct dnpds40_ctx *ctx,
respbuf[i] = 0; /* Explicitly null-pad */
/* Read in the actual response */
ret = read_data(ctx->dev, ctx->endp_up,
ret = read_data(ctx->conn,
respbuf, i, &num);
if (ret < 0) {
free(respbuf);
@ -701,17 +697,14 @@ static uint8_t *dnpds40_resp_cmd2(struct dnpds40_ctx *ctx,
#define dnpds40_resp_cmd(__ctx, __cmd, __len) dnpds40_resp_cmd2(__ctx, __cmd, __len, NULL, 0)
static int dnpds40_query_serno(struct libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, int iface, char *buf, int buf_len)
static int dnpds40_query_serno(struct dyesub_connection *conn, char *buf, int buf_len)
{
struct dnpds40_cmd cmd;
uint8_t *resp;
int len = 0;
struct dnpds40_ctx ctx = {
.dev = dev,
.endp_up = endp_up,
.endp_down = endp_down,
.iface = iface,
.conn = conn,
};
/* Get Serial Number */
@ -811,18 +804,13 @@ static int dnpds80dx_query_paper(struct dnpds40_ctx *ctx)
return CUPS_BACKEND_OK;
}
static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev, int type,
uint8_t endp_up, uint8_t endp_down, int iface, uint8_t jobid)
static int dnpds40_attach(void *vctx, struct dyesub_connection *conn, uint8_t jobid)
{
struct dnpds40_ctx *ctx = vctx;
UNUSED(jobid);
ctx->dev = dev;
ctx->endp_up = endp_up;
ctx->endp_down = endp_down;
ctx->type = type;
ctx->iface = iface;
ctx->conn = conn;
/* Nearly all models support 600dpi */
ctx->supports_600dpi = 1;
@ -859,7 +847,7 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev, int type
}
/* Per-printer options */
switch (ctx->type) {
switch (ctx->conn->type) {
case P_DNP_DS40:
ctx->native_width = 1920;
ctx->max_height = 5480;
@ -998,7 +986,7 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev, int type
ctx->supports_systime = 1;
break;
default:
ERROR("Unknown printer type %d\n", ctx->type);
ERROR("Unknown printer type %d\n", ctx->conn->type);
return CUPS_BACKEND_FAILED;
}
@ -1033,7 +1021,7 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev, int type
ctx->media = atoi(tmp);
if (ctx->type != P_DNP_QW410) {
if (ctx->conn->type != P_DNP_QW410) {
/* Subtract out the "mark" type */
if (ctx->media & 1)
ctx->media--;
@ -1055,7 +1043,7 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev, int type
free(resp);
}
if (ctx->type == P_DNP_DS80D) {
if (ctx->conn->type == P_DNP_DS80D) {
if (dnpds80dx_query_paper(ctx))
return CUPS_BACKEND_FAILED;
}
@ -1065,13 +1053,13 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev, int type
struct libusb_device_descriptor desc;
struct libusb_device *udev;
udev = libusb_get_device(ctx->dev);
udev = libusb_get_device(ctx->conn->dev);
libusb_get_device_descriptor(udev, &desc);
char buf[STR_LEN_MAX + 1];
buf[0] = 0;
buf[STR_LEN_MAX] = 0;
libusb_get_string_descriptor_ascii(ctx->dev, desc.iManufacturer, (unsigned char*)buf, STR_LEN_MAX);
libusb_get_string_descriptor_ascii(ctx->conn->dev, desc.iManufacturer, (unsigned char*)buf, STR_LEN_MAX);
if (!strncmp(buf, "Dai", 3)) /* "Dai Nippon Printing" */
ctx->mfg = 0;
@ -1092,7 +1080,7 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev, int type
#endif
}
} else {
switch(ctx->type) {
switch(ctx->conn->type) {
case P_DNP_DS80D:
ctx->duplex_media = 200;
/* Intentional fallthrough */
@ -1163,7 +1151,7 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev, int type
}
} else {
/* Look it up for legacy models & FW */
switch (ctx->type) {
switch (ctx->conn->type) {
case P_DNP_DS40:
switch (ctx->media) {
case 200: // L
@ -1342,7 +1330,7 @@ static int dnpds40_attach(void *vctx, struct libusb_device_handle *dev, int type
ctx->marker[0].levelnow = CUPS_MARKER_UNKNOWN;
ctx->marker_count = 1;
if (ctx->type == P_DNP_DS80D) {
if (ctx->conn->type == P_DNP_DS80D) {
ctx->marker[1].color = "#00FFFF#FF00FF#FFFF00";
ctx->marker[1].name = dnpds80_duplex_media_types(ctx->duplex_media);
ctx->marker[1].numtype = ctx->duplex_media;
@ -1369,7 +1357,7 @@ static void dnpds40_teardown(void *vctx) {
if (!ctx)
return;
if (test_mode < TEST_MODE_NOATTACH && ctx->type == P_DNP_DS80D) {
if (test_mode < TEST_MODE_NOATTACH && ctx->conn->type == P_DNP_DS80D) {
struct dnpds40_cmd cmd;
/* Check to see if last print was the front side
@ -1456,7 +1444,7 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
/* See if job lacks the standard ESC-P start sequence */
if (job->databuf[job->datalen + 0] != 0x1b ||
job->databuf[job->datalen + 1] != 0x50) {
switch(ctx->type) {
switch(ctx->conn->type) {
case P_DNP_QW410:
i = legacy_qw410_read_parse(job, data_fd, i);
break;
@ -1553,7 +1541,7 @@ static int dnpds40_read_parse(void *vctx, const void **vjob, int data_fd, int co
continue;
}
if (ctx->type == P_DNP_DS820) {
if (ctx->conn->type == P_DNP_DS820) {
if (j != 24) {
WARNING("Full cutter argument length incorrect, ignoring!\n");
continue;
@ -1649,7 +1637,7 @@ parsed:
}
/* QW410 only supports 0 and 3, supposedly. */
if (ctx->type == P_DNP_QW410 && job->printspeed > 1) {
if (ctx->conn->type == P_DNP_QW410 && job->printspeed > 1) {
job->printspeed = 3;
}
@ -1676,7 +1664,7 @@ parsed:
}
/* Make sure MULTICUT is sane, most validation needs this */
if (!job->multicut && ctx->type != P_CITIZEN_CW01) {
if (!job->multicut && ctx->conn->type != P_CITIZEN_CW01) {
WARNING("Missing or illegal MULTICUT command!\n");
if (job->dpi == 300)
job->buf_needed = 1;
@ -1688,7 +1676,7 @@ parsed:
/* Only DS80D supports Cut Paper types */
if (job->multicut > 100) {
if ( ctx->type == P_DNP_DS80D) {
if ( ctx->conn->type == P_DNP_DS80D) {
job->cut_paper = 1;
} else {
ERROR("Only DS80D supports cut-paper sizes!\n");
@ -1701,7 +1689,7 @@ parsed:
job->buf_needed = 1;
if (job->dpi == 600) {
switch(ctx->type) {
switch(ctx->conn->type) {
case P_DNP_DS620:
if (job->multicut == MULTICUT_6x9 ||
job->multicut == MULTICUT_6x4_5X2)
@ -1761,7 +1749,7 @@ parsed:
break;
}
}
if (job->dpi == 334 && ctx->type != P_CITIZEN_CW01)
if (job->dpi == 334 && ctx->conn->type != P_CITIZEN_CW01)
{
ERROR("Illegal resolution (%u) for printer!\n", job->dpi);
dnpds40_cleanup_job(job);
@ -1859,7 +1847,7 @@ parsed:
job->can_rewind = 1;
break;
case 500: //"8x10"
if (ctx->type == P_DNP_DS820 &&
if (ctx->conn->type == P_DNP_DS820 &&
(job->multicut == MULTICUT_8x7 || job->multicut == MULTICUT_8x9)) {
/* These are okay */
} else if (job->multicut < MULTICUT_8x10 || job->multicut == MULTICUT_8x12 ||
@ -2160,7 +2148,7 @@ top:
free(resp);
}
if (ctx->type == P_CITIZEN_CW01) {
if (ctx->conn->type == P_CITIZEN_CW01) {
/* Get Vertical resolution */
dnpds40_build_cmd(&cmd, "INFO", "RESOLUTION_V", 0);
@ -2217,7 +2205,7 @@ top:
snprintf(buf, sizeof(buf), "%08d", 1);
/* DS80D does not support BUFFCNTRL when using
cut media; all others support this */
if (ctx->type != P_DNP_DS80D ||
if (ctx->conn->type != P_DNP_DS80D ||
multicut < 100) {
dnpds40_build_cmd(&cmd, "CNTRL", "BUFFCNTRL", 8);
if ((ret = dnpds40_do_cmd(ctx, &cmd, (uint8_t*)buf, 8)))
@ -2265,7 +2253,7 @@ top:
memcpy(buf, ptr + 24, 8);
i = atoi(buf) + 32;
if ((ret = send_data(ctx->dev, ctx->endp_down,
if ((ret = send_data(ctx->conn,
ptr, i)))
return CUPS_BACKEND_FAILED;
@ -2416,7 +2404,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx)
int cwd_index = 1;
uint8_t cwd_buf[5];
INFO("Model: %s\n", dnpds40_printer_type(ctx->type, ctx->mfg));
INFO("Model: %s\n", dnpds40_printer_type(ctx->conn->type, ctx->mfg));
/* Serial number already queried */
INFO("Serial Number: %s\n", ctx->serno);
@ -2425,7 +2413,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx)
INFO("Firmware Version: %s\n", ctx->version);
/* Figure out Duplexer */
if (ctx->type == P_DNP_DS80D) {
if (ctx->conn->type == P_DNP_DS80D) {
dnpds40_build_cmd(&cmd, "INFO", "UNIT_FVER", 0);
resp = dnpds40_resp_cmd(ctx, &cmd, &len);
@ -2439,7 +2427,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx)
free(resp);
}
if (ctx->type == P_CITIZEN_CW01) {
if (ctx->conn->type == P_CITIZEN_CW01) {
/* Get Horizonal resolution */
dnpds40_build_cmd(&cmd, "INFO", "RESOLUTION_H", 0);
@ -2545,7 +2533,7 @@ static int dnpds40_get_info(struct dnpds40_ctx *ctx)
free(resp);
if (ctx->type == P_CITIZEN_CW01)
if (ctx->conn->type == P_CITIZEN_CW01)
goto skip;
/* Get Ribbon ID code (?) */
@ -2693,7 +2681,7 @@ CWD_TOP:
}
if (cwd_extra && cwd_index == 1) {
if (ctx->type == P_DNP_QW410)
if (ctx->conn->type == P_DNP_QW410)
cwd_index = 2;
else
cwd_index = 3;
@ -2795,7 +2783,7 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx)
free(resp);
/* Figure out Duplexer */
if (ctx->type == P_DNP_DS80D) {
if (ctx->conn->type == P_DNP_DS80D) {
dnpds40_build_cmd(&cmd, "INFO", "UNIT_STATUS", 0);
resp = dnpds40_resp_cmd(ctx, &cmd, &len);
@ -2859,7 +2847,7 @@ static int dnpds40_get_status(struct dnpds40_ctx *ctx)
}
/* Report Cut Media */
if (ctx->type == P_DNP_DS80D) {
if (ctx->conn->type == P_DNP_DS80D) {
INFO("Duplex Media Type: %s\n", dnpds80_duplex_media_types(ctx->duplex_media));
INFO("Duplexer Media Status: %s\n", dnpds80_duplex_paper_status(ctx->duplex_media_status));
}
@ -2913,8 +2901,8 @@ static int dnpds40_get_counters(struct dnpds40_ctx *ctx)
free(resp);
if (ctx->type == P_DNP_DS620 ||
ctx->type == P_DNP_DS820) {
if (ctx->conn->type == P_DNP_DS620 ||
ctx->conn->type == P_DNP_DS820) {
/* Generate command */
dnpds40_build_cmd(&cmd, "MNT_RD", "COUNTER_HEAD", 0);
@ -2998,7 +2986,7 @@ static int dnpds40_get_counters(struct dnpds40_ctx *ctx)
free(resp);
}
if (ctx->type == P_DNP_DS80D) {
if (ctx->conn->type == P_DNP_DS80D) {
dnpds40_build_cmd(&cmd, "MNT_RD", "COUNTER_DUPLEX", 0);
resp = dnpds40_resp_cmd(ctx, &cmd, &len);
@ -3261,7 +3249,7 @@ static int dnpds40_query_markers(void *vctx, struct marker **markers, int *count
if (ctx->marker[0].levelnow < 0)
return CUPS_BACKEND_FAILED;
if (ctx->type == P_DNP_DS80D) {
if (ctx->conn->type == P_DNP_DS80D) {
if (dnpds80dx_query_paper(ctx))
return CUPS_BACKEND_FAILED;
switch (ctx->duplex_media_status) {
@ -3299,11 +3287,11 @@ static int dnp_query_stats(void *vctx, struct printerstats *stats)
default: stats->mfg = "Unknown" ; break;
}
stats->model = dnpds40_printer_type(ctx->type, ctx->mfg);
stats->model = dnpds40_printer_type(ctx->conn->type, ctx->mfg);
stats->serial = ctx->serno;
stats->fwver = ctx->version; // XXX duplexer version?
stats->decks = ctx->type == P_DNP_DS80D ? 2: 1;
stats->decks = ctx->conn->type == P_DNP_DS80D ? 2: 1;
stats->mediatype[0] = ctx->marker[0].name;
stats->levelmax[0] = ctx->marker[0].levelmax;
stats->levelnow[0] = ctx->marker[0].levelnow;
@ -3330,7 +3318,7 @@ static int dnp_query_stats(void *vctx, struct printerstats *stats)
stats->cnt_life[0] = atoi((char*)resp+2);
free(resp);
if (ctx->type == P_DNP_DS80D) {
if (ctx->conn->type == P_DNP_DS80D) {
stats->name[0] = "Sheet";
stats->mediatype[1] = ctx->marker[1].name;
stats->levelmax[1] = ctx->marker[1].levelmax;
@ -3409,7 +3397,7 @@ static const char *dnpds40_prefixes[] = {
/* Exported */
struct dyesub_backend dnpds40_backend = {
.name = "DNP DS-series / Citizen C-series",
.version = "0.133",
.version = "0.134",
.uri_prefixes = dnpds40_prefixes,
.cmdline_usage = dnpds40_cmdline,
.cmdline_arg = dnpds40_cmdline_arg,

View file

@ -362,11 +362,8 @@ struct hiti_printjob {
};
struct hiti_ctx {
struct libusb_device_handle *dev;
uint8_t endp_up;
uint8_t endp_down;
int iface;
int type;
struct dyesub_connection *conn;
int jobid;
char serno[32];
@ -407,7 +404,7 @@ static int hiti_query_unk8010(struct hiti_ctx *ctx);
static int hiti_query_counter(struct hiti_ctx *ctx, uint8_t arg, uint32_t *resp);
static int hiti_query_markers(void *vctx, struct marker **markers, int *count);
static int hiti_query_serno(struct libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, int iface, char *buf, int buf_len);
static int hiti_query_serno(struct dyesub_connection *conn, char *buf, int buf_len);
static int hiti_docmd(struct hiti_ctx *ctx, uint16_t cmdid, uint8_t *buf, uint16_t buf_len, uint16_t *rsplen)
{
@ -423,14 +420,14 @@ static int hiti_docmd(struct hiti_ctx *ctx, uint16_t cmdid, uint8_t *buf, uint16
memcpy(cmd->payload, buf, buf_len);
/* Send over command */
if ((ret = send_data(ctx->dev, ctx->endp_down, (uint8_t*) cmd, buf_len + 3 + 3))) {
if ((ret = send_data(ctx->conn, (uint8_t*) cmd, buf_len + 3 + 3))) {
return ret;
}
__usleep(10*1000);
/* Read back command */
ret = read_data(ctx->dev, ctx->endp_up, cmdbuf, 6, &num);
ret = read_data(ctx->conn, cmdbuf, 6, &num);
if (ret)
return ret;
@ -473,7 +470,7 @@ static int hiti_docmd_resp(struct hiti_ctx *ctx, uint16_t cmdid,
__usleep(10*1000);
/* Read back the data*/
ret = read_data(ctx->dev, ctx->endp_up, respbuf, *resplen, &num);
ret = read_data(ctx->conn, respbuf, *resplen, &num);
if (ret)
return ret;
@ -507,14 +504,14 @@ static int hiti_sepd(struct hiti_ctx *ctx, uint32_t buf_len,
cmd->numLines = cpu_to_be16(numLines);
/* Send over command */
if ((ret = send_data(ctx->dev, ctx->endp_down, (uint8_t*) cmd, sizeof(*cmd)))) {
if ((ret = send_data(ctx->conn, (uint8_t*) cmd, sizeof(*cmd)))) {
return ret;
}
__usleep(10*1000);
/* Read back command */
ret = read_data(ctx->dev, ctx->endp_up, cmdbuf, 6, &num);
ret = read_data(ctx->conn, cmdbuf, 6, &num);
if (ret)
return ret;
@ -894,17 +891,12 @@ static void *hiti_init(void)
return ctx;
}
static int hiti_attach(void *vctx, struct libusb_device_handle *dev, int type,
uint8_t endp_up, uint8_t endp_down, int iface, uint8_t jobid)
static int hiti_attach(void *vctx, struct dyesub_connection *conn, uint8_t jobid)
{
struct hiti_ctx *ctx = vctx;
int ret;
ctx->dev = dev;
ctx->endp_up = endp_up;
ctx->endp_down = endp_down;
ctx->iface =