/[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 569 by n-ki, Wed Jan 21 14:40:40 2004 UTC revision 608 by astrand, Sun Feb 15 21:19:28 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[];  extern RDPDR_DEVICE g_rdpdr_device[];
57    
58  int serial_fd;  SERIAL_DEVICE *
59  struct termios termios;  get_serial_info(HANDLE handle)
   
 int dtr;  
 uint32 baud_rate;  
 uint32 queue_in_size, queue_out_size;  
 uint32 wait_mask;  
 uint8 stop_bits, parity, word_length;  
   
 SERIAL_DEVICE  
 *get_serial_info(HANDLE handle)  
60  {  {
61          int     index;          int index;
62    
63          for (index = 0; index < RDPDR_MAX_DEVICES; index++)          for (index = 0; index < RDPDR_MAX_DEVICES; index++)
64          {          {
65                  if (handle == g_rdpdr_device[index].handle)                  if (handle == g_rdpdr_device[index].handle)
66                          return (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;                          return (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;
67          }          }
68          return NULL;          return NULL;
69  }  }
70    
71  BOOL  BOOL
72  get_termios(SERIAL_DEVICE *pser_inf, HANDLE serial_fd)  get_termios(SERIAL_DEVICE * pser_inf, HANDLE serial_fd)
73  {  {
74          speed_t         speed;          speed_t speed;
75          struct termios  *ptermios;          struct termios *ptermios;
76    
77          ptermios        = pser_inf->ptermios;          ptermios = pser_inf->ptermios;
78    
79          if (tcgetattr(serial_fd, ptermios) == -1)          if (tcgetattr(serial_fd, ptermios) == -1)
80                  return False;                  return False;
81    
82          speed = cfgetispeed(ptermios);          speed = cfgetispeed(ptermios);
83          switch (speed)          switch (speed)
84          {          {
85  #ifdef B75  #ifdef B75
86                  case B75:       pser_inf->baud_rate = 75; break;                  case B75:
87                            pser_inf->baud_rate = 75;
88                            break;
89  #endif  #endif
90  #ifdef B110  #ifdef B110
91                  case B110:      pser_inf->baud_rate = 110; break;                  case B110:
92                            pser_inf->baud_rate = 110;
93                            break;
94  #endif  #endif
95  #ifdef B134  #ifdef B134
96                  case B134:      pser_inf->baud_rate = 134; break;                  case B134:
97                            pser_inf->baud_rate = 134;
98                            break;
99  #endif  #endif
100  #ifdef B150  #ifdef B150
101                  case B150:      pser_inf->baud_rate = 150; break;                  case B150:
102                            pser_inf->baud_rate = 150;
103                            break;
104  #endif  #endif
105  #ifdef B300  #ifdef B300
106                  case B300:      pser_inf->baud_rate = 300; break;                  case B300:
107                            pser_inf->baud_rate = 300;
108                            break;
109  #endif  #endif
110  #ifdef B600  #ifdef B600
111                  case B600:      pser_inf->baud_rate = 600; break;                  case B600:
112                            pser_inf->baud_rate = 600;
113                            break;
114  #endif  #endif
115  #ifdef B1200  #ifdef B1200
116                  case B1200:     pser_inf->baud_rate = 1200; break;                  case B1200:
117                            pser_inf->baud_rate = 1200;
118                            break;
119  #endif  #endif
120  #ifdef B1800  #ifdef B1800
121                  case B1800:     pser_inf->baud_rate = 1800; break;                  case B1800:
122                            pser_inf->baud_rate = 1800;
123                            break;
124  #endif  #endif
125  #ifdef B2400  #ifdef B2400
126                  case B2400:     pser_inf->baud_rate = 2400; break;                  case B2400:
127                            pser_inf->baud_rate = 2400;
128                            break;
129  #endif  #endif
130  #ifdef B4800  #ifdef B4800
131                  case B4800:     pser_inf->baud_rate = 4800; break;                  case B4800:
132                            pser_inf->baud_rate = 4800;
133                            break;
134  #endif  #endif
135  #ifdef B9600  #ifdef B9600
136                  case B9600:     pser_inf->baud_rate = 9600; break;                  case B9600:
137                            pser_inf->baud_rate = 9600;
138                            break;
139  #endif  #endif
140  #ifdef B19200  #ifdef B19200
141                  case B19200:    pser_inf->baud_rate = 19200; break;                  case B19200:
142                            pser_inf->baud_rate = 19200;
143                            break;
144  #endif  #endif
145  #ifdef B38400  #ifdef B38400
146                  case B38400:    pser_inf->baud_rate = 38400; break;                  case B38400:
147                            pser_inf->baud_rate = 38400;
148                            break;
149  #endif  #endif
150  #ifdef B57600  #ifdef B57600
151                  case B57600:    pser_inf->baud_rate = 57600; break;                  case B57600:
152                            pser_inf->baud_rate = 57600;
153                            break;
154  #endif  #endif
155  #ifdef B115200  #ifdef B115200
156                  case B115200:   pser_inf->baud_rate = 115200; break;                  case B115200:
157                            pser_inf->baud_rate = 115200;
158                            break;
159  #endif  #endif
160                  default:        pser_inf->baud_rate = 0; break;                  default:
161          }                          pser_inf->baud_rate = 0;
162                            break;
163            }
164    
165          speed = cfgetospeed(ptermios);          speed = cfgetospeed(ptermios);
166          pser_inf->dtr = (speed == B0) ? 0 : 1;          pser_inf->dtr = (speed == B0) ? 0 : 1;
167    
168          pser_inf->stop_bits = (ptermios->c_cflag & CSTOPB) ? STOP_BITS_2 : STOP_BITS_1;          pser_inf->stop_bits = (ptermios->c_cflag & CSTOPB) ? STOP_BITS_2 : STOP_BITS_1;
169          pser_inf->parity = (ptermios->c_cflag & PARENB) ? ((ptermios->c_cflag & PARODD) ? ODD_PARITY : EVEN_PARITY) : NO_PARITY;          pser_inf->parity =
170          switch (ptermios->c_cflag & CSIZE)                  (ptermios->
171          {                   c_cflag & PARENB) ? ((ptermios->
172                  case CS5: pser_inf->word_length = 5; break;                                         c_cflag & PARODD) ? ODD_PARITY : EVEN_PARITY) : NO_PARITY;
173                  case CS6: pser_inf->word_length = 6; break;          switch (ptermios->c_cflag & CSIZE)
174                  case CS7: pser_inf->word_length = 7; break;          {
175                  default:  pser_inf->word_length = 8; break;                  case CS5:
176          }                          pser_inf->word_length = 5;
177                            break;
178                    case CS6:
179                            pser_inf->word_length = 6;
180                            break;
181                    case CS7:
182                            pser_inf->word_length = 7;
183                            break;
184                    default:
185                            pser_inf->word_length = 8;
186                            break;
187            }
188    
189          return True;          return True;
190  }  }
191    
192  static void  static void
193  set_termios(void)  set_termios(SERIAL_DEVICE * pser_inf, HANDLE serial_fd)
194  {  {
195          speed_t speed;          speed_t speed;
196    
197          switch (baud_rate)          struct termios *ptermios;
198    
199            ptermios = pser_inf->ptermios;
200    
201    
202            switch (pser_inf->baud_rate)
203          {          {
204  #ifdef B75  #ifdef B75
205                  case 75:        speed = B75;break;                  case 75:
206                            speed = B75;
207                            break;
208  #endif  #endif
209  #ifdef B110  #ifdef B110
210                  case 110:       speed = B110;break;                  case 110:
211                            speed = B110;
212                            break;
213  #endif  #endif
214  #ifdef B134  #ifdef B134
215                  case 134:       speed = B134;break;                  case 134:
216                            speed = B134;
217                            break;
218  #endif  #endif
219  #ifdef B150  #ifdef B150
220                  case 150:       speed = B150;break;                  case 150:
221                            speed = B150;
222                            break;
223  #endif  #endif
224  #ifdef B300  #ifdef B300
225                  case 300:       speed = B300;break;                  case 300:
226                            speed = B300;
227                            break;
228  #endif  #endif
229  #ifdef B600  #ifdef B600
230                  case 600:       speed = B600;break;                  case 600:
231                            speed = B600;
232                            break;
233  #endif  #endif
234  #ifdef B1200  #ifdef B1200
235                  case 1200:      speed = B1200;break;                  case 1200:
236                            speed = B1200;
237                            break;
238  #endif  #endif
239  #ifdef B1800  #ifdef B1800
240                  case 1800:      speed = B1800;break;                  case 1800:
241                            speed = B1800;
242                            break;
243  #endif  #endif
244  #ifdef B2400  #ifdef B2400
245                  case 2400:      speed = B2400;break;                  case 2400:
246                            speed = B2400;
247                            break;
248  #endif  #endif
249  #ifdef B4800  #ifdef B4800
250                  case 4800:      speed = B4800;break;                  case 4800:
251                            speed = B4800;
252                            break;
253  #endif  #endif
254  #ifdef B9600  #ifdef B9600
255                  case 9600:      speed = B9600;break;                  case 9600:
256                            speed = B9600;
257                            break;
258  #endif  #endif
259  #ifdef B19200  #ifdef B19200
260                  case 19200:     speed = B19200;break;                  case 19200:
261                            speed = B19200;
262                            break;
263  #endif  #endif
264  #ifdef B38400  #ifdef B38400
265                  case 38400:     speed = B38400;break;                  case 38400:
266                            speed = B38400;
267                            break;
268  #endif  #endif
269  #ifdef B57600  #ifdef B57600
270                  case 57600:     speed = B57600;break;                  case 57600:
271                            speed = B57600;
272                            break;
273  #endif  #endif
274  #ifdef B115200  #ifdef B115200
275                  case 115200:    speed = B115200;break;                  case 115200:
276                            speed = B115200;
277                            break;
278  #endif  #endif
279                  default:        speed = B0;break;                  default:
280                            speed = B0;
281                            break;
282          }          }
283    
284          /* on systems with separate ispeed and ospeed, we can remember the speed          /* on systems with separate ispeed and ospeed, we can remember the speed
285             in ispeed while changing DTR with ospeed */             in ispeed while changing DTR with ospeed */
286          cfsetispeed(&termios, speed);          cfsetispeed(pser_inf->ptermios, speed);
287          cfsetospeed(&termios, dtr ? speed : 0);          cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0);
288    
289          termios.c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE);          ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE);
290          switch (stop_bits)          switch (pser_inf->stop_bits)
291          {          {
292                  case STOP_BITS_2:                  case STOP_BITS_2:
293                          termios.c_cflag |= CSTOPB;                          ptermios->c_cflag |= CSTOPB;
294                          break;                          break;
295          }          }
296          switch (parity)          switch (pser_inf->parity)
297          {          {
298                  case EVEN_PARITY:                  case EVEN_PARITY:
299                          termios.c_cflag |= PARENB;                          ptermios->c_cflag |= PARENB;
300                          break;                          break;
301                  case ODD_PARITY:                  case ODD_PARITY:
302                          termios.c_cflag |= PARENB | PARODD;                          ptermios->c_cflag |= PARENB | PARODD;
303                          break;                          break;
304          }          }
305          switch (word_length)          switch (pser_inf->word_length)
306          {          {
307                  case 5:                  case 5:
308                          termios.c_cflag |= CS5;                          ptermios->c_cflag |= CS5;
309                          break;                          break;
310                  case 6:                  case 6:
311                          termios.c_cflag |= CS6;                          ptermios->c_cflag |= CS6;
312                          break;                          break;
313                  case 7:                  case 7:
314                          termios.c_cflag |= CS7;                          ptermios->c_cflag |= CS7;
315                          break;                          break;
316                  default:                  default:
317                          termios.c_cflag |= CS8;                          ptermios->c_cflag |= CS8;
318                          break;                          break;
319          }          }
320    
321          tcsetattr(serial_fd, TCSANOW, &termios);          tcsetattr(serial_fd, TCSANOW, ptermios);
322  }  }
323    
324  /* Enumeration of devices from rdesktop.c        */  /* Enumeration of devices from rdesktop.c        */
325  /* returns numer of units found and initialized. */  /* returns numer of units found and initialized. */
326  /* optarg looks like ':com1=/dev/ttyS0'           */  /* optarg looks like ':com1=/dev/ttyS0'           */
327  /* when it arrives to this function.              */  /* when it arrives to this function.              */
328  /*  windev u*dev   baud, parity, stop bits, wordlength */  /* :com1=/dev/ttyS0,com2=/dev/ttyS1 */
 /* :com1=/dev/ttyS0:9600,0|1|2,0|2,5|6|7|8:dtr */  
