66from threading import RLock
77
88from pymodbus .exceptions import ModbusIOException , NotImplementedException
9- from pymodbus .exceptions import InvalidMessageRecievedException
9+ from pymodbus .exceptions import InvalidMessageReceivedException
1010from pymodbus .constants import Defaults
1111from pymodbus .framer .ascii_framer import ModbusAsciiFramer
1212from pymodbus .framer .rtu_framer import ModbusRtuFramer
@@ -74,14 +74,9 @@ def _set_adu_size(self):
7474 self .base_adu_size = 7 # start(1)+ Address(2), LRC(2) + end(2)
7575 elif isinstance (self .client .framer , ModbusBinaryFramer ):
7676 self .base_adu_size = 5 # start(1) + Address(1), CRC(2) + end(1)
77- else :
78- self .base_adu_size = - 1
7977
8078 def _calculate_response_length (self , expected_pdu_size ):
81- if self .base_adu_size == - 1 :
82- return None
83- else :
84- return self .base_adu_size + expected_pdu_size
79+ return self .base_adu_size + expected_pdu_size
8580
8681 def _calculate_exception_length (self ):
8782 ''' Returns the length of the Modbus Exception Response according to
@@ -94,8 +89,6 @@ def _calculate_exception_length(self):
9489 elif isinstance (self .client .framer , (ModbusRtuFramer , ModbusBinaryFramer )):
9590 return self .base_adu_size + 2 # Fcode(1), ExcecptionCode(1)
9691
97- return None
98-
9992 def _check_response (self , response ):
10093 ''' Checks if the response is a Modbus Exception.
10194 '''
@@ -208,11 +201,11 @@ def _transact(self, packet, response_length, full=False):
208201 _logger .debug ("Changing transaction state from 'SENDING' "
209202 "to 'WAITING FOR REPLY'" )
210203 self .client .state = ModbusTransactionState .WAITING_FOR_REPLY
211- result = self ._recv (response_length or 1024 , full )
204+ result = self ._recv (response_length , full )
212205 if _logger .isEnabledFor (logging .DEBUG ):
213206 _logger .debug ("RECV: " + hexlify_packets (result ))
214207 except (socket .error , ModbusIOException ,
215- InvalidMessageRecievedException ) as msg :
208+ InvalidMessageReceivedException ) as msg :
216209 self .client .close ()
217210 _logger .debug ("Transaction failed. (%s) " % msg )
218211 last_exception = msg
@@ -223,7 +216,6 @@ def _send(self, packet):
223216 return self .client .framer .sendPacket (packet )
224217
225218 def _recv (self , expected_response_length , full ):
226- expected_response_length = expected_response_length or 1024
227219 if not full :
228220 exception_length = self ._calculate_exception_length ()
229221 if isinstance (self .client .framer , ModbusSocketFramer ):
@@ -238,31 +230,37 @@ def _recv(self, expected_response_length, full):
238230 min_size = expected_response_length
239231
240232 read_min = self .client .framer .recvPacket (min_size )
241- if read_min :
233+ if not read_min :
234+ return read_min
235+
236+ if len (read_min ) < min_size :
237+ raise InvalidMessageReceivedException (
238+ "Incomplete message received, expected at least %d bytes (%d received)"
239+ % (min_size , len (read_min )))
240+
241+ if isinstance (self .client .framer , ModbusSocketFramer ):
242+ func_code = byte2int (read_min [- 1 ])
243+ elif isinstance (self .client .framer , ModbusRtuFramer ):
244+ func_code = byte2int (read_min [- 1 ])
245+ elif isinstance (self .client .framer , ModbusAsciiFramer ):
246+ func_code = int (read_min [3 :5 ], 16 )
247+ elif isinstance (self .client .framer , ModbusBinaryFramer ):
248+ func_code = byte2int (read_min [- 1 ])
249+ else :
250+ func_code = - 1
251+
252+ if func_code < 0x80 : # Not an error
242253 if isinstance (self .client .framer , ModbusSocketFramer ):
243- func_code = byte2int (read_min [- 1 ])
244- elif isinstance (self .client .framer , ModbusRtuFramer ):
245- func_code = byte2int (read_min [- 1 ])
246- elif isinstance (self .client .framer , ModbusAsciiFramer ):
247- func_code = int (read_min [3 :5 ], 16 )
248- elif isinstance (self .client .framer , ModbusBinaryFramer ):
249- func_code = byte2int (read_min [- 1 ])
250- else :
251- func_code = - 1
252-
253- if func_code < 0x80 : # Not an error
254- if isinstance (self .client .framer , ModbusSocketFramer ):
255- # Ommit UID, which is included in header size
256- h_size = self .client .framer ._hsize
257- length = struct .unpack (">H" , read_min [4 :6 ])[0 ] - 1
258- expected_response_length = h_size + length
259- expected_response_length -= min_size
260- total = expected_response_length + min_size
261- else :
262- expected_response_length = exception_length - min_size
263- total = expected_response_length + min_size
254+ # Ommit UID, which is included in header size
255+ h_size = self .client .framer ._hsize
256+ length = struct .unpack (">H" , read_min [4 :6 ])[0 ] - 1
257+ expected_response_length = h_size + length
258+ expected_response_length -= min_size
259+ total = expected_response_length + min_size
264260 else :
265- total = expected_response_length
261+ expected_response_length = exception_length - min_size
262+ total = expected_response_length + min_size
263+
266264 else :
267265 read_min = b''
268266 total = expected_response_length
@@ -273,6 +271,9 @@ def _recv(self, expected_response_length, full):
273271 _logger .debug ("Incomplete message received, "
274272 "Expected {} bytes Recieved "
275273 "{} bytes !!!!" .format (total , actual ))
274+ raise InvalidMessageReceivedException (
275+ "Incomplete message received, %d bytes expected (%d received)"
276+ % (total , actual ))
276277 if self .client .state != ModbusTransactionState .PROCESSING_REPLY :
277278 _logger .debug ("Changing transaction state from "
278279 "'WAITING FOR REPLY' to 'PROCESSING REPLY'" )
0 commit comments