/[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 432 - (show annotations)
Tue Jul 1 09:31:25 2003 UTC (20 years, 11 months ago) by matthewc
File MIME type: text/plain
File size: 7327 byte(s)
Commit of work in progress on channels (so that other people can hack on
RDPSND), in particular:
* channel layer takes care of virtual channel header
* split X dependent parts out of CLIPRDR, simplified IPC implementation
* initial RDPDR implementation

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

  ViewVC Help
Powered by ViewVC 1.1.26