99#include <stdio.h>
1010#include <stdlib.h>
1111#include <string.h>
12+ #include <time.h>
1213#ifndef _MSC_VER
1314#include <unistd.h>
1415#endif
@@ -251,6 +252,56 @@ static void _modbus_rtu_ioctl_rts(modbus_t *ctx, int on)
251252}
252253#endif
253254
255+ static ssize_t _modbus_rtu_suppress_echo_write (modbus_t * ctx , const uint8_t * req , int req_length ) {
256+ ssize_t write_size , read_size , count ;
257+ uint8_t req_echo [MODBUS_RTU_MAX_ADU_LENGTH ];
258+ time_t start_time ;
259+
260+ write_size = write (ctx -> s , req , req_length );
261+
262+ read_size = 0 ;
263+ count = 0 ;
264+ start_time = time (NULL );
265+ // Time limit the loop to 3 seconds in case the read continuously returns 0 bytes read
266+ while (read_size < write_size && difftime (time (NULL ), start_time ) < 3 )
267+ {
268+ count += read (ctx -> s , & req_echo [read_size ], write_size - read_size );
269+
270+ // return immediately on error
271+ if (count < 0 ) {
272+ return -1 ;
273+ }
274+
275+ read_size += count ;
276+ }
277+
278+ if (ctx -> debug )
279+ {
280+ printf ("Read back %d bytes echoed from the socket\n" , read_size );
281+ for (int i = 0 ; i < read_size ; i ++ )
282+ {
283+ fprintf (stderr , "|%02X|" , req_echo [i ]);
284+ }
285+ fprintf (stderr , "\n" );
286+ }
287+
288+ for (int i = 0 ; i < read_size ; i ++ )
289+ {
290+ if (req [i ] != req_echo [i ])
291+ {
292+ fprintf (stderr ,
293+ "ERROR: during echo suppression, sent 0x%02X for byte req[%d] of the request, read back 0x%02X for byte echo[%d] of the echo\n" ,
294+ req [i ],
295+ i ,
296+ req_echo [i ],
297+ i );
298+ return -1 ;
299+ }
300+ }
301+
302+ return write_size ;
303+ }
304+
254305static ssize_t _modbus_rtu_send (modbus_t * ctx , const uint8_t * req , int req_length )
255306{
256307#if defined(_WIN32 )
@@ -272,15 +323,23 @@ static ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_lengt
272323 ctx_rtu -> set_rts (ctx , ctx_rtu -> rts == MODBUS_RTU_RTS_UP );
273324 usleep (ctx_rtu -> rts_delay );
274325
275- size = write (ctx -> s , req , req_length );
326+ if (!ctx_rtu -> is_echo_suppressing ) {
327+ size = write (ctx -> s , req , req_length );
328+ } else {
329+ size = _modbus_rtu_suppress_echo_write (ctx , req , req_length );
330+ }
276331
277332 usleep (ctx_rtu -> onebyte_time * req_length + ctx_rtu -> rts_delay );
278333 ctx_rtu -> set_rts (ctx , ctx_rtu -> rts != MODBUS_RTU_RTS_UP );
279334
280335 return size ;
281336 } else {
282337#endif
283- return write (ctx -> s , req , req_length );
338+ if (!ctx_rtu -> is_echo_suppressing ) {
339+ return write (ctx -> s , req , req_length );
340+ } else {
341+ return _modbus_rtu_suppress_echo_write (ctx , req , req_length );
342+ }
284343#if HAVE_DECL_TIOCM_RTS
285344 }
286345#endif
@@ -1089,6 +1148,37 @@ int modbus_rtu_set_rts_delay(modbus_t *ctx, int us)
10891148 }
10901149}
10911150
1151+ int modbus_rtu_set_suppress_echo (modbus_t * ctx , bool on ) {
1152+ if (ctx == NULL ) {
1153+ errno = EINVAL ;
1154+ return -1 ;
1155+ }
1156+
1157+ if (ctx -> backend -> backend_type == _MODBUS_BACKEND_TYPE_RTU ) {
1158+ modbus_rtu_t * rtu = (modbus_rtu_t * ) ctx -> backend_data ;
1159+ rtu -> is_echo_suppressing = on ;
1160+ return 0 ;
1161+ }
1162+
1163+ errno = EINVAL ;
1164+ return -1 ;
1165+ }
1166+
1167+ int modbus_rtu_get_suppress_echo (modbus_t * ctx ) {
1168+ if (ctx == NULL ) {
1169+ errno = EINVAL ;
1170+ return -1 ;
1171+ }
1172+
1173+ if (ctx -> backend -> backend_type == _MODBUS_BACKEND_TYPE_RTU ) {
1174+ modbus_rtu_t * rtu = (modbus_rtu_t * ) ctx -> backend_data ;
1175+ return rtu -> is_echo_suppressing ;
1176+ }
1177+
1178+ errno = EINVAL ;
1179+ return -1 ;
1180+ }
1181+
10921182static void _modbus_rtu_close (modbus_t * ctx )
10931183{
10941184 /* Restore line settings and close file descriptor in RTU mode */
@@ -1283,6 +1373,7 @@ modbus_new_rtu(const char *device, int baud, char parity, int data_bit, int stop
12831373#endif
12841374
12851375 ctx_rtu -> confirmation_to_ignore = FALSE;
1376+ ctx_rtu -> is_echo_suppressing = FALSE;
12861377
12871378 return ctx ;
12881379}
0 commit comments