I'm a fookin' NINJA

This commit is contained in:
XANTRONIX Development 2016-06-10 03:20:20 +00:00
parent fdd550844b
commit 6ba12e1f38
8 changed files with 321 additions and 106 deletions

View file

@ -8,9 +8,9 @@ CFLAGS += -I$(INCLUDE_PATH)
LDFLAGS =
TABBY = tabby
TABBY_OBJS = main.o
TABBY_OBJS = main.o grab.o print.o
TABBY_STATIC = ../src/lib$(LIBNAME).a
TABBY_HEADERS =
TABBY_HEADERS = commands.h
TABBY_LDFLAGS =
LIBNAME = tabby

7
bin/commands.h Normal file
View file

@ -0,0 +1,7 @@
#ifndef _COMMANDS_H
#define _COMMANDS_H
int tabby_command_grab(int argc, char **argv);
int tabby_command_print(int argc, char **argv);
#endif /* _COMMANDS_H */

63
bin/grab.c Normal file
View file

@ -0,0 +1,63 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
#include <tabby/link.h>
#include <tabby/printer.h>
static void usage(int argc, char **argv, char *message, ...) {
if (message) {
va_list args;
va_start(args, message);
vfprintf(stderr, message, args);
fprintf(stderr, "\n");
va_end(args);
}
fprintf(stderr, "usage: %s grab device\n", argv[0]);
exit(1);
}
int tabby_command_grab(int argc, char **argv) {
tabby_printer *printer;
tabby_printer_packet header;
uint8_t body[TABBY_PRINTER_PACKET_MAX_SIZE];
if (argc != 2) {
usage(argc, argv, "No device specified");
}
if ((printer = tabby_printer_open(argv[1])) == NULL) {
fprintf(stderr, "%s: %s: %s: %s\n", argv[0], "tabby_printer_open()",
argv[1], strerror(errno));
goto error_printer_open;
}
while (1) {
if (tabby_printer_packet_recv(printer, &header, &body) < 0) {
fprintf(stderr, "%s: %s: %s\n",
argv[0], "tabby_printer_packet_recv()", strerror(errno));
continue;
}
if (header.type == 0x04) {
write(1, &body, header.size);
}
}
tabby_printer_close(printer);
return 0;
error_printer_open:
return 1;
}

View file

