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


Public Types | |
| enum | Control_Mode { SETPARAMS, GETPARAMS } |
Public Methods | |
| int | control (Control_Mode cmd, Serial_Params *arg) const |
| Interface for reading/writing serial device parameters. More... | |
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. Referenced by control.
|
|
||||||||||||
|
Interface for reading/writing serial device parameters.
Definition at line 16 of file TTY_IO.cpp. References ACE_IO_SAP::control, Control_Mode, ENOSYS, ACE_IO_SAP::get_handle, GETPARAMS, ACE_OS::set_errno_to_last_error, SETPARAMS, and ACE_OS_String::strcasecmp.
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 }
|
1.2.14 written by Dimitri van Heesch,
© 1997-2002