#include #include #include #include #include #include #include #include #include #include #include #include #include #define termios asmtermios #define winsize asmwinsize #define termio asmtermio #include #undef termios #undef winsize #undef termio #define S0(x) (x ? x : "") // start bit: low, 2 stop bits high int rate (int what_rate, int uart) { int r = 0; struct termios2 uartattr2; if (ioctl(uart, TCGETS2, &uartattr2) == -1) { error_at_line(0, errno, __FILE__, __LINE__, "ioctl TCGETS2, fd: %d", uart); r = 1; goto r; } uartattr2.c_cflag &= ~CBAUD; uartattr2.c_cflag |= BOTHER; uartattr2.c_ispeed = what_rate; uartattr2.c_ospeed = what_rate; if (ioctl(uart, TCSETS2, &uartattr2) == -1) { error_at_line(0, errno, __FILE__, __LINE__, "ioctl TCSETS2"); r = 2; goto r; } r: return r; } int main (int argc, char ** argv) { int r = 0; if (argc != 1+1) error_at_line(1, 0, __FILE__, __LINE__, "usage: %s /dev/ttyUSB0", S0(argv[0])); int uart = open(argv[1], O_RDONLY | O_NOCTTY | O_NDELAY | O_CLOEXEC); if (uart == -1) error_at_line(3, errno, __FILE__, __LINE__, "open"); struct termios uartattr; if (tcgetattr(uart, &uartattr) == -1) { error_at_line(0, errno, __FILE__, __LINE__, "tcgetattr"); r = 4; goto r; } uartattr.c_iflag = 0; uartattr.c_oflag = 0; uartattr.c_cflag = CS8 | CSTOPB; uartattr.c_lflag = 0; if (tcflush(uart, TCIOFLUSH) == -1) { error_at_line(0, errno, __FILE__, __LINE__, "tcflush"); r = 5; goto r; } if (tcsetattr(uart, TCSANOW, &uartattr) == -1) { error_at_line(0, errno, __FILE__, __LINE__, "tcsetattr"); r = 6; goto r; } if (tcflush(uart, TCIOFLUSH) == -1) { error_at_line(0, errno, __FILE__, __LINE__, "tcflush"); r = 15; goto r; } switch (rate(250000, uart)) { case 1: r = 20; goto r; break; case 2: r = 21; goto r; break; default: break; } while (1) { struct pollfd pollfd; pollfd.fd = uart; pollfd.events = POLLIN | POLLERR | POLLHUP | POLLNVAL; int poll_return; if ((poll_return = poll(&pollfd, 1, -1)) == -1) { error_at_line(0, errno, __FILE__, __LINE__, "poll"); r = 16; goto r; } if (!poll_return) { error_at_line(0, 0, __FILE__, __LINE__, "poll returned 0"); r = 17; goto r; } if ((pollfd.revents & POLLERR) | (pollfd.revents & POLLHUP) | (pollfd.revents & POLLNVAL)) { error_at_line(0, 0, __FILE__, __LINE__, "ERR | HUP | NVAL"); r = 18; goto r; } char buf[2048]; ssize_t r = read(uart, buf, 2048); if (r == -1) if (errno != EAGAIN) { error_at_line(0, errno, __FILE__, __LINE__, "read"); r = 19; goto r; } fwrite(buf, 1, 2048, stdout); } r: if (close(uart) == -1) error_at_line(22, errno, __FILE__, __LINE__, "close(uart)"); return r; }