From cfcce8f06bc4b94aafa5daed1e003c8d844192de Mon Sep 17 00:00:00 2001 From: rbiasini Date: Fri, 15 Nov 2019 00:32:45 -0800 Subject: [PATCH] WIP: Relay malfunction (#384) * relay malfunction handling. WIP * more cars to relay_malfunctions * fixed safety tests * minor change * Fix linter * all cars now have a relay_malfunction safety check * added relay_malfunction safety test for fwd hooks * added proper regression tests for relay malfunction to all cars * temp patch to not fail regression in honda bosch * also addr 0x194 is some nidec honda is steer control * proper relay check for honda bosch too --- board/safety/safety_chrysler.h | 34 +++++++--------- board/safety/safety_defaults.h | 6 ++- board/safety/safety_ford.h | 14 ++++++- board/safety/safety_gm.h | 15 ++----- board/safety/safety_honda.h | 68 ++++++++++++++++++++----------- board/safety/safety_hyundai.h | 40 ++++-------------- board/safety/safety_mazda.h | 37 ++++------------- board/safety/safety_subaru.h | 37 ++++++++++------- board/safety/safety_toyota.h | 20 ++++----- board/safety/safety_volkswagen.h | 52 ++++++++++++----------- board/safety_declarations.h | 9 ++-- tests/safety/common.py | 9 ++++ tests/safety/libpandasafety_py.py | 6 +-- tests/safety/test.c | 24 ++++------- tests/safety/test_chrysler.py | 12 ++++-- tests/safety/test_gm.py | 4 ++ tests/safety/test_honda.py | 50 ++++++++++++++--------- tests/safety/test_honda_bosch.py | 28 ++++++++----- tests/safety/test_hyundai.py | 14 ++++--- tests/safety/test_subaru.py | 32 ++++++++++----- tests/safety/test_toyota.py | 12 ++++-- tests/safety/test_volkswagen.py | 38 +++++++++++------ 22 files changed, 300 insertions(+), 261 deletions(-) create mode 100644 tests/safety/common.py diff --git a/board/safety/safety_chrysler.h b/board/safety/safety_chrysler.h index e9590d86b73b73..7085b2a5bd7cfd 100644 --- a/board/safety/safety_chrysler.h +++ b/board/safety/safety_chrysler.h @@ -5,7 +5,6 @@ const int CHRYSLER_MAX_RATE_UP = 3; const int CHRYSLER_MAX_RATE_DOWN = 3; const int CHRYSLER_MAX_TORQUE_ERROR = 80; // max torque cmd in excess of torque motor -bool chrysler_camera_detected = 0; // is giraffe switch 2 high? int chrysler_rt_torque_last = 0; int chrysler_desired_torque_last = 0; int chrysler_cruise_engaged_last = 0; @@ -36,10 +35,9 @@ static void chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { chrysler_cruise_engaged_last = cruise_engaged; } - // check if stock camera ECU is still online + // check if stock camera ECU is on bus 0 if ((bus == 0) && (addr == 0x292)) { - chrysler_camera_detected = 1; - controls_allowed = 0; + relay_malfunction = true; } } @@ -48,8 +46,7 @@ static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { int addr = GET_ADDR(to_send); int tx = 1; - // If camera is on bus 0, then nothing can be sent - if (chrysler_camera_detected) { + if (relay_malfunction) { tx = 0; } @@ -108,30 +105,27 @@ static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { return tx; } -static void chrysler_init(int16_t param) { - UNUSED(param); - controls_allowed = 0; - chrysler_camera_detected = 0; -} - static int chrysler_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { int bus_fwd = -1; int addr = GET_ADDR(to_fwd); - // forward CAN 0 -> 2 so stock LKAS camera sees messages - if ((bus_num == 0) && !chrysler_camera_detected) { - bus_fwd = 2; - } - // forward all messages from camera except LKAS_COMMAND and LKAS_HUD - if ((bus_num == 2) && !chrysler_camera_detected && (addr != 658) && (addr != 678)) { - bus_fwd = 0; + + if (!relay_malfunction) { + // forward CAN 0 -> 2 so stock LKAS camera sees messages + if (bus_num == 0) { + bus_fwd = 2; + } + // forward all messages from camera except LKAS_COMMAND and LKAS_HUD + if ((bus_num == 2) && (addr != 658) && (addr != 678)) { + bus_fwd = 0; + } } return bus_fwd; } const safety_hooks chrysler_hooks = { - .init = chrysler_init, + .init = nooutput_init, .rx = chrysler_rx_hook, .tx = chrysler_tx_hook, .tx_lin = nooutput_tx_lin_hook, diff --git a/board/safety/safety_defaults.h b/board/safety/safety_defaults.h index 2743db96fe6eff..4733438c9c4bd1 100644 --- a/board/safety/safety_defaults.h +++ b/board/safety/safety_defaults.h @@ -6,7 +6,8 @@ void default_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { static void nooutput_init(int16_t param) { UNUSED(param); - controls_allowed = 0; + controls_allowed = false; + relay_malfunction = false; } static int nooutput_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { @@ -39,7 +40,8 @@ const safety_hooks nooutput_hooks = { static void alloutput_init(int16_t param) { UNUSED(param); - controls_allowed = 1; + controls_allowed = true; + relay_malfunction = false; } static int alloutput_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { diff --git a/board/safety/safety_ford.h b/board/safety/safety_ford.h index 22fc604ff1dd9d..297f9f54a710bb 100644 --- a/board/safety/safety_ford.h +++ b/board/safety/safety_ford.h @@ -14,6 +14,7 @@ bool ford_moving = false; static void ford_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { int addr = GET_ADDR(to_push); + int bus = GET_BUS(to_push); if (addr == 0x217) { // wheel speeds are 14 bits every 16 @@ -53,6 +54,10 @@ static void ford_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { } ford_gas_prev = gas; } + + if ((bus == 0) && (addr == 0x3CA)) { + relay_malfunction = true; + } } // all commands: just steering @@ -64,11 +69,16 @@ static void ford_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { static int ford_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { int tx = 1; + int addr = GET_ADDR(to_send); + // disallow actuator commands if gas or brake (with vehicle moving) are pressed // and the the latching controls_allowed flag is True int pedal_pressed = ford_gas_prev || (ford_brake_prev && ford_moving); bool current_controls_allowed = controls_allowed && !(pedal_pressed); - int addr = GET_ADDR(to_send); + + if (relay_malfunction) { + tx = 0; + } // STEER: safety check if (addr == 0x3CA) { @@ -92,6 +102,8 @@ static int ford_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { return tx; } +// TODO: keep camera on bus 2 and make a fwd_hook + const safety_hooks ford_hooks = { .init = nooutput_init, .rx = ford_rx_hook, diff --git a/board/safety/safety_gm.h b/board/safety/safety_gm.h index 452f70953df640..a704d91f40cd54 100644 --- a/board/safety/safety_gm.h +++ b/board/safety/safety_gm.h @@ -22,8 +22,6 @@ const int GM_MAX_BRAKE = 350; int gm_brake_prev = 0; int gm_gas_prev = 0; bool gm_moving = false; -// silence everything if stock car control ECUs are still online -bool gm_ascm_detected = 0; int gm_rt_torque_last = 0; int gm_desired_torque_last = 0; uint32_t gm_ts_last = 0; @@ -51,8 +49,7 @@ static void gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // 384 = ASCMLKASteeringCmd // 715 = ASCMGasRegenCmd if ((bus_number == 0) && ((addr == 384) || (addr == 715))) { - gm_ascm_detected = 1; - controls_allowed = 0; + relay_malfunction = true; } // ACC steering wheel buttons @@ -114,8 +111,7 @@ static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { int tx = 1; - // There can be only one! (ASCM) - if (gm_ascm_detected) { + if (relay_malfunction) { tx = 0; } @@ -213,14 +209,9 @@ static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { return tx; } -static void gm_init(int16_t param) { - UNUSED(param); - controls_allowed = 0; -} - const safety_hooks gm_hooks = { - .init = gm_init, + .init = nooutput_init, .rx = gm_rx_hook, .tx = gm_tx_hook, .tx_lin = nooutput_tx_lin_hook, diff --git a/board/safety/safety_honda.h b/board/safety/safety_honda.h index f59e288812a7cf..53439934dbd065 100644 --- a/board/safety/safety_honda.h +++ b/board/safety/safety_honda.h @@ -98,6 +98,16 @@ static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // Leave honda forward brake as is } } + + // if steering controls messages are received on the destination bus, it's an indication + // that the relay might be malfucntioning + int bus_rdr_car = (board_has_relay()) ? 0 : 2; // radar bus, car side + if ((addr == 0xE4) || (addr == 0x194)) { + if ((honda_bosch_hardware && (bus == bus_rdr_car)) || + (!honda_bosch_hardware && (bus == 0))) { + relay_malfunction = true; + } + } } // all commands: gas, brake and steering @@ -112,6 +122,10 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { int addr = GET_ADDR(to_send); int bus = GET_BUS(to_send); + if (relay_malfunction) { + tx = 0; + } + // disallow actuator commands if gas or brake (with vehicle moving) are pressed // and the the latching controls_allowed flag is True int pedal_pressed = honda_gas_prev || (gas_interceptor_prev > HONDA_GAS_INTERCEPTOR_THRESHOLD) || @@ -170,13 +184,15 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { static void honda_init(int16_t param) { UNUSED(param); - controls_allowed = 0; + controls_allowed = false; + relay_malfunction = false; honda_bosch_hardware = false; honda_alt_brake_msg = false; } static void honda_bosch_init(int16_t param) { - controls_allowed = 0; + controls_allowed = false; + relay_malfunction = false; honda_bosch_hardware = true; // Checking for alternate brake override from safety parameter honda_alt_brake_msg = (param == 1) ? true : false; @@ -189,20 +205,22 @@ static int honda_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { // 0x39f is radar hud int bus_fwd = -1; - if (bus_num == 0) { - bus_fwd = 2; - } - if (bus_num == 2) { - // block stock lkas messages and stock acc messages (if OP is doing ACC) - int addr = GET_ADDR(to_fwd); - bool is_lkas_msg = (addr == 0xE4) || (addr == 0x194) || (addr == 0x33D); - bool is_acc_hud_msg = (addr == 0x30C) || (addr == 0x39F); - bool is_brake_msg = addr == 0x1FA; - bool block_fwd = is_lkas_msg || - (is_acc_hud_msg && long_controls_allowed) || - (is_brake_msg && long_controls_allowed && !honda_fwd_brake); - if (!block_fwd) { - bus_fwd = 0; + if (!relay_malfunction) { + if (bus_num == 0) { + bus_fwd = 2; + } + if (bus_num == 2) { + // block stock lkas messages and stock acc messages (if OP is doing ACC) + int addr = GET_ADDR(to_fwd); + bool is_lkas_msg = (addr == 0xE4) || (addr == 0x194) || (addr == 0x33D); + bool is_acc_hud_msg = (addr == 0x30C) || (addr == 0x39F); + bool is_brake_msg = addr == 0x1FA; + bool block_fwd = is_lkas_msg || + (is_acc_hud_msg && long_controls_allowed) || + (is_brake_msg && long_controls_allowed && !honda_fwd_brake); + if (!block_fwd) { + bus_fwd = 0; + } } } return bus_fwd; @@ -213,14 +231,16 @@ static int honda_bosch_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { int bus_rdr_cam = (board_has_relay()) ? 2 : 1; // radar bus, camera side int bus_rdr_car = (board_has_relay()) ? 0 : 2; // radar bus, car side - if (bus_num == bus_rdr_car) { - bus_fwd = bus_rdr_cam; - } - if (bus_num == bus_rdr_cam) { - int addr = GET_ADDR(to_fwd); - int is_lkas_msg = (addr == 0xE4) || (addr == 0x33D); - if (!is_lkas_msg) { - bus_fwd = bus_rdr_car; + if (!relay_malfunction) { + if (bus_num == bus_rdr_car) { + bus_fwd = bus_rdr_cam; + } + if (bus_num == bus_rdr_cam) { + int addr = GET_ADDR(to_fwd); + int is_lkas_msg = (addr == 0xE4) || (addr == 0x33D); + if (!is_lkas_msg) { + bus_fwd = bus_rdr_car; + } } } return bus_fwd; diff --git a/board/safety/safety_hyundai.h b/board/safety/safety_hyundai.h index 2e49f34f73d58b..b4b079521a122e 100644 --- a/board/safety/safety_hyundai.h +++ b/board/safety/safety_hyundai.h @@ -6,9 +6,6 @@ const int HYUNDAI_MAX_RATE_DOWN = 7; const int HYUNDAI_DRIVER_TORQUE_ALLOWANCE = 50; const int HYUNDAI_DRIVER_TORQUE_FACTOR = 2; -bool hyundai_camera_detected = 0; -bool hyundai_giraffe_switch_2 = 0; // is giraffe switch 2 high? -int hyundai_camera_bus = 0; int hyundai_rt_torque_last = 0; int hyundai_desired_torque_last = 0; int hyundai_cruise_engaged_last = 0; @@ -25,15 +22,9 @@ static void hyundai_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { update_sample(&hyundai_torque_driver, torque_driver_new); } - // check if stock camera ECU is still online + // check if stock camera ECU is on bus 0 if ((bus == 0) && (addr == 832)) { - hyundai_camera_detected = 1; - controls_allowed = 0; - } - - // Find out which bus the camera is on - if (addr == 832) { - hyundai_camera_bus = bus; + relay_malfunction = true; } // enter controls on rising edge of ACC, exit controls on ACC off @@ -48,11 +39,6 @@ static void hyundai_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { } hyundai_cruise_engaged_last = cruise_engaged; } - - // 832 is lkas cmd. If it is on camera bus, then giraffe switch 2 is high - if ((addr == 832) && (bus == hyundai_camera_bus) && (hyundai_camera_bus != 0)) { - hyundai_giraffe_switch_2 = 1; - } } static int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { @@ -60,8 +46,7 @@ static int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { int tx = 1; int addr = GET_ADDR(to_send); - // There can be only one! (camera) - if (hyundai_camera_detected) { + if (relay_malfunction) { tx = 0; } @@ -128,29 +113,22 @@ static int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { static int hyundai_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { int bus_fwd = -1; + int addr = GET_ADDR(to_fwd); // forward cam to ccan and viceversa, except lkas cmd - if (hyundai_giraffe_switch_2) { + if (!relay_malfunction) { if (bus_num == 0) { - bus_fwd = hyundai_camera_bus; + bus_fwd = 2; } - if (bus_num == hyundai_camera_bus) { - int addr = GET_ADDR(to_fwd); - if (addr != 832) { - bus_fwd = 0; - } + if ((bus_num == 2) && (addr != 832)) { + bus_fwd = 0; } } return bus_fwd; } -static void hyundai_init(int16_t param) { - UNUSED(param); - controls_allowed = 0; - hyundai_giraffe_switch_2 = 0; -} const safety_hooks hyundai_hooks = { - .init = hyundai_init, + .init = nooutput_init, .rx = hyundai_rx_hook, .tx = hyundai_tx_hook, .tx_lin = nooutput_tx_lin_hook, diff --git a/board/safety/safety_mazda.h b/board/safety/safety_mazda.h index 043f337c7017ce..acb60e1457f2ea 100644 --- a/board/safety/safety_mazda.h +++ b/board/safety/safety_mazda.h @@ -30,12 +30,6 @@ uint32_t mazda_ts_last = 0; struct sample_t mazda_torque_driver; // last few driver torques measured // track msgs coming from OP so that we know what CAM msgs to drop and what to forward -int mazda_op_lkas_detected = 0; -int mazda_op_laneinfo_detected = 0; - -int mazda_forward_cam = 0; -int mazda_giraffe_switch_2_on = 0; - void mazda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { int bus = GET_BUS(to_push); int addr = GET_ADDR(to_push); @@ -60,17 +54,9 @@ void mazda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { mazda_cruise_engaged_last = cruise_engaged; } - // we have msgs on bus MAZDA_CAM - if (bus == MAZDA_CAM) { - // the stock CAM is connected - if (addr == MAZDA_LKAS) { - mazda_forward_cam = 1; - } - // if we see wheel speed msgs on MAZDA_CAM bus then giraffe switch 2 is high - // (hardware passthru) - if (addr == MAZDA_WHEEL_SPEED) { - mazda_giraffe_switch_2_on = 1; - } + // if we see wheel speed msgs on MAZDA_CAM bus then relay is closed + if ((bus == MAZDA_CAM) && (addr == MAZDA_WHEEL_SPEED)) { + relay_malfunction = true; } } @@ -79,15 +65,12 @@ static int mazda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { int addr = GET_ADDR(to_send); int bus = GET_BUS(to_send); + if (relay_malfunction) { + tx = 0; + } + // Check if msg is sent on the main BUS if (bus == MAZDA_MAIN) { - if ((addr == MAZDA_LKAS) && !mazda_op_lkas_detected){ - mazda_op_lkas_detected = 1; - } - if ((addr == MAZDA_LANEINFO) && !mazda_op_laneinfo_detected){ - mazda_op_laneinfo_detected = 1; - } - // steer cmd checks if (addr == MAZDA_LKAS) { int desired_torque = (((GET_BYTE(to_send, 0) & 0x0f) << 8) | GET_BYTE(to_send, 1)) - MAZDA_MAX_STEER; @@ -140,15 +123,13 @@ static int mazda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { static int mazda_fwd_hook(int bus, CAN_FIFOMailBox_TypeDef *to_fwd) { int bus_fwd = -1; - if (mazda_forward_cam && !mazda_giraffe_switch_2_on) { + if (!relay_malfunction) { int addr = GET_ADDR(to_fwd); if (bus == MAZDA_MAIN) { bus_fwd = MAZDA_CAM; } else if (bus == MAZDA_CAM) { - // drop stock CAM_LKAS and CAM_LANEINFI if OP is sending them - if (!((addr == MAZDA_LKAS) && mazda_op_lkas_detected) && - !((addr == MAZDA_LANEINFO) && mazda_op_laneinfo_detected)) { + if (!(addr == MAZDA_LKAS)) { bus_fwd = MAZDA_MAIN; } } diff --git a/board/safety/safety_subaru.h b/board/safety/safety_subaru.h index c09b9d6225ed19..147fbb2d28e08f 100644 --- a/board/safety/safety_subaru.h +++ b/board/safety/safety_subaru.h @@ -38,12 +38,20 @@ static void subaru_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { } subaru_cruise_engaged_last = cruise_engaged; } + + if ((bus == 0) && ((addr == 0x122) || (addr == 0x164))) { + relay_malfunction = true; + } } static int subaru_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { int tx = 1; int addr = GET_ADDR(to_send); + if (relay_malfunction) { + tx = 0; + } + // steer cmd checks if ((addr == 0x122) || (addr == 0x164)) { int bit_shift = (addr == 0x122) ? 16 : 8; @@ -98,23 +106,24 @@ static int subaru_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { } static int subaru_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { - int bus_fwd = -1; - if (bus_num == 0) { - bus_fwd = 2; // Camera CAN - } - if (bus_num == 2) { - // 290 is LKAS for Global Platform - // 356 is LKAS for outback 2015 - // 545 is ES_Distance - // 802 is ES_LKAS - int addr = GET_ADDR(to_fwd); - int block_msg = (addr == 290) || (addr == 356) || (addr == 545) || (addr == 802); - if (!block_msg) { - bus_fwd = 0; // Main CAN + + if (!relay_malfunction) { + if (bus_num == 0) { + bus_fwd = 2; // Camera CAN + } + if (bus_num == 2) { + // 290 is LKAS for Global Platform + // 356 is LKAS for outback 2015 + // 545 is ES_Distance + // 802 is ES_LKAS + int addr = GET_ADDR(to_fwd); + int block_msg = (addr == 290) || (addr == 356) || (addr == 545) || (addr == 802); + if (!block_msg) { + bus_fwd = 0; // Main CAN + } } } - // fallback to do not forward return bus_fwd; } diff --git a/board/safety/safety_toyota.h b/board/safety/safety_toyota.h index 134cc845c97283..849101368a5ea1 100644 --- a/board/safety/safety_toyota.h +++ b/board/safety/safety_toyota.h @@ -22,8 +22,6 @@ const int TOYOTA_GAS_INTERCEPTOR_THRESHOLD = 475; // ratio between offset and g int toyota_dbc_eps_torque_factor = 100; // conversion factor for STEER_TORQUE_EPS in %: see dbc file // states -int toyota_giraffe_switch_1 = 0; // is giraffe switch 1 high? -int toyota_camera_forwarded = 0; // should we forward the camera bus? int toyota_desired_torque_last = 0; // last desired steer torque int toyota_rt_torque_last = 0; // last desired torque for real time check uint32_t toyota_ts_last = 0; @@ -87,14 +85,9 @@ static void toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { toyota_gas_prev = gas; } - // msgs are only on bus 2 if panda is connected to frc - if (bus == 2) { - toyota_camera_forwarded = 1; - } - - // 0x2E4 is lkas cmd. If it is on bus 0, then giraffe switch 1 is high + // 0x2E4 is lkas cmd. If it is on bus 0, then relay is unexpectedly closed if ((addr == 0x2E4) && (bus == 0)) { - toyota_giraffe_switch_1 = 1; + relay_malfunction = true; } } @@ -104,6 +97,10 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { int addr = GET_ADDR(to_send); int bus = GET_BUS(to_send); + if (relay_malfunction) { + tx = 0; + } + // Check if msg is sent on BUS 0 if (bus == 0) { @@ -191,15 +188,14 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { static void toyota_init(int16_t param) { controls_allowed = 0; - toyota_giraffe_switch_1 = 0; - toyota_camera_forwarded = 0; + relay_malfunction = 0; toyota_dbc_eps_torque_factor = param; } static int toyota_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { int bus_fwd = -1; - if (toyota_camera_forwarded && !toyota_giraffe_switch_1) { + if (!relay_malfunction) { if (bus_num == 0) { bus_fwd = 2; } diff --git a/board/safety/safety_volkswagen.h b/board/safety/safety_volkswagen.h index bb184cd91f5418..761905b842f943 100644 --- a/board/safety/safety_volkswagen.h +++ b/board/safety/safety_volkswagen.h @@ -21,11 +21,6 @@ int volkswagen_gas_prev = 0; #define MSG_LDW_02 0x397 #define MSG_KLEMMEN_STATUS_01 0x3C0 -static void volkswagen_init(int16_t param) { - UNUSED(param); // May use param in the future to indicate MQB vs PQ35/PQ46/NMS vs MLB, or wiring configuration. - controls_allowed = 0; -} - static void volkswagen_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { int bus = GET_BUS(to_push); int addr = GET_ADDR(to_push); @@ -58,6 +53,10 @@ static void volkswagen_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { } volkswagen_gas_prev = gas; } + + if ((bus == 0) && (addr == MSG_HCA_01)) { + relay_malfunction = true; + } } static int volkswagen_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { @@ -65,6 +64,10 @@ static int volkswagen_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { int bus = GET_BUS(to_send); int tx = 1; + if (relay_malfunction) { + tx = 0; + } + // Safety check for HCA_01 Heading Control Assist torque. if (addr == MSG_HCA_01) { bool violation = false; @@ -135,31 +138,32 @@ static int volkswagen_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { // NOTE: Will need refactoring for other bus layouts, such as no-forwarding at camera or J533 running-gear CAN - switch (bus_num) { - case 0: - // Forward all traffic from J533 gateway to Extended CAN devices. - bus_fwd = 2; - break; - case 2: - if ((addr == MSG_HCA_01) || (addr == MSG_LDW_02)) { - // OP takes control of the Heading Control Assist and Lane Departure Warning messages from the camera. + if (!relay_malfunction) { + switch (bus_num) { + case 0: + // Forward all traffic from J533 gateway to Extended CAN devices. + bus_fwd = 2; + break; + case 2: + if ((addr == MSG_HCA_01) || (addr == MSG_LDW_02)) { + // OP takes control of the Heading Control Assist and Lane Departure Warning messages from the camera. + bus_fwd = -1; + } else { + // Forward all remaining traffic from Extended CAN devices to J533 gateway. + bus_fwd = 0; + } + break; + default: + // No other buses should be in use; fallback to do-not-forward. bus_fwd = -1; - } else { - // Forward all remaining traffic from Extended CAN devices to J533 gateway. - bus_fwd = 0; - } - break; - default: - // No other buses should be in use; fallback to do-not-forward. - bus_fwd = -1; - break; + break; + } } - return bus_fwd; } const safety_hooks volkswagen_hooks = { - .init = volkswagen_init, + .init = nooutput_init, .rx = volkswagen_rx_hook, .tx = volkswagen_tx_hook, .tx_lin = nooutput_tx_lin_hook, diff --git a/board/safety_declarations.h b/board/safety_declarations.h index efa6a4e2b8744c..27d3d1f68a6a8a 100644 --- a/board/safety_declarations.h +++ b/board/safety_declarations.h @@ -40,13 +40,14 @@ typedef struct { fwd_hook fwd; } safety_hooks; -// This can be set by the safety hooks. -bool controls_allowed = 0; -bool gas_interceptor_detected = 0; +// This can be set by the safety hooks +bool controls_allowed = false; +bool relay_malfunction = false; +bool gas_interceptor_detected = false; int gas_interceptor_prev = 0; // This is set by USB command 0xdf -bool long_controls_allowed = 1; +bool long_controls_allowed = true; // avg between 2 tracks #define GET_INTERCEPTOR(msg) (((GET_BYTE((msg), 0) << 8) + GET_BYTE((msg), 1) + ((GET_BYTE((msg), 2) << 8) + GET_BYTE((msg), 3)) / 2 ) / 2) diff --git a/tests/safety/common.py b/tests/safety/common.py new file mode 100644 index 00000000000000..c16f7391118f69 --- /dev/null +++ b/tests/safety/common.py @@ -0,0 +1,9 @@ +def test_relay_malfunction(test, addr): + # input is a test class and the address that, if seen on bus 0, triggers + # the relay_malfunction logic + test.assertFalse(test.safety.get_relay_malfunction()) + test.safety.safety_rx_hook(test._send_msg(0, addr, 8)) + test.assertTrue(test.safety.get_relay_malfunction()) + for a in range(1, 0x800): + for b in range(0, 3): + test.assertFalse(test.safety.safety_tx_hook(test._send_msg(b, a, 8))) diff --git a/tests/safety/libpandasafety_py.py b/tests/safety/libpandasafety_py.py index ffe23c70d39aaf..5b1bd28c9ad7d9 100644 --- a/tests/safety/libpandasafety_py.py +++ b/tests/safety/libpandasafety_py.py @@ -34,6 +34,8 @@ void set_controls_allowed(bool c); bool get_controls_allowed(void); +void set_relay_malfunction(bool c); +bool get_relay_malfunction(void); void set_long_controls_allowed(bool c); bool get_long_controls_allowed(void); void set_gas_interceptor_detected(bool c); @@ -54,7 +56,6 @@ int get_toyota_gas_prev(void); void set_toyota_torque_meas(int min, int max); void set_toyota_desired_torque_last(int t); -void set_toyota_camera_forwarded(int t); void set_toyota_rt_torque_last(int t); void init_tests_honda(void); @@ -80,13 +81,10 @@ void set_hyundai_desired_torque_last(int t); void set_hyundai_rt_torque_last(int t); void set_hyundai_torque_driver(int min, int max); -void set_hyundai_giraffe_switch_2(int t); -void set_hyundai_camera_bus(int t); void init_tests_chrysler(void); void set_chrysler_desired_torque_last(int t); void set_chrysler_rt_torque_last(int t); -void set_chrysler_camera_detected(int t); int get_chrysler_torque_meas_min(void); int get_chrysler_torque_meas_max(void); void set_chrysler_torque_meas(int min, int max); diff --git a/tests/safety/test.c b/tests/safety/test.c index c61f64077c63b1..553d61edfa35e8 100644 --- a/tests/safety/test.c +++ b/tests/safety/test.c @@ -80,6 +80,10 @@ void set_controls_allowed(bool c){ controls_allowed = c; } +void set_relay_malfunction(bool c){ + relay_malfunction = c; +} + void set_long_controls_allowed(bool c){ long_controls_allowed = c; } @@ -96,6 +100,10 @@ bool get_controls_allowed(void){ return controls_allowed; } +bool get_relay_malfunction(void){ + return relay_malfunction; +} + bool get_long_controls_allowed(void){ return long_controls_allowed; } @@ -116,10 +124,6 @@ void set_timer(uint32_t t){ timer.CNT = t; } -void set_toyota_camera_forwarded(int t){ - toyota_camera_forwarded = t; -} - void set_toyota_torque_meas(int min, int max){ toyota_torque_meas.min = min; toyota_torque_meas.max = max; @@ -140,18 +144,6 @@ void set_hyundai_torque_driver(int min, int max){ hyundai_torque_driver.max = max; } -void set_hyundai_camera_bus(int t){ - hyundai_camera_bus = t; -} - -void set_hyundai_giraffe_switch_2(int t){ - hyundai_giraffe_switch_2 = t; -} - -void set_chrysler_camera_detected(int t){ - chrysler_camera_detected = t; -} - void set_chrysler_torque_meas(int min, int max){ chrysler_torque_meas.min = min; chrysler_torque_meas.max = max; diff --git a/tests/safety/test_chrysler.py b/tests/safety/test_chrysler.py index 32eb1cded35ecc..5d3db35153267d 100755 --- a/tests/safety/test_chrysler.py +++ b/tests/safety/test_chrysler.py @@ -3,6 +3,7 @@ import numpy as np import libpandasafety_py # pylint: disable=import-error from panda import Panda +from panda.tests.safety.common import test_relay_malfunction MAX_RATE_UP = 3 MAX_RATE_DOWN = 3 @@ -67,6 +68,9 @@ def _torque_msg(self, torque): to_send[0].RDLR = ((torque + 1024) >> 8) + (((torque + 1024) & 0xff) << 8) return to_send + def test_relay_malfunction(self): + test_relay_malfunction(self, 0x292) + def test_default_controls_not_allowed(self): self.assertFalse(self.safety.get_controls_allowed()) @@ -182,14 +186,14 @@ def test_torque_measurements(self): def test_fwd_hook(self): buss = list(range(0x0, 0x3)) msgs = list(range(0x1, 0x800)) - chrysler_camera_detected = [0, 1] + relay_malfunction = [0, 1] - for ccd in chrysler_camera_detected: - self.safety.set_chrysler_camera_detected(ccd) + for rm in relay_malfunction: + self.safety.set_relay_malfunction(rm) blocked_msgs = [658, 678] for b in buss: for m in msgs: - if not ccd: + if not rm: if b == 0: fwd_bus = 2 elif b == 1: diff --git a/tests/safety/test_gm.py b/tests/safety/test_gm.py index 9a2db31c354998..657336e8bf6ef2 100644 --- a/tests/safety/test_gm.py +++ b/tests/safety/test_gm.py @@ -3,6 +3,7 @@ import numpy as np import libpandasafety_py # pylint: disable=import-error from panda import Panda +from panda.tests.safety.common import test_relay_malfunction MAX_RATE_UP = 7 MAX_RATE_DOWN = 17 @@ -100,6 +101,9 @@ def _torque_msg(self, torque): to_send[0].RDLR = ((t >> 8) & 0x7) | ((t & 0xFF) << 8) return to_send + def test_relay_malfunction(self): + test_relay_malfunction(self, 384) + def test_default_controls_not_allowed(self): self.assertFalse(self.safety.get_controls_allowed()) diff --git a/tests/safety/test_honda.py b/tests/safety/test_honda.py index 7436dae4637eef..9187edd5ce62c4 100755 --- a/tests/safety/test_honda.py +++ b/tests/safety/test_honda.py @@ -3,6 +3,7 @@ import numpy as np import libpandasafety_py # pylint: disable=import-error from panda import Panda +from panda.tests.safety.common import test_relay_malfunction MAX_BRAKE = 255 @@ -86,6 +87,9 @@ def _send_steer_msg(self, steer): return to_send + def test_relay_malfunction(self): + test_relay_malfunction(self, 0xE4) + def test_default_controls_not_allowed(self): self.assertFalse(self.safety.get_controls_allowed()) @@ -258,30 +262,36 @@ def test_fwd_hook(self): buss = list(range(0x0, 0x3)) msgs = list(range(0x1, 0x800)) long_controls_allowed = [0, 1] + relay_malfunction = [0, 1] fwd_brake = [False, True] self.safety.set_honda_bosch_hardware(0) - for f in fwd_brake: - self.safety.set_honda_fwd_brake(f) - for l in long_controls_allowed: - self.safety.set_long_controls_allowed(l) - blocked_msgs = [0xE4, 0x194, 0x33D] - if l: - blocked_msgs += [0x30C, 0x39F] - if not f: - blocked_msgs += [0x1FA] - for b in buss: - for m in msgs: - if b == 0: - fwd_bus = 2 - elif b == 1: - fwd_bus = -1 - elif b == 2: - fwd_bus = -1 if m in blocked_msgs else 0 - - # assume len 8 - self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) + for rm in relay_malfunction: + self.safety.set_relay_malfunction(rm) + for f in fwd_brake: + self.safety.set_honda_fwd_brake(f) + for l in long_controls_allowed: + self.safety.set_long_controls_allowed(l) + blocked_msgs = [0xE4, 0x194, 0x33D] + if l: + blocked_msgs += [0x30C, 0x39F] + if not f: + blocked_msgs += [0x1FA] + for b in buss: + for m in msgs: + if not rm: + if b == 0: + fwd_bus = 2 + elif b == 1: + fwd_bus = -1 + elif b == 2: + fwd_bus = -1 if m in blocked_msgs else 0 + else: + fwd_bus = -1 + + # assume len 8 + self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) self.safety.set_long_controls_allowed(True) self.safety.set_honda_fwd_brake(False) diff --git a/tests/safety/test_honda_bosch.py b/tests/safety/test_honda_bosch.py index 6e0b21a997f26d..d717138f3aae4c 100755 --- a/tests/safety/test_honda_bosch.py +++ b/tests/safety/test_honda_bosch.py @@ -28,19 +28,25 @@ def test_fwd_hook(self): bus_rdr_cam = 2 if has_relay else 1 bus_rdr_car = 0 if has_relay else 2 bus_pt = 1 if has_relay else 0 + relay_malfunction = [0, 1] blocked_msgs = [0xE4, 0x33D] - for b in buss: - for m in msgs: - if b == bus_pt: - fwd_bus = -1 - elif b == bus_rdr_cam: - fwd_bus = -1 if m in blocked_msgs else bus_rdr_car - elif b == bus_rdr_car: - fwd_bus = bus_rdr_cam - - # assume len 8 - self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) + for rm in relay_malfunction: + self.safety.set_relay_malfunction(rm) + for b in buss: + for m in msgs: + if not rm: + if b == bus_pt: + fwd_bus = -1 + elif b == bus_rdr_cam: + fwd_bus = -1 if m in blocked_msgs else bus_rdr_car + elif b == bus_rdr_car: + fwd_bus = bus_rdr_cam + else: + fwd_bus = -1 + + # assume len 8 + self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) if __name__ == "__main__": diff --git a/tests/safety/test_hyundai.py b/tests/safety/test_hyundai.py index 0821fafa4bf119..780a7557430371 100644 --- a/tests/safety/test_hyundai.py +++ b/tests/safety/test_hyundai.py @@ -3,6 +3,7 @@ import numpy as np import libpandasafety_py # pylint: disable=import-error from panda import Panda +from panda.tests.safety.common import test_relay_malfunction MAX_RATE_UP = 3 MAX_RATE_DOWN = 7 @@ -62,6 +63,9 @@ def _torque_msg(self, torque): to_send[0].RDLR = (torque + 1024) << 16 return to_send + def test_relay_malfunction(self): + test_relay_malfunction(self, 832) + def test_default_controls_not_allowed(self): self.assertFalse(self.safety.get_controls_allowed()) @@ -180,7 +184,6 @@ def test_spam_cancel_safety_check(self): RESUME_BTN = 1 SET_BTN = 2 CANCEL_BTN = 4 - BUTTON_MSG = 1265 self.safety.set_controls_allowed(0) self.assertTrue(self.safety.safety_tx_hook(self._button_msg(CANCEL_BTN))) self.assertFalse(self.safety.safety_tx_hook(self._button_msg(RESUME_BTN))) @@ -193,15 +196,14 @@ def test_fwd_hook(self): buss = list(range(0x0, 0x3)) msgs = list(range(0x1, 0x800)) - hyundai_giraffe_switch_2 = [0, 1] + relay_malfunction = [0, 1] - self.safety.set_hyundai_camera_bus(2) - for hgs in hyundai_giraffe_switch_2: - self.safety.set_hyundai_giraffe_switch_2(hgs) + for rm in relay_malfunction: + self.safety.set_relay_malfunction(rm) blocked_msgs = [832] for b in buss: for m in msgs: - if hgs: + if not rm: if b == 0: fwd_bus = 2 elif b == 1: diff --git a/tests/safety/test_subaru.py b/tests/safety/test_subaru.py index 1985e9c4ea28e5..bf1e11c0329efb 100644 --- a/tests/safety/test_subaru.py +++ b/tests/safety/test_subaru.py @@ -3,6 +3,7 @@ import numpy as np import libpandasafety_py # pylint: disable=import-error from panda import Panda +from panda.tests.safety.common import test_relay_malfunction MAX_RATE_UP = 50 MAX_RATE_DOWN = 70 @@ -60,6 +61,9 @@ def _torque_msg(self, torque): to_send[0].RDLR = (t << 16) return to_send + def test_relay_malfunction(self): + test_relay_malfunction(self, 0x122) + def test_default_controls_not_allowed(self): self.assertFalse(self.safety.get_controls_allowed()) @@ -178,17 +182,23 @@ def test_fwd_hook(self): buss = list(range(0x0, 0x3)) msgs = list(range(0x1, 0x800)) blocked_msgs = [290, 356, 545, 802] - for b in buss: - for m in msgs: - if b == 0: - fwd_bus = 2 - elif b == 1: - fwd_bus = -1 - elif b == 2: - fwd_bus = -1 if m in blocked_msgs else 0 - - # assume len 8 - self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) + relay_malfunction = [0, 1] + for rm in relay_malfunction: + self.safety.set_relay_malfunction(rm) + for b in buss: + for m in msgs: + if not rm: + if b == 0: + fwd_bus = 2 + elif b == 1: + fwd_bus = -1 + elif b == 2: + fwd_bus = -1 if m in blocked_msgs else 0 + else: + fwd_bus = -1 + + # assume len 8 + self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) if __name__ == "__main__": diff --git a/tests/safety/test_toyota.py b/tests/safety/test_toyota.py index 7d2c3aa525ecb4..b5fdcac4a9e9a6 100644 --- a/tests/safety/test_toyota.py +++ b/tests/safety/test_toyota.py @@ -3,6 +3,7 @@ import numpy as np import libpandasafety_py # pylint: disable=import-error from panda import Panda +from panda.tests.safety.common import test_relay_malfunction MAX_RATE_UP = 10 MAX_RATE_DOWN = 25 @@ -97,6 +98,9 @@ def _pcm_cruise_msg(self, cruise_on): return to_send + def test_relay_malfunction(self): + test_relay_malfunction(self, 0x2E4) + def test_default_controls_not_allowed(self): self.assertFalse(self.safety.get_controls_allowed()) @@ -285,10 +289,10 @@ def test_fwd_hook(self): buss = list(range(0x0, 0x3)) msgs = list(range(0x1, 0x800)) long_controls_allowed = [0, 1] - toyota_camera_forwarded = [0, 1] + relay_malfunction = [0, 1] - for tcf in toyota_camera_forwarded: - self.safety.set_toyota_camera_forwarded(tcf) + for rm in relay_malfunction: + self.safety.set_relay_malfunction(rm) for lca in long_controls_allowed: self.safety.set_long_controls_allowed(lca) blocked_msgs = [0x2E4, 0x412, 0x191] @@ -296,7 +300,7 @@ def test_fwd_hook(self): blocked_msgs += [0x343] for b in buss: for m in msgs: - if tcf: + if not rm: if b == 0: fwd_bus = 2 elif b == 1: diff --git a/tests/safety/test_volkswagen.py b/tests/safety/test_volkswagen.py index 90c3e74c4c60d3..b41eb22491063b 100644 --- a/tests/safety/test_volkswagen.py +++ b/tests/safety/test_volkswagen.py @@ -3,6 +3,7 @@ import numpy as np import libpandasafety_py # pylint: disable=import-error from panda import Panda +from panda.tests.safety.common import test_relay_malfunction MAX_RATE_UP = 4 MAX_RATE_DOWN = 10 @@ -73,6 +74,9 @@ def _button_msg(self, bit): return to_send + def test_relay_malfunction(self): + test_relay_malfunction(self, 0x126) + def test_prev_gas(self): for g in range(0, 256): self.safety.safety_rx_hook(self._gas_msg(g)) @@ -226,21 +230,29 @@ def test_realtime_limits(self): def test_fwd_hook(self): - buss = list(range(0x0, 0x2)) + buss = list(range(0x0, 0x3)) msgs = list(range(0x1, 0x800)) blocked_msgs_0to2 = [] - blocked_msgs_2to0 = [0x122, 0x397] - for b in buss: - for m in msgs: - if b == 0: - fwd_bus = -1 if m in blocked_msgs_0to2 else 2 - elif b == 1: - fwd_bus = -1 - elif b == 2: - fwd_bus = -1 if m in blocked_msgs_2to0 else 0 - - # assume len 8 - self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) + blocked_msgs_2to0 = [0x126, 0x397] + relay_malfunction = [0, 1] + for rm in relay_malfunction: + self.safety.set_relay_malfunction(rm) + for b in buss: + for m in msgs: + if not rm: + if b == 0: + fwd_bus = -1 if m in blocked_msgs_0to2 else 2 + elif b == 1: + fwd_bus = -1 + elif b == 2: + fwd_bus = -1 if m in blocked_msgs_2to0 else 0 + else: + fwd_bus = -1 + + # assume len 8 + if fwd_bus != self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8)): + print(b, hex(m), fwd_bus) + self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) if __name__ == "__main__":