Statistics
| Revision:

root / tmp / org.txm.statsengine.r.core.win32 / res / win32 / library / BH / include / boost / asio / detail / impl / win_iocp_serial_port_service.ipp @ 2486

History | View | Annotate | Download (5.4 kB)

1
//
2
// detail/impl/win_iocp_serial_port_service.ipp
3
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
//
5
// Copyright (c) 2003-2015 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

    
28
namespace boost {
29
namespace asio {
30
namespace detail {
31

    
32
win_iocp_serial_port_service::win_iocp_serial_port_service(
33
    boost::asio::io_service& io_service)
34
  : handle_service_(io_service)
35
{
36
}
37

    
38
void win_iocp_serial_port_service::shutdown_service()
39
{
40
}
41

    
42
boost::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

    
120
boost::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

    
153
boost::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