handle response pending

pull/24724/head
Shane Smiskol 3 years ago
parent 921a411da5
commit 24776d7db9
  1. 23
      selfdrive/car/isotp_parallel_query.py

@ -10,7 +10,8 @@ from panda.python.uds import CanClient, IsoTpMessage, FUNCTIONAL_ADDRS, get_rx_a
class IsoTpParallelQuery: class IsoTpParallelQuery:
def __init__(self, sendcan, logcan, bus, addrs, request, response, response_offset=0x8, functional_addr=False, debug=False): def __init__(self, sendcan, logcan, bus, addrs, request, response, response_offset=0x8, functional_addr=False, debug=False,
response_pending_timeout=10):
self.sendcan = sendcan self.sendcan = sendcan
self.logcan = logcan self.logcan = logcan
self.bus = bus self.bus = bus
@ -18,6 +19,7 @@ class IsoTpParallelQuery:
self.response = response self.response = response
self.debug = debug self.debug = debug
self.functional_addr = functional_addr self.functional_addr = functional_addr
self.response_pending_timeout = response_pending_timeout
self.real_addrs = [] self.real_addrs = []
for a in addrs: for a in addrs:
@ -99,8 +101,8 @@ class IsoTpParallelQuery:
request_done[tx_addr] = False request_done[tx_addr] = False
results = {} results = {}
pending_responses = {} # keeps track of response pending times for proper timeouts
start_time = time.monotonic() start_time = time.monotonic()
last_response_time = start_time
while True: while True:
self.rx() self.rx()
@ -123,6 +125,7 @@ class IsoTpParallelQuery:
response_valid = dat[:len(expected_response)] == expected_response response_valid = dat[:len(expected_response)] == expected_response
if response_valid: if response_valid:
pending_responses.pop(tx_addr, None)
last_response_time = time.monotonic() last_response_time = time.monotonic()
if counter + 1 < len(self.request): if counter + 1 < len(self.request):
msg.send(self.request[counter + 1]) msg.send(self.request[counter + 1])
@ -131,16 +134,24 @@ class IsoTpParallelQuery:
results[tx_addr] = dat[len(expected_response):] results[tx_addr] = dat[len(expected_response):]
request_done[tx_addr] = True request_done[tx_addr] = True
else: else:
request_done[tx_addr] = True error_code = dat[2] if len(dat) > 2 else -1
cloudlog.warning(f"iso-tp query bad response: 0x{dat.hex()}") if error_code == 0x78:
pending_responses[tx_addr] = time.monotonic()
if self.debug:
cloudlog.warning(f"iso-tp query response pending: {hex(tx_addr)}")
else:
request_done[tx_addr] = True
cloudlog.warning(f"iso-tp query bad response: 0x{dat.hex()}")
cur_time = time.monotonic() cur_time = time.monotonic()
if cur_time - last_response_time > timeout: if (not len(pending_responses) and (cur_time - last_response_time > timeout)) or \
(len(pending_responses) and (cur_time - max(pending_responses.values()) > self.response_pending_timeout)):
for tx_addr in msgs: for tx_addr in msgs:
if (request_counter[tx_addr] > 0) and (not request_done[tx_addr]): if (request_counter[tx_addr] > 0 or pending_responses[tx_addr] != -1) and (not request_done[tx_addr]):
cloudlog.warning(f"iso-tp query timeout after receiving response: {tx_addr}") cloudlog.warning(f"iso-tp query timeout after receiving response: {tx_addr}")
break break
total_timeout = self.response_pending_timeout if len(pending_responses) else total_timeout
if cur_time - start_time > total_timeout: if cur_time - start_time > total_timeout:
cloudlog.warning("iso-tp query timeout while receiving data") cloudlog.warning("iso-tp query timeout while receiving data")
break break

Loading…
Cancel
Save