100 lines
2.4 KiB
C
100 lines
2.4 KiB
C
|
#include <errno.h>
|
||
|
|
||
|
#include <tabby/link.h>
|
||
|
#include <tabby/printer.h>
|
||
|
|
||
|
#define PACKET_RECV_ERROR_THRESHOLD 30
|
||
|
|
||
|
static uint16_t checksum(tabby_printer_packet_header *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;
|
||
|
}
|
||
|
|
||
|
int tabby_printer_packet_recv(int fd, tabby_printer_packet_header *header,
|
||
|
void *body,
|
||
|
tabby_printer_packet_footer *footer) {
|
||
|
ssize_t len;
|
||
|
|
||
|
size_t i = 0,
|
||
|
b = 0,
|
||
|
f = 0;
|
||
|
|
||
|
uint8_t value,
|
||
|
last;
|
||
|
|
||
|
int started = 0;
|
||
|
|
||
|
memset(header, '\0', sizeof(*header));
|
||
|
memset(footer, '\0', sizeof(*footer));
|
||
|
|
||
|
while ((len = tabby_link_recv(fd, &value, 1)) >= 0) {
|
||
|
if (started) {
|
||
|
if (i == 2) {
|
||
|
header->type = value;
|
||
|
} else if (i == 3) {
|
||
|
header->compression = value;
|
||
|
} else if (i == 4 || i == 5) {
|
||
|
header->size <<= 8;
|
||
|
header->size |= value;
|
||
|
} else if (i > 5 && b < header->size) {
|
||
|
((uint8_t *)body)[b++] = value;
|
||
|
} else if (b >= header->size && f < 2) {
|
||
|
footer->checksum <<= 8;
|
||
|
footer->checksum |= value;
|
||
|
|
||
|
f++;
|
||
|
} else if (f >= 2) {
|
||
|
footer->data[f++] = value;
|
||
|
|
||
|
if (f == sizeof(*footer)) {
|
||
|
if (checksum(header, body) != footer->checksum) {
|
||
|
errno = EIO;
|
||
|
|
||
|
goto error_io;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
if (last == 0x88 && value == 0x33) {
|
||
|
started = 1;
|
||
|
i = 2;
|
||
|
b = 0;
|
||
|
f = 0;
|
||
|
} else if (i == PACKET_RECV_ERROR_THRESHOLD) {
|
||
|
errno = EIO;
|
||
|
|
||
|
goto error_io;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
last = value;
|
||
|
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
return errno = 0;
|
||
|
|
||
|
error_io:
|
||
|
return -errno;
|
||
|
}
|
||
|
|
||
|
int tabby_printer_response_send(int fd, uint8_t device, uint8_t status) {
|
||
|
uint8_t response[2] = {
|
||
|
device, status
|
||
|
};
|
||
|
|
||
|
return tabby_link_send(fd, &response, sizeof(response));
|
||
|
}
|