#include #include #include #include #include #include #include #include volatile int quit; static void set_quit(int s) { quit = 1; } int main(int argc, const char *argv[]) { int d; int bytes; int nfds; char buf[256]; int i; fd_set rfds; char gpio[2], current[4], tension[4]; char *endp; int currenti, tensioni; int val; enum { INIT, GPIO, CURRENT, TENSION, MARK } state; struct termios t, ot; state = INIT; currenti = tensioni = 0; if (argc != 2) { errx(1, "usage: %s ", argv[0]); } d = open(argv[1], O_RDWR | O_NOCTTY | O_NONBLOCK, 0); if (d < 0) { err(1, "open %s", argv[1]); } fprintf(stderr, "o\n"); if (tcgetattr(d, &ot) < 0) { err(1, "tcgetattr"); } fprintf(stderr, "tg\n"); quit = 0; if (signal(SIGINT, set_quit) == SIG_ERR) { err(1, "signal(SIGINT)"); } if (signal(SIGQUIT, set_quit) == SIG_ERR) { err(1, "signal(SIGQUIT)"); } if (signal(SIGPIPE, set_quit) == SIG_ERR) { err(1, "signal(SIGPIPE)"); } if (signal(SIGTERM, set_quit) == SIG_ERR) { err(1, "signal(SIGTERM)"); } t = ot; cfmakeraw(&t); t.c_cflag |= CLOCAL; t.c_cflag &= ~CRTSCTS; cfsetspeed(&t, B921600); if (tcsetattr(d, TCSANOW | TCSAFLUSH, &t) < 0) { err(1, "tcsetattr"); } fprintf(stderr, "tty ready\n"); FD_ZERO(&rfds); while (quit == 0) { FD_SET(d, &rfds); nfds = select(d+1, &rfds, NULL, NULL, NULL); if (nfds > 0 && FD_ISSET(d, &rfds)) { bytes = read(d, buf, sizeof(buf)); if (bytes < 0 && errno != EAGAIN) { warn("read"); } for (i = 0; i < bytes; i++) { switch(state) { case INIT: /* look for an X mark */ if (buf[i] == 'X') state = GPIO; break; case GPIO: gpio[0] = buf[i]; gpio[1] = '\0'; val = strtol(gpio, &endp, 16); if (*endp != '\0') { fprintf(stderr, "gpio error: %c\n", *endp); state = INIT; } else { state = CURRENT; currenti = 0; printf("%2d ", val); } break; case CURRENT: current[currenti] = buf[i]; currenti++; if (currenti < 3) break; current[currenti] = '\0'; val = strtol(current, &endp, 16); if (*endp != '\0') { fprintf(stderr, "current error: %c\n", *endp); state = INIT; } else { state = TENSION; tensioni = 0; printf("%4d ", val); } break; case TENSION: tension[tensioni] = buf[i]; tensioni++; if (tensioni < 3) break; tension[tensioni] = '\0'; val = strtol(tension, &endp, 16); if (*endp != '\0') { fprintf(stderr, "tension error: %c\n", *endp); state = INIT; } else { state = MARK; printf("%4d\n", val); } break; case MARK: if (buf[i] != 'X') { fprintf(stderr, "mark error: %c\n", buf[i]); state = INIT; } else { state = GPIO; } break; } } } else if (nfds < 0) { warn("select"); } } if (tcsetattr(d, TCSANOW, &ot) < 0) { err(1, "restore tcsetattr"); } exit(0); }