/[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 759 by stargo, Wed Aug 25 15:42:42 2004 UTC revision 809 by stargo, Mon Jan 10 21:54:47 2005 UTC
# Line 3  Line 3 
3  #include <termios.h>  #include <termios.h>
4  #include <strings.h>  #include <strings.h>
5  #include <sys/ioctl.h>  #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 75  Line 92 
92  #define SERIAL_EV_EVENT2           0x1000       // Provider specific event 2  #define SERIAL_EV_EVENT2           0x1000       // Provider specific event 2
93    
94  /* Modem Status */  /* Modem Status */
95    #define SERIAL_MS_DTR 0x01
96    #define SERIAL_MS_RTS 0x02
97  #define SERIAL_MS_CTS 0x10  #define SERIAL_MS_CTS 0x10
98  #define SERIAL_MS_DSR 0x20  #define SERIAL_MS_DSR 0x20
99  #define SERIAL_MS_RNG 0x40  #define SERIAL_MS_RNG 0x40
100  #define SERIAL_MS_CAR 0x80  #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  #ifndef CRTSCTS
119  #define CRTSCTS 0  #define CRTSCTS 0
120  #endif  #endif
121    
122    /* FIONREAD should really do the same thing as TIOCINQ, where it is
123     * not available */
124    #ifndef TIOCINQ
125    #define TIOCINQ FIONREAD
126    #endif
127    #ifndef TIOCOUTQ
128    #define TIOCOUTQ FIONWRITE
129    #endif
130    
131  extern RDPDR_DEVICE g_rdpdr_device[];  extern RDPDR_DEVICE g_rdpdr_device[];
132    
133  static SERIAL_DEVICE *  static SERIAL_DEVICE *
134  get_serial_info(HANDLE handle)  get_serial_info(NTHANDLE handle)
135  {  {
136          int index;          int index;
137    
# Line 101  get_serial_info(HANDLE handle) Line 144  get_serial_info(HANDLE handle)
144  }  }
145    
146  static 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;
# Line 189  get_termios(SERIAL_DEVICE * pser_inf, HA Line 232  get_termios(SERIAL_DEVICE * pser_inf, HA
232                          pser_inf->baud_rate = 115200;                          pser_inf->baud_rate = 115200;
233                          break;                          break;
234  #endif  #endif
235    #ifdef B230400
236                    case B230400:
237                            pser_inf->baud_rate = 230400;
238                            break;
239    #endif
240    #ifdef B460800
241                    case B460800:
242                            pser_inf->baud_rate = 460800;
243                            break;
244    #endif
245                  default:                  default:
246                          pser_inf->baud_rate = 0;                          pser_inf->baud_rate = 9600;
247                          break;                          break;
248          }          }
249    
# Line 218  get_termios(SERIAL_DEVICE * pser_inf, HA Line 271  get_termios(SERIAL_DEVICE * pser_inf, HA
271                          break;                          break;
272          }          }
273    
274          pser_inf->rts = (ptermios->c_cflag & CRTSCTS) ? 1 : 0;          if (ptermios->c_cflag & CRTSCTS)
275            {
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->xonoff = SERIAL_DSR_SENSITIVITY;
284            if (ptermios->c_iflag & IXON)
285                    pser_inf->xonoff |= SERIAL_XON_HANDSHAKE;
286    
287            if (ptermios->c_iflag & IXOFF)
288                    pser_inf->xonoff |= SERIAL_XOFF_HANDSHAKE;
289    
290            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(SERIAL_DEVICE * pser_inf, HANDLE serial_fd)  set_termios(SERIAL_DEVICE * pser_inf, NTHANDLE serial_fd)
301  {  {
302          speed_t speed;          speed_t speed;
303    
# Line 310  set_termios(SERIAL_DEVICE * pser_inf, HA Line 383  set_termios(SERIAL_DEVICE * pser_inf, HA
383                          speed = B115200;                          speed = B115200;
384                          break;                          break;
385  #endif  #endif
386    #ifdef B230400
387                    case 230400:
388                            speed = B115200;
389                            break;
390    #endif
391    #ifdef B460800
392                    case 460800:
393                            speed = B115200;
394                            break;
395    #endif
396                  default:                  default:
397                          speed = B0;                          speed = B9600;
398                          break;                          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(pser_inf->ptermios, speed);          cfsetispeed(pser_inf->ptermios, speed);
408          cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0);          cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0);
409    #endif
410    
411          ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS);          ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS);
412          switch (pser_inf->stop_bits)          switch (pser_inf->stop_bits)
# Line 326  set_termios(SERIAL_DEVICE * pser_inf, HA Line 414  set_termios(SERIAL_DEVICE * pser_inf, HA
414                  case STOP_BITS_2:                  case STOP_BITS_2:
415                          ptermios->c_cflag |= CSTOPB;                          ptermios->c_cflag |= CSTOPB;
416                          break;                          break;
417                    default:
418                            ptermios->c_cflag &= ~CSTOPB;
419                            break;
420          }          }
421    
422          switch (pser_inf->parity)          switch (pser_inf->parity)
# Line 336  set_termios(SERIAL_DEVICE * pser_inf, HA Line 427  set_termios(SERIAL_DEVICE * pser_inf, HA
427                  case ODD_PARITY:                  case ODD_PARITY:
428                          ptermios->c_cflag |= PARENB | PARODD;                          ptermios->c_cflag |= PARENB | PARODD;
429                          break;                          break;
430                    case NO_PARITY:
431                            ptermios->c_cflag &= ~(PARENB | PARODD);
432                            break;
433          }          }
434    
435          switch (pser_inf->word_length)          switch (pser_inf->word_length)
# Line 354  set_termios(SERIAL_DEVICE * pser_inf, HA Line 448  set_termios(SERIAL_DEVICE * pser_inf, HA
448                          break;                          break;
449          }          }
450    
451    #if 0
452          if (pser_inf->rts)          if (pser_inf->rts)
453                  ptermios->c_cflag |= CRTSCTS;                  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);          tcsetattr(serial_fd, TCSANOW, ptermios);
490  }  }
# Line 407  serial_enum_devices(uint32 * id, char *o Line 536  serial_enum_devices(uint32 * id, char *o
536    
537  static NTSTATUS  static NTSTATUS
538  serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,  serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,
539                uint32 flags_and_attributes, char *filename, HANDLE * handle)                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    
# Line 434  serial_create(uint32 device_id, uint32 a Line 563  serial_create(uint32 device_id, uint32 a
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, 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);          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));
   
         printf("INFO: use stty to change settings\n");  
   
 /*      ptermios->c_cflag = B115200 | CRTSCTS | CS8 | CLOCAL | CREAD;  
         ptermios->c_cflag |= CREAD;  
         ptermios->c_lflag |= ICANON;  
         ptermios->c_iflag = IGNPAR | ICRNL;  
567    
568          tcsetattr(serial_fd, TCSANOW, ptermios);          pser_inf->ptermios->c_iflag &=
569  */                  ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
         pser_inf->ptermios->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);  
