From b22ffa08569ac8e00b6402bc2652562261ae8ea1 Mon Sep 17 00:00:00 2001 From: Danny Date: Sat, 19 Jun 2021 12:37:55 +0700 Subject: [PATCH] feature-reply-on-broadcast --- README.md | 2 ++ conf/mbusd.conf.example | 3 +++ doc/mbusd.8.in | 3 +++ src/cfg.c | 5 +++++ src/cfg.h | 2 ++ src/conn.c | 16 +++++++++++++--- src/main.c | 12 ++++++++---- 7 files changed, 36 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3e1def3..21ed479 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,8 @@ Usage: Specifies response wait time in milliseconds. -T timeout Specifies connection timeout value in seconds (0 disables timeout). + -b + Reply on a Broadcast Please note running **mbusd** on default Modbus TCP port (502) requires root privileges! diff --git a/conf/mbusd.conf.example b/conf/mbusd.conf.example index dc2ada0..116d01c 100644 --- a/conf/mbusd.conf.example +++ b/conf/mbusd.conf.example @@ -45,3 +45,6 @@ pause = 100 # Response wait time in milliseconds wait = 500 + +# Reply on Broadcast +#replyonbroadcast diff --git a/doc/mbusd.8.in b/doc/mbusd.8.in index 7988241..27b147b 100644 --- a/doc/mbusd.8.in +++ b/doc/mbusd.8.in @@ -36,6 +36,7 @@ mbusd \- MODBUS/TCP to MODBUS/RTU gateway. .IR wait ] .RB [ -T .IR timeout ] +.RB [ -b ] .SH DESCRIPTION \fImbusd\fR is MODBUS/TCP to MODBUS/RTU gateway. .SH OPTIONS @@ -81,6 +82,8 @@ Specifies pause between requests in milliseconds. Specifies response wait time in milliseconds. .IP "\fB-T \fItimeout\fR" Specifies connection timeout value in seconds (0 - disable timeout). +.IP "\fB-b\fR" +Instruct \fImbusd\fR to reply on a broadcast .SH NOTES In case of situation when \fImbusd\fR received response with invalid CRC and can't correct error by re-request, it return MODBUS/TCP packet with exception code 04. In case of situation diff --git a/src/cfg.c b/src/cfg.c index d0c5bc8..3e2c6ae 100644 --- a/src/cfg.c +++ b/src/cfg.c @@ -74,6 +74,7 @@ cfg_init(void) cfg.rqstpause = DEFAULT_RQSTPAUSE; cfg.respwait = DEFAULT_RESPWAIT; cfg.conntimeout = DEFAULT_CONNTIMEOUT; + cfg.replyonbroadcast=0; } static char * @@ -171,6 +172,10 @@ cfg_handle_param(char *name, char *value) CFG_ERR("invalid wait value: %s", value); return 0; } + } + else if (CFG_NAME_MATCH("replyonbroadcast")) + { + cfg.replyonbroadcast = 1; } else if (CFG_NAME_MATCH("timeout")) { diff --git a/src/cfg.h b/src/cfg.h index 40d8af6..0f0033f 100644 --- a/src/cfg.h +++ b/src/cfg.h @@ -72,6 +72,8 @@ typedef struct unsigned long rqstpause; /* response waiting time (in msec) */ unsigned long respwait; + /* reply to client on broadcast */ + int replyonbroadcast; } cfg_t; /* Prototypes */ diff --git a/src/conn.c b/src/conn.c index 1ff7e9a..a9f17a3 100644 --- a/src/conn.c +++ b/src/conn.c @@ -560,12 +560,22 @@ conn_loop(void) #endif if (!tty.txbuf[0]) { - /* broadcast request sent, no reply expected */ - state_conn_set(actconn, CONN_HEADER); - state_tty_set(&tty, TTY_PAUSE); #ifdef DEBUG logw(5, "conn[%s]: broadcast request sent", curconn->remote_addr); #endif + /* broadcast request sent, no reply expected from TTY*/ + state_tty_set(&tty, TTY_PAUSE); + if (cfg.replyonbroadcast) + { + /* switch connection to response state, reply w actconn->buf */ + state_conn_set(actconn, CONN_RESP); + } + else + { + /* Done, ready for next */ + state_conn_set(actconn, CONN_HEADER); + } + } else { diff --git a/src/main.c b/src/main.c index e4cdeea..77eba44 100644 --- a/src/main.c +++ b/src/main.c @@ -112,7 +112,7 @@ usage(char *exename) " [-t] [-y sysfsfile] [-Y sysfsfile]\n" #endif " [-A address] [-P port] [-C maxconn] [-N retries]\n" - " [-R pause] [-W wait] [-T timeout]\n\n" + " [-R pause] [-W wait] [-T timeout] [-b]\n\n" "Options:\n" " -h : this help\n" " -d : don't daemonize\n" @@ -145,7 +145,8 @@ usage(char *exename) " -W wait : set response wait time in milliseconds\n" " (1-%d, default %lu)\n" " -T timeout : set connection timeout value in seconds\n" - " (0-%d, default %d, 0 - no timeout)" + " (0-%d, default %d, 0 - no timeout)\n" + " -b : reply on broadcast (default %d)" "\n", PACKAGE, VERSION, exename, #ifdef LOG LOGPATH, LOGNAME, cfg.dbglvl, @@ -154,7 +155,7 @@ usage(char *exename) cfg.serveraddr, cfg.serverport, MAX_MAXCONN, cfg.maxconn, MAX_MAXTRY, cfg.maxtry, MAX_RQSTPAUSE, cfg.rqstpause, MAX_RESPWAIT, cfg.respwait, - MAX_CONNTIMEOUT, cfg.conntimeout); + MAX_CONNTIMEOUT, cfg.conntimeout, cfg.replyonbroadcast); exit(0); } @@ -184,7 +185,7 @@ main(int argc, char *argv[]) #ifdef LOG "v:L:" #endif - "p:s:m:A:P:C:N:R:W:T:c:")) != RC_ERR) + "p:s:m:A:P:C:N:R:W:T:c:b")) != RC_ERR) { switch (rc) { @@ -350,6 +351,9 @@ main(int argc, char *argv[]) exit(-1); } break; + case 'b': + cfg.replyonbroadcast = 1; + break; case 'h': usage(exename); break;