/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 545 - (show 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 #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 #ifdef B75
76 case B75:
77 baud_rate = 75;
78 break;
79 #endif
80 #ifdef B110
81 case B110:
82 baud_rate = 110;
83 break;
84 #endif
85 #ifdef B134
86 case B134:
87 baud_rate = 134;
88 break;
89 #endif
90 #ifdef B150
91 case B150:
92 baud_rate = 150;
93 break;
94 #endif
95 #ifdef B300
96 case B300:
97 baud_rate = 300;
98 break;
99 #endif
100 #ifdef B600
101 case B600:
102 baud_rate = 600;
103 break;
104 #endif
105 #ifdef B1200
106 case B1200:
107 baud_rate = 1200;
108 break;
109 #endif
110 #ifdef B1800
111 case B1800:
112 baud_rate = 1800;
113 break;
114 #endif
115 #ifdef B2400
116 case B2400:
117 baud_rate = 2400;
118 break;
119 #endif
120 #ifdef B4800
121 case B4800:
122 baud_rate = 4800;
123 break;
124 #endif
125 #ifdef B9600
126 case B9600:
127 baud_rate = 9600;
128 break;
129 #endif
130 #ifdef B19200
131 case B19200:
132 baud_rate = 19200;
133 break;
134 #endif
135 #ifdef B38400
136 case B38400:
137 baud_rate = 38400;
138 break;
139 #endif
140 #ifdef B57600
141 case B57600:
142 baud_rate = 57600;
143 break;
144 #endif
145 #ifdef B115200
146 case B115200:
147 baud_rate = 115200;
148 break;
149 #endif
150 default:
151 baud_rate = 0;
152 break;
153 }
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 parity = (termios.
160 c_cflag & PARENB) ? ((termios.
161 c_cflag & PARODD) ? ODD_PARITY : EVEN_PARITY) : NO_PARITY;
162 switch (termios.c_cflag & CSIZE)
163 {
164 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 }
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 #ifdef B75
189 case 75:
190 speed = B75;
191 break;
192 #endif
193 #ifdef B110
194 case 110:
195 speed = B110;
196 break;
197 #endif
198 #ifdef B134
199 case 134:
200 speed = B134;
201 break;
202 #endif
203 #ifdef B150
204 case 150:
205 speed = B150;
206 break;
207 #endif
208 #ifdef B300
209 case 300:
210 speed = B300;
211 break;
212 #endif
213 #ifdef B600
214 case 600:
215 speed = B600;
216 break;
217 #endif
218 #ifdef B1200
219 case 1200:
220 speed = B1200;
221 break;
222 #endif
223 #ifdef B1800
224 case 1800:
225 speed = B1800;
226 break;
227 #endif
228 #ifdef B2400
229 case 2400:
230 speed = B2400;
231 break;
232 #endif
233 #ifdef B4800
234 case 4800:
235 speed = B4800;
236 break;
237 #endif
238 #ifdef B9600
239 case 9600:
240 speed = B9600;
241 break;
242 #endif
243 #ifdef B19200
244 case 19200:
245 speed = B19200;
246 break;
247 #endif
248 #ifdef B38400
249 case 38400:
250 speed = B38400;
251 break;
252 #endif
253 #ifdef B57600
254 case 57600:
255 speed = B57600;
256 break;
257 #endif
258 #ifdef B115200
259 case 115200:
260 speed = B115200;
261 break;
262 #endif
263 default:
264 speed = B0;
265 break;
266 }
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 termios.c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE);
274 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 termios.c_cflag |= PARENB | PARODD;
287 break;
288 }
289 switch (word_length)
290 {
291 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 }
304
305 tcsetattr(serial_fd, TCSANOW, &termios);
306 }
307
308 static NTSTATUS
309 serial_create(HANDLE * handle)
310 {
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 serial_read(HANDLE handle, uint8 * data, uint32 length, uint32 * result)
332 {
333 *result = read(serial_fd, data, length);
334 return STATUS_SUCCESS;
335 }
336
337 static NTSTATUS
338 serial_write(HANDLE handle, uint8 * data, uint32 length, uint32 * result)
339 {
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 out_uint32_le(out, 3); /* Xon/Xoff */
399 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 DEVICE_FNS serial_fns = {
455 serial_create,
456 serial_close,
457 serial_read,
458 serial_write,
459 serial_device_control
460 };

  ViewVC Help
Powered by ViewVC 1.1.26