Restore HKG coffee-break advisory replacements

This commit is contained in:
firestar5683
2026-11-02 22:57:08 -06:00
parent 58fc0bb4e7
commit 507373cb7d
12 changed files with 417 additions and 5 deletions
@@ -297,6 +297,7 @@ class CarController(CarControllerBase):
self.frame += 1
if _projection is not None:
_projection.finish(new_actuators.torque)
can_sends.extend(CS.daw.command(now_nanos))
return new_actuators, can_sends
def create_can_msgs(self, apply_steer_req, apply_torque, torque_fault, set_speed_in_units, accel, stopping,
@@ -62,6 +62,8 @@ def get_non_scc_cruise_signals(flags: int, car=None) -> tuple[str, str, str, str
class CarState(CarStateBase):
def __init__(self, CP):
super().__init__(CP)
from opendbc.car.hyundai.daw import DawSource
self.daw = DawSource(CP)
self.forte_lkas_sources = NonSccLkasSources() if qualified_non_scc(CP) and CP.flags & HyundaiFlags.HAS_LDA_BUTTON else None
if (qualified_classic_scc(CP) or qualified_classic_long(CP)) and CP.flags & HyundaiFlags.HAS_LDA_BUTTON:
self.forte_lkas_sources = ClassicSccLkasSources(CP.carFingerprint)
+47
View File
@@ -0,0 +1,47 @@
from opendbc.car import CanData
from opendbc.car.hyundai.hyundaicanfd import CanBus, hkg_can_fd_checksum
from opendbc.car.hyundai.values import CAR, HyundaiFlags, is_blended
CANFD_DAW_WORDS = frozenset((0x11, 0x91, 0x811, 0x891, 0x8015, 0x8095, 0x8815, 0x8895))
class DawSource:
def __init__(self, cp):
self.canfd = bool(cp.flags & HyundaiFlags.CANFD)
self.enabled = (cp.brand == 'hyundai' and not cp.passive and not cp.dashcamOnly and not cp.notCar and
not is_blended(cp) and (not self.canfd or cp.carFingerprint == CAR.HYUNDAI_IONIQ_6))
if self.canfd:
self.enabled = bool(self.enabled and cp.safetyConfigs and
int(cp.safetyConfigs[-1].safetyParam) in CANFD_DAW_WORDS and CanBus(cp).ECAN % 4 == 1)
self.address = 0x11A if self.canfd else 0x53E
self.source_bus = CanBus(cp).ECAN if self.canfd else 2
self.target_bus = CanBus(cp).ECAN if self.canfd else 0
self.length = 16 if self.canfd else 6
self.data = None
self.stamp = 0
def update(self, packets):
if not self.enabled:
return
for stamp, frames in packets:
for address, data, bus in frames:
if address != self.address or bus != self.source_bus:
continue
if stamp <= self.stamp or len(data) != self.length or (self.canfd and
int.from_bytes(data[:2], 'little') != hkg_can_fd_checksum(address, None, data)):
self.data = None
continue
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:
return []
data = bytearray(self.data)
if self.canfd:
if (data[7] >> 3) & 7 == 1:
data[7] &= ~0x38
data[:2] = hkg_can_fd_checksum(self.address, None, data).to_bytes(2, 'little')
elif 1 <= data[5] & 7 <= 3:
data[5] &= ~7
return [CanData(self.address, bytes(data), self.target_bus)]
@@ -396,6 +396,9 @@ class CarInterface(CarInterfaceBase):
return ret
def update(self, can_packets):
if self.CS.daw.enabled:
can_packets = list(can_packets)
self.CS.daw.update(can_packets)
recovery = getattr(getattr(self, 'CC', None), 'angle_tx_recovery', None)
if recovery is not None:
can_packets = list(can_packets)
@@ -0,0 +1,104 @@
import pytest
from opendbc.car import CanData, gen_empty_fingerprint, structs
from opendbc.car.hyundai.daw import DawSource
from opendbc.car.hyundai.hyundaicanfd import hkg_can_fd_checksum
from opendbc.car.hyundai.interface import CarInterface
from opendbc.car.hyundai.tests.test_ioniq6_stock_parser import params as ioniq6_params
from opendbc.car.hyundai.values import CAR
BASE = 1_000_000_000
def params(canfd):
return ioniq6_params(True)[0] if canfd else CarInterface.get_params(
CAR.HYUNDAI_SONATA_HYBRID, gen_empty_fingerprint(), [], False, False, False)
def source(canfd, status):
data = bytearray.fromhex('1234567898f8') if not canfd else bytearray(range(16))
if canfd:
data[7] = (data[7] & ~0x38) | (status << 3)
data[:2] = hkg_can_fd_checksum(0x11A, None, data).to_bytes(2, 'little')
else:
data[5] = (data[5] & ~7) | 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):
owner = DawSource(params(canfd))
data = source(canfd, status)
assert not owner.command(BASE)
owner.update([(BASE, [CanData(owner.address, data, owner.source_bus)])])
command, = owner.command(BASE)
expected = bytearray(data)
if canfd:
if status == 1:
expected[7] &= ~0x38
expected[:2] = hkg_can_fd_checksum(owner.address, None, expected).to_bytes(2, 'little')
elif 1 <= status <= 3:
expected[5] &= ~7
assert command == CanData(owner.address, bytes(expected), owner.target_bus)
assert owner.data == data
assert owner.command(BASE + 100_000_000)
assert not owner.command(BASE + 100_000_001)
@pytest.mark.parametrize('canfd,fault', [(canfd, fault) for canfd in (False, True)
for fault in ('future', 'old', 'reversed', 'length', 'returned', 'wrong_bus', 'wrong_address', 'crc')
if canfd or fault != 'crc'])
def test_bad_or_missing_sources_cannot_create_replacements(canfd, fault):
owner = DawSource(params(canfd))
data = source(canfd, 1)
stamp, bus, addr = BASE, owner.source_bus, owner.address
if fault == 'length':
data = data[:-1]
elif fault == 'returned':
bus += 128
elif fault == 'wrong_bus':
bus = 0 if canfd else 1
elif fault == 'wrong_address':
addr += 1
elif fault == 'crc':
data = bytes([data[0] ^ 1]) + data[1:]
elif fault == 'reversed':
owner.update([(BASE + 1, [CanData(addr, data, bus)])])
owner.update([(stamp, [CanData(addr, data, bus)])])
now = BASE - 1 if fault == 'future' else BASE + 100_000_001 if fault == 'old' else BASE
assert not owner.command(now)
def test_actual_parser_and_controller_keep_optional_message_out_of_driving_health():
cp = params(False)
before = cp.to_dict()
first, second = CarInterface(cp.as_reader().as_builder()), CarInterface(cp.as_reader().as_builder())
data = bytes.fromhex('000000000883')
plain = first.update([(BASE, [])])
observed = second.update([(BASE, [CanData(0x53E, data, 2)])])
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 [frame for frame in actual if frame[0] != 0x53E] == baseline
assert [frame for frame in actual if frame[0] == 0x53E] == [CanData(0x53E, bytes.fromhex('000000000880'), 0)]
assert cp.to_dict() == before
def test_unrelated_canfd_profiles_do_not_emit_new_frames():
cp = CarInterface.get_params(CAR.KIA_EV6, gen_empty_fingerprint(), [], False, False, False)
owner = DawSource(cp)
assert not owner.enabled
owner.update([(BASE, [CanData(0x11A, source(True, 1), 1)])])
assert not owner.command(BASE)
@pytest.mark.parametrize('word', (0, 1, 9, 0x15, 0x5491, 0x5495))
def test_unsupported_ioniq6_native_profiles_cannot_emit_advisories(word):
cp = params(True)
cp.safetyConfigs[-1].safetyParam = word
owner = DawSource(cp)
assert not owner.enabled
owner.update([(BASE, [CanData(0x11A, source(True, 1), owner.source_bus)])])
assert not owner.command(BASE)
+7 -3
View File
@@ -2,6 +2,7 @@
#include "opendbc/safety/declarations.h"
#include "opendbc/safety/modes/hyundai_common.h"
#include "opendbc/safety/modes/hyundai_daw.h"
#include "opendbc/safety/modes/hyundai_classic_non_scc_aol.h"
#include "opendbc/safety/modes/hyundai_blended_stock_aol.h"
@@ -350,7 +351,7 @@ static bool hyundai_tx_hook(const CANPacket_t *msg) {
const TorqueSteeringLimits HYUNDAI_STEERING_LIMITS_ALT = HYUNDAI_LIMITS(270, 2, 3);
const TorqueSteeringLimits HYUNDAI_STEERING_LIMITS_ALT_2 = HYUNDAI_LIMITS(170, 2, 3);
bool tx = true;
bool tx = (msg->addr != 0x53EU) || hyundai_daw_tx(msg);
if (hyundai_ray_pedal && (msg->addr == 0x200U)) {
const uint16_t track1 = ((uint16_t)msg->data[0] << 8U) | msg->data[1];
@@ -638,6 +639,7 @@ static safety_config hyundai_init(uint16_t param) {
};
hyundai_common_init(param);
hyundai_daw_init(false, false);
if ((param == 0x800EU) && (alternative_experience == 0)) {
hyundai_long_main_policy = HYUNDAI_MAIN_TRACK;
}
@@ -900,7 +902,7 @@ static safety_config hyundai_init(uint16_t param) {
const safety_config denied = {0};
ret = denied;
}
return ret;
return hyundai_daw_configure(ret, false, !hyundai_blended_stock && !hyundai_blended_alpha);
}
static safety_config hyundai_legacy_init(uint16_t param) {
@@ -922,6 +924,7 @@ static safety_config hyundai_legacy_init(uint16_t param) {
}
}
hyundai_common_init(normalized);
hyundai_daw_init(false, false);
classic_non_scc_aol_configure(normalized, !legacy_long);
hyundai_legacy = true;
hyundai_blended_stock = false;
@@ -950,10 +953,11 @@ static safety_config hyundai_legacy_init(uint16_t param) {
#endif
}
hyundai_classic_scc_aol_rx_config(&ret, true);
return ret;
return hyundai_daw_configure(ret, false, true);
}
static void hyundai_optional_rx_hook(const CANPacket_t *msg) {
hyundai_daw_rx(msg);
if ((msg->addr == 0x391U) || (msg->addr == 0x50CU)) {
blended_aol_rx(msg);
}
@@ -2,6 +2,7 @@
#include "opendbc/safety/declarations.h"
#include "opendbc/safety/modes/hyundai_common.h"
#include "opendbc/safety/modes/hyundai_daw.h"
#include "opendbc/safety/modes/hyundai_canfd_aol.h"
#include "opendbc/safety/modes/hyundai_canfd_angle_aol.h"
@@ -527,6 +528,7 @@ static void hyundai_canfd_ioniq6_optional_rx_hook(const CANPacket_t *msg) {
}
static void hyundai_canfd_optional_rx_hook(const CANPacket_t *msg) {
hyundai_daw_rx(msg);
if (hyundai_canfd_ioniq6_long && (msg->bus == 1U)) {
hyundai_canfd_ioniq6_optional_rx_hook(msg);
}
@@ -1272,7 +1274,7 @@ static bool hyundai_canfd_tx_hook(const CANPacket_t *msg) {
}
}
if (ordinary_angle_valid && !((hyundai_canfd_ioniq6_long || hyundai_canfd_ccnc_ev_long) && safety_rx_checks_invalid)) {
tx = hyundai_canfd_tx_hook_valid(msg);
tx = (msg->addr == 0x11AU) ? hyundai_daw_tx(msg) : hyundai_canfd_tx_hook_valid(msg);
}
if ((hyundai_ordinary_angle_stock && !hyundai_angle_aol_enabled && (msg->addr == 0x110U) && tx) ||
(independent_command && independent_active && tx)) {
@@ -2221,6 +2223,7 @@ static safety_config hyundai_canfd_init_validated(uint16_t supplied_param) {
}
static safety_config hyundai_canfd_init(uint16_t param) {
hyundai_daw_init(true, false);
hyundai_canfd_reset_ioniq6_state();
hyundai_ordinary_angle_reset();
#ifdef ALLOW_DEBUG
@@ -2239,6 +2242,9 @@ static safety_config hyundai_canfd_init(uint16_t param) {
(param == 0x8815U) || (param == 0x8895U);
if (valid && marker_valid) {
ret = hyundai_canfd_init_validated(param);
const bool daw_profile = (param == 0x0011U) || (param == 0x0091U) || (param == 0x0811U) || (param == 0x0891U) ||
(param == 0x8015U) || (param == 0x8095U) || (param == 0x8815U) || (param == 0x8895U);
ret = hyundai_daw_configure(ret, true, daw_profile);
}
return ret;
}
@@ -0,0 +1,117 @@
#pragma once
#include "opendbc/safety/modes/hyundai_common.h"
static uint16_t hyundai_daw_addr;
static unsigned int hyundai_daw_bus;
static unsigned int hyundai_daw_len;
static uint8_t hyundai_daw_data[16];
static uint8_t hyundai_daw_previous[16];
static bool hyundai_daw_previous_seen;
static uint32_t hyundai_daw_previous_ts;
static uint32_t hyundai_daw_rx_ts;
static uint32_t hyundai_daw_tx_ts;
static bool hyundai_daw_seen;
static bool hyundai_daw_counter_seen;
static bool hyundai_daw_sent;
static void hyundai_daw_init(bool canfd, bool enabled) {
hyundai_daw_addr = enabled ? (canfd ? 0x11AU : 0x53EU) : 0U;
hyundai_daw_bus = canfd ? 1U : 0U;
hyundai_daw_len = canfd ? 16U : 6U;
hyundai_daw_previous_seen = false;
hyundai_daw_previous_ts = 0U;
hyundai_daw_seen = false;
hyundai_daw_counter_seen = false;
hyundai_daw_sent = false;
hyundai_daw_rx_ts = 0U;
hyundai_daw_tx_ts = 0U;
}
static void hyundai_daw_rx(const CANPacket_t *msg) {
const bool canfd = hyundai_daw_len == 16U;
if ((hyundai_daw_addr != 0U) && (msg->addr == hyundai_daw_addr) && (msg->bus == (canfd ? hyundai_daw_bus : 2U))) {
const uint32_t now = microsecond_timer_get();
const bool fresh = hyundai_daw_counter_seen && (safety_get_ts_elapsed(now, hyundai_daw_rx_ts) <= 100000U);
bool valid = GET_LEN(msg) == hyundai_daw_len;
if (valid && canfd) {
valid = GET_BYTES_LE(msg, 0, 2) == (hyundai_common_canfd_compute_checksum(msg) ^ 0x041DU);
if (fresh) {
valid &= (uint8_t)(msg->data[2] - hyundai_daw_data[2]) == 1U;
}
}
hyundai_daw_previous_seen = canfd && valid && fresh && hyundai_daw_seen;
if (hyundai_daw_previous_seen) {
(void)memcpy(hyundai_daw_previous, hyundai_daw_data, hyundai_daw_len);
hyundai_daw_previous_ts = hyundai_daw_rx_ts;
}
hyundai_daw_seen = valid;
if (valid) {
(void)memcpy(hyundai_daw_data, msg->data, hyundai_daw_len);
hyundai_daw_rx_ts = now;
hyundai_daw_counter_seen = true;
}
}
}
static uint8_t hyundai_daw_expected(const uint8_t *data, unsigned int i) {
uint8_t expected = data[i];
if ((hyundai_daw_len == 16U) && (i == 7U) && (((expected >> 3U) & 7U) == 1U)) {
expected &= (uint8_t)~0x38U;
} else if ((hyundai_daw_len == 6U) && (i == 5U) && ((expected & 7U) >= 1U) && ((expected & 7U) <= 3U)) {
expected &= (uint8_t)~7U;
} else {
// Non-advisory payload bits are copied exactly from the current source.
}
return expected;
}
static bool hyundai_daw_tx(const CANPacket_t *msg) {
const uint32_t now = microsecond_timer_get();
const bool canfd = hyundai_daw_len == 16U;
bool valid = hyundai_daw_seen && (hyundai_daw_addr != 0U) && (msg->addr == hyundai_daw_addr) &&
(msg->bus == hyundai_daw_bus) && (GET_LEN(msg) == hyundai_daw_len) &&
(safety_get_ts_elapsed(now, hyundai_daw_rx_ts) <= 100000U) &&
(!hyundai_daw_sent || (safety_get_ts_elapsed(now, hyundai_daw_tx_ts) >= 5000U));
if (valid) {
const uint8_t *source = hyundai_daw_data;
if (canfd && (msg->data[2] != hyundai_daw_data[2])) {
valid = hyundai_daw_previous_seen && (msg->data[2] == hyundai_daw_previous[2]) &&
(safety_get_ts_elapsed(now, hyundai_daw_previous_ts) <= 100000U);
if (valid) {
// A one-frame receive race cannot replace newer warning or status data.
for (unsigned int i = 3U; i < hyundai_daw_len; i++) {
valid &= hyundai_daw_expected(hyundai_daw_previous, i) == hyundai_daw_expected(hyundai_daw_data, i);
}
source = hyundai_daw_previous;
}
}
for (unsigned int i = canfd ? 2U : 0U; i < hyundai_daw_len; i++) {
valid &= msg->data[i] == hyundai_daw_expected(source, i);
}
if (canfd) {
valid &= GET_BYTES_LE(msg, 0, 2) == (hyundai_common_canfd_compute_checksum(msg) ^ 0x041DU);
}
}
if (valid) {
hyundai_daw_sent = true;
hyundai_daw_tx_ts = now;
}
return valid;
}
static safety_config hyundai_daw_configure(safety_config ret, bool canfd, bool enabled) {
hyundai_daw_init(canfd, false);
if (enabled && (ret.tx_msgs_len > 0) && (ret.tx_msgs_len < 64)) {
static CanMsg daw_tx_msgs[64];
for (int i = 0; i < ret.tx_msgs_len; i++) {
daw_tx_msgs[i] = ret.tx_msgs[i];
}
const CanMsg daw = {canfd ? 0x11AU : 0x53EU, canfd ? 1U : 0U, canfd ? 16U : 6U, .check_relay = false};
daw_tx_msgs[ret.tx_msgs_len] = daw;
ret.tx_msgs_len++;
ret.tx_msgs = daw_tx_msgs;
hyundai_daw_init(canfd, true);
}
return ret;
}
@@ -0,0 +1,127 @@
import pytest
from opendbc.car import structs
from opendbc.car.hyundai.daw import DawSource
from opendbc.car.hyundai.hyundaicanfd import hkg_can_fd_checksum
from opendbc.car.hyundai.tests.test_daw import BASE, params, source
from opendbc.safety.tests.libsafety import libsafety_py
PROFILES = [(False, 0), (False, 0xC02), (True, 0x11), (True, 0x91), (True, 0x811), (True, 0x891),
(True, 0x8015), (True, 0x8095), (True, 0x8815), (True, 0x8895)]
def packet(addr, data, bus):
return libsafety_py.make_CANPacket(addr, bus, data)
def setup(canfd, word):
safety = libsafety_py.libsafety
debug = safety.set_safety_hooks(structs.CarParams.SafetyModel.allOutput, 0) == 0
safety.set_alternative_experience(32 if word & 0x800 else 0)
mode = structs.CarParams.SafetyModel.hyundaiCanfd if canfd else structs.CarParams.SafetyModel.hyundai
assert safety.set_safety_hooks(mode, word) == 0
safety.init_tests()
safety.set_timer(1_000_000)
return safety, debug or not (canfd and word & 0x8000)
@pytest.mark.parametrize('canfd,word', PROFILES)
@pytest.mark.parametrize('status', range(8))
def test_actual_host_commands_obey_native_source_payload_and_expiry(canfd, word, status):
safety, supported = setup(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]
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
if not supported:
return
assert not safety.safety_tx_hook(packet(addr, output, bus))
safety.set_timer(1_010_000)
for bit in range(len(output) * 8):
bad = bytearray(output)
bad[bit // 8] ^= 1 << (bit % 8)
assert not safety.safety_tx_hook(packet(addr, bad, bus)), bit
assert safety.safety_tx_hook(packet(addr, output, bus))
safety.set_timer(1_100_000)
assert safety.safety_tx_hook(packet(addr, output, bus))
safety.set_timer(1_100_001)
assert not safety.safety_tx_hook(packet(addr, output, bus))
assert not safety.get_controls_allowed()
@pytest.mark.parametrize('canfd,fault', [(canfd, fault) for canfd in (False, True)
for fault in ('length', 'bus', 'crc', 'counter', 'reset', 'relay') if canfd or fault not in ('crc', 'counter')])
def test_source_rejection_reset_and_relay_are_preserved(canfd, fault):
safety, _ = setup(canfd, 0x11 if canfd else 0)
owner = DawSource(params(canfd))
data = source(canfd, 1)
owner.update([(BASE, [(owner.address, data, owner.source_bus)])])
addr, output, bus = owner.command(BASE)[0]
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':
incoming = bytes([incoming[0] ^ 1]) + incoming[1:]
safety.safety_rx_hook(packet(addr, incoming, rx_bus))
if fault == 'counter':
safety.set_timer(1_010_000)
safety.safety_rx_hook(packet(addr, incoming, rx_bus))
elif fault == 'reset':
setup(canfd, 0x11 if canfd else 0)
elif fault == 'relay':
safety.set_relay_malfunction(True)
assert not safety.safety_tx_hook(packet(addr, output, bus))
def test_forwarding_and_other_profiles_remain_unchanged():
safety, _ = setup(False, 0)
assert safety.safety_fwd_hook(2, 0x53E) == 0
assert safety.safety_fwd_hook(0, 0x53E) == 2
safety.set_safety_hooks(structs.CarParams.SafetyModel.hyundaiCanfd, 0)
safety.init_tests()
data = source(True, 1)
safety.safety_rx_hook(packet(0x11A, data, 0))
changed = bytearray(data)
changed[7] &= ~0x38
changed[:2] = hkg_can_fd_checksum(0x11A, None, changed).to_bytes(2, 'little')
assert not safety.safety_tx_hook(packet(0x11A, changed, 0))
def test_one_genuine_counter_predecessor_cannot_hide_newer_hands_off_request():
safety, _ = setup(True, 0x11)
owner = DawSource(params(True))
data = source(True, 1)
owner.update([(BASE, [(0x11A, data, 1)])])
_, output, _ = owner.command(BASE)[0]
safety.safety_rx_hook(packet(0x11A, data, 1))
following = bytearray(data)
following[2] += 1
following[:2] = hkg_can_fd_checksum(0x11A, None, following).to_bytes(2, 'little')
safety.set_timer(1_010_000)
safety.safety_rx_hook(packet(0x11A, following, 1))
assert safety.safety_tx_hook(packet(0x11A, output, 1))
safety.set_timer(1_015_000)
newer = bytearray(following)
newer[2] += 1
newer[:2] = hkg_can_fd_checksum(0x11A, None, newer).to_bytes(2, 'little')
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]
assert safety.safety_tx_hook(packet(0x11A, prior_output, 1))
hands_off = bytearray(newer)
hands_off[2] += 1
hands_off[7] = (hands_off[7] & ~0x38) | (2 << 3)
hands_off[:2] = hkg_can_fd_checksum(0x11A, None, hands_off).to_bytes(2, 'little')
safety.set_timer(1_020_000)
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]
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]
assert safety.safety_tx_hook(packet(0x11A, current_output, 1))
View File
-1
View File
@@ -1 +0,0 @@
{"protected_inventory_sha256": "fede7a3a054e8b7d37cc815a25f5d5296b19c34bc525281e97622bcbe1a569c0", "schema_version": 1}
+2
View File
@@ -44,6 +44,7 @@ AOL_LIFECYCLE_TARGETS = (
"opendbc_repo/opendbc/car/hyundai/tests/test_torque_ev_deferred_takeover.py",
'openpilot/starpilot/aol/tests/test_hkg_early_long_withdrawal.py',
'openpilot/starpilot/aol/tests/test_hkg_angle_eps_retention.py',
'opendbc_repo/opendbc/car/hyundai/tests/test_daw.py',
'openpilot/starpilot/aol/tests/test_hkg_angle_limit_warning.py',
'openpilot/starpilot/car/toyota/tests/test_prius_retrofit_stock.py',
'openpilot/starpilot/car/toyota/tests/test_prius_retrofit_stock_callers.py',
@@ -513,6 +514,7 @@ RELEASE_TARGETS = (
"opendbc_repo/opendbc/safety/tests/test_hyundai_ccnc_angle_two.py",
"opendbc_repo/opendbc/safety/tests/test_hyundai_ioniq6_long.py",
"opendbc_repo/opendbc/safety/tests/test_hyundai_ray_pedal.py",
"opendbc_repo/opendbc/safety/tests/test_hyundai_daw.py",
"opendbc_repo/opendbc/safety/tests/test_honda_mvl_stock.py",
"opendbc_repo/opendbc/safety/tests/test_honda_stock_aol.py",
"opendbc_repo/opendbc/safety/tests/test_mazda_stock_aol.py",