File indexing completed on 2025-01-18 09:28:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_ASIO_IMPL_SERIAL_PORT_BASE_IPP
0013 #define BOOST_ASIO_IMPL_SERIAL_PORT_BASE_IPP
0014
0015 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0016 # pragma once
0017 #endif
0018
0019 #include <boost/asio/detail/config.hpp>
0020
0021 #if defined(BOOST_ASIO_HAS_SERIAL_PORT)
0022
0023 #include <stdexcept>
0024 #include <boost/asio/error.hpp>
0025 #include <boost/asio/serial_port_base.hpp>
0026 #include <boost/asio/detail/throw_exception.hpp>
0027
0028 #if defined(GENERATING_DOCUMENTATION)
0029 # define BOOST_ASIO_OPTION_STORAGE implementation_defined
0030 #elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
0031 # define BOOST_ASIO_OPTION_STORAGE DCB
0032 #else
0033 # define BOOST_ASIO_OPTION_STORAGE termios
0034 #endif
0035
0036 #include <boost/asio/detail/push_options.hpp>
0037
0038 namespace boost {
0039 namespace asio {
0040
0041 BOOST_ASIO_SYNC_OP_VOID serial_port_base::baud_rate::store(
0042 BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
0043 {
0044 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
0045 storage.BaudRate = value_;
0046 #else
0047 speed_t baud;
0048 switch (value_)
0049 {
0050
0051 case 0: baud = B0; break;
0052 case 50: baud = B50; break;
0053 case 75: baud = B75; break;
0054 case 110: baud = B110; break;
0055 case 134: baud = B134; break;
0056 case 150: baud = B150; break;
0057 case 200: baud = B200; break;
0058 case 300: baud = B300; break;
0059 case 600: baud = B600; break;
0060 case 1200: baud = B1200; break;
0061 case 1800: baud = B1800; break;
0062 case 2400: baud = B2400; break;
0063 case 4800: baud = B4800; break;
0064 case 9600: baud = B9600; break;
0065 case 19200: baud = B19200; break;
0066 case 38400: baud = B38400; break;
0067
0068 # ifdef B7200
0069 case 7200: baud = B7200; break;
0070 # endif
0071 # ifdef B14400
0072 case 14400: baud = B14400; break;
0073 # endif
0074 # ifdef B57600
0075 case 57600: baud = B57600; break;
0076 # endif
0077 # ifdef B115200
0078 case 115200: baud = B115200; break;
0079 # endif
0080 # ifdef B230400
0081 case 230400: baud = B230400; break;
0082 # endif
0083 # ifdef B460800
0084 case 460800: baud = B460800; break;
0085 # endif
0086 # ifdef B500000
0087 case 500000: baud = B500000; break;
0088 # endif
0089 # ifdef B576000
0090 case 576000: baud = B576000; break;
0091 # endif
0092 # ifdef B921600
0093 case 921600: baud = B921600; break;
0094 # endif
0095 # ifdef B1000000
0096 case 1000000: baud = B1000000; break;
0097 # endif
0098 # ifdef B1152000
0099 case 1152000: baud = B1152000; break;
0100 # endif
0101 # ifdef B2000000
0102 case 2000000: baud = B2000000; break;
0103 # endif
0104 # ifdef B3000000
0105 case 3000000: baud = B3000000; break;
0106 # endif
0107 # ifdef B3500000
0108 case 3500000: baud = B3500000; break;
0109 # endif
0110 # ifdef B4000000
0111 case 4000000: baud = B4000000; break;
0112 # endif
0113 default:
0114 ec = boost::asio::error::invalid_argument;
0115 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0116 }
0117 # if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE)
0118 ::cfsetspeed(&storage, baud);
0119 # else
0120 ::cfsetispeed(&storage, baud);
0121 ::cfsetospeed(&storage, baud);
0122 # endif
0123 #endif
0124 ec = boost::system::error_code();
0125 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0126 }
0127
0128 BOOST_ASIO_SYNC_OP_VOID serial_port_base::baud_rate::load(
0129 const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
0130 {
0131 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
0132 value_ = storage.BaudRate;
0133 #else
0134 speed_t baud = ::cfgetospeed(&storage);
0135 switch (baud)
0136 {
0137
0138 case B0: value_ = 0; break;
0139 case B50: value_ = 50; break;
0140 case B75: value_ = 75; break;
0141 case B110: value_ = 110; break;
0142 case B134: value_ = 134; break;
0143 case B150: value_ = 150; break;
0144 case B200: value_ = 200; break;
0145 case B300: value_ = 300; break;
0146 case B600: value_ = 600; break;
0147 case B1200: value_ = 1200; break;
0148 case B1800: value_ = 1800; break;
0149 case B2400: value_ = 2400; break;
0150 case B4800: value_ = 4800; break;
0151 case B9600: value_ = 9600; break;
0152 case B19200: value_ = 19200; break;
0153 case B38400: value_ = 38400; break;
0154
0155 # ifdef B7200
0156 case B7200: value_ = 7200; break;
0157 # endif
0158 # ifdef B14400
0159 case B14400: value_ = 14400; break;
0160 # endif
0161 # ifdef B57600
0162 case B57600: value_ = 57600; break;
0163 # endif
0164 # ifdef B115200
0165 case B115200: value_ = 115200; break;
0166 # endif
0167 # ifdef B230400
0168 case B230400: value_ = 230400; break;
0169 # endif
0170 # ifdef B460800
0171 case B460800: value_ = 460800; break;
0172 # endif
0173 # ifdef B500000
0174 case B500000: value_ = 500000; break;
0175 # endif
0176 # ifdef B576000
0177 case B576000: value_ = 576000; break;
0178 # endif
0179 # ifdef B921600
0180 case B921600: value_ = 921600; break;
0181 # endif
0182 # ifdef B1000000
0183 case B1000000: value_ = 1000000; break;
0184 # endif
0185 # ifdef B1152000
0186 case B1152000: value_ = 1152000; break;
0187 # endif
0188 # ifdef B2000000
0189 case B2000000: value_ = 2000000; break;
0190 # endif
0191 # ifdef B3000000
0192 case B3000000: value_ = 3000000; break;
0193 # endif
0194 # ifdef B3500000
0195 case B3500000: value_ = 3500000; break;
0196 # endif
0197 # ifdef B4000000
0198 case B4000000: value_ = 4000000; break;
0199 # endif
0200 default:
0201 value_ = 0;
0202 ec = boost::asio::error::invalid_argument;
0203 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0204 }
0205 #endif
0206 ec = boost::system::error_code();
0207 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0208 }
0209
0210 serial_port_base::flow_control::flow_control(
0211 serial_port_base::flow_control::type t)
0212 : value_(t)
0213 {
0214 if (t != none && t != software && t != hardware)
0215 {
0216 std::out_of_range ex("invalid flow_control value");
0217 boost::asio::detail::throw_exception(ex);
0218 }
0219 }
0220
0221 BOOST_ASIO_SYNC_OP_VOID serial_port_base::flow_control::store(
0222 BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
0223 {
0224 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
0225 storage.fOutxCtsFlow = FALSE;
0226 storage.fOutxDsrFlow = FALSE;
0227 storage.fTXContinueOnXoff = TRUE;
0228 storage.fDtrControl = DTR_CONTROL_ENABLE;
0229 storage.fDsrSensitivity = FALSE;
0230 storage.fOutX = FALSE;
0231 storage.fInX = FALSE;
0232 storage.fRtsControl = RTS_CONTROL_ENABLE;
0233 switch (value_)
0234 {
0235 case none:
0236 break;
0237 case software:
0238 storage.fOutX = TRUE;
0239 storage.fInX = TRUE;
0240 break;
0241 case hardware:
0242 storage.fOutxCtsFlow = TRUE;
0243 storage.fRtsControl = RTS_CONTROL_HANDSHAKE;
0244 break;
0245 default:
0246 break;
0247 }
0248 #else
0249 switch (value_)
0250 {
0251 case none:
0252 storage.c_iflag &= ~(IXOFF | IXON);
0253 # if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE)
0254 storage.c_cflag &= ~CRTSCTS;
0255 # elif defined(__QNXNTO__)
0256 storage.c_cflag &= ~(IHFLOW | OHFLOW);
0257 # endif
0258 break;
0259 case software:
0260 storage.c_iflag |= IXOFF | IXON;
0261 # if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE)
0262 storage.c_cflag &= ~CRTSCTS;
0263 # elif defined(__QNXNTO__)
0264 storage.c_cflag &= ~(IHFLOW | OHFLOW);
0265 # endif
0266 break;
0267 case hardware:
0268 # if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE)
0269 storage.c_iflag &= ~(IXOFF | IXON);
0270 storage.c_cflag |= CRTSCTS;
0271 break;
0272 # elif defined(__QNXNTO__)
0273 storage.c_iflag &= ~(IXOFF | IXON);
0274 storage.c_cflag |= (IHFLOW | OHFLOW);
0275 break;
0276 # else
0277 ec = boost::asio::error::operation_not_supported;
0278 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0279 # endif
0280 default:
0281 break;
0282 }
0283 #endif
0284 ec = boost::system::error_code();
0285 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0286 }
0287
0288 BOOST_ASIO_SYNC_OP_VOID serial_port_base::flow_control::load(
0289 const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
0290 {
0291 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
0292 if (storage.fOutX && storage.fInX)
0293 {
0294 value_ = software;
0295 }
0296 else if (storage.fOutxCtsFlow && storage.fRtsControl == RTS_CONTROL_HANDSHAKE)
0297 {
0298 value_ = hardware;
0299 }
0300 else
0301 {
0302 value_ = none;
0303 }
0304 #else
0305 if (storage.c_iflag & (IXOFF | IXON))
0306 {
0307 value_ = software;
0308 }
0309 # if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE)
0310 else if (storage.c_cflag & CRTSCTS)
0311 {
0312 value_ = hardware;
0313 }
0314 # elif defined(__QNXNTO__)
0315 else if (storage.c_cflag & IHFLOW && storage.c_cflag & OHFLOW)
0316 {
0317 value_ = hardware;
0318 }
0319 # endif
0320 else
0321 {
0322 value_ = none;
0323 }
0324 #endif
0325 ec = boost::system::error_code();
0326 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0327 }
0328
0329 serial_port_base::parity::parity(serial_port_base::parity::type t)
0330 : value_(t)
0331 {
0332 if (t != none && t != odd && t != even)
0333 {
0334 std::out_of_range ex("invalid parity value");
0335 boost::asio::detail::throw_exception(ex);
0336 }
0337 }
0338
0339 BOOST_ASIO_SYNC_OP_VOID serial_port_base::parity::store(
0340 BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
0341 {
0342 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
0343 switch (value_)
0344 {
0345 case none:
0346 storage.fParity = FALSE;
0347 storage.Parity = NOPARITY;
0348 break;
0349 case odd:
0350 storage.fParity = TRUE;
0351 storage.Parity = ODDPARITY;
0352 break;
0353 case even:
0354 storage.fParity = TRUE;
0355 storage.Parity = EVENPARITY;
0356 break;
0357 default:
0358 break;
0359 }
0360 #else
0361 switch (value_)
0362 {
0363 case none:
0364 storage.c_iflag |= IGNPAR;
0365 storage.c_cflag &= ~(PARENB | PARODD);
0366 break;
0367 case even:
0368 storage.c_iflag &= ~(IGNPAR | PARMRK);
0369 storage.c_iflag |= INPCK;
0370 storage.c_cflag |= PARENB;
0371 storage.c_cflag &= ~PARODD;
0372 break;
0373 case odd:
0374 storage.c_iflag &= ~(IGNPAR | PARMRK);
0375 storage.c_iflag |= INPCK;
0376 storage.c_cflag |= (PARENB | PARODD);
0377 break;
0378 default:
0379 break;
0380 }
0381 #endif
0382 ec = boost::system::error_code();
0383 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0384 }
0385
0386 BOOST_ASIO_SYNC_OP_VOID serial_port_base::parity::load(
0387 const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
0388 {
0389 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
0390 if (storage.Parity == EVENPARITY)
0391 {
0392 value_ = even;
0393 }
0394 else if (storage.Parity == ODDPARITY)
0395 {
0396 value_ = odd;
0397 }
0398 else
0399 {
0400 value_ = none;
0401 }
0402 #else
0403 if (storage.c_cflag & PARENB)
0404 {
0405 if (storage.c_cflag & PARODD)
0406 {
0407 value_ = odd;
0408 }
0409 else
0410 {
0411 value_ = even;
0412 }
0413 }
0414 else
0415 {
0416 value_ = none;
0417 }
0418 #endif
0419 ec = boost::system::error_code();
0420 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0421 }
0422
0423 serial_port_base::stop_bits::stop_bits(
0424 serial_port_base::stop_bits::type t)
0425 : value_(t)
0426 {
0427 if (t != one && t != onepointfive && t != two)
0428 {
0429 std::out_of_range ex("invalid stop_bits value");
0430 boost::asio::detail::throw_exception(ex);
0431 }
0432 }
0433
0434 BOOST_ASIO_SYNC_OP_VOID serial_port_base::stop_bits::store(
0435 BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
0436 {
0437 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
0438 switch (value_)
0439 {
0440 case one:
0441 storage.StopBits = ONESTOPBIT;
0442 break;
0443 case onepointfive:
0444 storage.StopBits = ONE5STOPBITS;
0445 break;
0446 case two:
0447 storage.StopBits = TWOSTOPBITS;
0448 break;
0449 default:
0450 break;
0451 }
0452 #else
0453 switch (value_)
0454 {
0455 case one:
0456 storage.c_cflag &= ~CSTOPB;
0457 break;
0458 case two:
0459 storage.c_cflag |= CSTOPB;
0460 break;
0461 default:
0462 ec = boost::asio::error::operation_not_supported;
0463 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0464 }
0465 #endif
0466 ec = boost::system::error_code();
0467 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0468 }
0469
0470 BOOST_ASIO_SYNC_OP_VOID serial_port_base::stop_bits::load(
0471 const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
0472 {
0473 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
0474 if (storage.StopBits == ONESTOPBIT)
0475 {
0476 value_ = one;
0477 }
0478 else if (storage.StopBits == ONE5STOPBITS)
0479 {
0480 value_ = onepointfive;
0481 }
0482 else if (storage.StopBits == TWOSTOPBITS)
0483 {
0484 value_ = two;
0485 }
0486 else
0487 {
0488 value_ = one;
0489 }
0490 #else
0491 value_ = (storage.c_cflag & CSTOPB) ? two : one;
0492 #endif
0493 ec = boost::system::error_code();
0494 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0495 }
0496
0497 serial_port_base::character_size::character_size(unsigned int t)
0498 : value_(t)
0499 {
0500 if (t < 5 || t > 8)
0501 {
0502 std::out_of_range ex("invalid character_size value");
0503 boost::asio::detail::throw_exception(ex);
0504 }
0505 }
0506
0507 BOOST_ASIO_SYNC_OP_VOID serial_port_base::character_size::store(
0508 BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
0509 {
0510 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
0511 storage.ByteSize = value_;
0512 #else
0513 storage.c_cflag &= ~CSIZE;
0514 switch (value_)
0515 {
0516 case 5: storage.c_cflag |= CS5; break;
0517 case 6: storage.c_cflag |= CS6; break;
0518 case 7: storage.c_cflag |= CS7; break;
0519 case 8: storage.c_cflag |= CS8; break;
0520 default: break;
0521 }
0522 #endif
0523 ec = boost::system::error_code();
0524 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0525 }
0526
0527 BOOST_ASIO_SYNC_OP_VOID serial_port_base::character_size::load(
0528 const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
0529 {
0530 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
0531 value_ = storage.ByteSize;
0532 #else
0533 if ((storage.c_cflag & CSIZE) == CS5) { value_ = 5; }
0534 else if ((storage.c_cflag & CSIZE) == CS6) { value_ = 6; }
0535 else if ((storage.c_cflag & CSIZE) == CS7) { value_ = 7; }
0536 else if ((storage.c_cflag & CSIZE) == CS8) { value_ = 8; }
0537 else
0538 {
0539
0540 value_ = 8;
0541 }
0542 #endif
0543 ec = boost::system::error_code();
0544 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
0545 }
0546
0547 }
0548 }
0549
0550 #include <boost/asio/detail/pop_options.hpp>
0551
0552 #undef BOOST_ASIO_OPTION_STORAGE
0553
0554 #endif
0555
0556 #endif