diff --git a/selfdrive/car/car_helpers.py b/selfdrive/car/car_helpers.py index 0e2443d330..92c221d616 100644 --- a/selfdrive/car/car_helpers.py +++ b/selfdrive/car/car_helpers.py @@ -139,7 +139,7 @@ def fingerprint(logcan, sendcan, num_pandas): # VIN query only reliably works through OBDII vin_rx_addr, vin_rx_bus, vin = get_vin(logcan, sendcan, (0, 1)) ecu_rx_addrs = get_present_ecus(logcan, sendcan, num_pandas=num_pandas) - car_fw = get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, num_pandas=num_pandas) + car_fw = get_fw_versions_ordered(logcan, sendcan, vin, ecu_rx_addrs, num_pandas=num_pandas) cached = False exact_fw_match, fw_candidates = match_fw_to_car(car_fw) @@ -148,6 +148,7 @@ def fingerprint(logcan, sendcan, num_pandas): exact_fw_match, fw_candidates, car_fw = True, set(), [] cached = False + # TODO: move up? if not is_valid_vin(vin): cloudlog.event("Malformed VIN", vin=vin, error=True) vin = VIN_UNKNOWN diff --git a/selfdrive/car/fw_versions.py b/selfdrive/car/fw_versions.py index d7444ebf7d..4b360620e3 100755 --- a/selfdrive/car/fw_versions.py +++ b/selfdrive/car/fw_versions.py @@ -144,8 +144,8 @@ def match_fw_to_car_exact(live_fw_versions: LiveFwVersions, match_brand: str = N return set(candidates.keys()) - invalid -def match_fw_to_car(fw_versions: list[capnp.lib.capnp._DynamicStructBuilder], allow_exact: bool = True, allow_fuzzy: bool = True, - log: bool = True) -> tuple[bool, set[str]]: +def match_fw_to_car(fw_versions: list[capnp.lib.capnp._DynamicStructBuilder], vin: str, allow_exact: bool = True, + allow_fuzzy: bool = True, log: bool = True) -> tuple[bool, set[str]]: # Try exact matching first exact_matches: list[tuple[bool, MatchFwToCar]] = [] if allow_exact: @@ -158,12 +158,18 @@ def match_fw_to_car(fw_versions: list[capnp.lib.capnp._DynamicStructBuilder], al matches: set[str] = set() for brand in VERSIONS.keys(): fw_versions_dict = build_fw_dict(fw_versions, filter_brand=brand) - matches |= match_func(fw_versions_dict, match_brand=brand, log=log) + cur_matches = match_func(fw_versions_dict, match_brand=brand, log=log) # If specified and no matches so far, fall back to brand's fuzzy fingerprinting function config = FW_QUERY_CONFIGS[brand] - if not exact_match and not len(matches) and config.match_fw_to_car_fuzzy is not None: - matches |= config.match_fw_to_car_fuzzy(fw_versions_dict, VERSIONS[brand]) + if not exact_match and not len(cur_matches) and config.match_fw_to_car_fuzzy is not None: + cur_matches |= config.match_fw_to_car_fuzzy(fw_versions_dict, VERSIONS[brand]) + + # FIXME: this is super ugly + if len(cur_matches) != 1 and config.match_fw_to_car_custom is not None: + cur_matches = config.match_fw_to_car_custom(fw_versions_dict, vin, VERSIONS[brand]) + + matches |= cur_matches if len(matches): return exact_match, matches @@ -237,7 +243,7 @@ def set_obd_multiplexing(params: Params, obd_multiplexing: bool): cloudlog.warning("OBD multiplexing set successfully") -def get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs: set[EcuAddrBusType], timeout: float = 0.1, num_pandas: int = 1, +def get_fw_versions_ordered(logcan, sendcan, vin: str, ecu_rx_addrs: set[EcuAddrBusType], timeout: float = 0.1, num_pandas: int = 1, debug: bool = False, progress: bool = False) -> list[capnp.lib.capnp._DynamicStructBuilder]: """Queries for FW versions ordering brands by likelihood, breaks when exact match is found""" @@ -253,7 +259,7 @@ def get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs: set[EcuAddrBusType], all_car_fw.extend(car_fw) # If there is a match using this brand's FW alone, finish querying early - _, matches = match_fw_to_car(car_fw, log=False) + _, matches = match_fw_to_car(car_fw, vin, log=False) if len(matches) == 1: break