1 /* 2 * (C) Copyright 2000 3 * Murray Jensen <Murray.Jensen@csiro.au> 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24 #include <unistd.h> 25 #include <string.h> 26 #include <fcntl.h> 27 #include <sys/time.h> 28 #include "serial.h" 29 30 #if defined(__sun__) || \ 31 defined(__OpenBSD__) || \ 32 defined(__FreeBSD__) || \ 33 defined(__NetBSD__) || \ 34 defined(__APPLE__) 35 static struct termios tios = { BRKINT, 0, B115200|CS8|CREAD, 0, { 0 } }; 36 #else 37 static struct termios tios = { BRKINT, 0, B115200|CS8|CREAD, 0, 0 }; 38 #endif 39 40 static struct speedmap { 41 char *str; 42 speed_t val; 43 } speedmap[] = { 44 { "50", B50 }, { "75", B75 }, { "110", B110 }, 45 { "134", B134 }, { "150", B150 }, { "200", B200 }, 46 { "300", B300 }, { "600", B600 }, { "1200", B1200 }, 47 { "1800", B1800 }, { "2400", B2400 }, { "4800", B4800 }, 48 { "9600", B9600 }, { "19200", B19200 }, { "38400", B38400 }, 49 { "57600", B57600 }, 50 #ifdef B76800 51 { "76800", B76800 }, 52 #endif 53 { "115200", B115200 }, 54 #ifdef B153600 55 { "153600", B153600 }, 56 #endif 57 { "230400", B230400 }, 58 #ifdef B307200 59 { "307200", B307200 }, 60 #endif 61 #ifdef B460800 62 { "460800", B460800 } 63 #endif 64 }; 65 static int nspeeds = sizeof speedmap / sizeof speedmap[0]; 66 67 speed_t 68 cvtspeed(char *str) 69 { 70 struct speedmap *smp = speedmap, *esmp = &speedmap[nspeeds]; 71 72 while (smp < esmp) { 73 if (strcmp(str, smp->str) == 0) 74 return (smp->val); 75 smp++; 76 } 77 return B0; 78 } 79 80 int 81 serialopen(char *device, speed_t speed) 82 { 83 int fd; 84 85 if (cfsetospeed(&tios, speed) < 0) 86 return -1; 87 88 if ((fd = open(device, O_RDWR)) < 0) 89 return -1; 90 91 if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { 92 (void)close(fd); 93 return -1; 94 } 95 96 return fd; 97 } 98 99 int 100 serialreadchar(int fd, int timeout) 101 { 102 fd_set fds; 103 struct timeval tv; 104 int n; 105 char ch; 106 107 tv.tv_sec = timeout; 108 tv.tv_usec = 0; 109 110 FD_ZERO(&fds); 111 FD_SET(fd, &fds); 112 113 /* this is a fucking horrible quick hack - fix this */ 114 115 if ((n = select(fd + 1, &fds, 0, 0, &tv)) < 0) 116 return SERIAL_ERROR; 117 118 if (n == 0) 119 return SERIAL_TIMEOUT; 120 121 if ((n = read(fd, &ch, 1)) < 0) 122 return SERIAL_ERROR; 123 124 if (n == 0) 125 return SERIAL_EOF; 126 127 return ch; 128 } 129 130 int 131 serialwrite(int fd, char *buf, int len) 132 { 133 int n; 134 135 do { 136 n = write(fd, buf, len); 137 if (n < 0) 138 return 1; 139 len -= n; 140 buf += n; 141 } while (len > 0); 142 return 0; 143 } 144 145 int 146 serialclose(int fd) 147 { 148 return close(fd); 149 } 150