Skip to content

Commit

Permalink
Fixed MODBUS_ERROR_RECOVERY_LINK not working on Windows.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mohamed Amine Mzoughi authored and stephane committed Aug 17, 2022
1 parent 06dc37f commit db1cbc5
Showing 1 changed file with 44 additions and 2 deletions.
46 changes: 44 additions & 2 deletions src/modbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,21 @@ static int send_msg(modbus_t *ctx, uint8_t *msg, int msg_length)
rc = ctx->backend->send(ctx, msg, msg_length);
if (rc == -1) {
_error_print(ctx, NULL);
if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) {
if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK &&
ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_TCP) {
#ifdef _WIN32
const int wsa_err = WSAGetLastError();
if (wsa_err == WSAENETRESET || wsa_err == WSAENOTCONN || wsa_err == WSAENOTSOCK ||
wsa_err == WSAESHUTDOWN || wsa_err == WSAEHOSTUNREACH || wsa_err == WSAECONNABORTED ||
wsa_err == WSAECONNRESET || wsa_err == WSAETIMEDOUT) {
modbus_close(ctx);
_sleep_response_timeout(ctx);
modbus_connect(ctx);
} else {
_sleep_response_timeout(ctx);
modbus_flush(ctx);
}
#else
int saved_errno = errno;

if ((errno == EBADF || errno == ECONNRESET || errno == EPIPE)) {
Expand All @@ -194,6 +208,7 @@ static int send_msg(modbus_t *ctx, uint8_t *msg, int msg_length)
modbus_flush(ctx);
}
errno = saved_errno;
#endif
}
}
} while ((ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) &&
Expand Down Expand Up @@ -345,6 +360,9 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
int length_to_read;
int msg_length = 0;
_step_t step;
#ifdef _WIN32
int wsa_err;
#endif

if (ctx->debug) {
if (msg_type == MSG_INDICATION) {
Expand Down Expand Up @@ -386,7 +404,17 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
rc = ctx->backend->select(ctx, &rset, p_tv, length_to_read);
if (rc == -1) {
_error_print(ctx, "select");
if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) {
if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK &&
ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_TCP) {
#ifdef _WIN32
wsa_err = WSAGetLastError();

// no equivalent to ETIMEDOUT when select fails on Windows
if (wsa_err == WSAENETDOWN || wsa_err == WSAENOTSOCK) {
modbus_close(ctx);
modbus_connect(ctx);
}
#else
int saved_errno = errno;

if (errno == ETIMEDOUT) {
Expand All @@ -397,6 +425,7 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
modbus_connect(ctx);
}
errno = saved_errno;
#endif
}
return -1;
}
Expand All @@ -409,7 +438,19 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)

if (rc == -1) {
_error_print(ctx, "read");
#ifdef _WIN32
wsa_err = WSAGetLastError();
if ((ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) &&
(ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_TCP) &&
(wsa_err == WSAENOTCONN || wsa_err == WSAENETRESET || wsa_err == WSAENOTSOCK ||
wsa_err == WSAESHUTDOWN || wsa_err == WSAECONNABORTED || wsa_err == WSAETIMEDOUT ||
wsa_err == WSAECONNRESET)) {
modbus_close(ctx);
modbus_connect(ctx);
}
#else
if ((ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) &&
(ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_TCP) &&
(errno == ECONNRESET || errno == ECONNREFUSED ||
errno == EBADF)) {
int saved_errno = errno;
Expand All @@ -418,6 +459,7 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
/* Could be removed by previous calls */
errno = saved_errno;
}
#endif
return -1;
}

Expand Down

0 comments on commit db1cbc5

Please sign in to comment.