mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-12 23:43:44 +08:00
Build matching HKG coffee-break advisory firmware
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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))
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
extern const uint8_t gitversion[29];
|
||||
const uint8_t gitversion[29] = "DEV-fb7592f8-Pf38f504f-DEBUG";
|
||||
const uint8_t gitversion[29] = "DEV-507373cb-Pf38f504f-DEBUG";
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
DEV-fb7592f8-Pf38f504f-DEBUG
|
||||
DEV-507373cb-Pf38f504f-DEBUG
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"protected_inventory_sha256": "f77538c0677ffa3f40bef86667c6855d28def0fa52bf85ea9becb647f6349d0b", "schema_version": 1}
|
||||
{"protected_inventory_sha256": "a9f0267198b34ea37835792ba6838da6cbc6ecd63fb7e96fab256692f2e4bede", "schema_version": 1}
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user