basic_serial_port.hpp 22 KB

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