#include #include #include #include #include #include #include #define PACKET_RECV_ERROR_THRESHOLD 30 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; isize; i++) { checksum += ((uint8_t *)body)[i]; } return checksum; } int tabby_printer_packet_recv(int fd, 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)); while ((len = read(fd, &value, 1)) >= 0) { if (i == 0) { if (value == 0x88) { header->preamble[0] = value; i++; } else { continue; } } else if (i == 1) { if (value == 0x33) { 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; } int tabby_printer_packet_send(int fd, tabby_printer_packet *header, void *body, uint16_t *response) { uint16_t sum = checksum(header, body); if (write(fd, header, sizeof(*header)) < 0) { goto error_io; } if (header->size) { if (write(fd, body, header->size) < 0) { goto error_io; } } if (write(fd, &sum, sizeof(sum)) < 0) { goto error_io; } if (read(fd, response, sizeof(*response)) < 0) { goto error_io; } return 0; error_io: return -1; }