@@ -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