/[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 432 - (hide 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 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     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