/[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 435 by astrand, Wed Jul 9 09:18:20 2003 UTC revision 578 by n-ki, Fri Jan 23 06:56:42 2004 UTC
# Line 1  Line 1 
1  #include <unistd.h>  #include <unistd.h>
2  #include <fcntl.h>  #include <fcntl.h>
3  #include <termios.h>  #include <termios.h>
4    #include <strings.h>
5  #include "rdesktop.h"  #include "rdesktop.h"
6    
7  #define FILE_DEVICE_SERIAL_PORT         0x1b  #define FILE_DEVICE_SERIAL_PORT         0x1b
# Line 52  Line 53 
53  #define ODD_PARITY                      1  #define ODD_PARITY                      1
54  #define EVEN_PARITY                     2  #define EVEN_PARITY                     2
55    
56    extern RDPDR_DEVICE    g_rdpdr_device[];
57    
58  int serial_fd;  int serial_fd;
59  struct termios termios;  struct termios termios;
60    
# Line 61  uint32 queue_in_size, queue_out_size; Line 64  uint32 queue_in_size, queue_out_size;
64  uint32 wait_mask;  uint32 wait_mask;
65  uint8 stop_bits, parity, word_length;  uint8 stop_bits, parity, word_length;
66    
67  static BOOL  SERIAL_DEVICE
68  get_termios(void)  *get_serial_info(HANDLE handle)
69  {  {
70          speed_t speed;          int     index;
71    
72          if (tcgetattr(serial_fd, &termios) == -1)          for (index = 0; index < RDPDR_MAX_DEVICES; index++)
73                  return False;          {
74                    if (handle == g_rdpdr_device[index].handle)
75                            return (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;
76            }
77            return NULL;
78    }
79    
80          speed = cfgetispeed(&termios);  BOOL
81          switch (speed)  get_termios(SERIAL_DEVICE *pser_inf, HANDLE serial_fd)
82          {  {
83                  case B75:          speed_t         speed;
84                          baud_rate = 75;          struct termios  *ptermios;
                         break;  
                 case B110:  
                         baud_rate = 110;  
                         break;  
                 case B134:  
                         baud_rate = 134;  
                         break;  
                 case B150:  
                         baud_rate = 150;  
                         break;  
                 case B300:  
                         baud_rate = 300;  
                         break;  
                 case B600:  
                         baud_rate = 600;  
                         break;  
                 case B1200:  
                         baud_rate = 1200;  
                         break;  
                 case B1800:  
                         baud_rate = 1800;  
                         break;  
                 case B2400:  
                         baud_rate = 2400;  
                         break;  
                 case B4800:  
                         baud_rate = 4800;  
                         break;  
                 case B9600:  
                         baud_rate = 9600;  
                         break;  
                 case B19200:  
                         baud_rate = 19200;  
                         break;  
                 case B38400:  
                         baud_rate = 38400;  
                         break;  
                 case B57600:  
                         baud_rate = 57600;  
                         break;  
                 case B115200:  
                         baud_rate = 115200;  
                         break;  
                 default:  
                         baud_rate = 0;  
                         break;  
         }  
85    
86          speed = cfgetospeed(&termios);          ptermios        = pser_inf->ptermios;
         dtr = (speed == B0) ? 0 : 1;  
87    
88          stop_bits = (termios.c_cflag & CSTOPB) ? STOP_BITS_2 : STOP_BITS_1;          if (tcgetattr(serial_fd, ptermios) == -1)
89          parity = (termios.                  return False;
                   c_cflag & PARENB) ? ((termios.  
                                         c_cflag & PARODD) ? ODD_PARITY : EVEN_PARITY) : NO_PARITY;  
         switch (termios.c_cflag & CSIZE)  
         {  
                 case CS5:  
                         word_length = 5;  
                         break;  
                 case CS6:  
                         word_length = 6;  
                         break;  
                 case CS7:  
                         word_length = 7;  
                         break;  
                 default:  
                         word_length = 8;  
                         break;  
         }  
90    
91          return True;          speed = cfgetispeed(ptermios);
92            switch (speed)
93            {
94    #ifdef B75
95                    case B75:       pser_inf->baud_rate = 75; break;
96    #endif
97    #ifdef B110
98                    case B110:      pser_inf->baud_rate = 110; break;
99    #endif
100    #ifdef B134
101                    case B134:      pser_inf->baud_rate = 134; break;
102    #endif
103    #ifdef B150
104                    case B150:      pser_inf->baud_rate = 150; break;
105    #endif
106    #ifdef B300
107                    case B300:      pser_inf->baud_rate = 300; break;
108    #endif
109    #ifdef B600
110                    case B600:      pser_inf->baud_rate = 600; break;
111    #endif
112    #ifdef B1200
113                    case B1200:     pser_inf->baud_rate = 1200; break;
114    #endif
115    #ifdef B1800
116                    case B1800:     pser_inf->baud_rate = 1800; break;
117    #endif
118    #ifdef B2400
119                    case B2400:     pser_inf->baud_rate = 2400; break;
120    #endif
121    #ifdef B4800
122                    case B4800:     pser_inf->baud_rate = 4800; break;
123    #endif
124    #ifdef B9600
125                    case B9600:     pser_inf->baud_rate = 9600; break;
126    #endif
127    #ifdef B19200
128                    case B19200:    pser_inf->baud_rate = 19200; break;
129    #endif
130    #ifdef B38400
131                    case B38400:    pser_inf->baud_rate = 38400; break;
132    #endif
133    #ifdef B57600
134                    case B57600:    pser_inf->baud_rate = 57600; break;
135    #endif
136    #ifdef B115200
137                    case B115200:   pser_inf->baud_rate = 115200; break;
138    #endif
139                    default:        pser_inf->baud_rate = 0; break;
140            }
141    
142            speed = cfgetospeed(ptermios);
143            pser_inf->dtr = (speed == B0) ? 0 : 1;
144    
145            pser_inf->stop_bits = (ptermios->c_cflag & CSTOPB) ? STOP_BITS_2 : STOP_BITS_1;
146            pser_inf->parity = (ptermios->c_cflag & PARENB) ? ((ptermios->c_cflag & PARODD) ? ODD_PARITY : EVEN_PARITY) : NO_PARITY;
147            switch (ptermios->c_cflag & CSIZE)
148            {
149                    case CS5: pser_inf->word_length = 5; break;
150                    case CS6: pser_inf->word_length = 6; break;
151                    case CS7: pser_inf->word_length = 7; break;
152                    default:  pser_inf->word_length = 8; break;
153            }
154    
155            return True;
156  }  }
157    
158  static void  static void
# Line 155  set_termios(void) Line 162  set_termios(void)
162    
163          switch (baud_rate)          switch (baud_rate)
164          {          {
165                  case 75:  #ifdef B75
166                          speed = B75;                  case 75:        speed = B75;break;
167                          break;  #endif
168                  case 110:  #ifdef B110
169                          speed = B110;                  case 110:       speed = B110;break;
170                          break;  #endif
171                  case 134:  #ifdef B134
172                          speed = B134;                  case 134:       speed = B134;break;
173                          break;  #endif
174                  case 150:  #ifdef B150
175                          speed = B150;                  case 150:       speed = B150;break;
176                          break;  #endif
177                  case 300:  #ifdef B300
178                          speed = B300;                  case 300:       speed = B300;break;
179                          break;  #endif
180                  case 600:  #ifdef B600
181                          speed = B600;                  case 600:       speed = B600;break;
182                          break;  #endif
183                  case 1200:  #ifdef B1200
184                          speed = B1200;                  case 1200:      speed = B1200;break;
185                          break;  #endif
186                  case 1800:  #ifdef B1800
187                          speed = B1800;                  case 1800:      speed = B1800;break;
188                          break;  #endif
189                  case 2400:  #ifdef B2400
190                          speed = B2400;                  case 2400:      speed = B2400;break;
191                          break;  #endif
192                  case 4800:  #ifdef B4800
193                          speed = B4800;                  case 4800:      speed = B4800;break;
194                          break;  #endif
195                  case 9600:  #ifdef B9600
196                          speed = B9600;                  case 9600:      speed = B9600;break;
197                          break;  #endif
198                  case 19200:  #ifdef B19200
199                          speed = B19200;                  case 19200:     speed = B19200;break;
200                          break;  #endif
201                  case 38400:  #ifdef B38400
202                          speed = B38400;                  case 38400:     speed = B38400;break;
203                          break;  #endif
204                  case 57600:  #ifdef B57600
205                          speed = B57600;                  case 57600:     speed = B57600;break;
206                          break;  #endif
207                  case 115200:  #ifdef B115200
208                          speed = B115200;                  case 115200:    speed = B115200;break;
209                          break;  #endif
210                  default:                  default:        speed = B0;break;
                         speed = B0;  
                         break;  
211          }          }
212    
213          /* on systems with separate ispeed and ospeed, we can remember the speed          /* on systems with separate ispeed and ospeed, we can remember the speed
# Line 245  set_termios(void) Line 250  set_termios(void)
250          tcsetattr(serial_fd, TCSANOW, &termios);          tcsetattr(serial_fd, TCSANOW, &termios);
251  }  }
252    
253  static NTSTATUS  /* Enumeration of devices from rdesktop.c        */
254  serial_create(HANDLE * handle)  /* returns numer of units found and initialized. */
255    /* optarg looks like ':com1=/dev/ttyS0'           */
256    /* when it arrives to this function.              */
257    /* :com1=/dev/ttyS0,com2=/dev/ttyS1 */
258    int
259    serial_enum_devices(int *id, char* optarg)
260    {
261            SERIAL_DEVICE* pser_inf;
262    
263            char *pos = optarg;
264            char *pos2;
265            int count = 0;
266    
267            // skip the first colon
268            optarg++;
269            while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)
270            {
271                    // Init data structures for device
272                    pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE));
273                    pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios));
274                    pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios));
275    
276                    pos2 = next_arg(optarg, '=');
277                    strcpy(g_rdpdr_device[*id].name, optarg);
278    
279                    toupper_str(g_rdpdr_device[*id].name);
280    
281                    g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);
282                    strcpy(g_rdpdr_device[*id].local_path, pos2);
283                    printf("SERIAL %s to %s\n", g_rdpdr_device[*id].name, g_rdpdr_device[*id].local_path);
284                    // set device type
285                    g_rdpdr_device[*id].device_type = DEVICE_TYPE_SERIAL;
286                    g_rdpdr_device[*id].pdevice_data = (void *) pser_inf;
287                    count++;
288                    (*id)++;
289    
290                    optarg = pos;
291            }
292            return count;
293    }
294    
295    NTSTATUS
296    serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition, uint32 flags_and_attributes, char *filename, HANDLE *handle)
297  {  {
298          /* XXX do we have to handle concurrent open attempts? */          HANDLE          serial_fd;
299          serial_fd = open("/dev/ttyS0", O_RDWR);          SERIAL_DEVICE   *pser_inf;
300          if (serial_fd == -1)          struct termios  *ptermios;
                 return STATUS_ACCESS_DENIED;  
301    
302          if (!get_termios())          pser_inf        = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data;
303                  return STATUS_ACCESS_DENIED;          ptermios        = pser_inf->ptermios;
304            serial_fd       = open(g_rdpdr_device[device_id].local_path, O_RDWR | O_NOCTTY);
305    
306          *handle = 0;          if (serial_fd == -1)
307          return STATUS_SUCCESS;                  return STATUS_ACCESS_DENIED;
308    
309            if (!get_termios(pser_inf, serial_fd ))
310                    return STATUS_ACCESS_DENIED;
311    
312            // Store handle for later use
313            g_rdpdr_device[device_id].handle = serial_fd;
314    
315            /* some sane information */
316            printf("INFO: SERIAL %s to %s\nINFO: speed %u baud, stop bits %u, parity %u, word length %u bits, dtr %u\n",
317                    g_rdpdr_device[device_id].name, g_rdpdr_device[device_id].local_path,
318                    pser_inf->baud_rate, pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length, pser_inf->dtr );
319            printf("INFO: use stty to change settings\n" );
320    
321            //tcgetattr(serial_fd, pser_inf->ptermios);
322    
323             *handle = serial_fd;
324            return STATUS_SUCCESS;
325  }  }
326    
327  static NTSTATUS  static NTSTATUS
# Line 267  serial_close(HANDLE handle) Line 331  serial_close(HANDLE handle)
331          return STATUS_SUCCESS;          return STATUS_SUCCESS;
332  }  }
333    
334  static NTSTATUS  NTSTATUS
335  serial_read(HANDLE handle, uint8 * data, uint32 length, uint32 * result)  serial_read(HANDLE handle, uint8 *data, uint32 length, uint32 offset, uint32 *result)
336  {  {
337          *result = read(serial_fd, data, length);          long            timeout;
338          return STATUS_SUCCESS;          SERIAL_DEVICE   *pser_inf;
339            struct termios  *ptermios;
340    
341            timeout         = 0;
342            pser_inf        = get_serial_info(handle);
343            ptermios        = pser_inf->ptermios;
344    
345            // Set timeouts kind of like the windows serial timeout parameters. Multiply timeout
346            // with requested read size
347            if (pser_inf->read_total_timeout_multiplier | pser_inf->read_total_timeout_constant)
348            {
349                    timeout = (pser_inf->read_total_timeout_multiplier * length + pser_inf->read_total_timeout_constant + 99) / 100;
350            }
351            else if (pser_inf->read_interval_timeout)
352            {
353                    timeout = (pser_inf->read_interval_timeout * length + 99) / 100;
354            }
355    
356            // If a timeout is set, do a blocking read, which times out after some time.
357            // It will make rdesktop less responsive, but it will improve serial performance, by not
358            // reading one character at a time.
359            if (timeout == 0)
360            {
361                    ptermios->c_cc[VTIME] = 0;
362                    ptermios->c_cc[VMIN] = 0;
363            }
364            else
365            {
366                    ptermios->c_cc[VTIME] = timeout;
367                    ptermios->c_cc[VMIN] = 1;
368            }
369            tcsetattr(handle, TCSANOW, ptermios);
370    
371            *result = read(handle, data, length);
372            return STATUS_SUCCESS;
373  }  }
374    
375  static NTSTATUS  NTSTATUS
376  serial_write(HANDLE handle, uint8 * data, uint32 length, uint32 * result)  serial_write(HANDLE handle, uint8 *data, uint32 length, uint32 offset, uint32 *result)
377  {  {
378          *result = write(serial_fd, data, length);          *result = write(handle, data, length);
379          return STATUS_SUCCESS;          return STATUS_SUCCESS;
380  }  }
381    
382  static NTSTATUS  static NTSTATUS
# Line 322  serial_device_control(HANDLE handle, uin Line 420  serial_device_control(HANDLE handle, uin
420                          break;                          break;
421                  case SERIAL_IMMEDIATE_CHAR:                  case SERIAL_IMMEDIATE_CHAR:
422                          in_uint8(in, immediate);                          in_uint8(in, immediate);
423                          serial_write(handle, &immediate, 1, &result);                          serial_write(handle, &immediate, 1, 0, &result);
424                          break;                          break;
425                  case SERIAL_CONFIG_SIZE:                  case SERIAL_CONFIG_SIZE:
426                          out_uint32_le(out, 0);                          out_uint32_le(out, 0);
# Line 370  serial_device_control(HANDLE handle, uin Line 468  serial_device_control(HANDLE handle, uin
468                          tcsendbreak(serial_fd, 0);                          tcsendbreak(serial_fd, 0);
469                          break;                          break;
470                  case SERIAL_PURGE:                  case SERIAL_PURGE:
471                          in_uint32(purge_mask);  
472                          /* tcflush */                          printf("SERIAL_PURGE\n");
473                          break;                          in_uint32(in, purge_mask);
474                            if (purge_mask & 0x04) flush_mask |= TCOFLUSH;
475                            if (purge_mask & 0x08) flush_mask |= TCIFLUSH;
476                            if (flush_mask != 0) tcflush(handle, flush_mask);
477                            if (purge_mask & 0x01) rdpdr_abort_io(handle, 4, STATUS_CANCELLED);
478                            if (purge_mask & 0x02) rdpdr_abort_io(handle, 3, STATUS_CANCELLED);
479                            break;
480    
481                  case SERIAL_RESET_DEVICE:                  case SERIAL_RESET_DEVICE:
482                  case SERIAL_SET_BREAK_OFF:                  case SERIAL_SET_BREAK_OFF:
483                  case SERIAL_SET_RTS:                  case SERIAL_SET_RTS:
# Line 391  serial_device_control(HANDLE handle, uin Line 496  serial_device_control(HANDLE handle, uin
496          return STATUS_SUCCESS;          return STATUS_SUCCESS;
497  }  }
498    
499    /* Read timeout for a given file descripter (device) when adding fd's to select() */
500    BOOL
501    serial_get_timeout(uint32 handle, uint32 length, uint32 *timeout, uint32 *itv_timeout)
502    {
503            int             index;
504            SERIAL_DEVICE   *pser_inf;
505    
506            index = get_device_index(handle);
507    
508            if (g_rdpdr_device[index].device_type != DEVICE_TYPE_SERIAL)
509            {
510                    return False;
511            }
512    
513            pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;
514    
515            *timeout = pser_inf->read_total_timeout_multiplier * length + pser_inf->read_total_timeout_constant;
516            *itv_timeout = pser_inf->read_interval_timeout;
517            return True;
518    }
519    
520  DEVICE_FNS serial_fns = {  DEVICE_FNS serial_fns = {
521          serial_create,          serial_create,
522          serial_close,          serial_close,

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

  ViewVC Help
Powered by ViewVC 1.1.26