2016-06-01 20:33:47 -05:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
2016-05-29 14:21:16 -05:00
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include <tabby/link.h>
|
|
|
|
#include <tabby/printer.h>
|
|
|
|
|
|
|
|
#define PACKET_RECV_ERROR_THRESHOLD 30
|
|
|
|
|
2016-05-31 23:39:41 -05:00
|
|
|
static uint16_t checksum(tabby_printer_packet *header, void *body) {
|
2016-05-29 14:21:16 -05:00
|
|
|
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-01 23:56:00 -05:00
|
|
|
int tabby_printer_packet_recv(int fd,
|
|
|
|
tabby_printer_packet *header,
|
2016-06-02 00:10:57 -05:00
|
|
|
void *body) {
|
2016-05-29 14:21:16 -05:00
|
|
|
ssize_t len;
|
|
|
|
|
|
|
|
size_t i = 0,
|
2016-05-30 21:53:10 -05:00
|
|
|
b = 0;
|
2016-05-29 14:21:16 -05:00
|
|
|
|
2016-05-30 21:53:10 -05:00
|
|
|
uint8_t value;
|
2016-05-29 14:21:16 -05:00
|
|
|
|
2016-06-02 00:10:57 -05:00
|
|
|
uint16_t sum = 0;
|
2016-05-30 21:53:10 -05:00
|
|
|
|
2016-06-02 00:10:57 -05:00
|
|
|
memset(header, '\0', sizeof(*header));
|
2016-05-29 14:21:16 -05:00
|
|
|
|
2016-05-31 23:28:55 -05:00
|
|
|
while ((len = read(fd, &value, 1)) >= 0) {
|
2016-05-30 21:53:10 -05:00
|
|
|
if (i == 0) {
|
2016-06-05 12:37:05 -05:00
|
|
|
if (value == TABBY_PRINTER_SYNC_1) {
|
2016-05-30 21:53:10 -05:00
|
|
|
header->preamble[0] = value;
|
|
|
|
i++;
|
|
|
|
} else {
|
2016-05-31 19:32:20 -05:00
|
|
|
continue;
|
2016-05-29 14:21:16 -05:00
|
|
|
}
|
2016-05-30 21:53:10 -05:00
|
|
|
} else if (i == 1) {
|
2016-06-05 12:37:05 -05:00
|
|
|
if (value == TABBY_PRINTER_SYNC_2) {
|
2016-05-30 21:53:10 -05:00
|
|
|
header->preamble[1] = value;
|
|
|
|
i++;
|
|
|
|
} else {
|
|
|
|
i = 0;
|
2016-05-31 19:32:20 -05:00
|
|
|
continue;
|
2016-05-30 21:53:10 -05:00
|
|
|
}
|
|
|
|
} 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++;
|
2016-05-31 19:32:20 -05:00
|
|
|
|
2016-05-30 21:53:10 -05:00
|
|
|
b = 0;
|
|
|
|
} else if (b < header->size) {
|
|
|
|
((uint8_t *)body)[b++] = value;
|
|
|
|
} else if (b == header->size) {
|
2016-06-02 00:10:57 -05:00
|
|
|
sum = value;
|
2016-05-30 21:53:10 -05:00
|
|
|
b++;
|
|
|
|
} else if (b == header->size + 1) {
|
2016-06-02 00:10:57 -05:00
|
|
|
sum |= value << 8;
|
2016-05-30 21:53:10 -05:00
|
|
|
|
2016-06-02 00:10:57 -05:00
|
|
|
if (checksum(header, body) != sum) {
|
2016-05-30 21:53:10 -05:00
|
|
|
errno = EIO;
|
2016-05-29 14:21:16 -05:00
|
|
|
|
2016-05-30 21:53:10 -05:00
|
|
|
goto error_io;
|
|
|
|
}
|
2016-05-29 14:21:16 -05:00
|
|
|
|
2016-05-30 21:53:10 -05:00
|
|
|
return errno = 0;
|
|
|
|
}
|
2016-05-29 14:21:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
error_io:
|
|
|
|
return -errno;
|
|
|
|
}
|
2016-06-01 23:56:00 -05:00
|
|
|
|
2016-06-05 01:58:30 -05:00
|
|
|
static inline int resend(tabby_printer_response *response) {
|
|
|
|
if (response->device != TABBY_PRINTER_DEVICE_ID) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (response->status & (TABBY_PRINTER_ER0 | TABBY_PRINTER_SUM)) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-06-01 23:56:00 -05:00
|
|
|
int tabby_printer_packet_send(int fd,
|
|
|
|
tabby_printer_packet *header,
|
|
|
|
void *body,
|
2016-06-04 19:26:34 -05:00
|
|
|
tabby_printer_response *response) {
|
2016-06-01 23:56:00 -05:00
|
|
|
uint16_t sum = checksum(header, body);
|
|
|
|
|
2016-06-07 18:08:32 -05:00
|
|
|
if (write(fd, header, sizeof(*header)) < 0) {
|
|
|
|
goto error_io;
|
|
|
|
}
|
2016-06-01 23:56:00 -05:00
|
|
|
|
2016-06-07 18:08:32 -05:00
|
|
|
if (header->size) {
|
|
|
|
if (write(fd, body, header->size) < 0) {
|
2016-06-05 01:58:30 -05:00
|
|
|
goto error_io;
|
|
|
|
}
|
2016-06-07 18:08:32 -05:00
|
|
|
}
|
2016-06-01 23:56:00 -05:00
|
|
|
|
2016-06-07 18:08:32 -05:00
|
|
|
if (write(fd, &sum, sizeof(sum)) < 0) {
|
|
|
|
goto error_io;
|
|
|
|
}
|
2016-06-05 01:58:30 -05:00
|
|
|
|
2016-06-07 18:08:32 -05:00
|
|
|
if (read(fd, response, sizeof(*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;
|
|
|
|
}
|
|
|
|
|
|
|
|
int tabby_printer_init(int fd,
|
|
|
|
tabby_printer_response *response) {
|
|
|
|
tabby_printer_packet header;
|
|
|
|
|
|
|
|
init_header(&header, TABBY_PRINTER_PACKET_INIT, 0);
|
|
|
|
|
|
|
|
return tabby_printer_packet_send(fd, &header, NULL, response);
|
|
|
|
}
|
|
|
|
|
|
|
|
int tabby_printer_send_inquiry(int fd,
|
|
|
|
tabby_printer_response *response) {
|
|
|
|
tabby_printer_packet header;
|
|
|
|
|
|
|
|
init_header(&header, TABBY_PRINTER_PACKET_INQUIRY, 0);
|
|
|
|
|
|
|
|
return tabby_printer_packet_send(fd, &header, NULL, response);
|
|
|
|
}
|
|
|
|
|
|
|
|
int tabby_printer_job_start(int fd, uint8_t sheets,
|
|
|
|
uint8_t linefeeds,
|
|
|
|
uint8_t palette,
|
|
|
|
uint8_t density,
|
|
|
|
tabby_printer_response *response) {
|
|
|
|
tabby_printer_packet header;
|
|
|
|
|
|
|
|
uint8_t body[4] = {
|
|
|
|
sheets, linefeeds, palette, density
|
|
|
|
};
|
|
|
|
|
2016-06-04 22:01:06 -05:00
|
|
|
init_header(&header, TABBY_PRINTER_PACKET_JOB, sizeof(body));
|
2016-06-04 20:33:10 -05:00
|
|
|
|
|
|
|
return tabby_printer_packet_send(fd, &header, &body, response);
|
|
|
|
}
|
|
|
|
|
|
|
|
int tabby_printer_job_cancel(int fd,
|
|
|
|
tabby_printer_response *response) {
|
|
|
|
tabby_printer_packet header;
|
|
|
|
|
|
|
|
init_header(&header, TABBY_PRINTER_PACKET_CANCEL, 0);
|
|
|
|
|
|
|
|
return tabby_printer_packet_send(fd, &header, NULL, response);
|
|
|
|
}
|
|
|
|
|
|
|
|
int tabby_printer_send_sheet(int fd, void *data,
|
|
|
|
tabby_printer_response *response) {
|
|
|
|
int i;
|
|
|
|
size_t offset = 0;
|
|
|
|
|
2016-06-04 22:01:06 -05:00
|
|
|
tabby_printer_packet header;
|
|
|
|
|
2016-06-04 20:33:10 -05:00
|
|
|
for (i=0; i<TABBY_PRINTER_SHEET_BANDS; i++) {
|
|
|
|
tabby_printer_response current;
|
|
|
|
|
|
|
|
init_header(&header,
|
|
|
|
TABBY_PRINTER_PACKET_DATA,
|
|
|
|
TABBY_PRINTER_BAND_SIZE);
|
|
|
|
|
|
|
|
if (tabby_printer_packet_send(fd, &header,
|
|
|
|
((uint8_t *)data) + offset,
|
|
|
|
¤t) < 0) {
|
|
|
|
goto error_packet_send;
|
|
|
|
}
|
|
|
|
|
2016-06-07 18:08:32 -05:00
|
|
|
if (resend(¤t)) {
|
|
|
|
tabby_printer_init(fd, ¤t);
|
|
|
|
i = -1;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-06-04 20:33:10 -05:00
|
|
|
offset += TABBY_PRINTER_BAND_SIZE;
|
2016-06-05 17:24:25 -05:00
|
|
|
}
|
2016-06-04 22:01:06 -05:00
|
|
|
|
2016-06-05 22:54:31 -05:00
|
|
|
init_header(&header, TABBY_PRINTER_PACKET_DATA, 0);
|
|
|
|
|
|
|
|
return tabby_printer_packet_send(fd, &header, NULL, response);
|
2016-06-04 20:33:10 -05:00
|
|
|
|
|
|
|
error_packet_send:
|
|
|
|
return -1;
|
|
|
|
}
|