570          pser_inf->ptermios->c_oflag &= ~OPOST;          pser_inf->ptermios->c_oflag &= ~OPOST;
571          pser_inf->ptermios->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);          pser_inf->ptermios->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
572          pser_inf->ptermios->c_cflag &= ~(CSIZE|PARENB);          pser_inf->ptermios->c_cflag &= ~(CSIZE | PARENB);
573          pser_inf->ptermios->c_cflag |= CS8;          pser_inf->ptermios->c_cflag |= CS8;
574    
575          tcsetattr(serial_fd, TCSANOW, pser_inf->ptermios);          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;          *handle = serial_fd;
584    
585          /* all read and writes should be non blocking */          /* all read and writes should be non blocking */
586          if (fcntl(*handle, F_SETFL, O_NONBLOCK) == -1)          if (fcntl(*handle, F_SETFL, O_NONBLOCK) == -1)
587                  perror("fcntl");                  perror("fcntl");
588    
589            pser_inf->read_total_timeout_constant = 5;
590    
591          return STATUS_SUCCESS;          return STATUS_SUCCESS;
592  }  }
593    
594  static NTSTATUS  static NTSTATUS
595  serial_close(HANDLE handle)  serial_close(NTHANDLE handle)
596  {  {
597          int i = get_device_index(handle);          int i = get_device_index(handle);
598          if (i >= 0)          if (i >= 0)
599                  g_rdpdr_device[i].handle = 0;                  g_rdpdr_device[i].handle = 0;
600    
601            rdpdr_abort_io(handle, 0, STATUS_TIMEOUT);
602          close(handle);          close(handle);
603          return STATUS_SUCCESS;          return STATUS_SUCCESS;
604  }  }
605    
606  static 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            int bytes_inqueue;
614    #endif
615    
616    
617          timeout = 90;          timeout = 90;
618          pser_inf = get_serial_info(handle);          pser_inf = get_serial_info(handle);
# Line 510  serial_read(HANDLE handle, uint8 * data, Line 646  serial_read(HANDLE handle, uint8 * data,
646          }          }
647          tcsetattr(handle, TCSANOW, ptermios);          tcsetattr(handle, TCSANOW, ptermios);
648    
649    #ifdef WITH_DEBUG_SERIAL
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);          *result = read(handle, data, length);
655    
656          //hexdump(data, *read);  #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;          return STATUS_SUCCESS;
663  }  }
664    
665  static 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            SERIAL_DEVICE *pser_inf;
669    
670            pser_inf = get_serial_info(handle);
671    
672          *result = write(handle, data, length);          *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;          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  {  {
 #if 0  
685          int flush_mask, purge_mask;          int flush_mask, purge_mask;
 #endif  
686          uint32 result, modemstate;          uint32 result, modemstate;
687          uint8 immediate;          uint8 immediate;
688          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;
# Line 546  serial_device_control(HANDLE handle, uin Line 698  serial_device_control(HANDLE handle, uin
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, pser_inf->baud_rate);                          in_uint32_le(in, pser_inf->baud_rate);
705                          set_termios(pser_inf, handle);                          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, pser_inf->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, pser_inf->queue_in_size);                          in_uint32_le(in, pser_inf->queue_in_size);
716                          in_uint32_le(in, pser_inf->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, pser_inf->stop_bits);                          in_uint8(in, pser_inf->stop_bits);
722                          in_uint8(in, pser_inf->parity);                          in_uint8(in, pser_inf->parity);
723                          in_uint8(in, pser_inf->word_length);                          in_uint8(in, pser_inf->word_length);
724                          set_termios(pser_inf, handle);                          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                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_LINE_CONTROL\n"));
729                          out_uint8(out, pser_inf->stop_bits);                          out_uint8(out, pser_inf->stop_bits);
730                          out_uint8(out, pser_inf->parity);                          out_uint8(out, pser_inf->parity);
731                          out_uint8(out, pser_inf->word_length);                          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, pser_inf->wait_mask);                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_WAIT_MASK %X\n",
797                                          pser_inf->wait_mask); out_uint32(out, pser_inf->wait_mask));
798                          break;                          break;
799                  case SERIAL_SET_WAIT_MASK:                  case SERIAL_SET_WAIT_MASK:
800                          in_uint32(in, pser_inf->wait_mask);                          in_uint32(in, pser_inf->wait_mask);
801                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_WAIT_MASK %X\n",
802                                          pser_inf->wait_mask));
803                          break;                          break;
804                  case SERIAL_SET_DTR:                  case SERIAL_SET_DTR:
805                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_DTR\n"));
806                            ioctl(handle, TIOCMGET, &result);
807                            result |= TIOCM_DTR;
808                            ioctl(handle, TIOCMSET, &result);
809                          pser_inf->dtr = 1;                          pser_inf->dtr = 1;
                         set_termios(pser_inf, handle);  
