1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2000 4 * Murray Jensen <Murray.Jensen@csiro.au> 5 */ 6 7 #include <unistd.h> 8 #include <string.h> 9 #include <fcntl.h> 10 #include <sys/time.h> 11 #include "serial.h" 12 13 #if defined(__sun__) || \ 14 defined(__OpenBSD__) || \ 15 defined(__FreeBSD__) || \ 16 defined(__NetBSD__) || \ 17 defined(__APPLE__) 18 static struct termios tios = { BRKINT, 0, B115200|CS8|CREAD, 0, { 0 } }; 19 #else 20 static struct termios tios = { BRKINT, 0, B115200|CS8|CREAD, 0, 0 }; 21 #endif 22 23 static struct speedmap { 24 char *str; 25 speed_t val; 26 } speedmap[] = { 27 { "50", B50 }, { "75", B75 }, { "110", B110 }, 28 { "134", B134 }, { "150", B150 }, { "200", B200 }, 29 { "300", B300 }, { "600", B600 }, { "1200", B1200 }, 30 { "1800", B1800 }, { "2400", B2400 }, { "4800", B4800 }, 31 { "9600", B9600 }, { "19200", B19200 }, { "38400", B38400 }, 32 { "57600", B57600 }, 33 #ifdef B76800 34 { "76800", B76800 }, 35 #endif 36 { "115200", B115200 }, 37 #ifdef B153600 38 { "153600", B153600 }, 39 #endif 40 { "230400", B230400 }, 41 #ifdef B307200 42 { "307200", B307200 }, 43 #endif 44 #ifdef B460800 45 { "460800", B460800 } 46 #endif 47 }; 48 static int nspeeds = sizeof speedmap / sizeof speedmap[0]; 49 50 speed_t 51 cvtspeed(char *str) 52 { 53 struct speedmap *smp = speedmap, *esmp = &speedmap[nspeeds]; 54 55 while (smp < esmp) { 56 if (strcmp(str, smp->str) == 0) 57 return (smp->val); 58 smp++; 59 } 60 return B0; 61 } 62 63 int 64 serialopen(char *device, speed_t speed) 65 { 66 int fd; 67 68 if (cfsetospeed(&tios, speed) < 0) 69 return -1; 70 71 if ((fd = open(device, O_RDWR)) < 0) 72 return -1; 73 74 if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { 75 (void)close(fd); 76 return -1; 77 } 78 79 return fd; 80 } 81 82 int 83 serialreadchar(int fd, int timeout) 84 { 85 fd_set fds; 86 struct timeval tv; 87 int n; 88 char ch; 89 90 tv.tv_sec = timeout; 91 tv.tv_usec = 0; 92 93 FD_ZERO(&fds); 94 FD_SET(fd, &fds); 95 96 /* this is a fucking horrible quick hack - fix this */ 97 98 if ((n = select(fd + 1, &fds, 0, 0, &tv)) < 0) 99 return SERIAL_ERROR; 100 101 if (n == 0) 102 return SERIAL_TIMEOUT; 103 104 if ((n = read(fd, &ch, 1)) < 0) 105 return SERIAL_ERROR; 106 107 if (n == 0) 108 return SERIAL_EOF; 109 110 return ch; 111 } 112 113 int 114 serialwrite(int fd, char *buf, int len) 115 { 116 int n; 117 118 do { 119 n = write(fd, buf, len); 120 if (n < 0) 121 return 1; 122 len -= n; 123 buf += n; 124 } while (len > 0); 125 return 0; 126 } 127 128 int 129 serialclose(int fd) 130 { 131 return close(fd); 132 } 133