329  int  int
330  serial_enum_devices(int *id, char* optarg)  serial_enum_devices(uint32 * id, char *optarg)
331  {  {
332          SERIAL_DEVICE* pser_inf;          SERIAL_DEVICE *pser_inf;
   
         int argcount=0;  
         char* pos = optarg;  
         char* pos2;  
         char* pos3;  
333    
334          if(*id<RDPDR_MAX_DEVICES){          char *pos = optarg;
335            char *pos2;
336            int count = 0;
337    
338            // skip the first colon
339            optarg++;
340            while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)
341            {
342                  // Init data structures for device                  // Init data structures for device
343                  pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE));                  pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE));
344                  pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios));                  pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios));
345                  pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios));                  pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios));
346    
347                  // skip the first colon                  pos2 = next_arg(optarg, '=');
348                  optarg++;                  strcpy(g_rdpdr_device[*id].name, optarg);
                 while( (pos = next_arg( optarg, ':')) ){  
   
                         switch(argcount){  
                                 /* com1=/dev/ttyS0 */  
                                 case 0:  
                                         pos2 = next_arg(optarg,'=');  
                                         if( !pos2 || *pos2 == (char)0x00 ){  
                                                 error("-r comport arguments should look like: -r comport:com1=/dev/ttyS0\n");  
                                                 return 0;  
                                         }  
                                         /* optarg = com1, pos2 = /dev/ttyS0 */  
                                         strcpy(g_rdpdr_device[*id].name,optarg);  
   
                                         toupper(g_rdpdr_device[*id].name);  
   
                                         g_rdpdr_device[*id].local_path = xmalloc( strlen(pos2) + 1 );  
                                         strcpy(g_rdpdr_device[*id].local_path,pos2);  
                                         break;  
                                 /* 9600,0|1|2,O|2,5|6|7|8 */  
                                 /* TODO: values should be set in serial_create()... ??? */  
                                 case 1:  
                                         pos2 = next_arg(optarg,',');  
                                         /*optarg=9600*/  
                                         pser_inf->baud_rate = atoi(optarg);  
                                         if( !pos2 || *pos2 == (char)0x00 )  
                                                 break;  
                                         pos3 = next_arg(pos2,',');  
                                         /* pos2 = 0|1|2 */  
                                         pser_inf->parity = atoi(pos2);  
                                         /* pos3 = 0|2,5|6|7|8*/  
                                         pos2 = next_arg(pos3,',');  
                                         if( !pos3 || *pos3 == (char)0x00 )  
                                                 break;  
                                         pser_inf->stop_bits = atoi(pos3);  
                                         /* pos2 = 5|6|7|8 */  
                                         if( !pos2 || *pos2 == (char)0x00 )  
                                                 break;  
                                         pser_inf->word_length = atoi(pos2);  
                                         break;  
                                 default:  
                                         if( (*optarg != (char)0x00) && (strcmp( optarg, "dtr" ) == 0) ){  
                                                 pser_inf->dtr = 1;  
                                         }  
                                         /* TODO: add more switches here, like xon, xoff. they will be separated by colon  
                                         if( (*optarg != (char)0x00) && (strcmp( optarg, "xon" ) == 0) ){  
                                         }  
                                         */  
                                         break;  
                         }  
                         argcount++;  
                         optarg=pos;  
                 }  
   
                 printf("SERIAL %s to %s", g_rdpdr_device[*id].name, g_rdpdr_device[*id].local_path );  
                 if( pser_inf->baud_rate != 0 ){  
                         printf(" with baud: %u, parity: %u, stop bits: %u word length: %u", pser_inf->baud_rate, pser_inf->parity, pser_inf->stop_bits, pser_inf->word_length );  
                         if( pser_inf->dtr )  
                                 printf( " dtr set\n");  
                         else  
                                 printf( "\n" );  
                 }else  
                         printf("\n");  
