Skip to content

Commit

Permalink
Fixed #41. Timeout now raised when CF is not received after flow cont…
Browse files Browse the repository at this point in the history
…rol without waiting on next CAN msg.
  • Loading branch information
pylessard committed Mar 12, 2021
1 parent ecbf5c8 commit 4698f2f
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
15 changes: 9 additions & 6 deletions isotp/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,9 @@ def process(self):
Function to be called periodically, as fast as possible.
This function is non-blocking.
"""

self.check_timeouts_rx()

msg = True
while msg is not None:
msg = self.rxfn()
Expand All @@ -453,6 +456,12 @@ def process(self):
self.logger.debug("Sending : <%03X> (%d)\t %s" % (msg.arbitration_id, len(msg.data), binascii.hexlify(msg.data)))
self.txfn(msg)

def check_timeouts_rx(self):
# Check timeout first
if self.timer_rx_cf.is_timed_out():
self.trigger_error(isotp.errors.ConsecutiveFrameTimeoutError("Reception of CONSECUTIVE_FRAME timed out."))
self.stop_receiving()

def process_rx(self, msg):

if not self.address.is_for_me(msg):
Expand All @@ -466,11 +475,6 @@ def process_rx(self, msg):
self.stop_receiving()
return

# Check timeout first
if self.timer_rx_cf.is_timed_out():
self.trigger_error(isotp.errors.ConsecutiveFrameTimeoutError("Reception of CONSECUTIVE_FRAME timed out."))
self.stop_receiving()

# Process Flow Control message
if pdu.type == PDU.Type.FLOW_CONTROL:
self.last_flow_control_frame = pdu # Given to process_tx method. Queue of 1 message depth
Expand Down Expand Up @@ -587,7 +591,6 @@ def process_tx(self):


# ======= FSM ======

# Check this first as we may have another isotp frame to send and we need to handle it right away without waiting for next "process()" call
if self.tx_state != self.TxState.IDLE and len(self.tx_buffer) == 0:
self.stop_sending()
Expand Down
18 changes: 15 additions & 3 deletions test/test_transport_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,19 +235,31 @@ def test_receive_multiframe_bad_seqnum(self):
self.assertIsNone(self.get_tx_can_msg()) # Do not send flow control
self.assert_error_triggered(isotp.WrongSequenceNumberError)

def test_receive_timeout_consecutive_frame_after_flow_control(self):
self.stack.params.set('rx_consecutive_frame_timeout', 200)

payload_size = 10
payload = self.make_payload(payload_size)
self.simulate_rx(data = [0x10, payload_size] + payload[0:6])
self.stack.process()
time.sleep(0.2) # Should stop receivving after 200 msec
self.stack.process()
self.assertIsNone(self.rx_isotp_frame()) # No message received indeed
self.assert_error_triggered(isotp.ConsecutiveFrameTimeoutError)

def test_receive_timeout_consecutive_frame_after_first_frame(self):
self.stack.params.set('rx_consecutive_frame_timeout', 200)

payload_size = 10
payload = self.make_payload(payload_size)
self.simulate_rx(data = [0x10, payload_size] + payload[0:6])
self.stack.process()
time.sleep(0.2) # Should stop receivving after 200 msec
time.sleep(0.2) # Should stop receivving after 200 msec
self.simulate_rx(data = [0x21] + payload[6:10])
self.stack.process()
self.assertIsNone(self.rx_isotp_frame()) # No message received indeed
self.assertIsNone(self.rx_isotp_frame()) # No message received indeed
self.assert_error_triggered(isotp.ConsecutiveFrameTimeoutError)
self.assert_error_triggered(isotp.UnexpectedConsecutiveFrameError)
self.assert_error_triggered(isotp.UnexpectedConsecutiveFrameError)

def test_receive_recover_timeout_consecutive_frame(self):
self.stack.params.set('rx_consecutive_frame_timeout', 200)
Expand Down

0 comments on commit 4698f2f

Please sign in to comment.