summaryrefslogtreecommitdiffstats
path: root/lib/asio/impl/serial_port_base.ipp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/asio/impl/serial_port_base.ipp')
-rw-r--r--lib/asio/impl/serial_port_base.ipp557
1 files changed, 557 insertions, 0 deletions
diff --git a/lib/asio/impl/serial_port_base.ipp b/lib/asio/impl/serial_port_base.ipp
new file mode 100644
index 0000000..21323ee
--- /dev/null
+++ b/lib/asio/impl/serial_port_base.ipp
@@ -0,0 +1,557 @@
+//
+// impl/serial_port_base.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef ASIO_IMPL_SERIAL_PORT_BASE_IPP
+#define ASIO_IMPL_SERIAL_PORT_BASE_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+
+#if defined(ASIO_HAS_SERIAL_PORT)
+
+#include <stdexcept>
+#include "asio/error.hpp"
+#include "asio/serial_port_base.hpp"
+#include "asio/detail/throw_exception.hpp"
+
+#if defined(GENERATING_DOCUMENTATION)
+# define ASIO_OPTION_STORAGE implementation_defined
+#elif defined(ASIO_WINDOWS) || defined(__CYGWIN__)
+# define ASIO_OPTION_STORAGE DCB
+#else
+# define ASIO_OPTION_STORAGE termios
+#endif
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+
+ASIO_SYNC_OP_VOID serial_port_base::baud_rate::store(
+ ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const
+{
+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
+ storage.BaudRate = value_;
+#else
+ speed_t baud;
+ switch (value_)
+ {
+ // Do POSIX-specified rates first.
+ case 0: baud = B0; break;
+ case 50: baud = B50; break;
+ case 75: baud = B75; break;
+ case 110: baud = B110; break;
+ case 134: baud = B134; break;
+ case 150: baud = B150; break;
+ case 200: baud = B200; break;
+ case 300: baud = B300; break;
+ case 600: baud = B600; break;
+ case 1200: baud = B1200; break;
+ case 1800: baud = B1800; break;
+ case 2400: baud = B2400; break;
+ case 4800: baud = B4800; break;
+ case 9600: baud = B9600; break;
+ case 19200: baud = B19200; break;
+ case 38400: baud = B38400; break;
+ // And now the extended ones conditionally.
+# ifdef B7200
+ case 7200: baud = B7200; break;
+# endif
+# ifdef B14400
+ case 14400: baud = B14400; break;
+# endif
+# ifdef B57600
+ case 57600: baud = B57600; break;
+# endif
+# ifdef B115200
+ case 115200: baud = B115200; break;
+# endif
+# ifdef B230400
+ case 230400: baud = B230400; break;
+# endif
+# ifdef B460800
+ case 460800: baud = B460800; break;
+# endif
+# ifdef B500000
+ case 500000: baud = B500000; break;
+# endif
+# ifdef B576000
+ case 576000: baud = B576000; break;
+# endif
+# ifdef B921600
+ case 921600: baud = B921600; break;
+# endif
+# ifdef B1000000
+ case 1000000: baud = B1000000; break;
+# endif
+# ifdef B1152000
+ case 1152000: baud = B1152000; break;
+# endif
+# ifdef B2000000
+ case 2000000: baud = B2000000; break;
+# endif
+# ifdef B3000000
+ case 3000000: baud = B3000000; break;
+# endif
+# ifdef B3500000
+ case 3500000: baud = B3500000; break;
+# endif
+# ifdef B4000000
+ case 4000000: baud = B4000000; break;
+# endif
+ default:
+ ec = asio::error::invalid_argument;
+ ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+# if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE)
+ ::cfsetspeed(&storage, baud);
+# else
+ ::cfsetispeed(&storage, baud);
+ ::cfsetospeed(&storage, baud);
+# endif
+#endif
+ ec = asio::error_code();
+ ASIO_SYNC_OP_VOID_RETURN(ec);
+}
+
+ASIO_SYNC_OP_VOID serial_port_base::baud_rate::load(
+ const ASIO_OPTION_STORAGE& storage, asio::error_code& ec)
+{
+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
+ value_ = storage.BaudRate;
+#else
+ speed_t baud = ::cfgetospeed(&storage);
+ switch (baud)
+ {
+ // First do those specified by POSIX.
+ case B0: value_ = 0; break;
+ case B50: value_ = 50; break;
+ case B75: value_ = 75; break;
+ case B110: value_ = 110; break;
+ case B134: value_ = 134; break;
+ case B150: value_ = 150; break;
+ case B200: value_ = 200; break;
+ case B300: value_ = 300; break;
+ case B600: value_ = 600; break;
+ case B1200: value_ = 1200; break;
+ case B1800: value_ = 1800; break;
+ case B2400: value_ = 2400; break;
+ case B4800: value_ = 4800; break;
+ case B9600: value_ = 9600; break;
+ case B19200: value_ = 19200; break;
+ case B38400: value_ = 38400; break;
+ // Now conditionally handle a bunch of extended rates.
+# ifdef B7200
+ case B7200: value_ = 7200; break;
+# endif
+# ifdef B14400
+ case B14400: value_ = 14400; break;
+# endif
+# ifdef B57600
+ case B57600: value_ = 57600; break;
+# endif
+# ifdef B115200
+ case B115200: value_ = 115200; break;
+# endif
+# ifdef B230400
+ case B230400: value_ = 230400; break;
+# endif
+# ifdef B460800
+ case B460800: value_ = 460800; break;
+# endif
+# ifdef B500000
+ case B500000: value_ = 500000; break;
+# endif
+# ifdef B576000
+ case B576000: value_ = 576000; break;
+# endif
+# ifdef B921600
+ case B921600: value_ = 921600; break;
+# endif
+# ifdef B1000000
+ case B1000000: value_ = 1000000; break;
+# endif
+# ifdef B1152000
+ case B1152000: value_ = 1152000; break;
+# endif
+# ifdef B2000000
+ case B2000000: value_ = 2000000; break;
+# endif
+# ifdef B3000000
+ case B3000000: value_ = 3000000; break;
+# endif
+# ifdef B3500000
+ case B3500000: value_ = 3500000; break;
+# endif
+# ifdef B4000000
+ case B4000000: value_ = 4000000; break;
+# endif
+ default:
+ value_ = 0;
+ ec = asio::error::invalid_argument;
+ ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+#endif
+ ec = asio::error_code();
+ ASIO_SYNC_OP_VOID_RETURN(ec);
+}
+
+serial_port_base::flow_control::flow_control(
+ serial_port_base::flow_control::type t)
+ : value_(t)
+{
+ if (t != none && t != software && t != hardware)
+ {
+ std::out_of_range ex("invalid flow_control value");
+ asio::detail::throw_exception(ex);
+ }
+}
+
+ASIO_SYNC_OP_VOID serial_port_base::flow_control::store(
+ ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const
+{
+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
+ storage.fOutxCtsFlow = FALSE;
+ storage.fOutxDsrFlow = FALSE;
+ storage.fTXContinueOnXoff = TRUE;
+ storage.fDtrControl = DTR_CONTROL_ENABLE;
+ storage.fDsrSensitivity = FALSE;
+ storage.fOutX = FALSE;
+ storage.fInX = FALSE;
+ storage.fRtsControl = RTS_CONTROL_ENABLE;
+ switch (value_)
+ {
+ case none:
+ break;
+ case software:
+ storage.fOutX = TRUE;
+ storage.fInX = TRUE;
+ break;
+ case hardware:
+ storage.fOutxCtsFlow = TRUE;
+ storage.fRtsControl = RTS_CONTROL_HANDSHAKE;
+ break;
+ default:
+ break;
+ }
+#else
+ switch (value_)
+ {
+ case none:
+ storage.c_iflag &= ~(IXOFF | IXON);
+# if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE)
+ storage.c_cflag &= ~CRTSCTS;
+# elif defined(__QNXNTO__)
+ storage.c_cflag &= ~(IHFLOW | OHFLOW);
+# endif
+ break;
+ case software:
+ storage.c_iflag |= IXOFF | IXON;
+# if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE)
+ storage.c_cflag &= ~CRTSCTS;
+# elif defined(__QNXNTO__)
+ storage.c_cflag &= ~(IHFLOW | OHFLOW);
+# endif
+ break;
+ case hardware:
+# if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE)
+ storage.c_iflag &= ~(IXOFF | IXON);
+ storage.c_cflag |= CRTSCTS;
+ break;
+# elif defined(__QNXNTO__)
+ storage.c_iflag &= ~(IXOFF | IXON);
+ storage.c_cflag |= (IHFLOW | OHFLOW);
+ break;
+# else
+ ec = asio::error::operation_not_supported;
+ ASIO_SYNC_OP_VOID_RETURN(ec);
+# endif
+ default:
+ break;
+ }
+#endif
+ ec = asio::error_code();
+ ASIO_SYNC_OP_VOID_RETURN(ec);
+}
+
+ASIO_SYNC_OP_VOID serial_port_base::flow_control::load(
+ const ASIO_OPTION_STORAGE& storage, asio::error_code& ec)
+{
+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
+ if (storage.fOutX && storage.fInX)
+ {
+ value_ = software;
+ }
+ else if (storage.fOutxCtsFlow && storage.fRtsControl == RTS_CONTROL_HANDSHAKE)
+ {
+ value_ = hardware;
+ }
+ else
+ {
+ value_ = none;
+ }
+#else
+ if (storage.c_iflag & (IXOFF | IXON))
+ {
+ value_ = software;
+ }
+# if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE)
+ else if (storage.c_cflag & CRTSCTS)
+ {
+ value_ = hardware;
+ }
+# elif defined(__QNXNTO__)
+ else if (storage.c_cflag & IHFLOW && storage.c_cflag & OHFLOW)
+ {
+ value_ = hardware;
+ }
+# endif
+ else
+ {
+ value_ = none;
+ }
+#endif
+ ec = asio::error_code();
+ ASIO_SYNC_OP_VOID_RETURN(ec);
+}
+
+serial_port_base::parity::parity(serial_port_base::parity::type t)
+ : value_(t)
+{
+ if (t != none && t != odd && t != even)
+ {
+ std::out_of_range ex("invalid parity value");
+ asio::detail::throw_exception(ex);
+ }
+}
+
+ASIO_SYNC_OP_VOID serial_port_base::parity::store(
+ ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const
+{
+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
+ switch (value_)
+ {
+ case none:
+ storage.fParity = FALSE;
+ storage.Parity = NOPARITY;
+ break;
+ case odd:
+ storage.fParity = TRUE;
+ storage.Parity = ODDPARITY;
+ break;
+ case even:
+ storage.fParity = TRUE;
+ storage.Parity = EVENPARITY;
+ break;
+ default:
+ break;
+ }
+#else
+ switch (value_)
+ {
+ case none:
+ storage.c_iflag |= IGNPAR;
+ storage.c_cflag &= ~(PARENB | PARODD);
+ break;
+ case even:
+ storage.c_iflag &= ~(IGNPAR | PARMRK);
+ storage.c_iflag |= INPCK;
+ storage.c_cflag |= PARENB;
+ storage.c_cflag &= ~PARODD;
+ break;
+ case odd:
+ storage.c_iflag &= ~(IGNPAR | PARMRK);
+ storage.c_iflag |= INPCK;
+ storage.c_cflag |= (PARENB | PARODD);
+ break;
+ default:
+ break;
+ }
+#endif
+ ec = asio::error_code();
+ ASIO_SYNC_OP_VOID_RETURN(ec);
+}
+
+ASIO_SYNC_OP_VOID serial_port_base::parity::load(
+ const ASIO_OPTION_STORAGE& storage, asio::error_code& ec)
+{
+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
+ if (storage.Parity == EVENPARITY)
+ {
+ value_ = even;
+ }
+ else if (storage.Parity == ODDPARITY)
+ {
+ value_ = odd;
+ }
+ else
+ {
+ value_ = none;
+ }
+#else
+ if (storage.c_cflag & PARENB)
+ {
+ if (storage.c_cflag & PARODD)
+ {
+ value_ = odd;
+ }
+ else
+ {
+ value_ = even;
+ }
+ }
+ else
+ {
+ value_ = none;
+ }
+#endif
+ ec = asio::error_code();
+ ASIO_SYNC_OP_VOID_RETURN(ec);
+}
+
+serial_port_base::stop_bits::stop_bits(
+ serial_port_base::stop_bits::type t)
+ : value_(t)
+{
+ if (t != one && t != onepointfive && t != two)
+ {
+ std::out_of_range ex("invalid stop_bits value");
+ asio::detail::throw_exception(ex);
+ }
+}
+
+ASIO_SYNC_OP_VOID serial_port_base::stop_bits::store(
+ ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const
+{
+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
+ switch (value_)
+ {
+ case one:
+ storage.StopBits = ONESTOPBIT;
+ break;
+ case onepointfive:
+ storage.StopBits = ONE5STOPBITS;
+ break;
+ case two:
+ storage.StopBits = TWOSTOPBITS;
+ break;
+ default:
+ break;
+ }
+#else
+ switch (value_)
+ {
+ case one:
+ storage.c_cflag &= ~CSTOPB;
+ break;
+ case two:
+ storage.c_cflag |= CSTOPB;
+ break;
+ default:
+ ec = asio::error::operation_not_supported;
+ ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+#endif
+ ec = asio::error_code();
+ ASIO_SYNC_OP_VOID_RETURN(ec);
+}
+
+ASIO_SYNC_OP_VOID serial_port_base::stop_bits::load(
+ const ASIO_OPTION_STORAGE& storage, asio::error_code& ec)
+{
+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
+ if (storage.StopBits == ONESTOPBIT)
+ {
+ value_ = one;
+ }
+ else if (storage.StopBits == ONE5STOPBITS)
+ {
+ value_ = onepointfive;
+ }
+ else if (storage.StopBits == TWOSTOPBITS)
+ {
+ value_ = two;
+ }
+ else
+ {
+ value_ = one;
+ }
+#else
+ value_ = (storage.c_cflag & CSTOPB) ? two : one;
+#endif
+ ec = asio::error_code();
+ ASIO_SYNC_OP_VOID_RETURN(ec);
+}
+
+serial_port_base::character_size::character_size(unsigned int t)
+ : value_(t)
+{
+ if (t < 5 || t > 8)
+ {
+ std::out_of_range ex("invalid character_size value");
+ asio::detail::throw_exception(ex);
+ }
+}
+
+ASIO_SYNC_OP_VOID serial_port_base::character_size::store(
+ ASIO_OPTION_STORAGE& storage, asio::error_code& ec) const
+{
+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
+ storage.ByteSize = value_;
+#else
+ storage.c_cflag &= ~CSIZE;
+ switch (value_)
+ {
+ case 5: storage.c_cflag |= CS5; break;
+ case 6: storage.c_cflag |= CS6; break;
+ case 7: storage.c_cflag |= CS7; break;
+ case 8: storage.c_cflag |= CS8; break;
+ default: break;
+ }
+#endif
+ ec = asio::error_code();
+ ASIO_SYNC_OP_VOID_RETURN(ec);
+}
+
+ASIO_SYNC_OP_VOID serial_port_base::character_size::load(
+ const ASIO_OPTION_STORAGE& storage, asio::error_code& ec)
+{
+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
+ value_ = storage.ByteSize;
+#else
+
+#pragma GCC diagnostic ignored "-Wduplicated-branches"
+ if ((storage.c_cflag & CSIZE) == CS5) { value_ = 5; }
+ else if ((storage.c_cflag & CSIZE) == CS6) { value_ = 6; }
+ else if ((storage.c_cflag & CSIZE) == CS7) { value_ = 7; }
+ else if ((storage.c_cflag & CSIZE) == CS8) { value_ = 8; }
+ else
+ {
+ // Hmmm, use 8 for now.
+ value_ = 8;
+ }
+#pragma GCC diagnostic pop
+#endif
+ ec = asio::error_code();
+ ASIO_SYNC_OP_VOID_RETURN(ec);
+}
+
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#undef ASIO_OPTION_STORAGE
+
+#endif // defined(ASIO_HAS_SERIAL_PORT)
+
+#endif // ASIO_IMPL_SERIAL_PORT_BASE_IPP