diff --git a/selfdrive/car/volkswagen/tests/test_volkswagen.py b/selfdrive/car/volkswagen/tests/test_volkswagen.py index 92569e194e3e76..17331203bbe855 100755 --- a/selfdrive/car/volkswagen/tests/test_volkswagen.py +++ b/selfdrive/car/volkswagen/tests/test_volkswagen.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import random import re import unittest @@ -38,9 +39,9 @@ def test_chassis_codes(self): f"Shared chassis codes: {comp}") def test_custom_fuzzy_fingerprinting(self): - for platform in CAR: - expected_radar_fw = FW_VERSIONS[platform][Ecu.fwdRadar, 0x757, None] + all_radar_fw = list({fw for ecus in FW_VERSIONS.values() for fw in ecus[Ecu.fwdRadar, 0x757, None]}) + for platform in CAR: with self.subTest(platform=platform): for wmi in WMI: for chassis_code in platform.config.chassis_codes | {"00"}: @@ -50,9 +51,9 @@ def test_custom_fuzzy_fingerprinting(self): vin = "".join(vin) # Check a few FW cases - expected, unexpected - for radar_fw in expected_radar_fw + [b'\xf1\x877H9907572AA\xf1\x890396']: + for radar_fw in random.sample(all_radar_fw, 5) + [b'\xf1\x875Q0907572G \xf1\x890571', b'\xf1\x877H9907572AA\xf1\x890396']: should_match = ((wmi in platform.config.wmis and chassis_code in platform.config.chassis_codes) and - radar_fw in expected_radar_fw) + radar_fw in all_radar_fw) live_fws = {(0x757, None): [radar_fw]} matches = FW_QUERY_CONFIG.match_fw_to_car_fuzzy(live_fws, vin, FW_VERSIONS) diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index d25c52f225a93c..93473120eb341a 100644 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -1,4 +1,4 @@ -from collections import namedtuple +from collections import defaultdict, namedtuple from dataclasses import dataclass, field from enum import Enum, IntFlag, StrEnum @@ -433,19 +433,26 @@ class CAR(Platforms): def match_fw_to_car_fuzzy(live_fw_versions, vin, offline_fw_versions) -> set[str]: candidates = set() + # Compile all FW versions for each ECU + all_ecu_versions = defaultdict(set) + for ecus in offline_fw_versions.values(): + for ecu, versions in ecus.items(): + all_ecu_versions[ecu] |= set(versions) + # Check the WMI and chassis code to determine the platform wmi = vin[:3] chassis_code = vin[6:8] for platform in CAR: valid_ecus = set() - for ecu, expected_versions in offline_fw_versions[platform].items(): + for ecu in offline_fw_versions[platform]: addr = ecu[1:] if ecu[0] not in CHECK_FUZZY_ECUS: continue - # Sanity check that a subset of Volkswagen FW is in the database + # Sanity check that live FW is in the superset of all FW, Volkswagen ECU part numbers are commonly shared found_versions = live_fw_versions.get(addr, []) + expected_versions = all_ecu_versions[ecu] if not any(found_version in expected_versions for found_version in found_versions): break