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 "TTY_IO.cpp,v 4.56 2006/03/29 16:30:37 olli Exp")
00017
00018 #if defined (ACE_HAS_TERMIOS) || defined (ACE_HAS_TERMIO) || defined (ACE_WIN32)
00019 namespace
00020 {
00021 const char ACE_TTY_IO_ODD[] = "odd";
00022 const char ACE_TTY_IO_EVEN[] = "even";
00023 #if defined (ACE_WIN32)
00024 const char ACE_TTY_IO_MARK[] = "mark";
00025 const char ACE_TTY_IO_SPACE[] = "space";
00026 #endif
00027 }
00028 #endif
00029
00030 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00031
00032 ACE_TTY_IO::Serial_Params::Serial_Params (void)
00033 {
00034 ACE_OS::memset (this, 0, sizeof *this);
00035 }
00036
00037
00038
00039 int ACE_TTY_IO::control (Control_Mode cmd, Serial_Params *arg) const
00040 {
00041 #if defined (ACE_HAS_TERMIOS) || defined (ACE_HAS_TERMIO)
00042
00043 #if defined (ACE_HAS_TERMIOS)
00044 struct termios devpar;
00045 speed_t newbaudrate = 0;
00046 if (tcgetattr (get_handle () , &devpar) == -1)
00047 #elif defined (TCGETS)
00048 struct termios devpar;
00049 unsigned int newbaudrate = 0;
00050 if (this->ACE_IO_SAP::control (TCGETS, static_cast<void*>(&devpar)) == -1)
00051 #elif defined (TCGETA)
00052 struct termio devpar;
00053 unsigned int newbaudrate = 0;
00054 if (this->ACE_IO_SAP::control (TCGETA, static_cast<void*>(&devpar)) == -1)
00055 #else
00056 errno = ENOSYS;
00057 #endif
00058 return -1;
00059
00060 switch (cmd)
00061 {
00062 case SETPARAMS:
00063 switch (arg->baudrate)
00064 {
00065 #if defined (B0)
00066 case 0: newbaudrate = B0; break;
00067 #endif
00068 #if defined (B50)
00069 case 50: newbaudrate = B50; break;
00070 #endif
00071 #if defined (B75)
00072 case 75: newbaudrate = B75; break;
00073 #endif
00074 #if defined (B110)
00075 case 110: newbaudrate = B110; break;
00076 #endif
00077 #if defined (B134)
00078 case 134: newbaudrate = B134; break;
00079 #endif
00080 #if defined (B150)
00081 case 150: newbaudrate = B150; break;
00082 #endif
00083 #if defined (B200)
00084 case 200: newbaudrate = B200; break;
00085 #endif
00086 #if defined (B300)
00087 case 300: newbaudrate = B300; break;
00088 #endif
00089 #if defined (B600)
00090 case 600: newbaudrate = B600; break;
00091 #endif
00092 #if defined (B1200)
00093 case 1200: newbaudrate = B1200; break;
00094 #endif
00095 #if defined (B1800)
00096 case 1800: newbaudrate = B1800; break;
00097 #endif
00098 #if defined (B2400)
00099 case 2400: newbaudrate = B2400; break;
00100 #endif
00101 #if defined (B4800)
00102 case 4800: newbaudrate = B4800; break;
00103 #endif
00104 #if defined (B9600)
00105 case 9600: newbaudrate = B9600; break;
00106 #endif
00107 #if defined (B19200)
00108 case 19200: newbaudrate = B19200; break;
00109 #endif
00110 #if defined (B38400)
00111 case 38400: newbaudrate = B38400; break;
00112 #endif
00113 #if defined (B56000)
00114 case 56000: newbaudrate = B56000; break;
00115 #endif
00116 #if defined (B57600)
00117 case 57600: newbaudrate = B57600; break;
00118 #endif
00119 #if defined (B76800)
00120 case 76800: newbaudrate = B76800; break;
00121 #endif
00122 #if defined (B115200)
00123 case 115200: newbaudrate = B115200; break;
00124 #endif
00125 #if defined (B128000)
00126 case 128000: newbaudrate = B128000; break;
00127 #endif
00128 #if defined (B153600)
00129 case 153600: newbaudrate = B153600; break;
00130 #endif
00131 #if defined (B230400)
00132 case 230400: newbaudrate = B230400; break;
00133 #endif
00134 #if defined (B307200)
00135 case 307200: newbaudrate = B307200; break;
00136 #endif
00137 #if defined (B256000)
00138 case 256000: newbaudrate = B256000; break;
00139 #endif
00140 #if defined (B460800)
00141 case 460800: newbaudrate = B460800; break;
00142 #endif
00143 #if defined (B500000)
00144 case 500000: newbaudrate = B500000; break;
00145 #endif
00146 #if defined (B576000)
00147 case 576000: newbaudrate = B576000; break;
00148 #endif
00149 #if defined (B921600)
00150 case 921600: newbaudrate = B921600; break;
00151 #endif
00152 #if defined (B1000000)
00153 case 1000000: newbaudrate = B1000000; break;
00154 #endif
00155 #if defined (B1152000)
00156 case 1152000: newbaudrate = B1152000; break;
00157 #endif
00158 #if defined (B1500000)
00159 case 1500000: newbaudrate = B1500000; break;
00160 #endif
00161 #if defined (B2000000)
00162 case 2000000: newbaudrate = B2000000; break;
00163 #endif
00164 #if defined (B2500000)
00165 case 2500000: newbaudrate = B2500000; break;
00166 #endif
00167 #if defined (B3000000)
00168 case 3000000: newbaudrate = B3000000; break;
00169 #endif
00170 #if defined (B3500000)
00171 case 3500000: newbaudrate = B3500000; break;
00172 #endif
00173 #if defined (B4000000)
00174 case 4000000: newbaudrate = B4000000; break;
00175 #endif
00176 default:
00177 return -1;
00178 }
00179
00180 #if defined (ACE_HAS_TERMIOS)
00181
00182 if (cfsetospeed (&devpar, newbaudrate) == -1)
00183 return -1;
00184 if (cfsetispeed (&devpar, newbaudrate) == -1)
00185 return -1;
00186 #else
00187 devpar.c_cflag &= ~CBAUD;
00188 # if defined (CBAUDEX)
00189 devpar.c_cflag &= ~CBAUDEX;
00190 # endif
00191 devpar.c_cflag |= newbaudrate;
00192 #endif
00193
00194 devpar.c_cflag &= ~CSIZE;
00195 switch (arg->databits)
00196 {
00197 case 5:
00198 devpar.c_cflag |= CS5;
00199 break;
00200 case 6:
00201 devpar.c_cflag |= CS6;
00202 break;
00203 case 7:
00204 devpar.c_cflag |= CS7;
00205 break;
00206 case 8:
00207 devpar.c_cflag |= CS8;
00208 break;
00209 default:
00210 return -1;
00211 }
00212
00213 switch (arg->stopbits)
00214 {
00215 case 1:
00216 devpar.c_cflag &= ~CSTOPB;
00217 break;
00218 case 2:
00219 devpar.c_cflag |= CSTOPB;
00220 break;
00221 default:
00222 return -1;
00223 }
00224
00225 if (arg->parityenb && arg->paritymode)
00226 {
00227 devpar.c_cflag |= PARENB;
00228 if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_ODD) == 0)
00229 devpar.c_cflag |= PARODD;
00230 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_EVEN) == 0)
00231 devpar.c_cflag &= ~PARODD;
00232 else
00233 return -1;
00234 }
00235 else
00236 {
00237 devpar.c_cflag &= ~PARENB;
00238 }
00239
00240 #if defined (CNEW_RTSCTS)
00241 if ((arg->ctsenb) || (arg->rtsenb))
00242 devpar.c_cflag |= CNEW_RTSCTS;
00243 else
00244 devpar.c_cflag &= ~CNEW_RTSCTS;
00245 #elif defined (CRTSCTS)
00246 if ((arg->ctsenb) || (arg->rtsenb))
00247 devpar.c_cflag |= CRTSCTS;
00248 else
00249 devpar.c_cflag &= ~CRTSCTS;
00250 #endif
00251
00252 #if defined (CREAD)
00253
00254 if (arg->rcvenb)
00255 devpar.c_cflag |= CREAD;
00256 else
00257 devpar.c_cflag &= ~CREAD;
00258 #endif
00259
00260 #if defined (HUPCL)
00261
00262 devpar.c_cflag |= HUPCL;
00263 #endif
00264
00265 #if defined (CLOCAL)
00266
00267 if (arg->modem)
00268 devpar.c_cflag &= ~CLOCAL;
00269 else
00270 devpar.c_cflag |= CLOCAL;
00271 #endif
00272
00273 devpar.c_iflag = IGNPAR | INPCK;
00274 if (arg->databits < 8)
00275 devpar.c_iflag |= ISTRIP;
00276
00277 #if defined (IGNBRK)
00278
00279 if(arg->modem)
00280 devpar.c_iflag &= ~IGNBRK;
00281 else
00282 devpar.c_iflag |= IGNBRK;
00283 #endif
00284
00285 #if defined (IXOFF)
00286
00287 if (arg->xinenb)
00288 devpar.c_iflag |= IXOFF;
00289 else
00290 devpar.c_iflag &= ~IXOFF;
00291 #endif
00292
00293 #if defined (IXON)
00294
00295 if (arg->xoutenb)
00296 devpar.c_iflag |= IXON;
00297 else
00298 devpar.c_iflag &= ~IXON;
00299 #endif
00300
00301 #if defined (ICANON)
00302
00303 devpar.c_lflag &= ~ICANON;
00304 #endif
00305
00306 if (arg->readtimeoutmsec < 0)
00307 {
00308
00309 devpar.c_cc[VTIME] = 0;
00310
00311 if (arg->readmincharacters > UCHAR_MAX)
00312 devpar.c_cc[VMIN] = UCHAR_MAX;
00313 else if (arg->readmincharacters < 1)
00314 devpar.c_cc[VMIN] = 1;
00315 else
00316 devpar.c_cc[VMIN] = static_cast<unsigned char>(arg->readmincharacters);
00317 }
00318 else
00319 {
00320 devpar.c_cc[VTIME] = static_cast<unsigned char>(arg->readtimeoutmsec / 100);
00321
00322 if (arg->readmincharacters > UCHAR_MAX)
00323 devpar.c_cc[VMIN] = UCHAR_MAX;
00324 else if (arg->readmincharacters < 1)
00325 devpar.c_cc[VMIN] = 0;
00326 else
00327 devpar.c_cc[VMIN] = static_cast<unsigned char>(arg->readmincharacters);
00328 }
00329
00330 #if defined (TIOCMGET) && !defined (__Lynx__)
00331
00332 int status;
00333 this->ACE_IO_SAP::control (TIOCMGET, &status);
00334
00335 if (arg->dtrdisable)
00336 status &= ~TIOCM_DTR;
00337 else
00338 status |= TIOCM_DTR;
00339
00340 this->ACE_IO_SAP::control (TIOCMSET, &status);
00341 #endif
00342
00343 #if defined (ACE_HAS_TERMIOS)
00344 return tcsetattr (get_handle (), TCSANOW, &devpar);
00345 #elif defined (TCSETS)
00346 return this->ACE_IO_SAP::control (TCSETS, static_cast<void*>(&devpar));
00347 #elif defined (TCSETA)
00348 return this->ACE_IO_SAP::control (TCSETA, static_cast<void*>(&devpar));
00349 #else
00350 errno = ENOSYS;
00351 return -1;
00352 #endif
00353
00354 case GETPARAMS:
00355 return -1;
00356 default:
00357 return -1;
00358 }
00359 #elif defined (ACE_WIN32)
00360 switch (cmd)
00361 {
00362 case SETPARAMS:
00363 DCB dcb;
00364 dcb.DCBlength = sizeof dcb;
00365 if (!::GetCommState (this->get_handle (), &dcb))
00366 {
00367 ACE_OS::set_errno_to_last_error ();
00368 return -1;
00369 }
00370
00371 dcb.BaudRate = arg->baudrate;
00372
00373 switch (arg->databits)
00374 {
00375 case 4:
00376 case 5:
00377 case 6:
00378 case 7:
00379 case 8:
00380 dcb.ByteSize = arg->databits;
00381 break;
00382 default:
00383 return -1;
00384 }
00385
00386 switch (arg->stopbits)
00387 {
00388 case 1:
00389 dcb.StopBits = ONESTOPBIT;
00390 break;
00391 case 2:
00392 dcb.StopBits = TWOSTOPBITS;
00393 break;
00394 default:
00395 return -1;
00396 }
00397
00398 if (arg->parityenb && arg->paritymode)
00399 {
00400 dcb.fParity = TRUE;
00401 if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_ODD) == 0)
00402 dcb.Parity = ODDPARITY;
00403 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_EVEN) == 0)
00404 dcb.Parity = EVENPARITY;
00405 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_MARK) == 0)
00406 dcb.Parity = MARKPARITY;
00407 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_SPACE) == 0)
00408 dcb.Parity = SPACEPARITY;
00409 else
00410 dcb.Parity = NOPARITY;
00411 }
00412 else
00413 {
00414 dcb.fParity = FALSE;
00415 dcb.Parity = NOPARITY;
00416 }
00417
00418
00419 switch (arg->rtsenb)
00420 {
00421 case 1:
00422 dcb.fRtsControl = RTS_CONTROL_ENABLE;
00423 break;
00424 case 2:
00425 dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
00426 break;
00427 case 3:
00428 dcb.fRtsControl = RTS_CONTROL_TOGGLE;
00429 break;
00430 default:
00431 dcb.fRtsControl = RTS_CONTROL_DISABLE;
00432 }
00433
00434
00435 if (arg->ctsenb)
00436 dcb.fOutxCtsFlow = TRUE;
00437 else
00438 dcb.fOutxCtsFlow = FALSE;
00439
00440
00441 if (arg->dsrenb)
00442 dcb.fOutxDsrFlow = TRUE;
00443 else
00444 dcb.fOutxDsrFlow = FALSE;
00445
00446
00447 if (arg->dtrdisable)
00448 dcb.fDtrControl = DTR_CONTROL_DISABLE;
00449 else
00450 dcb.fDtrControl = DTR_CONTROL_ENABLE;
00451
00452
00453 if (arg->xinenb)
00454 dcb.fInX = TRUE;
00455 else
00456 dcb.fInX = FALSE;
00457
00458
00459 if (arg->xoutenb)
00460 dcb.fOutX = TRUE;
00461 else
00462 dcb.fOutX = FALSE;
00463
00464
00465 if (arg->xonlim >= 0)
00466 dcb.XonLim = static_cast<WORD>(arg->xonlim);
00467 if (arg->xofflim >= 0)
00468 dcb.XoffLim = static_cast<WORD>(arg->xofflim);
00469
00470 dcb.fAbortOnError = FALSE;
00471 dcb.fErrorChar = FALSE;
00472 dcb.fNull = FALSE;
00473 dcb.fBinary = TRUE;
00474
00475 if (!::SetCommState (this->get_handle (), &dcb))
00476 {
00477 ACE_OS::set_errno_to_last_error ();
00478 return -1;
00479 }
00480
00481 COMMTIMEOUTS timeouts;
00482 if (!::GetCommTimeouts (this->get_handle(), &timeouts))
00483 {
00484 ACE_OS::set_errno_to_last_error ();
00485 return -1;
00486 }
00487
00488 if (arg->readtimeoutmsec < 0)
00489 {
00490
00491 timeouts.ReadIntervalTimeout = 0;
00492 timeouts.ReadTotalTimeoutMultiplier = 0;
00493 timeouts.ReadTotalTimeoutConstant = 0;
00494 }
00495 else if (arg->readtimeoutmsec == 0)
00496 {
00497
00498 timeouts.ReadIntervalTimeout = MAXDWORD;
00499 timeouts.ReadTotalTimeoutMultiplier = 0;
00500 timeouts.ReadTotalTimeoutConstant = 0;
00501 }
00502 else
00503 {
00504
00505 timeouts.ReadIntervalTimeout = MAXDWORD;
00506 timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
00507 timeouts.ReadTotalTimeoutConstant = arg->readtimeoutmsec;
00508 }
00509
00510 if (!::SetCommTimeouts (this->get_handle (), &timeouts))
00511 {
00512 ACE_OS::set_errno_to_last_error ();
00513 return -1;
00514 }
00515
00516 return 0;
00517
00518 case GETPARAMS:
00519 ACE_NOTSUP_RETURN (-1);
00520 default:
00521 return -1;
00522
00523 }
00524 #else
00525 ACE_UNUSED_ARG (cmd);
00526 ACE_UNUSED_ARG (arg);
00527 ACE_NOTSUP_RETURN (-1);
00528 #endif
00529 }
00530
00531 #if defined (ACE_NEEDS_DEV_IO_CONVERSION)
00532 ACE_TTY_IO::operator ACE_DEV_IO &()
00533 {
00534 return static_cast<ACE_DEV_IO &>(*this);
00535 }
00536 #endif
00537
00538 ACE_END_VERSIONED_NAMESPACE_DECL