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)
libmodbus version
Git https://github.com/stephane/libmodbus/commit/b25629bfb508bdce7d519884c0fa9810b7d98d44 (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:
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
(there is some order mixup because ERROR... are written to stderr, other to stdout)