mirror of
https://github.com/3cky/mbusd.git
synced 2024-09-28 03:57:48 +02:00
Do not wait for a reply for RTU broadcast address #61
This commit is contained in:
parent
ad58141b87
commit
461ce8baa0
66
src/conn.c
66
src/conn.c
@ -468,8 +468,10 @@ conn_loop(void)
|
||||
#endif
|
||||
if (!tty.trynum) {
|
||||
modbus_ex_write(actconn->buf, MB_EX_CRC);
|
||||
#ifdef DEBUG
|
||||
logw(3, "tty: response is incorrect (%d of %d bytes, offset %d), return error", tty.ptrbuf,
|
||||
tty.rxoffset + tty.rxlen, tty.rxoffset);
|
||||
#endif
|
||||
} else
|
||||
{ /* retry request */
|
||||
#ifdef DEBUG
|
||||
@ -556,34 +558,46 @@ conn_loop(void)
|
||||
#ifdef DEBUG
|
||||
logw(7, "tty: request written (total %d bytes)", tty.txlen);
|
||||
#endif
|
||||
state_tty_set(&tty, TTY_RESP);
|
||||
switch (tty.txbuf[1]) {
|
||||
case 1:
|
||||
case 2:
|
||||
tty.rxlen = 5 + (tty.txbuf[4] * 256 + tty.txbuf[5] + 7)/8;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
tty.rxlen = 5 + tty.txbuf[5] * 2;
|
||||
break;
|
||||
case 7:
|
||||
tty.rxlen = 5;
|
||||
break;
|
||||
case 11:
|
||||
case 15:
|
||||
case 16:
|
||||
tty.rxlen = 8;
|
||||
break;
|
||||
default:
|
||||
tty.rxlen = tty.txlen;
|
||||
break;
|
||||
}
|
||||
if (tty.rxlen > TTY_BUFSIZE)
|
||||
tty.rxlen = TTY_BUFSIZE;
|
||||
tty.timer += DV(tty.rxlen, tty.bpc, tty.speed);
|
||||
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, "tty: estimated %d bytes, waiting %lu usec", tty.rxlen, tty.timer);
|
||||
logw(5, "conn[%s]: broadcast request sent", curconn->remote_addr);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
state_tty_set(&tty, TTY_RESP);
|
||||
switch (tty.txbuf[1]) {
|
||||
case 1:
|
||||
case 2:
|
||||
tty.rxlen = 5 + (tty.txbuf[4] * 256 + tty.txbuf[5] + 7)/8;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
tty.rxlen = 5 + tty.txbuf[5] * 2;
|
||||
break;
|
||||
case 7:
|
||||
tty.rxlen = 5;
|
||||
break;
|
||||
case 11:
|
||||
case 15:
|
||||
case 16:
|
||||
tty.rxlen = 8;
|
||||
break;
|
||||
default:
|
||||
tty.rxlen = tty.txlen;
|
||||
break;
|
||||
}
|
||||
if (tty.rxlen > TTY_BUFSIZE)
|
||||
tty.rxlen = TTY_BUFSIZE;
|
||||
tty.timer += DV(tty.rxlen, tty.bpc, tty.speed);
|
||||
#ifdef DEBUG
|
||||
logw(5, "tty: estimated %d bytes, waiting %lu usec", tty.rxlen, tty.timer);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ class ModbusSerialServer:
|
||||
#---------------------------------------------------------------------------#
|
||||
#StartTcpServer(context, identity=identity, address=("localhost", 5020))
|
||||
#StartUdpServer(context, identity=identity, address=("localhost", 502))
|
||||
StartSerialServer(context, identity=identity, port=self.serialPort, baudrate=19200, framer=framer)
|
||||
StartSerialServer(context, identity=identity, port=self.serialPort, baudrate=19200, framer=framer, broadcast_enable=True)
|
||||
#StartSerialServer(context, identity=identity, port='/dev/pts/3', framer=ModbusAsciiFramer)
|
||||
|
||||
p = None
|
||||
|
@ -33,7 +33,7 @@ class TestModbusRequests(unittest.TestCase):
|
||||
cls.mbs.start()
|
||||
|
||||
cls.log.debug("3. run mbusd to be tested with the binary:%s" % MBUSD_BINARY)
|
||||
cls.mbusd_main = Popen([MBUSD_BINARY, "-d", "-L", "-v9", "-p/tmp/pts0", "-s19200", "-P" + str(MBUSD_PORT)],
|
||||
cls.mbusd_main = Popen([MBUSD_BINARY, "-d", "-L/tmp/mbusd.log", "-v9", "-p/tmp/pts0", "-s19200", "-P" + str(MBUSD_PORT)],
|
||||
stdout=PIPE, stderr=STDOUT)
|
||||
# wait a little bit for mbusd to come up
|
||||
# alternatively do a poll for the socket
|
||||
@ -41,7 +41,7 @@ class TestModbusRequests(unittest.TestCase):
|
||||
sleep(5)
|
||||
|
||||
cls.log.debug("4. connect the modbus TCP client to mbusd")
|
||||
cls.client = ModbusTcpClient('127.0.0.1', port=MBUSD_PORT)
|
||||
cls.client = ModbusTcpClient('127.0.0.1', port=MBUSD_PORT, broadcast_enable=True)
|
||||
cls.client.connect()
|
||||
|
||||
@classmethod
|
||||
@ -62,35 +62,35 @@ class TestModbusRequests(unittest.TestCase):
|
||||
bits = [random.randrange(2)>0 for i in range(8)]
|
||||
|
||||
# 15 Write Multiple Coils
|
||||
result = self.client.write_coils(0, bits)
|
||||
result = self.client.write_coils(0, bits, unit=1)
|
||||
self.assertIsInstance(result, WriteMultipleCoilsResponse, result)
|
||||
self.assertEqual(result.address, 0, result)
|
||||
self.assertEqual(result.count, 8, result)
|
||||
|
||||
# 01 Read Coils
|
||||
result = self.client.read_coils(0, 8)
|
||||
result = self.client.read_coils(0, 8, unit=1)
|
||||
self.assertIsInstance(result, ReadCoilsResponse, result)
|
||||
self.assertEqual(result.bits, bits, result)
|
||||
|
||||
# 05 Write Single Coil
|
||||
bit1 = not bits[0]
|
||||
result = self.client.write_coil(0, bit1)
|
||||
result = self.client.write_coil(0, bit1, unit=1)
|
||||
self.assertIsInstance(result, WriteSingleCoilResponse, result)
|
||||
self.assertEqual(result.address, 0, result)
|
||||
self.assertEqual(result.value, bit1, result)
|
||||
result = self.client.read_coils(0, 1)
|
||||
result = self.client.read_coils(0, 1, unit=1)
|
||||
self.assertIsInstance(result, ReadCoilsResponse, result)
|
||||
self.assertEqual(result.bits[0], bit1, result)
|
||||
|
||||
def test_discreteInputs(self):
|
||||
# 02 Read Discrete Inputs
|
||||
result = self.client.read_discrete_inputs(0, 8)
|
||||
result = self.client.read_discrete_inputs(0, 8, unit=1)
|
||||
self.assertIsInstance(result, ReadDiscreteInputsResponse, result)
|
||||
self.assertEqual(result.bits, [True]*8, result)
|
||||
|
||||
def test_inputRegisters(self):
|
||||
# 04 Read Input Registers
|
||||
result = self.client.read_input_registers(0, 8)
|
||||
result = self.client.read_input_registers(0, 8, unit=1)
|
||||
self.assertIsInstance(result, ReadInputRegistersResponse, result)
|
||||
self.assertEqual(result.registers, list(range(8)), result)
|
||||
|
||||
@ -98,32 +98,42 @@ class TestModbusRequests(unittest.TestCase):
|
||||
registers = [random.randrange(8) for i in range(8)]
|
||||
|
||||
# 16 Write Multiple Holding Registers
|
||||
result = self.client.write_registers(0, registers)
|
||||
result = self.client.write_registers(0, registers, unit=1)
|
||||
self.assertIsInstance(result, WriteMultipleRegistersResponse, result)
|
||||
self.assertEqual(result.address, 0, result)
|
||||
self.assertEqual(result.count, 8, result)
|
||||
|
||||
# 03 Read Multiple Holding Registers
|
||||
result = self.client.read_holding_registers(0, 8)
|
||||
result = self.client.read_holding_registers(0, 8, unit=1)
|
||||
self.assertIsInstance(result, ReadHoldingRegistersResponse, result)
|
||||
self.assertEqual(result.registers, registers, result)
|
||||
|
||||
# 06 Write Single Holding Register
|
||||
register1 = (registers[0] + 1) % 65535
|
||||
result = self.client.write_register(0, register1)
|
||||
result = self.client.write_register(0, register1, unit=1)
|
||||
self.assertIsInstance(result, WriteSingleRegisterResponse, result)
|
||||
self.assertEqual(result.address, 0, result)
|
||||
self.assertEqual(result.value, register1, result)
|
||||
result = self.client.read_holding_registers(0, 1)
|
||||
result = self.client.read_holding_registers(0, 1, unit=1)
|
||||
self.assertIsInstance(result, ReadHoldingRegistersResponse, result)
|
||||
self.assertEqual(result.registers[0], register1, result)
|
||||
|
||||
def test_exception(self):
|
||||
result = self.client.write_coil(1000, False) # invalid address 1000
|
||||
result = self.client.write_coil(1000, False, unit=1) # invalid address 1000
|
||||
self.assertIsInstance(result, ExceptionResponse, result)
|
||||
self.assertEqual(result.original_code, 5, result) # fc05 Write Single Coil
|
||||
self.assertEqual(result.exception_code, 2, result) # Illegal Data Address
|
||||
|
||||
def test_broadcast(self):
|
||||
registers = [random.randrange(8) for i in range(8)]
|
||||
# 16 Write Multiple Holding Registers
|
||||
result = self.client.write_registers(0, registers, unit=0)
|
||||
|
||||
# 03 Read Multiple Holding Registers
|
||||
result = self.client.read_holding_registers(0, 8, unit=1)
|
||||
self.assertIsInstance(result, ReadHoldingRegistersResponse, result)
|
||||
self.assertEqual(result.registers, registers, result)
|
||||
|
||||
if __name__ == '__main__':
|
||||
stdout_handler = logging.StreamHandler(sys.stdout)
|
||||
logging.basicConfig(level=logging.DEBUG,
|
||||
|
Loading…
Reference in New Issue
Block a user