Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 13 additions & 34 deletions pymodbus/framer/ascii_framer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Ascii_framer."""
# pylint: disable=missing-type-doc
from binascii import a2b_hex

from pymodbus.exceptions import ModbusIOException
from pymodbus.framer.base import BYTE_ORDER, FRAME_HEADER, ModbusFramer
Expand Down Expand Up @@ -52,44 +51,24 @@ def decode_data(self, data):

def frameProcessIncomingPacket(self, single, callback, slave, _tid=None, **kwargs):
"""Process new packet pattern."""
def check_frame(self):
"""Check and decode the next frame."""
start = self._buffer.find(self._start)
if start == -1:
return False
if start > 0: # go ahead and skip old bad data
self._buffer = self._buffer[start:]
start = 0

if (end := self._buffer.find(self._end)) != -1:
self._header["len"] = end
self._header["uid"] = int(self._buffer[1:3], 16)
self._header["lrc"] = int(self._buffer[end - 2 : end], 16)
data = a2b_hex(self._buffer[start + 1 : end - 2])
return MessageAscii.check_LRC(data, self._header["lrc"])
return False

while len(self._buffer) > 1:
if not check_frame(self):
break
while len(self._buffer):
used_len, _tid, dev_id, data = self.message_handler.decode(self._buffer)
if not data:
if not used_len:
return
self._buffer = self._buffer[used_len :]
continue
self._header["uid"] = dev_id
if not self._validate_slave_id(slave, single):
header_txt = self._header["uid"]
Log.error("Not a valid slave id - {}, ignoring!!", header_txt)
Log.error("Not a valid slave id - {}, ignoring!!", dev_id)
self.resetFrame()
continue
return

start = self._hsize + 1
end = self._header["len"] - 2
buffer = self._buffer[start:end]
if end > 0:
frame = a2b_hex(buffer)
else:
frame = b""
if (result := self.decoder.decode(frame)) is None:
if (result := self.decoder.decode(data)) is None:
raise ModbusIOException("Unable to decode response")
self.populateResult(result)
self._buffer = self._buffer[self._header["len"] + 2 :]
self._header = {"lrc": "0000", "len": 0, "uid": 0x00}
self._buffer = self._buffer[used_len :]
self._header = {"uid": 0x00}
callback(result) # defer this

def buildPacket(self, message):
Expand Down
6 changes: 6 additions & 0 deletions test/transport/test_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,12 @@ async def test_handle_local_echo_partial(self, client):
assert client.recv_buffer == b"response"
assert not client.sent_buffer

async def test_handle_no_transport(self, client):
"""Test send()."""
client.transport = None
client.send(b"partial")
assert not client.sent_buffer


class TestTransportProtocol2:
"""Test transport module."""
Expand Down