Skip to content

Commit db1cbc5

Browse files
Mohamed Amine Mzoughistephane
authored andcommitted
Fixed MODBUS_ERROR_RECOVERY_LINK not working on Windows.
1 parent 06dc37f commit db1cbc5

1 file changed

Lines changed: 44 additions & 2 deletions

File tree

src/modbus.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,21 @@ static int send_msg(modbus_t *ctx, uint8_t *msg, int msg_length)
182182
rc = ctx->backend->send(ctx, msg, msg_length);
183183
if (rc == -1) {
184184
_error_print(ctx, NULL);
185-
if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) {
185+
if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK &&
186+
ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_TCP) {
187+
#ifdef _WIN32
188+
const int wsa_err = WSAGetLastError();
189+
if (wsa_err == WSAENETRESET || wsa_err == WSAENOTCONN || wsa_err == WSAENOTSOCK ||
190+
wsa_err == WSAESHUTDOWN || wsa_err == WSAEHOSTUNREACH || wsa_err == WSAECONNABORTED ||
191+
wsa_err == WSAECONNRESET || wsa_err == WSAETIMEDOUT) {
192+
modbus_close(ctx);
193+
_sleep_response_timeout(ctx);
194+
modbus_connect(ctx);
195+
} else {
196+
_sleep_response_timeout(ctx);
197+
modbus_flush(ctx);
198+
}
199+
#else
186200
int saved_errno = errno;
187201

188202
if ((errno == EBADF || errno == ECONNRESET || errno == EPIPE)) {
@@ -194,6 +208,7 @@ static int send_msg(modbus_t *ctx, uint8_t *msg, int msg_length)
194208
modbus_flush(ctx);
195209
}
196210
errno = saved_errno;
211+
#endif
197212
}
198213
}
199214
} while ((ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) &&
@@ -345,6 +360,9 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
345360
int length_to_read;
346361
int msg_length = 0;
347362
_step_t step;
363+
#ifdef _WIN32
364+
int wsa_err;
365+
#endif
348366

349367
if (ctx->debug) {
350368
if (msg_type == MSG_INDICATION) {
@@ -386,7 +404,17 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
386404
rc = ctx->backend->select(ctx, &rset, p_tv, length_to_read);
387405
if (rc == -1) {
388406
_error_print(ctx, "select");
389-
if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) {
407+
if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK &&
408+
ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_TCP) {
409+
#ifdef _WIN32
410+
wsa_err = WSAGetLastError();
411+
412+
// no equivalent to ETIMEDOUT when select fails on Windows
413+
if (wsa_err == WSAENETDOWN || wsa_err == WSAENOTSOCK) {
414+
modbus_close(ctx);
415+
modbus_connect(ctx);
416+
}
417+
#else
390418
int saved_errno = errno;
391419

392420
if (errno == ETIMEDOUT) {
@@ -397,6 +425,7 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
397425
modbus_connect(ctx);
398426
}
399427
errno = saved_errno;
428+
#endif
400429
}
401430
return -1;
402431
}
@@ -409,7 +438,19 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
409438

410439
if (rc == -1) {
411440
_error_print(ctx, "read");
441+
#ifdef _WIN32
442+
wsa_err = WSAGetLastError();
412443
if ((ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) &&
444+
(ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_TCP) &&
445+
(wsa_err == WSAENOTCONN || wsa_err == WSAENETRESET || wsa_err == WSAENOTSOCK ||
446+
wsa_err == WSAESHUTDOWN || wsa_err == WSAECONNABORTED || wsa_err == WSAETIMEDOUT ||
447+
wsa_err == WSAECONNRESET)) {
448+
modbus_close(ctx);
449+
modbus_connect(ctx);
450+
}
451+
#else
452+
if ((ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) &&
453+
(ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_TCP) &&
413454
(errno == ECONNRESET || errno == ECONNREFUSED ||
414455
errno == EBADF)) {
415456
int saved_errno = errno;
@@ -418,6 +459,7 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
418459
/* Could be removed by previous calls */
419460
errno = saved_errno;
420461
}
462+
#endif
421463
return -1;
422464
}
423465

0 commit comments

Comments
 (0)