Commit 0f06a0cdeebc41e91d337186c73810f21fe33d67
1 parent
7a6078b6
New functions to define the indication timeout (#95)
Showing
7 changed files
with
147 additions
and
3 deletions
doc/libmodbus.txt
| @@ -128,6 +128,8 @@ Timeout settings:: | @@ -128,6 +128,8 @@ Timeout settings:: | ||
| 128 | linkmb:modbus_set_byte_timeout[3] | 128 | linkmb:modbus_set_byte_timeout[3] |
| 129 | linkmb:modbus_get_response_timeout[3] | 129 | linkmb:modbus_get_response_timeout[3] |
| 130 | linkmb:modbus_set_response_timeout[3] | 130 | linkmb:modbus_set_response_timeout[3] |
| 131 | + linkmb:modbus_get_indication_timeout[3] | ||
| 132 | + linkmb:modbus_set_indication_timeout[3] | ||
| 131 | 133 | ||
| 132 | Error recovery mode:: | 134 | Error recovery mode:: |
| 133 | linkmb:modbus_set_error_recovery[3] | 135 | linkmb:modbus_set_error_recovery[3] |
doc/modbus_get_byte_timeout.txt
| @@ -39,9 +39,9 @@ modbus_get_byte_timeout(ctx, &to_sec, &to_usec); | @@ -39,9 +39,9 @@ modbus_get_byte_timeout(ctx, &to_sec, &to_usec); | ||
| 39 | 39 | ||
| 40 | SEE ALSO | 40 | SEE ALSO |
| 41 | -------- | 41 | -------- |
| 42 | +linkmb:modbus_set_byte_timeout[3] | ||
| 42 | linkmb:modbus_get_response_timeout[3] | 43 | linkmb:modbus_get_response_timeout[3] |
| 43 | linkmb:modbus_set_response_timeout[3] | 44 | linkmb:modbus_set_response_timeout[3] |
| 44 | -linkmb:modbus_set_byte_timeout[3] | ||
| 45 | 45 | ||
| 46 | 46 | ||
| 47 | AUTHORS | 47 | AUTHORS |
doc/modbus_get_indication_timeout.txt
0 → 100644
| 1 | +modbus_get_indication_timeout(3) | ||
| 2 | +================================ | ||
| 3 | + | ||
| 4 | + | ||
| 5 | +NAME | ||
| 6 | +---- | ||
| 7 | +modbus_get_indication_timeout - get timeout used to wait for an indication (request received by a server). | ||
| 8 | + | ||
| 9 | +SYNOPSIS | ||
| 10 | +-------- | ||
| 11 | +*int modbus_get_indication_timeout(modbus_t *'ctx', uint32_t *'to_sec', uint32_t *'to_usec');* | ||
| 12 | + | ||
| 13 | + | ||
| 14 | +DESCRIPTION | ||
| 15 | +----------- | ||
| 16 | + | ||
| 17 | +The *modbus_get_indication_timeout()* function shall store the timeout interval | ||
| 18 | +used to wait for an indication in the _to_sec_ and _to_usec_ arguments. | ||
| 19 | +Indication is the term used by the Modbus protocol to designate a request | ||
| 20 | +received by the server. | ||
| 21 | + | ||
| 22 | +The default value is zero, it means the server will wait forever. | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +RETURN VALUE | ||
| 26 | +------------ | ||
| 27 | +The function shall return 0 if successful. Otherwise it shall return -1 and set | ||
| 28 | +errno. | ||
| 29 | + | ||
| 30 | + | ||
| 31 | +EXAMPLE | ||
| 32 | +------- | ||
| 33 | +[source,c] | ||
| 34 | +------------------- | ||
| 35 | +uint32_t to_sec; | ||
| 36 | +uint32_t to_usec; | ||
| 37 | + | ||
| 38 | +/* Save original timeout */ | ||
| 39 | +modbus_get_indication_timeout(ctx, &to_sec, &to_usec); | ||
| 40 | +------------------- | ||
| 41 | + | ||
| 42 | + | ||
| 43 | +SEE ALSO | ||
| 44 | +-------- | ||
| 45 | +linkmb:modbus_set_indication_timeout[3] | ||
| 46 | +linkmb:modbus_get_response_timeout[3] | ||
| 47 | +linkmb:modbus_set_response_timeout[3] | ||
| 48 | + | ||
| 49 | + | ||
| 50 | +AUTHORS | ||
| 51 | +------- | ||
| 52 | +The libmodbus documentation was written by Stéphane Raimbault | ||
| 53 | +<stephane.raimbault@gmail.com> |
doc/modbus_set_indication_timeout.txt
0 → 100644
| 1 | +modbus_set_indication_timeout(3) | ||
| 2 | +================================ | ||
| 3 | + | ||
| 4 | + | ||
| 5 | +NAME | ||
| 6 | +---- | ||
| 7 | +modbus_set_indication_timeout - set timeout between indications | ||
| 8 | + | ||
| 9 | + | ||
| 10 | +SYNOPSIS | ||
| 11 | +-------- | ||
| 12 | +*void modbus_set_indication_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');* | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +DESCRIPTION | ||
| 16 | +----------- | ||
| 17 | +The *modbus_set_indication_timeout()* function shall set the timeout interval used by | ||
| 18 | +a server to wait for a request from a client. | ||
| 19 | + | ||
| 20 | +The value of _to_usec_ argument must be in the range 0 to 999999. | ||
| 21 | + | ||
| 22 | +If both _to_sec_ and _to_usec_ are zero, this timeout will not be used at all. | ||
| 23 | +In this case, the server will wait forever. | ||
| 24 | + | ||
| 25 | + | ||
| 26 | +RETURN VALUE | ||
| 27 | +------------ | ||
| 28 | +The function shall return 0 if successful. Otherwise it shall return -1 and set | ||
| 29 | +errno. | ||
| 30 | + | ||
| 31 | + | ||
| 32 | +ERRORS | ||
| 33 | +------ | ||
| 34 | +*EINVAL*:: | ||
| 35 | +The argument _ctx_ is NULL or _to_usec_ is larger than 1000000. | ||
| 36 | + | ||
| 37 | + | ||
| 38 | +SEE ALSO | ||
| 39 | +-------- | ||
| 40 | +linkmb:modbus_get_indication_timeout[3] | ||
| 41 | +linkmb:modbus_get_response_timeout[3] | ||
| 42 | +linkmb:modbus_set_response_timeout[3] | ||
| 43 | + | ||
| 44 | + | ||
| 45 | +AUTHORS | ||
| 46 | +------- | ||
| 47 | +The libmodbus documentation was written by Stéphane Raimbault | ||
| 48 | +<stephane.raimbault@gmail.com> |
src/modbus-private.h
| @@ -98,6 +98,7 @@ struct _modbus { | @@ -98,6 +98,7 @@ struct _modbus { | ||
| 98 | int error_recovery; | 98 | int error_recovery; |
| 99 | struct timeval response_timeout; | 99 | struct timeval response_timeout; |
| 100 | struct timeval byte_timeout; | 100 | struct timeval byte_timeout; |
| 101 | + struct timeval indication_timeout; | ||
| 101 | const modbus_backend_t *backend; | 102 | const modbus_backend_t *backend; |
| 102 | void *backend_data; | 103 | void *backend_data; |
| 103 | }; | 104 | }; |
src/modbus.c
| @@ -349,7 +349,7 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type) | @@ -349,7 +349,7 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type) | ||
| 349 | 349 | ||
| 350 | if (ctx->debug) { | 350 | if (ctx->debug) { |
| 351 | if (msg_type == MSG_INDICATION) { | 351 | if (msg_type == MSG_INDICATION) { |
| 352 | - printf("Waiting for a indication...\n"); | 352 | + printf("Waiting for an indication...\n"); |
| 353 | } else { | 353 | } else { |
| 354 | printf("Waiting for a confirmation...\n"); | 354 | printf("Waiting for a confirmation...\n"); |
| 355 | } | 355 | } |
| @@ -368,7 +368,15 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type) | @@ -368,7 +368,15 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type) | ||
| 368 | if (msg_type == MSG_INDICATION) { | 368 | if (msg_type == MSG_INDICATION) { |
| 369 | /* Wait for a message, we don't know when the message will be | 369 | /* Wait for a message, we don't know when the message will be |
| 370 | * received */ | 370 | * received */ |
| 371 | - p_tv = NULL; | 371 | + if (ctx->indication_timeout.tv_sec == 0 && ctx->indication_timeout.tv_usec == 0) { |
| 372 | + /* By default, the indication timeout isn't set */ | ||
| 373 | + p_tv = NULL; | ||
| 374 | + } else { | ||
| 375 | + /* Wait for an indication (name of a received request by a server, see schema) */ | ||
| 376 | + tv.tv_sec = ctx->indication_timeout.tv_sec; | ||
| 377 | + tv.tv_usec = ctx->indication_timeout.tv_usec; | ||
| 378 | + p_tv = &tv; | ||
| 379 | + } | ||
| 372 | } else { | 380 | } else { |
| 373 | tv.tv_sec = ctx->response_timeout.tv_sec; | 381 | tv.tv_sec = ctx->response_timeout.tv_sec; |
| 374 | tv.tv_usec = ctx->response_timeout.tv_usec; | 382 | tv.tv_usec = ctx->response_timeout.tv_usec; |
| @@ -1564,6 +1572,9 @@ void _modbus_init_common(modbus_t *ctx) | @@ -1564,6 +1572,9 @@ void _modbus_init_common(modbus_t *ctx) | ||
| 1564 | 1572 | ||
| 1565 | ctx->byte_timeout.tv_sec = 0; | 1573 | ctx->byte_timeout.tv_sec = 0; |
| 1566 | ctx->byte_timeout.tv_usec = _BYTE_TIMEOUT; | 1574 | ctx->byte_timeout.tv_usec = _BYTE_TIMEOUT; |
| 1575 | + | ||
| 1576 | + ctx->indication_timeout.tv_sec = 0; | ||
| 1577 | + ctx->indication_timeout.tv_usec = 0; | ||
| 1567 | } | 1578 | } |
| 1568 | 1579 | ||
| 1569 | /* Define the slave number */ | 1580 | /* Define the slave number */ |
| @@ -1673,6 +1684,32 @@ int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec) | @@ -1673,6 +1684,32 @@ int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec) | ||
| 1673 | return 0; | 1684 | return 0; |
| 1674 | } | 1685 | } |
| 1675 | 1686 | ||
| 1687 | +/* Get the timeout interval used by the server to wait for an indication from a client */ | ||
| 1688 | +int modbus_get_indication_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec) | ||
| 1689 | +{ | ||
| 1690 | + if (ctx == NULL) { | ||
| 1691 | + errno = EINVAL; | ||
| 1692 | + return -1; | ||
| 1693 | + } | ||
| 1694 | + | ||
| 1695 | + *to_sec = ctx->indication_timeout.tv_sec; | ||
| 1696 | + *to_usec = ctx->indication_timeout.tv_usec; | ||
| 1697 | + return 0; | ||
| 1698 | +} | ||
| 1699 | + | ||
| 1700 | +int modbus_set_indication_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec) | ||
| 1701 | +{ | ||
| 1702 | + /* Indication timeout can be disabled when both values are zero */ | ||
| 1703 | + if (ctx == NULL || to_usec > 999999) { | ||
| 1704 | + errno = EINVAL; | ||
| 1705 | + return -1; | ||
| 1706 | + } | ||
| 1707 | + | ||
| 1708 | + ctx->indication_timeout.tv_sec = to_sec; | ||
| 1709 | + ctx->indication_timeout.tv_usec = to_usec; | ||
| 1710 | + return 0; | ||
| 1711 | +} | ||
| 1712 | + | ||
| 1676 | int modbus_get_header_length(modbus_t *ctx) | 1713 | int modbus_get_header_length(modbus_t *ctx) |
| 1677 | { | 1714 | { |
| 1678 | if (ctx == NULL) { | 1715 | if (ctx == NULL) { |
src/modbus.h
| @@ -188,6 +188,9 @@ MODBUS_API int modbus_set_response_timeout(modbus_t *ctx, uint32_t to_sec, uint3 | @@ -188,6 +188,9 @@ MODBUS_API int modbus_set_response_timeout(modbus_t *ctx, uint32_t to_sec, uint3 | ||
| 188 | MODBUS_API int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec); | 188 | MODBUS_API int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec); |
| 189 | MODBUS_API int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec); | 189 | MODBUS_API int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec); |
| 190 | 190 | ||
| 191 | +MODBUS_API int modbus_get_indication_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec); | ||
| 192 | +MODBUS_API int modbus_set_indication_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec); | ||
| 193 | + | ||
| 191 | MODBUS_API int modbus_get_header_length(modbus_t *ctx); | 194 | MODBUS_API int modbus_get_header_length(modbus_t *ctx); |
| 192 | 195 | ||
| 193 | MODBUS_API int modbus_connect(modbus_t *ctx); | 196 | MODBUS_API int modbus_connect(modbus_t *ctx); |