00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP
00013 #define ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP
00014
00015 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00016 # pragma once
00017 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
00018
00019 #include "asio/detail/push_options.hpp"
00020
00021 #include "asio/detail/push_options.hpp"
00022 #include <cstring>
00023 #include <string>
00024 #include "asio/detail/pop_options.hpp"
00025
00026 #include "asio/detail/win_iocp_io_service_fwd.hpp"
00027
00028 #if defined(ASIO_HAS_IOCP)
00029
00030 #include "asio/error.hpp"
00031 #include "asio/io_service.hpp"
00032 #include "asio/detail/win_iocp_handle_service.hpp"
00033
00034 namespace asio {
00035 namespace detail {
00036
00037
00038 class win_iocp_serial_port_service
00039 : public asio::detail::service_base<win_iocp_serial_port_service>
00040 {
00041 public:
00042
00043 typedef win_iocp_handle_service::native_type native_type;
00044
00045
00046 typedef win_iocp_handle_service::implementation_type implementation_type;
00047
00048 win_iocp_serial_port_service(asio::io_service& io_service)
00049 : asio::detail::service_base<
00050 win_iocp_serial_port_service>(io_service),
00051 handle_service_(
00052 asio::use_service<win_iocp_handle_service>(io_service))
00053 {
00054 }
00055
00056
00057 void shutdown_service()
00058 {
00059 }
00060
00061
00062 void construct(implementation_type& impl)
00063 {
00064 handle_service_.construct(impl);
00065 }
00066
00067
00068 void destroy(implementation_type& impl)
00069 {
00070 handle_service_.destroy(impl);
00071 }
00072
00073
00074 asio::error_code open(implementation_type& impl,
00075 const std::string& device, asio::error_code& ec)
00076 {
00077 if (is_open(impl))
00078 {
00079 ec = asio::error::already_open;
00080 return ec;
00081 }
00082
00083
00084 std::string name = (device[0] == '\\') ? device : "\\\\.\\" + device;
00085
00086
00087 ::HANDLE handle = ::CreateFileA(name.c_str(),
00088 GENERIC_READ | GENERIC_WRITE, 0, 0,
00089 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
00090 if (handle == INVALID_HANDLE_VALUE)
00091 {
00092 DWORD last_error = ::GetLastError();
00093 ec = asio::error_code(last_error,
00094 asio::error::get_system_category());
00095 return ec;
00096 }
00097
00098
00099 using namespace std;
00100 ::DCB dcb;
00101 memset(&dcb, 0, sizeof(DCB));
00102 dcb.DCBlength = sizeof(DCB);
00103 if (!::GetCommState(handle, &dcb))
00104 {
00105 DWORD last_error = ::GetLastError();
00106 ::CloseHandle(handle);
00107 ec = asio::error_code(last_error,
00108 asio::error::get_system_category());
00109 return ec;
00110 }
00111
00112
00113
00114 dcb.fBinary = TRUE;
00115 dcb.fDsrSensitivity = FALSE;
00116 dcb.fNull = FALSE;
00117 dcb.fAbortOnError = FALSE;
00118 if (!::SetCommState(handle, &dcb))
00119 {
00120 DWORD last_error = ::GetLastError();
00121 ::CloseHandle(handle);
00122 ec = asio::error_code(last_error,
00123 asio::error::get_system_category());
00124 return ec;
00125 }
00126
00127
00128
00129
00130 ::COMMTIMEOUTS timeouts;
00131 timeouts.ReadIntervalTimeout = 1;
00132 timeouts.ReadTotalTimeoutMultiplier = 0;
00133 timeouts.ReadTotalTimeoutConstant = 0;
00134 timeouts.WriteTotalTimeoutMultiplier = 0;
00135 timeouts.WriteTotalTimeoutConstant = 0;
00136 if (!::SetCommTimeouts(handle, &timeouts))
00137 {
00138 DWORD last_error = ::GetLastError();
00139 ::CloseHandle(handle);
00140 ec = asio::error_code(last_error,
00141 asio::error::get_system_category());
00142 return ec;
00143 }
00144
00145
00146 if (handle_service_.assign(impl, handle, ec))
00147 ::CloseHandle(handle);
00148 return ec;
00149 }
00150
00151
00152 asio::error_code assign(implementation_type& impl,
00153 const native_type& native_handle, asio::error_code& ec)
00154 {
00155 return handle_service_.assign(impl, native_handle, ec);
00156 }
00157
00158
00159 bool is_open(const implementation_type& impl) const
00160 {
00161 return handle_service_.is_open(impl);
00162 }
00163
00164
00165 asio::error_code close(implementation_type& impl,
00166 asio::error_code& ec)
00167 {
00168 return handle_service_.close(impl, ec);
00169 }
00170
00171
00172 native_type native(implementation_type& impl)
00173 {
00174 return handle_service_.native(impl);
00175 }
00176
00177
00178 asio::error_code cancel(implementation_type& impl,
00179 asio::error_code& ec)
00180 {
00181 return handle_service_.cancel(impl, ec);
00182 }
00183
00184
00185 template <typename SettableSerialPortOption>
00186 asio::error_code set_option(implementation_type& impl,
00187 const SettableSerialPortOption& option, asio::error_code& ec)
00188 {
00189 using namespace std;
00190
00191 ::DCB dcb;
00192 memset(&dcb, 0, sizeof(DCB));
00193 dcb.DCBlength = sizeof(DCB);
00194 if (!::GetCommState(handle_service_.native(impl), &dcb))
00195 {
00196 DWORD last_error = ::GetLastError();
00197 ec = asio::error_code(last_error,
00198 asio::error::get_system_category());
00199 return ec;
00200 }
00201
00202 if (option.store(dcb, ec))
00203 return ec;
00204
00205 if (!::SetCommState(handle_service_.native(impl), &dcb))
00206 {
00207 DWORD last_error = ::GetLastError();
00208 ec = asio::error_code(last_error,
00209 asio::error::get_system_category());
00210 return ec;
00211 }
00212
00213 ec = asio::error_code();
00214 return ec;
00215 }
00216
00217
00218 template <typename GettableSerialPortOption>
00219 asio::error_code get_option(const implementation_type& impl,
00220 GettableSerialPortOption& option, asio::error_code& ec) const
00221 {
00222 using namespace std;
00223
00224 ::DCB dcb;
00225 memset(&dcb, 0, sizeof(DCB));
00226 dcb.DCBlength = sizeof(DCB);
00227 if (!::GetCommState(handle_service_.native(impl), &dcb))
00228 {
00229 DWORD last_error = ::GetLastError();
00230 ec = asio::error_code(last_error,
00231 asio::error::get_system_category());
00232 return ec;
00233 }
00234
00235 return option.load(dcb, ec);
00236 }
00237
00238
00239 asio::error_code send_break(implementation_type& impl,
00240 asio::error_code& ec)
00241 {
00242 ec = asio::error::operation_not_supported;
00243 return ec;
00244 }
00245
00246
00247 template <typename ConstBufferSequence>
00248 size_t write_some(implementation_type& impl,
00249 const ConstBufferSequence& buffers, asio::error_code& ec)
00250 {
00251 return handle_service_.write_some(impl, buffers, ec);
00252 }
00253
00254
00255
00256 template <typename ConstBufferSequence, typename Handler>
00257 void async_write_some(implementation_type& impl,
00258 const ConstBufferSequence& buffers, Handler handler)
00259 {
00260 handle_service_.async_write_some(impl, buffers, handler);
00261 }
00262
00263
00264 template <typename MutableBufferSequence>
00265 size_t read_some(implementation_type& impl,
00266 const MutableBufferSequence& buffers, asio::error_code& ec)
00267 {
00268 return handle_service_.read_some(impl, buffers, ec);
00269 }
00270
00271
00272
00273 template <typename MutableBufferSequence, typename Handler>
00274 void async_read_some(implementation_type& impl,
00275 const MutableBufferSequence& buffers, Handler handler)
00276 {
00277 handle_service_.async_read_some(impl, buffers, handler);
00278 }
00279
00280 private:
00281
00282 win_iocp_handle_service& handle_service_;
00283 };
00284
00285 }
00286 }
00287
00288 #endif // defined(ASIO_HAS_IOCP)
00289
00290 #include "asio/detail/pop_options.hpp"
00291
00292 #endif // ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP