/[rdesktop]/sourceforge.net/trunk/rdesktop/serial.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /sourceforge.net/trunk/rdesktop/serial.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 545 - (hide annotations)
Mon Nov 3 20:19:01 2003 UTC (20 years, 7 months ago) by stargo
File MIME type: text/plain
File size: 8182 byte(s)
compile when not all baudrates are defined on a system

1 matthewc 432 #include <unistd.h>
2     #include <fcntl.h>
3     #include <termios.h>
4     #include "rdesktop.h"
5    
6     #define FILE_DEVICE_SERIAL_PORT 0x1b
7    
8     #define SERIAL_SET_BAUD_RATE 1
9     #define SERIAL_SET_QUEUE_SIZE 2
10     #define SERIAL_SET_LINE_CONTROL 3
11     #define SERIAL_SET_BREAK_ON 4
12     #define SERIAL_SET_BREAK_OFF 5
13     #define SERIAL_IMMEDIATE_CHAR 6
14     #define SERIAL_SET_TIMEOUTS 7
15     #define SERIAL_GET_TIMEOUTS 8
16     #define SERIAL_SET_DTR 9
17     #define SERIAL_CLR_DTR 10
18     #define SERIAL_RESET_DEVICE 11
19     #define SERIAL_SET_RTS 12
20     #define SERIAL_CLR_RTS 13
21     #define SERIAL_SET_XOFF 14
22     #define SERIAL_SET_XON 15
23     #define SERIAL_GET_WAIT_MASK 16
24     #define SERIAL_SET_WAIT_MASK 17
25     #define SERIAL_WAIT_ON_MASK 18
26     #define SERIAL_PURGE 19
27     #define SERIAL_GET_BAUD_RATE 20
28     #define SERIAL_GET_LINE_CONTROL 21
29     #define SERIAL_GET_CHARS 22
30     #define SERIAL_SET_CHARS 23
31     #define SERIAL_GET_HANDFLOW 24
32     #define SERIAL_SET_HANDFLOW 25
33     #define SERIAL_GET_MODEMSTATUS 26
34     #define SERIAL_GET_COMMSTATUS 27
35     #define SERIAL_XOFF_COUNTER 28
36     #define SERIAL_GET_PROPERTIES 29
37     #define SERIAL_GET_DTRRTS 30
38     #define SERIAL_LSRMST_INSERT 31
39     #define SERIAL_CONFIG_SIZE 32
40     #define SERIAL_GET_COMMCONFIG 33
41     #define SERIAL_SET_COMMCONFIG 34
42     #define SERIAL_GET_STATS 35
43     #define SERIAL_CLEAR_STATS 36
44     #define SERIAL_GET_MODEM_CONTROL 37
45     #define SERIAL_SET_MODEM_CONTROL 38
46     #define SERIAL_SET_FIFO_CONTROL 39
47    
48     #define STOP_BITS_1 0
49     #define STOP_BITS_2 2
50    
51     #define NO_PARITY 0
52     #define ODD_PARITY 1
53     #define EVEN_PARITY 2
54    
55     int serial_fd;
56     struct termios termios;
57    
58     int dtr;
59     uint32 baud_rate;
60     uint32 queue_in_size, queue_out_size;
61     uint32 wait_mask;
62     uint8 stop_bits, parity, word_length;
63    
64     static BOOL
65     get_termios(void)
66     {
67     speed_t speed;
68    
69     if (tcgetattr(serial_fd, &termios) == -1)
70     return False;
71    
72     speed = cfgetispeed(&termios);
73     switch (speed)
74     {
75 stargo 545 #ifdef B75
76 astrand 435 case B75:
77     baud_rate = 75;
78     break;
79 stargo 545 #endif
80     #ifdef B110
81 astrand 435 case B110:
82     baud_rate = 110;
83     break;
84 stargo 545 #endif
85     #ifdef B134
86 astrand 435 case B134:
87     baud_rate = 134;
88     break;
89 stargo 545 #endif
90     #ifdef B150
91 astrand 435 case B150:
92     baud_rate = 150;
93     break;
94 stargo 545 #endif
95     #ifdef B300
96 astrand 435 case B300:
97     baud_rate = 300;
98     break;
99 stargo 545 #endif
100     #ifdef B600
101 astrand 435 case B600:
102     baud_rate = 600;
103     break;
104 stargo 545 #endif
105     #ifdef B1200
106 astrand 435 case B1200:
107     baud_rate = 1200;
108     break;
109 stargo 545 #endif
110     #ifdef B1800
111 astrand 435 case B1800:
112     baud_rate = 1800;
113     break;
114 stargo 545 #endif
115     #ifdef B2400
116 astrand 435 case B2400:
117     baud_rate = 2400;
118     break;
119 stargo 545 #endif
120     #ifdef B4800
121 astrand 435 case B4800:
122     baud_rate = 4800;
123     break;
124 stargo 545 #endif
125     #ifdef B9600
126 astrand 435 case B9600:
127     baud_rate = 9600;
128     break;
129 stargo 545 #endif
130     #ifdef B19200
131 astrand 435 case B19200:
132     baud_rate = 19200;
133     break;
134 stargo 545 #endif
135     #ifdef B38400
136 astrand 435 case B38400:
137     baud_rate = 38400;
138     break;
139 stargo 545 #endif
140     #ifdef B57600
141 astrand 435 case B57600:
142     baud_rate = 57600;
143     break;
144 stargo 545 #endif
145     #ifdef B115200
146 astrand 435 case B115200:
147     baud_rate = 115200;
148     break;
149 stargo 545 #endif
150 astrand 435 default:
151     baud_rate = 0;
152     break;
153 matthewc 432 }
154    
155     speed = cfgetospeed(&termios);
156     dtr = (speed == B0) ? 0 : 1;
157    
158     stop_bits = (termios.c_cflag & CSTOPB) ? STOP_BITS_2 : STOP_BITS_1;
159 astrand 435 parity = (termios.
160     c_cflag & PARENB) ? ((termios.
161     c_cflag & PARODD) ? ODD_PARITY : EVEN_PARITY) : NO_PARITY;
162 matthewc 432 switch (termios.c_cflag & CSIZE)
163     {
164 astrand 435 case CS5:
165     word_length = 5;
166     break;
167     case CS6:
168     word_length = 6;
169     break;
170     case CS7:
171     word_length = 7;
172     break;
173     default:
174     word_length = 8;
175     break;
176 matthewc 432 }
177    
178     return True;
179     }
180    
181     static void
182     set_termios(void)
183     {
184     speed_t speed;
185    
186     switch (baud_rate)
187     {
188 stargo 545 #ifdef B75
189 astrand 435 case 75:
190     speed = B75;
191     break;
192 stargo 545 #endif
193     #ifdef B110
194 astrand 435 case 110:
195     speed = B110;
196     break;
197 stargo 545 #endif
198     #ifdef B134
199 astrand 435 case 134:
200     speed = B134;
201     break;
202 stargo 545 #endif
203     #ifdef B150
204 astrand 435 case 150:
205     speed = B150;
206     break;
207 stargo 545 #endif
208     #ifdef B300
209 astrand 435 case 300:
210     speed = B300;
211     break;
212 stargo 545 #endif
213     #ifdef B600
214 astrand 435 case 600:
215     speed = B600;
216     break;
217 stargo 545 #endif
218     #ifdef B1200
219 astrand 435 case 1200:
220     speed = B1200;
221     break;
222 stargo 545 #endif
223     #ifdef B1800
224 astrand 435 case 1800:
225     speed = B1800;
226     break;
227 stargo 545 #endif
228     #ifdef B2400
229 astrand 435 case 2400:
230     speed = B2400;
231     break;
232 stargo 545 #endif
233     #ifdef B4800
234 astrand 435 case 4800:
235     speed = B4800;
236     break;
237 stargo 545 #endif
238     #ifdef B9600
239 astrand 435 case 9600:
240     speed = B9600;
241     break;
242 stargo 545 #endif
243     #ifdef B19200
244 astrand 435 case 19200:
245     speed = B19200;
246     break;
247 stargo 545 #endif
248     #ifdef B38400
249 astrand 435 case 38400:
250     speed = B38400;
251     break;
252 stargo 545 #endif
253     #ifdef B57600
254 astrand 435 case 57600:
255     speed = B57600;
256     break;
257 stargo 545 #endif
258     #ifdef B115200
259 astrand 435 case 115200:
260     speed = B115200;
261     break;
262 stargo 545 #endif
263 astrand 435 default:
264     speed = B0;
265     break;
266 matthewc 432 }
267    
268     /* on systems with separate ispeed and ospeed, we can remember the speed
269     in ispeed while changing DTR with ospeed */
270     cfsetispeed(&termios, speed);
271     cfsetospeed(&termios, dtr ? speed : 0);
272    
273 astrand 435 termios.c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE);
274 matthewc 432 switch (stop_bits)
275     {
276     case STOP_BITS_2:
277     termios.c_cflag |= CSTOPB;
278     break;
279     }
280     switch (parity)
281     {
282     case EVEN_PARITY:
283     termios.c_cflag |= PARENB;
284     break;
285     case ODD_PARITY:
286 astrand 435 termios.c_cflag |= PARENB | PARODD;
287 matthewc 432 break;
288     }
289     switch (word_length)
290     {
291 astrand 435 case 5:
292     termios.c_cflag |= CS5;
293     break;
294     case 6:
295     termios.c_cflag |= CS6;
296     break;
297     case 7:
298     termios.c_cflag |= CS7;
299     break;
300     default:
301     termios.c_cflag |= CS8;
302     break;
303 matthewc 432 }
304    
305     tcsetattr(serial_fd, TCSANOW, &termios);
306     }
307    
308     static NTSTATUS
309 astrand 435 serial_create(HANDLE * handle)
310 matthewc 432 {
311     /* XXX do we have to handle concurrent open attempts? */
312     serial_fd = open("/dev/ttyS0", O_RDWR);
313     if (serial_fd == -1)
314     return STATUS_ACCESS_DENIED;
315    
316     if (!get_termios())
317     return STATUS_ACCESS_DENIED;
318    
319     *handle = 0;
320     return STATUS_SUCCESS;
321     }
322    
323     static NTSTATUS
324     serial_close(HANDLE handle)
325     {
326     close(serial_fd);
327     return STATUS_SUCCESS;
328     }
329    
330     static NTSTATUS
331 astrand 435 serial_read(HANDLE handle, uint8 * data, uint32 length, uint32 * result)
332 matthewc 432 {
333     *result = read(serial_fd, data, length);
334     return STATUS_SUCCESS;
335     }
336    
337     static NTSTATUS
338 astrand 435 serial_write(HANDLE handle, uint8 * data, uint32 length, uint32 * result)
339 matthewc 432 {
340     *result = write(serial_fd, data, length);
341     return STATUS_SUCCESS;
342     }
343    
344     static NTSTATUS
345     serial_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out)
346     {
347     uint32 result;
348     uint8 immediate;
349    
350     if ((request >> 16) != FILE_DEVICE_SERIAL_PORT)
351     return STATUS_INVALID_PARAMETER;
352    
353     /* extract operation */
354     request >>= 2;
355     request &= 0xfff;
356    
357     printf("SERIAL IOCTL %d\n", request);
358    
359     switch (request)
360     {
361     case SERIAL_SET_BAUD_RATE:
362     in_uint32_le(in, baud_rate);
363     set_termios();
364     break;
365     case SERIAL_GET_BAUD_RATE:
366     out_uint32_le(out, baud_rate);
367     break;
368     case SERIAL_SET_QUEUE_SIZE:
369     in_uint32_le(in, queue_in_size);
370     in_uint32_le(in, queue_out_size);
371     break;
372     case SERIAL_SET_LINE_CONTROL:
373     in_uint8(in, stop_bits);
374     in_uint8(in, parity);
375     in_uint8(in, word_length);
376     set_termios();
377     break;
378     case SERIAL_GET_LINE_CONTROL:
379     out_uint8(out, stop_bits);
380     out_uint8(out, parity);
381     out_uint8(out, word_length);
382     break;
383     case SERIAL_IMMEDIATE_CHAR:
384     in_uint8(in, immediate);
385     serial_write(handle, &immediate, 1, &result);
386     break;
387     case SERIAL_CONFIG_SIZE:
388     out_uint32_le(out, 0);
389     break;
390     case SERIAL_GET_CHARS:
391     out_uint8s(out, 6);
392     break;
393     case SERIAL_SET_CHARS:
394     in_uint8s(in, 6);
395     break;
396     case SERIAL_GET_HANDFLOW:
397     out_uint32_le(out, 0);
398 astrand 435 out_uint32_le(out, 3); /* Xon/Xoff */
399 matthewc 432 out_uint32_le(out, 0);
400     out_uint32_le(out, 0);
401     break;
402     case SERIAL_SET_HANDFLOW:
403     in_uint8s(in, 16);
404     break;
405     case SERIAL_SET_TIMEOUTS:
406     in_uint8s(in, 20);
407     break;
408     case SERIAL_GET_TIMEOUTS:
409     out_uint8s(out, 20);
410     break;
411     case SERIAL_GET_WAIT_MASK:
412     out_uint32(out, wait_mask);
413     break;
414     case SERIAL_SET_WAIT_MASK:
415     in_uint32(in, wait_mask);
416     break;
417     case SERIAL_SET_DTR:
418     dtr = 1;
419     set_termios();
420     break;
421     case SERIAL_CLR_DTR:
422     dtr = 0;
423     set_termios();
424     break;
425     #if 0
426     case SERIAL_WAIT_ON_MASK:
427     /* XXX implement me */
428     break;
429     case SERIAL_SET_BREAK_ON:
430     tcsendbreak(serial_fd, 0);
431     break;
432     case SERIAL_PURGE:
433     in_uint32(purge_mask);
434     /* tcflush */
435     break;
436     case SERIAL_RESET_DEVICE:
437     case SERIAL_SET_BREAK_OFF:
438     case SERIAL_SET_RTS:
439     case SERIAL_CLR_RTS:
440     case SERIAL_SET_XOFF:
441     case SERIAL_SET_XON:
442     /* ignore */
443     break;
444     #endif
445    
446     default:
447     unimpl("SERIAL IOCTL %d\n", request);
448     return STATUS_INVALID_PARAMETER;
449     }
450    
451     return STATUS_SUCCESS;
452     }
453    
454 astrand 435 DEVICE_FNS serial_fns = {
455 matthewc 432 serial_create,
456     serial_close,
457     serial_read,
458     serial_write,
459     serial_device_control
460     };

  ViewVC Help
Powered by ViewVC 1.1.26