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

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

  ViewVC Help
Powered by ViewVC 1.1.26