def get_data(self, timeout): self._drain_rx() # Create message objects msgs = {} request_counter = {} request_done = {} for tx_addr, rx_addr in self.msg_addrs.items(): # rx_addr not set when using functional tx addr id_addr = rx_addr or tx_addr[0] sub_addr = tx_addr[1] can_client = CanClient(self._can_tx, partial(self._can_rx, id_addr, sub_addr=sub_addr), tx_addr[0], rx_addr, self.bus, sub_addr=sub_addr, debug=self.debug) max_len = 8 if sub_addr is None else 7 msg = IsoTpMessage(can_client, timeout=0, max_len=max_len, debug=self.debug) msg.send(self.request[0]) msgs[tx_addr] = msg request_counter[tx_addr] = 0 request_done[tx_addr] = False results = {} start_time = time.time() while True: self.rx() if all(request_done.values()): break for tx_addr, msg in msgs.items(): dat = msg.recv() if not dat: continue counter = request_counter[tx_addr] expected_response = self.response[counter] response_valid = dat[:len(expected_response)] == expected_response if response_valid: if counter + 1 < len(self.request): msg.send(self.request[counter + 1]) request_counter[tx_addr] += 1 else: results[tx_addr] = dat[len(expected_response):] request_done[tx_addr] = True else: request_done[tx_addr] = True cloudlog.warning(f"iso-tp query bad response: 0x{bytes.hex(dat)}") if time.time() - start_time > timeout: break return results
def get_data(self, timeout, total_timeout=60.): self._drain_rx() # Create message objects msgs = {} request_counter = {} request_done = {} for tx_addr, rx_addr in self.msg_addrs.items(): # rx_addr not set when using functional tx addr id_addr = rx_addr or tx_addr[0] sub_addr = tx_addr[1] can_client = CanClient(self._can_tx, partial(self._can_rx, id_addr, sub_addr=sub_addr), tx_addr[0], rx_addr, self.bus, sub_addr=sub_addr, debug=self.debug) max_len = 8 if sub_addr is None else 7 msg = IsoTpMessage(can_client, timeout=0, max_len=max_len, debug=self.debug) msg.send(self.request[0]) msgs[tx_addr] = msg request_counter[tx_addr] = 0 request_done[tx_addr] = False results = {} start_time = time.monotonic() response_timeouts = { tx_addr: start_time + timeout for tx_addr in self.msg_addrs } while True: self.rx() if all(request_done.values()): break for tx_addr, msg in msgs.items(): try: dat: Optional[bytes] = msg.recv() except Exception: cloudlog.exception("Error processing UDS response") request_done[tx_addr] = True continue if not dat: continue counter = request_counter[tx_addr] expected_response = self.response[counter] response_valid = dat[:len(expected_response )] == expected_response if response_valid: response_timeouts[tx_addr] = time.monotonic() + timeout if counter + 1 < len(self.request): msg.send(self.request[counter + 1]) request_counter[tx_addr] += 1 else: results[tx_addr] = dat[len(expected_response):] request_done[tx_addr] = True else: error_code = dat[2] if len(dat) > 2 else -1 if error_code == 0x78: response_timeouts[tx_addr] = time.monotonic( ) + self.response_pending_timeout if self.debug: cloudlog.warning( f"iso-tp query response pending: {tx_addr}") else: request_done[tx_addr] = True cloudlog.warning( f"iso-tp query bad response: {tx_addr} - 0x{dat.hex()}" ) cur_time = time.monotonic() if cur_time - max(response_timeouts.values()) > 0: for tx_addr in msgs: if request_counter[tx_addr] > 0 and not request_done[ tx_addr]: cloudlog.warning( f"iso-tp query timeout after receiving response: {tx_addr}" ) break if cur_time - start_time > total_timeout: cloudlog.warning("iso-tp query timeout while receiving data") break return results
def get_data(self, timeout, total_timeout=None): if total_timeout is None: total_timeout = 10 * timeout self._drain_rx() # Create message objects msgs = {} request_counter = {} request_done = {} for tx_addr, rx_addr in self.msg_addrs.items(): # rx_addr not set when using functional tx addr id_addr = rx_addr or tx_addr[0] sub_addr = tx_addr[1] can_client = CanClient(self._can_tx, partial(self._can_rx, id_addr, sub_addr=sub_addr), tx_addr[0], rx_addr, self.bus, sub_addr=sub_addr, debug=self.debug) max_len = 8 if sub_addr is None else 7 msg = IsoTpMessage(can_client, timeout=0, max_len=max_len, debug=self.debug) msg.send(self.request[0]) msgs[tx_addr] = msg request_counter[tx_addr] = 0 request_done[tx_addr] = False results = {} start_time = time.monotonic() last_response_time = start_time while True: self.rx() if all(request_done.values()): break for tx_addr, msg in msgs.items(): dat: Optional[bytes] = msg.recv() if not dat: continue counter = request_counter[tx_addr] expected_response = self.response[counter] response_valid = dat[:len(expected_response )] == expected_response if response_valid: last_response_time = time.monotonic() if counter + 1 < len(self.request): msg.send(self.request[counter + 1]) request_counter[tx_addr] += 1 else: results[tx_addr] = dat[len(expected_response):] request_done[tx_addr] = True else: request_done[tx_addr] = True cloudlog.warning( f"iso-tp query bad response: 0x{dat.hex()}") cur_time = time.monotonic() if cur_time - last_response_time > timeout: for tx_addr in msgs: if (request_counter[tx_addr] > 0) and (not request_done[tx_addr]): cloudlog.warning( f"iso-tp query timeout after receiving response: {tx_addr}" ) break if cur_time - start_time > total_timeout: cloudlog.warning("iso-tp query timeout while receiving data") break return results