You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							140 lines
						
					
					
						
							5.0 KiB
						
					
					
				
			
		
		
	
	
							140 lines
						
					
					
						
							5.0 KiB
						
					
					
				| #!/usr/bin/env python3
 | |
| # type: ignore
 | |
| 
 | |
| from collections import defaultdict
 | |
| import argparse
 | |
| import os
 | |
| import traceback
 | |
| from tqdm import tqdm
 | |
| from tools.lib.logreader import LogReader
 | |
| from selfdrive.car.fw_versions import match_fw_to_car
 | |
| from selfdrive.car.toyota.values import FW_VERSIONS as TOYOTA_FW_VERSIONS
 | |
| from selfdrive.car.honda.values import FW_VERSIONS as HONDA_FW_VERSIONS
 | |
| from selfdrive.car.hyundai.values import FW_VERSIONS as HYUNDAI_FW_VERSIONS
 | |
| from selfdrive.car.volkswagen.values import FW_VERSIONS as VW_FW_VERSIONS
 | |
| 
 | |
| from selfdrive.car.toyota.values import FINGERPRINTS as TOYOTA_FINGERPRINTS
 | |
| from selfdrive.car.honda.values import FINGERPRINTS as HONDA_FINGERPRINTS
 | |
| from selfdrive.car.hyundai.values import FINGERPRINTS as HYUNDAI_FINGERPRINTS
 | |
| from selfdrive.car.volkswagen.values import FINGERPRINTS as VW_FINGERPRINTS
 | |
| 
 | |
| SUPPORTED_CARS = list(TOYOTA_FINGERPRINTS.keys()) + list(HONDA_FINGERPRINTS.keys()) + list(HYUNDAI_FINGERPRINTS.keys())+ list(VW_FINGERPRINTS.keys())
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|   parser = argparse.ArgumentParser(description='Run FW fingerprint on Qlog of route or list of routes')
 | |
|   parser.add_argument('route', help='Route or file with list of routes')
 | |
|   parser.add_argument('--car', help='Force comparison fingerprint to known car')
 | |
|   args = parser.parse_args()
 | |
| 
 | |
|   if os.path.exists(args.route):
 | |
|     routes = list(open(args.route))
 | |
|   else:
 | |
|     routes = [args.route]
 | |
| 
 | |
|   mismatches = defaultdict(list)
 | |
| 
 | |
|   wrong = 0
 | |
|   good = 0
 | |
| 
 | |
|   dongles = []
 | |
|   for route in tqdm(routes):
 | |
|     route = route.rstrip()
 | |
|     dongle_id, time = route.split('|')
 | |
|     qlog_path = f"cd:/{dongle_id}/{time}/0/qlog.bz2"
 | |
| 
 | |
|     if dongle_id in dongles:
 | |
|       continue
 | |
| 
 | |
|     try:
 | |
|       lr = LogReader(qlog_path)
 | |
| 
 | |
|       for msg in lr:
 | |
|         if msg.which() == "pandaState":
 | |
|           if msg.pandaState.pandaType not in ['uno', 'blackPanda']:
 | |
|             dongles.append(dongle_id)
 | |
|             break
 | |
| 
 | |
|         elif msg.which() == "carParams":
 | |
|           bts = msg.carParams.as_builder().to_bytes()
 | |
| 
 | |
|           car_fw = msg.carParams.carFw
 | |
|           if len(car_fw) == 0:
 | |
|             break
 | |
| 
 | |
|           dongles.append(dongle_id)
 | |
|           live_fingerprint = msg.carParams.carFingerprint
 | |
| 
 | |
|           if args.car is not None:
 | |
|             live_fingerprint = args.car
 | |
| 
 | |
|           if live_fingerprint not in SUPPORTED_CARS:
 | |
|             break
 | |
| 
 | |
|           candidates = match_fw_to_car(car_fw)
 | |
|           if (len(candidates) == 1) and (list(candidates)[0] == live_fingerprint):
 | |
|             good += 1
 | |
|             print("Correct", live_fingerprint, dongle_id)
 | |
|             break
 | |
| 
 | |
|           print(f"{dongle_id}|{time}")
 | |
|           print("Old style:", live_fingerprint, "Vin", msg.carParams.carVin)
 | |
|           print("New style:", candidates)
 | |
| 
 | |
|           for version in car_fw:
 | |
|             subaddr = None if version.subAddress == 0 else hex(version.subAddress)
 | |
|             print(f"  (Ecu.{version.ecu}, {hex(version.address)}, {subaddr}): [{version.fwVersion}],")
 | |
| 
 | |
|           print("Mismatches")
 | |
|           found = False
 | |
|           for car_fws in [TOYOTA_FW_VERSIONS, HONDA_FW_VERSIONS, HYUNDAI_FW_VERSIONS, VW_FW_VERSIONS]:
 | |
|             if live_fingerprint in car_fws:
 | |
|               found = True
 | |
|               expected = car_fws[live_fingerprint]
 | |
|               for (_, expected_addr, expected_sub_addr), v in expected.items():
 | |
|                 for version in car_fw:
 | |
|                   sub_addr = None if version.subAddress == 0 else version.subAddress
 | |
|                   addr = version.address
 | |
| 
 | |
|                   if (addr, sub_addr) == (expected_addr, expected_sub_addr):
 | |
|                     if version.fwVersion not in v:
 | |
|                       print(f"({hex(addr)}, {'None' if sub_addr is None else hex(sub_addr)}) - {version.fwVersion}")
 | |
| 
 | |
|                       # Add to global list of mismatches
 | |
|                       mismatch = (addr, sub_addr, version.fwVersion)
 | |
|                       if mismatch not in mismatches[live_fingerprint]:
 | |
|                         mismatches[live_fingerprint].append(mismatch)
 | |
| 
 | |
|           # No FW versions for this car yet, add them all to mismatch list
 | |
|           if not found:
 | |
|             for version in car_fw:
 | |
|               sub_addr = None if version.subAddress == 0 else version.subAddress
 | |
|               addr = version.address
 | |
|               mismatch = (addr, sub_addr, version.fwVersion)
 | |
|               if mismatch not in mismatches[live_fingerprint]:
 | |
|                 mismatches[live_fingerprint].append(mismatch)
 | |
| 
 | |
|           print()
 | |
|           wrong += 1
 | |
|           break
 | |
|     except Exception:
 | |
|       traceback.print_exc()
 | |
|     except KeyboardInterrupt:
 | |
|       break
 | |
| 
 | |
|   print(f"Fingerprinted: {good} - Not fingerprinted: {wrong}")
 | |
|   print(f"Number of dongle ids checked: {len(dongles)}")
 | |
|   print()
 | |
| 
 | |
|   # Print FW versions that need to be added seperated out by car and address
 | |
|   for car, m in mismatches.items():
 | |
|     print(car)
 | |
|     addrs = defaultdict(list)
 | |
|     for (addr, sub_addr, version) in m:
 | |
|       addrs[(addr, sub_addr)].append(version)
 | |
| 
 | |
|     for (addr, sub_addr), versions in addrs.items():
 | |
|       print(f"  ({hex(addr)}, {'None' if sub_addr is None else hex(sub_addr)}): [")
 | |
|       for v in versions:
 | |
|         print(f"    {v},")
 | |
|       print("  ]")
 | |
|     print()
 | |
| 
 |