Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / TTY_IO.cpp
blobf94aa9e98c53d581af2e44eed076d6a3470c6937
1 #include "ace/TTY_IO.h"
2 #include "ace/OS_NS_errno.h"
3 #include "ace/OS_NS_string.h"
4 #include "ace/OS_NS_strings.h"
6 #if defined (ACE_HAS_TERMIOS)
7 # include "ace/os_include/os_termios.h"
8 #elif defined (ACE_HAS_TERMIO)
9 # include <termio.h>
10 #endif
12 namespace
14 const char ACE_TTY_IO_NONE[] = "none";
15 #if defined (ACE_HAS_TERMIOS) || defined (ACE_HAS_TERMIO) || defined (ACE_WIN32)
16 const char ACE_TTY_IO_ODD[] = "odd";
17 const char ACE_TTY_IO_EVEN[] = "even";
18 #endif
19 #if defined (ACE_WIN32)
20 const char ACE_TTY_IO_MARK[] = "mark";
21 const char ACE_TTY_IO_SPACE[] = "space";
22 #endif /* ACE_WIN32 */
25 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
27 ACE_TTY_IO::ACE_TTY_IO ()
31 ACE_TTY_IO::Serial_Params::Serial_Params ()
33 baudrate = 9600;
34 xonlim = 0;
35 xofflim = 0;
36 readmincharacters = 0;
37 readtimeoutmsec = 10000;
38 paritymode = ACE_TTY_IO_NONE;
39 inpckenb = true;
40 ctsenb = false;
41 rtsenb = 0;
42 xinenb = false;
43 xoutenb = false;
44 modem = false;
45 rcvenb = true;
46 dsrenb = false;
47 dtrdisable = false;
48 databits = 8;
49 stopbits = 1;
52 // Interface for reading/writing serial device parameters
54 int ACE_TTY_IO::control (Control_Mode cmd, Serial_Params *arg) const
56 #if defined (ACE_HAS_TERMIOS) || defined (ACE_HAS_TERMIO)
58 #if defined (ACE_HAS_TERMIOS)
59 struct termios devpar;
60 speed_t newbaudrate = 0;
61 if (tcgetattr (get_handle () , &devpar) == -1)
62 #elif defined (TCGETS)
63 struct termios devpar;
64 unsigned int newbaudrate = 0;
65 if (this->ACE_IO_SAP::control (TCGETS, static_cast<void*>(&devpar)) == -1)
66 #elif defined (TCGETA)
67 struct termio devpar;
68 unsigned int newbaudrate = 0;
69 if (this->ACE_IO_SAP::control (TCGETA, static_cast<void*>(&devpar)) == -1)
70 #else
71 errno = ENOSYS;
72 #endif /* ACE_HAS_TERMIOS */
73 return -1;
75 switch (cmd)
77 case SETPARAMS:
78 switch (arg->baudrate)
80 #if defined (B0)
81 case 0: newbaudrate = B0; break;
82 #endif /* B0 */
83 #if defined (B50)
84 case 50: newbaudrate = B50; break;
85 #endif /* B50 */
86 #if defined (B75)
87 case 75: newbaudrate = B75; break;
88 #endif /* B75 */
89 #if defined (B110)
90 case 110: newbaudrate = B110; break;
91 #endif /* B110 */
92 #if defined (B134)
93 case 134: newbaudrate = B134; break;
94 #endif /* B134 */
95 #if defined (B150)
96 case 150: newbaudrate = B150; break;
97 #endif /* B150 */
98 #if defined (B200)
99 case 200: newbaudrate = B200; break;
100 #endif /* B200 */
101 #if defined (B300)
102 case 300: newbaudrate = B300; break;
103 #endif /* B300 */
104 #if defined (B600)
105 case 600: newbaudrate = B600; break;
106 #endif /* B600 */
107 #if defined (B1200)
108 case 1200: newbaudrate = B1200; break;
109 #endif /* B1200 */
110 #if defined (B1800)
111 case 1800: newbaudrate = B1800; break;
112 #endif /* B1800 */
113 #if defined (B2400)
114 case 2400: newbaudrate = B2400; break;
115 #endif /* B2400 */
116 #if defined (B4800)
117 case 4800: newbaudrate = B4800; break;
118 #endif /* B4800 */
119 #if defined (B9600)
120 case 9600: newbaudrate = B9600; break;
121 #endif /* B9600 */
122 #if defined (B19200)
123 case 19200: newbaudrate = B19200; break;
124 #endif /* B19200 */
125 #if defined (B38400)
126 case 38400: newbaudrate = B38400; break;
127 #endif /* B38400 */
128 #if defined (B56000)
129 case 56000: newbaudrate = B56000; break;
130 #endif /* B56000 */
131 #if defined (B57600)
132 case 57600: newbaudrate = B57600; break;
133 #endif /* B57600 */
134 #if defined (B76800)
135 case 76800: newbaudrate = B76800; break;
136 #endif /* B76800 */
137 #if defined (B115200)
138 case 115200: newbaudrate = B115200; break;
139 #endif /* B115200 */
140 #if defined (B128000)
141 case 128000: newbaudrate = B128000; break;
142 #endif /* B128000 */
143 #if defined (B153600)
144 case 153600: newbaudrate = B153600; break;
145 #endif /* B153600 */
146 #if defined (B230400)
147 case 230400: newbaudrate = B230400; break;
148 #endif /* B230400 */
149 #if defined (B307200)
150 case 307200: newbaudrate = B307200; break;
151 #endif /* B307200 */
152 #if defined (B256000)
153 case 256000: newbaudrate = B256000; break;
154 #endif /* B256000 */
155 #if defined (B460800)
156 case 460800: newbaudrate = B460800; break;
157 #endif /* B460800 */
158 #if defined (B500000)
159 case 500000: newbaudrate = B500000; break;
160 #endif /* B500000 */
161 #if defined (B576000)
162 case 576000: newbaudrate = B576000; break;
163 #endif /* B576000 */
164 #if defined (B921600)
165 case 921600: newbaudrate = B921600; break;
166 #endif /* B921600 */
167 #if defined (B1000000)
168 case 1000000: newbaudrate = B1000000; break;
169 #endif /* B1000000 */
170 #if defined (B1152000)
171 case 1152000: newbaudrate = B1152000; break;
172 #endif /* B1152000 */
173 #if defined (B1500000)
174 case 1500000: newbaudrate = B1500000; break;
175 #endif /* B1500000 */
176 #if defined (B2000000)
177 case 2000000: newbaudrate = B2000000; break;
178 #endif /* B2000000 */
179 #if defined (B2500000)
180 case 2500000: newbaudrate = B2500000; break;
181 #endif /* B2500000 */
182 #if defined (B3000000)
183 case 3000000: newbaudrate = B3000000; break;
184 #endif /* B3000000 */
185 #if defined (B3500000)
186 case 3500000: newbaudrate = B3500000; break;
187 #endif /* B3500000 */
188 #if defined (B4000000)
189 case 4000000: newbaudrate = B4000000; break;
190 #endif /* B4000000 */
191 default:
192 return -1;
195 #if defined (ACE_HAS_TERMIOS)
196 // Can you really have different input and output baud rates?!
197 if (cfsetospeed (&devpar, newbaudrate) == -1)
198 return -1;
199 if (cfsetispeed (&devpar, newbaudrate) == -1)
200 return -1;
201 #else
202 devpar.c_cflag &= ~CBAUD;
203 # if defined (CBAUDEX)
204 devpar.c_cflag &= ~CBAUDEX;
205 # endif /* CBAUDEX */
206 devpar.c_cflag |= newbaudrate;
207 #endif /* ACE_HAS_TERMIOS */
209 devpar.c_cflag &= ~CSIZE;
210 switch (arg->databits)
212 case 5:
213 devpar.c_cflag |= CS5;
214 break;
215 case 6:
216 devpar.c_cflag |= CS6;
217 break;
218 case 7:
219 devpar.c_cflag |= CS7;
220 break;
221 case 8:
222 devpar.c_cflag |= CS8;
223 break;
224 default:
225 return -1;
228 switch (arg->stopbits)
230 case 1:
231 devpar.c_cflag &= ~CSTOPB;
232 break;
233 case 2:
234 devpar.c_cflag |= CSTOPB;
235 break;
236 default:
237 return -1;
240 if (arg->paritymode)
242 if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_ODD) == 0)
244 devpar.c_cflag |= PARENB;
245 devpar.c_cflag |= PARODD;
246 devpar.c_iflag &= ~IGNPAR;
247 if(arg->inpckenb)
248 devpar.c_iflag |= INPCK | PARMRK;
249 else
250 devpar.c_iflag &= ~(INPCK | PARMRK);
252 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_EVEN) == 0)
254 devpar.c_cflag |= PARENB;
255 devpar.c_cflag &= ~PARODD;
256 devpar.c_iflag &= ~IGNPAR;
257 if(arg->inpckenb)
258 devpar.c_iflag |= INPCK | PARMRK;
259 else
260 devpar.c_iflag &= ~(INPCK | PARMRK);
262 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_NONE) == 0)
264 devpar.c_cflag &= ~PARENB;
266 else
268 return -1;
271 else
273 devpar.c_cflag &= ~PARENB;
276 #if defined (CNEW_RTSCTS)
277 if ((arg->ctsenb) || (arg->rtsenb)) // Enable RTS/CTS protocol
278 devpar.c_cflag |= CNEW_RTSCTS;
279 else
280 devpar.c_cflag &= ~CNEW_RTSCTS;
281 #elif defined (CRTSCTS)
282 if ((arg->ctsenb) || (arg->rtsenb)) // Enable RTS/CTS protocol
283 devpar.c_cflag |= CRTSCTS;
284 else
285 devpar.c_cflag &= ~CRTSCTS;
286 #endif /* NEW_RTSCTS || CRTSCTS */
288 #if defined (CREAD)
289 // Enable/disable receiver
290 if (arg->rcvenb)
291 devpar.c_cflag |= CREAD;
292 else
293 devpar.c_cflag &= ~CREAD;
294 #endif /* CREAD */
296 #if defined (HUPCL)
297 // Cause DTR to drop after port close.
298 devpar.c_cflag |= HUPCL;
299 #endif /* HUPCL */
301 #if defined (CLOCAL)
302 // If device is not a modem set to local device.
303 if (arg->modem)
304 devpar.c_cflag &= ~CLOCAL;
305 else
306 devpar.c_cflag |= CLOCAL;
307 #endif /* CLOCAL */
309 if (arg->databits < 8)
310 devpar.c_iflag |= ISTRIP;
311 else
312 devpar.c_iflag &= ~ISTRIP;
314 #if defined (IGNBRK)
315 // If device is not a modem set to ignore break points
316 if(arg->modem)
317 devpar.c_iflag &= ~IGNBRK;
318 else
319 devpar.c_iflag |= IGNBRK;
320 #endif /* IGNBRK */
322 #if defined (IXOFF)
323 // Enable/disable software flow control on input
324 if (arg->xinenb)
325 devpar.c_iflag |= IXOFF;
326 else
327 devpar.c_iflag &= ~IXOFF;
328 #endif /* IXOFF */
330 #if defined (IXON)
331 // Enable/disable software flow control on output
332 if (arg->xoutenb)
333 devpar.c_iflag |= IXON;
334 else
335 devpar.c_iflag &= ~IXON;
336 #endif /* IXON */
338 #if defined (ICANON)
339 // Enable noncanonical input processing mode
340 devpar.c_lflag &= ~ICANON;
341 #endif /* ICANON */
343 #if defined (ECHO)
344 // Disable echoing of input characters
345 devpar.c_lflag &= ~ECHO;
346 #endif /* ECHO */
348 #if defined (ECHOE)
349 // Disable echoing erase chareacter as BS-SP-BS
350 devpar.c_lflag &= ~ECHOE;
351 #endif /* ECHOE */
353 #if defined (ISIG)
354 // Disable SIGINTR, SIGSUSP, SIGDSUSP and SIGQUIT signals
355 devpar.c_lflag &= ~ISIG;
356 #endif /* ISIG */
358 #if defined (IGNCR)
359 // Do not discard CR characters
360 devpar.c_iflag &= ~IGNCR;
361 #endif /* IGNCR */
363 #if defined (ICRNL)
364 // Disable CR to NL conversion
365 devpar.c_iflag &= ~ICRNL;
366 #endif /* ICRNL */
368 #if defined (INLCR)
369 // Disable NL to CR conversion
370 devpar.c_iflag &= ~INLCR;
371 #endif /* INLCR */
373 #if defined (OPOST)
374 // Disable post-processing of output data
375 devpar.c_oflag &= ~OPOST;
376 #endif /* OPOST */
378 if (arg->readtimeoutmsec < 0)
380 // Settings for infinite timeout.
381 devpar.c_cc[VTIME] = 0;
382 // In case of infinite timeout [VMIN] must be at least 1.
383 if (arg->readmincharacters > UCHAR_MAX)
384 devpar.c_cc[VMIN] = UCHAR_MAX;
385 else if (arg->readmincharacters < 1)
386 devpar.c_cc[VMIN] = 1;
387 else
388 devpar.c_cc[VMIN] = static_cast<unsigned char>(arg->readmincharacters);
390 else
392 devpar.c_cc[VTIME] = static_cast<unsigned char>(arg->readtimeoutmsec / 100);
394 if (arg->readmincharacters > UCHAR_MAX)
395 devpar.c_cc[VMIN] = UCHAR_MAX;
396 else if (arg->readmincharacters < 1)
397 devpar.c_cc[VMIN] = 0;
398 else
399 devpar.c_cc[VMIN] = static_cast<unsigned char>(arg->readmincharacters);
402 #if defined (TIOCMGET)
403 int status;
404 this->ACE_IO_SAP::control (TIOCMGET, &status);
406 if (arg->dtrdisable)
407 status &= ~TIOCM_DTR;
408 else
409 status |= TIOCM_DTR;
411 this->ACE_IO_SAP::control (TIOCMSET, &status);
412 #endif /* definded (TIOCMGET) */
414 #if defined (ACE_HAS_TERMIOS)
415 return tcsetattr (get_handle (), TCSANOW, &devpar);
416 #elif defined (TCSETS)
417 return this->ACE_IO_SAP::control (TCSETS, static_cast<void*>(&devpar));
418 #elif defined (TCSETA)
419 return this->ACE_IO_SAP::control (TCSETA, static_cast<void*>(&devpar));
420 #else
421 errno = ENOSYS;
422 return -1;
423 #endif /* ACE_HAS_TERMIOS */
425 case GETPARAMS:
426 return -1; // Not yet implemented.
427 default:
428 return -1; // Wrong cmd.
430 #elif defined (ACE_WIN32)
431 DCB dcb;
432 dcb.DCBlength = sizeof dcb;
433 if (!::GetCommState (this->get_handle (), &dcb))
435 ACE_OS::set_errno_to_last_error ();
436 return -1;
439 COMMTIMEOUTS timeouts;
440 if (!::GetCommTimeouts (this->get_handle(), &timeouts))
442 ACE_OS::set_errno_to_last_error ();
443 return -1;
446 switch (cmd)
448 case SETPARAMS:
449 dcb.BaudRate = arg->baudrate;
451 switch (arg->databits)
453 case 4:
454 case 5:
455 case 6:
456 case 7:
457 case 8:
458 dcb.ByteSize = arg->databits;
459 break;
460 default:
461 return -1;
464 switch (arg->stopbits)
466 case 1:
467 dcb.StopBits = ONESTOPBIT;
468 break;
469 case 2:
470 dcb.StopBits = TWOSTOPBITS;
471 break;
472 default:
473 return -1;
476 if (arg->paritymode)
478 dcb.fParity = TRUE;
479 if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_ODD) == 0)
480 dcb.Parity = ODDPARITY;
481 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_EVEN) == 0)
482 dcb.Parity = EVENPARITY;
483 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_NONE) == 0)
484 dcb.Parity = NOPARITY;
485 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_MARK) == 0)
486 dcb.Parity = MARKPARITY;
487 else if (ACE_OS::strcasecmp (arg->paritymode, ACE_TTY_IO_SPACE) == 0)
488 dcb.Parity = SPACEPARITY;
489 else
490 return -1;
492 else
494 dcb.fParity = FALSE;
495 dcb.Parity = NOPARITY;
498 // Enable/disable RTS protocol.
499 switch (arg->rtsenb)
501 case 1:
502 dcb.fRtsControl = RTS_CONTROL_ENABLE;
503 break;
504 case 2:
505 dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
506 break;
507 case 3:
508 dcb.fRtsControl = RTS_CONTROL_TOGGLE;
509 break;
510 default:
511 dcb.fRtsControl = RTS_CONTROL_DISABLE;
514 // Enable/disable CTS protocol.
515 if (arg->ctsenb)
516 dcb.fOutxCtsFlow = TRUE;
517 else
518 dcb.fOutxCtsFlow = FALSE;
520 // Enable/disable DSR protocol.
521 if (arg->dsrenb)
522 dcb.fOutxDsrFlow = TRUE;
523 else
524 dcb.fOutxDsrFlow = FALSE;
526 // Disable/enable DTR protocol
527 if (arg->dtrdisable)
528 dcb.fDtrControl = DTR_CONTROL_DISABLE;
529 else
530 dcb.fDtrControl = DTR_CONTROL_ENABLE;
532 // Enable/disable software flow control on input
533 if (arg->xinenb)
534 dcb.fInX = TRUE;
535 else
536 dcb.fInX = FALSE;
538 // Enable/disable software flow control on output
539 if (arg->xoutenb)
540 dcb.fOutX = TRUE;
541 else
542 dcb.fOutX = FALSE;
544 // Always set limits unless set to negative to use default.
545 if (arg->xonlim >= 0)
546 dcb.XonLim = static_cast<WORD>(arg->xonlim);
547 if (arg->xofflim >= 0)
548 dcb.XoffLim = static_cast<WORD>(arg->xofflim);
550 dcb.fAbortOnError = FALSE;
551 dcb.fErrorChar = FALSE;
552 dcb.fNull = FALSE;
553 dcb.fBinary = TRUE;
555 if (!::SetCommState (this->get_handle (), &dcb))
557 ACE_OS::set_errno_to_last_error ();
558 return -1;
561 if (arg->readtimeoutmsec < 0)
563 // Settings for infinite timeout.
564 timeouts.ReadIntervalTimeout = 0;
565 timeouts.ReadTotalTimeoutMultiplier = 0;
566 timeouts.ReadTotalTimeoutConstant = 0;
568 else if (arg->readtimeoutmsec == 0)
570 // Return immediately if no data in the input buffer.
571 timeouts.ReadIntervalTimeout = MAXDWORD;
572 timeouts.ReadTotalTimeoutMultiplier = 0;
573 timeouts.ReadTotalTimeoutConstant = 0;
575 else
577 // Wait for specified timeout for char to arrive before returning.
578 timeouts.ReadIntervalTimeout = MAXDWORD;
579 timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
580 timeouts.ReadTotalTimeoutConstant = arg->readtimeoutmsec;
583 if (!::SetCommTimeouts (this->get_handle (), &timeouts))
585 ACE_OS::set_errno_to_last_error ();
586 return -1;
589 return 0;
591 case GETPARAMS:
592 arg->baudrate = dcb.BaudRate;
594 switch (dcb.ByteSize)
596 case 4:
597 case 5:
598 case 6:
599 case 7:
600 case 8:
601 arg->databits = dcb.ByteSize;
602 break;
603 default:
604 return -1;
607 switch (dcb.StopBits)
609 case ONESTOPBIT:
610 arg->stopbits = 1;
611 break;
612 case TWOSTOPBITS:
613 arg->stopbits = 2;
614 break;
615 default:
616 return -1;
619 if (!dcb.fParity)
621 arg->paritymode = ACE_TTY_IO_NONE;
623 else
625 switch (dcb.Parity)
627 case ODDPARITY:
628 arg->paritymode = ACE_TTY_IO_ODD;
629 break;
630 case EVENPARITY:
631 arg->paritymode = ACE_TTY_IO_EVEN;
632 break;
633 case NOPARITY:
634 arg->paritymode = ACE_TTY_IO_NONE;
635 break;
636 case MARKPARITY:
637 arg->paritymode = ACE_TTY_IO_MARK;
638 break;
639 case SPACEPARITY:
640 arg->paritymode = ACE_TTY_IO_SPACE;
641 break;
642 default:
643 return -1;
647 // Enable/disable RTS protocol.
648 switch (dcb.fRtsControl)
650 case RTS_CONTROL_ENABLE:
651 arg->rtsenb = 1;
652 break;
653 case RTS_CONTROL_HANDSHAKE:
654 arg->rtsenb = 2;
655 break;
656 case RTS_CONTROL_TOGGLE:
657 arg->rtsenb = 3;
658 break;
659 case RTS_CONTROL_DISABLE:
660 arg->rtsenb = 0;
661 break;
662 default:
663 return -1;
666 // Enable/disable CTS protocol.
667 if (dcb.fOutxCtsFlow)
668 arg->ctsenb = true;
669 else
670 arg->ctsenb = false;
672 // Enable/disable DSR protocol.
673 if (dcb.fOutxDsrFlow)
674 arg->dsrenb = true;
675 else
676 arg->dsrenb = false;
678 // Disable/enable DTR protocol
679 // Attention: DTR_CONTROL_HANDSHAKE is not supported.
680 switch (dcb.fDtrControl)
682 case DTR_CONTROL_DISABLE:
683 arg->dtrdisable = true;
684 break;
685 case DTR_CONTROL_ENABLE:
686 arg->dtrdisable = false;
687 break;
688 default:
689 return -1;
692 // Enable/disable software flow control on input
693 if (dcb.fInX)
694 arg->xinenb = true;
695 else
696 arg->xinenb = false;
698 // Enable/disable software flow control on output
699 if (dcb.fOutX)
700 arg->xoutenb = true;
701 else
702 arg->xoutenb = false;
704 arg->xonlim = static_cast<int>(dcb.XonLim);
705 arg->xofflim = static_cast<int>(dcb.XoffLim);
707 if (timeouts.ReadIntervalTimeout == 0 &&
708 timeouts.ReadTotalTimeoutMultiplier == 0 &&
709 timeouts.ReadTotalTimeoutConstant == 0)
710 arg->readtimeoutmsec = -1;
711 else
712 arg->readtimeoutmsec = timeouts.ReadTotalTimeoutConstant;
714 return 0;
716 default:
717 return -1; // Wrong cmd.
719 } // arg switch
720 #else
721 ACE_UNUSED_ARG (cmd);
722 ACE_UNUSED_ARG (arg);
723 ACE_NOTSUP_RETURN (-1);
724 #endif /* ACE_HAS_TERMIOS || ACE_HAS_TERMIO */
727 ACE_END_VERSIONED_NAMESPACE_DECL