]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // basic_serial_port.hpp | |
3 | // ~~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
1e59de90 | 5 | // Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
7c673cae FG |
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_BASIC_SERIAL_PORT_HPP | |
13 | #define BOOST_ASIO_BASIC_SERIAL_PORT_HPP | |
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_SERIAL_PORT) \ | |
22 | || defined(GENERATING_DOCUMENTATION) | |
23 | ||
24 | #include <string> | |
20effc67 | 25 | #include <boost/asio/any_io_executor.hpp> |
92f5a8d4 | 26 | #include <boost/asio/async_result.hpp> |
7c673cae | 27 | #include <boost/asio/detail/handler_type_requirements.hpp> |
92f5a8d4 TL |
28 | #include <boost/asio/detail/io_object_impl.hpp> |
29 | #include <boost/asio/detail/non_const_lvalue.hpp> | |
7c673cae | 30 | #include <boost/asio/detail/throw_error.hpp> |
92f5a8d4 | 31 | #include <boost/asio/detail/type_traits.hpp> |
7c673cae | 32 | #include <boost/asio/error.hpp> |
92f5a8d4 | 33 | #include <boost/asio/execution_context.hpp> |
7c673cae | 34 | #include <boost/asio/serial_port_base.hpp> |
92f5a8d4 TL |
35 | #if defined(BOOST_ASIO_HAS_IOCP) |
36 | # include <boost/asio/detail/win_iocp_serial_port_service.hpp> | |
37 | #else | |
1e59de90 | 38 | # include <boost/asio/detail/posix_serial_port_service.hpp> |
92f5a8d4 TL |
39 | #endif |
40 | ||
41 | #if defined(BOOST_ASIO_HAS_MOVE) | |
42 | # include <utility> | |
43 | #endif // defined(BOOST_ASIO_HAS_MOVE) | |
7c673cae FG |
44 | |
45 | #include <boost/asio/detail/push_options.hpp> | |
46 | ||
47 | namespace boost { | |
48 | namespace asio { | |
49 | ||
50 | /// Provides serial port functionality. | |
51 | /** | |
92f5a8d4 TL |
52 | * The basic_serial_port class provides a wrapper over serial port |
53 | * functionality. | |
7c673cae FG |
54 | * |
55 | * @par Thread Safety | |
56 | * @e Distinct @e objects: Safe.@n | |
57 | * @e Shared @e objects: Unsafe. | |
58 | */ | |
20effc67 | 59 | template <typename Executor = any_io_executor> |
7c673cae | 60 | class basic_serial_port |
92f5a8d4 | 61 | : public serial_port_base |
7c673cae FG |
62 | { |
63 | public: | |
92f5a8d4 TL |
64 | /// The type of the executor associated with the object. |
65 | typedef Executor executor_type; | |
66 | ||
67 | /// Rebinds the serial port type to another executor. | |
68 | template <typename Executor1> | |
69 | struct rebind_executor | |
70 | { | |
71 | /// The serial port type when rebound to the specified executor. | |
72 | typedef basic_serial_port<Executor1> other; | |
73 | }; | |
74 | ||
7c673cae | 75 | /// The native representation of a serial port. |
92f5a8d4 TL |
76 | #if defined(GENERATING_DOCUMENTATION) |
77 | typedef implementation_defined native_handle_type; | |
78 | #elif defined(BOOST_ASIO_HAS_IOCP) | |
79 | typedef detail::win_iocp_serial_port_service::native_handle_type | |
80 | native_handle_type; | |
81 | #else | |
1e59de90 | 82 | typedef detail::posix_serial_port_service::native_handle_type |
92f5a8d4 TL |
83 | native_handle_type; |
84 | #endif | |
85 | ||
86 | /// A basic_basic_serial_port is always the lowest layer. | |
87 | typedef basic_serial_port lowest_layer_type; | |
7c673cae | 88 | |
92f5a8d4 TL |
89 | /// Construct a basic_serial_port without opening it. |
90 | /** | |
91 | * This constructor creates a serial port without opening it. | |
92 | * | |
93 | * @param ex The I/O executor that the serial port will use, by default, to | |
94 | * dispatch handlers for any asynchronous operations performed on the | |
95 | * serial port. | |
96 | */ | |
97 | explicit basic_serial_port(const executor_type& ex) | |
1e59de90 | 98 | : impl_(0, ex) |
92f5a8d4 TL |
99 | { |
100 | } | |
7c673cae FG |
101 | |
102 | /// Construct a basic_serial_port without opening it. | |
103 | /** | |
104 | * This constructor creates a serial port without opening it. | |
105 | * | |
92f5a8d4 TL |
106 | * @param context An execution context which provides the I/O executor that |
107 | * the serial port will use, by default, to dispatch handlers for any | |
108 | * asynchronous operations performed on the serial port. | |
109 | */ | |
110 | template <typename ExecutionContext> | |
111 | explicit basic_serial_port(ExecutionContext& context, | |
1e59de90 | 112 | typename constraint< |
92f5a8d4 | 113 | is_convertible<ExecutionContext&, execution_context&>::value, |
1e59de90 TL |
114 | defaulted_constraint |
115 | >::type = defaulted_constraint()) | |
116 | : impl_(0, 0, context) | |
92f5a8d4 TL |
117 | { |
118 | } | |
119 | ||
120 | /// Construct and open a basic_serial_port. | |
121 | /** | |
122 | * This constructor creates and opens a serial port for the specified device | |
123 | * name. | |
124 | * | |
125 | * @param ex The I/O executor that the serial port will use, by default, to | |
126 | * dispatch handlers for any asynchronous operations performed on the | |
127 | * serial port. | |
128 | * | |
129 | * @param device The platform-specific device name for this serial | |
130 | * port. | |
131 | */ | |
132 | basic_serial_port(const executor_type& ex, const char* device) | |
1e59de90 | 133 | : impl_(0, ex) |
92f5a8d4 TL |
134 | { |
135 | boost::system::error_code ec; | |
136 | impl_.get_service().open(impl_.get_implementation(), device, ec); | |
137 | boost::asio::detail::throw_error(ec, "open"); | |
138 | } | |
139 | ||
140 | /// Construct and open a basic_serial_port. | |
141 | /** | |
142 | * This constructor creates and opens a serial port for the specified device | |
143 | * name. | |
144 | * | |
145 | * @param context An execution context which provides the I/O executor that | |
146 | * the serial port will use, by default, to dispatch handlers for any | |
147 | * asynchronous operations performed on the serial port. | |
148 | * | |
149 | * @param device The platform-specific device name for this serial | |
150 | * port. | |
7c673cae | 151 | */ |
92f5a8d4 TL |
152 | template <typename ExecutionContext> |
153 | basic_serial_port(ExecutionContext& context, const char* device, | |
1e59de90 | 154 | typename constraint< |
92f5a8d4 | 155 | is_convertible<ExecutionContext&, execution_context&>::value |
1e59de90 TL |
156 | >::type = 0) |
157 | : impl_(0, 0, context) | |
7c673cae | 158 | { |
92f5a8d4 TL |
159 | boost::system::error_code ec; |
160 | impl_.get_service().open(impl_.get_implementation(), device, ec); | |
161 | boost::asio::detail::throw_error(ec, "open"); | |
7c673cae FG |
162 | } |
163 | ||
164 | /// Construct and open a basic_serial_port. | |
165 | /** | |
166 | * This constructor creates and opens a serial port for the specified device | |
167 | * name. | |
168 | * | |
92f5a8d4 TL |
169 | * @param ex The I/O executor that the serial port will use, by default, to |
170 | * dispatch handlers for any asynchronous operations performed on the | |
171 | * serial port. | |
7c673cae FG |
172 | * |
173 | * @param device The platform-specific device name for this serial | |
174 | * port. | |
175 | */ | |
92f5a8d4 | 176 | basic_serial_port(const executor_type& ex, const std::string& device) |
1e59de90 | 177 | : impl_(0, ex) |
7c673cae FG |
178 | { |
179 | boost::system::error_code ec; | |
92f5a8d4 | 180 | impl_.get_service().open(impl_.get_implementation(), device, ec); |
7c673cae FG |
181 | boost::asio::detail::throw_error(ec, "open"); |
182 | } | |
183 | ||
184 | /// Construct and open a basic_serial_port. | |
185 | /** | |
186 | * This constructor creates and opens a serial port for the specified device | |
187 | * name. | |
188 | * | |
92f5a8d4 TL |
189 | * @param context An execution context which provides the I/O executor that |
190 | * the serial port will use, by default, to dispatch handlers for any | |
191 | * asynchronous operations performed on the serial port. | |
7c673cae FG |
192 | * |
193 | * @param device The platform-specific device name for this serial | |
194 | * port. | |
195 | */ | |
92f5a8d4 TL |
196 | template <typename ExecutionContext> |
197 | basic_serial_port(ExecutionContext& context, const std::string& device, | |
1e59de90 | 198 | typename constraint< |
92f5a8d4 | 199 | is_convertible<ExecutionContext&, execution_context&>::value |
1e59de90 TL |
200 | >::type = 0) |
201 | : impl_(0, 0, context) | |
7c673cae FG |
202 | { |
203 | boost::system::error_code ec; | |
92f5a8d4 | 204 | impl_.get_service().open(impl_.get_implementation(), device, ec); |
7c673cae FG |
205 | boost::asio::detail::throw_error(ec, "open"); |
206 | } | |
207 | ||
208 | /// Construct a basic_serial_port on an existing native serial port. | |
209 | /** | |
210 | * This constructor creates a serial port object to hold an existing native | |
211 | * serial port. | |
212 | * | |
92f5a8d4 TL |
213 | * @param ex The I/O executor that the serial port will use, by default, to |
214 | * dispatch handlers for any asynchronous operations performed on the | |
215 | * serial port. | |
7c673cae FG |
216 | * |
217 | * @param native_serial_port A native serial port. | |
218 | * | |
219 | * @throws boost::system::system_error Thrown on failure. | |
220 | */ | |
92f5a8d4 | 221 | basic_serial_port(const executor_type& ex, |
7c673cae | 222 | const native_handle_type& native_serial_port) |
1e59de90 | 223 | : impl_(0, ex) |
92f5a8d4 TL |
224 | { |
225 | boost::system::error_code ec; | |
226 | impl_.get_service().assign(impl_.get_implementation(), | |
227 | native_serial_port, ec); | |
228 | boost::asio::detail::throw_error(ec, "assign"); | |
229 | } | |
230 | ||
231 | /// Construct a basic_serial_port on an existing native serial port. | |
232 | /** | |
233 | * This constructor creates a serial port object to hold an existing native | |
234 | * serial port. | |
235 | * | |
236 | * @param context An execution context which provides the I/O executor that | |
237 | * the serial port will use, by default, to dispatch handlers for any | |
238 | * asynchronous operations performed on the serial port. | |
239 | * | |
240 | * @param native_serial_port A native serial port. | |
241 | * | |
242 | * @throws boost::system::system_error Thrown on failure. | |
243 | */ | |
244 | template <typename ExecutionContext> | |
245 | basic_serial_port(ExecutionContext& context, | |
246 | const native_handle_type& native_serial_port, | |
1e59de90 | 247 | typename constraint< |
92f5a8d4 | 248 | is_convertible<ExecutionContext&, execution_context&>::value |
1e59de90 TL |
249 | >::type = 0) |
250 | : impl_(0, 0, context) | |
7c673cae FG |
251 | { |
252 | boost::system::error_code ec; | |
92f5a8d4 | 253 | impl_.get_service().assign(impl_.get_implementation(), |
7c673cae FG |
254 | native_serial_port, ec); |
255 | boost::asio::detail::throw_error(ec, "assign"); | |
256 | } | |
257 | ||
258 | #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
259 | /// Move-construct a basic_serial_port from another. | |
260 | /** | |
261 | * This constructor moves a serial port from one object to another. | |
262 | * | |
263 | * @param other The other basic_serial_port object from which the move will | |
264 | * occur. | |
265 | * | |
266 | * @note Following the move, the moved-from object is in the same state as if | |
92f5a8d4 TL |
267 | * constructed using the @c basic_serial_port(const executor_type&) |
268 | * constructor. | |
7c673cae FG |
269 | */ |
270 | basic_serial_port(basic_serial_port&& other) | |
92f5a8d4 | 271 | : impl_(std::move(other.impl_)) |
7c673cae FG |
272 | { |
273 | } | |
274 | ||
275 | /// Move-assign a basic_serial_port from another. | |
276 | /** | |
277 | * This assignment operator moves a serial port from one object to another. | |
278 | * | |
279 | * @param other The other basic_serial_port object from which the move will | |
280 | * occur. | |
281 | * | |
282 | * @note Following the move, the moved-from object is in the same state as if | |
92f5a8d4 TL |
283 | * constructed using the @c basic_serial_port(const executor_type&) |
284 | * constructor. | |
7c673cae FG |
285 | */ |
286 | basic_serial_port& operator=(basic_serial_port&& other) | |
287 | { | |
92f5a8d4 | 288 | impl_ = std::move(other.impl_); |
7c673cae FG |
289 | return *this; |
290 | } | |
291 | #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
292 | ||
92f5a8d4 TL |
293 | /// Destroys the serial port. |
294 | /** | |
295 | * This function destroys the serial port, cancelling any outstanding | |
296 | * asynchronous wait operations associated with the serial port as if by | |
297 | * calling @c cancel. | |
298 | */ | |
299 | ~basic_serial_port() | |
300 | { | |
301 | } | |
302 | ||
303 | /// Get the executor associated with the object. | |
304 | executor_type get_executor() BOOST_ASIO_NOEXCEPT | |
305 | { | |
306 | return impl_.get_executor(); | |
307 | } | |
308 | ||
7c673cae FG |
309 | /// Get a reference to the lowest layer. |
310 | /** | |
311 | * This function returns a reference to the lowest layer in a stack of | |
312 | * layers. Since a basic_serial_port cannot contain any further layers, it | |
313 | * simply returns a reference to itself. | |
314 | * | |
315 | * @return A reference to the lowest layer in the stack of layers. Ownership | |
316 | * is not transferred to the caller. | |
317 | */ | |
318 | lowest_layer_type& lowest_layer() | |
319 | { | |
320 | return *this; | |
321 | } | |
322 | ||
323 | /// Get a const reference to the lowest layer. | |
324 | /** | |
325 | * This function returns a const reference to the lowest layer in a stack of | |
326 | * layers. Since a basic_serial_port cannot contain any further layers, it | |
327 | * simply returns a reference to itself. | |
328 | * | |
329 | * @return A const reference to the lowest layer in the stack of layers. | |
330 | * Ownership is not transferred to the caller. | |
331 | */ | |
332 | const lowest_layer_type& lowest_layer() const | |
333 | { | |
334 | return *this; | |
335 | } | |
336 | ||
337 | /// Open the serial port using the specified device name. | |
338 | /** | |
339 | * This function opens the serial port for the specified device name. | |
340 | * | |
341 | * @param device The platform-specific device name. | |
342 | * | |
343 | * @throws boost::system::system_error Thrown on failure. | |
344 | */ | |
345 | void open(const std::string& device) | |
346 | { | |
347 | boost::system::error_code ec; | |
92f5a8d4 | 348 | impl_.get_service().open(impl_.get_implementation(), device, ec); |
7c673cae FG |
349 | boost::asio::detail::throw_error(ec, "open"); |
350 | } | |
351 | ||
352 | /// Open the serial port using the specified device name. | |
353 | /** | |
354 | * This function opens the serial port using the given platform-specific | |
355 | * device name. | |
356 | * | |
357 | * @param device The platform-specific device name. | |
358 | * | |
359 | * @param ec Set the indicate what error occurred, if any. | |
360 | */ | |
b32b8144 | 361 | BOOST_ASIO_SYNC_OP_VOID open(const std::string& device, |
7c673cae FG |
362 | boost::system::error_code& ec) |
363 | { | |
92f5a8d4 | 364 | impl_.get_service().open(impl_.get_implementation(), device, ec); |
b32b8144 | 365 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); |
7c673cae FG |
366 | } |
367 | ||
368 | /// Assign an existing native serial port to the serial port. | |
369 | /* | |
370 | * This function opens the serial port to hold an existing native serial port. | |
371 | * | |
372 | * @param native_serial_port A native serial port. | |
373 | * | |
374 | * @throws boost::system::system_error Thrown on failure. | |
375 | */ | |
376 | void assign(const native_handle_type& native_serial_port) | |
377 | { | |
378 | boost::system::error_code ec; | |
92f5a8d4 | 379 | impl_.get_service().assign(impl_.get_implementation(), |
7c673cae FG |
380 | native_serial_port, ec); |
381 | boost::asio::detail::throw_error(ec, "assign"); | |
382 | } | |
383 | ||
384 | /// Assign an existing native serial port to the serial port. | |
385 | /* | |
386 | * This function opens the serial port to hold an existing native serial port. | |
387 | * | |
388 | * @param native_serial_port A native serial port. | |
389 | * | |
390 | * @param ec Set to indicate what error occurred, if any. | |
391 | */ | |
b32b8144 | 392 | BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port, |
7c673cae FG |
393 | boost::system::error_code& ec) |
394 | { | |
92f5a8d4 | 395 | impl_.get_service().assign(impl_.get_implementation(), |
7c673cae | 396 | native_serial_port, ec); |
b32b8144 | 397 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); |
7c673cae FG |
398 | } |
399 | ||
400 | /// Determine whether the serial port is open. | |
401 | bool is_open() const | |
402 | { | |
92f5a8d4 | 403 | return impl_.get_service().is_open(impl_.get_implementation()); |
7c673cae FG |
404 | } |
405 | ||
406 | /// Close the serial port. | |
407 | /** | |
408 | * This function is used to close the serial port. Any asynchronous read or | |
409 | * write operations will be cancelled immediately, and will complete with the | |
410 | * boost::asio::error::operation_aborted error. | |
411 | * | |
412 | * @throws boost::system::system_error Thrown on failure. | |
413 | */ | |
414 | void close() | |
415 | { | |
416 | boost::system::error_code ec; | |
92f5a8d4 | 417 | impl_.get_service().close(impl_.get_implementation(), ec); |
7c673cae FG |
418 | boost::asio::detail::throw_error(ec, "close"); |
419 | } | |
420 | ||
421 | /// Close the serial port. | |
422 | /** | |
423 | * This function is used to close the serial port. Any asynchronous read or | |
424 | * write operations will be cancelled immediately, and will complete with the | |
425 | * boost::asio::error::operation_aborted error. | |
426 | * | |
427 | * @param ec Set to indicate what error occurred, if any. | |
428 | */ | |
b32b8144 | 429 | BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) |
7c673cae | 430 | { |
92f5a8d4 | 431 | impl_.get_service().close(impl_.get_implementation(), ec); |
b32b8144 | 432 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); |
7c673cae FG |
433 | } |
434 | ||
435 | /// Get the native serial port representation. | |
436 | /** | |
437 | * This function may be used to obtain the underlying representation of the | |
438 | * serial port. This is intended to allow access to native serial port | |
439 | * functionality that is not otherwise provided. | |
440 | */ | |
441 | native_handle_type native_handle() | |
442 | { | |
92f5a8d4 | 443 | return impl_.get_service().native_handle(impl_.get_implementation()); |
7c673cae FG |
444 | } |
445 | ||
446 | /// Cancel all asynchronous operations associated with the serial port. | |
447 | /** | |
448 | * This function causes all outstanding asynchronous read or write operations | |
449 | * to finish immediately, and the handlers for cancelled operations will be | |
450 | * passed the boost::asio::error::operation_aborted error. | |
451 | * | |
452 | * @throws boost::system::system_error Thrown on failure. | |
453 | */ | |
454 | void cancel() | |
455 | { | |
456 | boost::system::error_code ec; | |
92f5a8d4 | 457 | impl_.get_service().cancel(impl_.get_implementation(), ec); |
7c673cae FG |
458 | boost::asio::detail::throw_error(ec, "cancel"); |
459 | } | |
460 | ||
461 | /// Cancel all asynchronous operations associated with the serial port. | |
462 | /** | |
463 | * This function causes all outstanding asynchronous read or write operations | |
464 | * to finish immediately, and the handlers for cancelled operations will be | |
465 | * passed the boost::asio::error::operation_aborted error. | |
466 | * | |
467 | * @param ec Set to indicate what error occurred, if any. | |
468 | */ | |
b32b8144 | 469 | BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) |
7c673cae | 470 | { |
92f5a8d4 | 471 | impl_.get_service().cancel(impl_.get_implementation(), ec); |
b32b8144 | 472 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); |
7c673cae FG |
473 | } |
474 | ||
475 | /// Send a break sequence to the serial port. | |
476 | /** | |
477 | * This function causes a break sequence of platform-specific duration to be | |
478 | * sent out the serial port. | |
479 | * | |
480 | * @throws boost::system::system_error Thrown on failure. | |
481 | */ | |
482 | void send_break() | |
483 | { | |
484 | boost::system::error_code ec; | |
92f5a8d4 | 485 | impl_.get_service().send_break(impl_.get_implementation(), ec); |
7c673cae FG |
486 | boost::asio::detail::throw_error(ec, "send_break"); |
487 | } | |
488 | ||
489 | /// Send a break sequence to the serial port. | |
490 | /** | |
491 | * This function causes a break sequence of platform-specific duration to be | |
492 | * sent out the serial port. | |
493 | * | |
494 | * @param ec Set to indicate what error occurred, if any. | |
495 | */ | |
b32b8144 | 496 | BOOST_ASIO_SYNC_OP_VOID send_break(boost::system::error_code& ec) |
7c673cae | 497 | { |
92f5a8d4 | 498 | impl_.get_service().send_break(impl_.get_implementation(), ec); |
b32b8144 | 499 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); |
7c673cae FG |
500 | } |
501 | ||
502 | /// Set an option on the serial port. | |
503 | /** | |
504 | * This function is used to set an option on the serial port. | |
505 | * | |
506 | * @param option The option value to be set on the serial port. | |
507 | * | |
508 | * @throws boost::system::system_error Thrown on failure. | |
509 | * | |
510 | * @sa SettableSerialPortOption @n | |
511 | * boost::asio::serial_port_base::baud_rate @n | |
512 | * boost::asio::serial_port_base::flow_control @n | |
513 | * boost::asio::serial_port_base::parity @n | |
514 | * boost::asio::serial_port_base::stop_bits @n | |
515 | * boost::asio::serial_port_base::character_size | |
516 | */ | |
517 | template <typename SettableSerialPortOption> | |
518 | void set_option(const SettableSerialPortOption& option) | |
519 | { | |
520 | boost::system::error_code ec; | |
92f5a8d4 | 521 | impl_.get_service().set_option(impl_.get_implementation(), option, ec); |
7c673cae FG |
522 | boost::asio::detail::throw_error(ec, "set_option"); |
523 | } | |
524 | ||
525 | /// Set an option on the serial port. | |
526 | /** | |
527 | * This function is used to set an option on the serial port. | |
528 | * | |
529 | * @param option The option value to be set on the serial port. | |
530 | * | |
531 | * @param ec Set to indicate what error occurred, if any. | |
532 | * | |
533 | * @sa SettableSerialPortOption @n | |
534 | * boost::asio::serial_port_base::baud_rate @n | |
535 | * boost::asio::serial_port_base::flow_control @n | |
536 | * boost::asio::serial_port_base::parity @n | |
537 | * boost::asio::serial_port_base::stop_bits @n | |
538 | * boost::asio::serial_port_base::character_size | |
539 | */ | |
540 | template <typename SettableSerialPortOption> | |
b32b8144 | 541 | BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option, |
7c673cae FG |
542 | boost::system::error_code& ec) |
543 | { | |
92f5a8d4 | 544 | impl_.get_service().set_option(impl_.get_implementation(), option, ec); |
b32b8144 | 545 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); |
7c673cae FG |
546 | } |
547 | ||
548 | /// Get an option from the serial port. | |
549 | /** | |
550 | * This function is used to get the current value of an option on the serial | |
551 | * port. | |
552 | * | |
553 | * @param option The option value to be obtained from the serial port. | |
554 | * | |
555 | * @throws boost::system::system_error Thrown on failure. | |
556 | * | |
557 | * @sa GettableSerialPortOption @n | |
558 | * boost::asio::serial_port_base::baud_rate @n | |
559 | * boost::asio::serial_port_base::flow_control @n | |
560 | * boost::asio::serial_port_base::parity @n | |
561 | * boost::asio::serial_port_base::stop_bits @n | |
562 | * boost::asio::serial_port_base::character_size | |
563 | */ | |
564 | template <typename GettableSerialPortOption> | |
92f5a8d4 | 565 | void get_option(GettableSerialPortOption& option) const |
7c673cae FG |
566 | { |
567 | boost::system::error_code ec; | |
92f5a8d4 | 568 | impl_.get_service().get_option(impl_.get_implementation(), option, ec); |
7c673cae FG |
569 | boost::asio::detail::throw_error(ec, "get_option"); |
570 | } | |
571 | ||
572 | /// Get an option from the serial port. | |
573 | /** | |
574 | * This function is used to get the current value of an option on the serial | |
575 | * port. | |
576 | * | |
577 | * @param option The option value to be obtained from the serial port. | |
578 | * | |
579 | * @param ec Set to indicate what error occurred, if any. | |
580 | * | |
581 | * @sa GettableSerialPortOption @n | |
582 | * boost::asio::serial_port_base::baud_rate @n | |
583 | * boost::asio::serial_port_base::flow_control @n | |
584 | * boost::asio::serial_port_base::parity @n | |
585 | * boost::asio::serial_port_base::stop_bits @n | |
586 | * boost::asio::serial_port_base::character_size | |
587 | */ | |
588 | template <typename GettableSerialPortOption> | |
b32b8144 | 589 | BOOST_ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option, |
92f5a8d4 | 590 | boost::system::error_code& ec) const |
7c673cae | 591 | { |
92f5a8d4 | 592 | impl_.get_service().get_option(impl_.get_implementation(), option, ec); |
b32b8144 | 593 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); |
7c673cae FG |
594 | } |
595 | ||
596 | /// Write some data to the serial port. | |
597 | /** | |
598 | * This function is used to write data to the serial port. The function call | |
599 | * will block until one or more bytes of the data has been written | |
600 | * successfully, or until an error occurs. | |
601 | * | |
602 | * @param buffers One or more data buffers to be written to the serial port. | |
603 | * | |
604 | * @returns The number of bytes written. | |
605 | * | |
606 | * @throws boost::system::system_error Thrown on failure. An error code of | |
607 | * boost::asio::error::eof indicates that the connection was closed by the | |
608 | * peer. | |
609 | * | |
610 | * @note The write_some operation may not transmit all of the data to the | |
611 | * peer. Consider using the @ref write function if you need to ensure that | |
612 | * all data is written before the blocking operation completes. | |
613 | * | |
614 | * @par Example | |
615 | * To write a single data buffer use the @ref buffer function as follows: | |
616 | * @code | |
92f5a8d4 | 617 | * basic_serial_port.write_some(boost::asio::buffer(data, size)); |
7c673cae FG |
618 | * @endcode |
619 | * See the @ref buffer documentation for information on writing multiple | |
620 | * buffers in one go, and how to use it with arrays, boost::array or | |
621 | * std::vector. | |
622 | */ | |
623 | template <typename ConstBufferSequence> | |
624 | std::size_t write_some(const ConstBufferSequence& buffers) | |
625 | { | |
626 | boost::system::error_code ec; | |
92f5a8d4 TL |
627 | std::size_t s = impl_.get_service().write_some( |
628 | impl_.get_implementation(), buffers, ec); | |
7c673cae FG |
629 | boost::asio::detail::throw_error(ec, "write_some"); |
630 | return s; | |
631 | } | |
632 | ||
633 | /// Write some data to the serial port. | |
634 | /** | |
635 | * This function is used to write data to the serial port. The function call | |
636 | * will block until one or more bytes of the data has been written | |
637 | * successfully, or until an error occurs. | |
638 | * | |
639 | * @param buffers One or more data buffers to be written to the serial port. | |
640 | * | |
641 | * @param ec Set to indicate what error occurred, if any. | |
642 | * | |
643 | * @returns The number of bytes written. Returns 0 if an error occurred. | |
644 | * | |
645 | * @note The write_some operation may not transmit all of the data to the | |
646 | * peer. Consider using the @ref write function if you need to ensure that | |
647 | * all data is written before the blocking operation completes. | |
648 | */ | |
649 | template <typename ConstBufferSequence> | |
650 | std::size_t write_some(const ConstBufferSequence& buffers, | |
651 | boost::system::error_code& ec) | |
652 | { | |
92f5a8d4 TL |
653 | return impl_.get_service().write_some( |
654 | impl_.get_implementation(), buffers, ec); | |
7c673cae FG |
655 | } |
656 | ||
657 | /// Start an asynchronous write. | |
658 | /** | |
659 | * This function is used to asynchronously write data to the serial port. | |
1e59de90 TL |
660 | * It is an initiating function for an @ref asynchronous_operation, and always |
661 | * returns immediately. | |
7c673cae FG |
662 | * |
663 | * @param buffers One or more data buffers to be written to the serial port. | |
664 | * Although the buffers object may be copied as necessary, ownership of the | |
665 | * underlying memory blocks is retained by the caller, which must guarantee | |
1e59de90 | 666 | * that they remain valid until the completion handler is called. |
7c673cae | 667 | * |
1e59de90 TL |
668 | * @param token The @ref completion_token that will be used to produce a |
669 | * completion handler, which will be called when the write completes. | |
670 | * Potential completion tokens include @ref use_future, @ref use_awaitable, | |
671 | * @ref yield_context, or a function object with the correct completion | |
672 | * signature. The function signature of the completion handler must be: | |
7c673cae FG |
673 | * @code void handler( |
674 | * const boost::system::error_code& error, // Result of operation. | |
1e59de90 | 675 | * std::size_t bytes_transferred // Number of bytes written. |
7c673cae FG |
676 | * ); @endcode |
677 | * Regardless of whether the asynchronous operation completes immediately or | |
1e59de90 TL |
678 | * not, the completion handler will not be invoked from within this function. |
679 | * On immediate completion, invocation of the handler will be performed in a | |
92f5a8d4 | 680 | * manner equivalent to using boost::asio::post(). |
7c673cae | 681 | * |
1e59de90 TL |
682 | * @par Completion Signature |
683 | * @code void(boost::system::error_code, std::size_t) @endcode | |
684 | * | |
7c673cae FG |
685 | * @note The write operation may not transmit all of the data to the peer. |
686 | * Consider using the @ref async_write function if you need to ensure that all | |
687 | * data is written before the asynchronous operation completes. | |
688 | * | |
689 | * @par Example | |
690 | * To write a single data buffer use the @ref buffer function as follows: | |
691 | * @code | |
92f5a8d4 TL |
692 | * basic_serial_port.async_write_some( |
693 | * boost::asio::buffer(data, size), handler); | |
7c673cae FG |
694 | * @endcode |
695 | * See the @ref buffer documentation for information on writing multiple | |
696 | * buffers in one go, and how to use it with arrays, boost::array or | |
697 | * std::vector. | |
1e59de90 TL |
698 | * |
699 | * @par Per-Operation Cancellation | |
700 | * On POSIX or Windows operating systems, this asynchronous operation supports | |
701 | * cancellation for the following boost::asio::cancellation_type values: | |
702 | * | |
703 | * @li @c cancellation_type::terminal | |
704 | * | |
705 | * @li @c cancellation_type::partial | |
706 | * | |
707 | * @li @c cancellation_type::total | |
7c673cae | 708 | */ |
92f5a8d4 TL |
709 | template <typename ConstBufferSequence, |
710 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, | |
1e59de90 | 711 | std::size_t)) WriteToken |
92f5a8d4 | 712 | BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> |
1e59de90 | 713 | BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteToken, |
7c673cae FG |
714 | void (boost::system::error_code, std::size_t)) |
715 | async_write_some(const ConstBufferSequence& buffers, | |
1e59de90 | 716 | BOOST_ASIO_MOVE_ARG(WriteToken) token |
92f5a8d4 | 717 | BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) |
7c673cae | 718 | { |
1e59de90 | 719 | return async_initiate<WriteToken, |
92f5a8d4 | 720 | void (boost::system::error_code, std::size_t)>( |
1e59de90 | 721 | initiate_async_write_some(this), token, buffers); |
7c673cae FG |
722 | } |
723 | ||
724 | /// Read some data from the serial port. | |
725 | /** | |
726 | * This function is used to read data from the serial port. The function | |
727 | * call will block until one or more bytes of data has been read successfully, | |
728 | * or until an error occurs. | |
729 | * | |
730 | * @param buffers One or more buffers into which the data will be read. | |
731 | * | |
732 | * @returns The number of bytes read. | |
733 | * | |
734 | * @throws boost::system::system_error Thrown on failure. An error code of | |
735 | * boost::asio::error::eof indicates that the connection was closed by the | |
736 | * peer. | |
737 | * | |
738 | * @note The read_some operation may not read all of the requested number of | |
739 | * bytes. Consider using the @ref read function if you need to ensure that | |
740 | * the requested amount of data is read before the blocking operation | |
741 | * completes. | |
742 | * | |
743 | * @par Example | |
744 | * To read into a single data buffer use the @ref buffer function as follows: | |
745 | * @code | |
92f5a8d4 | 746 | * basic_serial_port.read_some(boost::asio::buffer(data, size)); |
7c673cae FG |
747 | * @endcode |
748 | * See the @ref buffer documentation for information on reading into multiple | |
749 | * buffers in one go, and how to use it with arrays, boost::array or | |
750 | * std::vector. | |
751 | */ | |
752 | template <typename MutableBufferSequence> | |
753 | std::size_t read_some(const MutableBufferSequence& buffers) | |
754 | { | |
755 | boost::system::error_code ec; | |
92f5a8d4 TL |
756 | std::size_t s = impl_.get_service().read_some( |
757 | impl_.get_implementation(), buffers, ec); | |
7c673cae FG |
758 | boost::asio::detail::throw_error(ec, "read_some"); |
759 | return s; | |
760 | } | |
761 | ||
762 | /// Read some data from the serial port. | |
763 | /** | |
764 | * This function is used to read data from the serial port. The function | |
765 | * call will block until one or more bytes of data has been read successfully, | |
766 | * or until an error occurs. | |
767 | * | |
768 | * @param buffers One or more buffers into which the data will be read. | |
769 | * | |
770 | * @param ec Set to indicate what error occurred, if any. | |
771 | * | |
772 | * @returns The number of bytes read. Returns 0 if an error occurred. | |
773 | * | |
774 | * @note The read_some operation may not read all of the requested number of | |
775 | * bytes. Consider using the @ref read function if you need to ensure that | |
776 | * the requested amount of data is read before the blocking operation | |
777 | * completes. | |
778 | */ | |
779 | template <typename MutableBufferSequence> | |
780 | std::size_t read_some(const MutableBufferSequence& buffers, | |
781 | boost::system::error_code& ec) | |
782 | { | |
92f5a8d4 TL |
783 | return impl_.get_service().read_some( |
784 | impl_.get_implementation(), buffers, ec); | |
7c673cae FG |
785 | } |
786 | ||
787 | /// Start an asynchronous read. | |
788 | /** | |
789 | * This function is used to asynchronously read data from the serial port. | |
1e59de90 TL |
790 | * It is an initiating function for an @ref asynchronous_operation, and always |
791 | * returns immediately. | |
7c673cae FG |
792 | * |
793 | * @param buffers One or more buffers into which the data will be read. | |
794 | * Although the buffers object may be copied as necessary, ownership of the | |
795 | * underlying memory blocks is retained by the caller, which must guarantee | |
1e59de90 | 796 | * that they remain valid until the completion handler is called. |
7c673cae | 797 | * |
1e59de90 TL |
798 | * @param token The @ref completion_token that will be used to produce a |
799 | * completion handler, which will be called when the read completes. | |
800 | * Potential completion tokens include @ref use_future, @ref use_awaitable, | |
801 | * @ref yield_context, or a function object with the correct completion | |
802 | * signature. The function signature of the completion handler must be: | |
7c673cae FG |
803 | * @code void handler( |
804 | * const boost::system::error_code& error, // Result of operation. | |
1e59de90 | 805 | * std::size_t bytes_transferred // Number of bytes read. |
7c673cae FG |
806 | * ); @endcode |
807 | * Regardless of whether the asynchronous operation completes immediately or | |
1e59de90 TL |
808 | * not, the completion handler will not be invoked from within this function. |
809 | * On immediate completion, invocation of the handler will be performed in a | |
92f5a8d4 | 810 | * manner equivalent to using boost::asio::post(). |
7c673cae | 811 | * |
1e59de90 TL |
812 | * @par Completion Signature |
813 | * @code void(boost::system::error_code, std::size_t) @endcode | |
814 | * | |
7c673cae FG |
815 | * @note The read operation may not read all of the requested number of bytes. |
816 | * Consider using the @ref async_read function if you need to ensure that the | |
817 | * requested amount of data is read before the asynchronous operation | |
818 | * completes. | |
819 | * | |
820 | * @par Example | |
821 | * To read into a single data buffer use the @ref buffer function as follows: | |
822 | * @code | |
92f5a8d4 TL |
823 | * basic_serial_port.async_read_some( |
824 | * boost::asio::buffer(data, size), handler); | |
7c673cae FG |
825 | * @endcode |
826 | * See the @ref buffer documentation for information on reading into multiple | |
827 | * buffers in one go, and how to use it with arrays, boost::array or | |
828 | * std::vector. | |
1e59de90 TL |
829 | * |
830 | * @par Per-Operation Cancellation | |
831 | * On POSIX or Windows operating systems, this asynchronous operation supports | |
832 | * cancellation for the following boost::asio::cancellation_type values: | |
833 | * | |
834 | * @li @c cancellation_type::terminal | |
835 | * | |
836 | * @li @c cancellation_type::partial | |
837 | * | |
838 | * @li @c cancellation_type::total | |
7c673cae | 839 | */ |
92f5a8d4 TL |
840 | template <typename MutableBufferSequence, |
841 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, | |
1e59de90 | 842 | std::size_t)) ReadToken |
92f5a8d4 | 843 | BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> |
1e59de90 | 844 | BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadToken, |
7c673cae FG |
845 | void (boost::system::error_code, std::size_t)) |
846 | async_read_some(const MutableBufferSequence& buffers, | |
1e59de90 | 847 | BOOST_ASIO_MOVE_ARG(ReadToken) token |
92f5a8d4 | 848 | BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) |
7c673cae | 849 | { |
1e59de90 | 850 | return async_initiate<ReadToken, |
92f5a8d4 | 851 | void (boost::system::error_code, std::size_t)>( |
1e59de90 | 852 | initiate_async_read_some(this), token, buffers); |
7c673cae | 853 | } |
92f5a8d4 TL |
854 | |
855 | private: | |
856 | // Disallow copying and assignment. | |
857 | basic_serial_port(const basic_serial_port&) BOOST_ASIO_DELETED; | |
858 | basic_serial_port& operator=(const basic_serial_port&) BOOST_ASIO_DELETED; | |
859 | ||
860 | class initiate_async_write_some | |
861 | { | |
862 | public: | |
863 | typedef Executor executor_type; | |
864 | ||
865 | explicit initiate_async_write_some(basic_serial_port* self) | |
866 | : self_(self) | |
867 | { | |
868 | } | |
869 | ||
870 | executor_type get_executor() const BOOST_ASIO_NOEXCEPT | |
871 | { | |
872 | return self_->get_executor(); | |
873 | } | |
874 | ||
875 | template <typename WriteHandler, typename ConstBufferSequence> | |
876 | void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, | |
877 | const ConstBufferSequence& buffers) const | |
878 | { | |
879 | // If you get an error on the following line it means that your handler | |
880 | // does not meet the documented type requirements for a WriteHandler. | |
881 | BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; | |
882 | ||
883 | detail::non_const_lvalue<WriteHandler> handler2(handler); | |
884 | self_->impl_.get_service().async_write_some( | |
20effc67 TL |
885 | self_->impl_.get_implementation(), buffers, |
886 | handler2.value, self_->impl_.get_executor()); | |
92f5a8d4 TL |
887 | } |
888 | ||
889 | private: | |
890 | basic_serial_port* self_; | |
891 | }; | |
892 | ||
893 | class initiate_async_read_some | |
894 | { | |
895 | public: | |
896 | typedef Executor executor_type; | |
897 | ||
898 | explicit initiate_async_read_some(basic_serial_port* self) | |
899 | : self_(self) | |
900 | { | |
901 | } | |
902 | ||
903 | executor_type get_executor() const BOOST_ASIO_NOEXCEPT | |
904 | { | |
905 | return self_->get_executor(); | |
906 | } | |
907 | ||
908 | template <typename ReadHandler, typename MutableBufferSequence> | |
909 | void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, | |
910 | const MutableBufferSequence& buffers) const | |
911 | { | |
912 | // If you get an error on the following line it means that your handler | |
913 | // does not meet the documented type requirements for a ReadHandler. | |
914 | BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; | |
915 | ||
916 | detail::non_const_lvalue<ReadHandler> handler2(handler); | |
917 | self_->impl_.get_service().async_read_some( | |
20effc67 TL |
918 | self_->impl_.get_implementation(), buffers, |
919 | handler2.value, self_->impl_.get_executor()); | |
92f5a8d4 TL |
920 | } |
921 | ||
922 | private: | |
923 | basic_serial_port* self_; | |
924 | }; | |
925 | ||
926 | #if defined(BOOST_ASIO_HAS_IOCP) | |
927 | detail::io_object_impl<detail::win_iocp_serial_port_service, Executor> impl_; | |
928 | #else | |
1e59de90 | 929 | detail::io_object_impl<detail::posix_serial_port_service, Executor> impl_; |
92f5a8d4 | 930 | #endif |
7c673cae FG |
931 | }; |
932 | ||
933 | } // namespace asio | |
934 | } // namespace boost | |
935 | ||
936 | #include <boost/asio/detail/pop_options.hpp> | |
937 | ||
938 | #endif // defined(BOOST_ASIO_HAS_SERIAL_PORT) | |
939 | // || defined(GENERATING_DOCUMENTATION) | |
940 | ||
941 | #endif // BOOST_ASIO_BASIC_SERIAL_PORT_HPP |