/[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 669 by astrand, Sun Apr 18 19:16:51 2004 UTC revision 798 by stargo, Sat Nov 6 15:29:38 2004 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 73  Line 91 
91  #define SERIAL_EV_EVENT1           0x0800       // Provider specific event 1  #define SERIAL_EV_EVENT1           0x0800       // Provider specific event 1
92  #define SERIAL_EV_EVENT2           0x1000       // Provider specific event 2  #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    #ifndef TIOCINQ
125    #define TIOCINQ FIONREAD
126    #endif
127    
128  extern RDPDR_DEVICE g_rdpdr_device[];  extern RDPDR_DEVICE g_rdpdr_device[];
129    
130  static SERIAL_DEVICE *  static SERIAL_DEVICE *
131  get_serial_info(HANDLE handle)  get_serial_info(NTHANDLE handle)
132  {  {
133          int index;          int index;
134    
# Line 90  get_serial_info(HANDLE handle) Line 141  get_serial_info(HANDLE handle)
141  }  }
142    
143  static BOOL  static BOOL
144  get_termios(SERIAL_DEVICE * pser_inf, HANDLE serial_fd)  get_termios(SERIAL_DEVICE * pser_inf, NTHANDLE serial_fd)
145  {  {
146          speed_t speed;          speed_t speed;
147          struct termios *ptermios;          struct termios *ptermios;
# Line 178  get_termios(SERIAL_DEVICE * pser_inf, HA Line 229  get_termios(SERIAL_DEVICE * pser_inf, HA
229                          pser_inf->baud_rate = 115200;                          pser_inf->baud_rate = 115200;
230                          break;                          break;
231  #endif  #endif
232    #ifdef B230400
233                    case B230400:
234                            pser_inf->baud_rate = 230400;
235                            break;
236    #endif
237    #ifdef B460800
238                    case B460800:
239                            pser_inf->baud_rate = 460800;
240                            break;
241    #endif
242                  default:                  default:
243                          pser_inf->baud_rate = 0;                          pser_inf->baud_rate = 9600;
244                          break;                          break;
245          }          }
246    
# Line 207  get_termios(SERIAL_DEVICE * pser_inf, HA Line 268  get_termios(SERIAL_DEVICE * pser_inf, HA
268                          break;                          break;
269          }          }
270    
271          pser_inf->rts = (ptermios->c_cflag & CRTSCTS) ? 1 : 0;          if (ptermios->c_cflag & CRTSCTS)
272            {
273                    pser_inf->control = SERIAL_DTR_CONTROL | SERIAL_CTS_HANDSHAKE | SERIAL_ERROR_ABORT;
274            }
275            else
276            {
277                    pser_inf->control = SERIAL_DTR_CONTROL | SERIAL_ERROR_ABORT;
278            }
279    
280            pser_inf->xonoff = SERIAL_DSR_SENSITIVITY;
281            if (ptermios->c_iflag & IXON)
282                    pser_inf->xonoff |= SERIAL_XON_HANDSHAKE;
283    
284            if (ptermios->c_iflag & IXOFF)
285                    pser_inf->xonoff |= SERIAL_XOFF_HANDSHAKE;
286    
287            pser_inf->chars[SERIAL_CHAR_XON] = ptermios->c_cc[VSTART];
288            pser_inf->chars[SERIAL_CHAR_XOFF] = ptermios->c_cc[VSTOP];
289            pser_inf->chars[SERIAL_CHAR_EOF] = ptermios->c_cc[VEOF];
290            pser_inf->chars[SERIAL_CHAR_BREAK] = ptermios->c_cc[VINTR];
291            pser_inf->chars[SERIAL_CHAR_ERROR] = ptermios->c_cc[VKILL];
292    
293          return True;          return True;
294  }  }
295    
296  static void  static void
297  set_termios(SERIAL_DEVICE * pser_inf, HANDLE serial_fd)  set_termios(SERIAL_DEVICE * pser_inf, NTHANDLE serial_fd)
298  {  {
299          speed_t speed;          speed_t speed;
300    
# Line 299  set_termios(SERIAL_DEVICE * pser_inf, HA Line 380  set_termios(SERIAL_DEVICE * pser_inf, HA
380                          speed = B115200;                          speed = B115200;
381                          break;                          break;
382  #endif  #endif
383    #ifdef B230400
384                    case 230400:
385                            speed = B115200;
386                            break;
387    #endif
388    #ifdef B460800
389                    case 460800:
390                            speed = B115200;
391                            break;
392    #endif
393                  default:                  default:
394                          speed = B0;                          speed = B9600;
395                          break;                          break;
396          }          }
397    
398    #if 0
399          /* on systems with separate ispeed and ospeed, we can remember the speed          /* on systems with separate ispeed and ospeed, we can remember the speed
400             in ispeed while changing DTR with ospeed */             in ispeed while changing DTR with ospeed */
401          cfsetispeed(pser_inf->ptermios, speed);          cfsetispeed(pser_inf->ptermios, speed);
402          cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0);          cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0);
403    #endif
404    
405            ptermios->c_cflag &= ~CBAUD;
406            ptermios->c_cflag |= speed;
407    
408          ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS);          ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS);
409          switch (pser_inf->stop_bits)          switch (pser_inf->stop_bits)
# Line 315  set_termios(SERIAL_DEVICE * pser_inf, HA Line 411  set_termios(SERIAL_DEVICE * pser_inf, HA
411                  case STOP_BITS_2:                  case STOP_BITS_2:
412                          ptermios->c_cflag |= CSTOPB;                          ptermios->c_cflag |= CSTOPB;
413                          break;                          break;
414                    default:
415                            ptermios->c_cflag &= ~CSTOPB;
416                            break;
417          }          }
418    
419          switch (pser_inf->parity)          switch (pser_inf->parity)
# Line 325  set_termios(SERIAL_DEVICE * pser_inf, HA Line 424  set_termios(SERIAL_DEVICE * pser_inf, HA
424                  case ODD_PARITY:                  case ODD_PARITY:
425                          ptermios->c_cflag |= PARENB | PARODD;                          ptermios->c_cflag |= PARENB | PARODD;
426                          break;                          break;
427                    case NO_PARITY:
428                            ptermios->c_cflag &= ~(PARENB | PARODD);
429                            break;
430          }          }
431    
432          switch (pser_inf->word_length)          switch (pser_inf->word_length)
# Line 343  set_termios(SERIAL_DEVICE * pser_inf, HA Line 445  set_termios(SERIAL_DEVICE * pser_inf, HA
445                          break;                          break;
446          }          }
447    
448    #if 0
449          if (pser_inf->rts)          if (pser_inf->rts)
450                  ptermios->c_cflag |= CRTSCTS;                  ptermios->c_cflag |= CRTSCTS;
451            else
452                    ptermios->c_cflag &= ~CRTSCTS;
453    #endif
454    
455            if (pser_inf->control & SERIAL_CTS_HANDSHAKE)
456            {
457                    ptermios->c_cflag |= CRTSCTS;
458            }
459            else
460            {
461                    ptermios->c_cflag &= ~CRTSCTS;
462            }
463    
464    
465            if (pser_inf->xonoff & SERIAL_XON_HANDSHAKE)
466            {
467                    ptermios->c_iflag |= IXON | IMAXBEL;
468            }
469            if (pser_inf->xonoff & SERIAL_XOFF_HANDSHAKE)
470            {
471                    ptermios->c_iflag |= IXOFF | IMAXBEL;
472            }
473    
474            if ((pser_inf->xonoff & (SERIAL_XOFF_HANDSHAKE | SERIAL_XON_HANDSHAKE)) == 0)
475            {
476                    ptermios->c_iflag &= ~IXON;
477                    ptermios->c_iflag &= ~IXOFF;
478            }
479    
480            ptermios->c_cc[VSTART] = pser_inf->chars[SERIAL_CHAR_XON];
481            ptermios->c_cc[VSTOP] = pser_inf->chars[SERIAL_CHAR_XOFF];
482            ptermios->c_cc[VEOF] = pser_inf->chars[SERIAL_CHAR_EOF];
483            ptermios->c_cc[VINTR] = pser_inf->chars[SERIAL_CHAR_BREAK];
484            ptermios->c_cc[VKILL] = pser_inf->chars[SERIAL_CHAR_ERROR];
485    
486          tcsetattr(serial_fd, TCSANOW, ptermios);          tcsetattr(serial_fd, TCSANOW, ptermios);
487  }  }
# Line 370  serial_enum_devices(uint32 * id, char *o Line 507  serial_enum_devices(uint32 * id, char *o
507                  // Init data structures for device                  // Init data structures for device
508                  pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE));                  pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE));
509                  pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios));                  pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios));
510                    memset(pser_inf->ptermios, 0, sizeof(struct termios));
511                  pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios));                  pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios));
512                    memset(pser_inf->pold_termios, 0, sizeof(struct termios));
513    
514                  pos2 = next_arg(optarg, '=');                  pos2 = next_arg(optarg, '=');
515                  strcpy(g_rdpdr_device[*id].name, optarg);                  strcpy(g_rdpdr_device[*id].name, optarg);
# Line 394  serial_enum_devices(uint32 * id, char *o Line 533  serial_enum_devices(uint32 * id, char *o
533    
534  static NTSTATUS  static NTSTATUS
535  serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,  serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,
536                uint32 flags_and_attributes, char *filename, HANDLE * handle)                uint32 flags_and_attributes, char *filename, NTHANDLE * handle)
537  {  {
538          HANDLE serial_fd;          NTHANDLE serial_fd;
539          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;
540          struct termios *ptermios;          struct termios *ptermios;
541    
542          pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data;          pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data;
543          ptermios = pser_inf->ptermios;          ptermios = pser_inf->ptermios;
544          serial_fd = open(g_rdpdr_device[device_id].local_path, O_RDWR | O_NOCTTY);          serial_fd = open(g_rdpdr_device[device_id].local_path, O_RDWR | O_NOCTTY | O_NONBLOCK);
545    
546          if (serial_fd == -1)          if (serial_fd == -1)
547          {          {
# Line 421  serial_create(uint32 device_id, uint32 a Line 560  serial_create(uint32 device_id, uint32 a
560          g_rdpdr_device[device_id].handle = serial_fd;          g_rdpdr_device[device_id].handle = serial_fd;
561    
562          /* some sane information */          /* some sane information */
563          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");  
564    
565  /*      ptermios->c_cflag = B115200 | CRTSCTS | CS8 | CLOCAL | CREAD;          pser_inf->ptermios->c_iflag &=
566          ptermios->c_cflag |= CREAD;                  ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
567          ptermios->c_lflag |= ICANON;          pser_inf->ptermios->c_oflag &= ~OPOST;
568          ptermios->c_iflag = IGNPAR | ICRNL;          pser_inf->ptermios->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN | XCASE);
569            pser_inf->ptermios->c_cflag &= ~(CSIZE | PARENB);
570          tcsetattr(serial_fd, TCSANOW, ptermios);          pser_inf->ptermios->c_cflag |= CS8;
571  */  
572            tcsetattr(serial_fd, TCSANOW, pser_inf->ptermios);
573    
574            pser_inf->event_txempty = 0;
575            pser_inf->event_cts = 0;
576            pser_inf->event_dsr = 0;
577            pser_inf->event_rlsd = 0;
578            pser_inf->event_pending = 0;
579    
580          *handle = serial_fd;          *handle = serial_fd;
581    
# Line 439  serial_create(uint32 device_id, uint32 a Line 583  serial_create(uint32 device_id, uint32 a
583          if (fcntl(*handle, F_SETFL, O_NONBLOCK) == -1)          if (fcntl(*handle, F_SETFL, O_NONBLOCK) == -1)
584                  perror("fcntl");                  perror("fcntl");
585    
586            pser_inf->read_total_timeout_constant = 5;
587    
588          return STATUS_SUCCESS;          return STATUS_SUCCESS;
589  }  }
590    
591  static NTSTATUS  static NTSTATUS
592  serial_close(HANDLE handle)  serial_close(NTHANDLE handle)
593  {  {
594          int i = get_device_index(handle);          int i = get_device_index(handle);
595          if (i >= 0)          if (i >= 0)
596                  g_rdpdr_device[i].handle = 0;                  g_rdpdr_device[i].handle = 0;
597    
598            rdpdr_abort_io(handle, 0, STATUS_TIMEOUT);
599          close(handle);          close(handle);
600          return STATUS_SUCCESS;          return STATUS_SUCCESS;
601  }  }
602    
603  static NTSTATUS  static NTSTATUS
604  serial_read(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  serial_read(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
605  {  {
606          long timeout;          long timeout;
607          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;
608          struct termios *ptermios;          struct termios *ptermios;
609    #ifdef WITH_DEBUG_SERIAL
610            int bytes_inqueue;
611    #endif
612    
613    
614          timeout = 90;          timeout = 90;
615          pser_inf = get_serial_info(handle);          pser_inf = get_serial_info(handle);
# Line 491  serial_read(HANDLE handle, uint8 * data, Line 643  serial_read(HANDLE handle, uint8 * data,
643          }          }
644          tcsetattr(handle, TCSANOW, ptermios);          tcsetattr(handle, TCSANOW, ptermios);
645    
646    #ifdef WITH_DEBUG_SERIAL
647            ioctl(handle, TIOCINQ, &bytes_inqueue);
648            DEBUG_SERIAL(("serial_read inqueue: %d expected %d\n", bytes_inqueue, length));
649    #endif
650    
651          *result = read(handle, data, length);          *result = read(handle, data, length);
652    
653          //hexdump(data, *read);  #ifdef WITH_DEBUG_SERIAL
654            DEBUG_SERIAL(("serial_read Bytes %d\n", *result));
655            if (*result > 0)
656                    hexdump(data, *result);
657    #endif
658    
659          return STATUS_SUCCESS;          return STATUS_SUCCESS;
660  }  }
661    
662  static NTSTATUS  static NTSTATUS
663  serial_write(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  serial_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
664  {  {
665            SERIAL_DEVICE *pser_inf;
666    
667            pser_inf = get_serial_info(handle);
668    
669          *result = write(handle, data, length);          *result = write(handle, data, length);
670    
671            if (*result > 0)
672                    pser_inf->event_txempty = *result;
673    
674            DEBUG_SERIAL(("serial_write length %d, offset %d result %d\n", length, offset, *result));
675    
676          return STATUS_SUCCESS;          return STATUS_SUCCESS;
677  }  }
678    
679  static NTSTATUS  static NTSTATUS
680  serial_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out)  serial_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
681  {  {
 #if 0  
682          int flush_mask, purge_mask;          int flush_mask, purge_mask;
683  #endif          uint32 result, modemstate;
         uint32 result;  
684          uint8 immediate;          uint8 immediate;
685          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;
686          struct termios *ptermios;          struct termios *ptermios;
# Line 527  serial_device_control(HANDLE handle, uin Line 695  serial_device_control(HANDLE handle, uin
695          request >>= 2;          request >>= 2;
696          request &= 0xfff;          request &= 0xfff;
697    
         printf("SERIAL IOCTL %d\n", request);  
   
698          switch (request)          switch (request)
699          {          {
700                  case SERIAL_SET_BAUD_RATE:                  case SERIAL_SET_BAUD_RATE:
701                          in_uint32_le(in, pser_inf->baud_rate);                          in_uint32_le(in, pser_inf->baud_rate);
702                          set_termios(pser_inf, handle);                          set_termios(pser_inf, handle);
703                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BAUD_RATE %d\n", pser_inf->baud_rate));
704                          break;                          break;
705                  case SERIAL_GET_BAUD_RATE:                  case SERIAL_GET_BAUD_RATE:
706                          out_uint32_le(out, pser_inf->baud_rate);                          out_uint32_le(out, pser_inf->baud_rate);
707                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_BAUD_RATE %d\n", pser_inf->baud_rate));
708                          break;                          break;
709                  case SERIAL_SET_QUEUE_SIZE:                  case SERIAL_SET_QUEUE_SIZE:
710                          in_uint32_le(in, pser_inf->queue_in_size);                          in_uint32_le(in, pser_inf->queue_in_size);
711                          in_uint32_le(in, pser_inf->queue_out_size);                          in_uint32_le(in, pser_inf->queue_out_size);
712                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_QUEUE_SIZE in %d out %d\n",
713                                pser_inf->queue_in_size, pser_inf->queue_out_size));
714                          break;                          break;
715                  case SERIAL_SET_LINE_CONTROL:                  case SERIAL_SET_LINE_CONTROL:
716                          in_uint8(in, pser_inf->stop_bits);                          in_uint8(in, pser_inf->stop_bits);
717                          in_uint8(in, pser_inf->parity);                          in_uint8(in, pser_inf->parity);
718                          in_uint8(in, pser_inf->word_length);                          in_uint8(in, pser_inf->word_length);
719                          set_termios(pser_inf, handle);                          set_termios(pser_inf, handle);
720                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_LINE_CONTROL stop %d parity %d word %d\n",
721                                pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length));
722                          break;                          break;
723                  case SERIAL_GET_LINE_CONTROL:                  case SERIAL_GET_LINE_CONTROL:
724                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_LINE_CONTROL\n"));
725                          out_uint8(out, pser_inf->stop_bits);                          out_uint8(out, pser_inf->stop_bits);
726                          out_uint8(out, pser_inf->parity);                          out_uint8(out, pser_inf->parity);
727                          out_uint8(out, pser_inf->word_length);                          out_uint8(out, pser_inf->word_length);
728                          break;                          break;
729                  case SERIAL_IMMEDIATE_CHAR:                  case SERIAL_IMMEDIATE_CHAR:
730                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_IMMEDIATE_CHAR\n"));
731                          in_uint8(in, immediate);                          in_uint8(in, immediate);
732                          serial_write(handle, &immediate, 1, 0, &result);                          serial_write(handle, &immediate, 1, 0, &result);
733                          break;                          break;
734                  case SERIAL_CONFIG_SIZE:                  case SERIAL_CONFIG_SIZE:
735                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_CONFIG_SIZE\n"));
736                          out_uint32_le(out, 0);                          out_uint32_le(out, 0);
737                          break;                          break;
738                  case SERIAL_GET_CHARS:                  case SERIAL_GET_CHARS:
739                          out_uint8s(out, 6);                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_CHARS\n"));
740                            out_uint8a(out, pser_inf->chars, 6);
741                          break;                          break;
742                  case SERIAL_SET_CHARS:                  case SERIAL_SET_CHARS:
743                          in_uint8s(in, 6);                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_CHARS\n"));
744                            in_uint8a(in, pser_inf->chars, 6);
745    #ifdef WITH_DEBUG_SERIAL
746                            hexdump(pser_inf->chars, 6);
747    #endif
748                            set_termios(pser_inf, handle);
749                          break;                          break;
750                  case SERIAL_GET_HANDFLOW:                  case SERIAL_GET_HANDFLOW:
751                          out_uint32_le(out, 0);                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_HANDFLOW\n"));
752                          out_uint32_le(out, 3);  /* Xon/Xoff */                          get_termios(pser_inf, handle);
753                          out_uint32_le(out, 0);                          out_uint32_le(out, pser_inf->control);
754                          out_uint32_le(out, 0);                          out_uint32_le(out, pser_inf->xonoff);   /* Xon/Xoff */
755                            out_uint32_le(out, pser_inf->onlimit);
756                            out_uint32_le(out, pser_inf->offlimit);
757                          break;                          break;
758                  case SERIAL_SET_HANDFLOW:                  case SERIAL_SET_HANDFLOW:
759                          in_uint8s(in, 16);                          in_uint32_le(in, pser_inf->control);
760                            in_uint32_le(in, pser_inf->xonoff);
761                            in_uint32_le(in, pser_inf->onlimit);
762                            in_uint32_le(in, pser_inf->offlimit);
763                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_HANDFLOW %x %x %x %x\n",
764                                pser_inf->control, pser_inf->xonoff, pser_inf->onlimit,
765                                pser_inf->onlimit));
766                            set_termios(pser_inf, handle);
767                          break;                          break;
768                  case SERIAL_SET_TIMEOUTS:                  case SERIAL_SET_TIMEOUTS:
769                          in_uint8s(in, 20);                          in_uint32(in, pser_inf->read_interval_timeout);
770                            in_uint32(in, pser_inf->read_total_timeout_multiplier);
771                            in_uint32(in, pser_inf->read_total_timeout_constant);
772                            in_uint32(in, pser_inf->write_total_timeout_multiplier);
773                            in_uint32(in, pser_inf->write_total_timeout_constant);
774                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_TIMEOUTS read timeout %d %d %d\n",
775                                pser_inf->read_interval_timeout,
776                                pser_inf->read_total_timeout_multiplier,
777                                pser_inf->read_total_timeout_constant));
778                          break;                          break;
779                  case SERIAL_GET_TIMEOUTS:                  case SERIAL_GET_TIMEOUTS:
780                          out_uint8s(out, 20);                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_TIMEOUTS read timeout %d %d %d\n",
781                                pser_inf->read_interval_timeout,
782                                pser_inf->read_total_timeout_multiplier,
783                                pser_inf->read_total_timeout_constant));
784    
785                            out_uint32(out, pser_inf->read_interval_timeout);
786                            out_uint32(out, pser_inf->read_total_timeout_multiplier);
787                            out_uint32(out, pser_inf->read_total_timeout_constant);
788                            out_uint32(out, pser_inf->write_total_timeout_multiplier);
789                            out_uint32(out, pser_inf->write_total_timeout_constant);
790                          break;                          break;
791                  case SERIAL_GET_WAIT_MASK:                  case SERIAL_GET_WAIT_MASK:
792                          out_uint32(out, pser_inf->wait_mask);                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_WAIT_MASK %X\n", pser_inf->wait_mask);
793                            out_uint32(out, pser_inf->wait_mask));
794                          break;                          break;
795                  case SERIAL_SET_WAIT_MASK:                  case SERIAL_SET_WAIT_MASK:
796                          in_uint32(in, pser_inf->wait_mask);                          in_uint32(in, pser_inf->wait_mask);
797                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_WAIT_MASK %X\n", pser_inf->wait_mask));
798                          break;                          break;
799                  case SERIAL_SET_DTR:                  case SERIAL_SET_DTR:
800                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_DTR\n"));
801                            ioctl(handle, TIOCMGET, &result);
802                            result |= TIOCM_DTR;
803                            ioctl(handle, TIOCMSET, &result);
804                          pser_inf->dtr = 1;                          pser_inf->dtr = 1;
                         set_termios(pser_inf, handle);  
