diff --git a/board/safety/safety_honda.h b/board/safety/safety_honda.h index dde27cdb0f5..7f1a73be664 100644 --- a/board/safety/safety_honda.h +++ b/board/safety/safety_honda.h @@ -353,9 +353,8 @@ static bool honda_tx_hook(CANPacket_t *to_send) { } } - // FORCE CANCEL: safety check only relevant when spamming the cancel button in Bosch HW - // ensuring that only the cancel button press is sent (VAL 2) when controls are off. - // This avoids unintended engagements while still allowing resume spam + // FORCE CANCEL: safety check for Bosch HW ensuring that only the cancel button press is sent (VAL 2) when + // controls are off. This avoids unintended engagements while still allowing resume spam and button passthrough. if ((addr == 0x296) && !controls_allowed && (bus == bus_buttons)) { if (((GET_BYTE(to_send, 0) >> 5) & 0x7U) != 2U) { tx = false; @@ -460,7 +459,11 @@ static int honda_bosch_fwd_hook(int bus_num, int addr) { int bus_fwd = -1; if (bus_num == 0) { - bus_fwd = 2; + int is_button_msg = (addr == 0x296); + bool block_msg = is_button_msg && controls_allowed && honda_bosch_radarless && !honda_bosch_long; + if (!block_msg) { + bus_fwd = 2; + } } if (bus_num == 2) { int is_lkas_msg = (addr == 0xE4) || (addr == 0xE5) || (addr == 0x33D) || (addr == 0x33DA) || (addr == 0x33DB); diff --git a/tests/safety/test_honda.py b/tests/safety/test_honda.py index 08d069b5ed8..11d6c3f3d8b 100755 --- a/tests/safety/test_honda.py +++ b/tests/safety/test_honda.py @@ -579,6 +579,24 @@ def setUp(self): self.safety.set_safety_hooks(Panda.SAFETY_HONDA_BOSCH, Panda.FLAG_HONDA_RADARLESS) self.safety.init_tests() + # Radarless must be able to send more buttons than cars that only spam + def test_spam_cancel_safety_check(self): + pass + + # Test that radarless can send any button when engaged. Only allow cancel when disengaged. + def test_button_tx_radarless(self): + for controls_allowed in [False, True]: + self.safety.set_controls_allowed(controls_allowed) + self.assertTrue(self._tx(self._button_msg(Btn.CANCEL, bus=self.BUTTONS_BUS))) + for button in (Btn.MAIN, Btn.RESUME, Btn.SET, Btn.NONE): + self.assertEqual(controls_allowed, self._tx(self._button_msg(button, bus=self.BUTTONS_BUS))) + + # Test that buttons only forward when disengaged + def test_button_fwd_radarless(self): + self.safety.set_controls_allowed(True) + self.FWD_BLACKLISTED_ADDRS[0] = [0x296] + super().test_fwd_hook() + self.FWD_BLACKLISTED_ADDRS[0] = [] class TestHondaBoschRadarlessAltBrakeSafety(HondaPcmEnableBase, TestHondaBoschRadarlessSafetyBase, TestHondaBoschAltBrakeSafetyBase): """