/[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 963 - (hide annotations)
Wed Aug 3 10:56:16 2005 UTC (18 years, 10 months ago) by astrand
File MIME type: text/plain
File size: 27181 byte(s)
Added missing c-basic-offset:s and license headers

1 astrand 963 /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.
3    
4     Copyright (C) Matthew Chapman 1999-2005
5    
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20 matthewc 432 #include <unistd.h>
21     #include <fcntl.h>
22     #include <termios.h>
23 stargo 570 #include <strings.h>
24 stargo 757 #include <sys/ioctl.h>
25 stargo 798
26     #ifdef HAVE_SYS_MODEM_H
27     #include <sys/modem.h>
28     #endif
29     #ifdef HAVE_SYS_FILIO_H
30     #include <sys/filio.h>
31     #endif
32     #ifdef HAVE_SYS_STRTIO_H
33     #include <sys/strtio.h>
34     #endif
35    
36 matthewc 432 #include "rdesktop.h"
37    
38 stargo 795 #ifdef WITH_DEBUG_SERIAL
39     #define DEBUG_SERIAL(args) printf args;
40     #else
41     #define DEBUG_SERIAL(args)
42     #endif
43    
44 matthewc 432 #define FILE_DEVICE_SERIAL_PORT 0x1b
45    
46     #define SERIAL_SET_BAUD_RATE 1
47     #define SERIAL_SET_QUEUE_SIZE 2
48     #define SERIAL_SET_LINE_CONTROL 3
49     #define SERIAL_SET_BREAK_ON 4
50     #define SERIAL_SET_BREAK_OFF 5
51     #define SERIAL_IMMEDIATE_CHAR 6
52     #define SERIAL_SET_TIMEOUTS 7
53     #define SERIAL_GET_TIMEOUTS 8
54     #define SERIAL_SET_DTR 9
55     #define SERIAL_CLR_DTR 10
56     #define SERIAL_RESET_DEVICE 11
57     #define SERIAL_SET_RTS 12
58     #define SERIAL_CLR_RTS 13
59     #define SERIAL_SET_XOFF 14
60     #define SERIAL_SET_XON 15
61     #define SERIAL_GET_WAIT_MASK 16
62     #define SERIAL_SET_WAIT_MASK 17
63     #define SERIAL_WAIT_ON_MASK 18
64     #define SERIAL_PURGE 19
65     #define SERIAL_GET_BAUD_RATE 20
66     #define SERIAL_GET_LINE_CONTROL 21
67     #define SERIAL_GET_CHARS 22
68     #define SERIAL_SET_CHARS 23
69     #define SERIAL_GET_HANDFLOW 24
70     #define SERIAL_SET_HANDFLOW 25
71     #define SERIAL_GET_MODEMSTATUS 26
72     #define SERIAL_GET_COMMSTATUS 27
73     #define SERIAL_XOFF_COUNTER 28
74     #define SERIAL_GET_PROPERTIES 29
75     #define SERIAL_GET_DTRRTS 30
76     #define SERIAL_LSRMST_INSERT 31
77     #define SERIAL_CONFIG_SIZE 32
78     #define SERIAL_GET_COMMCONFIG 33
79     #define SERIAL_SET_COMMCONFIG 34
80     #define SERIAL_GET_STATS 35
81     #define SERIAL_CLEAR_STATS 36
82     #define SERIAL_GET_MODEM_CONTROL 37
83     #define SERIAL_SET_MODEM_CONTROL 38
84     #define SERIAL_SET_FIFO_CONTROL 39
85    
86     #define STOP_BITS_1 0
87     #define STOP_BITS_2 2
88    
89     #define NO_PARITY 0
90     #define ODD_PARITY 1
91     #define EVEN_PARITY 2
92    
93 n-ki 622 #define SERIAL_PURGE_TXABORT 0x00000001
94     #define SERIAL_PURGE_RXABORT 0x00000002
95     #define SERIAL_PURGE_TXCLEAR 0x00000004
96     #define SERIAL_PURGE_RXCLEAR 0x00000008
97    
98     /* SERIAL_WAIT_ON_MASK */
99 stargo 865 #define SERIAL_EV_RXCHAR 0x0001 /* Any Character received */
100     #define SERIAL_EV_RXFLAG 0x0002 /* Received certain character */
101     #define SERIAL_EV_TXEMPTY 0x0004 /* Transmitt Queue Empty */
102     #define SERIAL_EV_CTS 0x0008 /* CTS changed state */
103     #define SERIAL_EV_DSR 0x0010 /* DSR changed state */
104     #define SERIAL_EV_RLSD 0x0020 /* RLSD changed state */
105     #define SERIAL_EV_BREAK 0x0040 /* BREAK received */
106     #define SERIAL_EV_ERR 0x0080 /* Line status error occurred */
107     #define SERIAL_EV_RING 0x0100 /* Ring signal detected */
108     #define SERIAL_EV_PERR 0x0200 /* Printer error occured */
109     #define SERIAL_EV_RX80FULL 0x0400 /* Receive buffer is 80 percent full */
110     #define SERIAL_EV_EVENT1 0x0800 /* Provider specific event 1 */
111     #define SERIAL_EV_EVENT2 0x1000 /* Provider specific event 2 */
112 n-ki 622
113 stargo 757 /* Modem Status */
114 stargo 795 #define SERIAL_MS_DTR 0x01
115     #define SERIAL_MS_RTS 0x02
116 stargo 757 #define SERIAL_MS_CTS 0x10
117     #define SERIAL_MS_DSR 0x20
118     #define SERIAL_MS_RNG 0x40
119     #define SERIAL_MS_CAR 0x80
120    
121 stargo 795 /* Handflow */
122     #define SERIAL_DTR_CONTROL 0x01
123     #define SERIAL_CTS_HANDSHAKE 0x08
124     #define SERIAL_ERROR_ABORT 0x80000000
125    
126     #define SERIAL_XON_HANDSHAKE 0x01
127     #define SERIAL_XOFF_HANDSHAKE 0x02
128     #define SERIAL_DSR_SENSITIVITY 0x40
129    
130     #define SERIAL_CHAR_EOF 0
131     #define SERIAL_CHAR_ERROR 1
132     #define SERIAL_CHAR_BREAK 2
133     #define SERIAL_CHAR_EVENT 3
134     #define SERIAL_CHAR_XON 4
135     #define SERIAL_CHAR_XOFF 5
136    
137 stargo 686 #ifndef CRTSCTS
138     #define CRTSCTS 0
139     #endif
140 n-ki 622
141 stargo 795 /* FIONREAD should really do the same thing as TIOCINQ, where it is
142     * not available */
143 jdmeijer 812 #if !defined(TIOCINQ) && defined(FIONREAD)
144 stargo 795 #define TIOCINQ FIONREAD
145     #endif
146 jdmeijer 812 #if !defined(TIOCOUTQ) && defined(FIONWRITE)
147 stargo 809 #define TIOCOUTQ FIONWRITE
148     #endif
149 stargo 686
150 astrand 580 extern RDPDR_DEVICE g_rdpdr_device[];
151 n-ki 569
152 astrand 665 static SERIAL_DEVICE *
153 jsorg71 776 get_serial_info(NTHANDLE handle)
154 matthewc 432 {
155 astrand 580 int index;
156 matthewc 432
157 astrand 580 for (index = 0; index < RDPDR_MAX_DEVICES; index++)
158     {
159     if (handle == g_rdpdr_device[index].handle)
160     return (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;
161     }
162     return NULL;
163 n-ki 569 }
164 matthewc 432
165 astrand 665 static BOOL
166 jsorg71 776 get_termios(SERIAL_DEVICE * pser_inf, NTHANDLE serial_fd)
167 n-ki 569 {
168 astrand 580 speed_t speed;
169     struct termios *ptermios;
170 n-ki 569
171 astrand 580 ptermios = pser_inf->ptermios;
172 n-ki 569
173 astrand 580 if (tcgetattr(serial_fd, ptermios) == -1)
174     return False;
175 n-ki 569
176 astrand 580 speed = cfgetispeed(ptermios);
177     switch (speed)
178     {
179 stargo 545 #ifdef B75
180 astrand 580 case B75:
181     pser_inf->baud_rate = 75;
182     break;
183 stargo 545 #endif
184     #ifdef B110
185 astrand 580 case B110:
186     pser_inf->baud_rate = 110;
187     break;
188 stargo 545 #endif
189     #ifdef B134
190 astrand 580 case B134:
191     pser_inf->baud_rate = 134;
192     break;
193 stargo 545 #endif
194     #ifdef B150
195 astrand 580 case B150:
196     pser_inf->baud_rate = 150;
197     break;
198 stargo 545 #endif
199     #ifdef B300
200 astrand 580 case B300:
201     pser_inf->baud_rate = 300;
202     break;
203 stargo 545 #endif
204     #ifdef B600
205 astrand 580 case B600:
206     pser_inf->baud_rate = 600;
207     break;
208 stargo 545 #endif
209     #ifdef B1200
210 astrand 580 case B1200:
211     pser_inf->baud_rate = 1200;
212     break;
213 stargo 545 #endif
214     #ifdef B1800
215 astrand 580 case B1800:
216     pser_inf->baud_rate = 1800;
217     break;
218 stargo 545 #endif
219     #ifdef B2400
220 astrand 580 case B2400:
221     pser_inf->baud_rate = 2400;
222     break;
223 stargo 545 #endif
224     #ifdef B4800
225 astrand 580 case B4800:
226     pser_inf->baud_rate = 4800;
227     break;
228 stargo 545 #endif
229     #ifdef B9600
230 astrand 580 case B9600:
231     pser_inf->baud_rate = 9600;
232     break;
233 stargo 545 #endif
234     #ifdef B19200
235 astrand 580 case B19200:
236     pser_inf->baud_rate = 19200;
237     break;
238 stargo 545 #endif
239     #ifdef B38400
240 astrand 580 case B38400:
241     pser_inf->baud_rate = 38400;
242     break;
243 stargo 545 #endif
244     #ifdef B57600
245 astrand 580 case B57600:
246     pser_inf->baud_rate = 57600;
247     break;
248 stargo 545 #endif
249     #ifdef B115200
250 astrand 580 case B115200:
251     pser_inf->baud_rate = 115200;
252     break;
253 stargo 545 #endif
254 stargo 795 #ifdef B230400
255     case B230400:
256     pser_inf->baud_rate = 230400;
257     break;
258     #endif
259     #ifdef B460800
260     case B460800:
261     pser_inf->baud_rate = 460800;
262     break;
263     #endif
264 astrand 580 default:
265 stargo 795 pser_inf->baud_rate = 9600;
266 astrand 580 break;
267     }
268 matthewc 432
269 astrand 580 speed = cfgetospeed(ptermios);
270     pser_inf->dtr = (speed == B0) ? 0 : 1;
271 matthewc 432
272 astrand 580 pser_inf->stop_bits = (ptermios->c_cflag & CSTOPB) ? STOP_BITS_2 : STOP_BITS_1;
273     pser_inf->parity =
274     (ptermios->
275     c_cflag & PARENB) ? ((ptermios->
276     c_cflag & PARODD) ? ODD_PARITY : EVEN_PARITY) : NO_PARITY;
277     switch (ptermios->c_cflag & CSIZE)
278     {
279     case CS5:
280     pser_inf->word_length = 5;
281     break;
282     case CS6:
283     pser_inf->word_length = 6;
284     break;
285     case CS7:
286     pser_inf->word_length = 7;
287     break;
288     default:
289     pser_inf->word_length = 8;
290     break;
291     }
292 matthewc 432
293 stargo 795 if (ptermios->c_cflag & CRTSCTS)
294     {
295     pser_inf->control = SERIAL_DTR_CONTROL | SERIAL_CTS_HANDSHAKE | SERIAL_ERROR_ABORT;
296     }
297     else
298     {
299     pser_inf->control = SERIAL_DTR_CONTROL | SERIAL_ERROR_ABORT;
300     }
301 n-ki 622
302 stargo 795 pser_inf->xonoff = SERIAL_DSR_SENSITIVITY;
303     if (ptermios->c_iflag & IXON)
304     pser_inf->xonoff |= SERIAL_XON_HANDSHAKE;
305    
306     if (ptermios->c_iflag & IXOFF)
307     pser_inf->xonoff |= SERIAL_XOFF_HANDSHAKE;
308    
309     pser_inf->chars[SERIAL_CHAR_XON] = ptermios->c_cc[VSTART];
310     pser_inf->chars[SERIAL_CHAR_XOFF] = ptermios->c_cc[VSTOP];
311     pser_inf->chars[SERIAL_CHAR_EOF] = ptermios->c_cc[VEOF];
312     pser_inf->chars[SERIAL_CHAR_BREAK] = ptermios->c_cc[VINTR];
313     pser_inf->chars[SERIAL_CHAR_ERROR] = ptermios->c_cc[VKILL];
314    
315 astrand 580 return True;
316 matthewc 432 }
317    
318     static void
319 jsorg71 776 set_termios(SERIAL_DEVICE * pser_inf, NTHANDLE serial_fd)
320 matthewc 432 {
321     speed_t speed;
322    
323 n-ki 588 struct termios *ptermios;
324    
325     ptermios = pser_inf->ptermios;
326    
327    
328     switch (pser_inf->baud_rate)
329 matthewc 432 {
330 stargo 545 #ifdef B75
331 astrand 580 case 75:
332     speed = B75;
333     break;
334 stargo 545 #endif
335     #ifdef B110
336 astrand 580 case 110:
337     speed = B110;
338     break;
339 stargo 545 #endif
340     #ifdef B134
341 astrand 580 case 134:
342     speed = B134;
343     break;
344 stargo 545 #endif
345     #ifdef B150
346 astrand 580 case 150:
347     speed = B150;
348     break;
349 stargo 545 #endif
350     #ifdef B300
351 astrand 580 case 300:
352     speed = B300;
353     break;
354 stargo 545 #endif
355     #ifdef B600
356 astrand 580 case 600:
357     speed = B600;
358     break;
359 stargo 545 #endif
360     #ifdef B1200
361 astrand 580 case 1200:
362     speed = B1200;
363     break;
364 stargo 545 #endif
365     #ifdef B1800
366 astrand 580 case 1800:
367     speed = B1800;
368     break;
369 stargo 545 #endif
370     #ifdef B2400
371 astrand 580 case 2400:
372     speed = B2400;
373     break;
374 stargo 545 #endif
375     #ifdef B4800
376 astrand 580 case 4800:
377     speed = B4800;
378     break;
379 stargo 545 #endif
380     #ifdef B9600
381 astrand 580 case 9600:
382     speed = B9600;
383     break;
384 stargo 545 #endif
385     #ifdef B19200
386 astrand 580 case 19200:
387     speed = B19200;
388     break;
389 stargo 545 #endif
390     #ifdef B38400
391 astrand 580 case 38400:
392     speed = B38400;
393     break;
394 stargo 545 #endif
395     #ifdef B57600
396 astrand 580 case 57600:
397     speed = B57600;
398     break;
399 stargo 545 #endif
400     #ifdef B115200
401 astrand 580 case 115200:
402     speed = B115200;
403     break;
404 stargo 545 #endif
405 stargo 795 #ifdef B230400
406     case 230400:
407     speed = B115200;
408     break;
409     #endif
410     #ifdef B460800
411     case 460800:
412     speed = B115200;
413     break;
414     #endif
415 astrand 580 default:
416 stargo 795 speed = B9600;
417 astrand 580 break;
418 matthewc 432 }
419    
420 stargo 799 #ifdef CBAUD
421     ptermios->c_cflag &= ~CBAUD;
422     ptermios->c_cflag |= speed;
423     #else
424 matthewc 432 /* on systems with separate ispeed and ospeed, we can remember the speed
425     in ispeed while changing DTR with ospeed */
426 n-ki 588 cfsetispeed(pser_inf->ptermios, speed);
427     cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0);
428 stargo 795 #endif
429 matthewc 432
430 n-ki 622 ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS);
431 n-ki 588 switch (pser_inf->stop_bits)
432 matthewc 432 {
433     case STOP_BITS_2:
434 n-ki 588 ptermios->c_cflag |= CSTOPB;
435 matthewc 432 break;
436 stargo 795 default:
437     ptermios->c_cflag &= ~CSTOPB;
438     break;
439 matthewc 432 }
440 n-ki 622
441 n-ki 588 switch (pser_inf->parity)
442 matthewc 432 {
443     case EVEN_PARITY:
444 n-ki 588 ptermios->c_cflag |= PARENB;
445 matthewc 432 break;
446     case ODD_PARITY:
447 n-ki 588 ptermios->c_cflag |= PARENB | PARODD;
448 matthewc 432 break;
449 stargo 795 case NO_PARITY:
450     ptermios->c_cflag &= ~(PARENB | PARODD);
451     break;
452 matthewc 432 }
453 n-ki 622
454 n-ki 588 switch (pser_inf->word_length)
455 matthewc 432 {
456 astrand 435 case 5:
457 n-ki 588 ptermios->c_cflag |= CS5;
458 astrand 435 break;
459     case 6:
460 n-ki 588 ptermios->c_cflag |= CS6;
461 astrand 435 break;
462     case 7:
463 n-ki 588 ptermios->c_cflag |= CS7;
464 astrand 435 break;
465     default:
466 n-ki 588 ptermios->c_cflag |= CS8;
467 astrand 435 break;
468 matthewc 432 }
469    
470 stargo 795 #if 0
471 n-ki 622 if (pser_inf->rts)
472     ptermios->c_cflag |= CRTSCTS;
473 stargo 795 else
474     ptermios->c_cflag &= ~CRTSCTS;
475     #endif
476 n-ki 622
477 stargo 795 if (pser_inf->control & SERIAL_CTS_HANDSHAKE)
478     {
479     ptermios->c_cflag |= CRTSCTS;
480     }
481     else
482     {
483     ptermios->c_cflag &= ~CRTSCTS;
484     }
485    
486    
487     if (pser_inf->xonoff & SERIAL_XON_HANDSHAKE)
488     {
489     ptermios->c_iflag |= IXON | IMAXBEL;
490     }
491     if (pser_inf->xonoff & SERIAL_XOFF_HANDSHAKE)
492     {
493     ptermios->c_iflag |= IXOFF | IMAXBEL;
494     }
495    
496     if ((pser_inf->xonoff & (SERIAL_XOFF_HANDSHAKE | SERIAL_XON_HANDSHAKE)) == 0)
497     {
498     ptermios->c_iflag &= ~IXON;
499     ptermios->c_iflag &= ~IXOFF;
500     }
501    
502     ptermios->c_cc[VSTART] = pser_inf->chars[SERIAL_CHAR_XON];
503     ptermios->c_cc[VSTOP] = pser_inf->chars[SERIAL_CHAR_XOFF];
504     ptermios->c_cc[VEOF] = pser_inf->chars[SERIAL_CHAR_EOF];
505     ptermios->c_cc[VINTR] = pser_inf->chars[SERIAL_CHAR_BREAK];
506     ptermios->c_cc[VKILL] = pser_inf->chars[SERIAL_CHAR_ERROR];
507    
508 n-ki 588 tcsetattr(serial_fd, TCSANOW, ptermios);
509 matthewc 432 }
510    
511 n-ki 569 /* Enumeration of devices from rdesktop.c */
512     /* returns numer of units found and initialized. */
513     /* optarg looks like ':com1=/dev/ttyS0' */
514     /* when it arrives to this function. */
515 n-ki 578 /* :com1=/dev/ttyS0,com2=/dev/ttyS1 */
516 n-ki 569 int
517 astrand 608 serial_enum_devices(uint32 * id, char *optarg)
518 matthewc 432 {
519 astrand 580 SERIAL_DEVICE *pser_inf;
520 matthewc 432
521 n-ki 578 char *pos = optarg;
522     char *pos2;
523     int count = 0;
524 matthewc 432
525 stargo 865 /* skip the first colon */
526 n-ki 578 optarg++;
527     while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)
528     {
529 stargo 865 /* Init data structures for device */
530 n-ki 569 pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE));
531     pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios));
532 stargo 755 memset(pser_inf->ptermios, 0, sizeof(struct termios));
533 n-ki 569 pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios));
534 stargo 755 memset(pser_inf->pold_termios, 0, sizeof(struct termios));
535 n-ki 569
536 n-ki 578 pos2 = next_arg(optarg, '=');
537     strcpy(g_rdpdr_device[*id].name, optarg);
538 n-ki 569
539 n-ki 578 toupper_str(g_rdpdr_device[*id].name);
540 n-ki 569
541 n-ki 578 g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);
542     strcpy(g_rdpdr_device[*id].local_path, pos2);
543 astrand 580 printf("SERIAL %s to %s\n", g_rdpdr_device[*id].name,
544     g_rdpdr_device[*id].local_path);
545 stargo 865 /* set device type */
546 n-ki 569 g_rdpdr_device[*id].device_type = DEVICE_TYPE_SERIAL;
547     g_rdpdr_device[*id].pdevice_data = (void *) pser_inf;
548 n-ki 578 count++;
549 n-ki 569 (*id)++;
550    
551 n-ki 578 optarg = pos;
552 n-ki 569 }
553 n-ki 578 return count;
554 matthewc 432 }
555    
556 astrand 665 static NTSTATUS
557 astrand 580 serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,
558 jsorg71 776 uint32 flags_and_attributes, char *filename, NTHANDLE * handle)
559 n-ki 569 {
560 jsorg71 776 NTHANDLE serial_fd;
561 astrand 580 SERIAL_DEVICE *pser_inf;
562     struct termios *ptermios;
563 n-ki 569
564 astrand 580 pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data;
565     ptermios = pser_inf->ptermios;
566 stargo 755 serial_fd = open(g_rdpdr_device[device_id].local_path, O_RDWR | O_NOCTTY | O_NONBLOCK);
567 n-ki 569
568 astrand 580 if (serial_fd == -1)
569 n-ki 588 {
570     perror("open");
571 astrand 580 return STATUS_ACCESS_DENIED;
572 n-ki 588 }
573 n-ki 569
574 astrand 580 if (!get_termios(pser_inf, serial_fd))
575 n-ki 622 {
576     printf("INFO: SERIAL %s access denied\n", g_rdpdr_device[device_id].name);
577     fflush(stdout);
578 astrand 580 return STATUS_ACCESS_DENIED;
579 n-ki 622 }
580 n-ki 569
581 stargo 865 /* Store handle for later use */
582 astrand 580 g_rdpdr_device[device_id].handle = serial_fd;
583 n-ki 569
584 n-ki 578 /* some sane information */
585 stargo 795 DEBUG_SERIAL(("INFO: SERIAL %s to %s\nINFO: speed %u baud, stop bits %u, parity %u, word length %u bits, dtr %u, rts %u\n", g_rdpdr_device[device_id].name, g_rdpdr_device[device_id].local_path, pser_inf->baud_rate, pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length, pser_inf->dtr, pser_inf->rts));
586 n-ki 622
587 astrand 782 pser_inf->ptermios->c_iflag &=
588     ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
589 stargo 759 pser_inf->ptermios->c_oflag &= ~OPOST;
590 stargo 809 pser_inf->ptermios->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
591 astrand 782 pser_inf->ptermios->c_cflag &= ~(CSIZE | PARENB);
592 stargo 759 pser_inf->ptermios->c_cflag |= CS8;
593 stargo 795
594 stargo 759 tcsetattr(serial_fd, TCSANOW, pser_inf->ptermios);
595 n-ki 592
596 stargo 795 pser_inf->event_txempty = 0;
597     pser_inf->event_cts = 0;
598     pser_inf->event_dsr = 0;
599     pser_inf->event_rlsd = 0;
600     pser_inf->event_pending = 0;
601    
602 astrand 580 *handle = serial_fd;
603 n-ki 592
604     /* all read and writes should be non blocking */
605     if (fcntl(*handle, F_SETFL, O_NONBLOCK) == -1)
606     perror("fcntl");
607    
608 stargo 795 pser_inf->read_total_timeout_constant = 5;
609    
610 astrand 580 return STATUS_SUCCESS;
611 n-ki 569 }
612    
613 matthewc 432 static NTSTATUS
614 jsorg71 776 serial_close(NTHANDLE handle)
615 matthewc 432 {
616 n-ki 622 int i = get_device_index(handle);
617     if (i >= 0)
618     g_rdpdr_device[i].handle = 0;
619 stargo 795
620     rdpdr_abort_io(handle, 0, STATUS_TIMEOUT);
621 n-ki 588 close(handle);
622 matthewc 432 return STATUS_SUCCESS;
623     }
624    
625 astrand 665 static NTSTATUS
626 jsorg71 776 serial_read(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
627 matthewc 432 {
628 astrand 580 long timeout;
629     SERIAL_DEVICE *pser_inf;
630     struct termios *ptermios;
631 stargo 795 #ifdef WITH_DEBUG_SERIAL
632     int bytes_inqueue;
633     #endif
634 n-ki 569
635 stargo 795
636 n-ki 592 timeout = 90;
637 astrand 580 pser_inf = get_serial_info(handle);
638     ptermios = pser_inf->ptermios;
639 n-ki 569
640 stargo 865 /* Set timeouts kind of like the windows serial timeout parameters. Multiply timeout
641     with requested read size */
642 astrand 580 if (pser_inf->read_total_timeout_multiplier | pser_inf->read_total_timeout_constant)
643     {
644     timeout =
645     (pser_inf->read_total_timeout_multiplier * length +
646     pser_inf->read_total_timeout_constant + 99) / 100;
647     }
648     else if (pser_inf->read_interval_timeout)
649     {
650     timeout = (pser_inf->read_interval_timeout * length + 99) / 100;
651     }
652 n-ki 569
653 stargo 865 /* If a timeout is set, do a blocking read, which times out after some time.
654     It will make rdesktop less responsive, but it will improve serial performance, by not
655     reading one character at a time. */
656 astrand 580 if (timeout == 0)
657     {
658     ptermios->c_cc[VTIME] = 0;
659     ptermios->c_cc[VMIN] = 0;
660     }
661     else
662     {
663     ptermios->c_cc[VTIME] = timeout;
664     ptermios->c_cc[VMIN] = 1;
665     }
666     tcsetattr(handle, TCSANOW, ptermios);
667 n-ki 592
668 jdmeijer 812 #if defined(WITH_DEBUG_SERIAL) && defined(TIOCINQ)
669 stargo 795 ioctl(handle, TIOCINQ, &bytes_inqueue);
670     DEBUG_SERIAL(("serial_read inqueue: %d expected %d\n", bytes_inqueue, length));
671     #endif
672 n-ki 592
673 astrand 580 *result = read(handle, data, length);
674 n-ki 592
675 stargo 795 #ifdef WITH_DEBUG_SERIAL
676     DEBUG_SERIAL(("serial_read Bytes %d\n", *result));
677     if (*result > 0)
678     hexdump(data, *result);
679     #endif
680 n-ki 622
681 astrand 580 return STATUS_SUCCESS;
682 matthewc 432 }
683    
684 astrand 665 static NTSTATUS
685 jsorg71 776 serial_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
686 matthewc 432 {
687 stargo 795 SERIAL_DEVICE *pser_inf;
688    
689     pser_inf = get_serial_info(handle);
690    
691 astrand 580 *result = write(handle, data, length);
692 stargo 795
693     if (*result > 0)
694     pser_inf->event_txempty = *result;
695    
696     DEBUG_SERIAL(("serial_write length %d, offset %d result %d\n", length, offset, *result));
697    
698 astrand 580 return STATUS_SUCCESS;
699 matthewc 432 }
700    
701     static NTSTATUS
702 jsorg71 776 serial_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
703 matthewc 432 {
704 n-ki 622 int flush_mask, purge_mask;
705 stargo 757 uint32 result, modemstate;
706 matthewc 432 uint8 immediate;
707 n-ki 588 SERIAL_DEVICE *pser_inf;
708     struct termios *ptermios;
709 matthewc 432
710     if ((request >> 16) != FILE_DEVICE_SERIAL_PORT)
711     return STATUS_INVALID_PARAMETER;
712    
713 n-ki 588 pser_inf = get_serial_info(handle);
714     ptermios = pser_inf->ptermios;
715    
716 matthewc 432 /* extract operation */
717     request >>= 2;
718     request &= 0xfff;
719    
720     switch (request)
721     {
722     case SERIAL_SET_BAUD_RATE:
723 n-ki 588 in_uint32_le(in, pser_inf->baud_rate);
724     set_termios(pser_inf, handle);
725 astrand 801 DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BAUD_RATE %d\n",
726     pser_inf->baud_rate));
727 matthewc 432 break;
728     case SERIAL_GET_BAUD_RATE:
729 n-ki 588 out_uint32_le(out, pser_inf->baud_rate);
730 astrand 801 DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_BAUD_RATE %d\n",
731     pser_inf->baud_rate));
732 matthewc 432 break;
733     case SERIAL_SET_QUEUE_SIZE:
734 n-ki 588 in_uint32_le(in, pser_inf->queue_in_size);
735     in_uint32_le(in, pser_inf->queue_out_size);
736 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_QUEUE_SIZE in %d out %d\n",
737 astrand 801 pser_inf->queue_in_size, pser_inf->queue_out_size));
738 matthewc 432 break;
739     case SERIAL_SET_LINE_CONTROL:
740 n-ki 588 in_uint8(in, pser_inf->stop_bits);
741     in_uint8(in, pser_inf->parity);
742     in_uint8(in, pser_inf->word_length);
743     set_termios(pser_inf, handle);
744 astrand 801 DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_LINE_CONTROL stop %d parity %d word %d\n", pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length));
745 matthewc 432 break;
746     case SERIAL_GET_LINE_CONTROL:
747 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_LINE_CONTROL\n"));
748 n-ki 588 out_uint8(out, pser_inf->stop_bits);
749     out_uint8(out, pser_inf->parity);
750     out_uint8(out, pser_inf->word_length);
751 matthewc 432 break;
752     case SERIAL_IMMEDIATE_CHAR:
753 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_IMMEDIATE_CHAR\n"));
754 matthewc 432 in_uint8(in, immediate);
755 n-ki 569 serial_write(handle, &immediate, 1, 0, &result);
756 matthewc 432 break;
757     case SERIAL_CONFIG_SIZE:
758 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_CONFIG_SIZE\n"));
759 matthewc 432 out_uint32_le(out, 0);
760     break;
761     case SERIAL_GET_CHARS:
762 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_CHARS\n"));
763     out_uint8a(out, pser_inf->chars, 6);
764 matthewc 432 break;
765     case SERIAL_SET_CHARS:
766 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_CHARS\n"));
767     in_uint8a(in, pser_inf->chars, 6);
768     #ifdef WITH_DEBUG_SERIAL
769     hexdump(pser_inf->chars, 6);
770     #endif
771     set_termios(pser_inf, handle);
772 matthewc 432 break;
773     case SERIAL_GET_HANDFLOW:
774 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_HANDFLOW\n"));
775     get_termios(pser_inf, handle);
776     out_uint32_le(out, pser_inf->control);
777     out_uint32_le(out, pser_inf->xonoff); /* Xon/Xoff */
778     out_uint32_le(out, pser_inf->onlimit);
779     out_uint32_le(out, pser_inf->offlimit);
780 matthewc 432 break;
781     case SERIAL_SET_HANDFLOW:
782 stargo 795 in_uint32_le(in, pser_inf->control);
783     in_uint32_le(in, pser_inf->xonoff);
784     in_uint32_le(in, pser_inf->onlimit);
785     in_uint32_le(in, pser_inf->offlimit);
786     DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_HANDFLOW %x %x %x %x\n",
787 astrand 801 pser_inf->control, pser_inf->xonoff, pser_inf->onlimit,
788     pser_inf->onlimit));
789 stargo 795 set_termios(pser_inf, handle);
790 matthewc 432 break;
791     case SERIAL_SET_TIMEOUTS:
792 stargo 795 in_uint32(in, pser_inf->read_interval_timeout);
793     in_uint32(in, pser_inf->read_total_timeout_multiplier);
794     in_uint32(in, pser_inf->read_total_timeout_constant);
795     in_uint32(in, pser_inf->write_total_timeout_multiplier);
796     in_uint32(in, pser_inf->write_total_timeout_constant);
797     DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_TIMEOUTS read timeout %d %d %d\n",
798 astrand 801 pser_inf->read_interval_timeout,
799     pser_inf->read_total_timeout_multiplier,
800     pser_inf->read_total_timeout_constant));
801 matthewc 432 break;
802     case SERIAL_GET_TIMEOUTS:
803 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_TIMEOUTS read timeout %d %d %d\n",
804 astrand 801 pser_inf->read_interval_timeout,
805     pser_inf->read_total_timeout_multiplier,
806     pser_inf->read_total_timeout_constant));
807 stargo 795
808     out_uint32(out, pser_inf->read_interval_timeout);
809     out_uint32(out, pser_inf->read_total_timeout_multiplier);
810     out_uint32(out, pser_inf->read_total_timeout_constant);
811     out_uint32(out, pser_inf->write_total_timeout_multiplier);
812     out_uint32(out, pser_inf->write_total_timeout_constant);
813 matthewc 432 break;
814     case SERIAL_GET_WAIT_MASK:
815 astrand 801 DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_WAIT_MASK %X\n",
816 jdmeijer 816 pser_inf->wait_mask));
817     out_uint32(out, pser_inf->wait_mask);
818 matthewc 432 break;
819     case SERIAL_SET_WAIT_MASK:
820 n-ki 588 in_uint32(in, pser_inf->wait_mask);
821 astrand 801 DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_WAIT_MASK %X\n",
822     pser_inf->wait_mask));
823 matthewc 432 break;
824     case SERIAL_SET_DTR:
825 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_DTR\n"));
826     ioctl(handle, TIOCMGET, &result);
827     result |= TIOCM_DTR;
828     ioctl(handle, TIOCMSET, &result);
829 n-ki 588 pser_inf->dtr = 1;
830 matthewc 432 break;
831     case SERIAL_CLR_DTR:
832 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_CLR_DTR\n"));
833     ioctl(handle, TIOCMGET, &result);
834     result &= ~TIOCM_DTR;
835     ioctl(handle, TIOCMSET, &result);
836 n-ki 588 pser_inf->dtr = 0;
837 matthewc 432 break;
838 n-ki 622 case SERIAL_SET_RTS:
839 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_RTS\n"));
840     ioctl(handle, TIOCMGET, &result);
841     result |= TIOCM_RTS;
842     ioctl(handle, TIOCMSET, &result);
843 n-ki 622 pser_inf->rts = 1;
844 matthewc 432 break;
845 n-ki 622 case SERIAL_CLR_RTS:
846 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_CLR_RTS\n"));
847     ioctl(handle, TIOCMGET, &result);
848     result &= ~TIOCM_RTS;
849     ioctl(handle, TIOCMSET, &result);
850 n-ki 622 pser_inf->rts = 0;
851 matthewc 432 break;
852 n-ki 622 case SERIAL_GET_MODEMSTATUS:
853 stargo 757 modemstate = 0;
854     #ifdef TIOCMGET
855     ioctl(handle, TIOCMGET, &result);
856     if (result & TIOCM_CTS)
857     modemstate |= SERIAL_MS_CTS;
858     if (result & TIOCM_DSR)
859     modemstate |= SERIAL_MS_DSR;
860     if (result & TIOCM_RNG)
861     modemstate |= SERIAL_MS_RNG;
862     if (result & TIOCM_CAR)
863     modemstate |= SERIAL_MS_CAR;
864 stargo 795 if (result & TIOCM_DTR)
865     modemstate |= SERIAL_MS_DTR;
866     if (result & TIOCM_RTS)
867     modemstate |= SERIAL_MS_RTS;
868 stargo 757 #endif
869 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_MODEMSTATUS %X\n", modemstate));
870 stargo 757 out_uint32_le(out, modemstate);
871 n-ki 622 break;
872     case SERIAL_GET_COMMSTATUS:
873     out_uint32_le(out, 0); /* Errors */
874     out_uint32_le(out, 0); /* Hold reasons */
875 stargo 795
876     result = 0;
877 jdmeijer 812 #ifdef TIOCINQ
878 stargo 795 ioctl(handle, TIOCINQ, &result);
879 jdmeijer 812 #endif
880 stargo 795 out_uint32_le(out, result); /* Amount in in queue */
881     if (result)
882 astrand 801 DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_COMMSTATUS in queue %d\n",
883     result));
884 stargo 795
885     result = 0;
886 jdmeijer 812 #ifdef TIOCOUTQ
887 stargo 795 ioctl(handle, TIOCOUTQ, &result);
888 jdmeijer 812 #endif
889 stargo 795 out_uint32_le(out, result); /* Amount in out queue */
890     if (result)
891     DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_COMMSTATUS out queue %d\n", result));
892    
893 n-ki 622 out_uint8(out, 0); /* EofReceived */
894     out_uint8(out, 0); /* WaitForImmediate */
895     break;
896 matthewc 432 case SERIAL_PURGE:
897 astrand 580 in_uint32(in, purge_mask);
898 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_PURGE purge_mask %X\n", purge_mask));
899     flush_mask = 0;
900     if (purge_mask & SERIAL_PURGE_TXCLEAR)
901 astrand 580 flush_mask |= TCOFLUSH;
902 stargo 795 if (purge_mask & SERIAL_PURGE_RXCLEAR)
903 astrand 580 flush_mask |= TCIFLUSH;
904     if (flush_mask != 0)
905     tcflush(handle, flush_mask);
906 stargo 795 if (purge_mask & SERIAL_PURGE_TXABORT)
907 astrand 580 rdpdr_abort_io(handle, 4, STATUS_CANCELLED);
908 stargo 795 if (purge_mask & SERIAL_PURGE_RXABORT)
909 astrand 580 rdpdr_abort_io(handle, 3, STATUS_CANCELLED);
910     break;
911 n-ki 622 case SERIAL_WAIT_ON_MASK:
912 astrand 801 DEBUG_SERIAL(("serial_ioctl -> SERIAL_WAIT_ON_MASK %X\n",
913     pser_inf->wait_mask));
914 stargo 795 pser_inf->event_pending = 1;
915     if (serial_get_event(handle, &result))
916     {
917     DEBUG_SERIAL(("WAIT end event = %x\n", result));
918     out_uint32_le(out, result);
919     break;
920     }
921     return STATUS_PENDING;
922 n-ki 622 break;
923     case SERIAL_SET_BREAK_ON:
924 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BREAK_ON\n"));
925     tcsendbreak(handle, 0);
926 n-ki 622 break;
927 matthewc 432 case SERIAL_RESET_DEVICE:
928 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_RESET_DEVICE\n"));
929     break;
930 matthewc 432 case SERIAL_SET_BREAK_OFF:
931 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BREAK_OFF\n"));
932     break;
933 matthewc 432 case SERIAL_SET_XOFF:
934 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_XOFF\n"));
935     break;
936 matthewc 432 case SERIAL_SET_XON:
937 stargo 795 DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_XON\n"));
938     tcflow(handle, TCION);
939 matthewc 432 break;
940     default:
941     unimpl("SERIAL IOCTL %d\n", request);
942     return STATUS_INVALID_PARAMETER;
943     }
944    
945     return STATUS_SUCCESS;
946     }
947    
948 stargo 795 BOOL
949     serial_get_event(NTHANDLE handle, uint32 * result)
950     {
951     int index;
952     SERIAL_DEVICE *pser_inf;
953     int bytes;
954     BOOL ret = False;
955    
956     *result = 0;
957     index = get_device_index(handle);
958     if (index < 0)
959     return False;
960    
961 jdmeijer 812 #ifdef TIOCINQ
962 stargo 795 pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;
963    
964     ioctl(handle, TIOCINQ, &bytes);
965    
966     if (bytes > 0)
967     {
968     DEBUG_SERIAL(("serial_get_event Bytes %d\n", bytes));
969     if (bytes > pser_inf->event_rlsd)
970     {
971     pser_inf->event_rlsd = bytes;
972     if (pser_inf->wait_mask & SERIAL_EV_RLSD)
973     {
974     DEBUG_SERIAL(("Event -> SERIAL_EV_RLSD \n"));
975     *result |= SERIAL_EV_RLSD;
976     ret = True;
977     }
978    
979     }
980    
981     if ((bytes > 1) && (pser_inf->wait_mask & SERIAL_EV_RXFLAG))
982     {
983     DEBUG_SERIAL(("Event -> SERIAL_EV_RXFLAG Bytes %d\n", bytes));
984     *result |= SERIAL_EV_RXFLAG;
985     ret = True;
986     }
987     if ((pser_inf->wait_mask & SERIAL_EV_RXCHAR))
988     {
989     DEBUG_SERIAL(("Event -> SERIAL_EV_RXCHAR Bytes %d\n", bytes));
990     *result |= SERIAL_EV_RXCHAR;
991     ret = True;
992     }
993    
994     }
995     else
996     {
997     pser_inf->event_rlsd = 0;
998     }
999 jdmeijer 812 #endif
1000 stargo 795
1001 jdmeijer 812 #ifdef TIOCOUTQ
1002 stargo 795 ioctl(handle, TIOCOUTQ, &bytes);
1003     if ((bytes == 0)
1004     && (pser_inf->event_txempty > 0) && (pser_inf->wait_mask & SERIAL_EV_TXEMPTY))
1005     {
1006    
1007     DEBUG_SERIAL(("Event -> SERIAL_EV_TXEMPTY\n"));
1008     *result |= SERIAL_EV_TXEMPTY;
1009     ret = True;
1010     }
1011     pser_inf->event_txempty = bytes;
1012 jdmeijer 812 #endif
1013 stargo 795
1014     ioctl(handle, TIOCMGET, &bytes);
1015     if ((bytes & TIOCM_DSR) != pser_inf->event_dsr)
1016     {
1017     pser_inf->event_dsr = bytes & TIOCM_DSR;
1018     if (pser_inf->wait_mask & SERIAL_EV_DSR)
1019     {
1020 astrand 801 DEBUG_SERIAL(("event -> SERIAL_EV_DSR %s\n",
1021     (bytes & TIOCM_DSR) ? "ON" : "OFF"));
1022 stargo 795 *result |= SERIAL_EV_DSR;
1023     ret = True;
1024     }
1025     }
1026    
1027     if ((bytes & TIOCM_CTS) != pser_inf->event_cts)
1028     {
1029     pser_inf->event_cts = bytes & TIOCM_CTS;
1030     if (pser_inf->wait_mask & SERIAL_EV_CTS)
1031     {
1032 astrand 801 DEBUG_SERIAL((" EVENT-> SERIAL_EV_CTS %s\n",
1033     (bytes & TIOCM_CTS) ? "ON" : "OFF"));
1034 stargo 795 *result |= SERIAL_EV_CTS;
1035     ret = True;
1036     }
1037     }
1038    
1039     if (ret)
1040     pser_inf->event_pending = 0;
1041    
1042     return ret;
1043     }
1044    
1045 n-ki 569 /* Read timeout for a given file descripter (device) when adding fd's to select() */
1046     BOOL
1047 jsorg71 776 serial_get_timeout(NTHANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout)
1048 n-ki 569 {
1049 astrand 580 int index;
1050     SERIAL_DEVICE *pser_inf;
1051 n-ki 569
1052 astrand 580 index = get_device_index(handle);
1053 n-ki 622 if (index < 0)
1054     return True;
1055 n-ki 569
1056 astrand 580 if (g_rdpdr_device[index].device_type != DEVICE_TYPE_SERIAL)
1057     {
1058     return False;
1059     }
1060 n-ki 569
1061 astrand 580 pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;
1062 n-ki 569
1063 astrand 580 *timeout =
1064     pser_inf->read_total_timeout_multiplier * length +
1065     pser_inf->read_total_timeout_constant;
1066     *itv_timeout = pser_inf->read_interval_timeout;
1067     return True;
1068 n-ki 569 }
1069    
1070 astrand 435 DEVICE_FNS serial_fns = {
1071 matthewc 432 serial_create,
1072     serial_close,
1073     serial_read,
1074     serial_write,
1075     serial_device_control
1076     };

  ViewVC Help
Powered by ViewVC 1.1.26