ACE_TTY_IO Class Reference

Class definitions for platform specific TTY features. More...

#include <TTY_IO.h>

Inheritance diagram for ACE_TTY_IO:

Inheritance graph
[legend]
Collaboration diagram for ACE_TTY_IO:

Collaboration graph
[legend]
List of all members.

Public Types

 SETPARAMS
 Set control parameters.
 GETPARAMS
 Get control parameters.
enum  Control_Mode { SETPARAMS, GETPARAMS }

Public Member Functions

int control (Control_Mode cmd, Serial_Params *arg) const

Classes

struct  Serial_Params

Detailed Description

Class definitions for platform specific TTY features.

This class represents an example interface for a specific device (a serial line). It extends the capability of the underlying DEV_IO class by adding a control method that takes a special structure (Serial_Params) as argument to allow a comfortable user interface (away from that annoying termios structure, which is very specific to UNIX).

Definition at line 36 of file TTY_IO.h.


Member Enumeration Documentation

enum ACE_TTY_IO::Control_Mode

Enumerator:
SETPARAMS  Set control parameters.
GETPARAMS  Get control parameters.

Definition at line 39 of file TTY_IO.h.

00040   {
00041     SETPARAMS,              ///< Set control parameters.
00042     GETPARAMS               ///< Get control parameters.
00043   };


Member Function Documentation

int ACE_TTY_IO::control ( Control_Mode  cmd,
Serial_Params arg 
) const

Interface for reading/writing serial device parameters.

Definition at line 56 of file TTY_IO.cpp.

References ACE_NOTSUP_RETURN, ACE_TTY_IO_NONE, ACE_TTY_IO::Serial_Params::baudrate, ACE_IO_SAP::control(), ACE_TTY_IO::Serial_Params::ctsenb, ACE_TTY_IO::Serial_Params::databits, ACE_TTY_IO::Serial_Params::dsrenb, ACE_TTY_IO::Serial_Params::dtrdisable, ENOSYS, ACE_IO_SAP::get_handle(), GETPARAMS, ACE_TTY_IO::Serial_Params::modem, ACE_TTY_IO::Serial_Params::parityenb, ACE_TTY_IO::Serial_Params::paritymode, ACE_TTY_IO::Serial_Params::rcvenb, ACE_TTY_IO::Serial_Params::readmincharacters, ACE_TTY_IO::Serial_Params::readtimeoutmsec, ACE_TTY_IO::Serial_Params::rtsenb, ACE_OS::set_errno_to_last_error(), SETPARAMS, ACE_TTY_IO::Serial_Params::stopbits, ACE_OS::strcasecmp(), ACE_TTY_IO::Serial_Params::xinenb, ACE_TTY_IO::Serial_Params::xofflim, ACE_TTY_IO::Serial_Params::xonlim, and ACE_TTY_IO::Serial_Params::xoutenb.

