/* * file: dc320.c # description: download program for Polaroid DC320 POS camera * author: Peter Desnoyers, pjd@fred.cambridge.ma.us */ #include #include #include #include #include #define E6_4 0xe6, 0xe6, 0xe6, 0xe6 #define E6_8 E6_4, E6_4 void printhex(int n, unsigned char *buf) { int i; for (i = 0; i < n; i++) { if (i > 0 && (i%16) == 0) printf("\n"); printf(" %02X", buf[i]); } printf("\n"); } /* need better read and write routines. In particular, read needs to use select() for timeout, and retry a few times in the camera find routine. Other routines can bail on timeout. Write should calculate the checksum for us; reads should verify the checksum and data received. */ void hdr(int fd) { char cmd1[] = {E6_8, 0, 0xff, 0xff}; char cmd2[] = {E6_4, 1, 0xfe, 0xff}; char cmd3[] = {E6_4, 2, 0xfd, 0xff}; char cmd4[] = {E6_4, 0xa, 0xf5, 0xff}; unsigned char buf[32]; int n; write(fd, cmd1, sizeof(cmd1)); n = read(fd, buf, sizeof(buf)); // printhex(n, buf); write(fd, cmd2, sizeof(cmd2)); n = read(fd, buf, sizeof(buf)); // printhex(n, buf); write(fd, cmd3, sizeof(cmd3)); n = read(fd, buf, sizeof(buf)); // printhex(n, buf); write(fd, cmd4, sizeof(cmd4)); n = read(fd, buf, sizeof(buf)); // printhex(n, buf); printf("found camera\n"); } int npics(int fd) { char cmd1[] = {E6_4, 3, 0xfc, 0xff}; unsigned char buf[32]; int n; write(fd, cmd1, sizeof(cmd1)); n = read(fd, buf, sizeof(buf)); printhex(n, buf); return buf[1]; } int picsiz(int fd, int i) { char cmd1[] = {E6_4, 4, 1, 0xfb, 0xfe}; unsigned char buf[32]; int n, len; cmd1[5] += (i-1); cmd1[7] -= (i-1); write(fd, cmd1, sizeof(cmd1)); n = read(fd, buf, sizeof(buf)); printhex(n, buf); len = (buf[1] << 24) + (buf[2] << 16) + (buf[3] << 8) + buf[4]; printf("pic(%d) = %d bytes\n", i, len); return len; } /* packet checksum: 1s complement sum of bytes, then subtract from 255 (like IP checksum, but 8 bits) so 1s complement sum of all bytes=0. */ /* Unknown data. It may be needed to interpret the image - it's identical for images with about the same brightness, but differs between varied images. Format is : 07 00 06 aa aa 7f bb bb ?? xx aa aa, bb bb = data ?? - not sure if data or checksum xx - packet checksum */ void getxxx(int fd, int i) { char cmd[] = {E6_4, 0x0c, 01, 0xf3, 0xfe}; unsigned char buf[32]; int n; cmd[5] += (i-1); cmd[7] -= (i-1); write(fd, cmd, sizeof(cmd)); n = read(fd, buf, sizeof(buf)); printf("unknown: "), printhex(n, buf); } void getpic(int fd, int i, int len, char *name) { char cmd1[] = {E6_4, 5, 1, 0xfa, 0xfe}; unsigned char buf[2048], *p; int n, j, cksum, f1, f2; FILE *fp; printf("reading picture %d (%s)\n", i, name); fp = fopen(name, "w"); cmd1[5] += (i-1); cmd1[7] -= (i-1); write(fd, cmd1, sizeof(cmd1)); while (len > 0) { j = (len>2000) ? 2000 : len; usleep(10000); n = read(fd, buf, 5); f1 = (buf[1]<<8) + buf[2]; f2 = (buf[3]<<8) + buf[4]; printf("frame %d (%d)\n", f1, f2); for (p = buf; n > 0 && j > 0; p += n, j -= n) { usleep(1000); n = read(fd, p, j); } fwrite(buf, p-buf, 1, fp); len -= (p-buf); n = read(fd, buf, 2); cksum = (buf[0]<<8) + buf[1]; } fclose(fp); } void delpics(int fd) { char cmd[] = {E6_4, 7, 0xf8, 0xff}; unsigned char buf[32]; int n; write(fd, cmd, sizeof(cmd)); n = read(fd, buf, sizeof(buf)); printf("delete complete: "), printhex(n, buf); } int main(int argc, char **argv) { int fd; struct termios ti; int n, size, i; int getpics=0, delete=0; char nbuf[32]; if (argc == 2 && !strcmp(argv[1], "-get")) getpics++; if (argc == 2 && !strcmp(argv[1], "-delete")) delete=1; if ((fd = open("/dev/ttyS0", O_RDWR)) < 0) perror("can't open tty\n"), exit(1); if (tcgetattr(fd, &ti) < 0) perror("can't get attr\n"), exit(1); cfmakeraw(&ti); cfsetospeed(&ti, B115200); cfsetispeed(&ti, B115200); if (tcsetattr(fd, TCSANOW, &ti) < 0) perror("can't set attr\n"), exit(1); hdr(fd); if (delete) delpics(fd); else { n = npics(fd); printf("%d pictures\n", n); for (i = 1; i <= n; i++) { size = picsiz(fd, i); printf("picture %d: %d bytes\n", i, size); if (getpics) { sprintf(nbuf, "pic.%d.dat", i); getpic(fd, i, size, nbuf); } getxxx(fd, i); } } close(fd); return 0; }