805                          break;                          break;
806                  case SERIAL_CLR_DTR:                  case SERIAL_CLR_DTR:
807                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_CLR_DTR\n"));
808                            ioctl(handle, TIOCMGET, &result);
809                            result &= ~TIOCM_DTR;
810                            ioctl(handle, TIOCMSET, &result);
811                          pser_inf->dtr = 0;                          pser_inf->dtr = 0;
                         set_termios(pser_inf, handle);  
812                          break;                          break;
813                  case SERIAL_SET_RTS:                  case SERIAL_SET_RTS:
814                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_RTS\n"));
815                            ioctl(handle, TIOCMGET, &result);
816                            result |= TIOCM_RTS;
817                            ioctl(handle, TIOCMSET, &result);
818                          pser_inf->rts = 1;                          pser_inf->rts = 1;
                         set_termios(pser_inf, handle);  
819                          break;                          break;
820                  case SERIAL_CLR_RTS:                  case SERIAL_CLR_RTS:
821                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_CLR_RTS\n"));
822                            ioctl(handle, TIOCMGET, &result);
823                            result &= ~TIOCM_RTS;
824                            ioctl(handle, TIOCMSET, &result);
825                          pser_inf->rts = 0;                          pser_inf->rts = 0;
                         set_termios(pser_inf, handle);  
