From 0f06a0cdeebc41e91d337186c73810f21fe33d67 Mon Sep 17 00:00:00 2001 From: Stéphane Raimbault Date: Wed, 22 Mar 2017 22:10:40 +0100 Subject: [PATCH] New functions to define the indication timeout (#95) --- doc/libmodbus.txt | 2 ++ doc/modbus_get_byte_timeout.txt | 2 +- doc/modbus_get_indication_timeout.txt | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ doc/modbus_set_indication_timeout.txt | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/modbus-private.h | 1 + src/modbus.c | 41 +++++++++++++++++++++++++++++++++++++++-- src/modbus.h | 3 +++ 7 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 doc/modbus_get_indication_timeout.txt create mode 100644 doc/modbus_set_indication_timeout.txt diff --git a/doc/libmodbus.txt b/doc/libmodbus.txt index 5c84448..dce9a6e 100644 --- a/doc/libmodbus.txt +++ b/doc/libmodbus.txt @@ -128,6 +128,8 @@ Timeout settings:: linkmb:modbus_set_byte_timeout[3] linkmb:modbus_get_response_timeout[3] linkmb:modbus_set_response_timeout[3] + linkmb:modbus_get_indication_timeout[3] + linkmb:modbus_set_indication_timeout[3] Error recovery mode:: linkmb:modbus_set_error_recovery[3] diff --git a/doc/modbus_get_byte_timeout.txt b/doc/modbus_get_byte_timeout.txt index b959a0a..d7ba070 100644 --- a/doc/modbus_get_byte_timeout.txt +++ b/doc/modbus_get_byte_timeout.txt @@ -39,9 +39,9 @@ modbus_get_byte_timeout(ctx, &to_sec, &to_usec); SEE ALSO -------- +linkmb:modbus_set_byte_timeout[3] linkmb:modbus_get_response_timeout[3] linkmb:modbus_set_response_timeout[3] -linkmb:modbus_set_byte_timeout[3] AUTHORS diff --git a/doc/modbus_get_indication_timeout.txt b/doc/modbus_get_indication_timeout.txt new file mode 100644 index 0000000..3af39d9 --- /dev/null +++ b/doc/modbus_get_indication_timeout.txt @@ -0,0 +1,53 @@ +modbus_get_indication_timeout(3) +================================ + + +NAME +---- +modbus_get_indication_timeout - get timeout used to wait for an indication (request received by a server). + +SYNOPSIS +-------- +*int modbus_get_indication_timeout(modbus_t *'ctx', uint32_t *'to_sec', uint32_t *'to_usec');* + + +DESCRIPTION +----------- + +The *modbus_get_indication_timeout()* function shall store the timeout interval +used to wait for an indication in the _to_sec_ and _to_usec_ arguments. +Indication is the term used by the Modbus protocol to designate a request +received by the server. + +The default value is zero, it means the server will wait forever. + + +RETURN VALUE +------------ +The function shall return 0 if successful. Otherwise it shall return -1 and set +errno. + + +EXAMPLE +------- +[source,c] +------------------- +uint32_t to_sec; +uint32_t to_usec; + +/* Save original timeout */ +modbus_get_indication_timeout(ctx, &to_sec, &to_usec); +------------------- + + +SEE ALSO +-------- +linkmb:modbus_set_indication_timeout[3] +linkmb:modbus_get_response_timeout[3] +linkmb:modbus_set_response_timeout[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/doc/modbus_set_indication_timeout.txt b/doc/modbus_set_indication_timeout.txt new file mode 100644 index 0000000..6524bdc --- /dev/null +++ b/doc/modbus_set_indication_timeout.txt @@ -0,0 +1,48 @@ +modbus_set_indication_timeout(3) +================================ + + +NAME +---- +modbus_set_indication_timeout - set timeout between indications + + +SYNOPSIS +-------- +*void modbus_set_indication_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');* + + +DESCRIPTION +----------- +The *modbus_set_indication_timeout()* function shall set the timeout interval used by +a server to wait for a request from a client. + +The value of _to_usec_ argument must be in the range 0 to 999999. + +If both _to_sec_ and _to_usec_ are zero, this timeout will not be used at all. +In this case, the server will wait forever. + + +RETURN VALUE +------------ +The function shall return 0 if successful. Otherwise it shall return -1 and set +errno. + + +ERRORS +------ +*EINVAL*:: +The argument _ctx_ is NULL or _to_usec_ is larger than 1000000. + + +SEE ALSO +-------- +linkmb:modbus_get_indication_timeout[3] +linkmb:modbus_get_response_timeout[3] +linkmb:modbus_set_response_timeout[3] + + +AUTHORS +------- +The libmodbus documentation was written by Stéphane Raimbault + diff --git a/src/modbus-private.h b/src/modbus-private.h index c5af0f9..2c601c4 100644 --- a/src/modbus-private.h +++ b/src/modbus-private.h @@ -98,6 +98,7 @@ struct _modbus { int error_recovery; struct timeval response_timeout; struct timeval byte_timeout; + struct timeval indication_timeout; const modbus_backend_t *backend; void *backend_data; }; diff --git a/src/modbus.c b/src/modbus.c index f117fd2..681cda3 100644 --- a/src/modbus.c +++ b/src/modbus.c @@ -349,7 +349,7 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type) if (ctx->debug) { if (msg_type == MSG_INDICATION) { - printf("Waiting for a indication...\n"); + printf("Waiting for an indication...\n"); } else { printf("Waiting for a confirmation...\n"); } @@ -368,7 +368,15 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type) if (msg_type == MSG_INDICATION) { /* Wait for a message, we don't know when the message will be * received */ - p_tv = NULL; + if (ctx->indication_timeout.tv_sec == 0 && ctx->indication_timeout.tv_usec == 0) { + /* By default, the indication timeout isn't set */ + p_tv = NULL; + } else { + /* Wait for an indication (name of a received request by a server, see schema) */ + tv.tv_sec = ctx->indication_timeout.tv_sec; + tv.tv_usec = ctx->indication_timeout.tv_usec; + p_tv = &tv; + } } else { tv.tv_sec = ctx->response_timeout.tv_sec; tv.tv_usec = ctx->response_timeout.tv_usec; @@ -1564,6 +1572,9 @@ void _modbus_init_common(modbus_t *ctx) ctx->byte_timeout.tv_sec = 0; ctx->byte_timeout.tv_usec = _BYTE_TIMEOUT; + + ctx->indication_timeout.tv_sec = 0; + ctx->indication_timeout.tv_usec = 0; } /* Define the slave number */ @@ -1673,6 +1684,32 @@ int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec) return 0; } +/* Get the timeout interval used by the server to wait for an indication from a client */ +int modbus_get_indication_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec) +{ + if (ctx == NULL) { + errno = EINVAL; + return -1; + } + + *to_sec = ctx->indication_timeout.tv_sec; + *to_usec = ctx->indication_timeout.tv_usec; + return 0; +} + +int modbus_set_indication_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec) +{ + /* Indication timeout can be disabled when both values are zero */ + if (ctx == NULL || to_usec > 999999) { + errno = EINVAL; + return -1; + } + + ctx->indication_timeout.tv_sec = to_sec; + ctx->indication_timeout.tv_usec = to_usec; + return 0; +} + int modbus_get_header_length(modbus_t *ctx) { if (ctx == NULL) { diff --git a/src/modbus.h b/src/modbus.h index f9f7449..fda3f02 100644 --- a/src/modbus.h +++ b/src/modbus.h @@ -188,6 +188,9 @@ MODBUS_API int modbus_set_response_timeout(modbus_t *ctx, uint32_t to_sec, uint3 MODBUS_API int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec); MODBUS_API int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec); +MODBUS_API int modbus_get_indication_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec); +MODBUS_API int modbus_set_indication_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec); + MODBUS_API int modbus_get_header_length(modbus_t *ctx); MODBUS_API int modbus_connect(modbus_t *ctx); -- libgit2 0.21.4