|
|
|
@ -1,8 +1,9 @@ |
|
|
|
|
#!/usr/bin/env python3 |
|
|
|
|
import struct |
|
|
|
|
import traceback |
|
|
|
|
from typing import Any |
|
|
|
|
from typing import Any, List |
|
|
|
|
from collections import defaultdict |
|
|
|
|
from dataclasses import dataclass |
|
|
|
|
|
|
|
|
|
from tqdm import tqdm |
|
|
|
|
|
|
|
|
@ -90,92 +91,89 @@ SUBARU_VERSION_RESPONSE = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER + 0x40 |
|
|
|
|
p16(uds.DATA_IDENTIFIER_TYPE.APPLICATION_DATA_IDENTIFICATION) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# brand, request, response, response offset |
|
|
|
|
REQUESTS = [ |
|
|
|
|
@dataclass |
|
|
|
|
class Request: |
|
|
|
|
brand: str |
|
|
|
|
request: List[bytes] |
|
|
|
|
response: List[bytes] |
|
|
|
|
rx_offset: int = DEFAULT_RX_OFFSET |
|
|
|
|
bus: int = 1 |
|
|
|
|
|
|
|
|
|
REQUESTS: List[Request] = [ |
|
|
|
|
# Subaru |
|
|
|
|
( |
|
|
|
|
Request( |
|
|
|
|
"subaru", |
|
|
|
|
[TESTER_PRESENT_REQUEST, SUBARU_VERSION_REQUEST], |
|
|
|
|
[TESTER_PRESENT_RESPONSE, SUBARU_VERSION_RESPONSE], |
|
|
|
|
DEFAULT_RX_OFFSET, |
|
|
|
|
), |
|
|
|
|
# Hyundai |
|
|
|
|
( |
|
|
|
|
Request( |
|
|
|
|
"hyundai", |
|
|
|
|
[HYUNDAI_VERSION_REQUEST_LONG], |
|
|
|
|
[HYUNDAI_VERSION_RESPONSE], |
|
|
|
|
DEFAULT_RX_OFFSET, |
|
|
|
|
), |
|
|
|
|
( |
|
|
|
|
Request( |
|
|
|
|
"hyundai", |
|
|
|
|
[HYUNDAI_VERSION_REQUEST_MULTI], |
|
|
|
|
[HYUNDAI_VERSION_RESPONSE], |
|
|
|
|
DEFAULT_RX_OFFSET, |
|
|
|
|
), |
|
|
|
|
# Honda |
|
|
|
|
( |
|
|
|
|
Request( |
|
|
|
|
"honda", |
|
|
|
|
[UDS_VERSION_REQUEST], |
|
|
|
|
[UDS_VERSION_RESPONSE], |
|
|
|
|
DEFAULT_RX_OFFSET, |
|
|
|
|
), |
|
|
|
|
# Toyota |
|
|
|
|
( |
|
|
|
|
Request( |
|
|
|
|
"toyota", |
|
|
|
|
[SHORT_TESTER_PRESENT_REQUEST, TOYOTA_VERSION_REQUEST], |
|
|
|
|
[SHORT_TESTER_PRESENT_RESPONSE, TOYOTA_VERSION_RESPONSE], |
|
|
|
|
DEFAULT_RX_OFFSET, |
|
|
|
|
), |
|
|
|
|
( |
|
|
|
|
Request( |
|
|
|
|
"toyota", |
|
|
|
|
[SHORT_TESTER_PRESENT_REQUEST, OBD_VERSION_REQUEST], |
|
|
|
|
[SHORT_TESTER_PRESENT_RESPONSE, OBD_VERSION_RESPONSE], |
|
|
|
|
DEFAULT_RX_OFFSET, |
|
|
|
|
), |
|
|
|
|
( |
|
|
|
|
Request( |
|
|
|
|
"toyota", |
|
|
|
|
[TESTER_PRESENT_REQUEST, DEFAULT_DIAGNOSTIC_REQUEST, EXTENDED_DIAGNOSTIC_REQUEST, UDS_VERSION_REQUEST], |
|
|
|
|
[TESTER_PRESENT_RESPONSE, DEFAULT_DIAGNOSTIC_RESPONSE, EXTENDED_DIAGNOSTIC_RESPONSE, UDS_VERSION_RESPONSE], |
|
|
|
|
DEFAULT_RX_OFFSET, |
|
|
|
|
), |
|
|
|
|
# Volkswagen |
|
|
|
|
( |
|
|
|
|
Request( |
|
|
|
|
"volkswagen", |
|
|
|
|
[VOLKSWAGEN_VERSION_REQUEST_MULTI], |
|
|
|
|
[VOLKSWAGEN_VERSION_RESPONSE], |
|
|
|
|
VOLKSWAGEN_RX_OFFSET, |
|
|
|
|
rx_offset=VOLKSWAGEN_RX_OFFSET, |
|
|
|
|
), |
|
|
|
|
( |
|
|
|
|
Request( |
|
|
|
|
"volkswagen", |
|
|
|
|
[VOLKSWAGEN_VERSION_REQUEST_MULTI], |
|
|
|
|
[VOLKSWAGEN_VERSION_RESPONSE], |
|
|
|
|
DEFAULT_RX_OFFSET, |
|
|
|
|
), |
|
|
|
|
# Mazda |
|
|
|
|
( |
|
|
|
|
Request( |
|
|
|
|
"mazda", |
|
|
|
|
[MAZDA_VERSION_REQUEST], |
|
|
|
|
[MAZDA_VERSION_RESPONSE], |
|
|
|
|
DEFAULT_RX_OFFSET, |
|
|
|
|
), |
|
|
|
|
# Nissan |
|
|
|
|
( |
|
|
|
|
Request( |
|
|
|
|
"nissan", |
|
|
|
|
[NISSAN_DIAGNOSTIC_REQUEST_KWP, NISSAN_VERSION_REQUEST_KWP], |
|
|
|
|
[NISSAN_DIAGNOSTIC_RESPONSE_KWP, NISSAN_VERSION_RESPONSE_KWP], |
|
|
|
|
DEFAULT_RX_OFFSET, |
|
|
|
|
), |
|
|
|
|
( |
|
|
|
|
Request( |
|
|
|
|
"nissan", |
|
|
|
|
[NISSAN_DIAGNOSTIC_REQUEST_KWP, NISSAN_VERSION_REQUEST_KWP], |
|
|
|
|
[NISSAN_DIAGNOSTIC_RESPONSE_KWP, NISSAN_VERSION_RESPONSE_KWP], |
|
|
|
|
NISSAN_RX_OFFSET, |
|
|
|
|
rx_offset=NISSAN_RX_OFFSET, |
|
|
|
|
), |
|
|
|
|
( |
|
|
|
|
Request( |
|
|
|
|
"nissan", |
|
|
|
|
[NISSAN_VERSION_REQUEST_STANDARD], |
|
|
|
|
[NISSAN_VERSION_RESPONSE_STANDARD], |
|
|
|
|
NISSAN_RX_OFFSET, |
|
|
|
|
rx_offset=NISSAN_RX_OFFSET, |
|
|
|
|
), |
|
|
|
|
] |
|
|
|
|
|
|
|
|
@ -286,7 +284,7 @@ def match_fw_to_car(fw_versions, allow_fuzzy=True): |
|
|
|
|
return exact_match, matches |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_fw_versions(logcan, sendcan, bus, extra=None, timeout=0.1, debug=False, progress=False): |
|
|
|
|
def get_fw_versions(logcan, sendcan, extra=None, timeout=0.1, debug=False, progress=False): |
|
|
|
|
ecu_types = {} |
|
|
|
|
|
|
|
|
|
# Extract ECU addresses to query from fingerprints |
|
|
|
@ -317,12 +315,12 @@ def get_fw_versions(logcan, sendcan, bus, extra=None, timeout=0.1, debug=False, |
|
|
|
|
fw_versions = {} |
|
|
|
|
for i, addr in enumerate(tqdm(addrs, disable=not progress)): |
|
|
|
|
for addr_chunk in chunks(addr): |
|
|
|
|
for brand, request, response, response_offset in REQUESTS: |
|
|
|
|
for r in REQUESTS: |
|
|
|
|
try: |
|
|
|
|
addrs = [(a, s) for (b, a, s) in addr_chunk if b in (brand, 'any')] |
|
|
|
|
addrs = [(a, s) for (b, a, s) in addr_chunk if b in (r.brand, 'any')] |
|
|
|
|
|
|
|
|
|
if addrs: |
|
|
|
|
query = IsoTpParallelQuery(sendcan, logcan, bus, addrs, request, response, response_offset, debug=debug) |
|
|
|
|
query = IsoTpParallelQuery(sendcan, logcan, r.bus, addrs, r.request, r.response, r.rx_offset, debug=debug) |
|
|
|
|
t = 2 * timeout if i == 0 else timeout |
|
|
|
|
fw_versions.update(query.get_data(t)) |
|
|
|
|
except Exception: |
|
|
|
@ -379,7 +377,7 @@ if __name__ == "__main__": |
|
|
|
|
print() |
|
|
|
|
|
|
|
|
|
t = time.time() |
|
|
|
|
fw_vers = get_fw_versions(logcan, sendcan, 1, extra=extra, debug=args.debug, progress=True) |
|
|
|
|
fw_vers = get_fw_versions(logcan, sendcan, extra=extra, debug=args.debug, progress=True) |
|
|
|
|
_, candidates = match_fw_to_car(fw_vers) |
|
|
|
|
|
|
|
|
|
print() |
|
|
|
|