810                          break;                          break;
811                  case SERIAL_CLR_DTR:                  case SERIAL_CLR_DTR:
812                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_CLR_DTR\n"));
813                            ioctl(handle, TIOCMGET, &result);
814                            result &= ~TIOCM_DTR;
815                            ioctl(handle, TIOCMSET, &result);
816                          pser_inf->dtr = 0;                          pser_inf->dtr = 0;
                         set_termios(pser_inf, handle);  
817                          break;                          break;
818                  case SERIAL_SET_RTS:                  case SERIAL_SET_RTS:
819                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_RTS\n"));
820                            ioctl(handle, TIOCMGET, &result);
821                            result |= TIOCM_RTS;
822                            ioctl(handle, TIOCMSET, &result);
823                          pser_inf->rts = 1;                          pser_inf->rts = 1;
                         set_termios(pser_inf, handle);  
824                          break;                          break;
825                  case SERIAL_CLR_RTS:                  case SERIAL_CLR_RTS:
826                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_CLR_RTS\n"));
827                            ioctl(handle, TIOCMGET, &result);
828                            result &= ~TIOCM_RTS;
829                            ioctl(handle, TIOCMSET, &result);
830                          pser_inf->rts = 0;                          pser_inf->rts = 0;
                         set_termios(pser_inf, handle);  
