/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/serial.c

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

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

Legend:
Removed from v.578  
changed lines
  Added in v.865

  ViewVC Help
Powered by ViewVC 1.1.26