TTY_IO.cpp
Upload User: wintxp
Upload Date: 2009-12-21
Package Size: 7842k
Code Size: 14k
Category:

TCP/IP Stack

Development Platform:

Unix_Linux

  1. // TTY_IO.cpp,v 4.38 2003/11/01 11:15:18 dhinton Exp
  2. #include "ace/TTY_IO.h"
  3. #include "ace/OS_NS_string.h"
  4. #include "ace/OS_NS_strings.h"
  5. #include "ace/os_include/os_termios.h"
  6. #include "ace/OS_NS_errno.h"
  7. ACE_RCSID (ace,
  8.            TTY_IO,
  9.            "TTY_IO.cpp,v 4.38 2003/11/01 11:15:18 dhinton Exp")
  10. ACE_TTY_IO::Serial_Params::Serial_Params (void)
  11. {
  12.   ACE_OS::memset (this, 0, sizeof *this);
  13. }
  14. // Interface for reading/writing serial device parameters
  15. int
  16. ACE_TTY_IO::control (Control_Mode cmd,
  17.                      Serial_Params *arg) const
  18. {
  19. #if defined (ACE_HAS_TERM_IOCTLS)
  20. #if defined(TCGETS)
  21.   struct termios devpar;
  22. #elif defined(TCGETA)
  23.   struct termio devpar;
  24. #else
  25.   errno = ENOSYS;
  26.   return -1;
  27. #endif
  28.   u_long c_iflag;
  29.   u_long c_oflag;
  30.   u_long c_cflag;
  31.   u_long c_lflag;
  32.   // u_long c_line;
  33.   u_char ivmin_cc4;
  34.   u_char ivtime_cc5;
  35.   c_iflag=0;
  36.   c_oflag=0;
  37.   c_cflag=0;
  38.   c_lflag=0;
  39.   // c_line=0;
  40.   // Get default device parameters.
  41. #if defined (TCGETS)
  42.     if (this->ACE_IO_SAP::control (TCGETS, (void *) &devpar) == -1)
  43. #elif defined (TCGETA)
  44.     if (this->ACE_IO_SAP::control (TCGETA, (void *) &devpar) == -1)
  45. #else
  46.     errno = ENOSYS;
  47. #endif /* TCGETS */
  48.       return -1;
  49.   u_int newbaudrate = 0;
  50.   switch (cmd)
  51.     {
  52.     case SETPARAMS:
  53.       switch (arg->baudrate)
  54.         {
  55. #if defined (B0)
  56. case 0:       newbaudrate = B0;       break;
  57. #endif /* B0 */
  58. #if defined (B50)
  59. case 50:      newbaudrate = B50;      break;
  60. #endif /* B50 */
  61. #if defined (B75)
  62. case 75:      newbaudrate = B75;      break;
  63. #endif /* B75 */
  64. #if defined (B110)
  65. case 110:     newbaudrate = B110;     break;
  66. #endif /* B110 */
  67. #if defined (B134)
  68. case 134:     newbaudrate = B134;     break;
  69. #endif /* B134 */
  70. #if defined (B150)
  71. case 150:     newbaudrate = B150;     break;
  72. #endif /* B150 */
  73. #if defined (B200)
  74. case 200:     newbaudrate = B200;     break;
  75. #endif /* B200 */
  76. #if defined (B300)
  77.         case 300:     newbaudrate = B300;     break;
  78. #endif /* B300 */
  79. #if defined (B600)
  80.         case 600:     newbaudrate = B600;     break;
  81. #endif /* B600 */
  82. #if defined (B1200)
  83.         case 1200:    newbaudrate = B1200;    break;
  84. #endif /* B1200 */
  85. #if defined (B1800)
  86. case 1800:    newbaudrate = B1800;    break;
  87. #endif /* B1800 */
  88. #if defined (B2400)
  89.         case 2400:    newbaudrate = B2400;    break;
  90. #endif /* B2400 */
  91. #if defined (B4800)
  92.         case 4800:    newbaudrate = B4800;    break;
  93. #endif /* B4800 */
  94. #if defined (B9600)
  95.         case 9600:    newbaudrate = B9600;    break;
  96. #endif /* B9600 */
  97. #if defined (B19200)
  98.         case 19200:   newbaudrate = B19200;   break;
  99. #endif /* B19200 */
  100. #if defined (B38400)
  101.         case 38400:   newbaudrate = B38400;   break;
  102. #endif /* B38400 */
  103. #if defined (B56000)
  104. case 56000:   newbaudrate = B56000;   break;
  105. #endif /* B56000 */
  106. #if defined (B57600)
  107.         case 57600:   newbaudrate = B57600;   break;
  108. #endif /* B57600 */
  109. #if defined (B76800)
  110. case 76800:   newbaudrate = B76800;   break;
  111. #endif /* B76800 */
  112. #if defined (B115200)
  113.         case 115200:  newbaudrate = B115200;  break;
  114. #endif /* B115200 */
  115. #if defined (B128000)
  116. case 128000:  newbaudrate = B128000;  break;
  117. #endif /* B128000 */
  118. #if defined (B153600)
  119. case 153600:  newbaudrate = B153600;  break;
  120. #endif /* B153600 */
  121. #if defined (B230400)
  122. case 230400:  newbaudrate = B230400;  break;
  123. #endif /* B230400 */
  124. #if defined (B307200)
  125. case 307200:  newbaudrate = B307200;  break;
  126. #endif /* B307200 */
  127. #if defined (B256000)
  128. case 256000:  newbaudrate = B256000;  break;
  129. #endif /* B256000 */
  130. #if defined (B460800)
  131. case 460800:  newbaudrate = B460800;  break;
  132. #endif /* B460800 */
  133. #if defined (B500000)
  134. case 500000:  newbaudrate = B500000;  break;
  135. #endif /* B500000 */
  136. #if defined (B576000)
  137. case 576000:  newbaudrate = B576000;  break;
  138. #endif /* B576000 */
  139. #if defined (B921600)
  140. case 921600:  newbaudrate = B921600;  break;
  141. #endif /* B921600 */
  142. #if defined (B1000000)
  143. case 1000000: newbaudrate = B1000000; break;
  144. #endif /* B1000000 */
  145. #if defined (B1152000)
  146. case 1152000: newbaudrate = B1152000; break;
  147. #endif /* B1152000 */
  148. #if defined (B1500000)
  149. case 1500000: newbaudrate = B1500000; break;
  150. #endif /* B1500000 */
  151. #if defined (B2000000)
  152. case 2000000: newbaudrate = B2000000; break;
  153. #endif /* B2000000 */
  154. #if defined (B2500000)
  155. case 2500000: newbaudrate = B2500000; break;
  156. #endif /* B2500000 */
  157. #if defined (B3000000)
  158. case 3000000: newbaudrate = B3000000; break;
  159. #endif /* B3000000 */
  160. #if defined (B3500000)
  161. case 3500000: newbaudrate = B3500000; break;
  162. #endif /* B3500000 */
  163. #if defined (B4000000)
  164. case 4000000: newbaudrate = B4000000; break;
  165. #endif /* B4000000 */
  166.         default:
  167.           return -1;
  168.         }
  169. #if defined(ACE_USES_NEW_TERMIOS_STRUCT)
  170.       // @@ Can you really have different input and output baud
  171.       // rates?!
  172.       devpar.c_ispeed = newbaudrate;
  173.       devpar.c_ospeed = newbaudrate;
  174. #else
  175.       c_cflag |= newbaudrate;
  176. #endif /* ACE_USES_NEW_TERMIOS_STRUCT */
  177.       switch (arg->databits)
  178.         {
  179.         case   5:
  180.           c_cflag |= CS5;
  181.           break;
  182.         case   6:
  183.           c_cflag |= CS6;
  184.           break;
  185.         case   7:
  186.           c_cflag |= CS7;
  187.           break;
  188.         case   8:
  189.           c_cflag |= CS8;
  190.           break;
  191.         default:
  192.           return -1;
  193.         }
  194.       switch (arg->stopbits)
  195.         {
  196.         case   1:
  197.           break;
  198.         case   2:
  199.           c_cflag |= CSTOPB;
  200.           break;
  201.         default:
  202.           return -1;
  203.         }
  204.       if (arg->parityenb)
  205.         {
  206.           c_cflag |= PARENB;
  207.           if (ACE_OS::strcasecmp (arg->paritymode, "odd") == 0)
  208.             c_cflag |= PARODD;
  209.         }
  210. #if defined (CRTSCTS)
  211.           // 6/22/00 MLS add rtsenb to if statement
  212.       if ((arg->ctsenb)||(arg->rtsenb)) /* enable CTS/RTS protocoll */
  213.         c_cflag |= CRTSCTS;
  214. #endif /* CRTSCTS */
  215. #if defined (NEW_RTSCTS)
  216.       // 8/30/00 MLS add rtsenb to if statement to support new termios
  217.       if ((arg->ctsenb)||(arg->rtsenb)) /* enable CTS/RTS protocoll */
  218.         c_cflag |= NEW_RTSCTS;
  219. #endif /* CRTSCTS */
  220. #if defined (CREAD)
  221.       if (arg->rcvenb) /* enable receiver */
  222.         c_cflag |= CREAD;
  223. #endif /* CREAD */
  224. #if defined (HUPCL)
  225.       // Cause DTR to be drop after port close MS 7/24/2000;
  226.       c_cflag |= HUPCL;
  227. #endif /* HUPCL */
  228. #if defined (CLOCAL)
  229.       // if device is not a modem set to local device MS  7/24/2000
  230.       if(!arg->modem)
  231.         c_cflag |= CLOCAL;
  232. #endif /* CLOCAL */
  233.       c_oflag = 0;
  234.       c_iflag = IGNPAR | INPCK;
  235.       if (arg->databits < 8)
  236.         c_iflag |= ISTRIP;
  237. #if defined (IGNBRK)
  238.       // if device is not a modem set to ignore break points MS  7/24/2000
  239.       if(!arg->modem)
  240.         c_iflag |= IGNBRK;
  241. #endif /* IGNBRK */
  242.           // 6/22/00 MLS add enable xon/xoff
  243. #if defined (IXON)
  244.       if (arg->xinenb) /* enable XON/XOFF output*/
  245.         c_iflag |= IXON;
  246. #endif /* IXON */
  247. #if defined (IXOFF)
  248.       if (arg->xoutenb) /* enable XON/XOFF input*/
  249.         c_iflag |= IXOFF;
  250. #endif /* IXOFF */
  251.       c_lflag = 0;
  252.       ivmin_cc4 = (u_char) arg->readmincharacters;
  253.       ivtime_cc5= (u_char) (arg->readtimeoutmsec / 100);
  254.       devpar.c_iflag = c_iflag;
  255.       devpar.c_oflag = c_oflag;
  256.       devpar.c_cflag = c_cflag;
  257.       devpar.c_lflag = c_lflag;
  258.       devpar.c_cc[ACE_VMIN] = ivmin_cc4;
  259.       devpar.c_cc[ACE_VTIME] = ivtime_cc5;
  260. #if defined(TIOCMGET)
  261.       // ensure DTR is enabled
  262.       int status;
  263.       this->ACE_IO_SAP::control (TIOCMGET, &status);
  264.        if (arg->dtrdisable)
  265.          status &= ~TIOCM_DTR;
  266.        else
  267.          status |= TIOCM_DTR;
  268.       this->ACE_IO_SAP::control (TIOCMSET,&status);
  269. #endif /* definded (TIOCMGET) */
  270. #if defined(TCSETS)
  271.       return this->ACE_IO_SAP::control (TCSETS,
  272.                                         (void *) &devpar);
  273. #elif defined(TCSETA)
  274.       return this->ACE_IO_SAP::control (TCSETA,
  275.                                         (void *) &devpar);
  276. #else
  277.       errno = ENOSYS;
  278.       return -1;
  279. #endif
  280.     case GETPARAMS:
  281.       return -1; // Not yet implemented.
  282.     default:
  283.       return -1; // Wrong cmd.
  284.     }
  285. #elif defined (ACE_WIN32)
  286.   switch (cmd)
  287.     {
  288.     case SETPARAMS:
  289.       DCB dcb;
  290.       dcb.DCBlength = sizeof dcb;
  291.       if (!::GetCommState (this->get_handle (), &dcb))
  292.         {
  293.           ACE_OS::set_errno_to_last_error ();
  294.           return -1;
  295.         }
  296. /*SadreevAA
  297.       switch (arg->baudrate)
  298.         {
  299.         case   300: dcb.BaudRate = CBR_300; break;
  300.         case   600: dcb.BaudRate = CBR_600; break;
  301.         case  1200: dcb.BaudRate = CBR_1200; break;
  302.         case  2400: dcb.BaudRate = CBR_2400; break;
  303.         case  4800: dcb.BaudRate = CBR_4800; break;
  304.         case  9600: dcb.BaudRate = CBR_9600; break;
  305.         case  19200: dcb.BaudRate = CBR_19200; break;
  306.         case  38400: dcb.BaudRate = CBR_38400; break;
  307. //          case  56000: dcb.BaudRate = CBR_56000; break;
  308.         case  57600: dcb.BaudRate = CBR_57600; break;
  309.         case  115200: dcb.BaudRate = CBR_115200; break;
  310. //          case  128000: dcb.BaudRate = CBR_128000; break;
  311. //          case  256000: dcb.BaudRate = CBR_256000; break;
  312.         default:  return -1;
  313.         }
  314. */
  315.       dcb.BaudRate = arg->baudrate;
  316.       switch (arg->databits)
  317.         {
  318.         case 4:
  319.         case 5:
  320.         case 6:
  321.         case 7:
  322.         case 8:
  323.           dcb.ByteSize = u_char (arg->databits);
  324.           break;
  325.         default:
  326.           return -1;
  327.         }
  328.       switch (arg->stopbits)
  329.         {
  330.         case 1:
  331.           dcb.StopBits = ONESTOPBIT;
  332.           break;
  333.         case 2:
  334.           dcb.StopBits = TWOSTOPBITS;
  335.           break;
  336.         default:
  337.           return -1;
  338.         }
  339.       // 6/22/00 MLS enabled extra paths for win32 parity checking.
  340.       if (arg->parityenb)
  341.         {
  342.           dcb.fParity = TRUE;
  343.           if (ACE_OS::strcasecmp (arg->paritymode, "odd") == 0)
  344.             dcb.Parity = ODDPARITY;
  345.           else if (ACE_OS::strcasecmp (arg->paritymode, "even") == 0)
  346.             dcb.Parity = EVENPARITY;
  347.           else if (ACE_OS::strcasecmp (arg->paritymode, "mark") == 0)
  348.             dcb.Parity = MARKPARITY;
  349.           else if (ACE_OS::strcasecmp (arg->paritymode, "space") == 0)
  350.             dcb.Parity = SPACEPARITY;
  351.           else
  352.             dcb.Parity = NOPARITY;
  353.         }
  354.       else
  355.         {
  356.           dcb.fParity = FALSE;
  357.           dcb.Parity = NOPARITY;
  358.         }
  359.       if (arg->ctsenb) // enable CTS protocol.
  360.         dcb.fOutxCtsFlow = TRUE;
  361.       else
  362.         dcb.fOutxCtsFlow = FALSE;
  363.             // SadreevAA
  364.       if (arg->dsrenb) // enable DSR protocol.
  365.         dcb.fOutxDsrFlow = TRUE;
  366.       else
  367.         dcb.fOutxDsrFlow = FALSE;
  368.       // 6/22/00 MLS add  great flexibility for win32
  369.       //                     pulled rts out of ctsenb
  370.       switch (arg->rtsenb) // enable RTS protocol.
  371.         {
  372.         case 1:
  373.           dcb.fRtsControl = RTS_CONTROL_ENABLE;
  374.           break;
  375.         case 2:
  376.           dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
  377.           break;
  378.         case 3:
  379.           dcb.fRtsControl = RTS_CONTROL_TOGGLE;
  380.           break;
  381.         default:
  382.           dcb.fRtsControl = RTS_CONTROL_DISABLE;
  383.         }
  384.       // 6/22/00 MLS add enable xon/xoff
  385.       if (arg->xinenb) // enable XON/XOFF for reception
  386.         dcb.fInX = TRUE; // Fixed by SadreevAA
  387.       else
  388.         dcb.fInX = FALSE; // Fixed by SadreevAA
  389.       if (arg->xoutenb) // enable XON/XOFF for transmission
  390.         dcb.fOutX = TRUE;
  391.       else
  392.         dcb.fOutX = FALSE;
  393.       // always set limits unless set to -1 to use default
  394.       // 6/22/00 MLS add xon/xoff limits
  395.       if (arg->xonlim != -1)
  396.         dcb.XonLim  = arg->xonlim;
  397.       if (arg->xofflim != -1)
  398.         dcb.XoffLim  = arg->xofflim;
  399.      if (arg->dtrdisable)
  400.        dcb.fDtrControl = DTR_CONTROL_DISABLE;
  401.      else
  402.        dcb.fDtrControl = DTR_CONTROL_ENABLE;
  403.       dcb.fAbortOnError = FALSE;
  404.       dcb.fErrorChar = FALSE;
  405.       dcb.fNull = FALSE;
  406.       dcb.fBinary = TRUE;
  407.       if (!::SetCommState (this->get_handle (), &dcb))
  408.         {
  409.           ACE_OS::set_errno_to_last_error ();
  410.           return -1;
  411.         }
  412.       // 2/13/97 BWF added drop out timer
  413.       // modified time out to operate correctly with when delay
  414.       // is requested or no delay is requestes
  415.       COMMTIMEOUTS timeouts;
  416.       if (!::GetCommTimeouts (this->get_handle(), &timeouts))
  417.         {
  418.           ACE_OS::set_errno_to_last_error ();
  419.           return -1;
  420.         }
  421.       if (arg->readtimeoutmsec == 0)
  422.         {
  423.           // return immediately if no data in the input buffer
  424.           timeouts.ReadIntervalTimeout = MAXDWORD;
  425.           timeouts.ReadTotalTimeoutMultiplier = 0;
  426.           timeouts.ReadTotalTimeoutConstant   = 0;
  427.         }
  428.       else
  429.         {
  430.           // Wait for specified  time-out for char to arrive
  431.           // before returning.
  432.           timeouts.ReadIntervalTimeout        = MAXDWORD;
  433.           timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
  434.           // ensure specified timeout is below MAXDWORD
  435.           // We don't test arg->readtimeoutmsec against MAXDWORD
  436.           // directly to avoid a warning in the case DWORD is
  437.           // unsigned.  Ensure specified timeout is below MAXDWORD use
  438.           // MAXDWORD as indicator for infinite timeout.
  439.           DWORD dw = arg->readtimeoutmsec;
  440.           if (dw < MAXDWORD)
  441.             {
  442.               // Wait for specified time-out for char to arrive before
  443.               // returning.
  444.               timeouts.ReadIntervalTimeout = MAXDWORD;
  445.               timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
  446.               timeouts.ReadTotalTimeoutConstant = dw;
  447.             }
  448.           else
  449.             {
  450.               // settings for infinite timeout
  451.               timeouts.ReadIntervalTimeout = 0;
  452.               timeouts.ReadTotalTimeoutMultiplier = 0;
  453.               timeouts.ReadTotalTimeoutConstant = 0;
  454.             }
  455.           }
  456.        if (!::SetCommTimeouts (this->get_handle (), &timeouts))
  457.          {
  458.            ACE_OS::set_errno_to_last_error ();
  459.            return -1;
  460.          }
  461.        return 0;
  462.     case GETPARAMS:
  463.       ACE_NOTSUP_RETURN (-1); // Not yet implemented.
  464.     default:
  465.       return -1; // Wrong cmd.
  466.     } // arg switch
  467. #else
  468.   ACE_UNUSED_ARG (cmd);
  469.   ACE_UNUSED_ARG (arg);
  470.   ACE_NOTSUP_RETURN (-1);
  471. #endif /* ACE_HAS_TERM_IOCTLS */
  472. }
  473. #if defined (ACE_NEEDS_DEV_IO_CONVERSION)
  474. ACE_TTY_IO::operator ACE_DEV_IO &()
  475. {
  476.   return (ACE_DEV_IO &) *this;
  477. }
  478. #endif /* ACE_NEEDS_DEV_IO_CONVERSION */