831                          break;                          break;
832                  case SERIAL_GET_MODEMSTATUS:                  case SERIAL_GET_MODEMSTATUS:
833                          modemstate = 0;                          modemstate = 0;
# Line 634  serial_device_control(HANDLE handle, uin Line 841  serial_device_control(HANDLE handle, uin
841                                  modemstate |= SERIAL_MS_RNG;                                  modemstate |= SERIAL_MS_RNG;
842                          if (result & TIOCM_CAR)                          if (result & TIOCM_CAR)
843                                  modemstate |= SERIAL_MS_CAR;                                  modemstate |= SERIAL_MS_CAR;
844                            if (result & TIOCM_DTR)
845                                    modemstate |= SERIAL_MS_DTR;
846                            if (result & TIOCM_RTS)
847                                    modemstate |= SERIAL_MS_RTS;
848  #endif  #endif
849                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_MODEMSTATUS %X\n", modemstate));
850                          out_uint32_le(out, modemstate);                          out_uint32_le(out, modemstate);
851                          break;                          break;
852                  case SERIAL_GET_COMMSTATUS:                  case SERIAL_GET_COMMSTATUS:
853                          out_uint32_le(out, 0);  /* Errors */                          out_uint32_le(out, 0);  /* Errors */
854                          out_uint32_le(out, 0);  /* Hold reasons */                          out_uint32_le(out, 0);  /* Hold reasons */
855                          out_uint32_le(out, 0);  /* Amount in in queue */  
856                          out_uint32_le(out, 0);  /* Amount in out queue */                          result = 0;
857                            ioctl(handle, TIOCINQ, &result);
858                            out_uint32_le(out, result);     /* Amount in in queue */
859                            if (result)
860                                    DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_COMMSTATUS in queue %d\n",
861                                                  result));
862    
863                            result = 0;
864                            ioctl(handle, TIOCOUTQ, &result);
865                            out_uint32_le(out, result);     /* Amount in out queue */
866                            if (result)
867                                    DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_COMMSTATUS out queue %d\n", result));
868    
869                          out_uint8(out, 0);      /* EofReceived */                          out_uint8(out, 0);      /* EofReceived */
870                          out_uint8(out, 0);      /* WaitForImmediate */                          out_uint8(out, 0);      /* WaitForImmediate */
871                          break;                          break;
 #if 0  
872                  case SERIAL_PURGE:                  case SERIAL_PURGE:
                         printf("SERIAL_PURGE\n");  
873                          in_uint32(in, purge_mask);                          in_uint32(in, purge_mask);
874                          if (purge_mask & 0x04)                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_PURGE purge_mask %X\n", purge_mask));
875                            flush_mask = 0;
876                            if (purge_mask & SERIAL_PURGE_TXCLEAR)
877                                  flush_mask |= TCOFLUSH;                                  flush_mask |= TCOFLUSH;
878                          if (purge_mask & 0x08)                          if (purge_mask & SERIAL_PURGE_RXCLEAR)
879                                  flush_mask |= TCIFLUSH;                                  flush_mask |= TCIFLUSH;
880                          if (flush_mask != 0)                          if (flush_mask != 0)
881                                  tcflush(handle, flush_mask);                                  tcflush(handle, flush_mask);
882                          if (purge_mask & 0x01)                          if (purge_mask & SERIAL_PURGE_TXABORT)
883                                  rdpdr_abort_io(handle, 4, STATUS_CANCELLED);                                  rdpdr_abort_io(handle, 4, STATUS_CANCELLED);
884                          if (purge_mask & 0x02)                          if (purge_mask & SERIAL_PURGE_RXABORT)
885                                  rdpdr_abort_io(handle, 3, STATUS_CANCELLED);                                  rdpdr_abort_io(handle, 3, STATUS_CANCELLED);
886                          break;                          break;
887                  case SERIAL_WAIT_ON_MASK:                  case SERIAL_WAIT_ON_MASK:
888                          /* XXX implement me */                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_WAIT_ON_MASK %X\n",
889                          out_uint32_le(out, pser_inf->wait_mask);                                        pser_inf->wait_mask));
890                            pser_inf->event_pending = 1;
891                            if (serial_get_event(handle, &result))
892                            {
893                                    DEBUG_SERIAL(("WAIT end  event = %x\n", result));
894                                    out_uint32_le(out, result);
895                                    break;
896                            }
897                            return STATUS_PENDING;
898                          break;                          break;
899                  case SERIAL_SET_BREAK_ON:                  case SERIAL_SET_BREAK_ON:
900                          tcsendbreak(serial_fd, 0);                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BREAK_ON\n"));
901                            tcsendbreak(handle, 0);
902                          break;                          break;
903                  case SERIAL_RESET_DEVICE:                  case SERIAL_RESET_DEVICE:
904                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_RESET_DEVICE\n"));
905                            break;
906                  case SERIAL_SET_BREAK_OFF:                  case SERIAL_SET_BREAK_OFF:
907                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BREAK_OFF\n"));
908                            break;
909                  case SERIAL_SET_XOFF:                  case SERIAL_SET_XOFF:
910                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_XOFF\n"));
911                            break;
912                  case SERIAL_SET_XON:                  case SERIAL_SET_XON:
913                          /* ignore */                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_XON\n"));
914                            tcflow(handle, TCION);
915                          break;                          break;
 #endif  
