Skip to content

Commit 8db93a5

Browse files
rtu layer: fix parsing of settings string
Throw exceptions on error instead of silently changing values. Check settings string for given stop bit value. Up until now, the stop bits value was hard coded to be 2 if the parity mode was set to none or 1 if the parity mode was set to even or odd. So a setting of "115200E1" would result in a stop bit value of 1. But "115200E2" would result also in a stop bit value of 1. And "115200N1" would result in a stop bit value of 2. This is not a restriction of libmodbus. The library supports all these modes just fine. In fact they are using 115200N1 in the documentation for modbus_new_rtu(). Rather this is a bug in the string parsing that libmodbuspp introduces in its constructor. libmodbus has no string parsing in modbus_new_rtu() and takes in the arguments as parameters directly. Fixes: b0f3dc4
1 parent c76baa9 commit 8db93a5

File tree

2 files changed

+25
-18
lines changed

2 files changed

+25
-18
lines changed

include/modbuspp/rtulayer.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -169,23 +169,22 @@ namespace Modbus {
169169

170170
/**
171171
* @brief Extracts the baudrate from a settings string.
172-
* @return the baudrate found. if no value is found, returns the default
173-
* value, ie 19200.
172+
* @return the baudrate found. If no valid value is found, an exception is thrown.
174173
*/
175174
static int baud (const std::string & settings);
176175

177176
/**
178177
* @brief Extracts the parity from a settings string.
179-
* @return the parity found. if no value is found, returns the default
180-
* value, ie E for Even parity.
178+
* @return the parity found. If no valid value is found, an exception is thrown.
181179
*/
182180
static char parity (const std::string & settings);
183181

184182
/**
185183
* @brief Return the stop bits from a settings string.
186184
*
187-
* @return the number returned is determined based on the parity found.
188-
* If the parity is None, this function returns 2, otherwise returns 1.
185+
* @return the number of stop bits.
186+
* It is parsed from the last character of the settings string.
187+
* If the last character is neither '1' or '2' an exception is thrown.
189188
*/
190189
static int stop (const std::string & settings);
191190

src/rtulayer.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -234,40 +234,48 @@ namespace Modbus {
234234
// ---------------------------------------------------------------------------
235235
// static
236236
int RtuLayer::baud (const std::string & settings) {
237-
int b;
238237
try {
239-
b = std::stoi (settings);
238+
return std::stoi (settings);
240239
}
241240
catch (...) {
242-
b = 19200;
241+
throw std::invalid_argument ("RtuLayer settings\"" + settings + "\" has an invalid baud rate setting.");
243242
}
244-
return b;
245243
}
246244

247245
// ---------------------------------------------------------------------------
248246
// static
249247
char RtuLayer::parity (const std::string & settings) {
250-
char p = 'N';
251248
size_t s = settings.length();
252249

253250
if (s >= 2) {
254251
char c = settings[s - 2];
255-
if ( (c == 'E') || (c == 'O')) {
256-
return c;
252+
switch (c) {
253+
case 'N':
254+
case 'E':
255+
case 'O':
256+
return c;
257257
}
258258
}
259-
return p;
259+
260+
throw std::invalid_argument ("RtuLayer settings\"" + settings + "\" has an invalid parity setting.");
260261
}
261262

262263
// ---------------------------------------------------------------------------
263264
// static
264265
int RtuLayer::stop (const std::string & settings) {
266+
size_t s = settings.length();
265267

266-
if (parity (settings) == 'N') {
267-
268-
return 2;
268+
if (s >= 3) {
269+
char c = settings[s - 1];
270+
switch (c) {
271+
case '1':
272+
return 1;
273+
case '2':
274+
return 2;
275+
}
269276
}
270-
return 1;
277+
278+
throw std::invalid_argument ("RtuLayer settings\"" + settings + "\" has an invalid stop bit setting.");
271279
}
272280

273281
// ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)