chiark / gitweb /
*** empty log message ***
[sympathy.git] / src / tty.c
1 /*
2  * tty.c:
3  *
4  * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
5  * All rights reserved.
6  *
7  */
8
9 static char rcsid[] = "$Id$";
10
11 /*
12  * $Log$
13  * Revision 1.12  2008/02/22 23:39:27  james
14  * *** empty log message ***
15  *
16  * Revision 1.11  2008/02/20 18:31:53  james
17  * *** empty log message ***
18  *
19  * Revision 1.10  2008/02/15 23:52:12  james
20  * *** empty log message ***
21  *
22  * Revision 1.9  2008/02/15 03:32:07  james
23  * *** empty log message ***
24  *
25  * Revision 1.8  2008/02/14 10:36:18  james
26  * *** empty log message ***
27  *
28  * Revision 1.7  2008/02/14 10:34:30  james
29  * *** empty log message ***
30  *
31  * Revision 1.6  2008/02/13 16:59:34  james
32  * *** empty log message ***
33  *
34  * Revision 1.5  2008/02/13 16:57:29  james
35  * *** empty log message ***
36  *
37  * Revision 1.4  2008/02/12 22:36:46  james
38  * *** empty log message ***
39  *
40  * Revision 1.3  2008/02/09 15:47:28  james
41  * *** empty log message ***
42  *
43  */
44
45
46 #include "project.h"
47
48 static int
49 speed_t_to_baud (speed_t s)
50 {
51   switch (s)
52     {
53 #ifdef B0
54     case B0:
55       return 0;
56 #endif
57 #ifdef B50
58     case B50:
59       return 50;
60 #endif
61 #ifdef B75
62     case B75:
63       return 75;
64 #endif
65 #ifdef B110
66     case B110:
67       return 110;
68 #endif
69 #ifdef B134
70     case B134:
71       return 134;
72 #endif
73 #ifdef B150
74     case B150:
75       return 150;
76 #endif
77 #ifdef B200
78     case B200:
79       return 200;
80 #endif
81 #ifdef B300
82     case B300:
83       return 300;
84 #endif
85 #ifdef B600
86     case B600:
87       return 600;
88 #endif
89 #ifdef B1200
90     case B1200:
91       return 1200;
92 #endif
93 #ifdef B1800
94     case B1800:
95       return 1800;
96 #endif
97 #ifdef B2400
98     case B2400:
99       return 2400;
100 #endif
101 #ifdef B4800
102     case B4800:
103       return 4800;
104 #endif
105 #ifdef B9600
106     case B9600:
107       return 9600;
108 #endif
109 #ifdef B19200
110     case B19200:
111       return 19200;
112 #endif
113 #ifdef B38400
114     case B38400:
115       return 38400;
116 #endif
117 #ifdef B57600
118     case B57600:
119       return 57600;
120 #endif
121 #ifdef B115200
122     case B115200:
123       return 115200;
124 #endif
125 #ifdef B230400
126     case B230400:
127       return 230400;
128 #endif
129     }
130
131   return -1;
132 }
133
134 static speed_t
135 baud_to_speed_t (int baud)
136 {
137   switch (baud)
138     {
139 #ifdef B0
140     case 0:
141       return B0;
142 #endif
143 #ifdef B50
144     case 50:
145       return B50;
146 #endif
147 #ifdef B75
148     case 75:
149       return B75;
150 #endif
151 #ifdef B110
152     case 110:
153       return B110;
154 #endif
155 #ifdef B134
156     case 134:
157       return B134;
158 #endif
159 #ifdef B150
160     case 150:
161       return B150;
162 #endif
163 #ifdef B200
164     case 200:
165       return B200;
166 #endif
167 #ifdef B300
168     case 300:
169       return B300;
170 #endif
171 #ifdef B600
172     case 600:
173       return B600;
174 #endif
175 #ifdef B1200
176     case 1200:
177       return B1200;
178 #endif
179 #ifdef B1800
180     case 1800:
181       return B1800;
182 #endif
183 #ifdef B2400
184     case 2400:
185       return B2400;
186 #endif
187 #ifdef B4800
188     case 4800:
189       return B4800;
190 #endif
191 #ifdef B9600
192     case 9600:
193       return B9600;
194 #endif
195 #ifdef B19200
196     case 19200:
197       return B19200;
198 #endif
199 #ifdef B38400
200     case 38400:
201       return B38400;
202 #endif
203 #ifdef B57600
204     case 57600:
205       return B57600;
206 #endif
207 #ifdef B115200
208     case 115200:
209       return B115200;
210 #endif
211 #ifdef B230400
212     case 230400:
213       return B230400;
214 #endif
215     }
216   return -1;
217 }
218
219 void
220 tty_pre_select (TTY * t, fd_set * rfds, fd_set * wfds)
221 {
222   int line;
223   struct timeval now, dif;
224
225   if (t->hanging_up)
226     {
227
228       gettimeofday (&now, NULL);
229       timersub (&now, &t->hangup_clock, &dif);
230       if (dif.tv_sec)
231         {
232           line = TIOCM_DTR;
233           ioctl (t->rfd, TIOCMBIS, &line);
234           t->hanging_up = 0;
235         }
236     }
237
238
239   FD_SET (t->rfd, rfds);
240 }
241
242 int
243 tty_get_status (TTY * t, TTY_Status * s)
244 {
245
246   s->lines = 0;
247   ioctl (t->rfd, TIOCMGET, &s->lines);
248
249   if (tcgetattr (t->rfd, &s->termios))
250     return -1;
251
252   s->baud = speed_t_to_baud (cfgetispeed (&s->termios));
253   s->blocked = t->blocked;
254
255   return 0;
256 }
257
258 void
259 tty_set_baud (TTY * t, int rate)
260 {
261   struct termios tios = { 0 };
262
263   speed_t s = baud_to_speed_t (rate);
264
265   if (s == (speed_t) - 1)
266     return;
267
268   if (tcgetattr (t->rfd, &tios))
269     return;
270
271   cfsetispeed (&tios, s);
272   cfsetospeed (&tios, s);
273
274   tcsetattr (t->rfd, TCSANOW, &tios);
275 }
276
277 void
278 tty_send_break (TTY * t)
279 {
280   tcsendbreak (t->wfd, 0);
281 }
282
283 void
284 tty_set_flow (TTY * t, int flow)
285 {
286   struct termios tios = { 0 };
287
288   if (tcgetattr (t->rfd, &tios))
289     return;
290
291   if (flow)
292     tios.c_cflag |= CRTSCTS;
293   else
294     tios.c_cflag &= ~CRTSCTS;
295
296   tcsetattr (t->rfd, TCSANOW, &tios);
297
298 }
299
300 void
301 tty_hangup (TTY * t)
302 {
303   int line;
304
305   line = TIOCM_DTR;
306   ioctl (t->rfd, TIOCMBIC, &line);
307
308   t->hanging_up = 1;
309   gettimeofday (&t->hangup_clock, NULL);
310
311 }
312
313
314 #if 0
315 typedef struct
316 {
317   int in_dle;
318   int in_errmark;
319
320   int bit_edge_frequency[8];
321   int errs;
322 }
323 #endif
324
325 #define DLE 0377
326
327 #define bit(p,b,z,o) \
328         do { \
329           if ((b && z)) { \
330             p->bitfreq[z]++; \
331             z = 0; \
332           } \
333           \
334           if ((!b && o)) \
335           { \
336             p->bitfreq[z]++; \
337             o = 0; \
338           } \
339           \
340           if (b) \
341             o++; \
342           else \
343             z++; \
344           } \
345         while (0)
346
347 void
348 tty_stats (TTY_Parser * p, int err, int ch)
349 {
350   int c = 128;
351   int zc = 0, oc = 0;
352
353   if (err)
354     p->biterrs++;
355
356   bit (p, 0, zc, oc);
357
358   while (c)
359     {
360       bit (p,ch & c,zc,oc);
361       c >>= 1;
362     }
363   bit (p, 1, zc, oc);
364 }
365
366 void
367 tty_parse (Context * c, uint8_t * buf, int len)
368 {
369   TTY_Parser *p = &c->t->parser;
370
371   while (len--)
372     {
373
374       if (p->in_dle)
375         {
376           p->in_dle = 0;
377           switch (*buf)
378             {
379             case DLE:
380               tty_bit_analyse (p, 0, *buf);
381               utf8_parse (c, *buf);
382               break;
383             case 0:
384               p->in_errmark = 1;
385               break;
386             default:
387               log_f (c->l, "%s:%d DLE parsing error: \\377 \\%03o", *buf);
388             }
389         }
390       else if (p->in_errmark)
391         {
392           p->in_errmark = 0;
393           log_f (c->l, "%s:%d tty reports error: \\377 \\000 \\%03o", *buf);
394           utf8_parse (c, *buf);
395           tty_bit_analyse (p, 1, *buf);
396           utf8_parse (c, SYM_CHAR_RESET);
397         }
398       else
399         {
400           tty_bit_analyse (p, 0, *buf);
401           utf8_parse (c, *buf);
402         }
403       buf++;
404     }
405 }