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 = LDFLAGS =
TABBY = tabby TABBY = tabby
TABBY_OBJS = main.o TABBY_OBJS = main.o grab.o print.o
TABBY_STATIC = ../src/lib$(LIBNAME).a TABBY_STATIC = ../src/lib$(LIBNAME).a
TABBY_HEADERS = TABBY_HEADERS = commands.h
TABBY_LDFLAGS = TABBY_LDFLAGS =
LIBNAME = tabby 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/link.h>
#include <tabby/printer.h> #include <tabby/printer.h>
#include "commands.h"
static void usage(int argc, char **argv, char *message, ...) { static void usage(int argc, char **argv, char *message, ...) {
if (message) { if (message) {
va_list args; va_list args;
@ -19,48 +21,36 @@ static void usage(int argc, char **argv, char *message, ...) {
va_end(args); 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); 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 main(int argc, char **argv) {
int fd, status; int i;
tabby_printer_packet header; if (argc < 2) {
usage(argc, argv, "No command specified");
uint8_t body[TABBY_PRINTER_PACKET_MAX_SIZE];
if (argc != 2) {
usage(argc, argv, "No device specified");
} }
if ((fd = tabby_link_open(argv[1])) < 0) { for (i=0; commands[i].name; i++) {
fprintf(stderr, "%s: %s: %s: %s\n", argv[0], "tabby_link_open()", if (strcmp(argv[1], commands[i].name) == 0) {
argv[1], strerror(errno)); return commands[i].fun(argc, argv);
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);
} }
} }
tabby_link_close(fd); usage(argc, argv, "Unknown command '%s'", argv[1]);
return 0; 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_RLE = 0x01
} tabby_printer_compression; } 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 * Data definitions for packets sent from Game Boy to printer
*/ */
@ -75,42 +93,42 @@ typedef struct _tabby_printer_buffer {
uint16_t sum; uint16_t sum;
} tabby_printer_buffer; } tabby_printer_buffer;
typedef struct _tabby_printer_response { tabby_printer *tabby_printer_open(const char *device);
uint8_t device;
uint8_t status; void tabby_printer_close(tabby_printer *printer);
} tabby_printer_response;
/* /*
* For receiving printer data packets from a Game Boy Camera * 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, tabby_printer_packet *header,
void *body); void *body);
/* /*
* For sending printer data packets to a Game Boy Printer * 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, tabby_printer_packet *header,
void *body, void *body);
tabby_printer_response *response);
int tabby_printer_init(int fd, int tabby_printer_init(tabby_printer *printer);
tabby_printer_response *response);
int tabby_printer_send_inquiry(int fd, int tabby_printer_inquiry_send(tabby_printer *printer);
tabby_printer_response *response);
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 linefeeds,
uint8_t palette, uint8_t palette,
uint8_t density, uint8_t density);
tabby_printer_response *response);
int tabby_printer_job_cancel(int fd, int tabby_printer_job_cancel(tabby_printer *printer);
tabby_printer_response *response);
int tabby_printer_send_sheet(int fd, void *data, int tabby_printer_job_wait(tabby_printer *printer);
tabby_printer_response *response);
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 */ #endif /* _TABBY_PRINTER_H */

View file

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

View file

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