2 // serial_port_base.ipp
3 // ~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
8 // Distributed under the Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
12 #ifndef BOOST_ASIO_SERIAL_PORT_BASE_IPP
13 #define BOOST_ASIO_SERIAL_PORT_BASE_IPP
15 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
17 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
19 #include <boost/asio/detail/push_options.hpp>
24 inline serial_port_base::baud_rate::baud_rate(unsigned int rate)
29 inline unsigned int serial_port_base::baud_rate::value() const
34 inline boost::system::error_code serial_port_base::baud_rate::store(
35 BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
37 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
38 storage.BaudRate = value_;
43 // Do POSIX-specified rates first.
44 case 0: baud = B0; break;
45 case 50: baud = B50; break;
46 case 75: baud = B75; break;
47 case 110: baud = B110; break;
48 case 134: baud = B134; break;
49 case 150: baud = B150; break;
50 case 200: baud = B200; break;
51 case 300: baud = B300; break;
52 case 600: baud = B600; break;
53 case 1200: baud = B1200; break;
54 case 1800: baud = B1800; break;
55 case 2400: baud = B2400; break;
56 case 4800: baud = B4800; break;
57 case 9600: baud = B9600; break;
58 case 19200: baud = B19200; break;
59 case 38400: baud = B38400; break;
60 // And now the extended ones conditionally.
62 case 7200: baud = B7200; break;
65 case 14400: baud = B14400; break;
68 case 57600: baud = B57600; break;
71 case 115200: baud = B115200; break;
74 case 230400: baud = B230400; break;
77 case 460800: baud = B460800; break;
80 case 500000: baud = B500000; break;
83 case 576000: baud = B576000; break;
86 case 921600: baud = B921600; break;
89 case 1000000: baud = B1000000; break;
92 case 1152000: baud = B1152000; break;
95 case 2000000: baud = B2000000; break;
98 case 3000000: baud = B3000000; break;
101 case 3500000: baud = B3500000; break;
104 case 4000000: baud = B4000000; break;
108 ec = boost::asio::error::invalid_argument;
111 # if defined(_BSD_SOURCE)
112 ::cfsetspeed(&storage, baud);
114 ::cfsetispeed(&storage, baud);
115 ::cfsetospeed(&storage, baud);
118 ec = boost::system::error_code();
122 inline boost::system::error_code serial_port_base::baud_rate::load(
123 const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
125 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
126 value_ = storage.BaudRate;
128 speed_t baud = ::cfgetospeed(&storage);
131 // First do those specified by POSIX.
132 case B0: value_ = 0; break;
133 case B50: value_ = 50; break;
134 case B75: value_ = 75; break;
135 case B110: value_ = 110; break;
136 case B134: value_ = 134; break;
137 case B150: value_ = 150; break;
138 case B200: value_ = 200; break;
139 case B300: value_ = 300; break;
140 case B600: value_ = 600; break;
141 case B1200: value_ = 1200; break;
142 case B1800: value_ = 1800; break;
143 case B2400: value_ = 2400; break;
144 case B4800: value_ = 4800; break;
145 case B9600: value_ = 9600; break;
146 case B19200: value_ = 19200; break;
147 case B38400: value_ = 38400; break;
148 // Now conditionally handle a bunch of extended rates.
150 case B7200: value_ = 7200; break;
153 case B14400: value_ = 14400; break;
156 case B57600: value_ = 57600; break;
159 case B115200: value_ = 115200; break;
162 case B230400: value_ = 230400; break;
165 case B460800: value_ = 460800; break;
168 case B500000: value_ = 500000; break;
171 case B576000: value_ = 576000; break;
174 case B921600: value_ = 921600; break;
177 case B1000000: value_ = 1000000; break;
180 case B1152000: value_ = 1152000; break;
183 case B2000000: value_ = 2000000; break;
186 case B3000000: value_ = 3000000; break;
189 case B3500000: value_ = 3500000; break;
192 case B4000000: value_ = 4000000; break;
196 ec = boost::asio::error::invalid_argument;
200 ec = boost::system::error_code();
204 inline serial_port_base::flow_control::flow_control(
205 serial_port_base::flow_control::type t)
208 if (t != none && t != software && t != hardware)
209 throw std::out_of_range("invalid flow_control value");
212 inline serial_port_base::flow_control::type
213 serial_port_base::flow_control::value() const
218 inline boost::system::error_code serial_port_base::flow_control::store(
219 BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
221 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
222 storage.fOutxCtsFlow = FALSE;
223 storage.fOutxDsrFlow = FALSE;
224 storage.fTXContinueOnXoff = TRUE;
225 storage.fDtrControl = DTR_CONTROL_ENABLE;
226 storage.fDsrSensitivity = FALSE;
227 storage.fOutX = FALSE;
228 storage.fInX = FALSE;
229 storage.fRtsControl = RTS_CONTROL_ENABLE;
235 storage.fOutX = TRUE;
239 storage.fOutxCtsFlow = TRUE;
240 storage.fRtsControl = RTS_CONTROL_HANDSHAKE;
249 storage.c_iflag &= ~(IXOFF | IXON);
250 # if defined(_BSD_SOURCE)
251 storage.c_cflag &= ~CRTSCTS;
255 storage.c_iflag |= IXOFF | IXON;
256 # if defined(_BSD_SOURCE)
257 storage.c_cflag &= ~CRTSCTS;
261 # if defined(_BSD_SOURCE)
262 storage.c_iflag &= ~(IXOFF | IXON);
263 storage.c_cflag |= CRTSCTS;
266 ec = boost::asio::error::operation_not_supported;
273 ec = boost::system::error_code();
277 inline boost::system::error_code serial_port_base::flow_control::load(
278 const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
280 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
281 if (storage.fOutX && storage.fInX)
285 else if (storage.fOutxCtsFlow && storage.fRtsControl == RTS_CONTROL_HANDSHAKE)
294 if (storage.c_iflag & (IXOFF | IXON))
298 # if defined(_BSD_SOURCE)
299 else if (storage.c_cflag & CRTSCTS)
309 ec = boost::system::error_code();
313 inline serial_port_base::parity::parity(serial_port_base::parity::type t)
316 if (t != none && t != odd && t != even)
317 throw std::out_of_range("invalid parity value");
320 inline serial_port_base::parity::type serial_port_base::parity::value() const
325 inline boost::system::error_code serial_port_base::parity::store(
326 BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
328 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
332 storage.fParity = FALSE;
333 storage.Parity = NOPARITY;
336 storage.fParity = TRUE;
337 storage.Parity = ODDPARITY;
340 storage.fParity = TRUE;
341 storage.Parity = EVENPARITY;
350 storage.c_iflag |= IGNPAR;
351 storage.c_cflag &= ~(PARENB | PARODD);
354 storage.c_iflag &= ~(IGNPAR | PARMRK);
355 storage.c_iflag |= INPCK;
356 storage.c_cflag |= PARENB;
357 storage.c_cflag &= ~PARODD;
360 storage.c_iflag &= ~(IGNPAR | PARMRK);
361 storage.c_iflag |= INPCK;
362 storage.c_cflag |= (PARENB | PARODD);
368 ec = boost::system::error_code();
372 inline boost::system::error_code serial_port_base::parity::load(
373 const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
375 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
376 if (storage.Parity == EVENPARITY)
380 else if (storage.Parity == ODDPARITY)
389 if (storage.c_cflag & PARENB)
391 if (storage.c_cflag & PARODD)
405 ec = boost::system::error_code();
409 inline serial_port_base::stop_bits::stop_bits(
410 serial_port_base::stop_bits::type t)
413 if (t != one && t != onepointfive && t != two)
414 throw std::out_of_range("invalid stop_bits value");
417 inline serial_port_base::stop_bits::type
418 serial_port_base::stop_bits::value() const
423 inline boost::system::error_code serial_port_base::stop_bits::store(
424 BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
426 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
430 storage.StopBits = ONESTOPBIT;
433 storage.StopBits = ONE5STOPBITS;
436 storage.StopBits = TWOSTOPBITS;
445 storage.c_cflag &= ~CSTOPB;
448 storage.c_cflag |= CSTOPB;
451 ec = boost::asio::error::operation_not_supported;
455 ec = boost::system::error_code();
459 inline boost::system::error_code serial_port_base::stop_bits::load(
460 const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
462 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
463 if (storage.StopBits == ONESTOPBIT)
467 else if (storage.StopBits == ONE5STOPBITS)
469 value_ = onepointfive;
471 else if (storage.StopBits == TWOSTOPBITS)
480 value_ = (storage.c_cflag & CSTOPB) ? two : one;
482 ec = boost::system::error_code();
486 inline serial_port_base::character_size::character_size(unsigned int t)
490 throw std::out_of_range("invalid character_size value");
493 inline unsigned int serial_port_base::character_size::value() const
498 inline boost::system::error_code serial_port_base::character_size::store(
499 BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
501 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
502 storage.ByteSize = value_;
504 storage.c_cflag &= ~CSIZE;
507 case 5: storage.c_cflag |= CS5; break;
508 case 6: storage.c_cflag |= CS6; break;
509 case 7: storage.c_cflag |= CS7; break;
510 case 8: storage.c_cflag |= CS8; break;
514 ec = boost::system::error_code();
518 inline boost::system::error_code serial_port_base::character_size::load(
519 const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
521 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
522 value_ = storage.ByteSize;
524 if ((storage.c_cflag & CSIZE) == CS5) { value_ = 5; }
525 else if ((storage.c_cflag & CSIZE) == CS6) { value_ = 6; }
526 else if ((storage.c_cflag & CSIZE) == CS7) { value_ = 7; }
527 else if ((storage.c_cflag & CSIZE) == CS8) { value_ = 8; }
530 // Hmmm, use 8 for now.
534 ec = boost::system::error_code();
541 #include <boost/asio/detail/pop_options.hpp>
543 #endif // BOOST_ASIO_SERIAL_PORT_BASE_IPP