Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

indication timeout in server mode times out while receiving master message #712

Open
martinwag opened this issue Aug 10, 2023 · 0 comments
Assignees

Comments

@martinwag
Copy link

martinwag commented Aug 10, 2023

libmodbus version

Git b25629b (Head as of 2023-08-10)

OS and/or distribution

Linux Debian 11

Environment

x86 32bit gcc (Debian 10.2.1-6) 10.2.1 20210110

Description

when using server mode with an indication timeout set by modbus_get_indication_timeout(), sometimes the indication timeout expires while a client message is currently being received.
In my use case (indication timeout 250ms) this leads to a few failed client request per minute (client does one request per second, 9600baud).

Expected behavior or suggestion

When a message reception is active (first byte(s) already read from socket), finish it instead of timing out.

I've fixed it for test like this:

int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
{
...
    if (msg_type == MSG_INDICATION) {
        /* By default, the indication timeout isn't set */
        p_tv = NULL;
    } else {
        tv.tv_sec = ctx->response_timeout.tv_sec;
        tv.tv_usec = ctx->response_timeout.tv_usec;
        p_tv = &tv;
    }

    while (length_to_read != 0) {

        if (ctx->indication_timeout.tv_sec != 0 || ctx->indication_timeout.tv_usec != 0) {
            /* 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;
        }
        rc = select(...)

...

This solution reloads the indication timeout for every select call. This might extend the timeout by quite a bit, so I don't know if this suggestion would be good for main branch. Be aware that this is only proof-of-concept, e.g. it conflicts with byte_timeout.

libmodbus output with debug mode enabled

ERROR Connection timed out: select
Waiting for an indication...
ERROR Connection timed out: select
Waiting for an indication...
ERROR Connection timed out: select
<2A><10><04>Waiting for an indication...
<4C><00><64><C8><49><CE><80><60>
Request for slave 76 ignored (not 42)
Waiting for a confirmation...
<42><78><9D><ED><83>
Request for slave 66 ignored (not 42)
Confirmation to ignore
Waiting for an indication...
<E4><80><00><B2>
Request for slave 228 ignored (not 42)
Waiting for a confirmation...
<3F><B2><40><B2><41>
Request for slave 63 ignored (not 42)
Confirmation to ignore
Waiting for an indication...
<B2><42><B2><43>

(there is some order mixup because ERROR... are written to stderr, other to stdout)

@stephane stephane self-assigned this Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants