/[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 435 - (show annotations)
Wed Jul 9 09:18:20 2003 UTC (20 years, 9 months ago) by astrand
File MIME type: text/plain
File size: 7586 byte(s)
Indent fixes

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 case B75:
76 baud_rate = 75;
77 break;
78 case B110:
79 baud_rate = 110;
80 break;
81 case B134:
82 baud_rate = 134;
83 break;
84 case B150:
85 baud_rate = 150;
86 break;
87 case B300:
88 baud_rate = 300;
89 break;
90 case B600:
91 baud_rate = 600;
92 break;
93 case B1200:
94 baud_rate = 1200;
95 break;
96 case B1800:
97 baud_rate = 1800;
98 break;
99 case B2400:
100 baud_rate = 2400;
101 break;
102 case B4800:
103 baud_rate = 4800;
104 break;
105 case B9600:
106 baud_rate = 9600;
107 break;
108 case B19200:
109 baud_rate = 19200;
110 break;
111 case B38400:
112 baud_rate = 38400;
113 break;
114 case B57600:
115 baud_rate = 57600;
116 break;
117 case B115200:
118 baud_rate = 115200;
119 break;
120 default:
121 baud_rate = 0;
122 break;
123 }
124
125 speed = cfgetospeed(&termios);
126 dtr = (speed == B0) ? 0 : 1;
127
128 stop_bits = (termios.c_cflag & CSTOPB) ? STOP_BITS_2 : STOP_BITS_1;
129 parity = (termios.
130 c_cflag & PARENB) ? ((termios.
131 c_cflag & PARODD) ? ODD_PARITY : EVEN_PARITY) : NO_PARITY;
132 switch (termios.c_cflag & CSIZE)
133 {
134 case CS5:
135 word_length = 5;
136 break;
137 case CS6:
138 word_length = 6;
139 break;
140 case CS7:
141 word_length = 7;
142 break;
143 default:
144 word_length = 8;
145 break;
146 }
147
148 return True;
149 }
150
151 static void
152 set_termios(void)
153 {
154 speed_t speed;
155
156 switch (baud_rate)
157 {
158 case 75:
159 speed = B75;
160 break;
161 case 110:
162 speed = B110;
163 break;
164 case 134:
165 speed = B134;
166 break;
167 case 150:
168 speed = B150;
169 break;
170 case 300:
171 speed = B300;
172 break;
173 case 600:
174 speed = B600;
175 break;
176 case 1200:
177 speed = B1200;
178 break;
179 case 1800:
180 speed = B1800;
181 break;
182 case 2400:
183 speed = B2400;
184 break;
185 case 4800:
186 speed = B4800;
187 break;
188 case 9600:
189 speed = B9600;
190 break;
191 case 19200:
192 speed = B19200;
193 break;
194 case 38400:
195 speed = B38400;
196 break;
197 case 57600:
198 speed = B57600;
199 break;
200 case 115200:
201 speed = B115200;
202 break;
203 default:
204 speed = B0;
205 break;
206 }
207
208 /* on systems with separate ispeed and ospeed, we can remember the speed
209 in ispeed while changing DTR with ospeed */
210 cfsetispeed(&termios, speed);
211 cfsetospeed(&termios, dtr ? speed : 0);
212
213 termios.c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE);
214 switch (stop_bits)
215 {
216 case STOP_BITS_2:
217 termios.c_cflag |= CSTOPB;
218 break;
219 }
220 switch (parity)
221 {
222 case EVEN_PARITY:
223 termios.c_cflag |= PARENB;
224 break;
225 case ODD_PARITY:
226 termios.c_cflag |= PARENB | PARODD;
227 break;
228 }
229 switch (word_length)
230 {
231 case 5:
232 termios.c_cflag |= CS5;
233 break;
234 case 6:
235 termios.c_cflag |= CS6;
236 break;
237 case 7:
238 termios.c_cflag |= CS7;
239 break;
240 default:
241 termios.c_cflag |= CS8;
242 break;
243 }
244
245 tcsetattr(serial_fd, TCSANOW, &termios);
246 }
247
248 static NTSTATUS
249 serial_create(HANDLE * handle)
250 {
251 /* XXX do we have to handle concurrent open attempts? */
252 serial_fd = open("/dev/ttyS0", O_RDWR);
253 if (serial_fd == -1)
254 return STATUS_ACCESS_DENIED;
255
256 if (!get_termios())
257 return STATUS_ACCESS_DENIED;
258
259 *handle = 0;
260 return STATUS_SUCCESS;
261 }
262
263 static NTSTATUS
264 serial_close(HANDLE handle)
265 {
266 close(serial_fd);
267 return STATUS_SUCCESS;
268 }
269
270 static NTSTATUS
271 serial_read(HANDLE handle, uint8 * data, uint32 length, uint32 * result)
272 {
273 *result = read(serial_fd, data, length);
274 return STATUS_SUCCESS;
275 }
276
277 static NTSTATUS
278 serial_write(HANDLE handle, uint8 * data, uint32 length, uint32 * result)
279 {
280 *result = write(serial_fd, data, length);
281 return STATUS_SUCCESS;
282 }
283
284 static NTSTATUS
285 serial_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out)
286 {
287 uint32 result;
288 uint8 immediate;
289
290 if ((request >> 16) != FILE_DEVICE_SERIAL_PORT)
291 return STATUS_INVALID_PARAMETER;
292
293 /* extract operation */
294 request >>= 2;
295 request &= 0xfff;
296
297 printf("SERIAL IOCTL %d\n", request);
298
299 switch (request)
300 {
301 case SERIAL_SET_BAUD_RATE:
302 in_uint32_le(in, baud_rate);
303 set_termios();
304 break;
305 case SERIAL_GET_BAUD_RATE:
306 out_uint32_le(out, baud_rate);
307 break;
308 case SERIAL_SET_QUEUE_SIZE:
309 in_uint32_le(in, queue_in_size);
310 in_uint32_le(in, queue_out_size);
311 break;
312 case SERIAL_SET_LINE_CONTROL:
313 in_uint8(in, stop_bits);
314 in_uint8(in, parity);
315 in_uint8(in, word_length);
316 set_termios();
317 break;
318 case SERIAL_GET_LINE_CONTROL:
319 out_uint8(out, stop_bits);
320 out_uint8(out, parity);
321 out_uint8(out, word_length);
322 break;
323 case SERIAL_IMMEDIATE_CHAR:
324 in_uint8(in, immediate);
325 serial_write(handle, &immediate, 1, &result);
326 break;
327 case SERIAL_CONFIG_SIZE:
328 out_uint32_le(out, 0);
329 break;
330 case SERIAL_GET_CHARS:
331 out_uint8s(out, 6);
332 break;
333 case SERIAL_SET_CHARS:
334 in_uint8s(in, 6);
335 break;
336 case SERIAL_GET_HANDFLOW:
337 out_uint32_le(out, 0);
338 out_uint32_le(out, 3); /* Xon/Xoff */
339 out_uint32_le(out, 0);
340 out_uint32_le(out, 0);
341 break;
342 case SERIAL_SET_HANDFLOW:
343 in_uint8s(in, 16);
344 break;
345 case SERIAL_SET_TIMEOUTS:
346 in_uint8s(in, 20);
347 break;
348 case SERIAL_GET_TIMEOUTS:
349 out_uint8s(out, 20);
350 break;
351 case SERIAL_GET_WAIT_MASK:
352 out_uint32(out, wait_mask);
353 break;
354 case SERIAL_SET_WAIT_MASK:
355 in_uint32(in, wait_mask);
356 break;
357 case SERIAL_SET_DTR:
358 dtr = 1;
359 set_termios();
360 break;
361 case SERIAL_CLR_DTR:
362 dtr = 0;
363 set_termios();
364 break;
365 #if 0
366 case SERIAL_WAIT_ON_MASK:
367 /* XXX implement me */
368 break;
369 case SERIAL_SET_BREAK_ON:
370 tcsendbreak(serial_fd, 0);
371 break;
372 case SERIAL_PURGE:
373 in_uint32(purge_mask);
374 /* tcflush */
375 break;
376 case SERIAL_RESET_DEVICE:
377 case SERIAL_SET_BREAK_OFF:
378 case SERIAL_SET_RTS:
379 case SERIAL_CLR_RTS:
380 case SERIAL_SET_XOFF:
381 case SERIAL_SET_XON:
382 /* ignore */
383 break;
384 #endif
385
386 default:
387 unimpl("SERIAL IOCTL %d\n", request);
388 return STATUS_INVALID_PARAMETER;
389 }
390
391 return STATUS_SUCCESS;
392 }
393
394 DEVICE_FNS serial_fns = {
395 serial_create,
396 serial_close,
397 serial_read,
398 serial_write,
399 serial_device_control
400 };

  ViewVC Help
Powered by ViewVC 1.1.26