From 2909adb643207b557ac7826d4092cbea9c2d24d1 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Mon, 5 Jun 2023 21:36:19 -0700 Subject: [PATCH] draft (need to count one ecu as a match) --- selfdrive/car/fw_versions.py | 114 +++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 44 deletions(-) diff --git a/selfdrive/car/fw_versions.py b/selfdrive/car/fw_versions.py index 17095beaa7..5cd4814ebf 100755 --- a/selfdrive/car/fw_versions.py +++ b/selfdrive/car/fw_versions.py @@ -48,50 +48,50 @@ def get_brand_addrs() -> Dict[str, Set[Tuple[int, Optional[int]]]]: return dict(brand_addrs) -def match_fw_to_car_fuzzy_orig(fw_versions_dict, log=True, exclude=None): - """Do a fuzzy FW match. This function will return a match, and the number of firmware version - that were matched uniquely to that specific car. If multiple ECUs uniquely match to different cars - the match is rejected.""" - - # These ECUs are known to be shared between models (EPS only between hybrid/ICE version) - # Getting this exactly right isn't crucial, but excluding camera and radar makes it almost - # impossible to get 3 matching versions, even if two models with shared parts are released at the same - # time and only one is in our database. - exclude_types = [Ecu.fwdCamera, Ecu.fwdRadar, Ecu.eps, Ecu.debug] - - # Build lookup table from (addr, sub_addr, fw) to list of candidate cars - all_fw_versions = defaultdict(list) - for candidate, fw_by_addr in FW_VERSIONS.items(): - if candidate == exclude: - continue - - for addr, fws in fw_by_addr.items(): - if addr[0] in exclude_types: - continue - for f in fws: - all_fw_versions[(addr[1], addr[2], f)].append(candidate) - - 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() - - if match_count >= 2: - if log: - cloudlog.error(f"Fingerprinted {candidate} using fuzzy match. {match_count} matching ECUs") - return {candidate} - else: - return set() +# def match_fw_to_car_fuzzy_orig(fw_versions_dict, log=True, exclude=None): +# """Do a fuzzy FW match. This function will return a match, and the number of firmware version +# that were matched uniquely to that specific car. If multiple ECUs uniquely match to different cars +# the match is rejected.""" +# +# # These ECUs are known to be shared between models (EPS only between hybrid/ICE version) +# # Getting this exactly right isn't crucial, but excluding camera and radar makes it almost +# # impossible to get 3 matching versions, even if two models with shared parts are released at the same +# # time and only one is in our database. +# exclude_types = [Ecu.fwdCamera, Ecu.fwdRadar, Ecu.eps, Ecu.debug] +# +# # Build lookup table from (addr, sub_addr, fw) to list of candidate cars +# all_fw_versions = defaultdict(list) +# for candidate, fw_by_addr in FW_VERSIONS.items(): +# if candidate == exclude: +# continue +# +# for addr, fws in fw_by_addr.items(): +# if addr[0] in exclude_types: +# continue +# for f in fws: +# all_fw_versions[(addr[1], addr[2], f)].append(candidate) +# +# 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() +# +# if match_count >= 2: +# if log: +# cloudlog.error(f"Fingerprinted {candidate} using fuzzy match. {match_count} matching ECUs") +# return {candidate} +# else: +# return set() def match_fw_to_car_fuzzy(fw_versions_dict, config, log=True, exclude=None): @@ -125,20 +125,32 @@ def match_fw_to_car_fuzzy(fw_versions_dict, config, log=True, exclude=None): for platform_code in config.fuzzy_get_platform_codes(fws): all_platform_codes[(addr[1], addr[2], platform_code)].append(candidate) + matches = defaultdict(set) match_count = 0 candidate = None + print('herererer') + print(fw_versions_dict) 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)] + # matches[(addr[0], addr[1])] |= candidates + print(candidates) # If no exact FW matches, try brand-specific fuzzy fingerprinting if len(candidates) != 1 and config.fuzzy_get_platform_codes is not None: + print('no candidates, trying hkg') platform_codes = config.fuzzy_get_platform_codes([version]) + print(addr, version, platform_codes) if len(platform_codes) == 1: + print('one platform code') platform_code = list(platform_codes)[0] candidates = all_platform_codes[(addr[0], addr[1], platform_code)] + # matches[(addr[0], addr[1])] |= candidates + print('candidates', candidates) + matches[(addr[0], addr[1])] |= set(candidates) + print() if len(candidates) == 1: match_count += 1 if candidate is None: @@ -147,6 +159,20 @@ def match_fw_to_car_fuzzy(fw_versions_dict, config, log=True, exclude=None): elif candidate != candidates[0]: return set() + print('matches', matches) + if len(matches) > 0: + candidates = set.union(*matches.values()) + + print('final candidates', candidates) + print('final matches', dict(matches)) + + else: + return set() + + # for addr, candidates in matches.items(): + # if + # print(addr, candidates) + if match_count >= config.fuzzy_min_match_count: if log: cloudlog.error(f"Fingerprinted {candidate} using fuzzy match. {match_count} matching ECUs")