1 #pragma once 2 #ifndef ASYNCSERIAL_H 3 #define ASYNCSERIAL_H 4 5 #include <stddef.h> // for size_t 6 #include "../main/Noncopyable.h" 7 #include <boost/asio/serial_port_base.hpp> // for serial_port_base 8 #include <boost/smart_ptr/shared_ptr.hpp> // for shared_ptr 9 #include <boost/function/function_fwd.hpp> // for function 10 #include <boost/exception/diagnostic_information.hpp> //for exception printing 11 namespace boost { namespace system { class error_code; } } 12 13 /** 14 * Used internally (pimpl) 15 */ 16 class AsyncSerialImpl; 17 18 /** 19 * Asynchronous serial class. 20 * Intended to be a base class. 21 */ 22 class AsyncSerial 23 : private domoticz::noncopyable 24 { 25 public: 26 AsyncSerial(); 27 28 /** 29 * Constructor. Creates and opens a serial device. 30 * \param devname serial device name, example "/dev/ttyS0" or "COM1" 31 * \param baud_rate serial baud rate 32 * \param opt_parity serial parity, default none 33 * \param opt_csize serial character size, default 8bit 34 * \param opt_flow serial flow control, default none 35 * \param opt_stop serial stop bits, default 1 36 * \throws boost::system::system_error if cannot open the 37 * serial device 38 */ 39 AsyncSerial(const std::string& devname, unsigned int baud_rate, 40 boost::asio::serial_port_base::parity opt_parity= 41 boost::asio::serial_port_base::parity( 42 boost::asio::serial_port_base::parity::none), 43 boost::asio::serial_port_base::character_size opt_csize= 44 boost::asio::serial_port_base::character_size(8), 45 boost::asio::serial_port_base::flow_control opt_flow= 46 boost::asio::serial_port_base::flow_control( 47 boost::asio::serial_port_base::flow_control::none), 48 boost::asio::serial_port_base::stop_bits opt_stop= 49 boost::asio::serial_port_base::stop_bits( 50 boost::asio::serial_port_base::stop_bits::one)); 51 52 /** 53 * Opens a serial device. 54 * \param devname serial device name, example "/dev/ttyS0" or "COM1" 55 * \param baud_rate serial baud rate 56 * \param opt_parity serial parity, default none 57 * \param opt_csize serial character size, default 8bit 58 * \param opt_flow serial flow control, default none 59 * \param opt_stop serial stop bits, default 1 60 * \throws boost::system::system_error if cannot open the 61 * serial device 62 */ 63 void open(const std::string& devname, unsigned int baud_rate, 64 boost::asio::serial_port_base::parity opt_parity= 65 boost::asio::serial_port_base::parity( 66 boost::asio::serial_port_base::parity::none), 67 boost::asio::serial_port_base::character_size opt_csize= 68 boost::asio::serial_port_base::character_size(8), 69 boost::asio::serial_port_base::flow_control opt_flow= 70 boost::asio::serial_port_base::flow_control( 71 boost::asio::serial_port_base::flow_control::none), 72 boost::asio::serial_port_base::stop_bits opt_stop= 73 boost::asio::serial_port_base::stop_bits( 74 boost::asio::serial_port_base::stop_bits::one)); 75 void openOnlyBaud(const std::string& devname, unsigned int baud_rate, 76 boost::asio::serial_port_base::parity opt_parity= 77 boost::asio::serial_port_base::parity( 78 boost::asio::serial_port_base::parity::none), 79 boost::asio::serial_port_base::character_size opt_csize= 80 boost::asio::serial_port_base::character_size(8), 81 boost::asio::serial_port_base::flow_control opt_flow= 82 boost::asio::serial_port_base::flow_control( 83 boost::asio::serial_port_base::flow_control::none), 84 boost::asio::serial_port_base::stop_bits opt_stop= 85 boost::asio::serial_port_base::stop_bits( 86 boost::asio::serial_port_base::stop_bits::one)); 87 88 /** 89 * \return true if serial device is open 90 */ 91 bool isOpen() const; 92 93 /** 94 * \return true if error were found 95 */ 96 bool errorStatus() const; 97 98 /** 99 * Close the serial device 100 * \throws boost::system::system_error if any error 101 */ 102 void close(); 103 104 /** 105 * Write data asynchronously. Returns immediately. 106 * \param data array of char to be sent through the serial device 107 * \param size array size 108 */ 109 void write(const char *data, size_t size); 110 111 /** 112 * Write data asynchronously. Returns immediately. 113 * \param data to be sent through the serial device 114 */ 115 void write(const std::vector<char>& data); 116 117 /** 118 * Write data asynchronously. Returns immediately. 119 * \param string to be sent through the serial device 120 */ 121 void write(const std::string &data); 122 123 /** 124 * Write a string asynchronously. Returns immediately. 125 * Can be used to send ASCII data to the serial device. 126 * To send binary data, use write() 127 * \param s string to send 128 */ 129 void writeString(const std::string& s); 130 131 /** 132 * Destructor. If necessary it silently removes the read callback and close the serial port. 133 */ 134 ~AsyncSerial(); 135 136 private: 137 /** 138 * Callback to close serial port 139 */ 140 void doClose(); 141 142 /** 143 * Callback called to start an asynchronous read operation. 144 * This callback is called by the io_service in the spawned thread. 145 */ 146 void doRead(); 147 148 /** 149 * Callback called at the end of the asynchronous operation. 150 * This callback is called by the io_service in the spawned thread. 151 */ 152 void readEnd(const boost::system::error_code& error, 153 size_t bytes_transferred); 154 155 /** 156 * Callback called to start an asynchronous write operation. 157 * If it is already in progress, does nothing. 158 * This callback is called by the io_service in the spawned thread. 159 */ 160 void doWrite(); 161 162 /** 163 * Callback called at the end of an asynchronuous write operation, 164 * if there is more data to write, restarts a new write operation. 165 * This callback is called by the io_service in the spawned thread. 166 */ 167 void writeEnd(const boost::system::error_code& error); 168 169 std::shared_ptr<AsyncSerialImpl> pimpl; 170 171 /** 172 * To allow derived classes to report errors 173 * \param e error status 174 */ 175 void setErrorStatus(bool e); 176 177 protected: 178 179 /** 180 * To allow derived classes to set a read callback 181 */ 182 void setReadCallback(const 183 boost::function<void (const char*, size_t)>& callback); 184 185 /** 186 * Unregister the read callback. 187 */ 188 void clearReadCallback(); 189 190 /** 191 * Process a clean close by unregistering the read callback and closing the port. 192 * Once this method has been called, you have to open the port and register the read callback again. 193 */ 194 void terminate(bool silent = true); 195 196 }; 197 198 199 #endif //ASYNCSERIAL_H 200