/[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 580 by astrand, Fri Jan 23 08:35:52 2004 UTC revision 795 by stargo, Wed Nov 3 13:56:52 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  #include "rdesktop.h"  #include "rdesktop.h"
7    
8    #ifdef WITH_DEBUG_SERIAL
9    #define DEBUG_SERIAL(args) printf args;
10    #else
11    #define DEBUG_SERIAL(args)
12    #endif
13    
14  #define FILE_DEVICE_SERIAL_PORT         0x1b  #define FILE_DEVICE_SERIAL_PORT         0x1b
15    
16  #define SERIAL_SET_BAUD_RATE            1  #define SERIAL_SET_BAUD_RATE            1
# Line 53  Line 60 
60  #define ODD_PARITY                      1  #define ODD_PARITY                      1
61  #define EVEN_PARITY                     2  #define EVEN_PARITY                     2
62    
63  extern RDPDR_DEVICE g_rdpdr_device[];  #define SERIAL_PURGE_TXABORT 0x00000001
64    #define SERIAL_PURGE_RXABORT 0x00000002
65  int serial_fd;  #define SERIAL_PURGE_TXCLEAR 0x00000004
66  struct termios termios;  #define SERIAL_PURGE_RXCLEAR 0x00000008
67    
68    /* SERIAL_WAIT_ON_MASK */
69    #define SERIAL_EV_RXCHAR           0x0001       // Any Character received
70    #define SERIAL_EV_RXFLAG           0x0002       // Received certain character
71    #define SERIAL_EV_TXEMPTY          0x0004       // Transmitt Queue Empty
72    #define SERIAL_EV_CTS              0x0008       // CTS changed state
73    #define SERIAL_EV_DSR              0x0010       // DSR changed state
74    #define SERIAL_EV_RLSD             0x0020       // RLSD changed state
75    #define SERIAL_EV_BREAK            0x0040       // BREAK received
76    #define SERIAL_EV_ERR              0x0080       // Line status error occurred
77    #define SERIAL_EV_RING             0x0100       // Ring signal detected
78    #define SERIAL_EV_PERR             0x0200       // Printer error occured
79    #define SERIAL_EV_RX80FULL         0x0400       // Receive buffer is 80 percent full
80    #define SERIAL_EV_EVENT1           0x0800       // Provider specific event 1
81    #define SERIAL_EV_EVENT2           0x1000       // Provider specific event 2
82    
83    /* Modem Status */
84    #define SERIAL_MS_DTR 0x01
85    #define SERIAL_MS_RTS 0x02
86    #define SERIAL_MS_CTS 0x10
87    #define SERIAL_MS_DSR 0x20
88    #define SERIAL_MS_RNG 0x40
89    #define SERIAL_MS_CAR 0x80
90    
91    /* Handflow */
92    #define SERIAL_DTR_CONTROL      0x01
93    #define SERIAL_CTS_HANDSHAKE    0x08
94    #define SERIAL_ERROR_ABORT      0x80000000
95    
96    #define SERIAL_XON_HANDSHAKE    0x01
97    #define SERIAL_XOFF_HANDSHAKE   0x02
98    #define SERIAL_DSR_SENSITIVITY  0x40
99    
100    #define SERIAL_CHAR_EOF         0
101    #define SERIAL_CHAR_ERROR       1
102    #define SERIAL_CHAR_BREAK       2
103    #define SERIAL_CHAR_EVENT       3
104    #define SERIAL_CHAR_XON         4
105    #define SERIAL_CHAR_XOFF        5
106    
107    #ifndef CRTSCTS
108    #define CRTSCTS 0
109    #endif
110    
111    /* FIONREAD should really do the same thing as TIOCINQ, where it is
112     * not available */
113    #ifndef TIOCINQ
114    #include <sys/filio.h>
115    #define TIOCINQ FIONREAD
116    #endif
117    
118  int dtr;  extern RDPDR_DEVICE g_rdpdr_device[];
 uint32 baud_rate;  
 uint32 queue_in_size, queue_out_size;  
 uint32 wait_mask;  
 uint8 stop_bits, parity, word_length;  
119    
120  SERIAL_DEVICE * get_serial_info(HANDLE handle)  static SERIAL_DEVICE *
121    get_serial_info(NTHANDLE handle)
122  {  {
123          int index;          int index;
124    
# Line 76  SERIAL_DEVICE * get_serial_info(HANDLE h Line 130  SERIAL_DEVICE * get_serial_info(HANDLE h
130          return NULL;          return NULL;
131  }  }
132    
133  BOOL  static BOOL
134  get_termios(SERIAL_DEVICE * pser_inf, HANDLE serial_fd)  get_termios(SERIAL_DEVICE * pser_inf, NTHANDLE serial_fd)
135  {  {
136          speed_t speed;          speed_t speed;
137          struct termios *ptermios;          struct termios *ptermios;
# Line 165  get_termios(SERIAL_DEVICE * pser_inf, HA Line 219  get_termios(SERIAL_DEVICE * pser_inf, HA
219                          pser_inf->baud_rate = 115200;                          pser_inf->baud_rate = 115200;
220                          break;                          break;
221  #endif  #endif
222    #ifdef B230400
223                    case B230400:
224                            pser_inf->baud_rate = 230400;
225                            break;
226    #endif
227    #ifdef B460800
228                    case B460800:
229                            pser_inf->baud_rate = 460800;
230                            break;
231    #endif
232                  default:                  default:
233                          pser_inf->baud_rate = 0;                          pser_inf->baud_rate = 9600;
234                          break;                          break;
235          }          }
236    
# Line 194  get_termios(SERIAL_DEVICE * pser_inf, HA Line 258  get_termios(SERIAL_DEVICE * pser_inf, HA
258                          break;                          break;
259          }          }
260    
261            if (ptermios->c_cflag & CRTSCTS)
262            {
263                    pser_inf->control = SERIAL_DTR_CONTROL | SERIAL_CTS_HANDSHAKE | SERIAL_ERROR_ABORT;
264            }
265            else
266            {
267                    pser_inf->control = SERIAL_DTR_CONTROL | SERIAL_ERROR_ABORT;
268            }
269    
270            pser_inf->xonoff = SERIAL_DSR_SENSITIVITY;
271            if (ptermios->c_iflag & IXON)
272                    pser_inf->xonoff |= SERIAL_XON_HANDSHAKE;
273    
274            if (ptermios->c_iflag & IXOFF)
275                    pser_inf->xonoff |= SERIAL_XOFF_HANDSHAKE;
276    
277            pser_inf->chars[SERIAL_CHAR_XON] = ptermios->c_cc[VSTART];
278            pser_inf->chars[SERIAL_CHAR_XOFF] = ptermios->c_cc[VSTOP];
279            pser_inf->chars[SERIAL_CHAR_EOF] = ptermios->c_cc[VEOF];
280            pser_inf->chars[SERIAL_CHAR_BREAK] = ptermios->c_cc[VINTR];
281            pser_inf->chars[SERIAL_CHAR_ERROR] = ptermios->c_cc[VKILL];
282    
283          return True;          return True;
284  }  }
285    
286  static void  static void
287  set_termios(void)  set_termios(SERIAL_DEVICE * pser_inf, NTHANDLE serial_fd)
288  {  {
289          speed_t speed;          speed_t speed;
290    
291          switch (baud_rate)          struct termios *ptermios;
292    
293            ptermios = pser_inf->ptermios;
294    
295    
296            switch (pser_inf->baud_rate)
297          {          {
298  #ifdef B75  #ifdef B75
299                  case 75:                  case 75:
# Line 279  set_termios(void) Line 370  set_termios(void)
370                          speed = B115200;                          speed = B115200;
371                          break;                          break;
372  #endif  #endif
373    #ifdef B230400
374                    case 230400:
375                            speed = B115200;
376                            break;
377    #endif
378    #ifdef B460800
379                    case 460800:
380                            speed = B115200;
381                            break;
382    #endif
383                  default:                  default:
384                          speed = B0;                          speed = B9600;
385                          break;                          break;
386          }          }
387    
388    #if 0
389          /* on systems with separate ispeed and ospeed, we can remember the speed          /* on systems with separate ispeed and ospeed, we can remember the speed
390             in ispeed while changing DTR with ospeed */             in ispeed while changing DTR with ospeed */
391          cfsetispeed(&termios, speed);          cfsetispeed(pser_inf->ptermios, speed);
392          cfsetospeed(&termios, dtr ? speed : 0);          cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0);
393    #endif
394    
395          termios.c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE);          ptermios->c_cflag &= ~CBAUD;
396          switch (stop_bits)          ptermios->c_cflag |= speed;
397    
398            ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS);
399            switch (pser_inf->stop_bits)
400          {          {
401                  case STOP_BITS_2:                  case STOP_BITS_2:
402                          termios.c_cflag |= CSTOPB;                          ptermios->c_cflag |= CSTOPB;
403                            break;
404                    default:
405                            ptermios->c_cflag &= ~CSTOPB;
406                          break;                          break;
407          }          }
408          switch (parity)  
409            switch (pser_inf->parity)
410          {          {
411                  case EVEN_PARITY:                  case EVEN_PARITY:
412                          termios.c_cflag |= PARENB;                          ptermios->c_cflag |= PARENB;
413                          break;                          break;
414                  case ODD_PARITY:                  case ODD_PARITY:
415                          termios.c_cflag |= PARENB | PARODD;                          ptermios->c_cflag |= PARENB | PARODD;
416                            break;
417                    case NO_PARITY:
418                            ptermios->c_cflag &= ~(PARENB | PARODD);
419                          break;                          break;
420          }          }
421          switch (word_length)  
422            switch (pser_inf->word_length)
423          {          {
424                  case 5:                  case 5:
425                          termios.c_cflag |= CS5;                          ptermios->c_cflag |= CS5;
426                          break;                          break;
427                  case 6:                  case 6:
428                          termios.c_cflag |= CS6;                          ptermios->c_cflag |= CS6;
429                          break;                          break;
430                  case 7:                  case 7:
431                          termios.c_cflag |= CS7;                          ptermios->c_cflag |= CS7;
432                          break;                          break;
433                  default:                  default:
434                          termios.c_cflag |= CS8;                          ptermios->c_cflag |= CS8;
435                          break;                          break;
436          }          }
437    
438          tcsetattr(serial_fd, TCSANOW, &termios);  #if 0
439            if (pser_inf->rts)
440                    ptermios->c_cflag |= CRTSCTS;
441            else
442                    ptermios->c_cflag &= ~CRTSCTS;
443    #endif
444    
445            if (pser_inf->control & SERIAL_CTS_HANDSHAKE)
446            {
447                    ptermios->c_cflag |= CRTSCTS;
448            }
449            else
450            {
451                    ptermios->c_cflag &= ~CRTSCTS;
452            }
453    
454    
455            if (pser_inf->xonoff & SERIAL_XON_HANDSHAKE)
456            {
457                    ptermios->c_iflag |= IXON | IMAXBEL;
458            }
459            if (pser_inf->xonoff & SERIAL_XOFF_HANDSHAKE)
460            {
461                    ptermios->c_iflag |= IXOFF | IMAXBEL;
462            }
463    
464            if ((pser_inf->xonoff & (SERIAL_XOFF_HANDSHAKE | SERIAL_XON_HANDSHAKE)) == 0)
465            {
466                    ptermios->c_iflag &= ~IXON;
467                    ptermios->c_iflag &= ~IXOFF;
468            }
469    
470            ptermios->c_cc[VSTART] = pser_inf->chars[SERIAL_CHAR_XON];
471            ptermios->c_cc[VSTOP] = pser_inf->chars[SERIAL_CHAR_XOFF];
472            ptermios->c_cc[VEOF] = pser_inf->chars[SERIAL_CHAR_EOF];
473            ptermios->c_cc[VINTR] = pser_inf->chars[SERIAL_CHAR_BREAK];
474            ptermios->c_cc[VKILL] = pser_inf->chars[SERIAL_CHAR_ERROR];
475    
476            tcsetattr(serial_fd, TCSANOW, ptermios);
477  }  }
478    
479  /* Enumeration of devices from rdesktop.c        */  /* Enumeration of devices from rdesktop.c        */
# Line 330  set_termios(void) Line 482  set_termios(void)
482  /* when it arrives to this function.              */  /* when it arrives to this function.              */
483  /* :com1=/dev/ttyS0,com2=/dev/ttyS1 */  /* :com1=/dev/ttyS0,com2=/dev/ttyS1 */
484  int  int
485  serial_enum_devices(int *id, char *optarg)  serial_enum_devices(uint32 * id, char *optarg)
486  {  {
487          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;
488    
# Line 345  serial_enum_devices(int *id, char *optar Line 497  serial_enum_devices(int *id, char *optar
497                  // Init data structures for device                  // Init data structures for device
498                  pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE));                  pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE));
499                  pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios));                  pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios));
500                    memset(pser_inf->ptermios, 0, sizeof(struct termios));
501                  pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios));                  pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios));
502                    memset(pser_inf->pold_termios, 0, sizeof(struct termios));
503    
504                  pos2 = next_arg(optarg, '=');                  pos2 = next_arg(optarg, '=');
505                  strcpy(g_rdpdr_device[*id].name, optarg);                  strcpy(g_rdpdr_device[*id].name, optarg);
# Line 367  serial_enum_devices(int *id, char *optar Line 521  serial_enum_devices(int *id, char *optar
521          return count;          return count;
522  }  }
523    
524  NTSTATUS  static NTSTATUS
525  serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,  serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,
526                uint32 flags_and_attributes, char *filename, HANDLE * handle)                uint32 flags_and_attributes, char *filename, NTHANDLE * handle)
527  {  {
528          HANDLE serial_fd;          NTHANDLE serial_fd;
529          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;
530          struct termios *ptermios;          struct termios *ptermios;
531    
532          pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data;          pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data;
533          ptermios = pser_inf->ptermios;          ptermios = pser_inf->ptermios;
534          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);
535    
536          if (serial_fd == -1)          if (serial_fd == -1)
537            {
538                    perror("open");
539                  return STATUS_ACCESS_DENIED;                  return STATUS_ACCESS_DENIED;
540            }
541    
542          if (!get_termios(pser_inf, serial_fd))          if (!get_termios(pser_inf, serial_fd))
543            {
544                    printf("INFO: SERIAL %s access denied\n", g_rdpdr_device[device_id].name);
545                    fflush(stdout);
546                  return STATUS_ACCESS_DENIED;                  return STATUS_ACCESS_DENIED;
547            }
548    
549          // Store handle for later use          // Store handle for later use
550          g_rdpdr_device[device_id].handle = serial_fd;          g_rdpdr_device[device_id].handle = serial_fd;
551    
552          /* some sane information */          /* some sane information */
553          printf("INFO: SERIAL %s to %s\nINFO: speed %u baud, stop bits %u, parity %u, word length %u bits, dtr %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);          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");  
554    
555          //tcgetattr(serial_fd, pser_inf->ptermios);          pser_inf->ptermios->c_iflag &=
556                    ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
557            pser_inf->ptermios->c_oflag &= ~OPOST;
558            pser_inf->ptermios->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN | XCASE);
559            pser_inf->ptermios->c_cflag &= ~(CSIZE | PARENB);
560            pser_inf->ptermios->c_cflag |= CS8;
561    
562            tcsetattr(serial_fd, TCSANOW, pser_inf->ptermios);
563    
564            pser_inf->event_txempty = 0;
565            pser_inf->event_cts = 0;
566            pser_inf->event_dsr = 0;
567            pser_inf->event_rlsd = 0;
568            pser_inf->event_pending = 0;
569    
570          *handle = serial_fd;          *handle = serial_fd;
571    
572            /* all read and writes should be non blocking */
573            if (fcntl(*handle, F_SETFL, O_NONBLOCK) == -1)
574                    perror("fcntl");
575    
576            pser_inf->read_total_timeout_constant = 5;
577    
578          return STATUS_SUCCESS;          return STATUS_SUCCESS;
579  }  }
580    
581  static NTSTATUS  static NTSTATUS
582  serial_close(HANDLE handle)  serial_close(NTHANDLE handle)
583  {  {
584          close(serial_fd);          int i = get_device_index(handle);
585            if (i >= 0)
586                    g_rdpdr_device[i].handle = 0;
587    
588            rdpdr_abort_io(handle, 0, STATUS_TIMEOUT);
589            close(handle);
590          return STATUS_SUCCESS;          return STATUS_SUCCESS;
591  }  }
592    
593  NTSTATUS  static NTSTATUS
594  serial_read(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  serial_read(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
595  {  {
596          long timeout;          long timeout;
597          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;
598          struct termios *ptermios;          struct termios *ptermios;
599    #ifdef WITH_DEBUG_SERIAL
600            int bytes_inqueue;
601    #endif
602    
603          timeout = 0;  
604            timeout = 90;
605          pser_inf = get_serial_info(handle);          pser_inf = get_serial_info(handle);
606          ptermios = pser_inf->ptermios;          ptermios = pser_inf->ptermios;
607    
# Line 444  serial_read(HANDLE handle, uint8 * data, Line 633  serial_read(HANDLE handle, uint8 * data,
633          }          }
634          tcsetattr(handle, TCSANOW, ptermios);          tcsetattr(handle, TCSANOW, ptermios);
635    
636    #ifdef WITH_DEBUG_SERIAL
637            ioctl(handle, TIOCINQ, &bytes_inqueue);
638            DEBUG_SERIAL(("serial_read inqueue: %d expected %d\n", bytes_inqueue, length));
639    #endif
640    
641          *result = read(handle, data, length);          *result = read(handle, data, length);
642    
643    #ifdef WITH_DEBUG_SERIAL
644            DEBUG_SERIAL(("serial_read Bytes %d\n", *result));
645            if (*result > 0)
646                    hexdump(data, *result);
647    #endif
648    
649          return STATUS_SUCCESS;          return STATUS_SUCCESS;
650  }  }
651    
652  NTSTATUS  static NTSTATUS
653  serial_write(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  serial_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
654  {  {
655            SERIAL_DEVICE *pser_inf;
656    
657            pser_inf = get_serial_info(handle);
658    
659          *result = write(handle, data, length);          *result = write(handle, data, length);
660    
661            if (*result > 0)
662                    pser_inf->event_txempty = *result;
663    
664            DEBUG_SERIAL(("serial_write length %d, offset %d result %d\n", length, offset, *result));
665    
666          return STATUS_SUCCESS;          return STATUS_SUCCESS;
667  }  }
668    
669  static NTSTATUS  static NTSTATUS
670  serial_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out)  serial_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
671  {  {
672          uint32 result;          int flush_mask, purge_mask;
673            uint32 result, modemstate;
674          uint8 immediate;          uint8 immediate;
675            SERIAL_DEVICE *pser_inf;
676            struct termios *ptermios;
677    
678          if ((request >> 16) != FILE_DEVICE_SERIAL_PORT)          if ((request >> 16) != FILE_DEVICE_SERIAL_PORT)
679                  return STATUS_INVALID_PARAMETER;                  return STATUS_INVALID_PARAMETER;
680    
681            pser_inf = get_serial_info(handle);
682            ptermios = pser_inf->ptermios;
683    
684          /* extract operation */          /* extract operation */
685          request >>= 2;          request >>= 2;
686          request &= 0xfff;          request &= 0xfff;
687    
         printf("SERIAL IOCTL %d\n", request);  
   
688          switch (request)          switch (request)
689          {          {
690                  case SERIAL_SET_BAUD_RATE:                  case SERIAL_SET_BAUD_RATE:
691                          in_uint32_le(in, baud_rate);                          in_uint32_le(in, pser_inf->baud_rate);
692                          set_termios();                          set_termios(pser_inf, handle);
693                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BAUD_RATE %d\n", pser_inf->baud_rate));
694                          break;                          break;
695                  case SERIAL_GET_BAUD_RATE:                  case SERIAL_GET_BAUD_RATE:
696                          out_uint32_le(out, baud_rate);                          out_uint32_le(out, pser_inf->baud_rate);
697                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_BAUD_RATE %d\n", pser_inf->baud_rate));
698                          break;                          break;
699                  case SERIAL_SET_QUEUE_SIZE:                  case SERIAL_SET_QUEUE_SIZE:
700                          in_uint32_le(in, queue_in_size);                          in_uint32_le(in, pser_inf->queue_in_size);
701                          in_uint32_le(in, queue_out_size);                          in_uint32_le(in, pser_inf->queue_out_size);
702                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_QUEUE_SIZE in %d out %d\n",
703                                pser_inf->queue_in_size, pser_inf->queue_out_size));
704                          break;                          break;
705                  case SERIAL_SET_LINE_CONTROL:                  case SERIAL_SET_LINE_CONTROL:
706                          in_uint8(in, stop_bits);                          in_uint8(in, pser_inf->stop_bits);
707                          in_uint8(in, parity);                          in_uint8(in, pser_inf->parity);
708                          in_uint8(in, word_length);                          in_uint8(in, pser_inf->word_length);
709                          set_termios();                          set_termios(pser_inf, handle);
710                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_LINE_CONTROL stop %d parity %d word %d\n",
711                                pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length));
712                          break;                          break;
713                  case SERIAL_GET_LINE_CONTROL:                  case SERIAL_GET_LINE_CONTROL:
714                          out_uint8(out, stop_bits);                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_LINE_CONTROL\n"));
715                          out_uint8(out, parity);                          out_uint8(out, pser_inf->stop_bits);
716                          out_uint8(out, word_length);                          out_uint8(out, pser_inf->parity);
717                            out_uint8(out, pser_inf->word_length);
718                          break;                          break;
719                  case SERIAL_IMMEDIATE_CHAR:                  case SERIAL_IMMEDIATE_CHAR:
720                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_IMMEDIATE_CHAR\n"));
721                          in_uint8(in, immediate);                          in_uint8(in, immediate);
722                          serial_write(handle, &immediate, 1, 0, &result);                          serial_write(handle, &immediate, 1, 0, &result);
723                          break;                          break;
724                  case SERIAL_CONFIG_SIZE:                  case SERIAL_CONFIG_SIZE:
725                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_CONFIG_SIZE\n"));
726                          out_uint32_le(out, 0);                          out_uint32_le(out, 0);
727                          break;                          break;
728                  case SERIAL_GET_CHARS:                  case SERIAL_GET_CHARS:
729                          out_uint8s(out, 6);                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_CHARS\n"));
730                            out_uint8a(out, pser_inf->chars, 6);
731                          break;                          break;
732                  case SERIAL_SET_CHARS:                  case SERIAL_SET_CHARS:
733                          in_uint8s(in, 6);                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_CHARS\n"));
734                            in_uint8a(in, pser_inf->chars, 6);
735    #ifdef WITH_DEBUG_SERIAL
736                            hexdump(pser_inf->chars, 6);
737    #endif
738                            set_termios(pser_inf, handle);
739                          break;                          break;
740                  case SERIAL_GET_HANDFLOW:                  case SERIAL_GET_HANDFLOW:
741                          out_uint32_le(out, 0);                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_HANDFLOW\n"));
742                          out_uint32_le(out, 3);  /* Xon/Xoff */                          get_termios(pser_inf, handle);
743                          out_uint32_le(out, 0);                          out_uint32_le(out, pser_inf->control);
744                          out_uint32_le(out, 0);                          out_uint32_le(out, pser_inf->xonoff);   /* Xon/Xoff */
745                            out_uint32_le(out, pser_inf->onlimit);
746                            out_uint32_le(out, pser_inf->offlimit);
747                          break;                          break;
748                  case SERIAL_SET_HANDFLOW:                  case SERIAL_SET_HANDFLOW:
749                          in_uint8s(in, 16);                          in_uint32_le(in, pser_inf->control);
750                            in_uint32_le(in, pser_inf->xonoff);
751                            in_uint32_le(in, pser_inf->onlimit);
752                            in_uint32_le(in, pser_inf->offlimit);
753                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_HANDFLOW %x %x %x %x\n",
754                                pser_inf->control, pser_inf->xonoff, pser_inf->onlimit,
755                                pser_inf->onlimit));
756                            set_termios(pser_inf, handle);
757                          break;                          break;
758                  case SERIAL_SET_TIMEOUTS:                  case SERIAL_SET_TIMEOUTS:
759                          in_uint8s(in, 20);                          in_uint32(in, pser_inf->read_interval_timeout);
760                            in_uint32(in, pser_inf->read_total_timeout_multiplier);
761                            in_uint32(in, pser_inf->read_total_timeout_constant);
762                            in_uint32(in, pser_inf->write_total_timeout_multiplier);
763                            in_uint32(in, pser_inf->write_total_timeout_constant);
764                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_TIMEOUTS read timeout %d %d %d\n",
765                                pser_inf->read_interval_timeout,
766                                pser_inf->read_total_timeout_multiplier,
767                                pser_inf->read_total_timeout_constant));
768                          break;                          break;
769                  case SERIAL_GET_TIMEOUTS:                  case SERIAL_GET_TIMEOUTS:
770                          out_uint8s(out, 20);                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_TIMEOUTS read timeout %d %d %d\n",
771                                pser_inf->read_interval_timeout,
772                                pser_inf->read_total_timeout_multiplier,
773                                pser_inf->read_total_timeout_constant));
774    
775                            out_uint32(out, pser_inf->read_interval_timeout);
776                            out_uint32(out, pser_inf->read_total_timeout_multiplier);
777                            out_uint32(out, pser_inf->read_total_timeout_constant);
778                            out_uint32(out, pser_inf->write_total_timeout_multiplier);
779                            out_uint32(out, pser_inf->write_total_timeout_constant);
780                          break;                          break;
781                  case SERIAL_GET_WAIT_MASK:                  case SERIAL_GET_WAIT_MASK:
782                          out_uint32(out, wait_mask);                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_WAIT_MASK %X\n", pser_inf->wait_mask);
783                            out_uint32(out, pser_inf->wait_mask));
784                          break;                          break;
785                  case SERIAL_SET_WAIT_MASK:                  case SERIAL_SET_WAIT_MASK:
786                          in_uint32(in, wait_mask);                          in_uint32(in, pser_inf->wait_mask);
787                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_WAIT_MASK %X\n", pser_inf->wait_mask));
788                          break;                          break;
789                  case SERIAL_SET_DTR:                  case SERIAL_SET_DTR:
790                          dtr = 1;                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_DTR\n"));
791                          set_termios();                          ioctl(handle, TIOCMGET, &result);
792                            result |= TIOCM_DTR;
793                            ioctl(handle, TIOCMSET, &result);
794                            pser_inf->dtr = 1;
795                          break;                          break;
796                  case SERIAL_CLR_DTR:                  case SERIAL_CLR_DTR:
797                          dtr = 0;                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_CLR_DTR\n"));
798                          set_termios();                          ioctl(handle, TIOCMGET, &result);
799                            result &= ~TIOCM_DTR;
800                            ioctl(handle, TIOCMSET, &result);
801                            pser_inf->dtr = 0;
802                          break;                          break;
803  #if 0                  case SERIAL_SET_RTS:
804                  case SERIAL_WAIT_ON_MASK:                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_RTS\n"));
805                          /* XXX implement me */                          ioctl(handle, TIOCMGET, &result);
806                            result |= TIOCM_RTS;
807                            ioctl(handle, TIOCMSET, &result);
808                            pser_inf->rts = 1;
809                          break;                          break;
810                  case SERIAL_SET_BREAK_ON:                  case SERIAL_CLR_RTS:
811                          tcsendbreak(serial_fd, 0);                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_CLR_RTS\n"));
812                            ioctl(handle, TIOCMGET, &result);
813                            result &= ~TIOCM_RTS;
814                            ioctl(handle, TIOCMSET, &result);
815                            pser_inf->rts = 0;
816                            break;
817                    case SERIAL_GET_MODEMSTATUS:
818                            modemstate = 0;
819    #ifdef TIOCMGET
820                            ioctl(handle, TIOCMGET, &result);
821                            if (result & TIOCM_CTS)
822                                    modemstate |= SERIAL_MS_CTS;
823                            if (result & TIOCM_DSR)
824                                    modemstate |= SERIAL_MS_DSR;
825                            if (result & TIOCM_RNG)
826                                    modemstate |= SERIAL_MS_RNG;
827                            if (result & TIOCM_CAR)
828                                    modemstate |= SERIAL_MS_CAR;
829                            if (result & TIOCM_DTR)
830                                    modemstate |= SERIAL_MS_DTR;
831                            if (result & TIOCM_RTS)
832                                    modemstate |= SERIAL_MS_RTS;
833    #endif
834                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_MODEMSTATUS %X\n", modemstate));
835                            out_uint32_le(out, modemstate);
836                            break;
837                    case SERIAL_GET_COMMSTATUS:
838                            out_uint32_le(out, 0);  /* Errors */
839                            out_uint32_le(out, 0);  /* Hold reasons */
840    
841                            result = 0;
842                            ioctl(handle, TIOCINQ, &result);
843                            out_uint32_le(out, result);     /* Amount in in queue */
844                            if (result)
845                                    DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_COMMSTATUS in queue %d\n", result));
846    
847                            result = 0;
848                            ioctl(handle, TIOCOUTQ, &result);
849                            out_uint32_le(out, result);     /* Amount in out queue */
850                            if (result)
851                                    DEBUG_SERIAL(("serial_ioctl -> SERIAL_GET_COMMSTATUS out queue %d\n", result));
852    
853                            out_uint8(out, 0);      /* EofReceived */
854                            out_uint8(out, 0);      /* WaitForImmediate */
855                          break;                          break;
856                  case SERIAL_PURGE:                  case SERIAL_PURGE:
   
                         printf("SERIAL_PURGE\n");  
