/* * swuart-chat/chat.c - Simple two-way chat using swuart * * Written 2012 by Werner Almesberger * Copyright 2012 Werner Almesberger * * 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. */ #include #include #include #include #include #include #include #include #include #include #define DEFAULT_RX UBB_DAT0 #define DEFAULT_TX UBB_DAT1 #define DEFAULT_BPS 38400 /* ----- TTY raw mode ------------------------------------------------------ */ static struct termios old_term; static void raw(void) { struct termios term; if (tcgetattr(0, &old_term) < 0) { perror("tcgetattr"); exit(1); } term = old_term; cfmakeraw(&term); if (tcsetattr(0, TCSAFLUSH, &term) < 0) { perror("tcsetattr"); exit(1); } if (fcntl(0, F_SETFL, O_NONBLOCK) < 0) { perror("fcntl"); exit(1); } } static void restore_term(void) { if (tcsetattr(0, TCSAFLUSH, &old_term) < 0) perror("tcsetattr"); } static void at_exit(void) { restore_term(); swuart_close(); ubb_close(0); } static uint32_t translate(const char *s) { if (!strcasecmp(s, "DAT0")) return UBB_DAT0; if (!strcasecmp(s, "DAT1")) return UBB_DAT1; if (!strcasecmp(s, "DAT2")) return UBB_DAT2; if (!strcasecmp(s, "DAT3")) return UBB_DAT3; if (!strcasecmp(s, "CMD")) return UBB_CMD; if (!strcasecmp(s, "CLK")) return UBB_CLK; if (!strcasecmp(s, "NONE")) return 0; fprintf(stderr, "unknown pin \"%s\"\n", s); exit(1); } static void usage(const char *name) { fprintf(stderr, "usage: %s [-r rx_pin] [-t tx_pin] [bps]\n", name); exit(1); } int main(int argc, char **argv) { uint32_t rx = DEFAULT_RX; uint32_t tx = DEFAULT_TX; int bps = DEFAULT_BPS; uint8_t local[10], remote[100]; int got, i; int c; while ((c = getopt(argc, argv, "r:t:")) != EOF) switch (c) { case 'r': rx = translate(optarg); break; case 't': tx = translate(optarg); break; default: usage(*argv); } switch (argc-optind) { case 0: break; case 1: bps = atoi(argv[optind]); if (!bps) usage(*argv); break; default: usage(*argv); } if (ubb_open(0) < 0) { perror("ubb_open"); exit(1); } atexit(at_exit); raw(); if (swuart_open(tx, rx, bps) < 0) { perror("swuart_open"); exit(1); } while (1) { got = read(0, local, sizeof(local)); if (got < 0 && errno == EAGAIN) got = 0; if (got < 0) { perror("read"); exit(1); } if (memchr(local, 3, got)) break; got = swuart_trx(local, got, remote, sizeof(remote), 1000, 100); for (i = 0; i != got; i++) if (remote[i] >= ' ' && remote[i] <= '~') printf("%c", remote[i]); else if (remote[i] == 13) printf("\r\n"); else if (remote[i] == 8 || remote[i] == 127) printf("\b \b"); else printf("\\%02o", remote[i]); fflush(stdout); } printf("\r\n"); return 0; }