#include <TTY_IO.h>
Inheritance diagram for ACE_TTY_IO:


Public Types | |
| enum | Control_Mode { SETPARAMS, GETPARAMS } |
Public Member Functions | |
| int | control (Control_Mode cmd, Serial_Params *arg) const |
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.
|
|
Definition at line 39 of file TTY_IO.h.
|
|
||||||||||||
|
Interface for reading/writing serial device parameters. Definition at line 56 of file TTY_IO.cpp. References ACE_NOTSUP_RETURN, ACE_TTY_IO_EVEN, ACE_TTY_IO_MARK, ACE_TTY_IO_NONE, ACE_TTY_IO_ODD, ACE_TTY_IO_SPACE, 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 }
|
1.3.6