From ef7ae05367932ed923058decac0de71a3e1b4456 Mon Sep 17 00:00:00 2001 From: Stéphane Raimbault Date: Wed, 7 Dec 2022 16:07:30 +0100 Subject: [PATCH] Fix setting baud rate for Linux (partial revert of fa20798) --- src/modbus-rtu.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 129 insertions(+), 4 deletions(-) diff --git a/src/modbus-rtu.c b/src/modbus-rtu.c index 236a63c..b774923 100644 --- a/src/modbus-rtu.c +++ b/src/modbus-rtu.c @@ -12,9 +12,8 @@ #ifndef _MSC_VER #include #endif -#include - #include "modbus-private.h" +#include #include "modbus-rtu-private.h" #include "modbus-rtu.h" @@ -505,11 +504,125 @@ static int _modbus_rtu_connect(modbus_t *ctx) return 0; } #else + +static speed_t _get_termios_speed(int baud, int debug) +{ + speed_t speed; + + switch (baud) { + case 110: + speed = B110; + break; + case 300: + speed = B300; + break; + case 600: + speed = B600; + break; + case 1200: + speed = B1200; + break; + case 2400: + speed = B2400; + break; + case 4800: + speed = B4800; + break; + case 9600: + speed = B9600; + break; + case 19200: + speed = B19200; + break; + case 38400: + speed = B38400; + break; +#ifdef B57600 + case 57600: + speed = B57600; + break; +#endif +#ifdef B115200 + case 115200: + speed = B115200; + break; +#endif +#ifdef B230400 + case 230400: + speed = B230400; + break; +#endif +#ifdef B460800 + case 460800: + speed = B460800; + break; +#endif +#ifdef B500000 + case 500000: + speed = B500000; + break; +#endif +#ifdef B576000 + case 576000: + speed = B576000; + break; +#endif +#ifdef B921600 + case 921600: + speed = B921600; + break; +#endif +#ifdef B1000000 + case 1000000: + speed = B1000000; + break; +#endif +#ifdef B1152000 + case 1152000: + speed = B1152000; + break; +#endif +#ifdef B1500000 + case 1500000: + speed = B1500000; + break; +#endif +#ifdef B2500000 + case 2500000: + speed = B2500000; + break; +#endif +#ifdef B3000000 + case 3000000: + speed = B3000000; + break; +#endif +#ifdef B3500000 + case 3500000: + speed = B3500000; + break; +#endif +#ifdef B4000000 + case 4000000: + speed = B4000000; + break; +#endif + default: + speed = B9600; + if (debug) { + fprintf(stderr, "WARNING Unknown baud rate %d (B9600 used)\n", baud); + } + } + + return speed; +} + /* POSIX */ static int _modbus_rtu_connect(modbus_t *ctx) { struct termios tios; int flags; + speed_t speed; modbus_rtu_t *ctx_rtu = ctx->backend_data; if (ctx->debug) { @@ -554,8 +667,20 @@ static int _modbus_rtu_connect(modbus_t *ctx) */ /* Set the baud rate */ - if ((cfsetispeed(&tios, ctx_rtu->baud) < 0) || - (cfsetospeed(&tios, ctx_rtu->baud) < 0)) { + + /* + On MacOS, constants of baud rates are equal to the integer in argument but + that's not the case under Linux so we have to find the corresponding + constant. Until the code is upgraded to termios2, the list of possible + values is limited (no 14400 for example). + */ + if (9600 == B9600) { + speed = ctx_rtu->baud; + } else { + speed = _get_termios_speed(ctx_rtu->baud, ctx->debug); + } + + if ((cfsetispeed(&tios, speed) < 0) || (cfsetospeed(&tios, speed) < 0)) { close(ctx->s); ctx->s = -1; return -1; -- libgit2 0.21.4