Commit db1cbc593501590eef16bbf9e0746290ac9116b9
Committed by
Stéphane Raimbault
1 parent
06dc37ff
Fixed MODBUS_ERROR_RECOVERY_LINK not working on Windows.
Showing
1 changed file
with
44 additions
and
2 deletions
src/modbus.c
| ... | ... | @@ -182,7 +182,21 @@ static int send_msg(modbus_t *ctx, uint8_t *msg, int msg_length) |
| 182 | 182 | rc = ctx->backend->send(ctx, msg, msg_length); |
| 183 | 183 | if (rc == -1) { |
| 184 | 184 | _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 | |
| 186 | 200 | int saved_errno = errno; |
| 187 | 201 | |
| 188 | 202 | if ((errno == EBADF || errno == ECONNRESET || errno == EPIPE)) { |
| ... | ... | @@ -194,6 +208,7 @@ static int send_msg(modbus_t *ctx, uint8_t *msg, int msg_length) |
| 194 | 208 | modbus_flush(ctx); |
| 195 | 209 | } |
| 196 | 210 | errno = saved_errno; |
| 211 | +#endif | |
| 197 | 212 | } |
| 198 | 213 | } |
| 199 | 214 | } 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) |
| 345 | 360 | int length_to_read; |
| 346 | 361 | int msg_length = 0; |
| 347 | 362 | _step_t step; |
| 363 | +#ifdef _WIN32 | |
| 364 | + int wsa_err; | |
| 365 | +#endif | |
| 348 | 366 | |
| 349 | 367 | if (ctx->debug) { |
| 350 | 368 | if (msg_type == MSG_INDICATION) { |
| ... | ... | @@ -386,7 +404,17 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type) |
| 386 | 404 | rc = ctx->backend->select(ctx, &rset, p_tv, length_to_read); |
| 387 | 405 | if (rc == -1) { |
| 388 | 406 | _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 | |
| 390 | 418 | int saved_errno = errno; |
| 391 | 419 | |
| 392 | 420 | if (errno == ETIMEDOUT) { |
| ... | ... | @@ -397,6 +425,7 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type) |
| 397 | 425 | modbus_connect(ctx); |
| 398 | 426 | } |
| 399 | 427 | errno = saved_errno; |
| 428 | +#endif | |
| 400 | 429 | } |
| 401 | 430 | return -1; |
| 402 | 431 | } |
| ... | ... | @@ -409,7 +438,19 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type) |
| 409 | 438 | |
| 410 | 439 | if (rc == -1) { |
| 411 | 440 | _error_print(ctx, "read"); |
| 441 | +#ifdef _WIN32 | |
| 442 | + wsa_err = WSAGetLastError(); | |
| 412 | 443 | 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) && | |
| 413 | 454 | (errno == ECONNRESET || errno == ECONNREFUSED || |
| 414 | 455 | errno == EBADF)) { |
| 415 | 456 | int saved_errno = errno; |
| ... | ... | @@ -418,6 +459,7 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type) |
| 418 | 459 | /* Could be removed by previous calls */ |
| 419 | 460 | errno = saved_errno; |
| 420 | 461 | } |
| 462 | +#endif | |
| 421 | 463 | return -1; |
| 422 | 464 | } |
| 423 | 465 | ... | ... |