9
9
#include <stdio.h>
10
10
#include <stdlib.h>
11
11
#include <string.h>
12
+ #include <time.h>
12
13
#ifndef _MSC_VER
13
14
#include <unistd.h>
14
15
#endif
@@ -251,6 +252,56 @@ static void _modbus_rtu_ioctl_rts(modbus_t *ctx, int on)
251
252
}
252
253
#endif
253
254
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
+
254
305
static ssize_t _modbus_rtu_send (modbus_t * ctx , const uint8_t * req , int req_length )
255
306
{
256
307
#if defined(_WIN32 )
@@ -272,15 +323,23 @@ static ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_lengt
272
323
ctx_rtu -> set_rts (ctx , ctx_rtu -> rts == MODBUS_RTU_RTS_UP );
273
324
usleep (ctx_rtu -> rts_delay );
274
325
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
+ }
276
331
277
332
usleep (ctx_rtu -> onebyte_time * req_length + ctx_rtu -> rts_delay );
278
333
ctx_rtu -> set_rts (ctx , ctx_rtu -> rts != MODBUS_RTU_RTS_UP );
279
334
280
335
return size ;
281
336
} else {
282
337
#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
+ }
284
343
#if HAVE_DECL_TIOCM_RTS
285
344
}
286
345
#endif
@@ -1089,6 +1148,37 @@ int modbus_rtu_set_rts_delay(modbus_t *ctx, int us)
1089
1148
}
1090
1149
}
1091
1150
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
+
1092
1182
static void _modbus_rtu_close (modbus_t * ctx )
1093
1183
{
1094
1184
/* 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
1283
1373
#endif
1284
1374
1285
1375
ctx_rtu -> confirmation_to_ignore = FALSE;
1376
+ ctx_rtu -> is_echo_suppressing = FALSE;
1286
1377
1287
1378
return ctx ;
1288
1379
}
0 commit comments