857                          in_uint32(in, purge_mask);                          in_uint32(in, purge_mask);
858                          if (purge_mask & 0x04)                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_PURGE purge_mask %X\n", purge_mask));
859                            flush_mask = 0;
860                            if (purge_mask & SERIAL_PURGE_TXCLEAR)
861                                  flush_mask |= TCOFLUSH;                                  flush_mask |= TCOFLUSH;
862                          if (purge_mask & 0x08)                          if (purge_mask & SERIAL_PURGE_RXCLEAR)
863                                  flush_mask |= TCIFLUSH;                                  flush_mask |= TCIFLUSH;
864                          if (flush_mask != 0)                          if (flush_mask != 0)
865                                  tcflush(handle, flush_mask);                                  tcflush(handle, flush_mask);
866                          if (purge_mask & 0x01)                          if (purge_mask & SERIAL_PURGE_TXABORT)
867                                  rdpdr_abort_io(handle, 4, STATUS_CANCELLED);                                  rdpdr_abort_io(handle, 4, STATUS_CANCELLED);
868                          if (purge_mask & 0x02)                          if (purge_mask & SERIAL_PURGE_RXABORT)
869                                  rdpdr_abort_io(handle, 3, STATUS_CANCELLED);                                  rdpdr_abort_io(handle, 3, STATUS_CANCELLED);
870                          break;                          break;
871                    case SERIAL_WAIT_ON_MASK:
872                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_WAIT_ON_MASK %X\n", pser_inf->wait_mask));
873                            pser_inf->event_pending = 1;
874                            if (serial_get_event(handle, &result))
875                            {
876                                    DEBUG_SERIAL(("WAIT end  event = %x\n", result));
877                                    out_uint32_le(out, result);
878                                    break;
879                            }
880                            return STATUS_PENDING;
881                            break;
882                    case SERIAL_SET_BREAK_ON:
883                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BREAK_ON\n"));
884                            tcsendbreak(handle, 0);
885                            break;
886                  case SERIAL_RESET_DEVICE:                  case SERIAL_RESET_DEVICE:
887                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_RESET_DEVICE\n"));
888                            break;
889                  case SERIAL_SET_BREAK_OFF:                  case SERIAL_SET_BREAK_OFF:
890                  case SERIAL_SET_RTS:                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_BREAK_OFF\n"));
891                  case SERIAL_CLR_RTS:                          break;
892                  case SERIAL_SET_XOFF:                  case SERIAL_SET_XOFF:
893                            DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_XOFF\n"));
894                            break;
895                  case SERIAL_SET_XON:                  case SERIAL_SET_XON:
896                          /* ignore */                          DEBUG_SERIAL(("serial_ioctl -> SERIAL_SET_XON\n"));
897                            tcflow(handle, TCION);
898                          break;                          break;
 #endif  
   
