/[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

Diff of /sourceforge.net/trunk/rdesktop/serial.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.432  
changed lines
  Added in v.686

  ViewVC Help
Powered by ViewVC 1.1.26