#include #include #include #include #include #include #define STX 0x02 #define ETX 0x03 #define ENQ 0x05 #define ACK 0x06 #define NAK 0x15 #define ETB 0x17 #define NORMAL 0 #define FINE 1 void flushtty(int fd); void showttystate(int fd); u_char rbyte(int fd); int running=1; int exiting=0; void sigint(); int debug=0; char *where="start"; main(argc,argv) int argc; char **argv; { int qvfd, s, num, attr, i; char buf[8], byte=0; long tym, otym, tym1, tym2, tym3; qvfd=devinit("/dev/term/a"); if (debug) fprintf(stderr,"trying initial ok...\n"); wbyte(qvfd,ENQ); wait_for_input(qvfd,10); if (read(qvfd,&byte,1) != 1) { fprintf(stderr, "Can't communicate! Trying high baud rate...\n"); tty_change_speed(qvfd,B115200); } qvok(qvfd); fprintf(stderr, "(communicating!)\n"); signal(SIGINT,sigint); if (debug) showttystate(qvfd); sleep(1); debug_status("changing speed"); qv_change_speed(qvfd,B115200); num=qvhowmany(qvfd); if (debug) fprintf(stderr,"%d pictures\n",num); /* debug_status("setting mode"); qvmode(qvfd,NORMAL); */ tym=0; while(running) { otym=tym; tym=time(NULL); if (otym) { printf("%d seconds for last snapshot", tym-otym); printf(" (%d, %d, %d, %d)\n", tym1-otym, tym2-tym1, tym3-tym2, tym-tym3); } debug_status("setting sector"); qvsector(qvfd, 0x340); tym1=time(NULL); /* take a picture */ usleep(700000); /* seems to lessen camera lock-ups */ debug_status("taking picture (ok)"); qvok(qvfd); debug_status("taking picture (command)"); wbyte(qvfd,'D'); wbyte(qvfd,'R'); s = rbyte(qvfd); debug_status("taking picture (command, ACK)"); /* sleep(1); */ wbyte(qvfd,ACK); s = rbyte(qvfd); /* debug_status("taking picture (reset sector)"); qvsector(qvfd, 0x600); */ /* sleep(1); */ debug_status("getting picture num"); /* get the picture number */ num=qvhowmany(qvfd); /* get picture attributes */ attr=qvattr(qvfd,num); if (debug) { fprintf(stderr, "attr=0x%x\n", attr); } tym2=time(NULL); debug_status("getting picture data"); /* grab the picture */ get_picture(qvfd,num,attr); /* sleep(1); */ debug_status("deleting picture data"); /* delete the picture */ qvdelete(qvfd,num); tym3=time(NULL); debug_status("resetting camera"); /* reset the camera? */ qvreset(qvfd); } clean_exit(qvfd); } int qvok (fd) int fd; { int i; for (i=0; i<100; ++i) { if (debug) fprintf(stderr,"trying ok...\n"); wbyte(fd,ENQ); if (rbyte(fd) == ACK) { if (debug) fprintf(stderr,"OK\n"); return(1); } } fprintf(stderr,"error at %s\n", where); perror("qv is not OK!"); exit(-1); } int qvhowmany (fd) int fd; { int x; qvok(fd); write(fd,"MP",2); x = rbyte(fd); if (x != 0x62) { fprintf(stderr,"error at %s\n", where); perror("howmany invalid response"); exit(-1); } wbyte(fd,ACK); x = rbyte(fd); return((int) x); } int qvattr (fd,picnum) int fd, picnum; { u_int c; qvok(fd); write(fd,"DY",2); wbyte(fd, 0x02); wbyte(fd, picnum); rbyte(fd); wbyte(fd,ACK); c=rbyte(fd); return(c); } int qvsector (fd, n) int fd; int n; { u_char c; qvok(fd); write(fd,"PP",2); wbyte(fd,(u_char)(n >> 8) & 0xff); wbyte(fd,(u_char)n & 0xff); c=rbyte(fd); wbyte(fd,ACK); } int devinit(devfile) char *devfile; { int fd, mode, val; struct termios tio; fd=open(devfile,O_RDWR | O_NDELAY); if (fd < 0) { perror("open"); exit(-1); } val=1; /* if (ioctl(fd, TIOCSSOFTCAR, &val) < 0) { perror("soft carrier detect"); exit(-1); } */ /* if (ioctl(fd, TIOCEXCL, 0) < 0) { perror("exclusive"); exit(-1); } if (ioctl(fd, TIOCHPCL, 0) < 0) { perror("hold"); exit(-1); } */ tty_change_speed(fd, B9600); return(fd); } int qv_change_speed(fd, baud) int fd, baud; { int mode, val; struct termios tio; int baud_code; switch(baud) { case B9600: baud_code=46; break; case B19200: baud_code=22; break; case B38400: baud_code=11; break; case B57600: baud_code=7; break; case B115200: baud_code=3; break; case B153600: baud_code=2; break; case B230400: baud_code=1; break; case B460800: baud_code=0; break; default: fprintf(stderr,"No such baud available!\n"); exit(1); } qvok(fd); wbyte(fd,'C'); wbyte(fd,'B'); wbyte(fd,baud_code); rbyte(fd); wbyte(fd,ACK); sleep(1); tty_change_speed(fd, baud); return(0); } int tty_change_speed(fd, baud) int fd, baud; { int mode, val; struct termios tio; if (tcgetattr(fd, &tio) < 0) { perror("tcgetattr"); exit(-1); } tio.c_iflag=0; tio.c_oflag=0; tio.c_cflag=CS8 | CREAD | CLOCAL ; tio.c_lflag=0; tio.c_cc[VMIN]=1; tio.c_cc[VTIME]=5; if (cfsetispeed(&tio, baud)) { perror("set input speed"); exit(-1); } if (cfsetospeed(&tio, baud)) { perror("set output speed"); exit(-1); } if (tcsetattr(fd, TCSANOW, &tio) < 0) { perror("tcsetattr"); exit(-1); } mode = TIOCM_RTS; if(ioctl(fd, TIOCMBIC, &mode) < 0){ /* RTS OFF */ fprintf(stderr, "Can't set RTS OFF.\n"); close(fd); return(-1); } mode = TIOCM_CTS|TIOCM_DTR; if(ioctl(fd, TIOCMBIS, &mode) < 0){ /* CTS DTR ON */ fprintf(stderr, "Can't set CTS DTR ON.\n"); close(fd); return(-1); } /* showttystate(fd); */ flushtty(fd); return(0); } int clean_exit(fd) int fd; { int mode, val; struct termios tio; int baud_code; /* don't re-enter */ if (exiting) { exit(1); } exiting=1; flushtty(fd); if (tcgetattr(fd, &tio) < 0) { perror("tcgetattr"); exit(-1); } tio.c_iflag=0; tio.c_oflag=0; tio.c_cflag=CS8 | CREAD | CLOCAL ; tio.c_lflag=0; tio.c_cc[VMIN]=1; tio.c_cc[VTIME]=5; if (cfsetispeed(&tio, B9600)) { perror("set input speed"); exit(-1); } if (cfsetospeed(&tio, B9600)) { perror("set output speed"); exit(-1); } qvok(fd); wbyte(fd,'C'); wbyte(fd,'B'); wbyte(fd, 46); rbyte(fd); wbyte(fd,ACK); sleep(1); if (tcsetattr(fd, TCSANOW, &tio) < 0) { perror("tcsetattr"); exit(-1); } fprintf(stderr, "Exited cleanly!\n"); exit(0); } int qvdelete (fd,picnum) int fd, picnum; { qvok(fd); wbyte(fd,'D'); wbyte(fd,'F'); wbyte(fd,picnum); wbyte(fd,255); rbyte(fd); wbyte(fd,ACK); } int show_picture (fd,picnum) int fd, picnum; { qvok(fd); wbyte(fd,'D'); wbyte(fd,'A'); wbyte(fd,picnum); rbyte(fd); wbyte(fd,ACK); } int get_picture (fd,picnum,attr) int fd, picnum, attr; { u_char c, buf[128*1024], *ptr; int i, sum, blksz, nr; FILE *fp; show_picture(fd,picnum); /* the DL may not be necessary, but it doesn't take much time */ qvok(fd); wbyte(fd,'D'); wbyte(fd,'L'); rbyte(fd); /* should be 6f */ wbyte(fd,ACK); qvok(fd); wbyte(fd,'M'); if (attr & 0x02) { /* fine mode */ wbyte(fd,'g'); } else { /* normal mode */ wbyte(fd,'G'); } rbyte(fd); /* should be 6b */ wbyte(fd,ACK); wbyte(fd,0x12); ptr=buf; while(1) { if (debug) fprintf(stderr,"======starting block read======\n"); sum=0; c=rbyte(fd); if (c!=STX) { fprintf(stderr,"didn't get STX (got 0x%x)\n", c); exit(1); } c=rbyte(fd); sum+=c; blksz=c*256; c=rbyte(fd); sum+=c; blksz += c; if (blksz == 0) break; nr=0; /* while ((nr+=read(fd,ptr+nr,blksz-nr)) < blksz); */ while (nr < blksz) { wait_for_input(fd,5); nr += read(fd,ptr+nr,blksz-nr); if (errno == EINTR && running == 0) { clean_exit(fd); } } if (debug) fprintf(stderr, " read completed, nr=%d\n",nr); for (i=0; i i) { l = ( (len - i) < BUFSIZ) ? (len -i) : BUFSIZ; if(fwrite(&buf[i], sizeof(u_char), l, outfp) != l){ perror("write_file"); return(-1); }; i = i + l; } return(i); } int write_jpeg(buf, outfp) u_char *buf; FILE *outfp; { int i = 0; int areaNum; int ysize; int usize; int vsize; areaNum = get_u_short(buf); /* areaNum == 0x03 */ ysize = get_u_short(buf + 2); usize = get_u_short(buf + 4); vsize = get_u_short(buf + 6); i = i + 8; if(write_file(soi, sizeof(soi), outfp) == -1) return(-1); if(write_file(app0, sizeof(app0), outfp) == -1) return(-1); if(write_file(dqt0, sizeof(dqt0), outfp) == -1) return(-1); if(write_file(&buf[i], 64, outfp) == -1) return(-1); i = i + 64; if(write_file(dqt1, sizeof(dqt1), outfp) == -1) return(-1); if(write_file(&buf[i], 64, outfp) == -1) return(-1); i = i + 64; if(write_file(sof, sizeof(sof), outfp) == -1) return(-1); if(write_file(dht, sizeof(dht), outfp) == -1) return(-1); if(write_file(sos_y, sizeof(sos_y), outfp) == -1) return(-1); if(write_file(&buf[i], ysize, outfp) == -1) return(-1); i = i + ysize; if(write_file(sos_u, sizeof(sos_u), outfp) == -1) return(-1); if(write_file(&buf[i], usize, outfp) == -1) return(-1); i = i + usize; if(write_file(sos_v, sizeof(sos_v), outfp) == -1) return(-1); if(write_file(&buf[i], vsize, outfp) == -1) return(-1); i = i + vsize; if(write_file(eoi, sizeof(eoi), outfp) == -1) return(-1); return(i); } int write_jpeg_fine(buf, outfp) u_char *buf; FILE *outfp; { int i = 0; int size; u_char c = 0x01; size = get_u_int(buf + 4); i = i + 8; if(write_file(soi, sizeof(soi), outfp) == -1) return(-1); if(write_file(app_f, sizeof(app_f), outfp) == -1) return(-1); if(write_file(dqt_f, sizeof(dqt_f), outfp) == -1) return(-1); if(write_file(&buf[i], 64, outfp) == -1) return(-1); i = i + 64; if(write_file(&c, 1, outfp) == -1) return(-1); if(write_file(&buf[i], 64, outfp) == -1) return(-1); i = i + 64; if(write_file(sof_f, sizeof(sof_f), outfp) == -1) return(-1); if(write_file(dht_f, sizeof(dht_f), outfp) == -1) return(-1); if(write_file(sos_f, sizeof(sos_f), outfp) == -1) return(-1); if(write_file(&buf[i], size, outfp) == -1) return(-1); if(write_file(eoi, sizeof(eoi), outfp) == -1) return(-1); return(i); }