899                  default:                  default:
900                          unimpl("SERIAL IOCTL %d\n", request);                          unimpl("SERIAL IOCTL %d\n", request);
901                          return STATUS_INVALID_PARAMETER;                          return STATUS_INVALID_PARAMETER;
# Line 577  serial_device_control(HANDLE handle, uin Line 904  serial_device_control(HANDLE handle, uin
904          return STATUS_SUCCESS;          return STATUS_SUCCESS;
905  }  }
906    
907    BOOL
908    serial_get_event(NTHANDLE handle, uint32 * result)
909    {
910            int index;
911            SERIAL_DEVICE *pser_inf;
912            int bytes;
913            BOOL ret = False;
914    
915            *result = 0;
916            index = get_device_index(handle);
917            if (index < 0)
918                    return False;
919    
920            pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;
921    
922    
923            ioctl(handle, TIOCINQ, &bytes);
924    
925            if (bytes > 0)
926            {
927                    DEBUG_SERIAL(("serial_get_event Bytes %d\n", bytes));
928                    if (bytes > pser_inf->event_rlsd)
929                    {
930                            pser_inf->event_rlsd = bytes;
931                            if (pser_inf->wait_mask & SERIAL_EV_RLSD)
932                            {
933                                    DEBUG_SERIAL(("Event -> SERIAL_EV_RLSD \n"));
934                                    *result |= SERIAL_EV_RLSD;
935                                    ret = True;
936                            }
937    
938                    }
939    
940                    if ((bytes > 1) && (pser_inf->wait_mask & SERIAL_EV_RXFLAG))
941                    {
942                            DEBUG_SERIAL(("Event -> SERIAL_EV_RXFLAG Bytes %d\n", bytes));
943                            *result |= SERIAL_EV_RXFLAG;
944                            ret = True;
945                    }
946                    if ((pser_inf->wait_mask & SERIAL_EV_RXCHAR))
947                    {
948                            DEBUG_SERIAL(("Event -> SERIAL_EV_RXCHAR Bytes %d\n", bytes));
949                            *result |= SERIAL_EV_RXCHAR;
950                            ret = True;
951                    }
952    
953            }
954            else
955            {
956                    pser_inf->event_rlsd = 0;
957            }
958    
959    
960            ioctl(handle, TIOCOUTQ, &bytes);
961            if ((bytes == 0)
962                && (pser_inf->event_txempty > 0) && (pser_inf->wait_mask & SERIAL_EV_TXEMPTY))
963            {
964    
965                    DEBUG_SERIAL(("Event -> SERIAL_EV_TXEMPTY\n"));
966                    *result |= SERIAL_EV_TXEMPTY;
967                    ret = True;
968            }
969            pser_inf->event_txempty = bytes;
970    
971    
972            ioctl(handle, TIOCMGET, &bytes);
973            if ((bytes & TIOCM_DSR) != pser_inf->event_dsr)
974            {
975                    pser_inf->event_dsr = bytes & TIOCM_DSR;
976                    if (pser_inf->wait_mask & SERIAL_EV_DSR)
977                    {
978                            DEBUG_SERIAL(("event -> SERIAL_EV_DSR %s\n", (bytes & TIOCM_DSR) ? "ON" : "OFF"));
979                            *result |= SERIAL_EV_DSR;
980                            ret = True;
981                    }
982            }
983    
984            if ((bytes & TIOCM_CTS) != pser_inf->event_cts)
985            {
986                    pser_inf->event_cts = bytes & TIOCM_CTS;
987                    if (pser_inf->wait_mask & SERIAL_EV_CTS)
988                    {
989                            DEBUG_SERIAL((" EVENT-> SERIAL_EV_CTS %s\n", (bytes & TIOCM_CTS) ? "ON" : "OFF"));
990                            *result |= SERIAL_EV_CTS;
991                            ret = True;
992                    }
993            }
994    
995            if (ret)
996                    pser_inf->event_pending = 0;
997    
998            return ret;
999    }
1000    
1001  /* 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() */
1002  BOOL  BOOL
1003  serial_get_timeout(uint32 handle, uint32 length, uint32 * timeout, uint32 * itv_timeout)  serial_get_timeout(NTHANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout)
1004  {  {
1005          int index;          int index;
1006          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;
1007    
1008          index = get_device_index(handle);          index = get_device_index(handle);
1009            if (index < 0)
1010                    return True;
1011    
1012          if (g_rdpdr_device[index].device_type != DEVICE_TYPE_SERIAL)          if (g_rdpdr_device[index].device_type != DEVICE_TYPE_SERIAL)
1013          {          {

Legend:
Removed from v.580  
changed lines
  Added in v.795

  ViewVC Help
Powered by ViewVC 1.1.26