/[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 776 - (hide annotations)
Sat Oct 2 01:30:33 2004 UTC (19 years, 8 months ago) by jsorg71
File MIME type: text/plain
File size: 16549 byte(s)
change HANDLE to NTHANDLE to avoid conflics

1 matthewc 432 #include <unistd.h>
2     #include <fcntl.h>
3     #include <termios.h>
4 stargo 570 #include <strings.h>
5 stargo 757 #include <sys/ioctl.h>
6 matthewc 432 #include "rdesktop.h"
7    
8     #define FILE_DEVICE_SERIAL_PORT 0x1b
9    
10     #define SERIAL_SET_BAUD_RATE 1
11     #define SERIAL_SET_QUEUE_SIZE 2
12     #define SERIAL_SET_LINE_CONTROL 3
13     #define SERIAL_SET_BREAK_ON 4
14     #define SERIAL_SET_BREAK_OFF 5
15     #define SERIAL_IMMEDIATE_CHAR 6
16     #define SERIAL_SET_TIMEOUTS 7
17     #define SERIAL_GET_TIMEOUTS 8
18     #define SERIAL_SET_DTR 9
19     #define SERIAL_CLR_DTR 10
20     #define SERIAL_RESET_DEVICE 11
21     #define SERIAL_SET_RTS 12
22     #define SERIAL_CLR_RTS 13
23     #define SERIAL_SET_XOFF 14
24     #define SERIAL_SET_XON 15
25     #define SERIAL_GET_WAIT_MASK 16
26     #define SERIAL_SET_WAIT_MASK 17
27     #define SERIAL_WAIT_ON_MASK 18
28     #define SERIAL_PURGE 19
29     #define SERIAL_GET_BAUD_RATE 20
30     #define SERIAL_GET_LINE_CONTROL 21
31     #define SERIAL_GET_CHARS 22
32     #define SERIAL_SET_CHARS 23
33     #define SERIAL_GET_HANDFLOW 24
34     #define SERIAL_SET_HANDFLOW 25
35     #define SERIAL_GET_MODEMSTATUS 26
36     #define SERIAL_GET_COMMSTATUS 27
37     #define SERIAL_XOFF_COUNTER 28
38     #define SERIAL_GET_PROPERTIES 29
39     #define SERIAL_GET_DTRRTS 30
40     #define SERIAL_LSRMST_INSERT 31
41     #define SERIAL_CONFIG_SIZE 32
42     #define SERIAL_GET_COMMCONFIG 33
43     #define SERIAL_SET_COMMCONFIG 34
44     #define SERIAL_GET_STATS 35
45     #define SERIAL_CLEAR_STATS 36
46     #define SERIAL_GET_MODEM_CONTROL 37
47     #define SERIAL_SET_MODEM_CONTROL 38
48     #define SERIAL_SET_FIFO_CONTROL 39
49    
50     #define STOP_BITS_1 0
51     #define STOP_BITS_2 2
52    
53     #define NO_PARITY 0
54     #define ODD_PARITY 1
55     #define EVEN_PARITY 2
56    
57 n-ki 622 #define SERIAL_PURGE_TXABORT 0x00000001
58     #define SERIAL_PURGE_RXABORT 0x00000002
59     #define SERIAL_PURGE_TXCLEAR 0x00000004
60     #define SERIAL_PURGE_RXCLEAR 0x00000008
61    
62     /* SERIAL_WAIT_ON_MASK */
63     #define SERIAL_EV_RXCHAR 0x0001 // Any Character received
64     #define SERIAL_EV_RXFLAG 0x0002 // Received certain character
65     #define SERIAL_EV_TXEMPTY 0x0004 // Transmitt Queue Empty
66     #define SERIAL_EV_CTS 0x0008 // CTS changed state
67     #define SERIAL_EV_DSR 0x0010 // DSR changed state
68     #define SERIAL_EV_RLSD 0x0020 // RLSD changed state
69     #define SERIAL_EV_BREAK 0x0040 // BREAK received
70     #define SERIAL_EV_ERR 0x0080 // Line status error occurred
71     #define SERIAL_EV_RING 0x0100 // Ring signal detected
72     #define SERIAL_EV_PERR 0x0200 // Printer error occured
73     #define SERIAL_EV_RX80FULL 0x0400 // Receive buffer is 80 percent full
74     #define SERIAL_EV_EVENT1 0x0800 // Provider specific event 1
75     #define SERIAL_EV_EVENT2 0x1000 // Provider specific event 2
76    
77 stargo 757 /* Modem Status */
78     #define SERIAL_MS_CTS 0x10
79     #define SERIAL_MS_DSR 0x20
80     #define SERIAL_MS_RNG 0x40
81     #define SERIAL_MS_CAR 0x80
82    
83 stargo 686 #ifndef CRTSCTS
84     #define CRTSCTS 0
85     #endif
86 n-ki 622
87 stargo 686
88 astrand 580 extern RDPDR_DEVICE g_rdpdr_device[];
89 n-ki 569
90 astrand 665 static SERIAL_DEVICE *
91 jsorg71 776 get_serial_info(NTHANDLE handle)
92 matthewc 432 {
93 astrand 580 int index;
94 matthewc 432
95 astrand 580 for (index = 0; index < RDPDR_MAX_DEVICES; index++)
96     {
97     if (handle == g_rdpdr_device[index].handle)
98     return (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;
99     }
100     return NULL;
101 n-ki 569 }
102 matthewc 432
103 astrand 665 static BOOL
104 jsorg71 776 get_termios(SERIAL_DEVICE * pser_inf, NTHANDLE serial_fd)
105 n-ki 569 {
106 astrand 580 speed_t speed;
107     struct termios *ptermios;
108 n-ki 569
109 astrand 580 ptermios = pser_inf->ptermios;
110 n-ki 569
111 astrand 580 if (tcgetattr(serial_fd, ptermios) == -1)
112     return False;
113 n-ki 569
114 astrand 580 speed = cfgetispeed(ptermios);
115     switch (speed)
116     {
117 stargo 545 #ifdef B75
118 astrand 580 case B75:
119     pser_inf->baud_rate = 75;
120     break;
121 stargo 545 #endif
122     #ifdef B110
123 astrand 580 case B110:
124     pser_inf->baud_rate = 110;
125     break;
126 stargo 545 #endif
127     #ifdef B134
128 astrand 580 case B134:
129     pser_inf->baud_rate = 134;
130     break;
131 stargo 545 #endif
132     #ifdef B150
133 astrand 580 case B150:
134     pser_inf->baud_rate = 150;
135     break;
136 stargo 545 #endif
137     #ifdef B300
138 astrand 580 case B300:
139     pser_inf->baud_rate = 300;
140     break;
141 stargo 545 #endif
142     #ifdef B600
143 astrand 580 case B600:
144     pser_inf->baud_rate = 600;
145     break;
146 stargo 545 #endif
147     #ifdef B1200
148 astrand 580 case B1200:
149     pser_inf->baud_rate = 1200;
150     break;
151 stargo 545 #endif
152     #ifdef B1800
153 astrand 580 case B1800:
154     pser_inf->baud_rate = 1800;
155     break;
156 stargo 545 #endif
157     #ifdef B2400
158 astrand 580 case B2400:
159     pser_inf->baud_rate = 2400;
160     break;
161 stargo 545 #endif
162     #ifdef B4800
163 astrand 580 case B4800:
164     pser_inf->baud_rate = 4800;
165     break;
166 stargo 545 #endif
167     #ifdef B9600
168 astrand 580 case B9600:
169     pser_inf->baud_rate = 9600;
170     break;
171 stargo 545 #endif
172     #ifdef B19200
173 astrand 580 case B19200:
174     pser_inf->baud_rate = 19200;
175     break;
176 stargo 545 #endif
177     #ifdef B38400
178 astrand 580 case B38400:
179     pser_inf->baud_rate = 38400;
180     break;
181 stargo 545 #endif
182     #ifdef B57600
183 astrand 580 case B57600:
184     pser_inf->baud_rate = 57600;
185     break;
186 stargo 545 #endif
187     #ifdef B115200
188 astrand 580 case B115200:
189     pser_inf->baud_rate = 115200;
190     break;
191 stargo 545 #endif
192 astrand 580 default:
193     pser_inf->baud_rate = 0;
194     break;
195     }
196 matthewc 432
197 astrand 580 speed = cfgetospeed(ptermios);
198     pser_inf->dtr = (speed == B0) ? 0 : 1;
199 matthewc 432
200 astrand 580 pser_inf->stop_bits = (ptermios->c_cflag & CSTOPB) ? STOP_BITS_2 : STOP_BITS_1;
201     pser_inf->parity =
202     (ptermios->
203     c_cflag & PARENB) ? ((ptermios->
204     c_cflag & PARODD) ? ODD_PARITY : EVEN_PARITY) : NO_PARITY;
205     switch (ptermios->c_cflag & CSIZE)
206     {
207     case CS5:
208     pser_inf->word_length = 5;
209     break;
210     case CS6:
211     pser_inf->word_length = 6;
212     break;
213     case CS7:
214     pser_inf->word_length = 7;
215     break;
216     default:
217     pser_inf->word_length = 8;
218     break;
219     }
220 matthewc 432
221 n-ki 622 pser_inf->rts = (ptermios->c_cflag & CRTSCTS) ? 1 : 0;
222    
223 astrand 580 return True;
224 matthewc 432 }
225    
226     static void
227 jsorg71 776 set_termios(SERIAL_DEVICE * pser_inf, NTHANDLE serial_fd)
228 matthewc 432 {
229     speed_t speed;
230    
231 n-ki 588 struct termios *ptermios;
232    
233     ptermios = pser_inf->ptermios;
234    
235    
236     switch (pser_inf->baud_rate)
237 matthewc 432 {
238 stargo 545 #ifdef B75
239 astrand 580 case 75:
240     speed = B75;
241     break;
242 stargo 545 #endif
243     #ifdef B110
244 astrand 580 case 110:
245     speed = B110;
246     break;
247 stargo 545 #endif
248     #ifdef B134
249 astrand 580 case 134:
250     speed = B134;
251     break;
252 stargo 545 #endif
253     #ifdef B150
254 astrand 580 case 150:
255     speed = B150;
256     break;
257 stargo 545 #endif
258     #ifdef B300
259 astrand 580 case 300:
260     speed = B300;
261     break;
262 stargo 545 #endif
263     #ifdef B600
264 astrand 580 case 600:
265     speed = B600;
266     break;
267 stargo 545 #endif
268     #ifdef B1200
269 astrand 580 case 1200:
270     speed = B1200;
271     break;
272 stargo 545 #endif
273     #ifdef B1800
274 astrand 580 case 1800:
275     speed = B1800;
276     break;
277 stargo 545 #endif
278     #ifdef B2400
279 astrand 580 case 2400:
280     speed = B2400;
281     break;
282 stargo 545 #endif
283     #ifdef B4800
284 astrand 580 case 4800:
285     speed = B4800;
286     break;
287 stargo 545 #endif
288     #ifdef B9600
289 astrand 580 case 9600:
290     speed = B9600;
291     break;
292 stargo 545 #endif
293     #ifdef B19200
294 astrand 580 case 19200:
295     speed = B19200;
296     break;
297 stargo 545 #endif
298     #ifdef B38400
299 astrand 580 case 38400:
300     speed = B38400;
301     break;
302 stargo 545 #endif
303     #ifdef B57600
304 astrand 580 case 57600:
305     speed = B57600;
306     break;
307 stargo 545 #endif
308     #ifdef B115200
309 astrand 580 case 115200:
310     speed = B115200;
311     break;
312 stargo 545 #endif
313 astrand 580 default:
314     speed = B0;
315     break;
316 matthewc 432 }
317    
318     /* on systems with separate ispeed and ospeed, we can remember the speed
319     in ispeed while changing DTR with ospeed */
320 n-ki 588 cfsetispeed(pser_inf->ptermios, speed);
321     cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0);
322 matthewc 432
323 n-ki 622 ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS);
324 n-ki 588 switch (pser_inf->stop_bits)
325 matthewc 432 {
326     case STOP_BITS_2:
327 n-ki 588 ptermios->c_cflag |= CSTOPB;
328 matthewc 432 break;
329     }
330 n-ki 622
331 n-ki 588 switch (pser_inf->parity)
332 matthewc 432 {
333     case EVEN_PARITY:
334 n-ki 588 ptermios->c_cflag |= PARENB;
335 matthewc 432 break;
336     case ODD_PARITY:
337 n-ki 588 ptermios->c_cflag |= PARENB | PARODD;
338 matthewc 432 break;
339     }
340 n-ki 622
341 n-ki 588 switch (pser_inf->word_length)
342 matthewc 432 {
343 astrand 435 case 5:
344 n-ki 588 ptermios->c_cflag |= CS5;
345 astrand 435 break;
346     case 6:
347 n-ki 588 ptermios->c_cflag |= CS6;
348 astrand 435 break;
349     case 7:
350 n-ki 588 ptermios->c_cflag |= CS7;
351 astrand 435 break;
352     default:
353 n-ki 588 ptermios->c_cflag |= CS8;
354 astrand 435 break;
355 matthewc 432 }
356    
357 n-ki 622 if (pser_inf->rts)
358     ptermios->c_cflag |= CRTSCTS;
359    
360 n-ki 588 tcsetattr(serial_fd, TCSANOW, ptermios);
361 matthewc 432 }
362    
363 n-ki 569 /* Enumeration of devices from rdesktop.c */
364     /* returns numer of units found and initialized. */
365     /* optarg looks like ':com1=/dev/ttyS0' */
366     /* when it arrives to this function. */
367 n-ki 578 /* :com1=/dev/ttyS0,com2=/dev/ttyS1 */
368 n-ki 569 int
369 astrand 608 serial_enum_devices(uint32 * id, char *optarg)
370 matthewc 432 {
371 astrand 580 SERIAL_DEVICE *pser_inf;
372 matthewc 432
373 n-ki 578 char *pos = optarg;
374     char *pos2;
375     int count = 0;
376 matthewc 432
377 n-ki 578 // skip the first colon
378     optarg++;
379     while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)
380     {
381 n-ki 569 // Init data structures for device
382     pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE));
383     pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios));
384 stargo 755 memset(pser_inf->ptermios, 0, sizeof(struct termios));
385 n-ki 569 pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios));
386 stargo 755 memset(pser_inf->pold_termios, 0, sizeof(struct termios));
387 n-ki 569
388 n-ki 578 pos2 = next_arg(optarg, '=');
389     strcpy(g_rdpdr_device[*id].name, optarg);
390 n-ki 569
391 n-ki 578 toupper_str(g_rdpdr_device[*id].name);
392 n-ki 569
393 n-ki 578 g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);
394     strcpy(g_rdpdr_device[*id].local_path, pos2);
395 astrand 580 printf("SERIAL %s to %s\n", g_rdpdr_device[*id].name,
396     g_rdpdr_device[*id].local_path);
397 n-ki 569 // set device type
398     g_rdpdr_device[*id].device_type = DEVICE_TYPE_SERIAL;
399     g_rdpdr_device[*id].pdevice_data = (void *) pser_inf;
400 n-ki 578 count++;
401 n-ki 569 (*id)++;
402    
403 n-ki 578 optarg = pos;
404 n-ki 569 }
405 n-ki 578 return count;
406 matthewc 432 }
407    
408 astrand 665 static NTSTATUS
409 astrand 580 serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,
410 jsorg71 776 uint32 flags_and_attributes, char *filename, NTHANDLE * handle)
411 n-ki 569 {
412 jsorg71 776 NTHANDLE serial_fd;
413 astrand 580 SERIAL_DEVICE *pser_inf;
414     struct termios *ptermios;
415 n-ki 569
416 astrand 580 pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data;
417     ptermios = pser_inf->ptermios;
418 stargo 755 serial_fd = open(g_rdpdr_device[device_id].local_path, O_RDWR | O_NOCTTY | O_NONBLOCK);
419 n-ki 569
420 astrand 580 if (serial_fd == -1)
421 n-ki 588 {
422     perror("open");
423 astrand 580 return STATUS_ACCESS_DENIED;
424 n-ki 588 }
425 n-ki 569
426 astrand 580 if (!get_termios(pser_inf, serial_fd))
427 n-ki 622 {
428     printf("INFO: SERIAL %s access denied\n", g_rdpdr_device[device_id].name);
429     fflush(stdout);
430 astrand 580 return STATUS_ACCESS_DENIED;
431 n-ki 622 }
432 n-ki 569
433 n-ki 578 // Store handle for later use
434 astrand 580 g_rdpdr_device[device_id].handle = serial_fd;
435 n-ki 569
436 n-ki 578 /* some sane information */
437 n-ki 622 printf("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);
438    
439 astrand 580 printf("INFO: use stty to change settings\n");
440 n-ki 569
441 n-ki 588 /* ptermios->c_cflag = B115200 | CRTSCTS | CS8 | CLOCAL | CREAD;
442     ptermios->c_cflag |= CREAD;
443     ptermios->c_lflag |= ICANON;
444     ptermios->c_iflag = IGNPAR | ICRNL;
445 n-ki 569
446 n-ki 588 tcsetattr(serial_fd, TCSANOW, ptermios);
447     */
448 stargo 759 pser_inf->ptermios->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
449     pser_inf->ptermios->c_oflag &= ~OPOST;
450     pser_inf->ptermios->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
451     pser_inf->ptermios->c_cflag &= ~(CSIZE|PARENB);
452     pser_inf->ptermios->c_cflag |= CS8;
453     tcsetattr(serial_fd, TCSANOW, pser_inf->ptermios);
454 n-ki 592
455 astrand 580 *handle = serial_fd;
456 n-ki 592
457     /* all read and writes should be non blocking */
458     if (fcntl(*handle, F_SETFL, O_NONBLOCK) == -1)
459     perror("fcntl");
460    
461 astrand 580 return STATUS_SUCCESS;
462 n-ki 569 }
463    
464 matthewc 432 static NTSTATUS
465 jsorg71 776 serial_close(NTHANDLE handle)
466 matthewc 432 {
467 n-ki 622 int i = get_device_index(handle);
468     if (i >= 0)
469     g_rdpdr_device[i].handle = 0;
470 n-ki 588 close(handle);
471 matthewc 432 return STATUS_SUCCESS;
472     }
473    
474 astrand 665 static NTSTATUS
475 jsorg71 776 serial_read(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
476 matthewc 432 {
477 astrand 580 long timeout;
478     SERIAL_DEVICE *pser_inf;
479     struct termios *ptermios;
480 n-ki 569
481 n-ki 592 timeout = 90;
482 astrand 580 pser_inf = get_serial_info(handle);
483     ptermios = pser_inf->ptermios;
484 n-ki 569
485 astrand 580 // Set timeouts kind of like the windows serial timeout parameters. Multiply timeout
486     // with requested read size
487     if (pser_inf->read_total_timeout_multiplier | pser_inf->read_total_timeout_constant)
488     {
489     timeout =
490     (pser_inf->read_total_timeout_multiplier * length +
491     pser_inf->read_total_timeout_constant + 99) / 100;
492     }
493     else if (pser_inf->read_interval_timeout)
494     {
495     timeout = (pser_inf->read_interval_timeout * length + 99) / 100;
496     }
497 n-ki 569
498 astrand 580 // If a timeout is set, do a blocking read, which times out after some time.
499     // It will make rdesktop less responsive, but it will improve serial performance, by not
500     // reading one character at a time.
501     if (timeout == 0)
502     {
503     ptermios->c_cc[VTIME] = 0;
504     ptermios->c_cc[VMIN] = 0;
505     }
506     else
507     {
508     ptermios->c_cc[VTIME] = timeout;
509     ptermios->c_cc[VMIN] = 1;
510     }
511     tcsetattr(handle, TCSANOW, ptermios);
512 n-ki 592
513    
514 astrand 580 *result = read(handle, data, length);
515 n-ki 592
516 n-ki 622 //hexdump(data, *read);
517    
518 astrand 580 return STATUS_SUCCESS;
519 matthewc 432 }
520    
521 astrand 665 static NTSTATUS
522 jsorg71 776 serial_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
523 matthewc 432 {
524 astrand 580 *result = write(handle, data, length);
525     return STATUS_SUCCESS;
526 matthewc 432 }
527    
528     static NTSTATUS
529 jsorg71 776 serial_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
530 matthewc 432 {
531 astrand 669 #if 0
532 n-ki 622 int flush_mask, purge_mask;
533 astrand 669 #endif
534 stargo 757 uint32 result, modemstate;
535 matthewc 432 uint8 immediate;
536 n-ki 588 SERIAL_DEVICE *pser_inf;
537     struct termios *ptermios;
538 matthewc 432
539     if ((request >> 16) != FILE_DEVICE_SERIAL_PORT)
540     return STATUS_INVALID_PARAMETER;
541    
542 n-ki 588 pser_inf = get_serial_info(handle);
543     ptermios = pser_inf->ptermios;
544    
545 matthewc 432 /* extract operation */
546     request >>= 2;
547     request &= 0xfff;
548    
549     printf("SERIAL IOCTL %d\n", request);
550    
551     switch (request)
552     {
553     case SERIAL_SET_BAUD_RATE:
554 n-ki 588 in_uint32_le(in, pser_inf->baud_rate);
555     set_termios(pser_inf, handle);
556 matthewc 432 break;
557     case SERIAL_GET_BAUD_RATE:
558 n-ki 588 out_uint32_le(out, pser_inf->baud_rate);
559 matthewc 432 break;
560     case SERIAL_SET_QUEUE_SIZE:
561 n-ki 588 in_uint32_le(in, pser_inf->queue_in_size);
562     in_uint32_le(in, pser_inf->queue_out_size);
563 matthewc 432 break;
564     case SERIAL_SET_LINE_CONTROL:
565 n-ki 588 in_uint8(in, pser_inf->stop_bits);
566     in_uint8(in, pser_inf->parity);
567     in_uint8(in, pser_inf->word_length);
568     set_termios(pser_inf, handle);
569 matthewc 432 break;
570     case SERIAL_GET_LINE_CONTROL:
571 n-ki 588 out_uint8(out, pser_inf->stop_bits);
572     out_uint8(out, pser_inf->parity);
573     out_uint8(out, pser_inf->word_length);
574 matthewc 432 break;
575     case SERIAL_IMMEDIATE_CHAR:
576     in_uint8(in, immediate);
577 n-ki 569 serial_write(handle, &immediate, 1, 0, &result);
578 matthewc 432 break;
579     case SERIAL_CONFIG_SIZE:
580     out_uint32_le(out, 0);
581     break;
582     case SERIAL_GET_CHARS:
583     out_uint8s(out, 6);
584     break;
585     case SERIAL_SET_CHARS:
586     in_uint8s(in, 6);
587     break;
588     case SERIAL_GET_HANDFLOW:
589     out_uint32_le(out, 0);
590 astrand 435 out_uint32_le(out, 3); /* Xon/Xoff */
591 matthewc 432 out_uint32_le(out, 0);
592     out_uint32_le(out, 0);
593     break;
594     case SERIAL_SET_HANDFLOW:
595     in_uint8s(in, 16);
596     break;
597     case SERIAL_SET_TIMEOUTS:
598     in_uint8s(in, 20);
599     break;
600     case SERIAL_GET_TIMEOUTS:
601     out_uint8s(out, 20);
602     break;
603     case SERIAL_GET_WAIT_MASK:
604 n-ki 588 out_uint32(out, pser_inf->wait_mask);
605 matthewc 432 break;
606     case SERIAL_SET_WAIT_MASK:
607 n-ki 588 in_uint32(in, pser_inf->wait_mask);
608 matthewc 432 break;
609     case SERIAL_SET_DTR:
610 n-ki 588 pser_inf->dtr = 1;
611     set_termios(pser_inf, handle);
612 matthewc 432 break;
613     case SERIAL_CLR_DTR:
614 n-ki 588 pser_inf->dtr = 0;
615     set_termios(pser_inf, handle);
616 matthewc 432 break;
617 n-ki 622 case SERIAL_SET_RTS:
618     pser_inf->rts = 1;
619     set_termios(pser_inf, handle);
620 matthewc 432 break;
621 n-ki 622 case SERIAL_CLR_RTS:
622     pser_inf->rts = 0;
623     set_termios(pser_inf, handle);
624 matthewc 432 break;
625 n-ki 622 case SERIAL_GET_MODEMSTATUS:
626 stargo 757 modemstate = 0;
627     #ifdef TIOCMGET
628     ioctl(handle, TIOCMGET, &result);
629     if (result & TIOCM_CTS)
630     modemstate |= SERIAL_MS_CTS;
631     if (result & TIOCM_DSR)
632     modemstate |= SERIAL_MS_DSR;
633     if (result & TIOCM_RNG)
634     modemstate |= SERIAL_MS_RNG;
635     if (result & TIOCM_CAR)
636     modemstate |= SERIAL_MS_CAR;
637     #endif
638     out_uint32_le(out, modemstate);
639 n-ki 622 break;
640     case SERIAL_GET_COMMSTATUS:
641     out_uint32_le(out, 0); /* Errors */
642     out_uint32_le(out, 0); /* Hold reasons */
643     out_uint32_le(out, 0); /* Amount in in queue */
644     out_uint32_le(out, 0); /* Amount in out queue */
645     out_uint8(out, 0); /* EofReceived */
646     out_uint8(out, 0); /* WaitForImmediate */
647     break;
648     #if 0
649 matthewc 432 case SERIAL_PURGE:
650 astrand 580 printf("SERIAL_PURGE\n");
651     in_uint32(in, purge_mask);
652     if (purge_mask & 0x04)
653     flush_mask |= TCOFLUSH;
654     if (purge_mask & 0x08)
655     flush_mask |= TCIFLUSH;
656     if (flush_mask != 0)
657     tcflush(handle, flush_mask);
658     if (purge_mask & 0x01)
659     rdpdr_abort_io(handle, 4, STATUS_CANCELLED);
660     if (purge_mask & 0x02)
661     rdpdr_abort_io(handle, 3, STATUS_CANCELLED);
662     break;
663 n-ki 622 case SERIAL_WAIT_ON_MASK:
664     /* XXX implement me */
665     out_uint32_le(out, pser_inf->wait_mask);
666     break;
667     case SERIAL_SET_BREAK_ON:
668     tcsendbreak(serial_fd, 0);
669     break;
670 matthewc 432 case SERIAL_RESET_DEVICE:
671     case SERIAL_SET_BREAK_OFF:
672     case SERIAL_SET_XOFF:
673     case SERIAL_SET_XON:
674     /* ignore */
675     break;
676     #endif
677     default:
678     unimpl("SERIAL IOCTL %d\n", request);
679     return STATUS_INVALID_PARAMETER;
680     }
681    
682     return STATUS_SUCCESS;
683     }
684    
685 n-ki 569 /* Read timeout for a given file descripter (device) when adding fd's to select() */
686     BOOL
687 jsorg71 776 serial_get_timeout(NTHANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout)
688 n-ki 569 {
689 astrand 580 int index;
690     SERIAL_DEVICE *pser_inf;
691 n-ki 569
692 astrand 580 index = get_device_index(handle);
693 n-ki 622 if (index < 0)
694     return True;
695 n-ki 569
696 astrand 580 if (g_rdpdr_device[index].device_type != DEVICE_TYPE_SERIAL)
697     {
698     return False;
699     }
700 n-ki 569
701 astrand 580 pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;
702 n-ki 569
703 astrand 580 *timeout =
704     pser_inf->read_total_timeout_multiplier * length +
705     pser_inf->read_total_timeout_constant;
706     *itv_timeout = pser_inf->read_interval_timeout;
707     return True;
708 n-ki 569 }
709    
710 astrand 435 DEVICE_FNS serial_fns = {
711 matthewc 432 serial_create,
712     serial_close,
713     serial_read,
714     serial_write,
715     serial_device_control
716     };

  ViewVC Help
Powered by ViewVC 1.1.26