349    
350                    toupper_str(g_rdpdr_device[*id].name);
351    
352                    g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);
353                    strcpy(g_rdpdr_device[*id].local_path, pos2);
354                    printf("SERIAL %s to %s\n", g_rdpdr_device[*id].name,
355                           g_rdpdr_device[*id].local_path);
356                  // set device type                  // set device type
357                  g_rdpdr_device[*id].device_type = DEVICE_TYPE_SERIAL;                  g_rdpdr_device[*id].device_type = DEVICE_TYPE_SERIAL;
358                  g_rdpdr_device[*id].pdevice_data = (void *) pser_inf;                  g_rdpdr_device[*id].pdevice_data = (void *) pser_inf;
359                    count++;
360                  (*id)++;                  (*id)++;
361    
362                  return 1;                  optarg = pos;
363          }          }
364          return 0;          return count;
365  }  }
366    
367  NTSTATUS  NTSTATUS
368  serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition, uint32 flags_and_attributes, char *filename, HANDLE *handle)  serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,
369                  uint32 flags_and_attributes, char *filename, HANDLE * handle)
370  {  {
371          HANDLE          serial_fd;          HANDLE serial_fd;
372          SERIAL_DEVICE   *pser_inf;          SERIAL_DEVICE *pser_inf;
373          struct termios  *ptermios;          struct termios *ptermios;
374          SERIAL_DEVICE   tmp_inf;  
375            pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data;
376          pser_inf        = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data;          ptermios = pser_inf->ptermios;
377          ptermios        = pser_inf->ptermios;          serial_fd = open(g_rdpdr_device[device_id].local_path, O_RDWR | O_NOCTTY);
378          serial_fd       = open(g_rdpdr_device[device_id].local_path, O_RDWR | O_NOCTTY);  
379            if (serial_fd == -1)
380          if (serial_fd == -1)          {
381                  return STATUS_ACCESS_DENIED;                  perror("open");
382                    return STATUS_ACCESS_DENIED;
         // before we clog the user inserted args store them locally  
         //  
         memcpy(&tmp_inf,pser_inf, sizeof(pser_inf) );  
   
         if (!get_termios(pser_inf, serial_fd))  
                 return STATUS_ACCESS_DENIED;  
   
         // Store handle for later use  
         g_rdpdr_device[device_id].handle = serial_fd;  
         tcgetattr(serial_fd, pser_inf->pold_termios);  // Backup original settings  
   
         // Initial configuration.  
         bzero(ptermios, sizeof(ptermios));  
         ptermios->c_cflag = B9600 | CRTSCTS | CS8 | CLOCAL | CREAD;  
         ptermios->c_iflag = IGNPAR;  
         ptermios->c_oflag = 0;  
         ptermios->c_lflag = 0; //non-canonical, no echo  
         ptermios->c_cc[VTIME] = 0;  
         tcsetattr(serial_fd, TCSANOW, ptermios);  
   
         // overload with user settings  
         // -- if there are any  
         if( tmp_inf.baud_rate != 0 ){  
                 dtr = tmp_inf.dtr;  
                 baud_rate = tmp_inf.baud_rate;  
                 parity = tmp_inf.parity;  
                 stop_bits = tmp_inf.stop_bits;  
                 word_length = tmp_inf.word_length;  
                 set_termios();  
383          }          }
384    
385            if (!get_termios(pser_inf, serial_fd))
386                    return STATUS_ACCESS_DENIED;
387    
388            // Store handle for later use
389            g_rdpdr_device[device_id].handle = serial_fd;
390    
391            /* some sane information */
392            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);
393            printf("INFO: use stty to change settings\n");
394    
395    /*      ptermios->c_cflag = B115200 | CRTSCTS | CS8 | CLOCAL | CREAD;
396            ptermios->c_cflag |= CREAD;
397            ptermios->c_lflag |= ICANON;
398            ptermios->c_iflag = IGNPAR | ICRNL;
399    
400            tcsetattr(serial_fd, TCSANOW, ptermios);
401    */
402    
403          *handle = serial_fd;          *handle = serial_fd;
404          return STATUS_SUCCESS;  
405            /* all read and writes should be non blocking */
406            if (fcntl(*handle, F_SETFL, O_NONBLOCK) == -1)
407                    perror("fcntl");
408    
409            return STATUS_SUCCESS;
410  }  }
411    
412  static NTSTATUS  static NTSTATUS
413  serial_close(HANDLE handle)  serial_close(HANDLE handle)
414  {  {
415          close(serial_fd);          g_rdpdr_device[get_device_index(handle)].handle = 0;
416            close(handle);
417          return STATUS_SUCCESS;          return STATUS_SUCCESS;
418  }  }
419    
420  NTSTATUS  NTSTATUS
421  serial_read(HANDLE handle, uint8 *data, uint32 length, uint32 offset, uint32 *result)  serial_read(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
422  {  {
423          long            timeout;          long timeout;
424          SERIAL_DEVICE   *pser_inf;          SERIAL_DEVICE *pser_inf;
425          struct termios  *ptermios;          struct termios *ptermios;
426    
427          timeout         = 0;          timeout = 90;
428          pser_inf        = get_serial_info(handle);          pser_inf = get_serial_info(handle);
429          ptermios        = pser_inf->ptermios;          ptermios = pser_inf->ptermios;
430    
431          // Set timeouts kind of like the windows serial timeout parameters. Multiply timeout          // Set timeouts kind of like the windows serial timeout parameters. Multiply timeout
432          // with requested read size          // with requested read size
433          if (pser_inf->read_total_timeout_multiplier | pser_inf->read_total_timeout_constant)          if (pser_inf->read_total_timeout_multiplier | pser_inf->read_total_timeout_constant)
434          {          {
435                  timeout = (pser_inf->read_total_timeout_multiplier * length + pser_inf->read_total_timeout_constant + 99) / 100;                  timeout =
436          }                          (pser_inf->read_total_timeout_multiplier * length +
437          else if (pser_inf->read_interval_timeout)                           pser_inf->read_total_timeout_constant + 99) / 100;
438          {          }
439                  timeout = (pser_inf->read_interval_timeout * length + 99) / 100;          else if (pser_inf->read_interval_timeout)
440          }          {
441                    timeout = (pser_inf->read_interval_timeout * length + 99) / 100;
442          // If a timeout is set, do a blocking read, which times out after some time.          }
443          // It will make rdesktop less responsive, but it will improve serial performance, by not  
444          // reading one character at a time.          // If a timeout is set, do a blocking read, which times out after some time.
445          if (timeout == 0)          // It will make rdesktop less responsive, but it will improve serial performance, by not
446          {          // reading one character at a time.
447                  ptermios->c_cc[VTIME] = 0;          if (timeout == 0)
448                  ptermios->c_cc[VMIN] = 0;          {
449          }                  ptermios->c_cc[VTIME] = 0;
450          else                  ptermios->c_cc[VMIN] = 0;
451          {          }
452                  ptermios->c_cc[VTIME] = timeout;          else
453                  ptermios->c_cc[VMIN] = 1;          {
454          }                  ptermios->c_cc[VTIME] = timeout;
455          tcsetattr(handle, TCSANOW, ptermios);                  ptermios->c_cc[VMIN] = 1;
456            }
457            tcsetattr(handle, TCSANOW, ptermios);
458    
459    
460          *result = read(handle, data, length);          *result = read(handle, data, length);
461          return STATUS_SUCCESS;  
462            return STATUS_SUCCESS;
463  }  }
464    
465  NTSTATUS  NTSTATUS
466  serial_write(HANDLE handle, uint8 *data, uint32 length, uint32 offset, uint32 *result)  serial_write(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
467  {  {
468          *result = write(handle, data, length);          *result = write(handle, data, length);
469          return STATUS_SUCCESS;          return STATUS_SUCCESS;
470  }  }
471    
472  static NTSTATUS  static NTSTATUS
# Line 456  serial_device_control(HANDLE handle, uin Line 474  serial_device_control(HANDLE handle, uin
474  {  {
475          uint32 result;          uint32 result;
476          uint8 immediate;          uint8 immediate;
477            SERIAL_DEVICE *pser_inf;
478            struct termios *ptermios;
479    
480          if ((request >> 16) != FILE_DEVICE_SERIAL_PORT)          if ((request >> 16) != FILE_DEVICE_SERIAL_PORT)
481                  return STATUS_INVALID_PARAMETER;                  return STATUS_INVALID_PARAMETER;
482    
483            pser_inf = get_serial_info(handle);
484            ptermios = pser_inf->ptermios;
485    
486          /* extract operation */          /* extract operation */
487          request >>= 2;          request >>= 2;
488          request &= 0xfff;          request &= 0xfff;
# Line 469  serial_device_control(HANDLE handle, uin Line 492  serial_device_control(HANDLE handle, uin
492          switch (request)          switch (request)
493          {          {
494                  case SERIAL_SET_BAUD_RATE:                  case SERIAL_SET_BAUD_RATE:
495                          in_uint32_le(in, baud_rate);                          in_uint32_le(in, pser_inf->baud_rate);
496                          set_termios();                          set_termios(pser_inf, handle);
497                          break;                          break;
498                  case SERIAL_GET_BAUD_RATE:                  case SERIAL_GET_BAUD_RATE:
499                          out_uint32_le(out, baud_rate);                          out_uint32_le(out, pser_inf->baud_rate);
500                          break;                          break;
501                  case SERIAL_SET_QUEUE_SIZE:                  case SERIAL_SET_QUEUE_SIZE:
502                          in_uint32_le(in, queue_in_size);                          in_uint32_le(in, pser_inf->queue_in_size);
503                          in_uint32_le(in, queue_out_size);                          in_uint32_le(in, pser_inf->queue_out_size);
504                          break;                          break;
505                  case SERIAL_SET_LINE_CONTROL:                  case SERIAL_SET_LINE_CONTROL:
506                          in_uint8(in, stop_bits);                          in_uint8(in, pser_inf->stop_bits);
507                          in_uint8(in, parity);                          in_uint8(in, pser_inf->parity);
508                          in_uint8(in, word_length);                          in_uint8(in, pser_inf->word_length);
509                          set_termios();                          set_termios(pser_inf, handle);
510                          break;                          break;
511                  case SERIAL_GET_LINE_CONTROL:                  case SERIAL_GET_LINE_CONTROL:
512                          out_uint8(out, stop_bits);                          out_uint8(out, pser_inf->stop_bits);
513                          out_uint8(out, parity);                          out_uint8(out, pser_inf->parity);
514                          out_uint8(out, word_length);                          out_uint8(out, pser_inf->word_length);
515                          break;                          break;
516                  case SERIAL_IMMEDIATE_CHAR:                  case SERIAL_IMMEDIATE_CHAR:
517                          in_uint8(in, immediate);                          in_uint8(in, immediate);
# Line 519  serial_device_control(HANDLE handle, uin Line 542  serial_device_control(HANDLE handle, uin
542                          out_uint8s(out, 20);                          out_uint8s(out, 20);
543                          break;                          break;
544                  case SERIAL_GET_WAIT_MASK:                  case SERIAL_GET_WAIT_MASK:
545                          out_uint32(out, wait_mask);                          out_uint32(out, pser_inf->wait_mask);
546                          break;                          break;
547                  case SERIAL_SET_WAIT_MASK:                  case SERIAL_SET_WAIT_MASK:
548                          in_uint32(in, wait_mask);                          in_uint32(in, pser_inf->wait_mask);
549                          break;                          break;
550                  case SERIAL_SET_DTR:                  case SERIAL_SET_DTR:
551                          dtr = 1;                          pser_inf->dtr = 1;
552                          set_termios();                          set_termios(pser_inf, handle);
553                          break;                          break;
554                  case SERIAL_CLR_DTR:                  case SERIAL_CLR_DTR:
555                          dtr = 0;                          pser_inf->dtr = 0;
556                          set_termios();                          set_termios(pser_inf, handle);
557                          break;                          break;
558  #if 0  #if 0
559                  case SERIAL_WAIT_ON_MASK:                  case SERIAL_WAIT_ON_MASK:
# Line 541  serial_device_control(HANDLE handle, uin Line 564  serial_device_control(HANDLE handle, uin
564                          break;                          break;
565                  case SERIAL_PURGE:                  case SERIAL_PURGE:
566    
567                          printf("SERIAL_PURGE\n");                          printf("SERIAL_PURGE\n");
568                          in_uint32(in, purge_mask);                          in_uint32(in, purge_mask);
569                          if (purge_mask & 0x04) flush_mask |= TCOFLUSH;                          if (purge_mask & 0x04)
570                          if (purge_mask & 0x08) flush_mask |= TCIFLUSH;                                  flush_mask |= TCOFLUSH;
571                          if (flush_mask != 0) tcflush(handle, flush_mask);                          if (purge_mask & 0x08)
572                          if (purge_mask & 0x01) rdpdr_abort_io(handle, 4, STATUS_CANCELLED);                                  flush_mask |= TCIFLUSH;
573                          if (purge_mask & 0x02) rdpdr_abort_io(handle, 3, STATUS_CANCELLED);                          if (flush_mask != 0)
574                          break;                                  tcflush(handle, flush_mask);
575                            if (purge_mask & 0x01)
576                                    rdpdr_abort_io(handle, 4, STATUS_CANCELLED);
577                            if (purge_mask & 0x02)
578                                    rdpdr_abort_io(handle, 3, STATUS_CANCELLED);
579                            break;
580    
581                  case SERIAL_RESET_DEVICE:                  case SERIAL_RESET_DEVICE:
582                  case SERIAL_SET_BREAK_OFF:                  case SERIAL_SET_BREAK_OFF:
# Line 570  serial_device_control(HANDLE handle, uin Line 598  serial_device_control(HANDLE handle, uin
598    
599  /* 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() */
600  BOOL  BOOL
601  serial_get_timeout(uint32 handle, uint32 length, uint32 *timeout, uint32 *itv_timeout)  serial_get_timeout(HANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout)
602  {  {
603          int             index;          int index;
604          SERIAL_DEVICE   *pser_inf;          SERIAL_DEVICE *pser_inf;
605    
606          index = get_device_index(handle);          index = get_device_index(handle);
607    
608          if (g_rdpdr_device[index].device_type != DEVICE_TYPE_SERIAL)          if (g_rdpdr_device[index].device_type != DEVICE_TYPE_SERIAL)
609          {          {
610                  return False;                  return False;
611          }          }
612    
613          pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;          pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;
614    
615          *timeout = pser_inf->read_total_timeout_multiplier * length + pser_inf->read_total_timeout_constant;          *timeout =
616          *itv_timeout = pser_inf->read_interval_timeout;                  pser_inf->read_total_timeout_multiplier * length +
617          return True;                  pser_inf->read_total_timeout_constant;
618            *itv_timeout = pser_inf->read_interval_timeout;
619            return True;
620  }  }
621    
622  DEVICE_FNS serial_fns = {  DEVICE_FNS serial_fns = {

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

  ViewVC Help
Powered by ViewVC 1.1.26