/[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 570 by stargo, Wed Jan 21 18:02:38 2004 UTC revision 755 by stargo, Tue Aug 24 21:37:25 2004 UTC
# Line 53  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[];  #define SERIAL_PURGE_TXABORT 0x00000001
57    #define SERIAL_PURGE_RXABORT 0x00000002
58    #define SERIAL_PURGE_TXCLEAR 0x00000004
59    #define SERIAL_PURGE_RXCLEAR 0x00000008
60    
61    /* SERIAL_WAIT_ON_MASK */
62    #define SERIAL_EV_RXCHAR           0x0001       // Any Character received
63    #define SERIAL_EV_RXFLAG           0x0002       // Received certain character
64    #define SERIAL_EV_TXEMPTY          0x0004       // Transmitt Queue Empty
65    #define SERIAL_EV_CTS              0x0008       // CTS changed state
66    #define SERIAL_EV_DSR              0x0010       // DSR changed state
67    #define SERIAL_EV_RLSD             0x0020       // RLSD changed state
68    #define SERIAL_EV_BREAK            0x0040       // BREAK received
69    #define SERIAL_EV_ERR              0x0080       // Line status error occurred
70    #define SERIAL_EV_RING             0x0100       // Ring signal detected
71    #define SERIAL_EV_PERR             0x0200       // Printer error occured
72    #define SERIAL_EV_RX80FULL         0x0400       // Receive buffer is 80 percent full
73    #define SERIAL_EV_EVENT1           0x0800       // Provider specific event 1
74    #define SERIAL_EV_EVENT2           0x1000       // Provider specific event 2
75    
76    #ifndef CRTSCTS
77    #define CRTSCTS 0
78    #endif
79    
 int serial_fd;  
 struct termios termios;  
80    
81  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;  
82    
83  SERIAL_DEVICE  static SERIAL_DEVICE *
84  *get_serial_info(HANDLE handle)  get_serial_info(HANDLE handle)
85  {  {
86          int     index;          int index;
87    
88          for (index = 0; index < RDPDR_MAX_DEVICES; index++)          for (index = 0; index < RDPDR_MAX_DEVICES; index++)
89          {          {
90                  if (handle == g_rdpdr_device[index].handle)                  if (handle == g_rdpdr_device[index].handle)
91                          return (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;                          return (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;
92          }          }
93          return NULL;          return NULL;
94  }  }
95    
96  BOOL  static BOOL
97  get_termios(SERIAL_DEVICE *pser_inf, HANDLE serial_fd)  get_termios(SERIAL_DEVICE * pser_inf, HANDLE serial_fd)
98  {  {
99          speed_t         speed;          speed_t speed;
100          struct termios  *ptermios;          struct termios *ptermios;
101    
102          ptermios        = pser_inf->ptermios;          ptermios = pser_inf->ptermios;
103    
104          if (tcgetattr(serial_fd, ptermios) == -1)          if (tcgetattr(serial_fd, ptermios) == -1)
105                  return False;                  return False;
106    
107          speed = cfgetispeed(ptermios);          speed = cfgetispeed(ptermios);
108          switch (speed)          switch (speed)
109          {          {
110  #ifdef B75  #ifdef B75
111                  case B75:       pser_inf->baud_rate = 75; break;                  case B75:
112                            pser_inf->baud_rate = 75;
113                            break;
114  #endif  #endif
115  #ifdef B110  #ifdef B110
116                  case B110:      pser_inf->baud_rate = 110; break;                  case B110:
117                            pser_inf->baud_rate = 110;
118                            break;
119  #endif  #endif
120  #ifdef B134  #ifdef B134
121                  case B134:      pser_inf->baud_rate = 134; break;                  case B134:
122                            pser_inf->baud_rate = 134;
123                            break;
124  #endif  #endif
125  #ifdef B150  #ifdef B150
126                  case B150:      pser_inf->baud_rate = 150; break;                  case B150:
127                            pser_inf->baud_rate = 150;
128                            break;
129  #endif  #endif
130  #ifdef B300  #ifdef B300
131                  case B300:      pser_inf->baud_rate = 300; break;                  case B300:
132                            pser_inf->baud_rate = 300;
133                            break;
134  #endif  #endif
135  #ifdef B600  #ifdef B600
136                  case B600:      pser_inf->baud_rate = 600; break;                  case B600:
137                            pser_inf->baud_rate = 600;
138                            break;
139  #endif  #endif
140  #ifdef B1200  #ifdef B1200
141                  case B1200:     pser_inf->baud_rate = 1200; break;                  case B1200:
142                            pser_inf->baud_rate = 1200;
143                            break;
144  #endif  #endif
145  #ifdef B1800  #ifdef B1800
146                  case B1800:     pser_inf->baud_rate = 1800; break;                  case B1800:
147                            pser_inf->baud_rate = 1800;
148                            break;
149  #endif  #endif
150  #ifdef B2400  #ifdef B2400
151                  case B2400:     pser_inf->baud_rate = 2400; break;                  case B2400:
152                            pser_inf->baud_rate = 2400;
153                            break;
154  #endif  #endif
155  #ifdef B4800  #ifdef B4800
156                  case B4800:     pser_inf->baud_rate = 4800; break;                  case B4800:
157                            pser_inf->baud_rate = 4800;
158                            break;
159  #endif  #endif
160  #ifdef B9600  #ifdef B9600
161                  case B9600:     pser_inf->baud_rate = 9600; break;                  case B9600:
162                            pser_inf->baud_rate = 9600;
163                            break;
164  #endif  #endif
165  #ifdef B19200  #ifdef B19200
166                  case B19200:    pser_inf->baud_rate = 19200; break;                  case B19200:
167                            pser_inf->baud_rate = 19200;
168                            break;
169  #endif  #endif
170  #ifdef B38400  #ifdef B38400
171                  case B38400:    pser_inf->baud_rate = 38400; break;                  case B38400:
172                            pser_inf->baud_rate = 38400;
173                            break;
174  #endif  #endif
175  #ifdef B57600  #ifdef B57600
176                  case B57600:    pser_inf->baud_rate = 57600; break;                  case B57600:
177                            pser_inf->baud_rate = 57600;
178                            break;
179  #endif  #endif
180  #ifdef B115200  #ifdef B115200
181                  case B115200:   pser_inf->baud_rate = 115200; break;                  case B115200:
182                            pser_inf->baud_rate = 115200;
183                            break;
184  #endif  #endif
185                  default:        pser_inf->baud_rate = 0; break;                  default:
186          }                          pser_inf->baud_rate = 0;
187                            break;
188            }
189    
190          speed = cfgetospeed(ptermios);          speed = cfgetospeed(ptermios);
191          pser_inf->dtr = (speed == B0) ? 0 : 1;          pser_inf->dtr = (speed == B0) ? 0 : 1;
192    
193            pser_inf->stop_bits = (ptermios->c_cflag & CSTOPB) ? STOP_BITS_2 : STOP_BITS_1;
194            pser_inf->parity =
195                    (ptermios->
196                     c_cflag & PARENB) ? ((ptermios->
197                                           c_cflag & PARODD) ? ODD_PARITY : EVEN_PARITY) : NO_PARITY;
198            switch (ptermios->c_cflag & CSIZE)
199            {
200                    case CS5:
201                            pser_inf->word_length = 5;
202                            break;
203                    case CS6:
204                            pser_inf->word_length = 6;
205                            break;
206                    case CS7:
207                            pser_inf->word_length = 7;
208                            break;
209                    default:
210                            pser_inf->word_length = 8;
211                            break;
212            }
213    
214          pser_inf->stop_bits = (ptermios->c_cflag & CSTOPB) ? STOP_BITS_2 : STOP_BITS_1;          pser_inf->rts = (ptermios->c_cflag & CRTSCTS) ? 1 : 0;
         pser_inf->parity = (ptermios->c_cflag & PARENB) ? ((ptermios->c_cflag & PARODD) ? ODD_PARITY : EVEN_PARITY) : NO_PARITY;  
         switch (ptermios->c_cflag & CSIZE)  
         {  
                 case CS5: pser_inf->word_length = 5; break;  
                 case CS6: pser_inf->word_length = 6; break;  
                 case CS7: pser_inf->word_length = 7; break;  
                 default:  pser_inf->word_length = 8; break;  
         }  
215    
216          return True;          return True;
217  }  }
218    
219  static void  static void
220  set_termios(void)  set_termios(SERIAL_DEVICE * pser_inf, HANDLE serial_fd)
221  {  {
222          speed_t speed;          speed_t speed;
223    
224          switch (baud_rate)          struct termios *ptermios;
225    
226            ptermios = pser_inf->ptermios;
227    
228    
229            switch (pser_inf->baud_rate)
230          {          {
231  #ifdef B75  #ifdef B75
232                  case 75:        speed = B75;break;                  case 75:
233                            speed = B75;
234                            break;
235  #endif  #endif
236  #ifdef B110  #ifdef B110
237                  case 110:       speed = B110;break;                  case 110:
238                            speed = B110;
239                            break;
240  #endif  #endif
241  #ifdef B134  #ifdef B134
242                  case 134:       speed = B134;break;                  case 134:
243                            speed = B134;
244                            break;
245  #endif  #endif
246  #ifdef B150  #ifdef B150
247                  case 150:       speed = B150;break;                  case 150:
248                            speed = B150;
249                            break;
250  #endif  #endif
251  #ifdef B300  #ifdef B300
252                  case 300:       speed = B300;break;                  case 300:
253                            speed = B300;
254                            break;
255  #endif  #endif
256  #ifdef B600  #ifdef B600
257                  case 600:       speed = B600;break;                  case 600:
258                            speed = B600;
259                            break;
260  #endif  #endif
261  #ifdef B1200  #ifdef B1200
262                  case 1200:      speed = B1200;break;                  case 1200:
263                            speed = B1200;
264                            break;
265  #endif  #endif
266  #ifdef B1800  #ifdef B1800
267                  case 1800:      speed = B1800;break;                  case 1800:
268                            speed = B1800;
269                            break;
270  #endif  #endif
271  #ifdef B2400  #ifdef B2400
272                  case 2400:      speed = B2400;break;                  case 2400:
273                            speed = B2400;
274                            break;
275  #endif  #endif
276  #ifdef B4800  #ifdef B4800
277                  case 4800:      speed = B4800;break;                  case 4800:
278                            speed = B4800;
279                            break;
280  #endif  #endif
281  #ifdef B9600  #ifdef B9600
282                  case 9600:      speed = B9600;break;                  case 9600:
283                            speed = B9600;
284                            break;
285  #endif  #endif
286  #ifdef B19200  #ifdef B19200
287                  case 19200:     speed = B19200;break;                  case 19200:
288                            speed = B19200;
289                            break;
290  #endif  #endif
291  #ifdef B38400  #ifdef B38400
292                  case 38400:     speed = B38400;break;                  case 38400:
293                            speed = B38400;
294                            break;
295  #endif  #endif
296  #ifdef B57600  #ifdef B57600
297                  case 57600:     speed = B57600;break;                  case 57600:
298                            speed = B57600;
299                            break;
300  #endif  #endif
301  #ifdef B115200  #ifdef B115200
302                  case 115200:    speed = B115200;break;                  case 115200:
303                            speed = B115200;
304                            break;
305  #endif  #endif
306                  default:        speed = B0;break;                  default:
307                            speed = B0;
308                            break;
309          }          }
310    
311          /* on systems with separate ispeed and ospeed, we can remember the speed          /* on systems with separate ispeed and ospeed, we can remember the speed
312             in ispeed while changing DTR with ospeed */             in ispeed while changing DTR with ospeed */
313          cfsetispeed(&termios, speed);          cfsetispeed(pser_inf->ptermios, speed);
314          cfsetospeed(&termios, dtr ? speed : 0);          cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0);
315    
316          termios.c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE);          ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS);
317          switch (stop_bits)          switch (pser_inf->stop_bits)
318          {          {
319                  case STOP_BITS_2:                  case STOP_BITS_2:
320                          termios.c_cflag |= CSTOPB;                          ptermios->c_cflag |= CSTOPB;
321                          break;                          break;
322          }          }
323          switch (parity)  
324            switch (pser_inf->parity)
325          {          {
326                  case EVEN_PARITY:                  case EVEN_PARITY:
327                          termios.c_cflag |= PARENB;                          ptermios->c_cflag |= PARENB;
328                          break;                          break;
329                  case ODD_PARITY:                  case ODD_PARITY:
330                          termios.c_cflag |= PARENB | PARODD;                          ptermios->c_cflag |= PARENB | PARODD;
331                          break;                          break;
332          }          }
333          switch (word_length)  
334            switch (pser_inf->word_length)
335          {          {
336                  case 5:                  case 5:
337                          termios.c_cflag |= CS5;                          ptermios->c_cflag |= CS5;
338                          break;                          break;
339                  case 6:                  case 6:
340                          termios.c_cflag |= CS6;                          ptermios->c_cflag |= CS6;
341                          break;                          break;
342                  case 7:                  case 7:
343                          termios.c_cflag |= CS7;                          ptermios->c_cflag |= CS7;
344                          break;                          break;
345                  default:                  default:
346                          termios.c_cflag |= CS8;                          ptermios->c_cflag |= CS8;
347                          break;                          break;
348          }          }
349    
350          tcsetattr(serial_fd, TCSANOW, &termios);          if (pser_inf->rts)
351                    ptermios->c_cflag |= CRTSCTS;
352    
353            tcsetattr(serial_fd, TCSANOW, ptermios);
354  }  }
355    
356  /* Enumeration of devices from rdesktop.c        */  /* Enumeration of devices from rdesktop.c        */
357  /* returns numer of units found and initialized. */  /* returns numer of units found and initialized. */
358  /* optarg looks like ':com1=/dev/ttyS0'           */  /* optarg looks like ':com1=/dev/ttyS0'           */
359  /* when it arrives to this function.              */  /* when it arrives to this function.              */
360  /*  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 */  
361  int  int
362  serial_enum_devices(int *id, char* optarg)  serial_enum_devices(uint32 * id, char *optarg)
363  {  {
364          SERIAL_DEVICE* pser_inf;          SERIAL_DEVICE *pser_inf;
   
         int argcount=0;  
         char* pos = optarg;  
         char* pos2;  
         char* pos3;  
365    
366          if(*id<RDPDR_MAX_DEVICES){          char *pos = optarg;
367            char *pos2;
368            int count = 0;
369    
370            // skip the first colon
371            optarg++;
372            while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)
373            {
374                  // Init data structures for device                  // Init data structures for device
375                  pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE));                  pser_inf = (SERIAL_DEVICE *) xmalloc(sizeof(SERIAL_DEVICE));
376                  pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios));                  pser_inf->ptermios = (struct termios *) xmalloc(sizeof(struct termios));
377                    memset(pser_inf->ptermios, 0, sizeof(struct termios));
378                  pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios));                  pser_inf->pold_termios = (struct termios *) xmalloc(sizeof(struct termios));
379                    memset(pser_inf->pold_termios, 0, sizeof(struct termios));
380    
381                    pos2 = next_arg(optarg, '=');
382                    strcpy(g_rdpdr_device[*id].name, optarg);
383    
384                  // skip the first colon                  toupper_str(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_str(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");  
385    
386                    g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);
387                    strcpy(g_rdpdr_device[*id].local_path, pos2);
388                    printf("SERIAL %s to %s\n", g_rdpdr_device[*id].name,
389                           g_rdpdr_device[*id].local_path);
390                  // set device type                  // set device type
391                  g_rdpdr_device[*id].device_type = DEVICE_TYPE_SERIAL;                  g_rdpdr_device[*id].device_type = DEVICE_TYPE_SERIAL;
392                  g_rdpdr_device[*id].pdevice_data = (void *) pser_inf;                  g_rdpdr_device[*id].pdevice_data = (void *) pser_inf;
393                    count++;
394                  (*id)++;                  (*id)++;
395    
396                  return 1;                  optarg = pos;
397          }          }
398          return 0;          return count;
399  }  }
400    
401  NTSTATUS  static NTSTATUS
402  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,
403                  uint32 flags_and_attributes, char *filename, HANDLE * handle)
404  {  {
405          HANDLE          serial_fd;          HANDLE serial_fd;
406          SERIAL_DEVICE   *pser_inf;          SERIAL_DEVICE *pser_inf;
407          struct termios  *ptermios;          struct termios *ptermios;
408          SERIAL_DEVICE   tmp_inf;  
409            pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data;
410          pser_inf        = (SERIAL_DEVICE *) g_rdpdr_device[device_id].pdevice_data;          ptermios = pser_inf->ptermios;
411          ptermios        = pser_inf->ptermios;          serial_fd = open(g_rdpdr_device[device_id].local_path, O_RDWR | O_NOCTTY | O_NONBLOCK);
412          serial_fd       = open(g_rdpdr_device[device_id].local_path, O_RDWR | O_NOCTTY);  
413            if (serial_fd == -1)
414          if (serial_fd == -1)          {
415                  return STATUS_ACCESS_DENIED;                  perror("open");
416                    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();  
417          }          }
418    
419            if (!get_termios(pser_inf, serial_fd))
420            {
421                    printf("INFO: SERIAL %s access denied\n", g_rdpdr_device[device_id].name);
422                    fflush(stdout);
423                    return STATUS_ACCESS_DENIED;
424            }
425    
426            // Store handle for later use
427            g_rdpdr_device[device_id].handle = serial_fd;
428    
429            /* some sane information */
430            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);
431    
432            printf("INFO: use stty to change settings\n");
433    
434    /*      ptermios->c_cflag = B115200 | CRTSCTS | CS8 | CLOCAL | CREAD;
435            ptermios->c_cflag |= CREAD;
436            ptermios->c_lflag |= ICANON;
437            ptermios->c_iflag = IGNPAR | ICRNL;
438    
439            tcsetattr(serial_fd, TCSANOW, ptermios);
440    */
441    
442            cfmakeraw(pser_inf->ptermios);
443          *handle = serial_fd;          *handle = serial_fd;
444          return STATUS_SUCCESS;  
445            /* all read and writes should be non blocking */
446            if (fcntl(*handle, F_SETFL, O_NONBLOCK) == -1)
447                    perror("fcntl");
448    
449            return STATUS_SUCCESS;
450  }  }
451    
452  static NTSTATUS  static NTSTATUS
453  serial_close(HANDLE handle)  serial_close(HANDLE handle)
454  {  {
455          close(serial_fd);          int i = get_device_index(handle);
456            if (i >= 0)
457                    g_rdpdr_device[i].handle = 0;
458            close(handle);
459          return STATUS_SUCCESS;          return STATUS_SUCCESS;
460  }  }
461    
462  NTSTATUS  static NTSTATUS
463  serial_read(HANDLE handle, uint8 *data, uint32 length, uint32 offset, uint32 *result)  serial_read(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
464  {  {
465          long            timeout;          long timeout;
466          SERIAL_DEVICE   *pser_inf;          SERIAL_DEVICE *pser_inf;
467          struct termios  *ptermios;          struct termios *ptermios;
468    
469          timeout         = 0;          timeout = 90;
470          pser_inf        = get_serial_info(handle);          pser_inf = get_serial_info(handle);
471          ptermios        = pser_inf->ptermios;          ptermios = pser_inf->ptermios;
472    
473          // Set timeouts kind of like the windows serial timeout parameters. Multiply timeout          // Set timeouts kind of like the windows serial timeout parameters. Multiply timeout
474          // with requested read size          // with requested read size
475          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)
476          {          {
477                  timeout = (pser_inf->read_total_timeout_multiplier * length + pser_inf->read_total_timeout_constant + 99) / 100;                  timeout =
478          }                          (pser_inf->read_total_timeout_multiplier * length +
479          else if (pser_inf->read_interval_timeout)                           pser_inf->read_total_timeout_constant + 99) / 100;
480          {          }
481                  timeout = (pser_inf->read_interval_timeout * length + 99) / 100;          else if (pser_inf->read_interval_timeout)
482          }          {
483                    timeout = (pser_inf->read_interval_timeout * length + 99) / 100;
484          // If a timeout is set, do a blocking read, which times out after some time.          }
         // It will make rdesktop less responsive, but it will improve serial performance, by not  
         // reading one character at a time.  
         if (timeout == 0)  
         {  
                 ptermios->c_cc[VTIME] = 0;  
                 ptermios->c_cc[VMIN] = 0;  
         }  
         else  
         {  
                 ptermios->c_cc[VTIME] = timeout;  
                 ptermios->c_cc[VMIN] = 1;  
         }  
         tcsetattr(handle, TCSANOW, ptermios);  
485    
486          *result = read(handle, data, length);          // If a timeout is set, do a blocking read, which times out after some time.
487          return STATUS_SUCCESS;          // It will make rdesktop less responsive, but it will improve serial performance, by not
488            // reading one character at a time.
489            if (timeout == 0)
490            {
491                    ptermios->c_cc[VTIME] = 0;
492                    ptermios->c_cc[VMIN] = 0;
493            }
494            else
495            {
496                    ptermios->c_cc[VTIME] = timeout;
497                    ptermios->c_cc[VMIN] = 1;
498            }
499            tcsetattr(handle, TCSANOW, ptermios);
500    
501    
502            *result = read(handle, data, length);
503    
504            //hexdump(data, *read);
505    
506            return STATUS_SUCCESS;
507  }  }
508    
509  NTSTATUS  static NTSTATUS
510  serial_write(HANDLE handle, uint8 *data, uint32 length, uint32 offset, uint32 *result)  serial_write(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
511  {  {
512          *result = write(handle, data, length);          *result = write(handle, data, length);
513          return STATUS_SUCCESS;          return STATUS_SUCCESS;
514  }  }
515    
516  static NTSTATUS  static NTSTATUS
517  serial_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out)  serial_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out)
518  {  {
519    #if 0
520            int flush_mask, purge_mask;
521    #endif
522          uint32 result;          uint32 result;
523          uint8 immediate;          uint8 immediate;
524            SERIAL_DEVICE *pser_inf;
525            struct termios *ptermios;
526    
527          if ((request >> 16) != FILE_DEVICE_SERIAL_PORT)          if ((request >> 16) != FILE_DEVICE_SERIAL_PORT)
528                  return STATUS_INVALID_PARAMETER;                  return STATUS_INVALID_PARAMETER;
529    
530            pser_inf = get_serial_info(handle);
531            ptermios = pser_inf->ptermios;
532    
533          /* extract operation */          /* extract operation */
534          request >>= 2;          request >>= 2;
535          request &= 0xfff;          request &= 0xfff;
# Line 470  serial_device_control(HANDLE handle, uin Line 539  serial_device_control(HANDLE handle, uin
539          switch (request)          switch (request)
540          {          {
541                  case SERIAL_SET_BAUD_RATE:                  case SERIAL_SET_BAUD_RATE:
542                          in_uint32_le(in, baud_rate);                          in_uint32_le(in, pser_inf->baud_rate);
543                          set_termios();                          set_termios(pser_inf, handle);
544                          break;                          break;
545                  case SERIAL_GET_BAUD_RATE:                  case SERIAL_GET_BAUD_RATE:
546                          out_uint32_le(out, baud_rate);                          out_uint32_le(out, pser_inf->baud_rate);
547                          break;                          break;
548                  case SERIAL_SET_QUEUE_SIZE:                  case SERIAL_SET_QUEUE_SIZE:
549                          in_uint32_le(in, queue_in_size);                          in_uint32_le(in, pser_inf->queue_in_size);
550                          in_uint32_le(in, queue_out_size);                          in_uint32_le(in, pser_inf->queue_out_size);
551                          break;                          break;
552                  case SERIAL_SET_LINE_CONTROL:                  case SERIAL_SET_LINE_CONTROL:
553                          in_uint8(in, stop_bits);                          in_uint8(in, pser_inf->stop_bits);
554                          in_uint8(in, parity);                          in_uint8(in, pser_inf->parity);
555                          in_uint8(in, word_length);                          in_uint8(in, pser_inf->word_length);
556                          set_termios();                          set_termios(pser_inf, handle);
557                          break;                          break;
558                  case SERIAL_GET_LINE_CONTROL:                  case SERIAL_GET_LINE_CONTROL:
559                          out_uint8(out, stop_bits);                          out_uint8(out, pser_inf->stop_bits);
560                          out_uint8(out, parity);                          out_uint8(out, pser_inf->parity);
561                          out_uint8(out, word_length);                          out_uint8(out, pser_inf->word_length);
562                          break;                          break;
563                  case SERIAL_IMMEDIATE_CHAR:                  case SERIAL_IMMEDIATE_CHAR:
564                          in_uint8(in, immediate);                          in_uint8(in, immediate);
# Line 520  serial_device_control(HANDLE handle, uin Line 589  serial_device_control(HANDLE handle, uin
589                          out_uint8s(out, 20);                          out_uint8s(out, 20);
590                          break;                          break;
591                  case SERIAL_GET_WAIT_MASK:                  case SERIAL_GET_WAIT_MASK:
592                          out_uint32(out, wait_mask);                          out_uint32(out, pser_inf->wait_mask);
593                          break;                          break;
594                  case SERIAL_SET_WAIT_MASK:                  case SERIAL_SET_WAIT_MASK:
595                          in_uint32(in, wait_mask);                          in_uint32(in, pser_inf->wait_mask);
596                          break;                          break;
597                  case SERIAL_SET_DTR:                  case SERIAL_SET_DTR:
598                          dtr = 1;                          pser_inf->dtr = 1;
599                          set_termios();                          set_termios(pser_inf, handle);
600                          break;                          break;
601                  case SERIAL_CLR_DTR:                  case SERIAL_CLR_DTR:
602                          dtr = 0;                          pser_inf->dtr = 0;
603                          set_termios();                          set_termios(pser_inf, handle);
604                            break;
605                    case SERIAL_SET_RTS:
606                            pser_inf->rts = 1;
607                            set_termios(pser_inf, handle);
608                            break;
609                    case SERIAL_CLR_RTS:
610                            pser_inf->rts = 0;
611                            set_termios(pser_inf, handle);
612                            break;
613                    case SERIAL_GET_MODEMSTATUS:
614                            out_uint32_le(out, 0);  /* Errors */
615                            break;
616                    case SERIAL_GET_COMMSTATUS:
617                            out_uint32_le(out, 0);  /* Errors */
618                            out_uint32_le(out, 0);  /* Hold reasons */
619                            out_uint32_le(out, 0);  /* Amount in in queue */
620                            out_uint32_le(out, 0);  /* Amount in out queue */
621                            out_uint8(out, 0);      /* EofReceived */
622                            out_uint8(out, 0);      /* WaitForImmediate */
623                          break;                          break;
624  #if 0  #if 0
625                    case SERIAL_PURGE:
626                            printf("SERIAL_PURGE\n");
627                            in_uint32(in, purge_mask);
628                            if (purge_mask & 0x04)
629                                    flush_mask |= TCOFLUSH;
630                            if (purge_mask & 0x08)
631                                    flush_mask |= TCIFLUSH;
632                            if (flush_mask != 0)
633                                    tcflush(handle, flush_mask);
634                            if (purge_mask & 0x01)
635                                    rdpdr_abort_io(handle, 4, STATUS_CANCELLED);
636                            if (purge_mask & 0x02)
637                                    rdpdr_abort_io(handle, 3, STATUS_CANCELLED);
638                            break;
639                  case SERIAL_WAIT_ON_MASK:                  case SERIAL_WAIT_ON_MASK:
640                          /* XXX implement me */                          /* XXX implement me */
641                            out_uint32_le(out, pser_inf->wait_mask);
642                          break;                          break;
643                  case SERIAL_SET_BREAK_ON:                  case SERIAL_SET_BREAK_ON:
644                          tcsendbreak(serial_fd, 0);                          tcsendbreak(serial_fd, 0);
645                          break;                          break;
                 case SERIAL_PURGE:  
   
                         printf("SERIAL_PURGE\n");  
                         in_uint32(in, purge_mask);  
                         if (purge_mask & 0x04) flush_mask |= TCOFLUSH;  
                         if (purge_mask & 0x08) flush_mask |= TCIFLUSH;  
                         if (flush_mask != 0) tcflush(handle, flush_mask);  
                         if (purge_mask & 0x01) rdpdr_abort_io(handle, 4, STATUS_CANCELLED);  
                         if (purge_mask & 0x02) rdpdr_abort_io(handle, 3, STATUS_CANCELLED);  
                         break;  
   
646                  case SERIAL_RESET_DEVICE:                  case SERIAL_RESET_DEVICE:
647                  case SERIAL_SET_BREAK_OFF:                  case SERIAL_SET_BREAK_OFF:
                 case SERIAL_SET_RTS:  
                 case SERIAL_CLR_RTS:  
648                  case SERIAL_SET_XOFF:                  case SERIAL_SET_XOFF:
649                  case SERIAL_SET_XON:                  case SERIAL_SET_XON:
650                          /* ignore */                          /* ignore */
651                          break;                          break;
652  #endif  #endif
   
653                  default:                  default:
654                          unimpl("SERIAL IOCTL %d\n", request);                          unimpl("SERIAL IOCTL %d\n", request);
655                          return STATUS_INVALID_PARAMETER;                          return STATUS_INVALID_PARAMETER;
# Line 571  serial_device_control(HANDLE handle, uin Line 660  serial_device_control(HANDLE handle, uin
660    
661  /* 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() */
662  BOOL  BOOL
663  serial_get_timeout(uint32 handle, uint32 length, uint32 *timeout, uint32 *itv_timeout)  serial_get_timeout(HANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout)
664  {  {
665          int             index;          int index;
666          SERIAL_DEVICE   *pser_inf;          SERIAL_DEVICE *pser_inf;
667    
668          index = get_device_index(handle);          index = get_device_index(handle);
669            if (index < 0)
670                    return True;
671    
672          if (g_rdpdr_device[index].device_type != DEVICE_TYPE_SERIAL)          if (g_rdpdr_device[index].device_type != DEVICE_TYPE_SERIAL)
673          {          {
674                  return False;                  return False;
675          }          }
676    
677          pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;          pser_inf = (SERIAL_DEVICE *) g_rdpdr_device[index].pdevice_data;
678    
679          *timeout = pser_inf->read_total_timeout_multiplier * length + pser_inf->read_total_timeout_constant;          *timeout =
680          *itv_timeout = pser_inf->read_interval_timeout;                  pser_inf->read_total_timeout_multiplier * length +
681          return True;                  pser_inf->read_total_timeout_constant;
682            *itv_timeout = pser_inf->read_interval_timeout;
683            return True;
684  }  }
685    
686  DEVICE_FNS serial_fns = {  DEVICE_FNS serial_fns = {

Legend:
Removed from v.570  
changed lines
  Added in v.755

  ViewVC Help
Powered by ViewVC 1.1.26