mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-14 08:23:59 +08:00
Prevent same-bus HKG advisory packet retransmission
This commit is contained in:
@@ -35,7 +35,8 @@ class DawSource:
|
||||
self.data, self.stamp = bytes(data), stamp
|
||||
|
||||
def command(self, now_ns):
|
||||
if not self.enabled or self.data is None or not 0 < self.stamp <= now_ns <= self.stamp + 100_000_000:
|
||||
if (not self.enabled or self.source_bus == self.target_bus or self.data is None or
|
||||
not 0 < self.stamp <= now_ns <= self.stamp + 100_000_000):
|
||||
return []
|
||||
data = bytearray(self.data)
|
||||
if self.canfd:
|
||||
|
||||
@@ -25,9 +25,9 @@ def source(canfd, status):
|
||||
return bytes(data)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('canfd', (False, True))
|
||||
@pytest.mark.parametrize('status', range(8))
|
||||
def test_exact_current_advisory_only_transform(canfd, status):
|
||||
def test_exact_current_advisory_only_transform(status):
|
||||
canfd = False
|
||||
owner = DawSource(params(canfd))
|
||||
data = source(canfd, status)
|
||||
assert not owner.command(BASE)
|
||||
@@ -102,3 +102,38 @@ def test_unsupported_ioniq6_native_profiles_cannot_emit_advisories(word):
|
||||
assert not owner.enabled
|
||||
owner.update([(BASE, [CanData(0x11A, source(True, 1), owner.source_bus)])])
|
||||
assert not owner.command(BASE)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('word', (0x11, 0x91, 0x811, 0x891, 0x8015, 0x8095, 0x8815, 0x8895))
|
||||
@pytest.mark.parametrize('status', range(8))
|
||||
def test_live_same_bus_canfd_source_is_never_retransmitted(word, status):
|
||||
cp = params(True)
|
||||
cp.safetyConfigs[-1].safetyParam = word
|
||||
owner = DawSource(cp)
|
||||
assert owner.enabled and owner.source_bus == owner.target_bus
|
||||
for tick in range(20):
|
||||
stamp = BASE + tick * 10_000_000
|
||||
data = bytearray(source(True, status))
|
||||
data[2] = tick
|
||||
data[:2] = hkg_can_fd_checksum(owner.address, None, data).to_bytes(2, 'little')
|
||||
owner.update([(stamp, [CanData(owner.address, bytes(data), owner.source_bus)])])
|
||||
assert owner.data == bytes(data)
|
||||
assert owner.command(stamp) == []
|
||||
assert owner.command(stamp + 5_000_000) == []
|
||||
|
||||
|
||||
@pytest.mark.parametrize('alternate', (False, True))
|
||||
def test_actual_ioniq6_controller_keeps_live_source_off_sendcan(alternate):
|
||||
cp, _ = ioniq6_params(alternate)
|
||||
before = cp.to_dict()
|
||||
first, second = CarInterface(cp.as_reader().as_builder()), CarInterface(cp.as_reader().as_builder())
|
||||
data = source(True, 1)
|
||||
plain = first.update([(BASE, [])])
|
||||
observed = second.update([(BASE, [CanData(0x11A, data, 1)])])
|
||||
assert observed.to_dict() == plain.to_dict()
|
||||
control = structs.CarControl()
|
||||
baseline = first.apply(control.as_reader(), BASE)[1]
|
||||
actual = second.apply(control.as_reader(), BASE)[1]
|
||||
assert actual == baseline
|
||||
assert all(frame[0] != 0x11A for frame in actual)
|
||||
assert cp.to_dict() == before
|
||||
|
||||
@@ -15,6 +15,17 @@ def packet(addr, data, bus):
|
||||
return libsafety_py.make_CANPacket(addr, bus, data)
|
||||
|
||||
|
||||
def advisory_candidate(owner, now):
|
||||
if not owner.canfd:
|
||||
return owner.command(now)[0]
|
||||
assert owner.command(now) == []
|
||||
data = bytearray(owner.data)
|
||||
if (data[7] >> 3) & 7 == 1:
|
||||
data[7] &= ~0x38
|
||||
data[:2] = hkg_can_fd_checksum(owner.address, None, data).to_bytes(2, 'little')
|
||||
return owner.address, bytes(data), owner.target_bus
|
||||
|
||||
|
||||
def setup(canfd, word):
|
||||
safety = libsafety_py.libsafety
|
||||
debug = safety.set_safety_hooks(structs.CarParams.SafetyModel.allOutput, 0) == 0
|
||||
@@ -33,7 +44,7 @@ def test_actual_host_commands_obey_native_source_payload_and_expiry(canfd, word,
|
||||
owner = DawSource(params(canfd))
|
||||
data = source(canfd, status)
|
||||
owner.update([(BASE, [(owner.address, data, owner.source_bus)])])
|
||||
addr, output, bus = owner.command(BASE)[0]
|
||||
addr, output, bus = advisory_candidate(owner, BASE)
|
||||
assert not safety.safety_tx_hook(packet(addr, output, bus))
|
||||
safety.safety_rx_hook(packet(addr, data, owner.source_bus))
|
||||
assert bool(safety.safety_tx_hook(packet(addr, output, bus))) == supported
|
||||
@@ -60,7 +71,7 @@ def test_source_rejection_reset_and_relay_are_preserved(canfd, fault):
|
||||
owner = DawSource(params(canfd))
|
||||
data = source(canfd, 1)
|
||||
owner.update([(BASE, [(owner.address, data, owner.source_bus)])])
|
||||
addr, output, bus = owner.command(BASE)[0]
|
||||
addr, output, bus = advisory_candidate(owner, BASE)
|
||||
incoming = data[:-4] if fault == 'length' and canfd else data[:-1] if fault == 'length' else data
|
||||
rx_bus = owner.source_bus + 1 if fault == 'bus' else owner.source_bus
|
||||
if fault == 'crc':
|
||||
@@ -95,7 +106,7 @@ def test_one_genuine_counter_predecessor_cannot_hide_newer_hands_off_request():
|
||||
owner = DawSource(params(True))
|
||||
data = source(True, 1)
|
||||
owner.update([(BASE, [(0x11A, data, 1)])])
|
||||
_, output, _ = owner.command(BASE)[0]
|
||||
_, output, _ = advisory_candidate(owner, BASE)
|
||||
safety.safety_rx_hook(packet(0x11A, data, 1))
|
||||
following = bytearray(data)
|
||||
following[2] += 1
|
||||
@@ -110,7 +121,7 @@ def test_one_genuine_counter_predecessor_cannot_hide_newer_hands_off_request():
|
||||
safety.safety_rx_hook(packet(0x11A, newer, 1))
|
||||
assert not safety.safety_tx_hook(packet(0x11A, output, 1))
|
||||
owner.update([(BASE + 10_000_000, [(0x11A, bytes(following), 1)])])
|
||||
_, prior_output, _ = owner.command(BASE + 10_000_000)[0]
|
||||
_, prior_output, _ = advisory_candidate(owner, BASE + 10_000_000)
|
||||
assert safety.safety_tx_hook(packet(0x11A, prior_output, 1))
|
||||
hands_off = bytearray(newer)
|
||||
hands_off[2] += 1
|
||||
@@ -120,8 +131,8 @@ def test_one_genuine_counter_predecessor_cannot_hide_newer_hands_off_request():
|
||||
safety.safety_rx_hook(packet(0x11A, hands_off, 1))
|
||||
assert not safety.safety_tx_hook(packet(0x11A, prior_output, 1))
|
||||
owner.update([(BASE + 20_000_000, [(0x11A, bytes(newer), 1)])])
|
||||
_, prior_output, _ = owner.command(BASE + 20_000_000)[0]
|
||||
_, prior_output, _ = advisory_candidate(owner, BASE + 20_000_000)
|
||||
assert not safety.safety_tx_hook(packet(0x11A, prior_output, 1))
|
||||
owner.update([(BASE + 30_000_000, [(0x11A, bytes(hands_off), 1)])])
|
||||
_, current_output, _ = owner.command(BASE + 30_000_000)[0]
|
||||
_, current_output, _ = advisory_candidate(owner, BASE + 30_000_000)
|
||||
assert safety.safety_tx_hook(packet(0x11A, current_output, 1))
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"protected_inventory_sha256": "16b87cb64ab51930429e6251dad19d486b669b0c86e4f005f97fa7a5f9045661", "schema_version": 1}
|
||||
{"protected_inventory_sha256": "fabbd14a4c2dfdaf5c55e515d9b8ba8e9b35f495f28b017bde6ec5df54406c34", "schema_version": 1}
|
||||
|
||||
Reference in New Issue
Block a user