Index: src/main.c =================================================================== RCS file: /u/cvsroot/camediaplay/src/main.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- main.c 1997/10/21 00:23:18 1.1.1.1 +++ main.c 1997/10/21 00:57:08 1.2 @@ -1,9 +1,11 @@ +#define TEST_CHECKSUM + /* * Copyright(c) 1997 by Jun-ichiro Itoh. All rights reserved. * Freely redistributable unless otherwise noted. Absolutely no warranty. * * author contact: Jun-ichiro itojun Itoh - * $Id: camediaplay-diff.txt,v 1.1 1997/12/14 09:11:11 wolfgang Exp $ + * $Id: camediaplay-diff.txt,v 1.1 1997/12/14 09:11:11 wolfgang Exp $ */ #include "common.h" #include "camedia.h" @@ -25,7 +27,7 @@ #include /* serial lines */ -static int baudrateflag = 19200; +static int baudrateflag = 115200;/* 57600 19200 */ static char *n0; static int fd0; @@ -36,12 +38,18 @@ static int thumbnail = 0; static int verbose = 0; -static enum { SHOWNPICTS, GETPICTS, GETPICT1, GETSTATUS } mode = SHOWNPICTS; +static enum { + SHOWNPICTS, GETPICTS, GETPICT1, GETSTATUS, SETTIME, SETID, SETSERIALNO, + TAKEPICTURE +} mode = SHOWNPICTS; static int startpict = 0; static int endpict = 0; static int allpict = 0; +static char *idstring = ""; +static char *serialnostring = ""; + static char *nametemplate = "pic%05d.jpg"; #define SMALLWAIT 200*1000 /*usec*/ @@ -67,7 +75,7 @@ jmp_buf fatal; void -daemonuid() +daemonuid(void) { if (uidswapped == 0) return; @@ -85,7 +93,7 @@ } void -useruid() +useruid(void) { if (uidswapped == 1) return; @@ -103,8 +111,7 @@ } static int -uucplock(name) - char *name; +uucplock(char *name) { int ret; @@ -118,8 +125,7 @@ } static int -uucpunlock(name) - char *name; +uucpunlock(char *name) { int ret; @@ -133,8 +139,7 @@ } static char * -canondev(name) - char *name; +canondev(char *name) { int fd; char *p; @@ -148,26 +153,10 @@ } strcpy(p, name); fd = open(p, O_RDWR|O_NONBLOCK); - if (0 <= fd) { - close(fd); - goto back; - } - - p = realloc(p, strlen(name) + 6); - if (!p) { - perror("realloc"); - goto back; - } - strcpy(p, "/dev/"); - strcat(p, name); - fd = open(p, O_RDWR|O_NONBLOCK); - if (0 <= fd) { - close(fd); - goto back; + if (fd < 0) { + perror(p); + return NULL; } - - free(p); - p = NULL; back: useruid(); return p; @@ -230,9 +219,7 @@ } int -setbaud(fd, baud) - int fd; - int baud; +setbaud(int fd, int baud) { #if HAVE_TERMIOS_H /* termios */ @@ -281,10 +268,7 @@ } void -dump_stream(dir, buf, len) - int dir; - char *buf; - int len; +dump_stream(int dir, unsigned char *buf, int len) { size_t i; int truncate; @@ -313,19 +297,18 @@ /*------------------------------------------------------------*/ -char camedia_buf[1024 * 4]; +unsigned char camedia_buf[1024 * 4]; size_t camedia_len; void -camedia_init() +camedia_init(void) { /* initialize buffers */ camedia_len = 0; } int -camedia_wait(rlen) - int rlen; +camedia_wait(int rlen) { fd_set rdfd; int maxfd; @@ -338,7 +321,7 @@ FD_SET(fd0, &rdfd); maxfd = fd0; /* timeout: 2sec */ - t.tv_sec = 2; + t.tv_sec = 10; t.tv_usec = 0; switch (select(maxfd + 1, &rdfd, NULL, NULL, &t)) { case -1: @@ -368,9 +351,7 @@ } int -camedia_get(buf, len) - char *buf; - int len; +camedia_get(unsigned char *buf, int len) { switch (camedia_wait(len)) { case 1: @@ -393,9 +374,7 @@ } int -camedia_put(buf, len) - char *buf; - int len; +camedia_put(unsigned char *buf, int len) { int wlen; int i; @@ -429,9 +408,9 @@ /*------------------------------------------------------------*/ int -camedia_attention() +camedia_attention(void) { - char buf[10]; + unsigned char buf[10]; /* XXX: Important fix!!! -wsr */ int timeout; #define ATTN_WAIT 10 @@ -466,9 +445,9 @@ } int -camedia_getack() +camedia_getack(void) { - char buf[10]; + unsigned char buf[10]; camedia_get(buf, 1); if (buf[0] != 0x06) { @@ -479,13 +458,17 @@ return 0; } +#ifdef TEST_CHECKSUM +#define JUNKMAX 7 +int junkcount = 0; +int test_checksum = 0; +#endif + + int -camedia_sendcmd(ch, buf, len) - int ch; - char *buf; - int len; +camedia_sendcmd(int ch, unsigned char *buf, int len) { - char tbuf[2]; + unsigned char tbuf[2]; u_short sum; size_t i; int err; @@ -498,6 +481,16 @@ sum += (buf[i] & 0xff); } +#ifdef TEST_CHECKSUM + if (test_checksum){ + if (junkcount++ > JUNKMAX){ + junkcount = 0; + sum++; + fprintf(stderr, "\nIntentionally breaking TX checksum\n"); + } + } +#endif + tbuf[0] = '\033'; tbuf[1] = ch & 0xff; err = camedia_put(tbuf, 2); @@ -516,19 +509,16 @@ } int -camedia_getpacket(buf, plen, pfinal, ack, sector) - char *buf; - int *plen; - int *pfinal; - int *ack; - int *sector; +camedia_getpacket(unsigned char *buf, int *plen, int *pfinal, int *ack, int *sector) { int err; u_char tbuf[2]; u_short len; u_short cksum; size_t i; + int trys = 3; +again: err = 0; /* init */ @@ -543,12 +533,18 @@ dprintf((stderr, "err in camedia_getpacket: getting type\n")); err++; } - if (tbuf[0] == 0x06) { + if (tbuf[0] == 0x15) { + fprintf(stderr, "**** got NAK ****\n"); + return 1; + } else if (tbuf[0] == 0xff) { + fprintf(stderr, "**** Got Framing Error notification ****\n"); + return 1; + } else if (tbuf[0] == 0x06) { dprintf((stderr, "got ACK\n")); *ack = 1; return 0; } else if (tbuf[0] != 0x02 && tbuf[0] != 0x03) { - dprintf((stderr, "illegal packet received\n")); + dprintf((stderr, "illegal packet received: 0x%x\n", tbuf[0])); err++; goto back; } @@ -598,22 +594,32 @@ cksum += (buf[i] & 0xff); } +#ifdef TEST_CHECKSUM + if (test_checksum){ + if (junkcount++ > JUNKMAX){ + junkcount = 0; + cksum++; + fprintf(stderr, "\nIntentionally breaking RX checksum\n"); + } + } +#endif + if (tbuf[0] != (cksum & 0x00ff) || tbuf[1] != (cksum & 0xff00) >> 8) { dprintf((stderr, "err in camedia_getpacket: cksum\n")); -#if 0 err++; -#endif } - /* XXX must check for retransmit */ -#if 0 - if (!err) - camedia_put("\006", 1); /*ACK*/ - else - camedia_put("\025", 1); /*NAK*/ -#else - camedia_put("\006", 1); /*ACK*/ -#endif + if (!err){ + camedia_put("\006", 1); /*ACK*/ + } else { + camedia_put("\025", 1); /*NAK*/ + + if (trys-- > 0) { + fprintf(stderr, "Sending NAK, try %d, trying again\n", + trys + 1); + goto again; + } + } if (!err) *plen = len; @@ -623,18 +629,20 @@ } int -camedia_getint(cmd, n) - int cmd; - int *n; +camedia_getint(int cmd, int *n) { - char buf[1024]; + unsigned char buf[1024]; int len; int final; int ack; int err; + int trys = 3; err = 0; + +again: + cmd &= 0xff; buf[0] = CAM_GETNUM; buf[1] = cmd; @@ -648,6 +656,11 @@ if (camedia_getpacket(buf, &len, &final, &ack, NULL)) { dprintf((stderr, "getpacket err in camedia_getint(%02x %02x)\n", CAM_GETNUM, cmd)); + if (trys-- > 0) { + fprintf(stderr, "try %d, trying again\n", trys + 1); + goto again; + } + err++; goto ng; } @@ -671,18 +684,19 @@ } int -camedia_setint(cmd, n) - int cmd; - int n; +camedia_setint(int cmd, int n) { - char buf[1024]; + unsigned char buf[1024]; int len; int final; int ack; int err; + int trys = 3; err = 0; +again: + cmd &= 0xff; buf[0] = CAM_SETNUM; buf[1] = cmd; @@ -699,6 +713,12 @@ if (camedia_getpacket(buf, &len, &final, &ack, NULL)) { dprintf((stderr, "getpacket err in camedia_setint(%02x %02x)\n", CAM_SETNUM, cmd)); + + if (trys-- > 0) { + fprintf(stderr, "try %d, trying again\n", trys + 1); + goto again; + } + err++; goto ng; } @@ -714,19 +734,115 @@ } int -camedia_getstr(cmd, buf, plen) - int cmd; - char *buf; - int *plen; +camedia_setstr(int cmd, char *cp) { - char tbuf[10]; + unsigned char buf[1024]; int len; int final; int ack; int err; + int trys = 3; err = 0; +again: + cmd &= 0xff; + buf[0] = CAM_SETSTR; + buf[1] = cmd; + strncpy(buf+2, cp, sizeof(buf) - 3); + + len = strlen(buf+2) + 2 + 1; + + fprintf(stderr, "about to set the string '%s' pkt len %d\n", cp, len); + + if (camedia_sendcmd('C', buf, len)) { + dprintf((stderr, "sendcmd err in camedia_setint(%02x %02x)\n", + CAM_SETSTR, cmd)); + err++; + goto ng; + } + if (camedia_getpacket(buf, &len, &final, &ack, NULL)) { + dprintf((stderr, "getpacket err in camedia_setint(%02x %02x)\n", + CAM_SETSTR, cmd)); + + if (trys-- > 0) { + fprintf(stderr, "try %d, trying again\n", trys + 1); + goto again; + } + + err++; + goto ng; + } + if (!ack) { + dprintf((stderr, + "getpacket err in camedia_setint(%02x %02x): %d/%d\n", + CAM_SETSTR, cmd, final, ack)); + err++; + } + +ng: + return err ? 1 : 0; +} + +int +camedia_control(int cmd) +{ + unsigned char buf[1024]; + int len; + int final; + int ack; + int err; + int trys = 3; + + err = 0; + +again: + + cmd &= 0xff; + buf[0] = CAM_CONTROL; /* 0x02 */ + buf[1] = cmd; + if (camedia_sendcmd('C', buf, 2)) { + dprintf((stderr, "sendcmd err in camedia_setint(%02x %02x)\n", + CAM_CONTROL, cmd)); + err++; + goto ng; + } + if (camedia_getpacket(buf, &len, &final, &ack, NULL)) { + dprintf((stderr, "getpacket err in camedia_setint(%02x %02x)\n", + CAM_CONTROL, cmd)); + + if (trys-- > 0) { + fprintf(stderr, "try %d, trying again\n", trys + 1); + goto again; + } + + err++; + goto ng; + } + if (!ack) { + dprintf((stderr, + "getpacket err in camedia_setint(%02x %02x): %d/%d\n", + CAM_CONTROL, cmd, final, ack)); + err++; + } + +ng: + return err ? 1 : 0; +} + +int +camedia_getstr(int cmd, unsigned char *buf, int *plen) +{ + unsigned char tbuf[10]; + int final; + int ack; + int err; + int trys = 3; + + err = 0; + +again: + cmd &= 0xff; tbuf[0] = CAM_GETSTR; tbuf[1] = cmd; @@ -740,6 +856,11 @@ if (camedia_getpacket(buf, plen, &final, &ack, NULL)) { dprintf((stderr, "getpacket err in camedia_getstr(%02x %02x)\n", CAM_GETSTR, cmd)); + if (trys-- > 0) { + fprintf(stderr, "try %d, trying again\n", trys + 1); + goto again; + } + err++; goto ng; } @@ -758,10 +879,9 @@ /*------------------------------------------------------------*/ int -camedia_setspeed(baud) - int baud; +camedia_setspeed(int baud) { - char buf[10]; + unsigned char buf[10]; int err; char value; @@ -793,6 +913,9 @@ case 115200: value = '\005'; break; + case 230400: + value = '\006'; + break; default: /* unsupported baud rate. */ dprintf((stderr, "unsupported baudrate %d\n", baud)); @@ -825,9 +948,8 @@ } int -camedia_checkcamera() +camedia_checkcamera(void) { - char buf[1024]; int err; err = 0; @@ -851,14 +973,9 @@ } int -camedia_getnpicts(n) - int *n; +camedia_getnpicts(int *n) { - char buf[1024]; int err; - int len; - int final; - int ack; err = 0; @@ -880,14 +997,97 @@ } int -camedia_getnpictremain(n) - int *n; +camedia_settime(time_t n) +{ + int err; + + err = 0; + + /* get battery capacity - should check for battery shortage */ + if (camedia_getint(CAM_NUM_BATTERY, NULL)) { + dprintf((stderr, "getint err in camedia_getnpicts\n")); + err++; + } + + /* get picture # */ + if (camedia_setint(CAM_NUM_DATE, (int) n)) { + dprintf((stderr, "getint err in camedia_settime\n")); + err++; + } + + return err ? 1 : 0; +} + +int +camedia_setid(char *cp) +{ + int err; + + err = 0; + + /* get battery capacity - should check for battery shortage */ + if (camedia_getint(CAM_NUM_BATTERY, NULL)) { + dprintf((stderr, "getint err in camedia_getnpicts\n")); + err++; + } + + /* get picture # */ + if (camedia_setstr(CAM_STR_MODELID, cp)) { + dprintf((stderr, "getint err in camedia_setid\n")); + err++; + } + + return err ? 1 : 0; +} + +int +camedia_setserialno(char *cp) +{ + int err; + + err = 0; + + /* get battery capacity - should check for battery shortage */ + if (camedia_getint(CAM_NUM_BATTERY, NULL)) { + dprintf((stderr, "getint err in camedia_getnpicts\n")); + err++; + } + + /* get picture # */ + if (camedia_setstr(CAM_STR_SERIALNO, cp)) { + dprintf((stderr, "getint err in camedia_setserialno\n")); + err++; + } + + return err ? 1 : 0; +} + +int +camedia_takepicture(void) +{ + int err; + + err = 0; + + /* get battery capacity - should check for battery shortage */ + if (camedia_getint(CAM_NUM_BATTERY, NULL)) { + dprintf((stderr, "getint err in camedia_getnpicts\n")); + err++; + } + + /* get picture # */ + if (camedia_control(CAM_CTL_SHUTTER)) { + dprintf((stderr, "control command err in camedia_takepicture\n")); + err++; + } + + return err ? 1 : 0; +} + +int +camedia_getnpictremain(int *n) { - char buf[1024]; int err; - int len; - int final; - int ack; err = 0; @@ -909,23 +1109,22 @@ } int -camedia_getpict(n, thumbnail, fd) - int n; - int thumbnail; - int fd; +camedia_getpict(int n, int thumbnail, int fd) { - char buf[1024 * 4]; + unsigned char buf[1024 * 4]; int len; int final; int ack; int sector; int err; int totallen; - int cmd; + int trys = 3; err = 0; +again: + /* get battery capacity - should check for battery shortage */ if (camedia_getint(CAM_NUM_BATTERY, NULL)) { dprintf((stderr, "getint err in camedia_getnpicts\n")); @@ -958,6 +1157,10 @@ if (camedia_sendcmd('C', buf, 2)) { dprintf((stderr, "sendcmd err in camedia_getpict\n")); + if (trys-- > 0) { + fprintf(stderr, "try %d, trying again\n", trys + 1); + goto again; + } err++; } @@ -1000,12 +1203,10 @@ } int -camedia_getstatus() +camedia_getstatus(void) { - char buf[1024 * 4]; + unsigned char buf[1024 * 4]; int len; - int final; - int ack; int err; int n; char *t; @@ -1032,6 +1233,20 @@ } else fprintf(stderr, "camera type: %s\n", buf); + /* get serial number */ + if (camedia_getstr(CAM_STR_SERIALNO, buf, &len)) { + dprintf((stderr, "can't get camera serial number\n")); + err++; + } else + fprintf(stderr, "Serial Number: %s\n", buf); + + /* get serial number */ + if (camedia_getstr(CAM_STR_VERSION, buf, &len)) { + dprintf((stderr, "can't get sw version number\n")); + err++; + } else + fprintf(stderr, "Version Number: %s\n", buf); + /* get lens mode */ if (camedia_getint(CAM_NUM_LENS, &n)) { dprintf((stderr, "can't get lens mode\n")); @@ -1084,13 +1299,13 @@ fprintf(stderr, "quality mode: %s\n", t); } -#if 0 +#if 1 /* get time setting */ if (camedia_getint(CAM_NUM_DATE, &n)) { dprintf((stderr, "can't get time setting\n")); err++; } else { - time_t t1; + time_t t1, t2; /* * XXX @@ -1099,15 +1314,59 @@ * in a portable manner? */ t1 = n; - fprintf(stderr, "date on camera: %s", ctime(&t1)); +#if 1 + +#define UTC_OFFSET (-7 * 60 * 60) /* UTC offset in seconds */ + + t1 -= UTC_OFFSET; + + t2 = time (NULL); + + +# if 0 + setenv("TZ", "GMT", 1); +# endif +#else + { + struct tm *tmp; + time_t epoctime; + + epoctime = time(NULL); + tmp = localtime (epoctime); + n += tmp->tm_gmtoff; + } +#endif + fprintf(stderr, "date on camera: %sTime Offset: %d seconds\n", + ctime(&t1), (int)(t1 - t2)); } #endif + /* get battery level */ + if (camedia_getint(CAM_NUM_BATTERY, &n)) { + dprintf((stderr, "getint err in get battery level\n")); + err++; + } else { + fprintf(stderr, "battery level: %d\n", n); + } + return err ? 1 : 0; } +int +camedia_setcurtime(void) +{ + time_t t1; + + t1 = time(NULL); + t1 += UTC_OFFSET; + + t1 += 1; /* Estimated 1 sec delay in setting clock. */ + + return (camedia_settime(t1)); +} + void -mainloop() +mainloop(void) { int n; char fnamebuf[MAXPATHLEN]; @@ -1138,6 +1397,8 @@ goto fatalerr; } + if ((mode == SHOWNPICTS) || (mode == GETPICTS) || (mode == GETPICT1)) { + /* * parameter clarification */ @@ -1151,6 +1412,11 @@ if (endpict == 0) endpict = n; } + + if (n == 0){ + fprintf(stderr, "There are no pictures in the camera to get.\n"); + } + if (startpict < 1 || n < startpict) { fprintf(stderr, "illegal startpict %d (must be 1 to %d)\n", @@ -1170,6 +1436,8 @@ endpict = tmp; } + } + switch (mode) { case SHOWNPICTS: fprintf(stderr, "picts=%d/", n); @@ -1211,6 +1479,27 @@ case GETSTATUS: camedia_getstatus(); + break; + + case SETTIME: + camedia_setcurtime(); + break; + + case SETID: + camedia_setid(idstring); + break; + + case SETSERIALNO: + camedia_setserialno(serialnostring); + break; + + case TAKEPICTURE: + camedia_takepicture(); + break; + + default: + fprintf(stderr, "internal error - case not matched\n"); + break; } camedia_setspeed(-1); @@ -1223,29 +1512,30 @@ } void -usage() +usage(void) { fprintf(stderr, "usage:\n" "\tcamediaplay [options] port\n" "\tcamediaplay [options] -o port > foo.jpg\n" "\tcamediaplay [options] -g port\n" - "\tcamediaplay [options] -S port\n"); + "\tcamediaplay [options] -S port\n" + "\tcamediaplay [options] -T port\n" + ); } void -cleanup() +cleanup(void) { close(fd0); uucpunlock(n0); } void -main(argc, argv) - int argc; - char **argv; +main(int argc, char **argv) { char *s; + char *tty = "/dev/tty01"; /* default */ uid = getuid(); euid = geteuid(); @@ -1336,6 +1626,46 @@ mode = GETSTATUS; break; + case 'T': + mode = SETTIME; + break; + + case 'P': + mode = TAKEPICTURE; + break; + + case 'I': /* set ID string */ + if (!s[1]) { + fprintf(stderr, "no string specified" + "for new ID string.\n"); + exit(1); + } + idstring = &s[1]; + while (*s) + s++; + s--; + mode = SETID; + break; + + case '#': /* set ID string */ + if (!s[1]) { + fprintf(stderr, "no string specified" + "for new ID string.\n"); + exit(1); + } + serialnostring = &s[1]; + while (*s) + s++; + s--; + mode = SETSERIALNO; + break; + +#ifdef TEST_CHECKSUM + case 'X': + test_checksum = 1; + break; +#endif + default: fprintf(stderr, "unknown option -%c\n", *s); usage(); @@ -1348,13 +1678,11 @@ fprintf(stderr, "invalid argument\n"); usage(); exit(1); - } else if (argc == 0) { - fprintf(stderr, "no device specified\n"); - usage(); - exit(1); + } else if (argc == 1) { + tty = argv[0]; } - n0 = canondev(argv[0]); + n0 = canondev(tty); if (!n0) { fprintf(stderr, "inappropriate device specified, " "or device permission error\n"); @@ -1380,3 +1708,7 @@ exit(0); } + +/* + * end + */ Index: src/uucplock.c =================================================================== RCS file: /u/cvsroot/camediaplay/src/uucplock.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- uucplock.c 1997/10/21 00:23:18 1.1.1.1 +++ uucplock.c 1997/10/21 00:57:08 1.2 @@ -1,3 +1,8 @@ +/* $Id: camediaplay-diff.txt,v 1.1 1997/12/14 09:11:11 wolfgang Exp $ */ + +#ifndef lint +static char vcid[] = "$Id: camediaplay-diff.txt,v 1.1 1997/12/14 09:11:11 wolfgang Exp $"; +#endif /* lint */ /* * Copyright (c) 1988 The Regents of the University of California. * All rights reserved. @@ -49,13 +54,22 @@ * -1 - failure */ -uu_lock(ttyname) - char *ttyname; + +extern int sprintf (char *, const char *, ...); +extern void perror (const char *); +extern int read (int, void *, size_t); +extern int close (int); +extern int kill (pid_t, int); +extern pid_t getpid (void); +extern int write (int, const void *, size_t); +extern int unlink (const char *); + +uu_lock(char *ttyname) { extern int errno; int fd, pid; char tbuf[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN]; - off_t lseek(); + off_t lseek(int, off_t, int); (void)sprintf(tbuf, _PATH_LOCKDIRNAME, ttyname); fd = open(tbuf, O_RDWR|O_CREAT|O_EXCL, 0664); @@ -70,12 +84,15 @@ return(-1); } if (read(fd, &pid, sizeof(pid)) != sizeof(pid)) { + extern int read (int, void *, size_t); (void)close(fd); perror("lock read"); return(-1); } if (kill(pid, 0) == 0 || errno != ESRCH) { + extern void perror (const char *); + extern int kill (pid_t, int); (void)close(fd); /* process is still running */ return(-1); } @@ -84,6 +101,7 @@ * we'll lock it ourselves */ if (lseek(fd, 0L, L_SET) < 0) { + extern void perror (const char *); (void)close(fd); perror("lock lseek"); return(-1); @@ -92,6 +110,7 @@ } pid = getpid(); if (write(fd, (char *)&pid, sizeof(pid)) != sizeof(pid)) { + extern int write (int, const void *, size_t); (void)close(fd); (void)unlink(tbuf); perror("lock write"); @@ -101,8 +120,7 @@ return(0); } -uu_unlock(ttyname) - char *ttyname; +uu_unlock(char *ttyname) { char tbuf[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN];