diff --git a/board/safety/safety_hyundai.h b/board/safety/safety_hyundai.h index 3e9d23216c..f103fc5a14 100644 --- a/board/safety/safety_hyundai.h +++ b/board/safety/safety_hyundai.h @@ -32,6 +32,16 @@ static const CanMsg HYUNDAI_TX_MSGS[] = { {0x485, 0, 4}, // LFAHDA_MFC Bus 0 }; +#define HYUNDAI_LONG_COMMON_TX_MSGS(scc_bus) \ + {0x340, 0, 8}, \ + {0x4F1, scc_bus, 4}, \ + {0x485, 0, 4}, \ + {0x420, 0, 8}, \ + {0x421, 0, 8}, \ + {0x50A, 0, 8}, \ + {0x389, 0, 8}, \ + {0x4A2, 0, 2}, \ + #define HYUNDAI_COMMON_RX_CHECKS(legacy) \ {.msg = {{0x260, 0, 8, .check_checksum = true, .max_counter = 3U, .frequency = 100U}, \ {0x371, 0, 8, .frequency = 100U}, { 0 }}}, \ @@ -120,7 +130,7 @@ static void hyundai_rx_hook(const CANPacket_t *to_push) { int addr = GET_ADDR(to_push); // SCC12 is on bus 2 for camera-based SCC cars, bus 0 on all others - if ((addr == 0x421) && (((bus == 0) && !hyundai_camera_scc) || ((bus == 2) && hyundai_camera_scc))) { + if ((addr == 0x421) && (((bus == 0) && !hyundai_camera_scc) || ((bus == 2) && hyundai_camera_scc && !hyundai_longitudinal))) { // 2 bits: 13-14 int cruise_engaged = (GET_BYTES(to_push, 0, 4) >> 13) & 0x3U; hyundai_common_cruise_state_check(cruise_engaged); @@ -165,7 +175,7 @@ static void hyundai_rx_hook(const CANPacket_t *to_push) { // If openpilot is controlling longitudinal we need to ensure the radar is turned off // Enforce by checking we don't see SCC12 - if (hyundai_longitudinal && (addr == 0x421)) { + if (hyundai_longitudinal && !hyundai_camera_scc && (addr == 0x421)) { stock_ecu_detected = true; } generic_rx_checks(stock_ecu_detected); @@ -250,8 +260,16 @@ static int hyundai_fwd_hook(int bus_num, int addr) { if (bus_num == 0) { bus_fwd = 2; } - if ((bus_num == 2) && (addr != 0x340) && (addr != 0x485)) { - bus_fwd = 0; + + if (bus_num == 2) { + bool is_lkas11_msg = (addr == 0x340); + bool is_lfahda_mfc_msg = (addr == 0x485); + bool is_scc_msg = (addr == 0x420) || (addr == 0x421) || (addr == 0x50A) || (addr == 0x389); + + bool block_msg = is_lkas11_msg || is_lfahda_mfc_msg || (is_scc_msg && hyundai_longitudinal && hyundai_camera_scc); + if (!block_msg) { + bus_fwd = 0; + } } return bus_fwd; @@ -259,14 +277,7 @@ static int hyundai_fwd_hook(int bus_num, int addr) { static safety_config hyundai_init(uint16_t param) { static const CanMsg HYUNDAI_LONG_TX_MSGS[] = { - {0x340, 0, 8}, // LKAS11 Bus 0 - {0x4F1, 0, 4}, // CLU11 Bus 0 - {0x485, 0, 4}, // LFAHDA_MFC Bus 0 - {0x420, 0, 8}, // SCC11 Bus 0 - {0x421, 0, 8}, // SCC12 Bus 0 - {0x50A, 0, 8}, // SCC13 Bus 0 - {0x389, 0, 8}, // SCC14 Bus 0 - {0x4A2, 0, 2}, // FRT_RADAR11 Bus 0 + HYUNDAI_LONG_COMMON_TX_MSGS(0) {0x38D, 0, 8}, // FCA11 Bus 0 {0x483, 0, 8}, // FCA12 Bus 0 {0x7D0, 0, 8}, // radar UDS TX addr Bus 0 (for radar disable) @@ -278,13 +289,13 @@ static safety_config hyundai_init(uint16_t param) { {0x485, 0, 4}, // LFAHDA_MFC Bus 0 }; + static const CanMsg HYUNDAI_CAMERA_SCC_LONG_TX_MSGS[] = { + HYUNDAI_LONG_COMMON_TX_MSGS(2) + }; + hyundai_common_init(param); hyundai_legacy = false; - if (hyundai_camera_scc) { - hyundai_longitudinal = false; - } - safety_config ret; if (hyundai_longitudinal) { static RxCheck hyundai_long_rx_checks[] = { @@ -293,7 +304,8 @@ static safety_config hyundai_init(uint16_t param) { {.msg = {{0x4F1, 0, 4, .check_checksum = false, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, }; - ret = BUILD_SAFETY_CFG(hyundai_long_rx_checks, HYUNDAI_LONG_TX_MSGS); + ret = hyundai_camera_scc ? BUILD_SAFETY_CFG(hyundai_long_rx_checks, HYUNDAI_CAMERA_SCC_LONG_TX_MSGS) : \ + BUILD_SAFETY_CFG(hyundai_long_rx_checks, HYUNDAI_LONG_TX_MSGS); } else if (hyundai_camera_scc) { static RxCheck hyundai_cam_scc_rx_checks[] = { HYUNDAI_COMMON_RX_CHECKS(false) diff --git a/tests/safety/common.py b/tests/safety/common.py index 884f21a360..253d7bf0ce 100644 --- a/tests/safety/common.py +++ b/tests/safety/common.py @@ -792,6 +792,11 @@ def test_tx_hook_on_wrong_safety_mode(self): if attr.startswith('TestHonda'): # exceptions for common msgs across different hondas tx = list(filter(lambda m: m[0] not in [0x1FA, 0x30C, 0x33D, 0x33DB], tx)) + + # TODO: Temporary, should be fixed in panda firmware, safety_hyundai.h + if attr.startswith('TestHyundaiLongitudinal'): + # exceptions for common msgs across different Hyundai CAN platforms + tx = list(filter(lambda m: m[0] not in [0x420, 0x50A, 0x389, 0x4A2], tx)) all_tx.append([[m[0], m[1], attr] for m in tx]) # make sure we got all the msgs diff --git a/tests/safety/test_hyundai.py b/tests/safety/test_hyundai.py index 1bff99fa75..a1dd778735 100755 --- a/tests/safety/test_hyundai.py +++ b/tests/safety/test_hyundai.py @@ -212,5 +212,37 @@ def test_no_aeb_scc12(self): self.assertFalse(self._tx(self._accel_msg(0, aeb_decel=1.0))) +class TestHyundaiLongitudinalSafetyCameraSCC(HyundaiLongitudinalBase, TestHyundaiSafety): + TX_MSGS = [[0x340, 0], [0x4F1, 2], [0x485, 0], [0x420, 0], [0x421, 0], [0x50A, 0], [0x389, 0], [0x4A2, 0]] + + FWD_BLACKLISTED_ADDRS = {2: [0x340, 0x485, 0x420, 0x421, 0x50A, 0x389]} + + def setUp(self): + self.packer = CANPackerPanda("hyundai_kia_generic") + self.safety = libpanda_py.libpanda + self.safety.set_safety_hooks(Panda.SAFETY_HYUNDAI, Panda.FLAG_HYUNDAI_LONG | Panda.FLAG_HYUNDAI_CAMERA_SCC) + self.safety.init_tests() + + def _accel_msg(self, accel, aeb_req=False, aeb_decel=0): + values = { + "aReqRaw": accel, + "aReqValue": accel, + "AEB_CmdAct": int(aeb_req), + "CR_VSM_DecCmd": aeb_decel, + } + return self.packer.make_can_msg_panda("SCC12", self.SCC_BUS, values) + + def test_no_aeb_scc12(self): + self.assertTrue(self._tx(self._accel_msg(0))) + self.assertFalse(self._tx(self._accel_msg(0, aeb_req=True))) + self.assertFalse(self._tx(self._accel_msg(0, aeb_decel=1.0))) + + def test_tester_present_allowed(self): + pass + + def test_disabled_ecu_alive(self): + pass + + if __name__ == "__main__": unittest.main()