/[rdesktop]/jpeg/rdesktop/trunk/serial.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /jpeg/rdesktop/trunk/serial.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

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

  ViewVC Help
Powered by ViewVC 1.1.26