00057 {
00058 #if defined (ACE_HAS_TERMIOS) || defined (ACE_HAS_TERMIO)
00059 
00060 #if defined (ACE_HAS_TERMIOS)
00061   struct termios devpar;
00062   speed_t newbaudrate = 0;
00063   if (tcgetattr (get_handle () , &devpar) == -1)
00064 #elif defined (TCGETS)
00065   struct termios devpar;
00066   unsigned int newbaudrate = 0;
00067   if (this->ACE_IO_SAP::control (TCGETS, static_cast<void*>(&devpar)) == -1)
00068 #elif defined (TCGETA)
00069   struct termio devpar;
00070   unsigned int newbaudrate = 0;
00071   if (this->ACE_IO_SAP::control (TCGETA, static_cast<void*>(&devpar)) == -1)
00072 #else
00073   errno = ENOSYS;
00074 #endif /* ACE_HAS_TERMIOS */
00075   return -1;
00076 
00077   switch (cmd)
00078     {
00079     case SETPARAMS:
00080       switch (arg->baudrate)
00081         {
00082 #if defined (B0)
00083         case 0:       newbaudrate = B0;       break;
00084 #endif /* B0 */
00085 #if defined (B50)
00086         case 50:      newbaudrate = B50;      break;
00087 #endif /* B50 */
00088 #if defined (B75)
00089         case 75:      newbaudrate = B75;      break;
00090 #endif /* B75 */
00091 #if defined (B110)
00092         case 110:     newbaudrate = B110;     break;
00093 #endif /* B110 */
00094 #if defined (B134)
00095         case 134:     newbaudrate = B134;     break;
00096 #endif /* B134 */
00097 #if defined (B150)
00098         case 150:     newbaudrate = B150;     break;
00099 #endif /* B150 */
00100 #if defined (B200)
00101         case 200:     newbaudrate = B200;     break;
00102 #endif /* B200 */
00103 #if defined (B300)
00104         case 300:     newbaudrate = B300;     break;
00105 #endif /* B300 */
00106 #if defined (B600)
00107         case 600:     newbaudrate = B600;     break;
00108 #endif /* B600 */
00109 #if defined (B1200)
00110         case 1200:    newbaudrate = B1200;    break;
00111 #endif /* B1200 */
00112 #if defined (B1800)
00113         case 1800:    newbaudrate = B1800;    break;
00114 #endif /* B1800 */
00115 #if defined (B2400)
00116         case 2400:    newbaudrate = B2400;    break;
00117 #endif /* B2400 */
00118 #if defined (B4800)
00119         case 4800:    newbaudrate = B4800;    break;
00120 #endif /* B4800 */
00121 #if defined (B9600)
00122         case 9600:    newbaudrate = B9600;    break;
00123 #endif /* B9600 */
00124 #if defined (B19200)
00125         case 19200:   newbaudrate = B19200;   break;
00126 #endif /* B19200 */
00127 #if defined (B38400)
00128         case 38400:   newbaudrate = B38400;   break;
00129 #endif /* B38400 */
00130 #if defined (B56000)
00131         case 56000:   newbaudrate = B56000;   break;
00132 #endif /* B56000 */
00133 #if defined (B57600)
00134         case 57600:   newbaudrate = B57600;   break;
00135 #endif /* B57600 */
00136 #if defined (B76800)
00137         case 76800:   newbaudrate = B76800;   break;
00138 #endif /* B76800 */
00139 #if defined (B115200)
00140         case 115200:  newbaudrate = B115200;  break;
00141 #endif /* B115200 */
00142 #if defined (B128000)
00143         case 128000:  newbaudrate = B128000;  break;
00144 #endif /* B128000 */
00145 #if defined (B153600)
00146         case 153600:  newbaudrate = B153600;  break;
00147 #endif /* B153600 */
00148 #if defined (B230400)
00149         case 230400:  newbaudrate = B230400;  break;
00150 #endif /* B230400 */
00151 #if defined (B307200)
00152         case 307200:  newbaudrate = B307200;  break;
00153 #endif /* B307200 */
00154 #if defined (B256000)
00155         case 256000:  newbaudrate = B256000;  break;
00156 #endif /* B256000 */
00157 #if defined (B460800)
00158         case 460800:  newbaudrate = B460800;  break;
00159 #endif /* B460800 */
00160 #if defined (B500000)
00161         case 500000:  newbaudrate = B500000;  break;
00162 #endif /* B500000 */
00163 #if defined (B576000)
00164         case 576000:  newbaudrate = B576000;  break;
00165 #endif /* B576000 */
00166 #if defined (B921600)
00167         case 921600:  newbaudrate = B921600;  break;
00168 #endif /* B921600 */
00169 #if defined (B1000000)
00170         case 1000000: newbaudrate = B1000000; break;
00171 #endif /* B1000000 */
00172 #if defined (B1152000)
00173         case 1152000: newbaudrate = B1152000; break;
00174 #endif /* B1152000 */
00175 #if defined (B1500000)
00176         case 1500000: newbaudrate = B1500000; break;
00177 #endif /* B1500000 */
00178 #if defined (B2000000)
00179         case 2000000: newbaudrate = B2000000; break;
00180 #endif /* B2000000 */
00181 #if defined (B2500000)
00182         case 2500000: newbaudrate = B2500000; break;
00183 #endif /* B2500000 */
00184 #if defined (B3000000)
00185         case 3000000: newbaudrate = B3000000; break;
00186 #endif /* B3000000 */
00187 #if defined (B3500000)
00188         case 3500000: newbaudrate = B3500000; break;
00189 #endif /* B3500000 */
00190 #if defined (B4000000)
00191         case 4000000: newbaudrate = B4000000; break;
00192 #endif /* B4000000 */
00193         default:
00194           return -1;
00195         }
00196 
00197 #if defined (ACE_HAS_TERMIOS)
00198       // Can you really have different input and output baud rates?!
00199       if (cfsetospeed (&devpar, newbaudrate) == -1)
00200         return -1;
00201       if (cfsetispeed (&devpar, newbaudrate) == -1)
00202         return -1;
00203 #else
00204       devpar.c_cflag &= ~CBAUD;
00205 # if defined (CBAUDEX)
00206       devpar.c_cflag &= ~CBAUDEX;
00207 # endif /* CBAUDEX */
00208       devpar.c_cflag |= newbaudrate;
00209 #endif /* ACE_HAS_TERMIOS */
00210 
00211       devpar.c_cflag &= ~CSIZE;
00212       switch (arg->databits)
00213         {
00214         case 5:
00215           devpar.c_cflag |= CS5;
00216           break;
00217         case 6:
00218           devpar.c_cflag |= CS6;
00219           break;
00220         case 7:
00221           devpar.c_cflag |= CS7;
00222           break;
00223         case 8:
00224           devpar.c_cflag |= CS8;
00225           break;
00226         default:
00227           return -1;
00228         }
00229 
00230       switch (arg->stopbits)
00231         {
00232         case 1:
00233           devpar.c_cflag &= ~CSTOPB;
00234           break;
00235         case 2:
00236           devpar.c_cflag |=  CSTOPB;
00237           break;
00238         default:
00239           return -1;
00240         }
00241 
00242       if (arg->parityenb && arg->paritymode)
00243         {
00244           if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_ODD) == 0)
00245             {
00246               devpar.c_cflag |=  PARENB;
00247               devpar.c_cflag |=  PARODD;
00248             }
00249           else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_EVEN) == 0)
00250             {
00251               devpar.c_cflag |=  PARENB;
00252               devpar.c_cflag &= ~PARODD;
00253             }
00254           else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_NONE) == 0)
00255             devpar.c_cflag &= ~PARENB;
00256           else
00257             return -1;
00258         }
00259       else
00260         {
00261           devpar.c_cflag &= ~PARENB;
00262         }
00263 
00264 #if defined (CNEW_RTSCTS)
00265       if ((arg->ctsenb) || (arg->rtsenb)) // Enable RTS/CTS protocol
00266         devpar.c_cflag |= CNEW_RTSCTS;
00267       else
00268         devpar.c_cflag &= ~CNEW_RTSCTS;
00269 #elif defined (CRTSCTS)
00270       if ((arg->ctsenb) || (arg->rtsenb)) // Enable RTS/CTS protocol
00271         devpar.c_cflag |= CRTSCTS;
00272       else
00273         devpar.c_cflag &= ~CRTSCTS;
00274 #endif /* NEW_RTSCTS || CRTSCTS */
00275 
00276 #if defined (CREAD)
00277       // Enable/disable receiver
00278       if (arg->rcvenb)
00279         devpar.c_cflag |= CREAD;
00280       else
00281         devpar.c_cflag &= ~CREAD;
00282 #endif /* CREAD */
00283 
00284 #if defined (HUPCL)
00285       // Cause DTR to drop after port close.
00286       devpar.c_cflag |= HUPCL;
00287 #endif /* HUPCL */
00288 
00289 #if defined (CLOCAL)
00290       // If device is not a modem set to local device.
00291       if (arg->modem)
00292         devpar.c_cflag &= ~CLOCAL;
00293       else
00294         devpar.c_cflag |= CLOCAL;
00295 #endif /* CLOCAL */
00296 
00297       devpar.c_iflag = IGNPAR | INPCK;
00298       if (arg->databits < 8)
00299         devpar.c_iflag |= ISTRIP;
00300 
00301 #if defined (IGNBRK)
00302       // If device is not a modem set to ignore break points
00303       if(arg->modem)
00304         devpar.c_iflag &= ~IGNBRK;
00305       else
00306         devpar.c_iflag |= IGNBRK;
00307 #endif /* IGNBRK */
00308 
00309 #if defined (IXOFF)
00310       // Enable/disable software flow control on input
00311       if (arg->xinenb)
00312         devpar.c_iflag |= IXOFF;
00313       else
00314         devpar.c_iflag &= ~IXOFF;
00315 #endif /* IXOFF */
00316 
00317 #if defined (IXON)
00318       // Enable/disable software flow control on output
00319       if (arg->xoutenb)
00320         devpar.c_iflag |= IXON;
00321       else
00322         devpar.c_iflag &= ~IXON;
00323 #endif /* IXON */
00324 
00325 #if defined (ICANON)
00326       // Enable noncanonical input processing mode
00327       devpar.c_lflag &= ~ICANON;
00328 #endif /* ICANON */
00329 
00330 #if defined (ECHO)
00331       // Disable echoing of input characters
00332       devpar.c_lflag &= ~ECHO;
00333 #endif /* ECHO */
00334 
00335 #if defined (ECHOE)
00336       // Disable echoing erase chareacter as BS-SP-BS
00337       devpar.c_lflag &= ~ECHOE;
00338 #endif /* ECHOE */
00339 
00340 #if defined (ISIG)
00341       // Disable SIGINTR, SIGSUSP, SIGDSUSP and SIGQUIT signals
00342       devpar.c_lflag &= ~ISIG;
00343 #endif /* ISIG */
00344 
00345 #if defined (OPOST)
00346       // Disable post-processing of output data
00347       devpar.c_oflag &= ~OPOST;
00348 #endif /* OPOST */
00349 
00350       if (arg->readtimeoutmsec < 0)
00351         {
00352           // Settings for infinite timeout.
00353           devpar.c_cc[VTIME] = 0;
00354           // In case of infinite timeout [VMIN] must be at least 1.
00355           if (arg->readmincharacters > UCHAR_MAX)
00356             devpar.c_cc[VMIN] = UCHAR_MAX;
00357           else if (arg->readmincharacters < 1)
00358             devpar.c_cc[VMIN] = 1;
00359           else
00360             devpar.c_cc[VMIN] = static_cast<unsigned char>(arg->readmincharacters);
00361         }
00362       else
00363         {
00364           devpar.c_cc[VTIME] = static_cast<unsigned char>(arg->readtimeoutmsec / 100);
00365 
00366           if (arg->readmincharacters > UCHAR_MAX)
00367             devpar.c_cc[VMIN] = UCHAR_MAX;
00368           else if (arg->readmincharacters < 1)
00369             devpar.c_cc[VMIN] = 0;
00370           else
00371             devpar.c_cc[VMIN] = static_cast<unsigned char>(arg->readmincharacters);
00372         }
00373 
00374 #if defined (TIOCMGET)
00375       int status;
00376       this->ACE_IO_SAP::control (TIOCMGET, &status);
00377 
00378       if (arg->dtrdisable)
00379         status &= ~TIOCM_DTR;
00380       else
00381         status |=  TIOCM_DTR;
00382 
00383       this->ACE_IO_SAP::control (TIOCMSET, &status);
00384 #endif /* definded (TIOCMGET) */
00385 
00386 #if defined (ACE_HAS_TERMIOS)
00387       return tcsetattr (get_handle (), TCSANOW, &devpar);
00388 #elif defined (TCSETS)
00389       return this->ACE_IO_SAP::control (TCSETS, static_cast<void*>(&devpar));
00390 #elif defined (TCSETA)
00391       return this->ACE_IO_SAP::control (TCSETA, static_cast<void*>(&devpar));
00392 #else
00393       errno = ENOSYS;
00394       return -1;
00395 #endif /* ACE_HAS_TERMIOS */
00396 
00397     case GETPARAMS:
00398       return -1; // Not yet implemented.
00399     default:
00400       return -1; // Wrong cmd.
00401     }
00402 #elif defined (ACE_WIN32)
00403   switch (cmd)
00404     {
00405     case SETPARAMS:
00406       DCB dcb;
00407       dcb.DCBlength = sizeof dcb;
00408       if (!::GetCommState (this->get_handle (), &dcb))
00409         {
00410           ACE_OS::set_errno_to_last_error ();
00411           return -1;
00412         }
00413 
00414       dcb.BaudRate = arg->baudrate;
00415 
00416       switch (arg->databits)
00417         {
00418         case 4:
00419         case 5:
00420         case 6:
00421         case 7:
00422         case 8:
00423           dcb.ByteSize = arg->databits;
00424           break;
00425         default:
00426           return -1;
00427         }
00428 
00429       switch (arg->stopbits)
00430         {
00431         case 1:
00432           dcb.StopBits = ONESTOPBIT;
00433           break;
00434         case 2:
00435           dcb.StopBits = TWOSTOPBITS;
00436           break;
00437         default:
00438           return -1;
00439         }
00440 
00441       if (arg->parityenb && arg->paritymode)
00442         {
00443           dcb.fParity = TRUE;
00444           if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_ODD) == 0)
00445             dcb.Parity = ODDPARITY;
00446           else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_EVEN) == 0)
00447             dcb.Parity = EVENPARITY;
00448           else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_NONE) == 0)
00449             dcb.Parity = NOPARITY;
00450           else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_MARK) == 0)
00451             dcb.Parity = MARKPARITY;
00452           else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_SPACE) == 0)
00453             dcb.Parity = SPACEPARITY;
00454           else
00455             return -1;
00456         }
00457       else
00458         {
00459           dcb.fParity = FALSE;
00460           dcb.Parity = NOPARITY;
00461         }
00462 
00463       // Enable/disable RTS protocol.
00464       switch (arg->rtsenb)
00465         {
00466         case 1:
00467           dcb.fRtsControl = RTS_CONTROL_ENABLE;
00468           break;
00469         case 2:
00470           dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
00471           break;
00472         case 3:
00473           dcb.fRtsControl = RTS_CONTROL_TOGGLE;
00474           break;
00475         default:
00476           dcb.fRtsControl = RTS_CONTROL_DISABLE;
00477         }
00478 
00479       // Enable/disable CTS protocol.
00480       if (arg->ctsenb)
00481         dcb.fOutxCtsFlow = TRUE;
00482       else
00483         dcb.fOutxCtsFlow = FALSE;
00484 
00485       // Enable/disable DSR protocol.
00486       if (arg->dsrenb)
00487         dcb.fOutxDsrFlow = TRUE;
00488       else
00489         dcb.fOutxDsrFlow = FALSE;
00490 
00491       // Disable/enable DTR protocol
00492       if (arg->dtrdisable)
00493         dcb.fDtrControl = DTR_CONTROL_DISABLE;
00494       else
00495         dcb.fDtrControl = DTR_CONTROL_ENABLE;
00496 
00497       // Enable/disable software flow control on input
00498       if (arg->xinenb)
00499         dcb.fInX = TRUE;
00500       else
00501         dcb.fInX = FALSE;
00502 
00503       // Enable/disable software flow control on output
00504       if (arg->xoutenb)
00505         dcb.fOutX = TRUE;
00506       else
00507         dcb.fOutX = FALSE;
00508 
00509       // Always set limits unless set to negative to use default.
00510       if (arg->xonlim >= 0)
00511         dcb.XonLim  = static_cast<WORD>(arg->xonlim);
00512       if (arg->xofflim >= 0)
00513         dcb.XoffLim = static_cast<WORD>(arg->xofflim);
00514 
00515       dcb.fAbortOnError = FALSE;
00516       dcb.fErrorChar = FALSE;
00517       dcb.fNull = FALSE;
00518       dcb.fBinary = TRUE;
00519 
00520       if (!::SetCommState (this->get_handle (), &dcb))
00521         {
00522           ACE_OS::set_errno_to_last_error ();
00523           return -1;
00524         }
00525 
00526       COMMTIMEOUTS timeouts;
00527       if (!::GetCommTimeouts (this->get_handle(), &timeouts))
00528         {
00529           ACE_OS::set_errno_to_last_error ();
00530           return -1;
00531         }
00532 
00533       if (arg->readtimeoutmsec < 0)
00534         {
00535           // Settings for infinite timeout.
00536           timeouts.ReadIntervalTimeout        = 0;
00537           timeouts.ReadTotalTimeoutMultiplier = 0;
00538           timeouts.ReadTotalTimeoutConstant   = 0;
00539         }
00540       else if (arg->readtimeoutmsec == 0)
00541         {
00542           // Return immediately if no data in the input buffer.
00543           timeouts.ReadIntervalTimeout        = MAXDWORD;
00544           timeouts.ReadTotalTimeoutMultiplier = 0;
00545           timeouts.ReadTotalTimeoutConstant   = 0;
00546         }
00547       else
00548         {
00549           // Wait for specified timeout for char to arrive before returning.
00550           timeouts.ReadIntervalTimeout        = MAXDWORD;
00551           timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
00552           timeouts.ReadTotalTimeoutConstant   = arg->readtimeoutmsec;
00553         }
00554 
00555        if (!::SetCommTimeouts (this->get_handle (), &timeouts))
00556          {
00557            ACE_OS::set_errno_to_last_error ();
00558            return -1;
00559          }
00560 
00561        return 0;
00562 
00563     case GETPARAMS:
00564       ACE_NOTSUP_RETURN (-1); // Not yet implemented.
00565     default:
00566       return -1; // Wrong cmd.
00567 
00568     } // arg switch
00569 #else
00570   ACE_UNUSED_ARG (cmd);
00571   ACE_UNUSED_ARG (arg);
00572   ACE_NOTSUP_RETURN (-1);
00573 #endif /* ACE_HAS_TERMIOS || ACE_HAS_TERMIO */
00574 }


The documentation for this class was generated from the following files:
Generated on Tue Feb 2 17:35:50 2010 for ACE by  doxygen 1.4.7