Skip to content

Commit 6878c3d

Browse files
Adds api to suppress echo
1 parent bb13443 commit 6878c3d

File tree

3 files changed

+86
-2
lines changed

3 files changed

+86
-2
lines changed

src/modbus-rtu-private.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ typedef struct _modbus_rtu {
7272
#endif
7373
/* To handle many slaves on the same link */
7474
int confirmation_to_ignore;
75+
/* software-side local echo suppression of sent bytes since hardware
76+
* does not support it or is configured to not do it */
77+
bool is_echo_suppressing;
7578
} modbus_rtu_t;
7679

7780
#endif /* MODBUS_RTU_PRIVATE_H */

src/modbus-rtu.c

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
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,42 @@ 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+
return write_size;
289+
}
290+
254291
static ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length)
255292
{
256293
#if defined(_WIN32)
@@ -272,15 +309,23 @@ static ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_lengt
272309
ctx_rtu->set_rts(ctx, ctx_rtu->rts == MODBUS_RTU_RTS_UP);
273310
usleep(ctx_rtu->rts_delay);
274311

275-
size = write(ctx->s, req, req_length);
312+
if (!ctx_rtu->is_echo_suppressing) {
313+
size = write(ctx->s, req, req_length);
314+
} else {
315+
size = _modbus_rtu_suppress_echo_write(ctx, req, req_length);
316+
}
276317

277318
usleep(ctx_rtu->onebyte_time * req_length + ctx_rtu->rts_delay);
278319
ctx_rtu->set_rts(ctx, ctx_rtu->rts != MODBUS_RTU_RTS_UP);
279320

280321
return size;
281322
} else {
282323
#endif
283-
return write(ctx->s, req, req_length);
324+
if (!ctx_rtu->is_echo_suppressing) {
325+
return write(ctx->s, req, req_length);
326+
} else {
327+
return _modbus_rtu_suppress_echo_write(ctx, req, req_length);
328+
}
284329
#if HAVE_DECL_TIOCM_RTS
285330
}
286331
#endif
@@ -1089,6 +1134,37 @@ int modbus_rtu_set_rts_delay(modbus_t *ctx, int us)
10891134
}
10901135
}
10911136

1137+
int modbus_rtu_set_suppress_echo(modbus_t* ctx, bool on) {
1138+
if (ctx == NULL) {
1139+
errno = EINVAL;
1140+
return -1;
1141+
}
1142+
1143+
if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
1144+
modbus_rtu_t* rtu = (modbus_rtu_t*) ctx->backend_data;
1145+
rtu->is_echo_suppressing = on;
1146+
return 0;
1147+
}
1148+
1149+
errno = EINVAL;
1150+
return -1;
1151+
}
1152+
1153+
int modbus_rtu_get_suppress_echo(modbus_t* ctx) {
1154+
if (ctx == NULL) {
1155+
errno = EINVAL;
1156+
return -1;
1157+
}
1158+
1159+
if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
1160+
modbus_rtu_t* rtu = (modbus_rtu_t*) ctx->backend_data;
1161+
return rtu->is_echo_suppressing;
1162+
}
1163+
1164+
errno = EINVAL;
1165+
return -1;
1166+
}
1167+
10921168
static void _modbus_rtu_close(modbus_t *ctx)
10931169
{
10941170
/* Restore line settings and close file descriptor in RTU mode */
@@ -1283,6 +1359,7 @@ modbus_new_rtu(const char *device, int baud, char parity, int data_bit, int stop
12831359
#endif
12841360

12851361
ctx_rtu->confirmation_to_ignore = FALSE;
1362+
ctx_rtu->is_echo_suppressing = FALSE;
12861363

12871364
return ctx;
12881365
}

src/modbus-rtu.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#ifndef MODBUS_RTU_H
88
#define MODBUS_RTU_H
99

10+
#include <stdbool.h>
1011
#include "modbus.h"
1112

1213
MODBUS_BEGIN_DECLS
@@ -40,4 +41,7 @@ MODBUS_API int modbus_rtu_get_rts_delay(modbus_t *ctx);
4041

4142
MODBUS_END_DECLS
4243

44+
int modbus_rtu_set_suppress_echo(modbus_t *ctx, bool on);
45+
int modbus_rtu_get_suppress_echo(modbus_t *ctx);
46+
4347
#endif /* MODBUS_RTU_H */

0 commit comments

Comments
 (0)