@ -9,6 +9,8 @@
#include <tabby/link.h>
#include <tabby/printer.h>
#include "commands.h"
static void usage(int argc, char **argv, char *message, ...) {
if (message) {
va_list args;
@ -19,48 +21,36 @@ static void usage(int argc, char **argv, char *message, ...) {
va_end(args);
}
fprintf(stderr, "usage: %s device\n", argv[0]);
fprintf(stderr, "usage: %1$s print ...\n"
" %1$s grab ...\n",
argv[0]);
exit(1);
}
static struct {
char *name;
int (*fun)(int, char **);
} commands[] = {
{ "print", tabby_command_print },
{ "grab", tabby_command_grab },
{ NULL, NULL }
};
int main(int argc, char **argv) {
int fd, status;
int i;
tabby_printer_packet header;
uint8_t body[TABBY_PRINTER_PACKET_MAX_SIZE];
if (argc != 2) {
usage(argc, argv, "No device specified");
if (argc < 2) {
usage(argc, argv, "No command specified");
}
if ((fd = tabby_link_open(argv[1])) < 0) {
fprintf(stderr, "%s: %s: %s: %s\n", argv[0], "tabby_link_open()",
argv[1], strerror(errno));
goto error_link_open;
}
while (1) {
status = tabby_printer_packet_recv(fd, &header, &body);
if (status < 0) {
fprintf(stderr, "%s: %s: %s\n",
argv[0], "tabby_printer_packet_recv()", strerror(errno));
continue;
}
if (header.type == 0x04) {
write(1, &body, header.size);
for (i=0; commands[i].name; i++) {
if (strcmp(argv[1], commands[i].name) == 0) {
return commands[i].fun(argc, argv);
}
}
tabby_link_close(fd);
usage(argc, argv, "Unknown command '%s'", argv[1]);
return 0;
error_link_open:
return 1;
}

95
bin/print.c Normal file
View file

@ -0,0 +1,95 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <tabby/link.h>
#include <tabby/printer.h>
static void usage(int argc, char **argv, char *message, ...) {
if (message) {
va_list args;
va_start(args, message);
vfprintf(stderr, message, args);
fprintf(stderr, "\n");
va_end(args);
}
fprintf(stderr, "usage: %s print device sheet.tile\n", argv[0]);
exit(1);
}
int tabby_command_print(int argc, char **argv) {
int fd;
ssize_t readlen;
size_t offset = 0;
tabby_printer *printer;
uint8_t band[TABBY_PRINTER_BAND_SIZE];
if (argc != 3) {
usage(argc, argv, "Must specify device and tile");
}
if ((fd = open(argv[2], O_RDONLY)) < 0) {
fprintf(stderr, "%s: %s: %s: %s\n",
argv[0], "open()", argv[2], strerror(errno));
goto error_open_tile;
}
if ((printer = tabby_printer_open(argv[1])) == NULL) {
fprintf(stderr, "%s: %s: %s: %s\n",
argv[0], "tabby_printer_open()", argv[1], strerror(errno));
goto error_printer_open;
}
do {
sleep(1);
tabby_printer_init(printer);
} while (printer->device != TABBY_PRINTER_DEVICE_ID);
while ((readlen = read(fd, band, sizeof(band))) >= 0) {
offset += readlen;
tabby_printer_band_send(printer, band);
if (offset % TABBY_PRINTER_SHEET_SIZE == 0) {
uint8_t feeds = 0x00;
if (offset == TABBY_PRINTER_SHEET_SIZE) {
feeds |= 0x10;
}
tabby_printer_band_finish(printer);
tabby_printer_job_start(printer, 1, feeds, 0x00, 0x40);
tabby_printer_job_wait(printer);
}
}
tabby_printer_job_start(printer, 1, 0x03, 0x00, 0x40);
tabby_printer_job_wait(printer);
tabby_printer_close(printer);
return 0;
error_printer_open:
close(fd);
error_open_tile:
return 1;
}

View file

@ -39,6 +39,24 @@ typedef enum {
TABBY_PRINTER_COMPRESSION_RLE = 0x01
} tabby_printer_compression;
typedef struct _tabby_printer_response {
uint8_t device;
uint8_t status;
} tabby_printer_response;
typedef struct _tabby_printer {
int fd;
union {
tabby_printer_response response;
struct {
uint8_t device,
status;
};
};
} tabby_printer;
/*
* Data definitions for packets sent from Game Boy to printer
*/
@ -75,42 +93,42 @@ typedef struct _tabby_printer_buffer {
uint16_t sum;
} tabby_printer_buffer;
typedef struct _tabby_printer_response {
uint8_t device;
uint8_t status;
} tabby_printer_response;
tabby_printer *tabby_printer_open(const char *device);
void tabby_printer_close(tabby_printer *printer);
/*
* For receiving printer data packets from a Game Boy Camera
*/
int tabby_printer_packet_recv(int fd,
int tabby_printer_packet_recv(tabby_printer *printer,
tabby_printer_packet *header,
void *body);
/*
* For sending printer data packets to a Game Boy Printer
*/
int tabby_printer_packet_send(int fd,
int tabby_printer_packet_send(tabby_printer *printer,
tabby_printer_packet *header,
void *body,
tabby_printer_response *response);
void *body);
int tabby_printer_init(int fd,
tabby_printer_response *response);
int tabby_printer_init(tabby_printer *printer);
int tabby_printer_send_inquiry(int fd,
tabby_printer_response *response);
int tabby_printer_inquiry_send(tabby_printer *printer);
int tabby_printer_job_start(int fd, uint8_t sheets,
int tabby_printer_job_start(tabby_printer *printer, uint8_t sheets,
uint8_t linefeeds,
uint8_t palette,
uint8_t density,
tabby_printer_response *response);
uint8_t density);
int tabby_printer_job_cancel(int fd,
tabby_printer_response *response);
int tabby_printer_job_cancel(tabby_printer *printer);
int tabby_printer_send_sheet(int fd, void *data,
tabby_printer_response *response);
int tabby_printer_job_wait(tabby_printer *printer);
int tabby_printer_band_send(tabby_printer *printer, uint8_t *band);
int tabby_printer_band_finish(tabby_printer *printer);
int tabby_printer_sheet_send(tabby_printer *printer, void *data,
uint16_t size);
#endif /* _TABBY_PRINTER_H */

View file

@ -1,4 +1,3 @@
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
@ -18,6 +17,8 @@ int tabby_link_open(const char *dev) {
cfmakeraw(&attr);
cfsetspeed(&attr, TABBY_LINK_BAUD);
sleep(1);
if (tcsetattr(fd, TCSAFLUSH, &attr) < 0) {
goto error_io;
}

View file

@ -1,5 +1,6 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
@ -9,6 +10,34 @@
#define PACKET_RECV_ERROR_THRESHOLD 30
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]
@ -24,7 +53,7 @@ static uint16_t checksum(tabby_printer_packet *header, void *body) {
return checksum;
}
int tabby_printer_packet_recv(int fd,
int tabby_printer_packet_recv(tabby_printer *printer,
tabby_printer_packet *header,
void *body) {
ssize_t len;
@ -38,7 +67,7 @@ int tabby_printer_packet_recv(int fd,
memset(header, '\0', sizeof(*header));
while ((len = read(fd, &value, 1)) >= 0) {
while ((len = read(printer->fd, &value, 1)) >= 0) {
if (i == 0) {
if (value == TABBY_PRINTER_SYNC_1) {
header->preamble[0] = value;
@ -90,39 +119,26 @@ error_io:
return -errno;
}
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;
}
int tabby_printer_packet_send(int fd,
int tabby_printer_packet_send(tabby_printer *printer,
tabby_printer_packet *header,
void *body,
tabby_printer_response *response) {
void *body) {
uint16_t sum = checksum(header, body);
if (write(fd, header, sizeof(*header)) < 0) {
if (write(printer->fd, header, sizeof(*header)) < 0) {
goto error_io;
}
if (header->size) {
if (write(fd, body, header->size) < 0) {
if (write(printer->fd, body, header->size) < 0) {
goto error_io;
}
}
if (write(fd, &sum, sizeof(sum)) < 0) {
if (write(printer->fd, &sum, sizeof(sum)) < 0) {
goto error_io;
}
if (read(fd, response, sizeof(*response)) < 0) {
if (read(printer->fd, &printer->response, sizeof(printer->response)) < 0) {
goto error_io;
}
@ -141,29 +157,26 @@ static void init_header(tabby_printer_packet *header,
header->size = (uint16_t)size;
}
int tabby_printer_init(int fd,
tabby_printer_response *response) {
int tabby_printer_init(tabby_printer *printer) {
tabby_printer_packet header;
init_header(&header, TABBY_PRINTER_PACKET_INIT, 0);
return tabby_printer_packet_send(fd, &header, NULL, response);
return tabby_printer_packet_send(printer, &header, NULL);
}
int tabby_printer_send_inquiry(int fd,
tabby_printer_response *response) {
int tabby_printer_inquiry_send(tabby_printer *printer) {
tabby_printer_packet header;
init_header(&header, TABBY_PRINTER_PACKET_INQUIRY, 0);
return tabby_printer_packet_send(fd, &header, NULL, response);
return tabby_printer_packet_send(printer, &header, NULL);
}
int tabby_printer_job_start(int fd, uint8_t sheets,
int tabby_printer_job_start(tabby_printer *printer, uint8_t sheets,
uint8_t linefeeds,
uint8_t palette,
uint8_t density,
tabby_printer_response *response) {
uint8_t density) {
tabby_printer_packet header;
uint8_t body[4] = {
@ -172,41 +185,69 @@ int tabby_printer_job_start(int fd, uint8_t sheets,
init_header(&header, TABBY_PRINTER_PACKET_JOB, sizeof(body));
return tabby_printer_packet_send(fd, &header, &body, response);
return tabby_printer_packet_send(printer, &header, &body);
}
int tabby_printer_job_cancel(int fd,
tabby_printer_response *response) {
int tabby_printer_job_cancel(tabby_printer *printer) {
tabby_printer_packet header;
init_header(&header, TABBY_PRINTER_PACKET_CANCEL, 0);
return tabby_printer_packet_send(fd, &header, NULL, response);
return tabby_printer_packet_send(printer, &header, NULL);
}
int tabby_printer_send_sheet(int fd, void *data,
tabby_printer_response *response) {
int i;
size_t offset = 0;
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;
}
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);
}
int tabby_printer_band_finish(tabby_printer *printer) {
tabby_printer_packet header;
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;
tabby_printer_packet header;
for (i=0; i<TABBY_PRINTER_SHEET_BANDS; i++) {
tabby_printer_response current;
while (offset < size) {
init_header(&header,
TABBY_PRINTER_PACKET_DATA,
TABBY_PRINTER_BAND_SIZE);
if (tabby_printer_packet_send(fd, &header,
((uint8_t *)data) + offset,
&current) < 0) {
if (tabby_printer_packet_send(printer,
&header,
((uint8_t *)data) + offset) < 0) {
goto error_packet_send;
}
if (resend(&current)) {
tabby_printer_init(fd, &current);
i = -1;
if (printer->status & TABBY_PRINTER_SUM) {
tabby_printer_init(printer);
offset = 0;
continue;
}
@ -216,7 +257,7 @@ int tabby_printer_send_sheet(int fd, void *data,
init_header(&header, TABBY_PRINTER_PACKET_DATA, 0);
return tabby_printer_packet_send(fd, &header, NULL, response);
return tabby_printer_packet_send(printer, &header, NULL);
error_packet_send:
return -1;