/[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 608 by astrand, Sun Feb 15 21:19:28 2004 UTC revision 782 by astrand, Thu Oct 7 13:00:29 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  #define FILE_DEVICE_SERIAL_PORT         0x1b  #define FILE_DEVICE_SERIAL_PORT         0x1b
# Line 53  Line 54 
54  #define ODD_PARITY                      1  #define ODD_PARITY                      1
55  #define EVEN_PARITY                     2  #define EVEN_PARITY                     2
56    
57    #define SERIAL_PURGE_TXABORT 0x00000001
58    #define SERIAL_PURGE_RXABORT 0x00000002
59    #define SERIAL_PURGE_TXCLEAR 0x00000004
60    #define SERIAL_PURGE_RXCLEAR 0x00000008
61    
62    /* SERIAL_WAIT_ON_MASK */
63    #define SERIAL_EV_RXCHAR           0x0001       // Any Character received
64    #define SERIAL_EV_RXFLAG           0x0002       // Received certain character
65    #define SERIAL_EV_TXEMPTY          0x0004       // Transmitt Queue Empty
66    #define SERIAL_EV_CTS              0x0008       // CTS changed state
67    #define SERIAL_EV_DSR              0x0010       // DSR changed state
68    #define SERIAL_EV_RLSD             0x0020       // RLSD changed state
69    #define SERIAL_EV_BREAK            0x0040       // BREAK received
70    #define SERIAL_EV_ERR              0x0080       // Line status error occurred
71    #define SERIAL_EV_RING             0x0100       // Ring signal detected
72    #define SERIAL_EV_PERR             0x0200       // Printer error occured
73    #define SERIAL_EV_RX80FULL         0x0400       // Receive buffer is 80 percent full
74    #define SERIAL_EV_EVENT1           0x0800       // Provider specific event 1
75    #define SERIAL_EV_EVENT2           0x1000       // Provider specific event 2
76    
77    /* Modem Status */
78    #define SERIAL_MS_CTS 0x10
79    #define SERIAL_MS_DSR 0x20
80    #define SERIAL_MS_RNG 0x40
81    #define SERIAL_MS_CAR 0x80
82    
83    #ifndef CRTSCTS
84    #define CRTSCTS 0
85    #endif
86    
87    
88  extern RDPDR_DEVICE g_rdpdr_device[];  extern RDPDR_DEVICE g_rdpdr_device[];
89    
90  SERIAL_DEVICE *  static SERIAL_DEVICE *
91  get_serial_info(HANDLE handle)  get_serial_info(NTHANDLE handle)
92  {  {
93          int index;          int index;
94    
# Line 68  get_serial_info(HANDLE handle) Line 100  get_serial_info(HANDLE handle)
100          return NULL;          return NULL;
101  }  }
102    
103  BOOL  static BOOL
104  get_termios(SERIAL_DEVICE * pser_inf, HANDLE serial_fd)  get_termios(SERIAL_DEVICE * pser_inf, NTHANDLE serial_fd)
105  {  {
106          speed_t speed;          speed_t speed;
107          struct termios *ptermios;          struct termios *ptermios;
# Line 186  get_termios(SERIAL_DEVICE * pser_inf, HA Line 218  get_termios(SERIAL_DEVICE * pser_inf, HA
218                          break;                          break;
219          }          }
220    
221            pser_inf->rts = (ptermios->c_cflag & CRTSCTS) ? 1 : 0;
222    
223          return True;          return True;
224  }  }
225    
226  static void  static void
227  set_termios(SERIAL_DEVICE * pser_inf, HANDLE serial_fd)  set_termios(SERIAL_DEVICE * pser_inf, NTHANDLE serial_fd)
228  {  {
229          speed_t speed;          speed_t speed;
230    
# Line 286  set_termios(SERIAL_DEVICE * pser_inf, HA Line 320  set_termios(SERIAL_DEVICE * pser_inf, HA
320          cfsetispeed(pser_inf->ptermios, speed);          cfsetispeed(pser_inf->ptermios, speed);
321          cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0);          cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0);
322    
323          ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE);          ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS);
324          switch (pser_inf->stop_bits)          switch (pser_inf->stop_bits)
325          {          {
326                  case STOP_BITS_2:                  case STOP_BITS_2:
327                          ptermios->c_cflag |= CSTOPB;                          ptermios->c_cflag |= CSTOPB;
328                          break;                          break;
329          }          }
330    
331          switch (pser_inf->parity)          switch (pser_inf->parity)
332          {          {
333                  case EVEN_PARITY:                  case EVEN_PARITY:
# Line 302  set_termios(SERIAL_DEVICE * pser_inf, HA Line 337  set_termios(SERIAL_DEVICE * pser_inf, HA
337                          ptermios->c_cflag |= PARENB | PARODD;                          ptermios->c_cflag |= PARENB | PARODD;
338                          break;                          break;
339          }          }
340    
341          switch (pser_inf->word_length)          switch (pser_inf->word_length)
342          {          {
343                  case 5:                  case 5:
# Line 318  set_termios(SERIAL_DEVICE * pser_inf, HA Line 354  set_termios(SERIAL_DEVICE * pser_inf, HA
354                          break;                          break;
355          }          }
356    
357            if (pser_inf->rts)
358                    ptermios->c_cflag |= CRTSCTS;
359    
360          tcsetattr(serial_fd, TCSANOW, ptermios);          tcsetattr(serial_fd, TCSANOW, ptermios);
361  }  }
362    
# Line 342  serial_enum_devices(uint32 * id, char *o Line 381  serial_enum_devices(uint32 * id, char *o
381                  // Init data structures for device                  // Init data structures for device
382                  pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE));                  pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE));
383                  pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios));                  pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios));
384                    memset(pser_inf->ptermios, 0, sizeof(struct termios));
385                  pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios));                  pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios));
386                    memset(pser_inf->pold_termios, 0, sizeof(struct termios));
387    
388                  pos2 = next_arg(optarg, '=');                  pos2 = next_arg(optarg, '=');
389                  strcpy(g_rdpdr_device[*id].name, optarg);                  strcpy(g_rdpdr_device[*id].name, optarg);
# Line 364  serial_enum_devices(uint32 * id, char *o Line 405  serial_enum_devices(uint32 * id, char *o
405          return count;          return count;
406  }  }
407    
408  NTSTATUS  static NTSTATUS
409  serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,  serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,
410                uint32 flags_and_attributes, char *filename, HANDLE * handle)                uint32 flags_and_attributes, char *filename, NTHANDLE * handle)
411  {  {
412          HANDLE serial_fd;          NTHANDLE serial_fd;
413          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;
414          struct termios *ptermios;          struct termios *ptermios;
415    
416          pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data;          pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data;
417          ptermios = pser_inf->ptermios;          ptermios = pser_inf->ptermios;
418          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);
419    
420          if (serial_fd == -1)          if (serial_fd == -1)
421          {          {
# Line 383  serial_create(uint32 device_id, uint32 a Line 424  serial_create(uint32 device_id, uint32 a
424          }          }
425    
426          if (!get_termios(pser_inf, serial_fd))          if (!get_termios(pser_inf, serial_fd))
427            {
428                    printf("INFO: SERIAL %s access denied\n", g_rdpdr_device[device_id].name);
429                    fflush(stdout);
430                  return STATUS_ACCESS_DENIED;                  return STATUS_ACCESS_DENIED;
431            }
432    
433          // Store handle for later use          // Store handle for later use
434          g_rdpdr_device[device_id].handle = serial_fd;          g_rdpdr_device[device_id].handle = serial_fd;
435    
436          /* some sane information */          /* some sane information */
437          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);          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);
438    
439          printf("INFO: use stty to change settings\n");          printf("INFO: use stty to change settings\n");
440    
441  /*      ptermios->c_cflag = B115200 | CRTSCTS | CS8 | CLOCAL | CREAD;  /*      ptermios->c_cflag = B115200 | CRTSCTS | CS8 | CLOCAL | CREAD;
# Line 399  serial_create(uint32 device_id, uint32 a Line 445  serial_create(uint32 device_id, uint32 a
445    
446          tcsetattr(serial_fd, TCSANOW, ptermios);          tcsetattr(serial_fd, TCSANOW, ptermios);
447  */  */
448            pser_inf->ptermios->c_iflag &=
449                    ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
450            pser_inf->ptermios->c_oflag &= ~OPOST;
451            pser_inf->ptermios->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
452            pser_inf->ptermios->c_cflag &= ~(CSIZE | PARENB);
453            pser_inf->ptermios->c_cflag |= CS8;
454            tcsetattr(serial_fd, TCSANOW, pser_inf->ptermios);
455    
456          *handle = serial_fd;          *handle = serial_fd;
457    
# Line 410  serial_create(uint32 device_id, uint32 a Line 463  serial_create(uint32 device_id, uint32 a
463  }  }
464    
465  static NTSTATUS  static NTSTATUS
466  serial_close(HANDLE handle)  serial_close(NTHANDLE handle)
467  {  {
468          g_rdpdr_device[get_device_index(handle)].handle = 0;          int i = get_device_index(handle);
469            if (i >= 0)
470                    g_rdpdr_device[i].handle = 0;
471          close(handle);          close(handle);
472          return STATUS_SUCCESS;          return STATUS_SUCCESS;
473  }  }
474    
475  NTSTATUS  static NTSTATUS
476  serial_read(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  serial_read(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
477  {  {
478          long timeout;          long timeout;
479          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;
# Line 459  serial_read(HANDLE handle, uint8 * data, Line 514  serial_read(HANDLE handle, uint8 * data,
514    
515          *result = read(handle, data, length);          *result = read(handle, data, length);
516    
517            //hexdump(data, *read);
518    
519          return STATUS_SUCCESS;          return STATUS_SUCCESS;
520  }  }
521    
522  NTSTATUS  static NTSTATUS
523  serial_write(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  serial_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
524  {  {
525          *result = write(handle, data, length);          *result = write(handle, data, length);
526          return STATUS_SUCCESS;          return STATUS_SUCCESS;
527  }  }
528    
529  static NTSTATUS  static NTSTATUS
530  serial_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out)  serial_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
531  {  {
532          uint32 result;  #if 0
533            int flush_mask, purge_mask;
534    #endif
535            uint32 result, modemstate;
536          uint8 immediate;          uint8 immediate;
537          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;
538          struct termios *ptermios;          struct termios *ptermios;
# Line 555  serial_device_control(HANDLE handle, uin Line 615  serial_device_control(HANDLE handle, uin
615                          pser_inf->dtr = 0;                          pser_inf->dtr = 0;
616                          set_termios(pser_inf, handle);                          set_termios(pser_inf, handle);
617                          break;                          break;
618  #if 0                  case SERIAL_SET_RTS:
619                  case SERIAL_WAIT_ON_MASK:                          pser_inf->rts = 1;
620                          /* XXX implement me */                          set_termios(pser_inf, handle);
621                          break;                          break;
622                  case SERIAL_SET_BREAK_ON:                  case SERIAL_CLR_RTS:
623                          tcsendbreak(serial_fd, 0);                          pser_inf->rts = 0;
624                            set_termios(pser_inf, handle);
625                            break;
626                    case SERIAL_GET_MODEMSTATUS:
627                            modemstate = 0;
628    #ifdef TIOCMGET
629                            ioctl(handle, TIOCMGET, &result);
630                            if (result & TIOCM_CTS)
631                                    modemstate |= SERIAL_MS_CTS;
632                            if (result & TIOCM_DSR)
633                                    modemstate |= SERIAL_MS_DSR;
634                            if (result & TIOCM_RNG)
635                                    modemstate |= SERIAL_MS_RNG;
636                            if (result & TIOCM_CAR)
637                                    modemstate |= SERIAL_MS_CAR;
638    #endif
639                            out_uint32_le(out, modemstate);
640                            break;
641                    case SERIAL_GET_COMMSTATUS:
642                            out_uint32_le(out, 0);  /* Errors */
643                            out_uint32_le(out, 0);  /* Hold reasons */
644                            out_uint32_le(out, 0);  /* Amount in in queue */
645                            out_uint32_le(out, 0);  /* Amount in out queue */
646                            out_uint8(out, 0);      /* EofReceived */
647                            out_uint8(out, 0);      /* WaitForImmediate */
648                          break;                          break;
649    #if 0
650                  case SERIAL_PURGE:                  case SERIAL_PURGE:
   
651                          printf("SERIAL_PURGE\n");                          printf("SERIAL_PURGE\n");
652                          in_uint32(in, purge_mask);                          in_uint32(in, purge_mask);
653                          if (purge_mask & 0x04)                          if (purge_mask & 0x04)
# Line 577  serial_device_control(HANDLE handle, uin Line 661  serial_device_control(HANDLE handle, uin
661                          if (purge_mask & 0x02)                          if (purge_mask & 0x02)
662                                  rdpdr_abort_io(handle, 3, STATUS_CANCELLED);                                  rdpdr_abort_io(handle, 3, STATUS_CANCELLED);
663                          break;                          break;
664                    case SERIAL_WAIT_ON_MASK:
665                            /* XXX implement me */
666                            out_uint32_le(out, pser_inf->wait_mask);
667                            break;
668                    case SERIAL_SET_BREAK_ON:
669                            tcsendbreak(serial_fd, 0);
670                            break;
671                  case SERIAL_RESET_DEVICE:                  case SERIAL_RESET_DEVICE:
672                  case SERIAL_SET_BREAK_OFF:                  case SERIAL_SET_BREAK_OFF:
                 case SERIAL_SET_RTS:  
                 case SERIAL_CLR_RTS:  
673                  case SERIAL_SET_XOFF:                  case SERIAL_SET_XOFF:
674                  case SERIAL_SET_XON:                  case SERIAL_SET_XON:
675                          /* ignore */                          /* ignore */
676                          break;                          break;
677  #endif  #endif
   
678                  default:                  default:
679                          unimpl("SERIAL IOCTL %d\n", request);                          unimpl("SERIAL IOCTL %d\n", request);
680                          return STATUS_INVALID_PARAMETER;                          return STATUS_INVALID_PARAMETER;
# Line 598  serial_device_control(HANDLE handle, uin Line 685  serial_device_control(HANDLE handle, uin
685    
686  /* 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() */
687  BOOL  BOOL
688  serial_get_timeout(HANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout)  serial_get_timeout(NTHANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout)
689  {  {
690          int index;          int index;
691          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;
692    
693          index = get_device_index(handle);          index = get_device_index(handle);
694            if (index < 0)
695                    return True;
696    
697          if (g_rdpdr_device[index].device_type != DEVICE_TYPE_SERIAL)          if (g_rdpdr_device[index].device_type != DEVICE_TYPE_SERIAL)
698          {          {

Legend:
Removed from v.608  
changed lines
  Added in v.782

  ViewVC Help
Powered by ViewVC 1.1.26