Beispiel #1
0
  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
Beispiel #2
0
    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
Beispiel #3
0
    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