mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-10-29 17:43:47 +08:00
Recognize Camry filter with independent cluster radar traffic
This commit is contained in:
@@ -13,6 +13,14 @@ PROFILES = {
|
||||
}
|
||||
|
||||
|
||||
def _camry_radar_bus(candidate, bus, messages):
|
||||
# The 2018–20 Camry exposes an independent eight-byte 2FF stream alongside
|
||||
# its six cluster-radar frames on bus1 (cluster_radar.CLUSTERS). It is not
|
||||
# the four-byte filter advertisement or a bus0 smartDSU status source.
|
||||
return (candidate == CAR.TOYOTA_CAMRY and bus == 1 and messages.get(0x2FF) == 8 and
|
||||
all(messages.get(address) == 8 for address in range(0x680, 0x686)))
|
||||
|
||||
|
||||
def hardware_supported(candidate, fingerprint):
|
||||
# The filter's advertisement is a hardware discriminator, not an actuation
|
||||
# permission or a copy of ACC_CONTROL to decode under a different checksum.
|
||||
@@ -21,11 +29,13 @@ def hardware_supported(candidate, fingerprint):
|
||||
# Panda discovery may also expose its forwarded camera-bus copy.
|
||||
if (candidate in PROFILES and fingerprint.get(0, {}).get(0x2FF) == 4 and
|
||||
not any(address in messages for messages in fingerprint.values() for address in (0x201, 0x2AA)) and
|
||||
all(bus in (0, 2) and messages[0x2FF] == 4 for bus, messages in fingerprint.items() if 0x2FF in messages)):
|
||||
all((bus in (0, 2) and messages[0x2FF] == 4) or _camry_radar_bus(candidate, bus, messages)
|
||||
for bus, messages in fingerprint.items() if 0x2FF in messages)):
|
||||
return True
|
||||
return (candidate in PROFILES and fingerprint.get(0, {}).get(0x2AA) == 8 and
|
||||
all(bus in (0, 2) and frames[0x2AA] == 8 for bus, frames in fingerprint.items() if 0x2AA in frames) and
|
||||
not any(addr in frames for frames in fingerprint.values() for addr in (0x201, 0x2FF)))
|
||||
not any(0x201 in frames or 0x2FF in frames and not _camry_radar_bus(candidate, bus, frames)
|
||||
for bus, frames in fingerprint.items()))
|
||||
|
||||
|
||||
def configured(cp):
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
"""Camry cluster-radar traffic must not impersonate a bus-0 filter status."""
|
||||
import pytest
|
||||
from opendbc.car import gen_empty_fingerprint
|
||||
from opendbc.car.toyota import radar_filter
|
||||
from opendbc.car.toyota.cluster_radar import CLUSTERS
|
||||
from opendbc.car.toyota.interface import CarInterface
|
||||
from opendbc.car.toyota.values import CAR
|
||||
from openpilot.starpilot.car.toyota.aol import qualified
|
||||
|
||||
|
||||
def observed():
|
||||
fp = gen_empty_fingerprint()
|
||||
fp[0][0x2FF] = fp[2][0x2FF] = 4
|
||||
fp[1] = {0x2FF: 8, **dict.fromkeys(CLUSTERS, 8)}
|
||||
return fp
|
||||
|
||||
|
||||
@pytest.mark.parametrize('alpha', (False, True))
|
||||
@pytest.mark.parametrize('primary', (0x2FF, 0x2AA))
|
||||
def test_camry_radar_bus_preserves_exact_filter_owner(alpha, primary):
|
||||
fp = observed()
|
||||
if primary == 0x2AA:
|
||||
fp[0] = fp[2] = {primary: 8}
|
||||
canonical = gen_empty_fingerprint()
|
||||
canonical[0][primary] = 4 if primary == 0x2FF else 8
|
||||
expected = CarInterface.get_params(CAR.TOYOTA_CAMRY, canonical, [], alpha, False, False)
|
||||
actual = CarInterface.get_params(CAR.TOYOTA_CAMRY, fp, [], alpha, False, False)
|
||||
assert radar_filter.hardware_supported(CAR.TOYOTA_CAMRY, fp)
|
||||
assert actual.to_dict() == expected.to_dict()
|
||||
assert actual.safetyConfigs[0].safetyParam == (0x1049 if alpha else 0x1249)
|
||||
assert actual.openpilotLongitudinalControl == alpha and qualified(actual)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('bad', ('missing_filter', 'bus1_short', 'missing_cluster', 'bad_cluster',
|
||||
'wrong_cluster_bus', 'wrong_model', 'bus1_advert', 'mixed_status', 'pedal'))
|
||||
def test_camry_radar_bus_is_not_general_adapter_evidence(bad):
|
||||
fp = observed()
|
||||
candidate = CAR.TOYOTA_CAMRY
|
||||
if bad == 'missing_filter':
|
||||
fp[0].clear()
|
||||
elif bad == 'bus1_short':
|
||||
fp[1][0x2FF] = 7
|
||||
elif bad == 'missing_cluster':
|
||||
del fp[1][CLUSTERS[-1]]
|
||||
elif bad == 'bad_cluster':
|
||||
fp[1][CLUSTERS[-1]] = 7
|
||||
elif bad == 'wrong_cluster_bus':
|
||||
fp[3] = fp.pop(1)
|
||||
elif bad == 'wrong_model':
|
||||
candidate = CAR.TOYOTA_CHR
|
||||
elif bad == 'bus1_advert':
|
||||
fp[1][0x2FF] = 4
|
||||
elif bad == 'mixed_status':
|
||||
fp[2][0x2FF] = 8
|
||||
else:
|
||||
fp[0][0x201] = 6
|
||||
assert not radar_filter.hardware_supported(candidate, fp)
|
||||
@@ -13,3 +13,13 @@ daemon_gc_scope=helpers.daemon_gc_scope
|
||||
def test_other_filter_variants_full_callers(candidate,alpha,disable,aol,tmp_path,host_heartbeat_bridge):
|
||||
advertisements=[(0x2FF,bytes.fromhex('00000409'),bus) for bus in (0,2)]
|
||||
helpers.run_case(candidate,alpha,disable,0,tmp_path,aol=aol,bridge=host_heartbeat_bridge,filter_advertisements=advertisements)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('alpha,disable', [(False, False), (True, False), (True, True)])
|
||||
def test_camry_cluster_bus_advertisement_actual_callers(alpha, disable, tmp_path, host_heartbeat_bridge):
|
||||
from opendbc.car.toyota.cluster_radar import CLUSTERS
|
||||
advertisements = [(0x2FF, bytes.fromhex('00000409'), bus) for bus in (0, 2)]
|
||||
advertisements += [(0x2FF, bytes.fromhex('100068010000b5ff'), 1)]
|
||||
advertisements += [(address, bytes(8), 1) for address in CLUSTERS]
|
||||
helpers.run_case(CAR.TOYOTA_CAMRY, alpha, disable, 0, tmp_path, aol=True,
|
||||
bridge=host_heartbeat_bridge, filter_advertisements=advertisements)
|
||||
|
||||
Reference in New Issue
Block a user