Revert "FPv2: fingerprint on all FW combinations (#25204)"

This reverts commit ee081f278b.
pull/25417/head
Shane Smiskol 3 years ago committed by GitHub
parent 24645c92da
commit bb68b7bc1c
  1. 52
      selfdrive/car/fw_versions.py
  2. 21
      selfdrive/debug/test_fw_query_on_routes.py

@ -238,13 +238,13 @@ def chunks(l, n=128):
def build_fw_dict(fw_versions, filter_brand=None):
fw_versions_dict = defaultdict(set)
fw_versions_dict = {}
for fw in fw_versions:
if filter_brand is None or fw.brand == filter_brand:
addr = fw.address
sub_addr = fw.subAddress if fw.subAddress != 0 else None
fw_versions_dict[(addr, sub_addr)].add(fw.fwVersion)
return dict(fw_versions_dict)
fw_versions_dict[(addr, sub_addr)] = fw.fwVersion
return fw_versions_dict
def get_brand_addrs():
@ -281,18 +281,17 @@ def match_fw_to_car_fuzzy(fw_versions_dict, log=True, exclude=None):
match_count = 0
candidate = None
for addr, versions in fw_versions_dict.items():
for version in versions:
# All cars that have this FW response on the specified address
candidates = all_fw_versions[(addr[0], addr[1], version)]
if len(candidates) == 1:
match_count += 1
if candidate is None:
candidate = candidates[0]
# We uniquely matched two different cars. No fuzzy match possible
elif candidate != candidates[0]:
return set()
for addr, version in fw_versions_dict.items():
# All cars that have this FW response on the specified address
candidates = all_fw_versions[(addr[0], addr[1], version)]
if len(candidates) == 1:
match_count += 1
if candidate is None:
candidate = candidates[0]
# We uniquely matched two different cars. No fuzzy match possible
elif candidate != candidates[0]:
return set()
if match_count >= 2:
if log:
@ -314,23 +313,23 @@ def match_fw_to_car_exact(fw_versions_dict):
for ecu, expected_versions in fws.items():
ecu_type = ecu[0]
addr = ecu[1:]
found_versions = fw_versions_dict.get(addr, set())
if ecu_type == Ecu.esp and candidate in (TOYOTA.RAV4, TOYOTA.COROLLA, TOYOTA.HIGHLANDER, TOYOTA.SIENNA, TOYOTA.LEXUS_IS) and not len(found_versions):
found_version = fw_versions_dict.get(addr, None)
if ecu_type == Ecu.esp and candidate in (TOYOTA.RAV4, TOYOTA.COROLLA, TOYOTA.HIGHLANDER, TOYOTA.SIENNA, TOYOTA.LEXUS_IS) and found_version is None:
continue
# On some Toyota models, the engine can show on two different addresses
if ecu_type == Ecu.engine and candidate in (TOYOTA.CAMRY, TOYOTA.COROLLA_TSS2, TOYOTA.CHR, TOYOTA.LEXUS_IS) and not len(found_versions):
if ecu_type == Ecu.engine and candidate in (TOYOTA.CAMRY, TOYOTA.COROLLA_TSS2, TOYOTA.CHR, TOYOTA.LEXUS_IS) and found_version is None:
continue
# Ignore non essential ecus
if ecu_type not in ESSENTIAL_ECUS and not len(found_versions):
if ecu_type not in ESSENTIAL_ECUS and found_version is None:
continue
# Virtual debug ecu doesn't need to match the database
if ecu_type == Ecu.debug:
continue
if not any([found_version in expected_versions for found_version in found_versions]):
if found_version not in expected_versions:
invalid.append(candidate)
break
@ -338,16 +337,19 @@ def match_fw_to_car_exact(fw_versions_dict):
def match_fw_to_car(fw_versions, allow_fuzzy=True):
versions = get_interface_attr('FW_VERSIONS', ignore_none=True)
# Try exact matching first
exact_matches = [(True, match_fw_to_car_exact)]
if allow_fuzzy:
exact_matches.append((False, match_fw_to_car_fuzzy))
for exact_match, match_func in exact_matches:
# TODO: For each brand, attempt to fingerprint using only FW returned from its queries
# For each brand, attempt to fingerprint using FW returned from its queries
matches = set()
fw_versions_dict = build_fw_dict(fw_versions, filter_brand=None)
matches |= match_func(fw_versions_dict)
for brand in versions.keys():
fw_versions_dict = build_fw_dict(fw_versions, filter_brand=brand)
matches |= match_func(fw_versions_dict)
if len(matches):
return exact_match, matches
@ -416,9 +418,7 @@ def get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, timeout=0.1, debug=Fa
for brand in sorted(brand_matches, key=lambda b: len(brand_matches[b]), reverse=True):
car_fw = get_fw_versions(logcan, sendcan, query_brand=brand, timeout=timeout, debug=debug, progress=progress)
all_car_fw.extend(car_fw)
# TODO: Until erroneous FW versions are removed, try to fingerprint on all possible combinations so far
_, matches = match_fw_to_car(all_car_fw, allow_fuzzy=False)
matches = match_fw_to_car_exact(build_fw_dict(car_fw))
if len(matches) == 1:
break

@ -89,9 +89,24 @@ if __name__ == "__main__":
print("not in supported cars")
break
fw_versions_dict = build_fw_dict(car_fw)
exact_matches = match_fw_to_car_exact(fw_versions_dict)
fuzzy_matches = match_fw_to_car_fuzzy(fw_versions_dict)
# Older routes only have carFw from their brand
old_route = not any([len(fw.brand) for fw in car_fw])
brands = SUPPORTED_BRANDS if not old_route else [None]
# Exact match
exact_matches, fuzzy_matches = [], []
for brand in brands:
fw_versions_dict = build_fw_dict(car_fw, filter_brand=brand)
exact_matches = match_fw_to_car_exact(fw_versions_dict)
if len(exact_matches) == 1:
break
# Fuzzy match
for brand in brands:
fw_versions_dict = build_fw_dict(car_fw, filter_brand=brand)
fuzzy_matches = match_fw_to_car_fuzzy(fw_versions_dict)
if len(fuzzy_matches) == 1:
break
if (len(exact_matches) == 1) and (list(exact_matches)[0] == live_fingerprint):
good_exact += 1

Loading…
Cancel
Save