Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

TTY_IO.cpp

Go to the documentation of this file.
00001 #include "ace_pch.h"
00002 // $Id: TTY_IO.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:22 chad Exp $
00003 
00004 #include "ace/TTY_IO.h"
00005 
00006 ACE_RCSID(ace, TTY_IO, "$Id: TTY_IO.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:22 chad Exp $")
00007 
00008 ACE_TTY_IO::Serial_Params::Serial_Params (void)
00009 {
00010   ACE_OS::memset (this, 0, sizeof *this);
00011 }
00012 
00013 // Interface for reading/writing serial device parameters
00014 
00015 int
00016 ACE_TTY_IO::control (Control_Mode cmd,
00017                      Serial_Params *arg) const
00018 {
00019 #if defined (ACE_HAS_TERM_IOCTLS)
00020 #if defined(TCGETS)
00021   struct termios devpar;
00022 #elif defined(TCGETA)
00023   struct termio devpar;
00024 #else
00025   errno = ENOSYS;
00026   return -1;
00027 #endif
00028   u_long c_iflag;
00029   u_long c_oflag;
00030   u_long c_cflag;
00031   u_long c_lflag;
00032   // u_long c_line;
00033   u_char ivmin_cc4;
00034   u_char ivtime_cc5;
00035 
00036   c_iflag=0;
00037   c_oflag=0;
00038   c_cflag=0;
00039   c_lflag=0;
00040   // c_line=0;
00041 
00042   // Get default device parameters.
00043 
00044 #if defined (TCGETS)
00045     if (this->ACE_IO_SAP::control (TCGETS, (void *) &devpar) == -1)
00046 #elif defined (TCGETA)
00047     if (this->ACE_IO_SAP::control (TCGETA, (void *) &devpar) == -1)
00048 #else
00049     errno = ENOSYS;
00050 #endif /* TCGETS */
00051       return -1;
00052 
00053   u_int newbaudrate = 0;
00054 
00055   switch (cmd)
00056     {
00057     case SETPARAMS:
00058       switch (arg->baudrate)
00059         {
00060 #if defined (B0)
00061         case 0:       newbaudrate = B0;       break;
00062 #endif /* B0 */
00063 #if defined (B50)
00064         case 50:      newbaudrate = B50;      break;
00065 #endif /* B50 */
00066 #if defined (B75)
00067         case 75:      newbaudrate = B75;      break;
00068 #endif /* B75 */
00069 #if defined (B110)
00070         case 110:     newbaudrate = B110;     break;
00071 #endif /* B110 */
00072 #if defined (B134)
00073         case 134:     newbaudrate = B134;     break;
00074 #endif /* B134 */
00075 #if defined (B150)
00076         case 150:     newbaudrate = B150;     break;
00077 #endif /* B150 */
00078 #if defined (B200)
00079         case 200:     newbaudrate = B200;     break;
00080 #endif /* B200 */
00081 #if defined (B300)
00082         case 300:     newbaudrate = B300;     break;
00083 #endif /* B300 */
00084 #if defined (B600)
00085         case 600:     newbaudrate = B600;     break;
00086 #endif /* B600 */
00087 #if defined (B1200)
00088         case 1200:    newbaudrate = B1200;    break;
00089 #endif /* B1200 */
00090 #if defined (B1800)
00091         case 1800:    newbaudrate = B1800;    break;
00092 #endif /* B1800 */
00093 #if defined (B2400)
00094         case 2400:    newbaudrate = B2400;    break;
00095 #endif /* B2400 */
00096 #if defined (B4800)
00097         case 4800:    newbaudrate = B4800;    break;
00098 #endif /* B4800 */
00099 #if defined (B9600)
00100         case 9600:    newbaudrate = B9600;    break;
00101 #endif /* B9600 */
00102 #if defined (B19200)
00103         case 19200:   newbaudrate = B19200;   break;
00104 #endif /* B19200 */
00105 #if defined (B38400)
00106         case 38400:   newbaudrate = B38400;   break;
00107 #endif /* B38400 */
00108 #if defined (B56000)
00109         case 56000:   newbaudrate = B56000;   break;
00110 #endif /* B56000 */
00111 #if defined (B57600)
00112         case 57600:   newbaudrate = B57600;   break;
00113 #endif /* B57600 */
00114 #if defined (B76800)
00115         case 76800:   newbaudrate = B76800;   break;
00116 #endif /* B76800 */
00117 #if defined (B115200)
00118         case 115200:  newbaudrate = B115200;  break;
00119 #endif /* B115200 */
00120 #if defined (B128000)
00121         case 128000:  newbaudrate = B128000;  break;
00122 #endif /* B128000 */
00123 #if defined (B153600)
00124         case 153600:  newbaudrate = B153600;  break;
00125 #endif /* B153600 */
00126 #if defined (B230400)
00127         case 230400:  newbaudrate = B230400;  break;
00128 #endif /* B230400 */
00129 #if defined (B307200)
00130         case 307200:  newbaudrate = B307200;  break;
00131 #endif /* B307200 */
00132 #if defined (B256000)
00133         case 256000:  newbaudrate = B256000;  break;
00134 #endif /* B256000 */
00135 #if defined (B460800)
00136         case 460800:  newbaudrate = B460800;  break;
00137 #endif /* B460800 */
00138 #if defined (B500000)
00139         case 500000:  newbaudrate = B500000;  break;
00140 #endif /* B500000 */
00141 #if defined (B576000)
00142         case 576000:  newbaudrate = B576000;  break;
00143 #endif /* B576000 */
00144 #if defined (B921600)
00145         case 921600:  newbaudrate = B921600;  break;
00146 #endif /* B921600 */
00147 #if defined (B1000000)
00148         case 1000000: newbaudrate = B1000000; break;
00149 #endif /* B1000000 */
00150 #if defined (B1152000)
00151         case 1152000: newbaudrate = B1152000; break;
00152 #endif /* B1152000 */
00153 #if defined (B1500000)
00154         case 1500000: newbaudrate = B1500000; break;
00155 #endif /* B1500000 */
00156 #if defined (B2000000)
00157         case 2000000: newbaudrate = B2000000; break;
00158 #endif /* B2000000 */
00159 #if defined (B2500000)
00160         case 2500000: newbaudrate = B2500000; break;
00161 #endif /* B2500000 */
00162 #if defined (B3000000)
00163         case 3000000: newbaudrate = B3000000; break;
00164 #endif /* B3000000 */
00165 #if defined (B3500000)
00166         case 3500000: newbaudrate = B3500000; break;
00167 #endif /* B3500000 */
00168 #if defined (B4000000)
00169         case 4000000: newbaudrate = B4000000; break;
00170 #endif /* B4000000 */
00171         default:
00172           return -1;
00173         }
00174 
00175 #if defined(ACE_USES_NEW_TERMIOS_STRUCT)
00176       // @@ Can you really have different input and output baud
00177       // rates?!
00178       devpar.c_ispeed = newbaudrate;
00179       devpar.c_ospeed = newbaudrate;
00180 #else
00181       c_cflag |= newbaudrate;
00182 #endif /* ACE_USES_NEW_TERMIOS_STRUCT */
00183 
00184       switch (arg->databits)
00185         {
00186         case   5:
00187           c_cflag |= CS5;
00188           break;
00189         case   6:
00190           c_cflag |= CS6;
00191           break;
00192         case   7:
00193           c_cflag |= CS7;
00194           break;
00195         case   8:
00196           c_cflag |= CS8;
00197           break;
00198         default:
00199           return -1;
00200         }
00201 
00202       switch (arg->stopbits)
00203         {
00204         case   1:
00205           break;
00206         case   2:
00207           c_cflag |= CSTOPB;
00208           break;
00209         default:
00210           return -1;
00211         }
00212       if (arg->parityenb)
00213         {
00214           c_cflag |= PARENB;
00215           if (ACE_OS::strcasecmp (arg->paritymode, "odd") == 0)
00216             c_cflag |= PARODD;
00217         }
00218 
00219 #if defined (CRTSCTS)
00220           // 6/22/00 MLS add rtsenb to if statement
00221       if ((arg->ctsenb)||(arg->rtsenb)) /* enable CTS/RTS protocoll */
00222         c_cflag |= CRTSCTS;
00223 #endif /* CRTSCTS */
00224 #if defined (NEW_RTSCTS)
00225       // 8/30/00 MLS add rtsenb to if statement to support new termios
00226       if ((arg->ctsenb)||(arg->rtsenb)) /* enable CTS/RTS protocoll */
00227         c_cflag |= NEW_RTSCTS;
00228 #endif /* CRTSCTS */
00229 #if defined (CREAD)
00230       if (arg->rcvenb) /* enable receiver */
00231         c_cflag |= CREAD;
00232 #endif /* CREAD */
00233 
00234 
00235 #if defined (HUPCL)
00236       // Cause DTR to be drop after port close MS 7/24/2000;
00237       c_cflag |= HUPCL;
00238 #endif /* HUPCL */
00239 
00240 #if defined (CLOCAL)
00241       // if device is not a modem set to local device MS  7/24/2000
00242       if(!arg->modem)
00243         c_cflag |= CLOCAL;
00244 #endif /* CLOCAL */
00245 
00246       c_oflag = 0;
00247       c_iflag = IGNPAR | INPCK;
00248       if (arg->databits < 8)
00249         c_iflag |= ISTRIP;
00250 #if defined (IGNBRK)
00251       // if device is not a modem set to ignore break points MS  7/24/2000
00252       if(!arg->modem)
00253         c_iflag |= IGNBRK;
00254 #endif /* IGNBRK */
00255           // 6/22/00 MLS add enable xon/xoff
00256 #if defined (IXON)
00257       if (arg->xinenb) /* enable XON/XOFF output*/
00258         c_iflag |= IXON;
00259 #endif /* IXON */
00260 #if defined (IXOFF)
00261       if (arg->xoutenb) /* enable XON/XOFF input*/
00262         c_iflag |= IXOFF;
00263 #endif /* IXOFF */
00264       c_lflag = 0;
00265 
00266       ivmin_cc4 = (u_char) 0;
00267       ivtime_cc5= (u_char) (arg->readtimeoutmsec / 100);
00268       devpar.c_iflag = c_iflag;
00269       devpar.c_oflag = c_oflag;
00270       devpar.c_cflag = c_cflag;
00271       devpar.c_lflag = c_lflag;
00272       devpar.c_cc[ACE_VMIN] = ivmin_cc4;
00273       devpar.c_cc[ACE_VTIME] = ivtime_cc5;
00274 
00275 #if defined(TIOCMGET)
00276       // ensure DTR is enabled
00277       int status;
00278       this->ACE_IO_SAP::control(TIOCMGET, &status);
00279       status |= TIOCM_DTR;
00280       this->ACE_IO_SAP::control(TIOCMSET,&status);
00281 #endif /* definded (TIOCMGET) */
00282 
00283 #if defined(TCSETS)
00284       return this->ACE_IO_SAP::control (TCSETS,
00285                                         (void *) &devpar);
00286 #elif defined(TCSETA)
00287       return this->ACE_IO_SAP::control (TCSETA,
00288                                         (void *) &devpar);
00289 #else
00290       errno = ENOSYS;
00291       return -1;
00292 #endif
00293     case GETPARAMS:
00294       return -1; // Not yet implemented.
00295     default:
00296       return -1; // Wrong cmd.
00297     }
00298 #elif defined (ACE_WIN32)
00299   switch (cmd)
00300     {
00301     case SETPARAMS:
00302       DCB dcb;
00303       dcb.DCBlength = sizeof dcb;
00304       if (!::GetCommState (this->get_handle (), &dcb)) 
00305         {
00306           ACE_OS::set_errno_to_last_error ();
00307           return -1; 
00308         }
00309 /*SadreevAA
00310       switch (arg->baudrate)
00311         {
00312         case   300: dcb.BaudRate = CBR_300; break;
00313         case   600: dcb.BaudRate = CBR_600; break;
00314         case  1200: dcb.BaudRate = CBR_1200; break;
00315         case  2400: dcb.BaudRate = CBR_2400; break;
00316         case  4800: dcb.BaudRate = CBR_4800; break;
00317         case  9600: dcb.BaudRate = CBR_9600; break;
00318         case  19200: dcb.BaudRate = CBR_19200; break;
00319         case  38400: dcb.BaudRate = CBR_38400; break;
00320 //          case  56000: dcb.BaudRate = CBR_56000; break;
00321         case  57600: dcb.BaudRate = CBR_57600; break;
00322         case  115200: dcb.BaudRate = CBR_115200; break;
00323 //          case  128000: dcb.BaudRate = CBR_128000; break;
00324 //          case  256000: dcb.BaudRate = CBR_256000; break;
00325         default:  return -1;
00326         }
00327 */  
00328       dcb.BaudRate = arg->baudrate;
00329       switch (arg->databits)
00330         {
00331         case 4:
00332         case 5:
00333         case 6:
00334         case 7:
00335         case 8:
00336           dcb.ByteSize = u_char (arg->databits);
00337           break;
00338         default:
00339           return -1;
00340         }
00341 
00342       switch (arg->stopbits)
00343         {
00344         case 1:
00345           dcb.StopBits = ONESTOPBIT;
00346           break;
00347         case 2:
00348           dcb.StopBits = TWOSTOPBITS;
00349           break;
00350         default:
00351           return -1;
00352         }
00353 
00354 
00355       // 6/22/00 MLS enabled extra paths for win32 parity checking.
00356       if (arg->parityenb)
00357         {
00358           dcb.fParity = TRUE;
00359           if (ACE_OS::strcasecmp (arg->paritymode, "odd") == 0)
00360             dcb.Parity = ODDPARITY;
00361           else if (ACE_OS::strcasecmp (arg->paritymode, "even") == 0)
00362             dcb.Parity = EVENPARITY;
00363           else if (ACE_OS::strcasecmp (arg->paritymode, "mark") == 0)
00364             dcb.Parity = MARKPARITY;
00365           else if (ACE_OS::strcasecmp (arg->paritymode, "space") == 0)
00366             dcb.Parity = SPACEPARITY;
00367           else
00368             dcb.Parity = NOPARITY;
00369         }
00370       else
00371         {
00372           dcb.fParity = FALSE;
00373           dcb.Parity = NOPARITY;
00374         }
00375 
00376       if (arg->ctsenb) // enable CTS protocol.
00377         dcb.fOutxCtsFlow = TRUE;
00378       else
00379         dcb.fOutxCtsFlow = FALSE;
00380 
00381             // SadreevAA
00382       if (arg->dsrenb) // enable DSR protocol.
00383         dcb.fOutxDsrFlow = TRUE;
00384       else
00385         dcb.fOutxDsrFlow = FALSE;
00386 
00387       // 6/22/00 MLS add  great flexibility for win32
00388       //                     pulled rts out of ctsenb
00389       switch (arg->rtsenb) // enable RTS protocol.
00390         {
00391         case 1:
00392           dcb.fRtsControl = RTS_CONTROL_ENABLE;
00393           break;
00394         case 2:
00395           dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
00396           break;
00397         case 3:
00398           dcb.fRtsControl = RTS_CONTROL_TOGGLE;
00399           break;
00400         default:
00401           dcb.fRtsControl = RTS_CONTROL_DISABLE;
00402         }
00403 
00404       // 6/22/00 MLS add enable xon/xoff
00405       if (arg->xinenb) // enable XON/XOFF for reception
00406         dcb.fInX = TRUE; // Fixed by SadreevAA
00407       else
00408         dcb.fInX = FALSE; // Fixed by SadreevAA
00409 
00410       if (arg->xoutenb) // enable XON/XOFF for transmission
00411         dcb.fOutX = TRUE;
00412       else
00413         dcb.fOutX = FALSE;
00414 
00415       // always set limits unless set to -1 to use default
00416       // 6/22/00 MLS add xon/xoff limits
00417       if (arg->xonlim != -1)
00418         dcb.XonLim  = arg->xonlim;
00419       if (arg->xofflim != -1)
00420         dcb.XoffLim  = arg->xofflim;
00421 
00422       dcb.fDtrControl = DTR_CONTROL_ENABLE;
00423       dcb.fAbortOnError = FALSE;
00424       dcb.fErrorChar = FALSE; 
00425       dcb.fNull = FALSE; 
00426       dcb.fBinary = TRUE;
00427       if (!::SetCommState (this->get_handle (), &dcb))
00428         {
00429           ACE_OS::set_errno_to_last_error ();
00430           return -1; 
00431         }
00432 
00433       // 2/13/97 BWF added drop out timer
00434       // modified time out to operate correctly with when delay
00435       // is requested or no delay is requestes
00436       COMMTIMEOUTS timeouts;
00437       if (!::GetCommTimeouts (this->get_handle(), &timeouts))
00438         {
00439           ACE_OS::set_errno_to_last_error ();
00440           return -1; 
00441         }
00442 
00443       if (arg->readtimeoutmsec == 0)
00444         {
00445           // return immediately if no data in the input buffer
00446           timeouts.ReadIntervalTimeout = MAXDWORD; 
00447           timeouts.ReadTotalTimeoutMultiplier = 0;
00448           timeouts.ReadTotalTimeoutConstant   = 0;
00449         }
00450       else
00451         {
00452           // Wait for specified  time-out for char to arrive
00453           // before returning.
00454           timeouts.ReadIntervalTimeout        = MAXDWORD;
00455           timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
00456 
00457           // ensure specified timeout is below MAXDWORD
00458 
00459           // We don't test arg->readtimeoutmsec against MAXDWORD
00460           // directly to avoid a warning in the case DWORD is
00461           // unsigned.  Ensure specified timeout is below MAXDWORD use
00462           // MAXDWORD as indicator for infinite timeout.
00463           DWORD dw = arg->readtimeoutmsec;
00464           if (dw < MAXDWORD)
00465             {
00466               // Wait for specified time-out for char to arrive before
00467               // returning.
00468               timeouts.ReadIntervalTimeout = MAXDWORD;
00469               timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
00470               timeouts.ReadTotalTimeoutConstant = dw;
00471             }
00472           else
00473             {
00474               // settings for infinite timeout
00475               timeouts.ReadIntervalTimeout = 0;
00476               timeouts.ReadTotalTimeoutMultiplier = 0;
00477               timeouts.ReadTotalTimeoutConstant = 0;
00478             }
00479           }
00480   
00481        if (!::SetCommTimeouts (this->get_handle (), &timeouts))
00482          {
00483            ACE_OS::set_errno_to_last_error ();
00484            return -1; 
00485          }
00486  
00487        return 0;
00488 
00489     case GETPARAMS:
00490       ACE_NOTSUP_RETURN (-1); // Not yet implemented.
00491     default:
00492       return -1; // Wrong cmd.
00493 
00494     } // arg switch
00495 #else
00496   ACE_UNUSED_ARG (cmd);
00497   ACE_UNUSED_ARG (arg);
00498   ACE_NOTSUP_RETURN (-1);
00499 #endif /* ACE_HAS_TERM_IOCTLS */
00500 }
00501 
00502 #if defined (ACE_NEEDS_DEV_IO_CONVERSION)
00503 ACE_TTY_IO::operator ACE_DEV_IO &()
00504 {
00505   return (ACE_DEV_IO &) *this;
00506 }
00507 #endif /* ACE_NEEDS_DEV_IO_CONVERSION */

Generated on Mon Jun 16 11:21:59 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002