Root/swuart-chat/chat.c

1
2/*
3 * swuart-chat/chat.c - Simple two-way chat using swuart
4 *
5 * Written 2012 by Werner Almesberger
6 * Copyright 2012 Werner Almesberger
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14
15#include <stdlib.h>
16#include <stdio.h>
17#include <unistd.h>
18#include <string.h>
19#include <strings.h>
20#include <termios.h>
21#include <fcntl.h>
22#include <errno.h>
23
24#include <ubb/ubb.h>
25#include <ubb/swuart.h>
26
27
28#define DEFAULT_RX UBB_DAT0
29#define DEFAULT_TX UBB_DAT1
30
31#define DEFAULT_BPS 38400
32
33
34/* ----- TTY raw mode ------------------------------------------------------ */
35
36
37static struct termios old_term;
38
39static void raw(void)
40{
41    struct termios term;
42
43    if (tcgetattr(0, &old_term) < 0) {
44        perror("tcgetattr");
45        exit(1);
46    }
47    term = old_term;
48    cfmakeraw(&term);
49    if (tcsetattr(0, TCSAFLUSH, &term) < 0) {
50        perror("tcsetattr");
51        exit(1);
52    }
53    if (fcntl(0, F_SETFL, O_NONBLOCK) < 0) {
54        perror("fcntl");
55        exit(1);
56    }
57}
58
59
60static void restore_term(void)
61{
62    if (tcsetattr(0, TCSAFLUSH, &old_term) < 0)
63        perror("tcsetattr");
64}
65
66
67static void at_exit(void)
68{
69    restore_term();
70    swuart_close();
71    ubb_close(0);
72}
73
74
75static uint32_t translate(const char *s)
76{
77    if (!strcasecmp(s, "DAT0"))
78        return UBB_DAT0;
79    if (!strcasecmp(s, "DAT1"))
80        return UBB_DAT1;
81    if (!strcasecmp(s, "DAT2"))
82        return UBB_DAT2;
83    if (!strcasecmp(s, "DAT3"))
84        return UBB_DAT3;
85    if (!strcasecmp(s, "CMD"))
86        return UBB_CMD;
87    if (!strcasecmp(s, "CLK"))
88        return UBB_CLK;
89    if (!strcasecmp(s, "NONE"))
90        return 0;
91    fprintf(stderr, "unknown pin \"%s\"\n", s);
92    exit(1);
93}
94
95
96static void usage(const char *name)
97{
98    fprintf(stderr, "usage: %s [-r rx_pin] [-t tx_pin] [bps]\n", name);
99    exit(1);
100}
101
102
103int main(int argc, char **argv)
104{
105    uint32_t rx = DEFAULT_RX;
106    uint32_t tx = DEFAULT_TX;
107    int bps = DEFAULT_BPS;
108    uint8_t local[10], remote[100];
109    int got, i;
110    int c;
111
112    while ((c = getopt(argc, argv, "r:t:")) != EOF)
113        switch (c) {
114        case 'r':
115            rx = translate(optarg);
116            break;
117        case 't':
118            tx = translate(optarg);
119            break;
120        default:
121            usage(*argv);
122        }
123
124    switch (argc-optind) {
125    case 0:
126        break;
127    case 1:
128        bps = atoi(argv[optind]);
129        if (!bps)
130            usage(*argv);
131        break;
132    default:
133        usage(*argv);
134    }
135
136    if (ubb_open(0) < 0) {
137        perror("ubb_open");
138        exit(1);
139    }
140    atexit(at_exit);
141    raw();
142    if (swuart_open(tx, rx, bps) < 0) {
143        perror("swuart_open");
144        exit(1);
145    }
146
147    while (1) {
148        got = read(0, local, sizeof(local));
149        if (got < 0 && errno == EAGAIN)
150            got = 0;
151        if (got < 0) {
152            perror("read");
153            exit(1);
154        }
155        if (memchr(local, 3, got))
156            break;
157        got = swuart_trx(local, got, remote, sizeof(remote),
158            1000, 100);
159        for (i = 0; i != got; i++)
160            if (remote[i] >= ' ' && remote[i] <= '~')
161                printf("%c", remote[i]);
162            else if (remote[i] == 13)
163                printf("\r\n");
164            else if (remote[i] == 8 || remote[i] == 127)
165                printf("\b \b");
166            else
167                printf("\\%02o", remote[i]);
168        fflush(stdout);
169    }
170    printf("\r\n");
171    return 0;
172}
173

Archive Download this file

Branches:
master



interactive