diff --git a/board/safety/safety_hyundai.h b/board/safety/safety_hyundai.h index 49c8641fc..9930f6e77 100644 --- a/board/safety/safety_hyundai.h +++ b/board/safety/safety_hyundai.h @@ -324,6 +324,10 @@ static int hyundai_tx_hook(CANPacket_t *to_send, bool longitudinal_allowed) { if (addr == 832) { int desired_torque = ((GET_BYTES_04(to_send) >> 16) & 0x7ffU) - 1024U; bool steer_req = GET_BIT(to_send, 27U) != 0U; + bool toi_flt = GET_BIT(to_send, 28U) != 0U; + if (toi_flt && !controls_allowed) { + tx = 0; + } if (steer_torque_cmd_checks(desired_torque, steer_req, HYUNDAI_STEERING_LIMITS)) { tx = 0; diff --git a/tests/safety/test_hyundai.py b/tests/safety/test_hyundai.py index 39aa9c37a..f3ac2e598 100755 --- a/tests/safety/test_hyundai.py +++ b/tests/safety/test_hyundai.py @@ -174,8 +174,8 @@ class TestHyundaiSafety(HyundaiButtonBase, common.PandaSafetyTest, common.Driver values = {"CR_Mdps_StrColTq": torque} return self.packer.make_can_msg_panda("MDPS12", 0, values) - def _torque_cmd_msg(self, torque, steer_req=1): - values = {"CR_Lkas_StrToqReq": torque, "CF_Lkas_ActToi": steer_req} + def _torque_cmd_msg(self, torque, steer_req=1, toi_flt=0): + values = {"CR_Lkas_StrToqReq": torque, "CF_Lkas_ActToi": steer_req, "CF_Lkas_ToiFlt": toi_flt} return self.packer.make_can_msg_panda("LKAS11", 0, values) def test_steer_req_bit(self): @@ -194,6 +194,14 @@ class TestHyundaiSafety(HyundaiButtonBase, common.PandaSafetyTest, common.Driver for _ in range(100): self.assertTrue(self._tx(self._torque_cmd_msg(self.MAX_TORQUE, steer_req=1))) + def test_toi_flt_bit(self): + # No actuation of fault bit while controls are not allowed + for controls_allowed in [True, False]: + for toi_flt in [0, 1]: + self.safety.set_controls_allowed(controls_allowed) + should_tx = toi_flt == 0 or controls_allowed + self.assertEqual(should_tx, self._tx(self._torque_cmd_msg(0, toi_flt=toi_flt))) + class TestHyundaiSafetyCameraSCC(TestHyundaiSafety): BUTTONS_BUS = 2 # tx on 2, rx on 0