/* * (C) Copyright 2000 * Murray Jensen <Murray.Jensen@csiro.au> * * See file CREDITS for list of people who contributed to this * project. * * 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 */ #include <unistd.h> #include <string.h> #include <fcntl.h> #include <sys/time.h> #include "serial.h" #if defined(__sun__) || \ defined(__OpenBSD__) || \ defined(__FreeBSD__) || \ defined(__NetBSD__) || \ defined(__APPLE__) static struct termios tios = { BRKINT, 0, B115200|CS8|CREAD, 0, { 0 } }; #else static struct termios tios = { BRKINT, 0, B115200|CS8|CREAD, 0, 0 }; #endif static struct speedmap { char *str; speed_t val; } speedmap[] = { { "50", B50 }, { "75", B75 }, { "110", B110 }, { "134", B134 }, { "150", B150 }, { "200", B200 }, { "300", B300 }, { "600", B600 }, { "1200", B1200 }, { "1800", B1800 }, { "2400", B2400 }, { "4800", B4800 }, { "9600", B9600 }, { "19200", B19200 }, { "38400", B38400 }, { "57600", B57600 }, #ifdef B76800 { "76800", B76800 }, #endif { "115200", B115200 }, #ifdef B153600 { "153600", B153600 }, #endif { "230400", B230400 }, #ifdef B307200 { "307200", B307200 }, #endif #ifdef B460800 { "460800", B460800 } #endif }; static int nspeeds = sizeof speedmap / sizeof speedmap[0]; speed_t cvtspeed(char *str) { struct speedmap *smp = speedmap, *esmp = &speedmap[nspeeds]; while (smp < esmp) { if (strcmp(str, smp->str) == 0) return (smp->val); smp++; } return B0; } int serialopen(char *device, speed_t speed) { int fd; if (cfsetospeed(&tios, speed) < 0) return -1; if ((fd = open(device, O_RDWR)) < 0) return -1; if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { (void)close(fd); return -1; } return fd; } int serialreadchar(int fd, int timeout) { fd_set fds; struct timeval tv; int n; char ch; tv.tv_sec = timeout; tv.tv_usec = 0; FD_ZERO(&fds); FD_SET(fd, &fds); /* this is a fucking horrible quick hack - fix this */ if ((n = select(fd + 1, &fds, 0, 0, &tv)) < 0) return SERIAL_ERROR; if (n == 0) return SERIAL_TIMEOUT; if ((n = read(fd, &ch, 1)) < 0) return SERIAL_ERROR; if (n == 0) return SERIAL_EOF; return ch; } int serialwrite(int fd, char *buf, int len) { int n; do { n = write(fd, buf, len); if (n < 0) return 1; len -= n; buf += n; } while (len > 0); return 0; } int serialclose(int fd) { return close(fd); }