Go to the documentation of this file.00001
00002
00003 #include "ace/TTY_IO.h"
00004 #include "ace/OS_NS_errno.h"
00005 #include "ace/OS_NS_string.h"
00006 #include "ace/OS_NS_strings.h"
00007
00008 #if defined (ACE_HAS_TERMIOS)
00009 # include "ace/os_include/os_termios.h"
00010 #elif defined (ACE_HAS_TERMIO)
00011 # include <termio.h>
00012 #endif
00013
00014 ACE_RCSID (ace,
00015 TTY_IO,
00016 "$Id: TTY_IO.cpp 86739 2009-09-21 07:33:22Z olli $")
00017
00018 namespace
00019 {
00020 const char ACE_TTY_IO_NONE[] = "none";
00021 #if defined (ACE_HAS_TERMIOS) || defined (ACE_HAS_TERMIO) || defined (ACE_WIN32)
00022 const char ACE_TTY_IO_ODD[] = "odd";
00023 const char ACE_TTY_IO_EVEN[] = "even";
00024 #endif
00025 #if defined (ACE_WIN32)
00026 const char ACE_TTY_IO_MARK[] = "mark";
00027 const char ACE_TTY_IO_SPACE[] = "space";
00028 #endif
00029 }
00030
00031 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00032
00033 ACE_TTY_IO::Serial_Params::Serial_Params (void)
00034 {
00035 baudrate = 9600;
00036 xonlim = 0;
00037 xofflim = 0;
00038 readmincharacters = 0;
00039 readtimeoutmsec = 10000;
00040 paritymode = ACE_TTY_IO_NONE;
00041 ctsenb = false;
00042 rtsenb = 0;
00043 xinenb = false;
00044 xoutenb = false;
00045 modem = false;
00046 rcvenb = true;
00047 dsrenb = false;
00048 dtrdisable = false;
00049 databits = 8;
00050 stopbits = 1;
00051 }
00052
00053
00054
00055 int ACE_TTY_IO::control (Control_Mode cmd, Serial_Params *arg) const
00056 {
00057 #if defined (ACE_HAS_TERMIOS) || defined (ACE_HAS_TERMIO)
00058
00059 #if defined (ACE_HAS_TERMIOS)
00060 struct termios devpar;
00061 speed_t newbaudrate = 0;
00062 if (tcgetattr (get_handle () , &devpar) == -1)
00063 #elif defined (TCGETS)
00064 struct termios devpar;
00065 unsigned int newbaudrate = 0;
00066 if (this->ACE_IO_SAP::control (TCGETS, static_cast<void*>(&devpar)) == -1)
00067 #elif defined (TCGETA)
00068 struct termio devpar;
00069 unsigned int newbaudrate = 0;
00070 if (this->ACE_IO_SAP::control (TCGETA, static_cast<void*>(&devpar)) == -1)
00071 #else
00072 errno = ENOSYS;
00073 #endif
00074 return -1;
00075
00076 switch (cmd)
00077 {
00078 case SETPARAMS:
00079 switch (arg->baudrate)
00080 {
00081 #if defined (B0)
00082 case 0: newbaudrate = B0; break;
00083 #endif
00084 #if defined (B50)
00085 case 50: newbaudrate = B50; break;
00086 #endif
00087 #if defined (B75)
00088 case 75: newbaudrate = B75; break;
00089 #endif
00090 #if defined (B110)
00091 case 110: newbaudrate = B110; break;
00092 #endif
00093 #if defined (B134)
00094 case 134: newbaudrate = B134; break;
00095 #endif
00096 #if defined (B150)
00097 case 150: newbaudrate = B150; break;
00098 #endif
00099 #if defined (B200)
00100 case 200: newbaudrate = B200; break;
00101 #endif
00102 #if defined (B300)
00103 case 300: newbaudrate = B300; break;
00104 #endif
00105 #if defined (B600)
00106 case 600: newbaudrate = B600; break;
00107 #endif
00108 #if defined (B1200)
00109 case 1200: newbaudrate = B1200; break;
00110 #endif
00111 #if defined (B1800)
00112 case 1800: newbaudrate = B1800; break;
00113 #endif
00114 #if defined (B2400)
00115 case 2400: newbaudrate = B2400; break;
00116 #endif
00117 #if defined (B4800)
00118 case 4800: newbaudrate = B4800; break;
00119 #endif
00120 #if defined (B9600)
00121 case 9600: newbaudrate = B9600; break;
00122 #endif
00123 #if defined (B19200)
00124 case 19200: newbaudrate = B19200; break;
00125 #endif
00126 #if defined (B38400)
00127 case 38400: newbaudrate = B38400; break;
00128 #endif
00129 #if defined (B56000)
00130 case 56000: newbaudrate = B56000; break;
00131 #endif
00132 #if defined (B57600)
00133 case 57600: newbaudrate = B57600; break;
00134 #endif
00135 #if defined (B76800)
00136 case 76800: newbaudrate = B76800; break;
00137 #endif
00138 #if defined (B115200)
00139 case 115200: newbaudrate = B115200; break;
00140 #endif
00141 #if defined (B128000)
00142 case 128000: newbaudrate = B128000; break;
00143 #endif
00144 #if defined (B153600)
00145 case 153600: newbaudrate = B153600; break;
00146 #endif
00147 #if defined (B230400)
00148 case 230400: newbaudrate = B230400; break;
00149 #endif
00150 #if defined (B307200)
00151 case 307200: newbaudrate = B307200; break;
00152 #endif
00153 #if defined (B256000)
00154 case 256000: newbaudrate = B256000; break;
00155 #endif
00156 #if defined (B460800)
00157 case 460800: newbaudrate = B460800; break;
00158 #endif
00159 #if defined (B500000)
00160 case 500000: newbaudrate = B500000; break;
00161 #endif
00162 #if defined (B576000)
00163 case 576000: newbaudrate = B576000; break;
00164 #endif
00165 #if defined (B921600)
00166 case 921600: newbaudrate = B921600; break;
00167 #endif
00168 #if defined (B1000000)
00169 case 1000000: newbaudrate = B1000000; break;
00170 #endif
00171 #if defined (B1152000)
00172 case 1152000: newbaudrate = B1152000; break;
00173 #endif
00174 #if defined (B1500000)
00175 case 1500000: newbaudrate = B1500000; break;
00176 #endif
00177 #if defined (B2000000)
00178 case 2000000: newbaudrate = B2000000; break;
00179 #endif
00180 #if defined (B2500000)
00181 case 2500000: newbaudrate = B2500000; break;
00182 #endif
00183 #if defined (B3000000)
00184 case 3000000: newbaudrate = B3000000; break;
00185 #endif
00186 #if defined (B3500000)
00187 case 3500000: newbaudrate = B3500000; break;
00188 #endif
00189 #if defined (B4000000)
00190 case 4000000: newbaudrate = B4000000; break;
00191 #endif
00192 default:
00193 return -1;
00194 }
00195
00196 #if defined (ACE_HAS_TERMIOS)
00197
00198 if (cfsetospeed (&devpar, newbaudrate) == -1)
00199 return -1;
00200 if (cfsetispeed (&devpar, newbaudrate) == -1)
00201 return -1;
00202 #else
00203 devpar.c_cflag &= ~CBAUD;
00204 # if defined (CBAUDEX)
00205 devpar.c_cflag &= ~CBAUDEX;
00206 # endif
00207 devpar.c_cflag |= newbaudrate;
00208 #endif
00209
00210 devpar.c_cflag &= ~CSIZE;
00211 switch (arg->databits)
00212 {
00213 case 5:
00214 devpar.c_cflag |= CS5;
00215 break;
00216 case 6:
00217 devpar.c_cflag |= CS6;
00218 break;
00219 case 7:
00220 devpar.c_cflag |= CS7;
00221 break;
00222 case 8:
00223 devpar.c_cflag |= CS8;
00224 break;
00225 default:
00226 return -1;
00227 }
00228
00229 switch (arg->stopbits)
00230 {
00231 case 1:
00232 devpar.c_cflag &= ~CSTOPB;
00233 break;
00234 case 2:
00235 devpar.c_cflag |= CSTOPB;
00236 break;
00237 default:
00238 return -1;
00239 }
00240
00241 if (arg->paritymode)
00242 {
00243 if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_ODD) == 0)
00244 {
00245 devpar.c_cflag |= PARENB;
00246 devpar.c_cflag |= PARODD;
00247 }
00248 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_EVEN) == 0)
00249 {
00250 devpar.c_cflag |= PARENB;
00251 devpar.c_cflag &= ~PARODD;
00252 }
00253 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_NONE) == 0)
00254 devpar.c_cflag &= ~PARENB;
00255 else
00256 return -1;
00257 }
00258 else
00259 {
00260 devpar.c_cflag &= ~PARENB;
00261 }
00262
00263 #if defined (CNEW_RTSCTS)
00264 if ((arg->ctsenb) || (arg->rtsenb))
00265 devpar.c_cflag |= CNEW_RTSCTS;
00266 else
00267 devpar.c_cflag &= ~CNEW_RTSCTS;
00268 #elif defined (CRTSCTS)
00269 if ((arg->ctsenb) || (arg->rtsenb))
00270 devpar.c_cflag |= CRTSCTS;
00271 else
00272 devpar.c_cflag &= ~CRTSCTS;
00273 #endif
00274
00275 #if defined (CREAD)
00276
00277 if (arg->rcvenb)
00278 devpar.c_cflag |= CREAD;
00279 else
00280 devpar.c_cflag &= ~CREAD;
00281 #endif
00282
00283 #if defined (HUPCL)
00284
00285 devpar.c_cflag |= HUPCL;
00286 #endif
00287
00288 #if defined (CLOCAL)
00289
00290 if (arg->modem)
00291 devpar.c_cflag &= ~CLOCAL;
00292 else
00293 devpar.c_cflag |= CLOCAL;
00294 #endif
00295
00296 devpar.c_iflag = IGNPAR | INPCK;
00297 if (arg->databits < 8)
00298 devpar.c_iflag |= ISTRIP;
00299
00300 #if defined (IGNBRK)
00301
00302 if(arg->modem)
00303 devpar.c_iflag &= ~IGNBRK;
00304 else
00305 devpar.c_iflag |= IGNBRK;
00306 #endif
00307
00308 #if defined (IXOFF)
00309
00310 if (arg->xinenb)
00311 devpar.c_iflag |= IXOFF;
00312 else
00313 devpar.c_iflag &= ~IXOFF;
00314 #endif
00315
00316 #if defined (IXON)
00317
00318 if (arg->xoutenb)
00319 devpar.c_iflag |= IXON;
00320 else
00321 devpar.c_iflag &= ~IXON;
00322 #endif
00323
00324 #if defined (ICANON)
00325
00326 devpar.c_lflag &= ~ICANON;
00327 #endif
00328
00329 #if defined (ECHO)
00330
00331 devpar.c_lflag &= ~ECHO;
00332 #endif
00333
00334 #if defined (ECHOE)
00335
00336 devpar.c_lflag &= ~ECHOE;
00337 #endif
00338
00339 #if defined (ISIG)
00340
00341 devpar.c_lflag &= ~ISIG;
00342 #endif
00343
00344 #if defined (OPOST)
00345
00346 devpar.c_oflag &= ~OPOST;
00347 #endif
00348
00349 if (arg->readtimeoutmsec < 0)
00350 {
00351
00352 devpar.c_cc[VTIME] = 0;
00353
00354 if (arg->readmincharacters > UCHAR_MAX)
00355 devpar.c_cc[VMIN] = UCHAR_MAX;
00356 else if (arg->readmincharacters < 1)
00357 devpar.c_cc[VMIN] = 1;
00358 else
00359 devpar.c_cc[VMIN] = static_cast<unsigned char>(arg->readmincharacters);
00360 }
00361 else
00362 {
00363 devpar.c_cc[VTIME] = static_cast<unsigned char>(arg->readtimeoutmsec / 100);
00364
00365 if (arg->readmincharacters > UCHAR_MAX)
00366 devpar.c_cc[VMIN] = UCHAR_MAX;
00367 else if (arg->readmincharacters < 1)
00368 devpar.c_cc[VMIN] = 0;
00369 else
00370 devpar.c_cc[VMIN] = static_cast<unsigned char>(arg->readmincharacters);
00371 }
00372
00373 #if defined (TIOCMGET)
00374 int status;
00375 this->ACE_IO_SAP::control (TIOCMGET, &status);
00376
00377 if (arg->dtrdisable)
00378 status &= ~TIOCM_DTR;
00379 else
00380 status |= TIOCM_DTR;
00381
00382 this->ACE_IO_SAP::control (TIOCMSET, &status);
00383 #endif
00384
00385 #if defined (ACE_HAS_TERMIOS)
00386 return tcsetattr (get_handle (), TCSANOW, &devpar);
00387 #elif defined (TCSETS)
00388 return this->ACE_IO_SAP::control (TCSETS, static_cast<void*>(&devpar));
00389 #elif defined (TCSETA)
00390 return this->ACE_IO_SAP::control (TCSETA, static_cast<void*>(&devpar));
00391 #else
00392 errno = ENOSYS;
00393 return -1;
00394 #endif
00395
00396 case GETPARAMS:
00397 return -1;
00398 default:
00399 return -1;
00400 }
00401 #elif defined (ACE_WIN32)
00402 DCB dcb;
00403 dcb.DCBlength = sizeof dcb;
00404 if (!::GetCommState (this->get_handle (), &dcb))
00405 {
00406 ACE_OS::set_errno_to_last_error ();
00407 return -1;
00408 }
00409
00410 COMMTIMEOUTS timeouts;
00411 if (!::GetCommTimeouts (this->get_handle(), &timeouts))
00412 {
00413 ACE_OS::set_errno_to_last_error ();
00414 return -1;
00415 }
00416
00417 switch (cmd)
00418 {
00419 case SETPARAMS:
00420 dcb.BaudRate = arg->baudrate;
00421
00422 switch (arg->databits)
00423 {
00424 case 4:
00425 case 5:
00426 case 6:
00427 case 7:
00428 case 8:
00429 dcb.ByteSize = arg->databits;
00430 break;
00431 default:
00432 return -1;
00433 }
00434
00435 switch (arg->stopbits)
00436 {
00437 case 1:
00438 dcb.StopBits = ONESTOPBIT;
00439 break;
00440 case 2:
00441 dcb.StopBits = TWOSTOPBITS;
00442 break;
00443 default:
00444 return -1;
00445 }
00446
00447 if (arg->paritymode)
00448 {
00449 dcb.fParity = TRUE;
00450 if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_ODD) == 0)
00451 dcb.Parity = ODDPARITY;
00452 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_EVEN) == 0)
00453 dcb.Parity = EVENPARITY;
00454 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_NONE) == 0)
00455 dcb.Parity = NOPARITY;
00456 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_MARK) == 0)
00457 dcb.Parity = MARKPARITY;
00458 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_SPACE) == 0)
00459 dcb.Parity = SPACEPARITY;
00460 else
00461 return -1;
00462 }
00463 else
00464 {
00465 dcb.fParity = FALSE;
00466 dcb.Parity = NOPARITY;
00467 }
00468
00469
00470 switch (arg->rtsenb)
00471 {
00472 case 1:
00473 dcb.fRtsControl = RTS_CONTROL_ENABLE;
00474 break;
00475 case 2:
00476 dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
00477 break;
00478 case 3:
00479 dcb.fRtsControl = RTS_CONTROL_TOGGLE;
00480 break;
00481 default:
00482 dcb.fRtsControl = RTS_CONTROL_DISABLE;
00483 }
00484
00485
00486 if (arg->ctsenb)
00487 dcb.fOutxCtsFlow = TRUE;
00488 else
00489 dcb.fOutxCtsFlow = FALSE;
00490
00491
00492 if (arg->dsrenb)
00493 dcb.fOutxDsrFlow = TRUE;
00494 else
00495 dcb.fOutxDsrFlow = FALSE;
00496
00497
00498 if (arg->dtrdisable)
00499 dcb.fDtrControl = DTR_CONTROL_DISABLE;
00500 else
00501 dcb.fDtrControl = DTR_CONTROL_ENABLE;
00502
00503
00504 if (arg->xinenb)
00505 dcb.fInX = TRUE;
00506 else
00507 dcb.fInX = FALSE;
00508
00509
00510 if (arg->xoutenb)
00511 dcb.fOutX = TRUE;
00512 else
00513 dcb.fOutX = FALSE;
00514
00515
00516 if (arg->xonlim >= 0)
00517 dcb.XonLim = static_cast<WORD>(arg->xonlim);
00518 if (arg->xofflim >= 0)
00519 dcb.XoffLim = static_cast<WORD>(arg->xofflim);
00520
00521 dcb.fAbortOnError = FALSE;
00522 dcb.fErrorChar = FALSE;
00523 dcb.fNull = FALSE;
00524 dcb.fBinary = TRUE;
00525
00526 if (!::SetCommState (this->get_handle (), &dcb))
00527 {
00528 ACE_OS::set_errno_to_last_error ();
00529 return -1;
00530 }
00531
00532 if (arg->readtimeoutmsec < 0)
00533 {
00534
00535 timeouts.ReadIntervalTimeout = 0;
00536 timeouts.ReadTotalTimeoutMultiplier = 0;
00537 timeouts.ReadTotalTimeoutConstant = 0;
00538 }
00539 else if (arg->readtimeoutmsec == 0)
00540 {
00541
00542 timeouts.ReadIntervalTimeout = MAXDWORD;
00543 timeouts.ReadTotalTimeoutMultiplier = 0;
00544 timeouts.ReadTotalTimeoutConstant = 0;
00545 }
00546 else
00547 {
00548
00549 timeouts.ReadIntervalTimeout = MAXDWORD;
00550 timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
00551 timeouts.ReadTotalTimeoutConstant = arg->readtimeoutmsec;
00552 }
00553
00554 if (!::SetCommTimeouts (this->get_handle (), &timeouts))
00555 {
00556 ACE_OS::set_errno_to_last_error ();
00557 return -1;
00558 }
00559
00560 return 0;
00561
00562 case GETPARAMS:
00563 arg->baudrate = dcb.BaudRate;
00564
00565 switch (dcb.ByteSize)
00566 {
00567 case 4:
00568 case 5:
00569 case 6:
00570 case 7:
00571 case 8:
00572 arg->databits = dcb.ByteSize;
00573 break;
00574 default:
00575 return -1;
00576 }
00577
00578 switch (dcb.StopBits)
00579 {
00580 case ONESTOPBIT:
00581 arg->stopbits = 1;
00582 break;
00583 case TWOSTOPBITS:
00584 arg->stopbits = 2;
00585 break;
00586 default:
00587 return -1;
00588 }
00589
00590 if (!dcb.fParity)
00591 {
00592 arg->paritymode = ACE_TTY_IO_NONE;
00593 }
00594 else
00595 {
00596 switch (dcb.Parity)
00597 {
00598 case ODDPARITY:
00599 arg->paritymode = ACE_TTY_IO_ODD;
00600 break;
00601 case EVENPARITY:
00602 arg->paritymode = ACE_TTY_IO_EVEN;
00603 break;
00604 case NOPARITY:
00605 arg->paritymode = ACE_TTY_IO_NONE;
00606 break;
00607 case MARKPARITY:
00608 arg->paritymode = ACE_TTY_IO_MARK;
00609 break;
00610 case SPACEPARITY:
00611 arg->paritymode = ACE_TTY_IO_SPACE;
00612 break;
00613 default:
00614 return -1;
00615 }
00616 }
00617
00618
00619 switch (dcb.fRtsControl)
00620 {
00621 case RTS_CONTROL_ENABLE:
00622 arg->rtsenb = 1;
00623 break;
00624 case RTS_CONTROL_HANDSHAKE:
00625 arg->rtsenb = 2;
00626 break;
00627 case RTS_CONTROL_TOGGLE:
00628 arg->rtsenb = 3;
00629 break;
00630 case RTS_CONTROL_DISABLE:
00631 arg->rtsenb = 0;
00632 break;
00633 default:
00634 return -1;
00635 }
00636
00637
00638 if (dcb.fOutxCtsFlow)
00639 arg->ctsenb = true;
00640 else
00641 arg->ctsenb = false;
00642
00643
00644 if (dcb.fOutxDsrFlow)
00645 arg->dsrenb = true;
00646 else
00647 arg->dsrenb = false;
00648
00649
00650
00651 switch (dcb.fDtrControl)
00652 {
00653 case DTR_CONTROL_DISABLE:
00654 arg->dtrdisable = true;
00655 break;
00656 case DTR_CONTROL_ENABLE:
00657 arg->dtrdisable = false;
00658 break;
00659 default:
00660 return -1;
00661 }
00662
00663
00664 if (dcb.fInX)
00665 arg->xinenb = true;
00666 else
00667 arg->xinenb = false;
00668
00669
00670 if (dcb.fOutX)
00671 arg->xoutenb = true;
00672 else
00673 arg->xoutenb = false;
00674
00675 arg->xonlim = static_cast<int>(dcb.XonLim);
00676 arg->xofflim = static_cast<int>(dcb.XoffLim);
00677
00678 if (timeouts.ReadIntervalTimeout == 0 &&
00679 timeouts.ReadTotalTimeoutMultiplier == 0 &&
00680 timeouts.ReadTotalTimeoutConstant == 0)
00681 arg->readtimeoutmsec = -1;
00682 else
00683 arg->readtimeoutmsec = timeouts.ReadTotalTimeoutConstant;
00684
00685 return 0;
00686
00687 default:
00688 return -1;
00689
00690 }
00691 #else
00692 ACE_UNUSED_ARG (cmd);
00693 ACE_UNUSED_ARG (arg);
00694 ACE_NOTSUP_RETURN (-1);
00695 #endif
00696 }
00697
00698 #if defined (ACE_NEEDS_DEV_IO_CONVERSION)
00699 ACE_TTY_IO::operator ACE_DEV_IO &()
00700 {
00701 return static_cast<ACE_DEV_IO &>(*this);
00702 }
00703 #endif
00704
00705 ACE_END_VERSIONED_NAMESPACE_DECL