826                          break;                          break;
827                  case SERIAL_GET_MODEMSTATUS:                  case SERIAL_GET_MODEMSTATUS:
828                          out_uint32_le(out, 0);  /* Errors */                          modemstate = 0;
829    #ifdef TIOCMGET
830                            ioctl(handle, TIOCMGET, &result);
831                            if (result & TIOCM_CTS)
832                                    modemstate |= SERIAL_MS_CTS;
833                            if (result & TIOCM_DSR)
834                                    modemstate |= SERIAL_MS_DSR;
835                            if (result & TIOCM_RNG)
836                                    modemstate |= SERIAL_MS_RNG;
837                            if (result & TIOCM_CAR)
838                                    modemstate |= SERIAL_MS_CAR;
839                            if (result & TIOCM_DTR)
840                                    modemstate |= SERIAL_MS_DTR;
841                            if (result & TIOCM_RTS)
842                                    modemstate |= SERIAL_MS_RTS;
843    #endif
844                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_MODEMSTATUS %X\n", modemstate));
845                            out_uint32_le(out, modemstate);
846                          break;                          break;
847                  case SERIAL_GET_COMMSTATUS:                  case SERIAL_GET_COMMSTATUS:
848                          out_uint32_le(out, 0);  /* Errors */                          out_uint32_le(out, 0);  /* Errors */
849                          out_uint32_le(out, 0);  /* Hold reasons */                          out_uint32_le(out, 0);  /* Hold reasons */
850                          out_uint32_le(out, 0);  /* Amount in in queue */  
851                          out_uint32_le(out, 0);  /* Amount in out queue */                          result = 0;
852                            ioctl(handle, TIOCINQ, &result);
853                            out_uint32_le(out, result);     /* Amount in in queue */
854                            if (result)
855                                    DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_COMMSTATUS in queue %d\n", result));
856    
857                            result = 0;
858                            ioctl(handle, TIOCOUTQ, &result);
859                            out_uint32_le(out, result);     /* Amount in out queue */
860                            if (result)
861                                    DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_COMMSTATUS out queue %d\n", result));
862    
863                          out_uint8(out, 0);      /* EofReceived */                          out_uint8(out, 0);      /* EofReceived */
864                          out_uint8(out, 0);      /* WaitForImmediate */                          out_uint8(out, 0);      /* WaitForImmediate */
865                          break;                          break;
 #if 0  
