From d8f254779570daf8bba60819fe677af4cba8c87a Mon Sep 17 00:00:00 2001 From: Stéphane Raimbault Date: Wed, 7 Jul 2010 14:50:17 +0200 Subject: [PATCH] Fix #463299 - New functions to get/set timeouts of begin and end of trame --- NEWS | 6 ++++-- src/modbus.c | 45 +++++++++++++++++++++++++++++++++++++++++---- src/modbus.h.in | 8 ++++++++ tests/unit-test-master.c | 25 +++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index dc8a2fb..53aaa11 100644 --- a/NEWS +++ b/NEWS @@ -4,10 +4,12 @@ libmodbus 2.1.1 (2010-XX-XX) - Remove the internal function set_message_length_tcp - Restore slave ID (server ID) argument in functions - Error conventions of POSIX systems and error recover -- Versioning infrastructure. +- Versioning infrastructure Inspired by the Clutter project and the work done by Florian Forster. - Fix the broadcast constant (255 -> 0) - Reported by David Olivari + Reported by David Olivari. +- Fix #463299 - New functions to define the timeouts of begin and end of trame + Original patch by Sisyph (eric-paul). libmodbus 2.1.0 (2010-03-24) ============================ diff --git a/src/modbus.c b/src/modbus.c index b2a9ebc..815ef0b 100644 --- a/src/modbus.c +++ b/src/modbus.c @@ -615,8 +615,8 @@ static int receive_msg(modbus_param_t *mb_param, state = FUNCTION; msg_length_computed = TAB_HEADER_LENGTH[mb_param->type_com] + 1; } else { - tv.tv_sec = 0; - tv.tv_usec = TIME_OUT_BEGIN_OF_TRAME; + tv.tv_sec = mb_param->timeout_begin.tv_sec; + tv.tv_usec = mb_param->timeout_begin.tv_usec; state = COMPLETE; } @@ -697,8 +697,8 @@ static int receive_msg(modbus_param_t *mb_param, if (length_to_read > 0) { /* If no character at the buffer wait TIME_OUT_END_OF_TRAME before to generate an error. */ - tv.tv_sec = 0; - tv.tv_usec = TIME_OUT_END_OF_TRAME; + tv.tv_sec = mb_param->timeout_end.tv_sec; + tv.tv_usec = mb_param->timeout_end.tv_usec; WAIT_DATA(); } else { @@ -1466,6 +1466,15 @@ int report_slave_id(modbus_param_t *mb_param, int slave, uint8_t *data_dest) return rc; } +void init_common(modbus_param_t *mb_param) +{ + mb_param->timeout_begin.tv_sec = 0; + mb_param->timeout_begin.tv_usec = TIME_OUT_BEGIN_OF_TRAME; + + mb_param->timeout_end.tv_sec = 0; + mb_param->timeout_end.tv_usec = TIME_OUT_END_OF_TRAME; +} + /* Initializes the modbus_param_t structure for RTU - device: "/dev/ttyS0" - baud: 9600, 19200, 57600, 115200, etc @@ -1488,6 +1497,8 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device, mb_param->type_com = RTU; mb_param->error_recovery = FALSE; mb_param->slave = slave; + + init_common(mb_param); } /* Initializes the modbus_param_t structure for TCP. @@ -1507,6 +1518,8 @@ void modbus_init_tcp(modbus_param_t *mb_param, const char *ip, int port, int sla mb_param->type_com = TCP; mb_param->error_recovery = FALSE; mb_param->slave = slave; + + init_common(mb_param); } /* Define the slave number */ @@ -1540,6 +1553,30 @@ int modbus_set_error_recovery(modbus_param_t *mb_param, int enabled) return 0; } +/* Get the timeout of begin of trame */ +void modbus_get_timeout_begin(modbus_param_t *mb_param, struct timeval *timeout) +{ + *timeout = mb_param->timeout_begin; +} + +/* Set timeout when waiting the beginning of a trame */ +void modbus_set_timeout_begin(modbus_param_t *mb_param, const struct timeval *timeout) +{ + mb_param->timeout_begin = *timeout; +} + +/* Get the timeout of end of trame */ +void modbus_get_timeout_end(modbus_param_t *mb_param, struct timeval *timeout) +{ + *timeout = mb_param->timeout_end; +} + +/* Set timeout when waiting the end of a trame */ +void modbus_set_timeout_end(modbus_param_t *mb_param, const struct timeval *timeout) +{ + mb_param->timeout_end = *timeout; +} + /* Sets up a serial port for RTU communications */ static int modbus_connect_rtu(modbus_param_t *mb_param) { diff --git a/src/modbus.h.in b/src/modbus.h.in index df9085c..713fa70 100644 --- a/src/modbus.h.in +++ b/src/modbus.h.in @@ -234,6 +234,8 @@ typedef struct { char ip[16]; /* Save old termios settings */ struct termios old_tios; + struct timeval timeout_begin; + struct timeval timeout_end; } modbus_param_t; typedef struct { @@ -255,6 +257,12 @@ void modbus_init_tcp(modbus_param_t *mb_param, const char *ip_address, int port, void modbus_set_slave(modbus_param_t *mb_param, int slave); int modbus_set_error_recovery(modbus_param_t *mb_param, int enabled); +void modbus_get_timeout_begin(modbus_param_t *mb_param, struct timeval *timeout); +void modbus_set_timeout_begin(modbus_param_t *mb_param, const struct timeval *timeout); + +void modbus_get_timeout_end(modbus_param_t *mb_param, struct timeval *timeout); +void modbus_set_timeout_end(modbus_param_t *mb_param, const struct timeval *timeout); + int modbus_connect(modbus_param_t *mb_param); void modbus_close(modbus_param_t *mb_param); diff --git a/tests/unit-test-master.c b/tests/unit-test-master.c index 933b001..cafb96a 100644 --- a/tests/unit-test-master.c +++ b/tests/unit-test-master.c @@ -36,6 +36,8 @@ int main(void) int nb_points; int rc; float real; + struct timeval timeout_begin_old; + struct timeval timeout_begin_new; /* RTU parity : none, even, odd */ /* @@ -468,10 +470,33 @@ int main(void) if (rc == UT_HOLDING_REGISTERS_NB_POINTS) { printf("OK\n"); } else { + printf("FAILED\n"); goto close; + } + + /* Save original timeout */ + modbus_get_timeout_begin(&mb_param, &timeout_begin_old); + + /* Define a new and too short timeout */ + timeout_begin_new.tv_sec = 0; + timeout_begin_new.tv_usec = 0; + modbus_set_timeout_begin(&mb_param, &timeout_begin_new); + + rc = read_holding_registers(&mb_param, SERVER_ID, + UT_HOLDING_REGISTERS_ADDRESS, + UT_HOLDING_REGISTERS_NB_POINTS, + tab_rp_registers); + printf("3/3 Too short timeout: "); + if (rc == -1 && errno == ETIMEDOUT) { + printf("OK\n"); + } else { printf("FAILED\n"); + goto close; } + /* Restore original timeout */ + modbus_set_timeout_begin(&mb_param, &timeout_begin_old); + /** BAD RESPONSE **/ printf("\nTEST BAD RESPONSE ERROR:\n"); -- libgit2 0.21.4