Merge pull request #75 from dgoo2308/feature-reply-on-broadcast

This commit is contained in:
Victor Antonovich 2021-07-06 15:01:53 +03:00
commit 6a95a732d4
7 changed files with 36 additions and 7 deletions

View File

@ -94,6 +94,8 @@ Usage:
Specifies response wait time in milliseconds. Specifies response wait time in milliseconds.
-T timeout -T timeout
Specifies connection timeout value in seconds (0 disables 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! Please note running **mbusd** on default Modbus TCP port (502) requires root privileges!

View File

@ -45,3 +45,6 @@ pause = 100
# Response wait time in milliseconds # Response wait time in milliseconds
wait = 500 wait = 500
# Reply on Broadcast
#replyonbroadcast

View File

@ -36,6 +36,7 @@ mbusd \- MODBUS/TCP to MODBUS/RTU gateway.
.IR wait ] .IR wait ]
.RB [ -T .RB [ -T
.IR timeout ] .IR timeout ]
.RB [ -b ]
.SH DESCRIPTION .SH DESCRIPTION
\fImbusd\fR is MODBUS/TCP to MODBUS/RTU gateway. \fImbusd\fR is MODBUS/TCP to MODBUS/RTU gateway.
.SH OPTIONS .SH OPTIONS
@ -81,6 +82,8 @@ Specifies pause between requests in milliseconds.
Specifies response wait time in milliseconds. Specifies response wait time in milliseconds.
.IP "\fB-T \fItimeout\fR" .IP "\fB-T \fItimeout\fR"
Specifies connection timeout value in seconds (0 - disable timeout). Specifies connection timeout value in seconds (0 - disable timeout).
.IP "\fB-b\fR"
Instruct \fImbusd\fR to reply on a broadcast
.SH NOTES .SH NOTES
In case of situation when \fImbusd\fR received response with invalid CRC and can't correct 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 error by re-request, it return MODBUS/TCP packet with exception code 04. In case of situation

View File

@ -74,6 +74,7 @@ cfg_init(void)
cfg.rqstpause = DEFAULT_RQSTPAUSE; cfg.rqstpause = DEFAULT_RQSTPAUSE;
cfg.respwait = DEFAULT_RESPWAIT; cfg.respwait = DEFAULT_RESPWAIT;
cfg.conntimeout = DEFAULT_CONNTIMEOUT; cfg.conntimeout = DEFAULT_CONNTIMEOUT;
cfg.replyonbroadcast=0;
} }
static char * static char *
@ -171,6 +172,10 @@ cfg_handle_param(char *name, char *value)
CFG_ERR("invalid wait value: %s", value); CFG_ERR("invalid wait value: %s", value);
return 0; return 0;
} }
}
else if (CFG_NAME_MATCH("replyonbroadcast"))
{
cfg.replyonbroadcast = 1;
} }
else if (CFG_NAME_MATCH("timeout")) else if (CFG_NAME_MATCH("timeout"))
{ {

View File

@ -72,6 +72,8 @@ typedef struct
unsigned long rqstpause; unsigned long rqstpause;
/* response waiting time (in msec) */ /* response waiting time (in msec) */
unsigned long respwait; unsigned long respwait;
/* reply to client on broadcast */
int replyonbroadcast;
} cfg_t; } cfg_t;
/* Prototypes */ /* Prototypes */

View File

@ -560,12 +560,22 @@ conn_loop(void)
#endif #endif
if (!tty.txbuf[0]) if (!tty.txbuf[0])
{ {
/* broadcast request sent, no reply expected */
state_conn_set(actconn, CONN_HEADER);
state_tty_set(&tty, TTY_PAUSE);
#ifdef DEBUG #ifdef DEBUG
logw(5, "conn[%s]: broadcast request sent", curconn->remote_addr); logw(5, "conn[%s]: broadcast request sent", curconn->remote_addr);
#endif #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 else
{ {

View File

@ -112,7 +112,7 @@ usage(char *exename)
" [-t] [-y sysfsfile] [-Y sysfsfile]\n" " [-t] [-y sysfsfile] [-Y sysfsfile]\n"
#endif #endif
" [-A address] [-P port] [-C maxconn] [-N retries]\n" " [-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" "Options:\n"
" -h : this help\n" " -h : this help\n"
" -d : don't daemonize\n" " -d : don't daemonize\n"
@ -145,7 +145,8 @@ usage(char *exename)
" -W wait : set response wait time in milliseconds\n" " -W wait : set response wait time in milliseconds\n"
" (1-%d, default %lu)\n" " (1-%d, default %lu)\n"
" -T timeout : set connection timeout value in seconds\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, "\n", PACKAGE, VERSION, exename,
#ifdef LOG #ifdef LOG
LOGPATH, LOGNAME, cfg.dbglvl, LOGPATH, LOGNAME, cfg.dbglvl,
@ -154,7 +155,7 @@ usage(char *exename)
cfg.serveraddr, cfg.serverport, cfg.serveraddr, cfg.serverport,
MAX_MAXCONN, cfg.maxconn, MAX_MAXTRY, cfg.maxtry, MAX_MAXCONN, cfg.maxconn, MAX_MAXTRY, cfg.maxtry,
MAX_RQSTPAUSE, cfg.rqstpause, MAX_RESPWAIT, cfg.respwait, MAX_RQSTPAUSE, cfg.rqstpause, MAX_RESPWAIT, cfg.respwait,
MAX_CONNTIMEOUT, cfg.conntimeout); MAX_CONNTIMEOUT, cfg.conntimeout, cfg.replyonbroadcast);
exit(0); exit(0);
} }
@ -184,7 +185,7 @@ main(int argc, char *argv[])
#ifdef LOG #ifdef LOG
"v:L:" "v:L:"
#endif #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) switch (rc)
{ {
@ -350,6 +351,9 @@ main(int argc, char *argv[])
exit(-1); exit(-1);
} }
break; break;
case 'b':
cfg.replyonbroadcast = 1;
break;
case 'h': case 'h':
usage(exename); usage(exename);
break; break;