/* Open Digita Services -- Camera Device Protocol definitions. Copyright (C) 1998, 1999 James C. Thompson Copyright (C) 1998, 1999 Viljo Hakala This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /*-------------------------------------------------------------------------- System include files */ #if defined(HAVE_CONFIG_H) #include "config.h" #endif #include #if defined(HAVE_FCNTL_H) #include #endif #include #if defined(HAVE_UNISTD_H) #include #endif #include #include #if defined(__BEOS__) #include #endif /*-------------------------------------------------------------------------- Local include files */ #include "defs.h" #include "format-mem.h" /* Start editing here: */ #if defined(__BEOS__) /* Be doesn't have usleep, but it has the equivalent "snooze". */ void usleep(unsigned long usec) { bigtime_t bt = usec; snooze(bt); } #endif unsigned int checksum(const unsigned char *buffer, int len) { int i; int limit = len - 1; unsigned int sum = 0; for (i = 0; i < limit; i++) { sum += *(buffer++); } return sum & 0xff; } int verify_checksum(const unsigned char *buffer, int len) { unsigned int sum = checksum(buffer, len); return sum == buffer[len - 1] ? 1 : 0; } void set_checksum(unsigned char *buffer, int len) { unsigned int sum = checksum(buffer, len); buffer[len - 1] = sum; } int read_fully(int fd, unsigned char *buffer, int len, unsigned long timeout) { #if defined(DEBUG) unsigned char *buforig = buffer; #endif int bytes_read = 0; int bytes_remaining = len; #if defined(HAVE_SELECT) /* We're not using select on BeOS. */ fd_set fds; int ret; struct timeval time; /* Set up the file-descriptor array for select. */ FD_ZERO(&fds); FD_SET(fd, &fds); /* Set up the select call for the specified timeout. */ time.tv_sec = timeout / 1000; time.tv_usec = 1000 * (timeout % 1000); #endif #if defined(DEBUG) printf("reading with timeout = %ld\n", timeout); #endif while (bytes_read < len) { int read_here; #if defined(HAVE_SELECT) /* Apparently, selecting on a serial port doesn't work as it on unixes. We can just skip the call to select; it means we don't get timeouts, but for now that's OK. */ if ((ret = select(fd + 1, &fds, NULL, NULL, &time)) < 0) { fprintf(stderr, "Couldn't select() on the port\n"); exit(-1); } if (!ret) { return -1; } #endif read_here = read(fd, buffer, bytes_remaining); if (read_here > 0) { bytes_remaining -= read_here; bytes_read += read_here; buffer += read_here; } else #if defined(__BEOS__) /* On BeOS, sleep for a millisecond before trying to reread; this keeps us from pegging the CPU, but adds only a tiny bit of extra time to the download. */ { usleep(1000); } #else /* On BeOS, skip this error check. Be sometimes returns 0, even if we use a blocking socket. We have much to learn about I/O on BeOS, but for now this at least works. */ { #if defined(HAVE_STRERROR) printf("read returned %d : %s\n", read_here, strerror(errno)); #else printf("read returned %d.\n", read_here); #endif printf("Can't get any answer from camera. Check cable/power/mode.\n"); exit(-1); } #endif } #ifdef DEBUG printf("read_fully:\n"); format_chars(stdout, (char *) buforig, 0, len); #endif return bytes_read; } int write_fully(int fd, const unsigned char *buffer, int len) { int bytes_written = 0; int bytes_remaining = len; #ifdef DEBUG printf("write_fully:\n"); format_chars(stdout, (char *) buffer, 0, len); #endif while (bytes_written < len) { int written_here = write(fd, buffer, bytes_remaining); if (written_here > 0) { bytes_remaining -= written_here; bytes_written += written_here; buffer += written_here; } } return bytes_written; }