-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlars_timeoutserial.h
234 lines (208 loc) · 8.94 KB
/
lars_timeoutserial.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
* File: TimeoutSerial.h
* Author: Terraneo Federico
* Distributed under the Boost Software License, Version 1.0.
*
* Created on September 12, 2009, 3:47 PM
*/
#ifndef TIMEOUTSERIAL_H
#define TIMEOUTSERIAL_H
#include <stdexcept>
#include <boost/utility.hpp>
#include <boost/asio.hpp>
/**
* Thrown if timeout occurs
*/
class timeout_exception : public std::runtime_error
{
public:
timeout_exception ( const std::string& arg ) : runtime_error ( arg ) { }
};
/**
* Serial port class, with timeout on read operations.
*/
class TimeoutSerial : private boost::noncopyable
{
public:
TimeoutSerial ( );
/**
* Opens a serial device. By default timeout is disabled.
* \param devname serial device name, example "/dev/ttyS0" or "COM1"
* \param baud_rate serial baud rate
* \param opt_parity serial parity, default none
* \param opt_csize serial character size, default 8bit
* \param opt_flow serial flow control, default none
* \param opt_stop serial stop bits, default 1
* \throws boost::system::system_error if cannot open the
* serial device
*/
TimeoutSerial ( const std::string& devname, unsigned int baud_rate,
boost::asio::serial_port_base::parity opt_parity =
boost::asio::serial_port_base::parity (
boost::asio::serial_port_base::parity::none ),
boost::asio::serial_port_base::character_size opt_csize =
boost::asio::serial_port_base::character_size ( 8 ),
boost::asio::serial_port_base::flow_control opt_flow =
boost::asio::serial_port_base::flow_control (
boost::asio::serial_port_base::flow_control::none ),
boost::asio::serial_port_base::stop_bits opt_stop =
boost::asio::serial_port_base::stop_bits (
boost::asio::serial_port_base::stop_bits::one ) );
/**
* Opens a serial device.
* \param devname serial device name, example "/dev/ttyS0" or "COM1"
* \param baud_rate serial baud rate
* \param opt_parity serial parity, default none
* \param opt_csize serial character size, default 8bit
* \param opt_flow serial flow control, default none
* \param opt_stop serial stop bits, default 1
* \throws boost::system::system_error if cannot open the
* serial device
*/
void open ( const std::string& devname, unsigned int baud_rate,
boost::asio::serial_port_base::parity opt_parity =
boost::asio::serial_port_base::parity (
boost::asio::serial_port_base::parity::none ),
boost::asio::serial_port_base::character_size opt_csize =
boost::asio::serial_port_base::character_size ( 8 ),
boost::asio::serial_port_base::flow_control opt_flow =
boost::asio::serial_port_base::flow_control (
boost::asio::serial_port_base::flow_control::none ),
boost::asio::serial_port_base::stop_bits opt_stop =
boost::asio::serial_port_base::stop_bits (
boost::asio::serial_port_base::stop_bits::one ) );
/**
* \return true if serial device is open
*/
bool isOpen ( ) const;
/**
* Close the serial device
* \throws boost::system::system_error if any error
*/
void close ( );
/**
* Set the timeout on read/write operations.
* To disable the timeout, call setTimeout(boost::posix_time::seconds(0));
*/
void setTimeout ( const boost::posix_time::time_duration& t );
/**
* Write data
* \param data array of char to be sent through the serial device
* \param size array size
* \throws boost::system::system_error if any error
*/
void write ( const char *data, size_t size );
/**
* Write data
* \param data to be sent through the serial device
* \throws boost::system::system_error if any error
*/
void write ( const std::vector<char>& data );
/**
* Write a string. Can be used to send ASCII data to the serial device.
* To send binary data, use write()
* \param s string to send
* \throws boost::system::system_error if any error
*/
void writeString ( const std::string& s );
/**
* Read some data, blocking
* \param data array of char to be read through the serial device
* \param size array size
* \return numbr of character actually read 0<=return<=size
* \throws boost::system::system_error if any error
* \throws timeout_exception in case of timeout
*/
void read ( char *data, size_t size );
/**
* \clears the buffer
*/
void clearBuffer ( );
/**
* Read some data, blocking
* \param size how much data to read
* \return the receive buffer. It iempty if no data is available
* \throws boost::system::system_error if any error
* \throws timeout_exception in case of timeout
*/
std::vector<char> read ( size_t size );
/**
* Read a string, blocking
* Can only be used if the user is sure that the serial device will not
* send binary data. For binary data read, use read()
* The returned string is empty if no data has arrived
* \param size hw much data to read
* \return a string with the received data.
* \throws boost::system::system_error if any error
* \throws timeout_exception in case of timeout
*/
std::string readString ( size_t size );
/**
* Read a line, blocking
* Can only be used if the user is sure that the serial device will not
* send binary data. For binary data read, use read()
* The returned string is empty if the line delimiter has not yet arrived.
* \param delimiter line delimiter, default="\n"
* \return a string with the received data. The delimiter is removed from
* the string.
* \throws boost::system::system_error if any error
* \throws timeout_exception in case of timeout
*/
std::string readStringUntil ( const std::string& delim = "\n" );
~TimeoutSerial ( );
private:
/**
* Parameters of performReadSetup.
* Just wrapper class, no encapsulation provided
*/
class ReadSetupParameters
{
public:
ReadSetupParameters ( ) : fixedSize ( false ), delim ( "" ), data ( 0 ), size ( 0 ) { }
explicit ReadSetupParameters ( const std::string& delim ) :
fixedSize ( false ), delim ( delim ), data ( 0 ), size ( 0 ) { }
ReadSetupParameters ( char *data, size_t size ) : fixedSize ( true ),
delim ( "" ), data ( data ), size ( size ) { }
//Using default copy constructor, operator=
bool fixedSize; ///< True if need to read a fixed number of parameters
std::string delim; ///< String end delimiter (valid if fixedSize=false)
char *data; ///< Pointer to data array (valid if fixedSize=true)
size_t size; ///< Array size (valid if fixedSize=true)
};
/**
* This member function sets up a read operation, both reading a specified
* number of characters and reading until a delimiter string.
*/
void performReadSetup ( const ReadSetupParameters& param );
/**
* Callack called either when the read timeout is expired or canceled.
* If called because timeout expired, sets result to resultTimeoutExpired
*/
void timeoutExpired ( const boost::system::error_code& error );
/**
* Callback called either if a read complete or read error occurs
* If called because of read complete, sets result to resultSuccess
* If called because read error, sets result to resultError
*/
void readCompleted ( const boost::system::error_code& error,
const size_t bytesTransferred );
/**
* Possible outcome of a read. Set by callbacks, read from main code
*/
enum ReadResult
{
resultInProgress,
resultSuccess,
resultError,
resultTimeoutExpired
};
boost::asio::io_service io; ///< Io service object
boost::asio::serial_port port; ///< Serial port object
boost::asio::deadline_timer timer; ///< Timer for timeout
boost::posix_time::time_duration timeout; ///< Read/write timeout
boost::asio::streambuf readData; ///< Holds eventual read but not consumed
enum ReadResult result; ///< Used by read with timeout
size_t bytesTransferred; ///< Used by async read callback
ReadSetupParameters setupParameters; ///< Global because used in the OSX fix
};
#endif //TIMEOUTSERIAL_H