diff --git a/package/libmodbus/001-GfA-echo-rtu.patch b/package/libmodbus/001-GfA-echo-rtu.patch new file mode 100644 index 0000000000..386172f970 --- /dev/null +++ b/package/libmodbus/001-GfA-echo-rtu.patch @@ -0,0 +1,105 @@ +diff -Naur a/src/modbus-rtu.c b/src/modbus-rtu.c +--- a/src/modbus-rtu.c 2017-10-11 23:07:11.623017506 +0200 ++++ b/src/modbus-rtu.c 2017-10-11 23:07:20.495035402 +0200 +@@ -257,6 +257,27 @@ + } + #endif + ++ ++ssize_t _modbus_rtu_write_n_read(modbus_t *ctx, const uint8_t *req, int req_length) { ++ ssize_t w, r, i; ++ uint8_t rb[req_length]; ++ ++ // Transmit ++ w = write(ctx->s, req, req_length); ++ ++ // Read back written bytes if hw has echo ++ r = 0; ++ while (r < w) ++ r += read(ctx->s, rb + r, w - r); ++ if (ctx->debug) { ++ for (i = 0; i < r; ++i) ++ fprintf(stderr, "|%02X|", rb[i]); ++ fprintf(stderr, "\n"); ++ } ++ ++ return w; ++} ++ + ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length) + { + #if defined(_WIN32) +@@ -264,7 +285,14 @@ + DWORD n_bytes = 0; + return (WriteFile(ctx_rtu->w_ser.fd, req, req_length, &n_bytes, NULL)) ? n_bytes : -1; + #else +- return write(ctx->s, req, req_length); ++ modbus_rtu_t *ctx_rtu = ctx->backend_data; ++ ssize_t w; ++ ++ if(!ctx_rtu->echohw) ++ w = write(ctx->s, req, req_length); ++ else ++ w = _modbus_rtu_write_n_read(ctx, req, req_length); ++ return w; + #endif + } + +@@ -772,6 +800,30 @@ + } + } + ++ ++int modbus_rtu_set_echohw_mode(modbus_t* ctx, uint8_t mode) { ++ if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { ++ modbus_rtu_t* rtu = (modbus_rtu_t*) ctx->backend_data; ++ rtu->echohw= mode; ++ return 0; ++ } ++ /* Wrong backend and invalid mode specified */ ++ errno = EINVAL; ++ return -1; ++ ++} ++ ++int modbus_rtu_get_echohw_mode(modbus_t* ctx) { ++ if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { ++ modbus_rtu_t* rtu = (modbus_rtu_t*) ctx->backend_data; ++ return rtu->echohw; ++ } ++ /* Wrong backend and invalid mode specified */ ++ errno = EINVAL; ++ return -1; ++ ++} ++ + void _modbus_rtu_close(modbus_t *ctx) + { + /* Closes the file descriptor in RTU mode */ +diff -Naur a/src/modbus-rtu.h b/src/modbus-rtu.h +--- a/src/modbus-rtu.h 2017-10-11 23:07:11.623017506 +0200 ++++ b/src/modbus-rtu.h 2017-10-11 23:07:20.495035402 +0200 +@@ -37,6 +37,12 @@ + int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode); + int modbus_rtu_get_serial_mode(modbus_t *ctx); + ++#define MODBUS_RTU_HAS_ECHOHW 1 ++#define MODBUS_RTU_NO_ECHOHW 0 ++ ++int modbus_rtu_set_echohw_mode(modbus_t *ctx, uint8_t mode); ++int modbus_rtu_get_echohw_mode(modbus_t *ctx); ++ + MODBUS_END_DECLS + + #endif /* _MODBUS_RTU_H_ */ +diff -Naur a/src/modbus-rtu-private.h b/src/modbus-rtu-private.h +--- a/src/modbus-rtu-private.h 2017-10-11 23:07:11.623017506 +0200 ++++ b/src/modbus-rtu-private.h 2017-10-11 23:07:20.495035402 +0200 +@@ -81,6 +81,7 @@ + #if HAVE_DECL_TIOCSRS485 + int serial_mode; + #endif ++ uint8_t echohw; + } modbus_rtu_t; + + #endif /* _MODBUS_RTU_PRIVATE_H_ */