From 5968a0620ef7d16703b774afac3425389012fc63 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Mon, 19 Oct 2026 00:47:35 -0500 Subject: [PATCH] Restore Subaru Firmware Recognition --- .../opendbc/car/subaru/fingerprints.py | 39 +++++++++++ .../subaru/tests/test_supported_firmware.py | 69 +++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 opendbc_repo/opendbc/car/subaru/tests/test_supported_firmware.py diff --git a/opendbc_repo/opendbc/car/subaru/fingerprints.py b/opendbc_repo/opendbc/car/subaru/fingerprints.py index 00fe7192ef..057e3b0824 100644 --- a/opendbc_repo/opendbc/car/subaru/fingerprints.py +++ b/opendbc_repo/opendbc/car/subaru/fingerprints.py @@ -37,18 +37,24 @@ FW_VERSIONS = { CAR.SUBARU_ASCENT_2023: { (Ecu.abs, 0x7b0, None): [ b'\xa5 #\x03\x00', + b'\xa5 %\x03\x01', ], (Ecu.eps, 0x746, None): [ b'%\xc0\xd0\x11', + b'U\xc0\xd0\x10', ], (Ecu.fwdCamera, 0x787, None): [ b'\x05!\x08\x1dK\x05!\x08\x01/', + b'\x17!\x08\x01A\x12!\x08\x00;', + b'\x17!\x08\x01A\x00\x00\x00\x00\x00', ], (Ecu.engine, 0x7a2, None): [ b'\xe5,\xa0P\x07', + b'\x11,\xa00\x07', ], (Ecu.transmission, 0x7a3, None): [ b'\x04\xfe\xf3\x00\x00', + b'\x05\xfe\xe7\x00\x00', ], }, CAR.SUBARU_LEGACY: { @@ -587,4 +593,37 @@ FW_VERSIONS = { b'\xa8\xfe\xf41\x00', ], }, + + CAR.SUBARU_CROSSTREK_2025: { + (Ecu.abs, 0x7b0, None): [ + b'\xa2 $\x15\x05', + b'\xa2 $\x17\x06', + ], + (Ecu.fwdCamera, 0x787, None): [ + b'\x1d!\x08\x00F\x14!\x08\x00=', + b'\x1b!\x08\x00D\x11!\x08\x01;', + ], + (Ecu.engine, 0x7a2, None): [ + b'\x04"cP\x07', + b'\xe8!cp\x07', + ], + }, + + CAR.SUBARU_LEGACY_2025: { + (Ecu.abs, 0x7b0, None): [ + b'\xa1 $\x11\x00', + ], + (Ecu.eps, 0x746, None): [ + b'[\xc0\xd1\x10\x00', + ], + (Ecu.fwdCamera, 0x787, None): [ + b'\x1a!\x08\x00C\x0e!\x08\x018', + ], + (Ecu.engine, 0x7a2, None): [ + b'\x08,\xa0p\x07', + ], + (Ecu.transmission, 0x7a3, None): [ + b'\xeb\x17U!r', + ], + }, } diff --git a/opendbc_repo/opendbc/car/subaru/tests/test_supported_firmware.py b/opendbc_repo/opendbc/car/subaru/tests/test_supported_firmware.py new file mode 100644 index 0000000000..aa18339ef8 --- /dev/null +++ b/opendbc_repo/opendbc/car/subaru/tests/test_supported_firmware.py @@ -0,0 +1,69 @@ +"""Supported Subaru identities preserve exact matching and stock-only admission.""" +import unittest + +from opendbc.car.structs import CarParams +from opendbc.car.fw_versions import match_fw_to_car_exact +from opendbc.car.subaru.fingerprints import FW_VERSIONS +from opendbc.car.subaru.interface import CarInterface +from opendbc.car.subaru.values import CAR + +RESTORED = [ + ('SUBARU_ASCENT_2023', 'abs', 1968, 'a520250301'), + ('SUBARU_ASCENT_2023', 'eps', 1862, '55c0d010'), + ('SUBARU_ASCENT_2023', 'fwdCamera', 1927, '1721080141122108003b'), + ('SUBARU_ASCENT_2023', 'fwdCamera', 1927, '17210801410000000000'), + ('SUBARU_ASCENT_2023', 'engine', 1954, '112ca03007'), + ('SUBARU_ASCENT_2023', 'transmission', 1955, '05fee70000'), + ('SUBARU_CROSSTREK_2025', 'abs', 1968, 'a220241505'), + ('SUBARU_CROSSTREK_2025', 'abs', 1968, 'a220241706'), + ('SUBARU_CROSSTREK_2025', 'fwdCamera', 1927, '1d21080046142108003d'), + ('SUBARU_CROSSTREK_2025', 'fwdCamera', 1927, '1b21080044112108013b'), + ('SUBARU_CROSSTREK_2025', 'engine', 1954, '0422635007'), + ('SUBARU_CROSSTREK_2025', 'engine', 1954, 'e821637007'), + ('SUBARU_LEGACY_2025', 'abs', 1968, 'a120241100'), + ('SUBARU_LEGACY_2025', 'eps', 1862, '5bc0d11000'), + ('SUBARU_LEGACY_2025', 'fwdCamera', 1927, '1a210800430e21080138'), + ('SUBARU_LEGACY_2025', 'engine', 1954, '082ca07007'), + ('SUBARU_LEGACY_2025', 'transmission', 1955, 'eb17552172'), +] + + +class TestSupportedSubaruFirmware(unittest.TestCase): + def test_each_restored_identity_reaches_the_real_exact_matcher(self): + for name, ecu_name, address, encoded in RESTORED: + with self.subTest(platform=name, ecu=ecu_name, firmware=encoded): + platform = CAR[name] + self.assertIn(platform, FW_VERSIONS) + versions = FW_VERSIONS[platform] + live = {(addr, sub): {values[0]} for (_, addr, sub), values in versions.items()} + live[address, None] = {bytes.fromhex(encoded)} + self.assertEqual(match_fw_to_car_exact(live, match_brand='subaru', log=False), {platform}) + + def test_unknown_engine_and_camera_still_reject_the_platform(self): + for name in sorted({row[0] for row in RESTORED}): + platform = CAR[name] + for (ecu, address, sub), _ in FW_VERSIONS[platform].items(): + if ecu not in (CarParams.Ecu.engine, CarParams.Ecu.fwdCamera): + continue + with self.subTest(platform=name, ecu=ecu): + live = {(addr, sa): {values[0]} for (_, addr, sa), values in FW_VERSIONS[platform].items()} + live[address, sub] = {b'unknown firmware'} + self.assertNotIn(platform, match_fw_to_car_exact(live, match_brand='subaru', log=False)) + + def test_existing_stock_admission_and_disabled_alpha_are_preserved(self): + words = {CAR.SUBARU_ASCENT_2023: 177, CAR.SUBARU_CROSSTREK_2025: 17, CAR.SUBARU_LEGACY_2025: 145} + for platform, word in words.items(): + for alpha in (False, True): + for release in (False, True): + with self.subTest(platform=platform, alpha=alpha, release=release): + cp = CarInterface.get_params(platform, {0: {}, 1: {}, 2: {}}, [], alpha, release, False) + self.assertFalse(cp.dashcamOnly) + self.assertFalse(cp.alphaLongitudinalAvailable) + self.assertFalse(cp.openpilotLongitudinalControl) + self.assertTrue(cp.pcmCruise) + self.assertEqual(cp.safetyConfigs[0].safetyParam, word) + + def test_three_byte_diagnostic_response_is_not_a_camera_identity(self): + for platform in (CAR.SUBARU_ASCENT_2023, CAR.SUBARU_LEGACY_2025): + for versions in FW_VERSIONS[platform].values(): + self.assertNotIn(bytes.fromhex('20020e'), versions)