/[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 580 by astrand, Fri Jan 23 08:35:52 2004 UTC revision 669 by astrand, Sun Apr 18 19:16:51 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    
 int serial_fd;  
 struct termios termios;  
76    
77  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;  
78    
79  SERIAL_DEVICE * get_serial_info(HANDLE handle)  static SERIAL_DEVICE *
80    get_serial_info(HANDLE handle)
81  {  {
82          int index;          int index;
83    
# Line 76  SERIAL_DEVICE * get_serial_info(HANDLE h Line 89  SERIAL_DEVICE * get_serial_info(HANDLE h
89          return NULL;          return NULL;
90  }  }
91    
92  BOOL  static BOOL
93  get_termios(SERIAL_DEVICE * pser_inf, HANDLE serial_fd)  get_termios(SERIAL_DEVICE * pser_inf, HANDLE serial_fd)
94  {  {
95          speed_t speed;          speed_t speed;
# Line 194  get_termios(SERIAL_DEVICE * pser_inf, HA Line 207  get_termios(SERIAL_DEVICE * pser_inf, HA
207                          break;                          break;
208          }          }
209    
210            pser_inf->rts = (ptermios->c_cflag & CRTSCTS) ? 1 : 0;
211    
212          return True;          return True;
213  }  }
214    
215  static void  static void
216  set_termios(void)  set_termios(SERIAL_DEVICE * pser_inf, HANDLE serial_fd)
217  {  {
218          speed_t speed;          speed_t speed;
219    
220          switch (baud_rate)          struct termios *ptermios;
221    
222            ptermios = pser_inf->ptermios;
223    
224    
225            switch (pser_inf->baud_rate)
226          {          {
227  #ifdef B75  #ifdef B75
228                  case 75:                  case 75:
# Line 286  set_termios(void) Line 306  set_termios(void)
306    
307          /* on systems with separate ispeed and ospeed, we can remember the speed          /* on systems with separate ispeed and ospeed, we can remember the speed
308             in ispeed while changing DTR with ospeed */             in ispeed while changing DTR with ospeed */
309          cfsetispeed(&termios, speed);          cfsetispeed(pser_inf->ptermios, speed);
310          cfsetospeed(&termios, dtr ? speed : 0);          cfsetospeed(pser_inf->ptermios, pser_inf->dtr ? speed : 0);
311    
312          termios.c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE);          ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS);
313          switch (stop_bits)          switch (pser_inf->stop_bits)
314          {          {
315                  case STOP_BITS_2:                  case STOP_BITS_2:
316                          termios.c_cflag |= CSTOPB;                          ptermios->c_cflag |= CSTOPB;
317                          break;                          break;
318          }          }
319          switch (parity)  
320            switch (pser_inf->parity)
321          {          {
322                  case EVEN_PARITY:                  case EVEN_PARITY:
323                          termios.c_cflag |= PARENB;                          ptermios->c_cflag |= PARENB;
324                          break;                          break;
325                  case ODD_PARITY:                  case ODD_PARITY:
326                          termios.c_cflag |= PARENB | PARODD;                          ptermios->c_cflag |= PARENB | PARODD;
327                          break;                          break;
328          }          }
329          switch (word_length)  
330            switch (pser_inf->word_length)
331          {          {
332                  case 5:                  case 5:
333                          termios.c_cflag |= CS5;                          ptermios->c_cflag |= CS5;
334                          break;                          break;
335                  case 6:                  case 6:
336                          termios.c_cflag |= CS6;                          ptermios->c_cflag |= CS6;
337                          break;                          break;
338                  case 7:                  case 7:
339                          termios.c_cflag |= CS7;                          ptermios->c_cflag |= CS7;
340                          break;                          break;
341                  default:                  default:
342                          termios.c_cflag |= CS8;                          ptermios->c_cflag |= CS8;
343                          break;                          break;
344          }          }
345    
346          tcsetattr(serial_fd, TCSANOW, &termios);          if (pser_inf->rts)
347                    ptermios->c_cflag |= CRTSCTS;
348    
349            tcsetattr(serial_fd, TCSANOW, ptermios);
350  }  }
351    
352  /* Enumeration of devices from rdesktop.c        */  /* Enumeration of devices from rdesktop.c        */
# Line 330  set_termios(void) Line 355  set_termios(void)
355  /* when it arrives to this function.              */  /* when it arrives to this function.              */
356  /* :com1=/dev/ttyS0,com2=/dev/ttyS1 */  /* :com1=/dev/ttyS0,com2=/dev/ttyS1 */
357  int  int
358  serial_enum_devices(int *id, char *optarg)  serial_enum_devices(uint32 * id, char *optarg)
359  {  {
360          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;
361    
# Line 367  serial_enum_devices(int *id, char *optar Line 392  serial_enum_devices(int *id, char *optar
392          return count;          return count;
393  }  }
394    
395  NTSTATUS  static NTSTATUS
396  serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,  serial_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,
397                uint32 flags_and_attributes, char *filename, HANDLE * handle)                uint32 flags_and_attributes, char *filename, HANDLE * handle)
398  {  {
# Line 380  serial_create(uint32 device_id, uint32 a Line 405  serial_create(uint32 device_id, uint32 a
405          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);
406    
407          if (serial_fd == -1)          if (serial_fd == -1)
408            {
409                    perror("open");
410                  return STATUS_ACCESS_DENIED;                  return STATUS_ACCESS_DENIED;
411            }
412    
413          if (!get_termios(pser_inf, serial_fd))          if (!get_termios(pser_inf, serial_fd))
414            {
415                    printf("INFO: SERIAL %s access denied\n", g_rdpdr_device[device_id].name);
416                    fflush(stdout);
417                  return STATUS_ACCESS_DENIED;                  return STATUS_ACCESS_DENIED;
418            }
419    
420          // Store handle for later use          // Store handle for later use
421          g_rdpdr_device[device_id].handle = serial_fd;          g_rdpdr_device[device_id].handle = serial_fd;
422    
423          /* some sane information */          /* some sane information */
424          printf("INFO: SERIAL %s to %s\nINFO: speed %u baud, stop bits %u, parity %u, word length %u bits, dtr %u\n", g_rdpdr_device[device_id].name, g_rdpdr_device[device_id].local_path, pser_inf->baud_rate, pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length, pser_inf->dtr);          printf("INFO: SERIAL %s to %s\nINFO: speed %u baud, stop bits %u, parity %u, word length %u bits, dtr %u, rts %u\n", g_rdpdr_device[device_id].name, g_rdpdr_device[device_id].local_path, pser_inf->baud_rate, pser_inf->stop_bits, pser_inf->parity, pser_inf->word_length, pser_inf->dtr, pser_inf->rts);
425    
426          printf("INFO: use stty to change settings\n");          printf("INFO: use stty to change settings\n");
427    
428          //tcgetattr(serial_fd, pser_inf->ptermios);  /*      ptermios->c_cflag = B115200 | CRTSCTS | CS8 | CLOCAL | CREAD;
429            ptermios->c_cflag |= CREAD;
430            ptermios->c_lflag |= ICANON;
431            ptermios->c_iflag = IGNPAR | ICRNL;
432    
433            tcsetattr(serial_fd, TCSANOW, ptermios);
434    */
435    
436          *handle = serial_fd;          *handle = serial_fd;
437    
438            /* all read and writes should be non blocking */
439            if (fcntl(*handle, F_SETFL, O_NONBLOCK) == -1)
440                    perror("fcntl");
441    
442          return STATUS_SUCCESS;          return STATUS_SUCCESS;
443  }  }
444    
445  static NTSTATUS  static NTSTATUS
446  serial_close(HANDLE handle)  serial_close(HANDLE handle)
447  {  {
448          close(serial_fd);          int i = get_device_index(handle);
449            if (i >= 0)
450                    g_rdpdr_device[i].handle = 0;
451            close(handle);
452          return STATUS_SUCCESS;          return STATUS_SUCCESS;
453  }  }
454    
455  NTSTATUS  static NTSTATUS
456  serial_read(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  serial_read(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
457  {  {
458          long timeout;          long timeout;
459          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;
460          struct termios *ptermios;          struct termios *ptermios;
461    
462          timeout = 0;          timeout = 90;
463          pser_inf = get_serial_info(handle);          pser_inf = get_serial_info(handle);
464          ptermios = pser_inf->ptermios;          ptermios = pser_inf->ptermios;
465    
# Line 444  serial_read(HANDLE handle, uint8 * data, Line 491  serial_read(HANDLE handle, uint8 * data,
491          }          }
492          tcsetattr(handle, TCSANOW, ptermios);          tcsetattr(handle, TCSANOW, ptermios);
493    
494    
495          *result = read(handle, data, length);          *result = read(handle, data, length);
496    
497            //hexdump(data, *read);
498    
499          return STATUS_SUCCESS;          return STATUS_SUCCESS;
500  }  }
501    
502  NTSTATUS  static NTSTATUS
503  serial_write(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  serial_write(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
504  {  {
505          *result = write(handle, data, length);          *result = write(handle, data, length);
# Line 458  serial_write(HANDLE handle, uint8 * data Line 509  serial_write(HANDLE handle, uint8 * data
509  static NTSTATUS  static NTSTATUS
510  serial_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out)  serial_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out)
511  {  {
512    #if 0
513            int flush_mask, purge_mask;
514    #endif
515          uint32 result;          uint32 result;
516          uint8 immediate;          uint8 immediate;
517            SERIAL_DEVICE *pser_inf;
518            struct termios *ptermios;
519    
520          if ((request >> 16) != FILE_DEVICE_SERIAL_PORT)          if ((request >> 16) != FILE_DEVICE_SERIAL_PORT)
521                  return STATUS_INVALID_PARAMETER;                  return STATUS_INVALID_PARAMETER;
522    
523            pser_inf = get_serial_info(handle);
524            ptermios = pser_inf->ptermios;
525    
526          /* extract operation */          /* extract operation */
527          request >>= 2;          request >>= 2;
528          request &= 0xfff;          request &= 0xfff;
# Line 473  serial_device_control(HANDLE handle, uin Line 532  serial_device_control(HANDLE handle, uin
532          switch (request)          switch (request)
533          {          {
534                  case SERIAL_SET_BAUD_RATE:                  case SERIAL_SET_BAUD_RATE:
535                          in_uint32_le(in, baud_rate);                          in_uint32_le(in, pser_inf->baud_rate);
536                          set_termios();                          set_termios(pser_inf, handle);
537                          break;                          break;
538                  case SERIAL_GET_BAUD_RATE:                  case SERIAL_GET_BAUD_RATE:
539                          out_uint32_le(out, baud_rate);                          out_uint32_le(out, pser_inf->baud_rate);
540                          break;                          break;
541                  case SERIAL_SET_QUEUE_SIZE:                  case SERIAL_SET_QUEUE_SIZE:
542                          in_uint32_le(in, queue_in_size);                          in_uint32_le(in, pser_inf->queue_in_size);
543                          in_uint32_le(in, queue_out_size);                          in_uint32_le(in, pser_inf->queue_out_size);
544                          break;                          break;
545                  case SERIAL_SET_LINE_CONTROL:                  case SERIAL_SET_LINE_CONTROL:
546                          in_uint8(in, stop_bits);                          in_uint8(in, pser_inf->stop_bits);
547                          in_uint8(in, parity);                          in_uint8(in, pser_inf->parity);
548                          in_uint8(in, word_length);                          in_uint8(in, pser_inf->word_length);
549                          set_termios();                          set_termios(pser_inf, handle);
550                          break;                          break;
551                  case SERIAL_GET_LINE_CONTROL:                  case SERIAL_GET_LINE_CONTROL:
552                          out_uint8(out, stop_bits);                          out_uint8(out, pser_inf->stop_bits);
553                          out_uint8(out, parity);                          out_uint8(out, pser_inf->parity);
554                          out_uint8(out, word_length);                          out_uint8(out, pser_inf->word_length);
555                          break;                          break;
556                  case SERIAL_IMMEDIATE_CHAR:                  case SERIAL_IMMEDIATE_CHAR:
557                          in_uint8(in, immediate);                          in_uint8(in, immediate);
# Line 523  serial_device_control(HANDLE handle, uin Line 582  serial_device_control(HANDLE handle, uin
582                          out_uint8s(out, 20);                          out_uint8s(out, 20);
583                          break;                          break;
584                  case SERIAL_GET_WAIT_MASK:                  case SERIAL_GET_WAIT_MASK:
585                          out_uint32(out, wait_mask);                          out_uint32(out, pser_inf->wait_mask);
586                          break;                          break;
587                  case SERIAL_SET_WAIT_MASK:                  case SERIAL_SET_WAIT_MASK:
588                          in_uint32(in, wait_mask);                          in_uint32(in, pser_inf->wait_mask);
589                          break;                          break;
590                  case SERIAL_SET_DTR:                  case SERIAL_SET_DTR:
591                          dtr = 1;                          pser_inf->dtr = 1;
592                          set_termios();                          set_termios(pser_inf, handle);
593                          break;                          break;
594                  case SERIAL_CLR_DTR:                  case SERIAL_CLR_DTR:
595                          dtr = 0;                          pser_inf->dtr = 0;
596                          set_termios();                          set_termios(pser_inf, handle);
597                          break;                          break;
598  #if 0                  case SERIAL_SET_RTS:
599                  case SERIAL_WAIT_ON_MASK:                          pser_inf->rts = 1;
600                          /* XXX implement me */                          set_termios(pser_inf, handle);
601                          break;                          break;
602                  case SERIAL_SET_BREAK_ON:                  case SERIAL_CLR_RTS:
603                          tcsendbreak(serial_fd, 0);                          pser_inf->rts = 0;
604                            set_termios(pser_inf, handle);
605                            break;
606                    case SERIAL_GET_MODEMSTATUS:
607                            out_uint32_le(out, 0);  /* Errors */
608                          break;                          break;
609                    case SERIAL_GET_COMMSTATUS:
610                            out_uint32_le(out, 0);  /* Errors */
611                            out_uint32_le(out, 0);  /* Hold reasons */
612                            out_uint32_le(out, 0);  /* Amount in in queue */
613                            out_uint32_le(out, 0);  /* Amount in out queue */
614                            out_uint8(out, 0);      /* EofReceived */
615                            out_uint8(out, 0);      /* WaitForImmediate */
616                            break;
617    #if 0
618                  case SERIAL_PURGE:                  case SERIAL_PURGE:
   
619                          printf("SERIAL_PURGE\n");                          printf("SERIAL_PURGE\n");
620                          in_uint32(in, purge_mask);                          in_uint32(in, purge_mask);
621                          if (purge_mask & 0x04)                          if (purge_mask & 0x04)
# Line 558  serial_device_control(HANDLE handle, uin Line 629  serial_device_control(HANDLE handle, uin
629                          if (purge_mask & 0x02)                          if (purge_mask & 0x02)
630                                  rdpdr_abort_io(handle, 3, STATUS_CANCELLED);                                  rdpdr_abort_io(handle, 3, STATUS_CANCELLED);
631                          break;                          break;
632                    case SERIAL_WAIT_ON_MASK:
633                            /* XXX implement me */
634                            out_uint32_le(out, pser_inf->wait_mask);
635                            break;
636                    case SERIAL_SET_BREAK_ON:
637                            tcsendbreak(serial_fd, 0);
638                            break;
639                  case SERIAL_RESET_DEVICE:                  case SERIAL_RESET_DEVICE:
640                  case SERIAL_SET_BREAK_OFF:                  case SERIAL_SET_BREAK_OFF:
                 case SERIAL_SET_RTS:  
                 case SERIAL_CLR_RTS:  
641                  case SERIAL_SET_XOFF:                  case SERIAL_SET_XOFF:
642                  case SERIAL_SET_XON:                  case SERIAL_SET_XON:
643                          /* ignore */                          /* ignore */
644                          break;                          break;
645  #endif  #endif
   
646                  default:                  default:
647                          unimpl("SERIAL IOCTL %d\n", request);                          unimpl("SERIAL IOCTL %d\n", request);
648                          return STATUS_INVALID_PARAMETER;                          return STATUS_INVALID_PARAMETER;
# Line 579  serial_device_control(HANDLE handle, uin Line 653  serial_device_control(HANDLE handle, uin
653    
654  /* 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() */
655  BOOL  BOOL
656  serial_get_timeout(uint32 handle, uint32 length, uint32 * timeout, uint32 * itv_timeout)  serial_get_timeout(HANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout)
657  {  {
658          int index;          int index;
659          SERIAL_DEVICE *pser_inf;          SERIAL_DEVICE *pser_inf;
660    
661          index = get_device_index(handle);          index = get_device_index(handle);
662            if (index < 0)
663                    return True;
664    
665          if (g_rdpdr_device[index].device_type != DEVICE_TYPE_SERIAL)          if (g_rdpdr_device[index].device_type != DEVICE_TYPE_SERIAL)
666          {          {

Legend:
Removed from v.580  
changed lines
  Added in v.669

  ViewVC Help
Powered by ViewVC 1.1.26