Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:42

0001 //
0002 // detail/posix_serial_port_service.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
0007 //
0008 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0009 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 
0012 #ifndef BOOST_ASIO_DETAIL_POSIX_SERIAL_PORT_SERVICE_HPP
0013 #define BOOST_ASIO_DETAIL_POSIX_SERIAL_PORT_SERVICE_HPP
0014 
0015 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0016 # pragma once
0017 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0018 
0019 #include <boost/asio/detail/config.hpp>
0020 
0021 #if defined(BOOST_ASIO_HAS_SERIAL_PORT)
0022 #if !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
0023 
0024 #include <string>
0025 #include <boost/asio/error.hpp>
0026 #include <boost/asio/execution_context.hpp>
0027 #include <boost/asio/serial_port_base.hpp>
0028 #include <boost/asio/detail/descriptor_ops.hpp>
0029 
0030 #if defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
0031 # include <boost/asio/detail/io_uring_descriptor_service.hpp>
0032 #else // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
0033 # include <boost/asio/detail/reactive_descriptor_service.hpp>
0034 #endif // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
0035 
0036 #include <boost/asio/detail/push_options.hpp>
0037 
0038 namespace boost {
0039 namespace asio {
0040 namespace detail {
0041 
0042 // Extend a descriptor_service to provide serial port support.
0043 class posix_serial_port_service :
0044   public execution_context_service_base<posix_serial_port_service>
0045 {
0046 public:
0047 #if defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
0048   typedef io_uring_descriptor_service descriptor_service;
0049 #else // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
0050   typedef reactive_descriptor_service descriptor_service;
0051 #endif // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
0052 
0053   // The native type of a serial port.
0054   typedef descriptor_service::native_handle_type native_handle_type;
0055 
0056   // The implementation type of the serial port.
0057   typedef descriptor_service::implementation_type implementation_type;
0058 
0059   BOOST_ASIO_DECL posix_serial_port_service(execution_context& context);
0060 
0061   // Destroy all user-defined handler objects owned by the service.
0062   BOOST_ASIO_DECL void shutdown();
0063 
0064   // Construct a new serial port implementation.
0065   void construct(implementation_type& impl)
0066   {
0067     descriptor_service_.construct(impl);
0068   }
0069 
0070   // Move-construct a new serial port implementation.
0071   void move_construct(implementation_type& impl,
0072       implementation_type& other_impl)
0073   {
0074     descriptor_service_.move_construct(impl, other_impl);
0075   }
0076 
0077   // Move-assign from another serial port implementation.
0078   void move_assign(implementation_type& impl,
0079       posix_serial_port_service& other_service,
0080       implementation_type& other_impl)
0081   {
0082     descriptor_service_.move_assign(impl,
0083         other_service.descriptor_service_, other_impl);
0084   }
0085 
0086   // Destroy a serial port implementation.
0087   void destroy(implementation_type& impl)
0088   {
0089     descriptor_service_.destroy(impl);
0090   }
0091 
0092   // Open the serial port using the specified device name.
0093   BOOST_ASIO_DECL boost::system::error_code open(implementation_type& impl,
0094       const std::string& device, boost::system::error_code& ec);
0095 
0096   // Assign a native descriptor to a serial port implementation.
0097   boost::system::error_code assign(implementation_type& impl,
0098       const native_handle_type& native_descriptor,
0099       boost::system::error_code& ec)
0100   {
0101     return descriptor_service_.assign(impl, native_descriptor, ec);
0102   }
0103 
0104   // Determine whether the serial port is open.
0105   bool is_open(const implementation_type& impl) const
0106   {
0107     return descriptor_service_.is_open(impl);
0108   }
0109 
0110   // Destroy a serial port implementation.
0111   boost::system::error_code close(implementation_type& impl,
0112       boost::system::error_code& ec)
0113   {
0114     return descriptor_service_.close(impl, ec);
0115   }
0116 
0117   // Get the native serial port representation.
0118   native_handle_type native_handle(implementation_type& impl)
0119   {
0120     return descriptor_service_.native_handle(impl);
0121   }
0122 
0123   // Cancel all operations associated with the serial port.
0124   boost::system::error_code cancel(implementation_type& impl,
0125       boost::system::error_code& ec)
0126   {
0127     return descriptor_service_.cancel(impl, ec);
0128   }
0129 
0130   // Set an option on the serial port.
0131   template <typename SettableSerialPortOption>
0132   boost::system::error_code set_option(implementation_type& impl,
0133       const SettableSerialPortOption& option, boost::system::error_code& ec)
0134   {
0135     return do_set_option(impl,
0136         &posix_serial_port_service::store_option<SettableSerialPortOption>,
0137         &option, ec);
0138   }
0139 
0140   // Get an option from the serial port.
0141   template <typename GettableSerialPortOption>
0142   boost::system::error_code get_option(const implementation_type& impl,
0143       GettableSerialPortOption& option, boost::system::error_code& ec) const
0144   {
0145     return do_get_option(impl,
0146         &posix_serial_port_service::load_option<GettableSerialPortOption>,
0147         &option, ec);
0148   }
0149 
0150   // Send a break sequence to the serial port.
0151   boost::system::error_code send_break(implementation_type& impl,
0152       boost::system::error_code& ec)
0153   {
0154     int result = ::tcsendbreak(descriptor_service_.native_handle(impl), 0);
0155     descriptor_ops::get_last_error(ec, result < 0);
0156     BOOST_ASIO_ERROR_LOCATION(ec);
0157     return ec;
0158   }
0159 
0160   // Write the given data. Returns the number of bytes sent.
0161   template <typename ConstBufferSequence>
0162   size_t write_some(implementation_type& impl,
0163       const ConstBufferSequence& buffers, boost::system::error_code& ec)
0164   {
0165     return descriptor_service_.write_some(impl, buffers, ec);
0166   }
0167 
0168   // Start an asynchronous write. The data being written must be valid for the
0169   // lifetime of the asynchronous operation.
0170   template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
0171   void async_write_some(implementation_type& impl,
0172       const ConstBufferSequence& buffers,
0173       Handler& handler, const IoExecutor& io_ex)
0174   {
0175     descriptor_service_.async_write_some(impl, buffers, handler, io_ex);
0176   }
0177 
0178   // Read some data. Returns the number of bytes received.
0179   template <typename MutableBufferSequence>
0180   size_t read_some(implementation_type& impl,
0181       const MutableBufferSequence& buffers, boost::system::error_code& ec)
0182   {
0183     return descriptor_service_.read_some(impl, buffers, ec);
0184   }
0185 
0186   // Start an asynchronous read. The buffer for the data being received must be
0187   // valid for the lifetime of the asynchronous operation.
0188   template <typename MutableBufferSequence,
0189       typename Handler, typename IoExecutor>
0190   void async_read_some(implementation_type& impl,
0191       const MutableBufferSequence& buffers,
0192       Handler& handler, const IoExecutor& io_ex)
0193   {
0194     descriptor_service_.async_read_some(impl, buffers, handler, io_ex);
0195   }
0196 
0197 private:
0198   // Function pointer type for storing a serial port option.
0199   typedef boost::system::error_code (*store_function_type)(
0200       const void*, termios&, boost::system::error_code&);
0201 
0202   // Helper function template to store a serial port option.
0203   template <typename SettableSerialPortOption>
0204   static boost::system::error_code store_option(const void* option,
0205       termios& storage, boost::system::error_code& ec)
0206   {
0207     static_cast<const SettableSerialPortOption*>(option)->store(storage, ec);
0208     return ec;
0209   }
0210 
0211   // Helper function to set a serial port option.
0212   BOOST_ASIO_DECL boost::system::error_code do_set_option(
0213       implementation_type& impl, store_function_type store,
0214       const void* option, boost::system::error_code& ec);
0215 
0216   // Function pointer type for loading a serial port option.
0217   typedef boost::system::error_code (*load_function_type)(
0218       void*, const termios&, boost::system::error_code&);
0219 
0220   // Helper function template to load a serial port option.
0221   template <typename GettableSerialPortOption>
0222   static boost::system::error_code load_option(void* option,
0223       const termios& storage, boost::system::error_code& ec)
0224   {
0225     static_cast<GettableSerialPortOption*>(option)->load(storage, ec);
0226     return ec;
0227   }
0228 
0229   // Helper function to get a serial port option.
0230   BOOST_ASIO_DECL boost::system::error_code do_get_option(
0231       const implementation_type& impl, load_function_type load,
0232       void* option, boost::system::error_code& ec) const;
0233 
0234   // The implementation used for initiating asynchronous operations.
0235   descriptor_service descriptor_service_;
0236 };
0237 
0238 } // namespace detail
0239 } // namespace asio
0240 } // namespace boost
0241 
0242 #include <boost/asio/detail/pop_options.hpp>
0243 
0244 #if defined(BOOST_ASIO_HEADER_ONLY)
0245 # include <boost/asio/detail/impl/posix_serial_port_service.ipp>
0246 #endif // defined(BOOST_ASIO_HEADER_ONLY)
0247 
0248 #endif // !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
0249 #endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
0250 
0251 #endif // BOOST_ASIO_DETAIL_POSIX_SERIAL_PORT_SERVICE_HPP