basic_serial_port.hpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. //
  2. // basic_serial_port.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2010 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 ASIO_BASIC_SERIAL_PORT_HPP
  12. #define ASIO_BASIC_SERIAL_PORT_HPP
  13. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  14. # pragma once
  15. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  16. #include "asio/detail/push_options.hpp"
  17. #include "asio/detail/push_options.hpp"
  18. #include <string>
  19. #include <boost/config.hpp>
  20. #include "asio/detail/pop_options.hpp"
  21. #include "asio/basic_io_object.hpp"
  22. #include "asio/error.hpp"
  23. #include "asio/serial_port_base.hpp"
  24. #include "asio/serial_port_service.hpp"
  25. #include "asio/detail/throw_error.hpp"
  26. #if defined(ASIO_HAS_SERIAL_PORT) \
  27. || defined(GENERATING_DOCUMENTATION)
  28. namespace asio {
  29. /// Provides serial port functionality.
  30. /**
  31. * The basic_serial_port class template provides functionality that is common
  32. * to all serial ports.
  33. *
  34. * @par Thread Safety
  35. * @e Distinct @e objects: Safe.@n
  36. * @e Shared @e objects: Unsafe.
  37. */
  38. template <typename SerialPortService = serial_port_service>
  39. class basic_serial_port
  40. : public basic_io_object<SerialPortService>,
  41. public serial_port_base
  42. {
  43. public:
  44. /// The native representation of a serial port.
  45. typedef typename SerialPortService::native_type native_type;
  46. /// A basic_serial_port is always the lowest layer.
  47. typedef basic_serial_port<SerialPortService> lowest_layer_type;
  48. /// Construct a basic_serial_port without opening it.
  49. /**
  50. * This constructor creates a serial port without opening it.
  51. *
  52. * @param io_service The io_service object that the serial port will use to
  53. * dispatch handlers for any asynchronous operations performed on the port.
  54. */
  55. explicit basic_serial_port(asio::io_service& io_service)
  56. : basic_io_object<SerialPortService>(io_service)
  57. {
  58. }
  59. /// Construct and open a basic_serial_port.
  60. /**
  61. * This constructor creates and opens a serial port for the specified device
  62. * name.
  63. *
  64. * @param io_service The io_service object that the serial port will use to
  65. * dispatch handlers for any asynchronous operations performed on the port.
  66. *
  67. * @param device The platform-specific device name for this serial
  68. * port.
  69. */
  70. explicit basic_serial_port(asio::io_service& io_service,
  71. const char* device)
  72. : basic_io_object<SerialPortService>(io_service)
  73. {
  74. asio::error_code ec;
  75. this->service.open(this->implementation, device, ec);
  76. asio::detail::throw_error(ec);
  77. }
  78. /// Construct and open a basic_serial_port.
  79. /**
  80. * This constructor creates and opens a serial port for the specified device
  81. * name.
  82. *
  83. * @param io_service The io_service object that the serial port will use to
  84. * dispatch handlers for any asynchronous operations performed on the port.
  85. *
  86. * @param device The platform-specific device name for this serial
  87. * port.
  88. */
  89. explicit basic_serial_port(asio::io_service& io_service,
  90. const std::string& device)
  91. : basic_io_object<SerialPortService>(io_service)
  92. {
  93. asio::error_code ec;
  94. this->service.open(this->implementation, device, ec);
  95. asio::detail::throw_error(ec);
  96. }
  97. /// Construct a basic_serial_port on an existing native serial port.
  98. /**
  99. * This constructor creates a serial port object to hold an existing native
  100. * serial port.
  101. *
  102. * @param io_service The io_service object that the serial port will use to
  103. * dispatch handlers for any asynchronous operations performed on the port.
  104. *
  105. * @param native_serial_port A native serial port.
  106. *
  107. * @throws asio::system_error Thrown on failure.
  108. */
  109. basic_serial_port(asio::io_service& io_service,
  110. const native_type& native_serial_port)
  111. : basic_io_object<SerialPortService>(io_service)
  112. {
  113. asio::error_code ec;
  114. this->service.assign(this->implementation, native_serial_port, ec);
  115. asio::detail::throw_error(ec);
  116. }
  117. /// Get a reference to the lowest layer.
  118. /**
  119. * This function returns a reference to the lowest layer in a stack of
  120. * layers. Since a basic_serial_port cannot contain any further layers, it
  121. * simply returns a reference to itself.
  122. *
  123. * @return A reference to the lowest layer in the stack of layers. Ownership
  124. * is not transferred to the caller.
  125. */
  126. lowest_layer_type& lowest_layer()
  127. {
  128. return *this;
  129. }
  130. /// Get a const reference to the lowest layer.
  131. /**
  132. * This function returns a const reference to the lowest layer in a stack of
  133. * layers. Since a basic_serial_port cannot contain any further layers, it
  134. * simply returns a reference to itself.
  135. *
  136. * @return A const reference to the lowest layer in the stack of layers.
  137. * Ownership is not transferred to the caller.
  138. */
  139. const lowest_layer_type& lowest_layer() const
  140. {
  141. return *this;
  142. }
  143. /// Open the serial port using the specified device name.
  144. /**
  145. * This function opens the serial port for the specified device name.
  146. *
  147. * @param device The platform-specific device name.
  148. *
  149. * @throws asio::system_error Thrown on failure.
  150. */
  151. void open(const std::string& device)
  152. {
  153. asio::error_code ec;
  154. this->service.open(this->implementation, device, ec);
  155. asio::detail::throw_error(ec);
  156. }
  157. /// Open the serial port using the specified device name.
  158. /**
  159. * This function opens the serial port using the given platform-specific
  160. * device name.
  161. *
  162. * @param device The platform-specific device name.
  163. *
  164. * @param ec Set the indicate what error occurred, if any.
  165. */
  166. asio::error_code open(const std::string& device,
  167. asio::error_code& ec)
  168. {
  169. return this->service.open(this->implementation, device, ec);
  170. }
  171. /// Assign an existing native serial port to the serial port.
  172. /*
  173. * This function opens the serial port to hold an existing native serial port.
  174. *
  175. * @param native_serial_port A native serial port.
  176. *
  177. * @throws asio::system_error Thrown on failure.
  178. */
  179. void assign(const native_type& native_serial_port)
  180. {
  181. asio::error_code ec;
  182. this->service.assign(this->implementation, native_serial_port, ec);
  183. asio::detail::throw_error(ec);
  184. }
  185. /// Assign an existing native serial port to the serial port.
  186. /*
  187. * This function opens the serial port to hold an existing native serial port.
  188. *
  189. * @param native_serial_port A native serial port.
  190. *
  191. * @param ec Set to indicate what error occurred, if any.
  192. */
  193. asio::error_code assign(const native_type& native_serial_port,
  194. asio::error_code& ec)
  195. {
  196. return this->service.assign(this->implementation, native_serial_port, ec);
  197. }
  198. /// Determine whether the serial port is open.
  199. bool is_open() const
  200. {
  201. return this->service.is_open(this->implementation);
  202. }
  203. /// Close the serial port.
  204. /**
  205. * This function is used to close the serial port. Any asynchronous read or
  206. * write operations will be cancelled immediately, and will complete with the
  207. * asio::error::operation_aborted error.
  208. *
  209. * @throws asio::system_error Thrown on failure.
  210. */
  211. void close()
  212. {
  213. asio::error_code ec;
  214. this->service.close(this->implementation, ec);
  215. asio::detail::throw_error(ec);
  216. }
  217. /// Close the serial port.
  218. /**
  219. * This function is used to close the serial port. Any asynchronous read or
  220. * write operations will be cancelled immediately, and will complete with the
  221. * asio::error::operation_aborted error.
  222. *
  223. * @param ec Set to indicate what error occurred, if any.
  224. */
  225. asio::error_code close(asio::error_code& ec)
  226. {
  227. return this->service.close(this->implementation, ec);
  228. }
  229. /// Get the native serial port representation.
  230. /**
  231. * This function may be used to obtain the underlying representation of the
  232. * serial port. This is intended to allow access to native serial port
  233. * functionality that is not otherwise provided.
  234. */
  235. native_type native()
  236. {
  237. return this->service.native(this->implementation);
  238. }
  239. /// Cancel all asynchronous operations associated with the serial port.
  240. /**
  241. * This function causes all outstanding asynchronous read or write operations
  242. * to finish immediately, and the handlers for cancelled operations will be
  243. * passed the asio::error::operation_aborted error.
  244. *
  245. * @throws asio::system_error Thrown on failure.
  246. */
  247. void cancel()
  248. {
  249. asio::error_code ec;
  250. this->service.cancel(this->implementation, ec);
  251. asio::detail::throw_error(ec);
  252. }
  253. /// Cancel all asynchronous operations associated with the serial port.
  254. /**
  255. * This function causes all outstanding asynchronous read or write operations
  256. * to finish immediately, and the handlers for cancelled operations will be
  257. * passed the asio::error::operation_aborted error.
  258. *
  259. * @param ec Set to indicate what error occurred, if any.
  260. */
  261. asio::error_code cancel(asio::error_code& ec)
  262. {
  263. return this->service.cancel(this->implementation, ec);
  264. }
  265. /// Send a break sequence to the serial port.
  266. /**
  267. * This function causes a break sequence of platform-specific duration to be
  268. * sent out the serial port.
  269. *
  270. * @throws asio::system_error Thrown on failure.
  271. */
  272. void send_break()
  273. {
  274. asio::error_code ec;
  275. this->service.send_break(this->implementation, ec);
  276. asio::detail::throw_error(ec);
  277. }
  278. /// Send a break sequence to the serial port.
  279. /**
  280. * This function causes a break sequence of platform-specific duration to be
  281. * sent out the serial port.
  282. *
  283. * @param ec Set to indicate what error occurred, if any.
  284. */
  285. asio::error_code send_break(asio::error_code& ec)
  286. {
  287. return this->service.send_break(this->implementation, ec);
  288. }
  289. /// Set an option on the serial port.
  290. /**
  291. * This function is used to set an option on the serial port.
  292. *
  293. * @param option The option value to be set on the serial port.
  294. *
  295. * @throws asio::system_error Thrown on failure.
  296. *
  297. * @sa SettableSerialPortOption @n
  298. * asio::serial_port_base::baud_rate @n
  299. * asio::serial_port_base::flow_control @n
  300. * asio::serial_port_base::parity @n
  301. * asio::serial_port_base::stop_bits @n
  302. * asio::serial_port_base::character_size
  303. */
  304. template <typename SettableSerialPortOption>
  305. void set_option(const SettableSerialPortOption& option)
  306. {
  307. asio::error_code ec;
  308. this->service.set_option(this->implementation, option, ec);
  309. asio::detail::throw_error(ec);
  310. }
  311. /// Set an option on the serial port.
  312. /**
  313. * This function is used to set an option on the serial port.
  314. *
  315. * @param option The option value to be set on the serial port.
  316. *
  317. * @param ec Set to indicate what error occurred, if any.
  318. *
  319. * @sa SettableSerialPortOption @n
  320. * asio::serial_port_base::baud_rate @n
  321. * asio::serial_port_base::flow_control @n
  322. * asio::serial_port_base::parity @n
  323. * asio::serial_port_base::stop_bits @n
  324. * asio::serial_port_base::character_size
  325. */
  326. template <typename SettableSerialPortOption>
  327. asio::error_code set_option(const SettableSerialPortOption& option,
  328. asio::error_code& ec)
  329. {
  330. return this->service.set_option(this->implementation, option, ec);
  331. }
  332. /// Get an option from the serial port.
  333. /**
  334. * This function is used to get the current value of an option on the serial
  335. * port.
  336. *
  337. * @param option The option value to be obtained from the serial port.
  338. *
  339. * @throws asio::system_error Thrown on failure.
  340. *
  341. * @sa GettableSerialPortOption @n
  342. * asio::serial_port_base::baud_rate @n
  343. * asio::serial_port_base::flow_control @n
  344. * asio::serial_port_base::parity @n
  345. * asio::serial_port_base::stop_bits @n
  346. * asio::serial_port_base::character_size
  347. */
  348. template <typename GettableSerialPortOption>
  349. void get_option(GettableSerialPortOption& option)
  350. {
  351. asio::error_code ec;
  352. this->service.get_option(this->implementation, option, ec);
  353. asio::detail::throw_error(ec);
  354. }
  355. /// Get an option from the serial port.
  356. /**
  357. * This function is used to get the current value of an option on the serial
  358. * port.
  359. *
  360. * @param option The option value to be obtained from the serial port.
  361. *
  362. * @param ec Set to indicate what error occured, if any.
  363. *
  364. * @sa GettableSerialPortOption @n
  365. * asio::serial_port_base::baud_rate @n
  366. * asio::serial_port_base::flow_control @n
  367. * asio::serial_port_base::parity @n
  368. * asio::serial_port_base::stop_bits @n
  369. * asio::serial_port_base::character_size
  370. */
  371. template <typename GettableSerialPortOption>
  372. asio::error_code get_option(GettableSerialPortOption& option,
  373. asio::error_code& ec)
  374. {
  375. return this->service.get_option(this->implementation, option, ec);
  376. }
  377. /// Write some data to the serial port.
  378. /**
  379. * This function is used to write data to the serial port. The function call
  380. * will block until one or more bytes of the data has been written
  381. * successfully, or until an error occurs.
  382. *
  383. * @param buffers One or more data buffers to be written to the serial port.
  384. *
  385. * @returns The number of bytes written.
  386. *
  387. * @throws asio::system_error Thrown on failure. An error code of
  388. * asio::error::eof indicates that the connection was closed by the
  389. * peer.
  390. *
  391. * @note The write_some operation may not transmit all of the data to the
  392. * peer. Consider using the @ref write function if you need to ensure that
  393. * all data is written before the blocking operation completes.
  394. *
  395. * @par Example
  396. * To write a single data buffer use the @ref buffer function as follows:
  397. * @code
  398. * serial_port.write_some(asio::buffer(data, size));
  399. * @endcode
  400. * See the @ref buffer documentation for information on writing multiple
  401. * buffers in one go, and how to use it with arrays, boost::array or
  402. * std::vector.
  403. */
  404. template <typename ConstBufferSequence>
  405. std::size_t write_some(const ConstBufferSequence& buffers)
  406. {
  407. asio::error_code ec;
  408. std::size_t s = this->service.write_some(this->implementation, buffers, ec);
  409. asio::detail::throw_error(ec);
  410. return s;
  411. }
  412. /// Write some data to the serial port.
  413. /**
  414. * This function is used to write data to the serial port. The function call
  415. * will block until one or more bytes of the data has been written
  416. * successfully, or until an error occurs.
  417. *
  418. * @param buffers One or more data buffers to be written to the serial port.
  419. *
  420. * @param ec Set to indicate what error occurred, if any.
  421. *
  422. * @returns The number of bytes written. Returns 0 if an error occurred.
  423. *
  424. * @note The write_some operation may not transmit all of the data to the
  425. * peer. Consider using the @ref write function if you need to ensure that
  426. * all data is written before the blocking operation completes.
  427. */
  428. template <typename ConstBufferSequence>
  429. std::size_t write_some(const ConstBufferSequence& buffers,
  430. asio::error_code& ec)
  431. {
  432. return this->service.write_some(this->implementation, buffers, ec);
  433. }
  434. /// Start an asynchronous write.
  435. /**
  436. * This function is used to asynchronously write data to the serial port.
  437. * The function call always returns immediately.
  438. *
  439. * @param buffers One or more data buffers to be written to the serial port.
  440. * Although the buffers object may be copied as necessary, ownership of the
  441. * underlying memory blocks is retained by the caller, which must guarantee
  442. * that they remain valid until the handler is called.
  443. *
  444. * @param handler The handler to be called when the write operation completes.
  445. * Copies will be made of the handler as required. The function signature of
  446. * the handler must be:
  447. * @code void handler(
  448. * const asio::error_code& error, // Result of operation.
  449. * std::size_t bytes_transferred // Number of bytes written.
  450. * ); @endcode
  451. * Regardless of whether the asynchronous operation completes immediately or
  452. * not, the handler will not be invoked from within this function. Invocation
  453. * of the handler will be performed in a manner equivalent to using
  454. * asio::io_service::post().
  455. *
  456. * @note The write operation may not transmit all of the data to the peer.
  457. * Consider using the @ref async_write function if you need to ensure that all
  458. * data is written before the asynchronous operation completes.
  459. *
  460. * @par Example
  461. * To write a single data buffer use the @ref buffer function as follows:
  462. * @code
  463. * serial_port.async_write_some(asio::buffer(data, size), handler);
  464. * @endcode
  465. * See the @ref buffer documentation for information on writing multiple
  466. * buffers in one go, and how to use it with arrays, boost::array or
  467. * std::vector.
  468. */
  469. template <typename ConstBufferSequence, typename WriteHandler>
  470. void async_write_some(const ConstBufferSequence& buffers,
  471. WriteHandler handler)
  472. {
  473. this->service.async_write_some(this->implementation, buffers, handler);
  474. }
  475. /// Read some data from the serial port.
  476. /**
  477. * This function is used to read data from the serial port. The function
  478. * call will block until one or more bytes of data has been read successfully,
  479. * or until an error occurs.
  480. *
  481. * @param buffers One or more buffers into which the data will be read.
  482. *
  483. * @returns The number of bytes read.
  484. *
  485. * @throws asio::system_error Thrown on failure. An error code of
  486. * asio::error::eof indicates that the connection was closed by the
  487. * peer.
  488. *
  489. * @note The read_some operation may not read all of the requested number of
  490. * bytes. Consider using the @ref read function if you need to ensure that
  491. * the requested amount of data is read before the blocking operation
  492. * completes.
  493. *
  494. * @par Example
  495. * To read into a single data buffer use the @ref buffer function as follows:
  496. * @code
  497. * serial_port.read_some(asio::buffer(data, size));
  498. * @endcode
  499. * See the @ref buffer documentation for information on reading into multiple
  500. * buffers in one go, and how to use it with arrays, boost::array or
  501. * std::vector.
  502. */
  503. template <typename MutableBufferSequence>
  504. std::size_t read_some(const MutableBufferSequence& buffers)
  505. {
  506. asio::error_code ec;
  507. std::size_t s = this->service.read_some(this->implementation, buffers, ec);
  508. asio::detail::throw_error(ec);
  509. return s;
  510. }
  511. /// Read some data from the serial port.
  512. /**
  513. * This function is used to read data from the serial port. The function
  514. * call will block until one or more bytes of data has been read successfully,
  515. * or until an error occurs.
  516. *
  517. * @param buffers One or more buffers into which the data will be read.
  518. *
  519. * @param ec Set to indicate what error occurred, if any.
  520. *
  521. * @returns The number of bytes read. Returns 0 if an error occurred.
  522. *
  523. * @note The read_some operation may not read all of the requested number of
  524. * bytes. Consider using the @ref read function if you need to ensure that
  525. * the requested amount of data is read before the blocking operation
  526. * completes.
  527. */
  528. template <typename MutableBufferSequence>
  529. std::size_t read_some(const MutableBufferSequence& buffers,
  530. asio::error_code& ec)
  531. {
  532. return this->service.read_some(this->implementation, buffers, ec);
  533. }
  534. /// Start an asynchronous read.
  535. /**
  536. * This function is used to asynchronously read data from the serial port.
  537. * The function call always returns immediately.
  538. *
  539. * @param buffers One or more buffers into which the data will be read.
  540. * Although the buffers object may be copied as necessary, ownership of the
  541. * underlying memory blocks is retained by the caller, which must guarantee
  542. * that they remain valid until the handler is called.
  543. *
  544. * @param handler The handler to be called when the read operation completes.
  545. * Copies will be made of the handler as required. The function signature of
  546. * the handler must be:
  547. * @code void handler(
  548. * const asio::error_code& error, // Result of operation.
  549. * std::size_t bytes_transferred // Number of bytes read.
  550. * ); @endcode
  551. * Regardless of whether the asynchronous operation completes immediately or
  552. * not, the handler will not be invoked from within this function. Invocation
  553. * of the handler will be performed in a manner equivalent to using
  554. * asio::io_service::post().
  555. *
  556. * @note The read operation may not read all of the requested number of bytes.
  557. * Consider using the @ref async_read function if you need to ensure that the
  558. * requested amount of data is read before the asynchronous operation
  559. * completes.
  560. *
  561. * @par Example
  562. * To read into a single data buffer use the @ref buffer function as follows:
  563. * @code
  564. * serial_port.async_read_some(asio::buffer(data, size), handler);
  565. * @endcode
  566. * See the @ref buffer documentation for information on reading into multiple
  567. * buffers in one go, and how to use it with arrays, boost::array or
  568. * std::vector.
  569. */
  570. template <typename MutableBufferSequence, typename ReadHandler>
  571. void async_read_some(const MutableBufferSequence& buffers,
  572. ReadHandler handler)
  573. {
  574. this->service.async_read_some(this->implementation, buffers, handler);
  575. }
  576. };
  577. } // namespace asio
  578. #endif // defined(ASIO_HAS_SERIAL_PORT)
  579. // || defined(GENERATING_DOCUMENTATION)
  580. #include "asio/detail/pop_options.hpp"
  581. #endif // ASIO_BASIC_SERIAL_PORT_HPP