/Src/Dependencies/Boost/boost/asio/detail/impl/win_iocp_serial_port_service.ipp

http://hadesmem.googlecode.com/ · C++ Header · 182 lines · 135 code · 28 blank · 19 comment · 14 complexity · fdcf6b84e30123e9e1eef322a9f6178a MD5 · raw file

  1. //
  2. // detail/impl/win_iocp_serial_port_service.ipp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
  7. //
  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)
  10. //
  11. #ifndef BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_SERIAL_PORT_SERVICE_IPP
  12. #define BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_SERIAL_PORT_SERVICE_IPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  16. #include <boost/asio/detail/config.hpp>
  17. #if defined(BOOST_ASIO_HAS_IOCP) && defined(BOOST_ASIO_HAS_SERIAL_PORT)
  18. #include <cstring>
  19. #include <boost/asio/detail/win_iocp_serial_port_service.hpp>
  20. #include <boost/asio/detail/push_options.hpp>
  21. namespace boost {
  22. namespace asio {
  23. namespace detail {
  24. win_iocp_serial_port_service::win_iocp_serial_port_service(
  25. boost::asio::io_service& io_service)
  26. : handle_service_(io_service)
  27. {
  28. }
  29. void win_iocp_serial_port_service::shutdown_service()
  30. {
  31. }
  32. boost::system::error_code win_iocp_serial_port_service::open(
  33. win_iocp_serial_port_service::implementation_type& impl,
  34. const std::string& device, boost::system::error_code& ec)
  35. {
  36. if (is_open(impl))
  37. {
  38. ec = boost::asio::error::already_open;
  39. return ec;
  40. }
  41. // For convenience, add a leading \\.\ sequence if not already present.
  42. std::string name = (device[0] == '\\') ? device : "\\\\.\\" + device;
  43. // Open a handle to the serial port.
  44. ::HANDLE handle = ::CreateFileA(name.c_str(),
  45. GENERIC_READ | GENERIC_WRITE, 0, 0,
  46. OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
  47. if (handle == INVALID_HANDLE_VALUE)
  48. {
  49. DWORD last_error = ::GetLastError();
  50. ec = boost::system::error_code(last_error,
  51. boost::asio::error::get_system_category());
  52. return ec;
  53. }
  54. // Determine the initial serial port parameters.
  55. using namespace std; // For memset.
  56. ::DCB dcb;
  57. memset(&dcb, 0, sizeof(DCB));
  58. dcb.DCBlength = sizeof(DCB);
  59. if (!::GetCommState(handle, &dcb))
  60. {
  61. DWORD last_error = ::GetLastError();
  62. ::CloseHandle(handle);
  63. ec = boost::system::error_code(last_error,
  64. boost::asio::error::get_system_category());
  65. return ec;
  66. }
  67. // Set some default serial port parameters. This implementation does not
  68. // support changing these, so they might as well be in a known state.
  69. dcb.fBinary = TRUE; // Win32 only supports binary mode.
  70. dcb.fDsrSensitivity = FALSE;
  71. dcb.fNull = FALSE; // Do not ignore NULL characters.
  72. dcb.fAbortOnError = FALSE; // Ignore serial framing errors.
  73. if (!::SetCommState(handle, &dcb))
  74. {
  75. DWORD last_error = ::GetLastError();
  76. ::CloseHandle(handle);
  77. ec = boost::system::error_code(last_error,
  78. boost::asio::error::get_system_category());
  79. return ec;
  80. }
  81. // Set up timeouts so that the serial port will behave similarly to a
  82. // network socket. Reads wait for at least one byte, then return with
  83. // whatever they have. Writes return once everything is out the door.
  84. ::COMMTIMEOUTS timeouts;
  85. timeouts.ReadIntervalTimeout = 1;
  86. timeouts.ReadTotalTimeoutMultiplier = 0;
  87. timeouts.ReadTotalTimeoutConstant = 0;
  88. timeouts.WriteTotalTimeoutMultiplier = 0;
  89. timeouts.WriteTotalTimeoutConstant = 0;
  90. if (!::SetCommTimeouts(handle, &timeouts))
  91. {
  92. DWORD last_error = ::GetLastError();
  93. ::CloseHandle(handle);
  94. ec = boost::system::error_code(last_error,
  95. boost::asio::error::get_system_category());
  96. return ec;
  97. }
  98. // We're done. Take ownership of the serial port handle.
  99. if (handle_service_.assign(impl, handle, ec))
  100. ::CloseHandle(handle);
  101. return ec;
  102. }
  103. boost::system::error_code win_iocp_serial_port_service::do_set_option(
  104. win_iocp_serial_port_service::implementation_type& impl,
  105. win_iocp_serial_port_service::store_function_type store,
  106. const void* option, boost::system::error_code& ec)
  107. {
  108. using namespace std; // For memcpy.
  109. ::DCB dcb;
  110. memset(&dcb, 0, sizeof(DCB));
  111. dcb.DCBlength = sizeof(DCB);
  112. if (!::GetCommState(handle_service_.native_handle(impl), &dcb))
  113. {
  114. DWORD last_error = ::GetLastError();
  115. ec = boost::system::error_code(last_error,
  116. boost::asio::error::get_system_category());
  117. return ec;
  118. }
  119. if (store(option, dcb, ec))
  120. return ec;
  121. if (!::SetCommState(handle_service_.native_handle(impl), &dcb))
  122. {
  123. DWORD last_error = ::GetLastError();
  124. ec = boost::system::error_code(last_error,
  125. boost::asio::error::get_system_category());
  126. return ec;
  127. }
  128. ec = boost::system::error_code();
  129. return ec;
  130. }
  131. boost::system::error_code win_iocp_serial_port_service::do_get_option(
  132. const win_iocp_serial_port_service::implementation_type& impl,
  133. win_iocp_serial_port_service::load_function_type load,
  134. void* option, boost::system::error_code& ec) const
  135. {
  136. using namespace std; // For memset.
  137. ::DCB dcb;
  138. memset(&dcb, 0, sizeof(DCB));
  139. dcb.DCBlength = sizeof(DCB);
  140. if (!::GetCommState(handle_service_.native_handle(impl), &dcb))
  141. {
  142. DWORD last_error = ::GetLastError();
  143. ec = boost::system::error_code(last_error,
  144. boost::asio::error::get_system_category());
  145. return ec;
  146. }
  147. return load(option, dcb, ec);
  148. }
  149. } // namespace detail
  150. } // namespace asio
  151. } // namespace boost
  152. #include <boost/asio/detail/pop_options.hpp>
  153. #endif // defined(BOOST_ASIO_HAS_IOCP) && defined(BOOST_ASIO_HAS_SERIAL_PORT)
  154. #endif // BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_SERIAL_PORT_SERVICE_IPP