866                  case SERIAL_PURGE:                  case SERIAL_PURGE:
                         printf("SERIAL_PURGE\n");  
867                          in_uint32(in, purge_mask);                          in_uint32(in, purge_mask);
868                          if (purge_mask & 0x04)                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_PURGE purge_mask %X\n", purge_mask));
869                            flush_mask = 0;
870                            if (purge_mask & SERIAL_PURGE_TXCLEAR)
871                                  flush_mask |= TCOFLUSH;                                  flush_mask |= TCOFLUSH;
872                          if (purge_mask & 0x08)                          if (purge_mask & SERIAL_PURGE_RXCLEAR)
873                                  flush_mask |= TCIFLUSH;                                  flush_mask |= TCIFLUSH;
874                          if (flush_mask != 0)                          if (flush_mask != 0)
875                                  tcflush(handle, flush_mask);                                  tcflush(handle, flush_mask);
876                          if (purge_mask & 0x01)                          if (purge_mask & SERIAL_PURGE_TXABORT)
877                                  rdpdr_abort_io(handle, 4, STATUS_CANCELLED);                                  rdpdr_abort_io(handle, 4, STATUS_CANCELLED);
878                          if (purge_mask & 0x02)                          if (purge_mask & SERIAL_PURGE_RXABORT)
879                                  rdpdr_abort_io(handle, 3, STATUS_CANCELLED);                                  rdpdr_abort_io(handle, 3, STATUS_CANCELLED);
880                          break;                          break;
881                  case SERIAL_WAIT_ON_MASK:                  case SERIAL_WAIT_ON_MASK:
882                          /* XXX implement me */                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_WAIT_ON_MASK %X\n", pser_inf->wait_mask));
883                          out_uint32_le(out, pser_inf->wait_mask);                          pser_inf->event_pending = 1;
884                            if (serial_get_event(handle, &result))
885                            {
886                                    DEBUG_SERIAL(("WAIT end  event = %x\n", result));
887                                    out_uint32_le(out, result);
888                                    break;
889                            }
890                            return STATUS_PENDING;
891                          break;                          break;
892                  case SERIAL_SET_BREAK_ON:                  case SERIAL_SET_BREAK_ON:
893                          tcsendbreak(serial_fd, 0);                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BREAK_ON\n"));
894                            tcsendbreak(handle, 0);
895                          break;                          break;
896                  case SERIAL_RESET_DEVICE:                  case SERIAL_RESET_DEVICE:
897                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_RESET_DEVICE\n"));
898                            break;
899                  case SERIAL_SET_BREAK_OFF:                  case SERIAL_SET_BREAK_OFF:
900                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BREAK_OFF\n"));
901                            break;
902                  case SERIAL_SET_XOFF:                  case SERIAL_SET_XOFF:
903                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_XOFF\n"));
904                            break;
905                  case SERIAL_SET_XON:                  case SERIAL_SET_XON:
906                          /* ignore */                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_XON\n"));
907                            tcflow(handle, TCION);
908                          break;                          break;
 #endif  
