tabby/src/printer.c

265 lines
6.4 KiB
C
Raw Normal View History

2016-06-10 03:20:20 +00:00
#include <stdlib.h>
2016-06-01 20:33:47 -05:00
#include <string.h>
2016-06-10 03:20:20 +00:00
#include <stdint.h>
2016-06-01 20:33:47 -05:00
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <tabby/link.h>
#include <tabby/printer.h>
#define PACKET_RECV_ERROR_THRESHOLD 30
2016-06-10 03:20:20 +00:00
tabby_printer *tabby_printer_open(const char *device) {
tabby_printer *printer;
if ((printer = malloc(sizeof(*printer))) == NULL) {
goto error_malloc_printer;
}
if ((printer->fd = tabby_link_open(device)) < 0) {
goto error_link_open;
}
printer->device = TABBY_PRINTER_DEVICE_ID;
printer->status = TABBY_PRINTER_OK;
return printer;
error_link_open:
free(printer);
error_malloc_printer:
return NULL;
}
void tabby_printer_close(tabby_printer *printer) {
tabby_link_close(printer->fd);
free(printer);
}
static uint16_t checksum(tabby_printer_packet *header, void *body) {
uint16_t checksum = header->data[2]
+ header->data[3]
+ header->data[4]
+ header->data[5];
size_t i;
for (i=0; i<header->size; i++) {
checksum += ((uint8_t *)body)[i];
}
return checksum;
}
2016-06-10 03:20:20 +00:00
int tabby_printer_packet_recv(tabby_printer *printer,
2016-06-01 23:56:00 -05:00
tabby_printer_packet *header,
void *body) {
ssize_t len;
size_t i = 0,
b = 0;
uint8_t value;
uint16_t sum = 0;
memset(header, '\0', sizeof(*header));
2016-06-10 03:20:20 +00:00
while ((len = read(printer->fd, &value, 1)) >= 0) {
if (i == 0) {
2016-06-05 12:37:05 -05:00
if (value == TABBY_PRINTER_SYNC_1) {
header->preamble[0] = value;
i++;
} else {
continue;
}
} else if (i == 1) {
2016-06-05 12:37:05 -05:00
if (value == TABBY_PRINTER_SYNC_2) {
header->preamble[1] = value;
i++;
} else {
i = 0;
continue;
}
} else if (i == 2) {
header->type = value;
i++;
} else if (i == 3) {
header->compression = value;
i++;
} else if (i == 4) {
header->size = value;
i++;
} else if (i == 5) {
header->size |= value << 8;
i++;
b = 0;
} else if (b < header->size) {
((uint8_t *)body)[b++] = value;
} else if (b == header->size) {
sum = value;
b++;
} else if (b == header->size + 1) {
sum |= value << 8;
if (checksum(header, body) != sum) {
errno = EIO;
goto error_io;
}
return errno = 0;
}
}
error_io:
return -errno;
}
2016-06-01 23:56:00 -05:00
2016-06-10 03:20:20 +00:00
int tabby_printer_packet_send(tabby_printer *printer,
2016-06-01 23:56:00 -05:00
tabby_printer_packet *header,
2016-06-10 03:20:20 +00:00
void *body) {
2016-06-01 23:56:00 -05:00
uint16_t sum = checksum(header, body);
2016-06-10 03:20:20 +00:00
if (write(printer->fd, header, sizeof(*header)) < 0) {
goto error_io;
}
2016-06-01 23:56:00 -05:00
if (header->size) {
2016-06-10 03:20:20 +00:00
if (write(printer->fd, body, header->size) < 0) {
2016-06-05 01:58:30 -05:00
goto error_io;
}
}
2016-06-01 23:56:00 -05:00
2016-06-10 03:20:20 +00:00
if (write(printer->fd, &sum, sizeof(sum)) < 0) {
goto error_io;
}
2016-06-05 01:58:30 -05:00
2016-06-10 03:20:20 +00:00
if (read(printer->fd, &printer->response, sizeof(printer->response)) < 0) {
goto error_io;
}
2016-06-01 23:56:00 -05:00
return 0;
error_io:
return -1;
}
2016-06-04 20:33:10 -05:00
static void init_header(tabby_printer_packet *header,
tabby_printer_packet_type type, size_t size) {
2016-06-05 12:37:05 -05:00
header->preamble[0] = TABBY_PRINTER_SYNC_1;
header->preamble[1] = TABBY_PRINTER_SYNC_2;
2016-06-04 20:33:10 -05:00
header->type = type;
header->compression = TABBY_PRINTER_COMPRESSION_NONE;
header->size = (uint16_t)size;
}
2016-06-10 03:20:20 +00:00
int tabby_printer_init(tabby_printer *printer) {
2016-06-04 20:33:10 -05:00
tabby_printer_packet header;
init_header(&header, TABBY_PRINTER_PACKET_INIT, 0);
2016-06-10 03:20:20 +00:00
return tabby_printer_packet_send(printer, &header, NULL);
2016-06-04 20:33:10 -05:00
}
2016-06-10 03:20:20 +00:00
int tabby_printer_inquiry_send(tabby_printer *printer) {
2016-06-04 20:33:10 -05:00
tabby_printer_packet header;
init_header(&header, TABBY_PRINTER_PACKET_INQUIRY, 0);
2016-06-10 03:20:20 +00:00
return tabby_printer_packet_send(printer, &header, NULL);
2016-06-04 20:33:10 -05:00
}
2016-06-10 03:20:20 +00:00
int tabby_printer_job_start(tabby_printer *printer, uint8_t sheets,
uint8_t linefeeds,
uint8_t palette,
uint8_t density) {
2016-06-04 20:33:10 -05:00
tabby_printer_packet header;
uint8_t body[4] = {
sheets, linefeeds, palette, density
};
init_header(&header, TABBY_PRINTER_PACKET_JOB, sizeof(body));
2016-06-04 20:33:10 -05:00
2016-06-10 03:20:20 +00:00
return tabby_printer_packet_send(printer, &header, &body);
2016-06-04 20:33:10 -05:00
}
2016-06-10 03:20:20 +00:00
int tabby_printer_job_cancel(tabby_printer *printer) {
2016-06-04 20:33:10 -05:00
tabby_printer_packet header;
init_header(&header, TABBY_PRINTER_PACKET_CANCEL, 0);
2016-06-10 03:20:20 +00:00
return tabby_printer_packet_send(printer, &header, NULL);
}
int tabby_printer_job_wait(tabby_printer *printer) {
do {
sleep(1);
if (tabby_printer_inquiry_send(printer) < 0) {
goto error_inquiry_send;
}
} while (printer->status & TABBY_PRINTER_UNTRAN);
return 0;
error_inquiry_send:
return -1;
2016-06-04 20:33:10 -05:00
}
2016-06-10 03:20:20 +00:00
int tabby_printer_band_send(tabby_printer *printer, uint8_t *band) {
tabby_printer_packet header;
init_header(&header, TABBY_PRINTER_PACKET_DATA, TABBY_PRINTER_BAND_SIZE);
return tabby_printer_packet_send(printer, &header, band);
}
2016-06-04 20:33:10 -05:00
2016-06-10 03:20:20 +00:00
int tabby_printer_band_finish(tabby_printer *printer) {
tabby_printer_packet header;
2016-06-10 03:20:20 +00:00
init_header(&header, TABBY_PRINTER_PACKET_DATA, 0);
return tabby_printer_packet_send(printer, &header, NULL);
}
int tabby_printer_sheet_send(tabby_printer *printer, void *data,
uint16_t size) {
uint16_t offset = 0;
2016-06-04 20:33:10 -05:00
2016-06-10 03:20:20 +00:00
tabby_printer_packet header;
while (offset < size) {
2016-06-04 20:33:10 -05:00
init_header(&header,
TABBY_PRINTER_PACKET_DATA,
TABBY_PRINTER_BAND_SIZE);
2016-06-10 03:20:20 +00:00
if (tabby_printer_packet_send(printer,
&header,
((uint8_t *)data) + offset) < 0) {
2016-06-04 20:33:10 -05:00
goto error_packet_send;
}
2016-06-10 03:20:20 +00:00
if (printer->status & TABBY_PRINTER_SUM) {
tabby_printer_init(printer);
offset = 0;
continue;
}
2016-06-04 20:33:10 -05:00
offset += TABBY_PRINTER_BAND_SIZE;
}
2016-06-05 22:54:31 -05:00
init_header(&header, TABBY_PRINTER_PACKET_DATA, 0);
2016-06-10 03:20:20 +00:00
return tabby_printer_packet_send(printer, &header, NULL);
2016-06-04 20:33:10 -05:00
error_packet_send:
return -1;
}