Commit db1cbc593501590eef16bbf9e0746290ac9116b9

Authored by Mohamed Amine Mzoughi
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  
... ...