909                  default:                  default:
910                          unimpl("SERIAL IOCTL %d\n", request);                          unimpl("SERIAL IOCTL %d\n", request);
911                          return STATUS_INVALID_PARAMETER;                          return STATUS_INVALID_PARAMETER;
# Line 651  serial_device_control(HANDLE handle, uin Line 914  serial_device_control(HANDLE handle, uin
914          return STATUS_SUCCESS;          return STATUS_SUCCESS;
915  }  }
916    
917    BOOL
918    serial_get_event(NTHANDLE handle, uint32 * result)
919    {
920            int index;
921            SERIAL_DEVICE *pser_inf;
922            int bytes;
923            BOOL ret = False;
924    
925            *result = 0;
926            index = get_device_index(handle);
927            if (index < 0)
928                    return False;
929    
930            pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;
931    
932    
933            ioctl(handle, TIOCINQ, &bytes);
934    
935            if (bytes > 0)
936            {
937                    DEBUG_SERIAL(("serial_get_event Bytes %d\n", bytes));
938                    if (bytes > pser_inf->event_rlsd)
939                    {
940                            pser_inf->event_rlsd = bytes;
941                            if (pser_inf->wait_mask & SERIAL_EV_RLSD)
942                            {
943                                    DEBUG_SERIAL(("Event -> SERIAL_EV_RLSD \n"));
944                                    *result |= SERIAL_EV_RLSD;
945                                    ret = True;
946                            }
947    
948                    }
949    
950                    if ((bytes > 1) && (pser_inf->wait_mask & SERIAL_EV_RXFLAG))
951                    {
952                            DEBUG_SERIAL(("Event -> SERIAL_EV_RXFLAG Bytes %d\n", bytes));
953                            *result |= SERIAL_EV_RXFLAG;
954                            ret = True;
955                    }
956                    if ((pser_inf->wait_mask & SERIAL_EV_RXCHAR))
957                    {
958                            DEBUG_SERIAL(("Event -> SERIAL_EV_RXCHAR Bytes %d\n", bytes));
959                            *result |= SERIAL_EV_RXCHAR;
960                            ret = True;
961                    }
962    
963            }
964            else
965            {
966                    pser_inf->event_rlsd = 0;
967            }
968    
969    
970            ioctl(handle, TIOCOUTQ, &bytes);
971            if ((bytes == 0)
972                && (pser_inf->event_txempty > 0) && (pser_inf->wait_mask & SERIAL_EV_TXEMPTY))
973            {
974    
975                    DEBUG_SERIAL(("Event -> SERIAL_EV_TXEMPTY\n"));
976                    *result |= SERIAL_EV_TXEMPTY;
977                    ret = True;
978            }
979            pser_inf->event_txempty = bytes;
980    
981    
982            ioctl(handle, TIOCMGET, &bytes);
983            if ((bytes & TIOCM_DSR) != pser_inf->event_dsr)
984            {
985                    pser_inf->event_dsr = bytes & TIOCM_DSR;
986                    if (pser_inf->wait_mask & SERIAL_EV_DSR)
987                    {
988                            DEBUG_SERIAL(("event -> SERIAL_EV_DSR %s\n", (bytes & TIOCM_DSR) ? "ON" : "OFF"));
989                            *result |= SERIAL_EV_DSR;
990                            ret = True;
991                    }
992            }
993    
994            if ((bytes & TIOCM_CTS) != pser_inf->event_cts)
995            {
996                    pser_inf->event_cts = bytes & TIOCM_CTS;
997                    if (pser_inf->wait_mask & SERIAL_EV_CTS)
998                    {
999                            DEBUG_SERIAL((" EVENT-> SERIAL_EV_CTS %s\n", (bytes & TIOCM_CTS) ? "ON" : "OFF"));
1000                            *result |= SERIAL_EV_CTS;
1001                            ret = True;
1002                    }
1003            }
1004    
1005            if (ret)
1006                    pser_inf->event_pending = 0;
1007    
1008            return ret;
1009    }
1010    
1011  /* 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() */
1012  BOOL  BOOL
1013  serial_get_timeout(HANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout)  serial_get_timeout(NTHANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout)
1014  {  {
1015          int index;          int index;
1016          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;

Legend:
Removed from v.669  
changed lines
  Added in v.798

  ViewVC Help
Powered by ViewVC 1.1.26