916                  default:                  default:
917                          unimpl("SERIAL IOCTL %d\n", request);                          unimpl("SERIAL IOCTL %d\n", request);
918                          return STATUS_INVALID_PARAMETER;                          return STATUS_INVALID_PARAMETER;
# Line 682  serial_device_control(HANDLE handle, uin Line 921  serial_device_control(HANDLE handle, uin
921          return STATUS_SUCCESS;          return STATUS_SUCCESS;
922  }  }
923    
924    BOOL
925    serial_get_event(NTHANDLE handle, uint32 * result)
926    {
927            int index;
928            SERIAL_DEVICE *pser_inf;
929            int bytes;
930            BOOL ret = False;
931    
932            *result = 0;
933            index = get_device_index(handle);
934            if (index < 0)
935                    return False;
936    
937            pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;
938    
939    
940            ioctl(handle, TIOCINQ, &bytes);
941    
942            if (bytes > 0)
943            {
944                    DEBUG_SERIAL(("serial_get_event Bytes %d\n", bytes));
945                    if (bytes > pser_inf->event_rlsd)
946                    {
947                            pser_inf->event_rlsd = bytes;
948                            if (pser_inf->wait_mask & SERIAL_EV_RLSD)
949                            {
950                                    DEBUG_SERIAL(("Event -> SERIAL_EV_RLSD \n"));
951                                    *result |= SERIAL_EV_RLSD;
952                                    ret = True;
953                            }
954    
955                    }
956    
957                    if ((bytes > 1) && (pser_inf->wait_mask & SERIAL_EV_RXFLAG))
958                    {
959                            DEBUG_SERIAL(("Event -> SERIAL_EV_RXFLAG Bytes %d\n", bytes));
960                            *result |= SERIAL_EV_RXFLAG;
961                            ret = True;
962                    }
963                    if ((pser_inf->wait_mask & SERIAL_EV_RXCHAR))
964                    {
965                            DEBUG_SERIAL(("Event -> SERIAL_EV_RXCHAR Bytes %d\n", bytes));
966                            *result |= SERIAL_EV_RXCHAR;
967                            ret = True;
968                    }
969    
970            }
971            else
972            {
973                    pser_inf->event_rlsd = 0;
974            }
975    
976    
977            ioctl(handle, TIOCOUTQ, &bytes);
978            if ((bytes == 0)
979                && (pser_inf->event_txempty > 0) && (pser_inf->wait_mask & SERIAL_EV_TXEMPTY))
980            {
981    
982                    DEBUG_SERIAL(("Event -> SERIAL_EV_TXEMPTY\n"));
983                    *result |= SERIAL_EV_TXEMPTY;
984                    ret = True;
985            }
986            pser_inf->event_txempty = bytes;
987    
988    
989            ioctl(handle, TIOCMGET, &bytes);
990            if ((bytes & TIOCM_DSR) != pser_inf->event_dsr)
991            {
992                    pser_inf->event_dsr = bytes & TIOCM_DSR;
993                    if (pser_inf->wait_mask & SERIAL_EV_DSR)
994                    {
995                            DEBUG_SERIAL(("event -> SERIAL_EV_DSR %s\n",
996                                          (bytes & TIOCM_DSR) ? "ON" : "OFF"));
997                            *result |= SERIAL_EV_DSR;
998                            ret = True;
999                    }
1000            }
1001    
1002            if ((bytes & TIOCM_CTS) != pser_inf->event_cts)
1003            {
1004                    pser_inf->event_cts = bytes & TIOCM_CTS;
1005                    if (pser_inf->wait_mask & SERIAL_EV_CTS)
1006                    {
1007                            DEBUG_SERIAL((" EVENT-> SERIAL_EV_CTS %s\n",
1008                                          (bytes & TIOCM_CTS) ? "ON" : "OFF"));
1009                            *result |= SERIAL_EV_CTS;
1010                            ret = True;
1011                    }
1012            }
1013    
1014            if (ret)
1015                    pser_inf->event_pending = 0;
1016    
1017            return ret;
1018    }
1019    
1020  /* 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() */
1021  BOOL  BOOL
1022  serial_get_timeout(HANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout)  serial_get_timeout(NTHANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout)
1023  {  {
1024          int index;          int index;
1025          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;

Legend:
Removed from v.759  
changed lines
  Added in v.809

  ViewVC Help
Powered by ViewVC 1.1.26