コード例 #1
0
ファイル: isotp_parallel_query.py プロジェクト: neokii/op4
    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.logcan = logcan
        self.bus = bus
        self.request = request
        self.response = response
        self.debug = debug
        self.functional_addr = functional_addr
        self.response_pending_timeout = response_pending_timeout

        self.real_addrs = []
        for a in addrs:
            if isinstance(a, tuple):
                self.real_addrs.append(a)
            else:
                self.real_addrs.append((a, None))

        self.msg_addrs = {
            tx_addr: get_rx_addr_for_tx_addr(tx_addr[0],
                                             rx_offset=response_offset)
            for tx_addr in self.real_addrs
        }
        self.msg_buffer = defaultdict(list)
コード例 #2
0
def get_present_ecus(logcan, sendcan):
    queries = list()
    parallel_queries = list()
    responses = set()
    versions = get_interface_attr('FW_VERSIONS', ignore_none=True)

    for r in REQUESTS:
        if r.brand not in versions:
            continue

        for brand_versions in versions[r.brand].values():
            for ecu_type, addr, sub_addr in brand_versions:
                # Only query ecus in whitelist if whitelist is not empty
                if len(r.whitelist_ecus) == 0 or ecu_type in r.whitelist_ecus:
                    a = (addr, sub_addr, r.bus)
                    # Build set of queries
                    if sub_addr is None:
                        if a not in parallel_queries:
                            parallel_queries.append(a)
                    else:  # subaddresses must be queried one by one
                        if [a] not in queries:
                            queries.append([a])

                    # Build set of expected responses to filter
                    response_addr = uds.get_rx_addr_for_tx_addr(
                        addr, r.rx_offset)
                    responses.add((response_addr, sub_addr, r.bus))

    queries.insert(0, parallel_queries)

    ecu_responses: Set[Tuple[int, Optional[int], int]] = set()
    for query in queries:
        ecu_responses.update(
            get_ecu_addrs(logcan, sendcan, set(query), responses, timeout=0.1))
    return ecu_responses
コード例 #3
0
def get_fw_versions(logcan, sendcan, extra=None, timeout=0.1, debug=False, progress=False):
  ecu_types = {}

  # Extract ECU addresses to query from fingerprints
  # ECUs using a subaddress need be queried one by one, the rest can be done in parallel
  addrs = []
  parallel_addrs = []

  versions = get_interface_attr('FW_VERSIONS', ignore_none=True)
  if extra is not None:
    versions.update(extra)

  for brand, brand_versions in versions.items():
    for c in brand_versions.values():
      for ecu_type, addr, sub_addr in c.keys():
        a = (brand, addr, sub_addr)
        if a not in ecu_types:
          ecu_types[(addr, sub_addr)] = ecu_type

        if sub_addr is None:
          if a not in parallel_addrs:
            parallel_addrs.append(a)
        else:
          if [a] not in addrs:
            addrs.append([a])

  addrs.insert(0, parallel_addrs)

  fw_versions = {}
  for i, addr in enumerate(tqdm(addrs, disable=not progress)):
    for addr_chunk in chunks(addr):
      for r in REQUESTS:
        try:
          addrs = [(a, s) for (b, a, s) in addr_chunk if b in (r.brand, 'any') and
                   (len(r.whitelist_ecus) == 0 or ecu_types[(a, s)] in r.whitelist_ecus)]

          if addrs:
            query = IsoTpParallelQuery(sendcan, logcan, r.bus, addrs, r.request, r.response, r.rx_offset, debug=debug)
            t = 2 * timeout if i == 0 else timeout
            fw_versions.update({addr: (version, r.request, r.rx_offset) for addr, version in query.get_data(t).items()})
        except Exception:
          cloudlog.warning(f"FW query exception: {traceback.format_exc()}")

  # Build capnp list to put into CarParams
  car_fw = []
  for addr, (version, request, rx_offset) in fw_versions.items():
    f = car.CarParams.CarFw.new_message()

    f.ecu = ecu_types[addr]
    f.fwVersion = version
    f.address = addr[0]
    f.responseAddress = uds.get_rx_addr_for_tx_addr(addr[0], rx_offset)
    f.request = request

    if addr[1] is not None:
      f.subAddress = addr[1]

    car_fw.append(f)

  return car_fw
コード例 #4
0
def get_brand_ecu_matches(ecu_rx_addrs):
    """Returns dictionary of brands and matches with ECUs in their FW versions"""

    brand_addrs = get_brand_addrs()
    brand_matches = {r.brand: set() for r in REQUESTS}

    brand_rx_offsets = set((r.brand, r.rx_offset) for r in REQUESTS)
    for addr, sub_addr, _ in ecu_rx_addrs:
        # Since we can't know what request an ecu responded to, add matches for all possible rx offsets
        for brand, rx_offset in brand_rx_offsets:
            a = (uds.get_rx_addr_for_tx_addr(addr, -rx_offset), sub_addr)
            if a in brand_addrs[brand]:
                brand_matches[brand].add(a)

    return brand_matches