Commit c4f7a2428521765dac88977eb726f544f2e3b040
1 parent
8dc4e2e5
Change timeout to uint32 and add 3 byte timeout tests
- add byte timeout tests (TCP backend only) - update and improve documentation - long timeout values are now uint32_t so it changes the API to disable byte timeout
Showing
9 changed files
with
123 additions
and
50 deletions
doc/modbus_get_byte_timeout.txt
| @@ -9,7 +9,7 @@ modbus_get_byte_timeout - get timeout between bytes | @@ -9,7 +9,7 @@ modbus_get_byte_timeout - get timeout between bytes | ||
| 9 | 9 | ||
| 10 | SYNOPSIS | 10 | SYNOPSIS |
| 11 | -------- | 11 | -------- |
| 12 | -*int modbus_get_byte_timeout(modbus_t *'ctx', long *'to_sec', long *'to_usec');* | 12 | +*int modbus_get_byte_timeout(modbus_t *'ctx', uint32_t *'to_sec', uint32_t *'to_usec');* |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | DESCRIPTION | 15 | DESCRIPTION |
| @@ -29,8 +29,8 @@ EXAMPLE | @@ -29,8 +29,8 @@ EXAMPLE | ||
| 29 | ------- | 29 | ------- |
| 30 | [source,c] | 30 | [source,c] |
| 31 | ------------------- | 31 | ------------------- |
| 32 | -long to_sec; | ||
| 33 | -long to_usec; | 32 | +uint32_t to_sec; |
| 33 | +uint32_t to_usec; | ||
| 34 | 34 | ||
| 35 | /* Save original timeout */ | 35 | /* Save original timeout */ |
| 36 | modbus_get_byte_timeout(ctx, &to_sec, &to_usec); | 36 | modbus_get_byte_timeout(ctx, &to_sec, &to_usec); |
doc/modbus_get_response_timeout.txt
| @@ -9,7 +9,7 @@ modbus_get_response_timeout - get timeout for response | @@ -9,7 +9,7 @@ modbus_get_response_timeout - get timeout for response | ||
| 9 | 9 | ||
| 10 | SYNOPSIS | 10 | SYNOPSIS |
| 11 | -------- | 11 | -------- |
| 12 | -*int modbus_get_response_timeout(modbus_t *'ctx', long *'to_sec', long *'to_usec');* | 12 | +*int modbus_get_response_timeout(modbus_t *'ctx', uint32_t *'to_sec', uint32_t *'to_usec');* |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | DESCRIPTION | 15 | DESCRIPTION |
| @@ -28,8 +28,8 @@ EXAMPLE | @@ -28,8 +28,8 @@ EXAMPLE | ||
| 28 | ------- | 28 | ------- |
| 29 | [source,c] | 29 | [source,c] |
| 30 | ------------------- | 30 | ------------------- |
| 31 | -long old_response_to_sec; | ||
| 32 | -long old_response_to_usec; | 31 | +uint32_t old_response_to_sec; |
| 32 | +uint32_t old_response_to_usec; | ||
| 33 | 33 | ||
| 34 | /* Save original timeout */ | 34 | /* Save original timeout */ |
| 35 | modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); | 35 | modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); |
doc/modbus_set_byte_timeout.txt
| @@ -9,23 +9,24 @@ modbus_set_byte_timeout - set timeout between bytes | @@ -9,23 +9,24 @@ modbus_set_byte_timeout - set timeout between bytes | ||
| 9 | 9 | ||
| 10 | SYNOPSIS | 10 | SYNOPSIS |
| 11 | -------- | 11 | -------- |
| 12 | -*void modbus_set_byte_timeout(modbus_t *'ctx', long 'to_sec', long 'to_usec');* | 12 | +*void modbus_set_byte_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');* |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | DESCRIPTION | 15 | DESCRIPTION |
| 16 | ----------- | 16 | ----------- |
| 17 | The _modbus_set_byte_timeout()_ function shall set the timeout interval between | 17 | The _modbus_set_byte_timeout()_ function shall set the timeout interval between |
| 18 | -two consecutive bytes of the same message. If the delay between bytes is longer | ||
| 19 | -than the given timeout, the 'ETIMEDOUT' error will be raised by the the function | ||
| 20 | -waiting for a response. | 18 | +two consecutive bytes of the same message. The timeout is an upper bound on the |
| 19 | +amount of time elapsed before _select()_ returns, if the time elapsed is longer | ||
| 20 | +than the defined timeout, an 'ETIMEDOUT' error will be raised by the | ||
| 21 | +function waiting for a response. | ||
| 21 | 22 | ||
| 22 | The value of _to_usec_ argument must be in the range 0 to 999999. | 23 | The value of _to_usec_ argument must be in the range 0 to 999999. |
| 23 | 24 | ||
| 24 | -If _to_sec_ is set to -1 then this timeout will not be used at all. In this | ||
| 25 | -case, _modbus_set_response_timeout()_ governs the entire handling of the | 25 | +If both _to_sec_ and _to_usec_ are zero, this timeout will not be used at all. |
| 26 | +In this case, _modbus_set_response_timeout()_ governs the entire handling of the | ||
| 26 | response, the full confirmation response must be received before expiration of | 27 | response, the full confirmation response must be received before expiration of |
| 27 | the response timeout. When a byte timeout is set, the response timeout is only | 28 | the response timeout. When a byte timeout is set, the response timeout is only |
| 28 | -used to wait for the first byte of the response. | 29 | +used to wait for until the first byte of the response. |
| 29 | 30 | ||
| 30 | 31 | ||
| 31 | RETURN VALUE | 32 | RETURN VALUE |
| @@ -37,7 +38,7 @@ errno. | @@ -37,7 +38,7 @@ errno. | ||
| 37 | ERRORS | 38 | ERRORS |
| 38 | ------ | 39 | ------ |
| 39 | *EINVAL*:: | 40 | *EINVAL*:: |
| 40 | -The argument _ctx_ is NULL or _to_usec_ is not smaller than 1000000. | 41 | +The argument _ctx_ is NULL or _to_usec_ is larger than 1000000. |
| 41 | 42 | ||
| 42 | 43 | ||
| 43 | SEE ALSO | 44 | SEE ALSO |
doc/modbus_set_response_timeout.txt
| @@ -9,18 +9,18 @@ modbus_set_response_timeout - set timeout for response | @@ -9,18 +9,18 @@ modbus_set_response_timeout - set timeout for response | ||
| 9 | 9 | ||
| 10 | SYNOPSIS | 10 | SYNOPSIS |
| 11 | -------- | 11 | -------- |
| 12 | -*int modbus_set_response_timeout(modbus_t *'ctx', long 'to_sec', long 'to_usec');* | 12 | +*int modbus_set_response_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');* |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | DESCRIPTION | 15 | DESCRIPTION |
| 16 | ----------- | 16 | ----------- |
| 17 | 17 | ||
| 18 | The _modbus_set_response_timeout()_ function shall set the timeout interval used | 18 | The _modbus_set_response_timeout()_ function shall set the timeout interval used |
| 19 | -to wait for a response. When a byte timeout is set, if the waiting before | ||
| 20 | -receiving the first byte of response is longer than the given timeout, the | ||
| 21 | -'ETIMEDOUT' error will be raised by the function waiting for a response. When | ||
| 22 | -byte timeout is disabled, the full confirmation response must be received before | ||
| 23 | -expiration of the response timeout. | 19 | +to wait for a response. When a byte timeout is set, if elapsed time for the |
| 20 | +first byte of response is longer than the given timeout, an 'ETIMEDOUT' error | ||
| 21 | +will be raised by the function waiting for a response. When byte timeout is | ||
| 22 | +disabled, the full confirmation response must be received before expiration of | ||
| 23 | +the response timeout. | ||
| 24 | 24 | ||
| 25 | The value of to_usec argument must be in the range 0 to 999999. | 25 | The value of to_usec argument must be in the range 0 to 999999. |
| 26 | 26 | ||
| @@ -34,22 +34,22 @@ errno. | @@ -34,22 +34,22 @@ errno. | ||
| 34 | ERRORS | 34 | ERRORS |
| 35 | ------ | 35 | ------ |
| 36 | *EINVAL*:: | 36 | *EINVAL*:: |
| 37 | -The argument _ctx_ is NULL or _to_sec_/_to_usec_ aren't equal or greater than 0 or | ||
| 38 | -_to_usec_ is not smaller than 1000000. | 37 | +The argument _ctx_ is NULL, or both _to_sec_ and _to_usec_ are zero, or _to_usec_ |
| 38 | +is larger than 1000000. | ||
| 39 | 39 | ||
| 40 | 40 | ||
| 41 | EXAMPLE | 41 | EXAMPLE |
| 42 | ------- | 42 | ------- |
| 43 | [source,c] | 43 | [source,c] |
| 44 | ------------------- | 44 | ------------------- |
| 45 | -long old_response_to_sec; | ||
| 46 | -long old_response_to_usec; | 45 | +uint32_t old_response_to_sec; |
| 46 | +uint32_t old_response_to_usec; | ||
| 47 | 47 | ||
| 48 | /* Save original timeout */ | 48 | /* Save original timeout */ |
| 49 | modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); | 49 | modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); |
| 50 | 50 | ||
| 51 | -/* Define a new and too short timeout! */ | ||
| 52 | -modbus_set_response_timeout(ctx, 0, 0); | 51 | +/* Define a new timeout of 200ms */ |
| 52 | +modbus_set_response_timeout(ctx, 0, 200000); | ||
| 53 | ------------------- | 53 | ------------------- |
| 54 | 54 | ||
| 55 | 55 |
src/modbus.c
| @@ -462,7 +462,8 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type) | @@ -462,7 +462,8 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type) | ||
| 462 | } | 462 | } |
| 463 | } | 463 | } |
| 464 | 464 | ||
| 465 | - if (length_to_read > 0 && ctx->byte_timeout.tv_sec >= 0 && ctx->byte_timeout.tv_usec >= 0) { | 465 | + if (length_to_read > 0 && |
| 466 | + (ctx->byte_timeout.tv_sec > 0 || ctx->byte_timeout.tv_usec > 0)) { | ||
| 466 | /* If there is no character in the buffer, the allowed timeout | 467 | /* If there is no character in the buffer, the allowed timeout |
| 467 | interval between two consecutive bytes is defined by | 468 | interval between two consecutive bytes is defined by |
| 468 | byte_timeout */ | 469 | byte_timeout */ |
| @@ -1644,7 +1645,7 @@ int modbus_get_socket(modbus_t *ctx) | @@ -1644,7 +1645,7 @@ int modbus_get_socket(modbus_t *ctx) | ||
| 1644 | } | 1645 | } |
| 1645 | 1646 | ||
| 1646 | /* Get the timeout interval used to wait for a response */ | 1647 | /* Get the timeout interval used to wait for a response */ |
| 1647 | -int modbus_get_response_timeout(modbus_t *ctx, long *to_sec, long *to_usec) | 1648 | +int modbus_get_response_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec) |
| 1648 | { | 1649 | { |
| 1649 | if (ctx == NULL) { | 1650 | if (ctx == NULL) { |
| 1650 | errno = EINVAL; | 1651 | errno = EINVAL; |
| @@ -1656,10 +1657,10 @@ int modbus_get_response_timeout(modbus_t *ctx, long *to_sec, long *to_usec) | @@ -1656,10 +1657,10 @@ int modbus_get_response_timeout(modbus_t *ctx, long *to_sec, long *to_usec) | ||
| 1656 | return 0; | 1657 | return 0; |
| 1657 | } | 1658 | } |
| 1658 | 1659 | ||
| 1659 | -int modbus_set_response_timeout(modbus_t *ctx, long to_sec, long to_usec) | 1660 | +int modbus_set_response_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec) |
| 1660 | { | 1661 | { |
| 1661 | if (ctx == NULL || | 1662 | if (ctx == NULL || |
| 1662 | - to_sec < 0 || to_usec < 0 || to_usec > 999999) { | 1663 | + (to_sec == 0 && to_usec == 0) || to_usec > 999999) { |
| 1663 | errno = EINVAL; | 1664 | errno = EINVAL; |
| 1664 | return -1; | 1665 | return -1; |
| 1665 | } | 1666 | } |
| @@ -1670,7 +1671,7 @@ int modbus_set_response_timeout(modbus_t *ctx, long to_sec, long to_usec) | @@ -1670,7 +1671,7 @@ int modbus_set_response_timeout(modbus_t *ctx, long to_sec, long to_usec) | ||
| 1670 | } | 1671 | } |
| 1671 | 1672 | ||
| 1672 | /* Get the timeout interval between two consecutive bytes of a message */ | 1673 | /* Get the timeout interval between two consecutive bytes of a message */ |
| 1673 | -int modbus_get_byte_timeout(modbus_t *ctx, long *to_sec, long *to_usec) | 1674 | +int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec) |
| 1674 | { | 1675 | { |
| 1675 | if (ctx == NULL) { | 1676 | if (ctx == NULL) { |
| 1676 | errno = EINVAL; | 1677 | errno = EINVAL; |
| @@ -1682,9 +1683,9 @@ int modbus_get_byte_timeout(modbus_t *ctx, long *to_sec, long *to_usec) | @@ -1682,9 +1683,9 @@ int modbus_get_byte_timeout(modbus_t *ctx, long *to_sec, long *to_usec) | ||
| 1682 | return 0; | 1683 | return 0; |
| 1683 | } | 1684 | } |
| 1684 | 1685 | ||
| 1685 | -int modbus_set_byte_timeout(modbus_t *ctx, long to_sec, long to_usec) | 1686 | +int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec) |
| 1686 | { | 1687 | { |
| 1687 | - /* Byte timeout can be disabled with negative values */ | 1688 | + /* Byte timeout can be disabled when both values are zero */ |
| 1688 | if (ctx == NULL || to_usec > 999999) { | 1689 | if (ctx == NULL || to_usec > 999999) { |
| 1689 | errno = EINVAL; | 1690 | errno = EINVAL; |
| 1690 | return -1; | 1691 | return -1; |
src/modbus.h
| @@ -172,11 +172,11 @@ MODBUS_API int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mo | @@ -172,11 +172,11 @@ MODBUS_API int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mo | ||
| 172 | MODBUS_API int modbus_set_socket(modbus_t *ctx, int s); | 172 | MODBUS_API int modbus_set_socket(modbus_t *ctx, int s); |
| 173 | MODBUS_API int modbus_get_socket(modbus_t *ctx); | 173 | MODBUS_API int modbus_get_socket(modbus_t *ctx); |
| 174 | 174 | ||
| 175 | -MODBUS_API int modbus_get_response_timeout(modbus_t *ctx, long *to_sec, long *to_usec); | ||
| 176 | -MODBUS_API int modbus_set_response_timeout(modbus_t *ctx, long to_sec, long to_usec); | 175 | +MODBUS_API int modbus_get_response_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec); |
| 176 | +MODBUS_API int modbus_set_response_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec); | ||
| 177 | 177 | ||
| 178 | -MODBUS_API int modbus_get_byte_timeout(modbus_t *ctx, long *to_sec, long *to_usec); | ||
| 179 | -MODBUS_API int modbus_set_byte_timeout(modbus_t *ctx, long to_sec, long to_usec); | 178 | +MODBUS_API int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec); |
| 179 | +MODBUS_API int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec); | ||
| 180 | 180 | ||
| 181 | MODBUS_API int modbus_get_header_length(modbus_t *ctx); | 181 | MODBUS_API int modbus_get_header_length(modbus_t *ctx); |
| 182 | 182 |
tests/unit-test-client.c
| @@ -44,8 +44,10 @@ int main(int argc, char *argv[]) | @@ -44,8 +44,10 @@ int main(int argc, char *argv[]) | ||
| 44 | int rc; | 44 | int rc; |
| 45 | float real; | 45 | float real; |
| 46 | uint32_t ireal; | 46 | uint32_t ireal; |
| 47 | - long old_response_timeout_sec; | ||
| 48 | - long old_response_timeout_usec; | 47 | + uint32_t old_response_to_sec; |
| 48 | + uint32_t old_response_to_usec; | ||
| 49 | + uint32_t old_byte_to_sec; | ||
| 50 | + uint32_t old_byte_to_usec; | ||
| 49 | int use_backend; | 51 | int use_backend; |
| 50 | 52 | ||
| 51 | if (argc > 1) { | 53 | if (argc > 1) { |
| @@ -647,10 +649,11 @@ int main(int argc, char *argv[]) | @@ -647,10 +649,11 @@ int main(int argc, char *argv[]) | ||
| 647 | } | 649 | } |
| 648 | 650 | ||
| 649 | /* Save original timeout */ | 651 | /* Save original timeout */ |
| 650 | - modbus_get_response_timeout(ctx, &old_response_timeout_sec, &old_response_timeout_usec); | 652 | + modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec); |
| 653 | + modbus_get_byte_timeout(ctx, &old_byte_to_sec, &old_byte_to_usec); | ||
| 651 | 654 | ||
| 652 | - rc = modbus_set_response_timeout(ctx, -1, 0); | ||
| 653 | - printf("1/6 Invalid response timeout (negative): "); | 655 | + rc = modbus_set_response_timeout(ctx, 0, 0); |
| 656 | + printf("1/6 Invalid response timeout (zero): "); | ||
| 654 | if (rc == -1 && errno == EINVAL) { | 657 | if (rc == -1 && errno == EINVAL) { |
| 655 | printf("OK\n"); | 658 | printf("OK\n"); |
| 656 | } else { | 659 | } else { |
| @@ -659,7 +662,7 @@ int main(int argc, char *argv[]) | @@ -659,7 +662,7 @@ int main(int argc, char *argv[]) | ||
| 659 | } | 662 | } |
| 660 | 663 | ||
| 661 | rc = modbus_set_response_timeout(ctx, 0, 1000000); | 664 | rc = modbus_set_response_timeout(ctx, 0, 1000000); |
| 662 | - printf("2/6 Invalid response timeout (too large): "); | 665 | + printf("2/6 Invalid response timeout (too large us): "); |
| 663 | if (rc == -1 && errno == EINVAL) { | 666 | if (rc == -1 && errno == EINVAL) { |
| 664 | printf("OK\n"); | 667 | printf("OK\n"); |
| 665 | } else { | 668 | } else { |
| @@ -668,7 +671,7 @@ int main(int argc, char *argv[]) | @@ -668,7 +671,7 @@ int main(int argc, char *argv[]) | ||
| 668 | } | 671 | } |
| 669 | 672 | ||
| 670 | rc = modbus_set_byte_timeout(ctx, 0, 1000000); | 673 | rc = modbus_set_byte_timeout(ctx, 0, 1000000); |
| 671 | - printf("3/6 Invalid byte timeout (too large): "); | 674 | + printf("3/6 Invalid byte timeout (too large us): "); |
| 672 | if (rc == -1 && errno == EINVAL) { | 675 | if (rc == -1 && errno == EINVAL) { |
| 673 | printf("OK\n"); | 676 | printf("OK\n"); |
| 674 | } else { | 677 | } else { |
| @@ -676,21 +679,21 @@ int main(int argc, char *argv[]) | @@ -676,21 +679,21 @@ int main(int argc, char *argv[]) | ||
| 676 | goto close; | 679 | goto close; |
| 677 | } | 680 | } |
| 678 | 681 | ||
| 679 | - modbus_set_response_timeout(ctx, 0, 0); | 682 | + modbus_set_response_timeout(ctx, 0, 1); |
| 680 | rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, | 683 | rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, |
| 681 | UT_REGISTERS_NB, tab_rp_registers); | 684 | UT_REGISTERS_NB, tab_rp_registers); |
| 682 | - printf("4/6 Zero response timeout: "); | 685 | + printf("4/6 1us response timeout: "); |
| 683 | if (rc == -1 && errno == ETIMEDOUT) { | 686 | if (rc == -1 && errno == ETIMEDOUT) { |
| 684 | printf("OK\n"); | 687 | printf("OK\n"); |
| 685 | } else { | 688 | } else { |
| 686 | - printf("FAILED (can fail on slow systems or Windows)\n"); | 689 | + printf("FAILED (can fail on some platforms)\n"); |
| 687 | } | 690 | } |
| 688 | 691 | ||
| 689 | /* A wait and flush operation is done by the error recovery code of | 692 | /* A wait and flush operation is done by the error recovery code of |
| 690 | * libmodbus but after a sleep of current response timeout | 693 | * libmodbus but after a sleep of current response timeout |
| 691 | * so 0 can't be too short! | 694 | * so 0 can't be too short! |
| 692 | */ | 695 | */ |
| 693 | - usleep(old_response_timeout_sec * 1000000 + old_response_timeout_usec); | 696 | + usleep(old_response_to_sec * 1000000 + old_response_to_usec); |
| 694 | modbus_flush(ctx); | 697 | modbus_flush(ctx); |
| 695 | 698 | ||
| 696 | /* Trigger a special behaviour on server to wait for 0.5 second before | 699 | /* Trigger a special behaviour on server to wait for 0.5 second before |
| @@ -721,8 +724,57 @@ int main(int argc, char *argv[]) | @@ -721,8 +724,57 @@ int main(int argc, char *argv[]) | ||
| 721 | goto close; | 724 | goto close; |
| 722 | } | 725 | } |
| 723 | 726 | ||
| 724 | - /* Restore original timeout */ | ||
| 725 | - modbus_set_response_timeout(ctx, old_response_timeout_sec, old_response_timeout_usec); | 727 | + /* Disable the byte timeout. |
| 728 | + The full response must be available in the 600ms interval */ | ||
| 729 | + modbus_set_byte_timeout(ctx, 0, 0); | ||
| 730 | + rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS_SLEEP_500_MS, | ||
| 731 | + 1, tab_rp_registers); | ||
| 732 | + printf("7/7 Disable byte timeout: "); | ||
| 733 | + if (rc == 1) { | ||
| 734 | + printf("OK\n"); | ||
| 735 | + } else { | ||
| 736 | + printf("FAILED\n"); | ||
| 737 | + goto close; | ||
| 738 | + } | ||
| 739 | + | ||
| 740 | + /* Restore original response timeout */ | ||
| 741 | + modbus_set_response_timeout(ctx, old_response_to_sec, | ||
| 742 | + old_response_to_usec); | ||
| 743 | + | ||
| 744 | + if (use_backend == TCP) { | ||
| 745 | + /* Test server is only able to test byte timeout with the TCP backend */ | ||
| 746 | + | ||
| 747 | + /* Timeout of 3ms between bytes */ | ||
| 748 | + modbus_set_byte_timeout(ctx, 0, 3000); | ||
| 749 | + rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS_BYTE_SLEEP_5_MS, | ||
| 750 | + 1, tab_rp_registers); | ||
| 751 | + printf("1/2 Too small byte timeout (3ms < 5ms): "); | ||
| 752 | + if (rc == -1 && errno == ETIMEDOUT) { | ||
| 753 | + printf("OK\n"); | ||
| 754 | + } else { | ||
| 755 | + printf("FAILED\n"); | ||
| 756 | + goto close; | ||
| 757 | + } | ||
| 758 | + | ||
| 759 | + /* Wait remaing bytes before flushing */ | ||
| 760 | + usleep(11 * 5000); | ||
| 761 | + modbus_flush(ctx); | ||
| 762 | + | ||
| 763 | + /* Timeout of 10ms between bytes */ | ||
| 764 | + modbus_set_byte_timeout(ctx, 0, 7000); | ||
| 765 | + rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS_BYTE_SLEEP_5_MS, | ||
| 766 | + 1, tab_rp_registers); | ||
| 767 | + printf("2/2 Adapted byte timeout (7ms > 5ms): "); | ||
| 768 | + if (rc == 1) { | ||
| 769 | + printf("OK\n"); | ||
| 770 | + } else { | ||
| 771 | + printf("FAILED\n"); | ||
| 772 | + goto close; | ||
| 773 | + } | ||
| 774 | + } | ||
| 775 | + | ||
| 776 | + /* Restore original byte timeout */ | ||
| 777 | + modbus_set_byte_timeout(ctx, old_byte_to_sec, old_byte_to_usec); | ||
| 726 | 778 | ||
| 727 | /** BAD RESPONSE **/ | 779 | /** BAD RESPONSE **/ |
| 728 | printf("\nTEST BAD RESPONSE ERROR:\n"); | 780 | printf("\nTEST BAD RESPONSE ERROR:\n"); |
tests/unit-test-server.c
| @@ -21,6 +21,7 @@ | @@ -21,6 +21,7 @@ | ||
| 21 | #include <stdlib.h> | 21 | #include <stdlib.h> |
| 22 | #include <errno.h> | 22 | #include <errno.h> |
| 23 | #include <modbus.h> | 23 | #include <modbus.h> |
| 24 | +#include <sys/socket.h> | ||
| 24 | 25 | ||
| 25 | #include "unit-test.h" | 26 | #include "unit-test.h" |
| 26 | 27 | ||
| @@ -179,6 +180,22 @@ int main(int argc, char*argv[]) | @@ -179,6 +180,22 @@ int main(int argc, char*argv[]) | ||
| 179 | == UT_REGISTERS_ADDRESS_SLEEP_500_MS) { | 180 | == UT_REGISTERS_ADDRESS_SLEEP_500_MS) { |
| 180 | printf("Sleep 0.5 s before replying\n"); | 181 | printf("Sleep 0.5 s before replying\n"); |
| 181 | usleep(500000); | 182 | usleep(500000); |
| 183 | + } else if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 1) | ||
| 184 | + == UT_REGISTERS_ADDRESS_BYTE_SLEEP_5_MS) { | ||
| 185 | + /* Test low level only available in TCP mode */ | ||
| 186 | + /* Catch the reply and send reply byte a byte */ | ||
| 187 | + uint8_t req[] = "\x00\x1C\x00\x00\x00\x05\xFF\x03\x02\x00\x00"; | ||
| 188 | + int req_length = 11; | ||
| 189 | + int w_s = modbus_get_socket(ctx); | ||
| 190 | + | ||
| 191 | + /* Copy TID */ | ||
| 192 | + req[1] = query[1]; | ||
| 193 | + for (i=0; i < req_length; i++) { | ||
| 194 | + printf("(%.2X)", req[i]); | ||
| 195 | + usleep(500); | ||
| 196 | + send(w_s, req + i, 1, MSG_NOSIGNAL); | ||
| 197 | + } | ||
| 198 | + continue; | ||
| 182 | } | 199 | } |
| 183 | } | 200 | } |
| 184 | 201 |
tests/unit-test.h.in
| @@ -52,6 +52,8 @@ const uint16_t UT_REGISTERS_ADDRESS_SPECIAL = 0x6C; | @@ -52,6 +52,8 @@ const uint16_t UT_REGISTERS_ADDRESS_SPECIAL = 0x6C; | ||
| 52 | const uint16_t UT_REGISTERS_ADDRESS_INVALID_TID_OR_SLAVE = 0x6D; | 52 | const uint16_t UT_REGISTERS_ADDRESS_INVALID_TID_OR_SLAVE = 0x6D; |
| 53 | /* The server will wait for 1 second before replying to test timeout */ | 53 | /* The server will wait for 1 second before replying to test timeout */ |
| 54 | const uint16_t UT_REGISTERS_ADDRESS_SLEEP_500_MS = 0x6E; | 54 | const uint16_t UT_REGISTERS_ADDRESS_SLEEP_500_MS = 0x6E; |
| 55 | +/* The server will wait for 5 ms before sending each byte */ | ||
| 56 | +const uint16_t UT_REGISTERS_ADDRESS_BYTE_SLEEP_5_MS = 0x6F; | ||
| 55 | 57 | ||
| 56 | const uint16_t UT_REGISTERS_NB = 0x3; | 58 | const uint16_t UT_REGISTERS_NB = 0x3; |
| 57 | const uint16_t UT_REGISTERS_TAB[] = { 0x022B, 0x0001, 0x0064 }; | 59 | const uint16_t UT_REGISTERS_TAB[] = { 0x022B, 0x0001, 0x0064 }; |