PageRenderTime 42ms CodeModel.GetById 39ms app.highlight 1ms RepoModel.GetById 1ms app.codeStats 0ms

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

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