mirror of
https://github.com/3cky/mbusd.git
synced 2024-11-25 12:05:12 +01:00
modbus: read only a single frame at a time
When multiple modbus frames were queued in the socket buffer conn_read() would read until it completely drained the kernel's socket buffer or filled the connection buffer. The first modbus frame in the buffer is then processed and sent to the tty, then the buffer is reused for the reponse after it is received from the tty possibly overwritting any subsequent modbus request frames already read. Avoid this by maintaining pre-connection length to read, so we only read a single modbus frame at a time.
This commit is contained in:
parent
8a29a0e029
commit
5c064928ae
@ -767,7 +767,7 @@ conn_loop(void)
|
||||
{
|
||||
rc = conn_read(curconn->sd,
|
||||
curconn->buf + curconn->ctr,
|
||||
RQSTSIZE - curconn->ctr);
|
||||
curconn->read_len - curconn->ctr);
|
||||
if (rc <= 0)
|
||||
{ /* error - drop this connection and go to next queue element */
|
||||
curconn = conn_close(curconn);
|
||||
|
@ -105,6 +105,7 @@ typedef struct conn_t
|
||||
int timeout; /* timeout value, secs */
|
||||
struct sockaddr_in sockaddr; /* connection structure */
|
||||
int ctr; /* counter of data in the buffer */
|
||||
int read_len; /* length of modbus frame to read */
|
||||
unsigned char buf[HDRSIZE + BUFSIZE]; /* data buffer */
|
||||
} conn_t;
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
*/
|
||||
|
||||
#include "modbus.h"
|
||||
#include "conn.h"
|
||||
|
||||
/*
|
||||
* Check CRC of MODBUS frame
|
||||
@ -83,5 +84,6 @@ modbus_check_header(unsigned char *packet)
|
||||
return (MB_FRAME(packet, MB_PROTO_ID_H) == 0 &&
|
||||
MB_FRAME(packet, MB_PROTO_ID_L) == 0 &&
|
||||
MB_FRAME(packet, MB_LENGTH_H) == 0 &&
|
||||
MB_FRAME(packet, MB_LENGTH_L) > 0) ? RC_OK : RC_ERR;
|
||||
MB_FRAME(packet, MB_LENGTH_L) > 0 &&
|
||||
MB_FRAME(packet, MB_LENGTH_L) < BUFSIZE - CRCSIZE) ? RC_OK : RC_ERR;
|
||||
}
|
||||
|
@ -74,12 +74,14 @@ state_conn_set(conn_t *conn, int state)
|
||||
{
|
||||
case CONN_HEADER:
|
||||
conn->ctr = 0;
|
||||
conn->read_len = HDRSIZE;
|
||||
#ifdef DEBUG
|
||||
logw(5, "conn[%s]: state now is CONN_HEADER",
|
||||
inet_ntoa(conn->sockaddr.sin_addr));
|
||||
#endif
|
||||
break;
|
||||
case CONN_RQST_FUNC:
|
||||
conn->read_len = HDRSIZE + MB_FRAME(conn->buf, MB_LENGTH_L);
|
||||
#ifdef DEBUG
|
||||
logw(5, "conn[%s]: state now is CONN_RQST_FUNC",
|
||||
inet_ntoa(conn->sockaddr.sin_addr));
|
||||
|
Loading…
Reference in New Issue
Block a user