| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "safety_declarations.h" | ||
| 4 | #include "safety_hyundai_common.h" | ||
| 5 | |||
| 6 | #define HYUNDAI_LIMITS(steer, rate_up, rate_down) { \ | ||
| 7 | .max_steer = (steer), \ | ||
| 8 | .max_rate_up = (rate_up), \ | ||
| 9 | .max_rate_down = (rate_down), \ | ||
| 10 | .max_rt_delta = 112, \ | ||
| 11 | .max_rt_interval = 250000, \ | ||
| 12 | .driver_torque_allowance = 50, \ | ||
| 13 | .driver_torque_multiplier = 2, \ | ||
| 14 | .type = TorqueDriverLimited, \ | ||
| 15 | /* the EPS faults when the steering angle is above a certain threshold for too long. to prevent this, */ \ | ||
| 16 | /* we allow setting CF_Lkas_ActToi bit to 0 while maintaining the requested torque value for two consecutive frames */ \ | ||
| 17 | .min_valid_request_frames = 89, \ | ||
| 18 | .max_invalid_request_frames = 2, \ | ||
| 19 | .min_valid_request_rt_interval = 810000, /* 810ms; a ~10% buffer on cutting every 90 frames */ \ | ||
| 20 | .has_steer_req_tolerance = true, \ | ||
| 21 | } | ||
| 22 | |||
| 23 | extern const LongitudinalLimits HYUNDAI_LONG_LIMITS; | ||
| 24 | const LongitudinalLimits HYUNDAI_LONG_LIMITS = { | ||
| 25 | .max_accel = 200, // 1/100 m/s2 | ||
| 26 | .min_accel = -350, // 1/100 m/s2 | ||
| 27 | }; | ||
| 28 | |||
| 29 | #define HYUNDAI_COMMON_TX_MSGS(scc_bus) \ | ||
| 30 | {0x340, 0, 8}, /* LKAS11 Bus 0 */ \ | ||
| 31 | {0x4F1, scc_bus, 4}, /* CLU11 Bus 0 (radar-SCC) or 2 (camera-SCC) */ \ | ||
| 32 | {0x485, 0, 4}, /* LFAHDA_MFC Bus 0 */ \ | ||
| 33 | |||
| 34 | #define HYUNDAI_LONG_COMMON_TX_MSGS(scc_bus) \ | ||
| 35 | HYUNDAI_COMMON_TX_MSGS(scc_bus) \ | ||
| 36 | {0x420, 0, 8}, /* SCC11 Bus 0 */ \ | ||
| 37 | {0x421, 0, 8}, /* SCC12 Bus 0 */ \ | ||
| 38 | {0x50A, 0, 8}, /* SCC13 Bus 0 */ \ | ||
| 39 | {0x389, 0, 8}, /* SCC14 Bus 0 */ \ | ||
| 40 | {0x4A2, 0, 2}, /* FRT_RADAR11 Bus 0 */ \ | ||
| 41 | |||
| 42 | #define HYUNDAI_COMMON_RX_CHECKS(legacy) \ | ||
| 43 | {.msg = {{0x260, 0, 8, .check_checksum = true, .max_counter = 3U, .frequency = 100U}, \ | ||
| 44 | {0x371, 0, 8, .frequency = 100U}, \ | ||
| 45 | {0x91, 0, 8, .frequency = 100U}}}, \ | ||
| 46 | {.msg = {{0x386, 0, 8, .check_checksum = !(legacy), .max_counter = (legacy) ? 0U : 15U, .frequency = 100U}, { 0 }, { 0 }}}, \ | ||
| 47 | {.msg = {{0x394, 0, 8, .check_checksum = !(legacy), .max_counter = (legacy) ? 0U : 7U, .frequency = 100U}, { 0 }, { 0 }}}, \ | ||
| 48 | |||
| 49 | #define HYUNDAI_SCC12_ADDR_CHECK(scc_bus) \ | ||
| 50 | {.msg = {{0x421, (scc_bus), 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, \ | ||
| 51 | |||
| 52 | static const CanMsg HYUNDAI_TX_MSGS[] = { | ||
| 53 | HYUNDAI_COMMON_TX_MSGS(0) | ||
| 54 | }; | ||
| 55 | |||
| 56 | static bool hyundai_legacy = false; | ||
| 57 | |||
| 58 | 2331 | static uint8_t hyundai_get_counter(const CANPacket_t *to_push) { | |
| 59 | 2331 | int addr = GET_ADDR(to_push); | |
| 60 | |||
| 61 | 2331 | uint8_t cnt = 0; | |
| 62 |
2/2✓ Branch 0 taken 70 times.
✓ Branch 1 taken 2261 times.
|
2331 | if (addr == 0x260) { |
| 63 | 70 | cnt = (GET_BYTE(to_push, 7) >> 4) & 0x3U; | |
| 64 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 2205 times.
|
2261 | } else if (addr == 0x386) { |
| 65 | 56 | cnt = ((GET_BYTE(to_push, 3) >> 6) << 2) | (GET_BYTE(to_push, 1) >> 6); | |
| 66 |
2/2✓ Branch 0 taken 91 times.
✓ Branch 1 taken 2114 times.
|
2205 | } else if (addr == 0x394) { |
| 67 | 91 | cnt = (GET_BYTE(to_push, 1) >> 5) & 0x7U; | |
| 68 |
2/2✓ Branch 0 taken 576 times.
✓ Branch 1 taken 1538 times.
|
2114 | } else if (addr == 0x421) { |
| 69 | 576 | cnt = GET_BYTE(to_push, 7) & 0xFU; | |
| 70 |
1/2✓ Branch 0 taken 1538 times.
✗ Branch 1 not taken.
|
1538 | } else if (addr == 0x4F1) { |
| 71 | 1538 | cnt = (GET_BYTE(to_push, 3) >> 4) & 0xFU; | |
| 72 | } else { | ||
| 73 | } | ||
| 74 | 2331 | return cnt; | |
| 75 | } | ||
| 76 | |||
| 77 | 793 | static uint32_t hyundai_get_checksum(const CANPacket_t *to_push) { | |
| 78 | 793 | int addr = GET_ADDR(to_push); | |
| 79 | |||
| 80 | 793 | uint8_t chksum = 0; | |
| 81 |
2/2✓ Branch 0 taken 70 times.
✓ Branch 1 taken 723 times.
|
793 | if (addr == 0x260) { |
| 82 | 70 | chksum = GET_BYTE(to_push, 7) & 0xFU; | |
| 83 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 667 times.
|
723 | } else if (addr == 0x386) { |
| 84 | 56 | chksum = ((GET_BYTE(to_push, 7) >> 6) << 2) | (GET_BYTE(to_push, 5) >> 6); | |
| 85 |
2/2✓ Branch 0 taken 91 times.
✓ Branch 1 taken 576 times.
|
667 | } else if (addr == 0x394) { |
| 86 | 91 | chksum = GET_BYTE(to_push, 6) & 0xFU; | |
| 87 |
1/2✓ Branch 0 taken 576 times.
✗ Branch 1 not taken.
|
576 | } else if (addr == 0x421) { |
| 88 | 576 | chksum = GET_BYTE(to_push, 7) >> 4; | |
| 89 | } else { | ||
| 90 | } | ||
| 91 | 793 | return chksum; | |
| 92 | } | ||
| 93 | |||
| 94 | 793 | static uint32_t hyundai_compute_checksum(const CANPacket_t *to_push) { | |
| 95 | 793 | int addr = GET_ADDR(to_push); | |
| 96 | |||
| 97 | 793 | uint8_t chksum = 0; | |
| 98 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 737 times.
|
793 | if (addr == 0x386) { |
| 99 | // count the bits | ||
| 100 |
2/2✓ Branch 0 taken 448 times.
✓ Branch 1 taken 56 times.
|
504 | for (int i = 0; i < 8; i++) { |
| 101 | 448 | uint8_t b = GET_BYTE(to_push, i); | |
| 102 |
2/2✓ Branch 0 taken 3584 times.
✓ Branch 1 taken 448 times.
|
4032 | for (int j = 0; j < 8; j++) { |
| 103 | 3584 | uint8_t bit = 0; | |
| 104 | // exclude checksum and counter | ||
| 105 |
16/16✓ Branch 0 taken 448 times.
✓ Branch 1 taken 3136 times.
✓ Branch 2 taken 336 times.
✓ Branch 3 taken 112 times.
✓ Branch 4 taken 448 times.
✓ Branch 5 taken 3024 times.
✓ Branch 6 taken 336 times.
✓ Branch 7 taken 112 times.
✓ Branch 8 taken 448 times.
✓ Branch 9 taken 2912 times.
✓ Branch 10 taken 336 times.
✓ Branch 11 taken 112 times.
✓ Branch 12 taken 448 times.
✓ Branch 13 taken 2800 times.
✓ Branch 14 taken 336 times.
✓ Branch 15 taken 112 times.
|
3584 | if (((i != 1) || (j < 6)) && ((i != 3) || (j < 6)) && ((i != 5) || (j < 6)) && ((i != 7) || (j < 6))) { |
| 106 | 3136 | bit = (b >> (uint8_t)j) & 1U; | |
| 107 | } | ||
| 108 | 3584 | chksum += bit; | |
| 109 | } | ||
| 110 | } | ||
| 111 | 56 | chksum = (chksum ^ 9U) & 15U; | |
| 112 | } else { | ||
| 113 | // sum of nibbles | ||
| 114 |
2/2✓ Branch 0 taken 5896 times.
✓ Branch 1 taken 737 times.
|
6633 | for (int i = 0; i < 8; i++) { |
| 115 |
4/4✓ Branch 0 taken 728 times.
✓ Branch 1 taken 5168 times.
✓ Branch 2 taken 91 times.
✓ Branch 3 taken 637 times.
|
5896 | if ((addr == 0x394) && (i == 7)) { |
| 116 | 91 | continue; // exclude | |
| 117 | } | ||
| 118 | 5805 | uint8_t b = GET_BYTE(to_push, i); | |
| 119 |
12/12✓ Branch 0 taken 560 times.
✓ Branch 1 taken 5245 times.
✓ Branch 2 taken 490 times.
✓ Branch 3 taken 70 times.
✓ Branch 4 taken 637 times.
✓ Branch 5 taken 5098 times.
✓ Branch 6 taken 546 times.
✓ Branch 7 taken 91 times.
✓ Branch 8 taken 4608 times.
✓ Branch 9 taken 1036 times.
✓ Branch 10 taken 576 times.
✓ Branch 11 taken 4032 times.
|
5805 | if (((addr == 0x260) && (i == 7)) || ((addr == 0x394) && (i == 6)) || ((addr == 0x421) && (i == 7))) { |
| 120 |
2/2✓ Branch 0 taken 576 times.
✓ Branch 1 taken 161 times.
|
737 | b &= (addr == 0x421) ? 0x0FU : 0xF0U; // remove checksum |
| 121 | } | ||
| 122 | 5805 | chksum += (b % 16U) + (b / 16U); | |
| 123 | } | ||
| 124 | 737 | chksum = (16U - (chksum % 16U)) % 16U; | |
| 125 | } | ||
| 126 | |||
| 127 | 793 | return chksum; | |
| 128 | } | ||
| 129 | |||
| 130 | 100998 | static void hyundai_rx_hook(const CANPacket_t *to_push) { | |
| 131 | 100998 | int bus = GET_BUS(to_push); | |
| 132 | 100998 | int addr = GET_ADDR(to_push); | |
| 133 | |||
| 134 | // SCC12 is on bus 2 for camera-based SCC cars, bus 0 on all others | ||
| 135 |
2/2✓ Branch 0 taken 599 times.
✓ Branch 1 taken 100399 times.
|
100998 | if (addr == 0x421) { |
| 136 |
8/8✓ Branch 0 taken 508 times.
✓ Branch 1 taken 91 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 506 times.
✓ Branch 4 taken 81 times.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 73 times.
✓ Branch 7 taken 8 times.
|
599 | if (((bus == 0) && !hyundai_camera_scc) || ((bus == 2) && hyundai_camera_scc)) { |
| 137 | // 2 bits: 13-14 | ||
| 138 | 579 | int cruise_engaged = (GET_BYTES(to_push, 0, 4) >> 13) & 0x3U; | |
| 139 | 579 | hyundai_common_cruise_state_check(cruise_engaged); | |
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 |
2/2✓ Branch 0 taken 44607 times.
✓ Branch 1 taken 56391 times.
|
100998 | if (bus == 0) { |
| 144 |
2/2✓ Branch 0 taken 12850 times.
✓ Branch 1 taken 31757 times.
|
44607 | if (addr == 0x251) { |
| 145 | 12850 | int torque_driver_new = (GET_BYTES(to_push, 0, 2) & 0x7ffU) - 1024U; | |
| 146 | // update array of samples | ||
| 147 | 12850 | update_sample(&torque_driver, torque_driver_new); | |
| 148 | } | ||
| 149 | |||
| 150 | // ACC steering wheel buttons | ||
| 151 |
2/2✓ Branch 0 taken 2836 times.
✓ Branch 1 taken 41771 times.
|
44607 | if (addr == 0x4F1) { |
| 152 | 2836 | int cruise_button = GET_BYTE(to_push, 0) & 0x7U; | |
| 153 | 2836 | bool main_button = GET_BIT(to_push, 3U); | |
| 154 | 2836 | hyundai_common_cruise_buttons_check(cruise_button, main_button); | |
| 155 | } | ||
| 156 | |||
| 157 | // gas press, different for EV, hybrid, and ICE models | ||
| 158 |
4/4✓ Branch 0 taken 30 times.
✓ Branch 1 taken 44577 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 19 times.
|
44607 | if ((addr == 0x371) && hyundai_ev_gas_signal) { |
| 159 | 11 | gas_pressed = (((GET_BYTE(to_push, 4) & 0x7FU) << 1) | GET_BYTE(to_push, 3) >> 7) != 0U; | |
| 160 |
4/4✓ Branch 0 taken 19 times.
✓ Branch 1 taken 44577 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 8 times.
|
44596 | } else if ((addr == 0x371) && hyundai_hybrid_gas_signal) { |
| 161 | 11 | gas_pressed = GET_BYTE(to_push, 7) != 0U; | |
| 162 |
4/4✓ Branch 0 taken 20 times.
✓ Branch 1 taken 44565 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 9 times.
|
44585 | } else if ((addr == 0x91) && hyundai_fcev_gas_signal) { |
| 163 | 11 | gas_pressed = GET_BYTE(to_push, 6) != 0U; | |
| 164 |
6/6✓ Branch 0 taken 80 times.
✓ Branch 1 taken 44494 times.
✓ Branch 2 taken 79 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 78 times.
✓ Branch 5 taken 1 times.
|
44574 | } else if ((addr == 0x260) && !hyundai_ev_gas_signal && !hyundai_hybrid_gas_signal) { |
| 165 | 78 | gas_pressed = (GET_BYTE(to_push, 7) >> 6) != 0U; | |
| 166 | } else { | ||
| 167 | } | ||
| 168 | |||
| 169 | // sample wheel speed, averaging opposite corners | ||
| 170 |
2/2✓ Branch 0 taken 73 times.
✓ Branch 1 taken 44534 times.
|
44607 | if (addr == 0x386) { |
| 171 | 73 | uint32_t front_left_speed = GET_BYTES(to_push, 0, 2) & 0x3FFFU; | |
| 172 | 73 | uint32_t rear_right_speed = GET_BYTES(to_push, 6, 2) & 0x3FFFU; | |
| 173 |
3/4✓ Branch 0 taken 53 times.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 53 times.
|
73 | vehicle_moving = (front_left_speed > HYUNDAI_STANDSTILL_THRSLD) || (rear_right_speed > HYUNDAI_STANDSTILL_THRSLD); |
| 174 | } | ||
| 175 | |||
| 176 |
2/2✓ Branch 0 taken 130 times.
✓ Branch 1 taken 44477 times.
|
44607 | if (addr == 0x394) { |
| 177 | 130 | brake_pressed = ((GET_BYTE(to_push, 5) >> 5U) & 0x3U) == 0x2U; | |
| 178 | } | ||
| 179 | |||
| 180 | 44607 | bool stock_ecu_detected = (addr == 0x340); | |
| 181 | |||
| 182 | // If openpilot is controlling longitudinal we need to ensure the radar is turned off | ||
| 183 | // Enforce by checking we don't see SCC12 | ||
| 184 |
6/6✓ Branch 0 taken 9795 times.
✓ Branch 1 taken 34812 times.
✓ Branch 2 taken 4898 times.
✓ Branch 3 taken 4897 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 4896 times.
|
44607 | if (hyundai_longitudinal && !hyundai_camera_scc && (addr == 0x421)) { |
| 185 | 2 | stock_ecu_detected = true; | |
| 186 | } | ||
| 187 | 44607 | generic_rx_checks(stock_ecu_detected); | |
| 188 | } | ||
| 189 | 100998 | } | |
| 190 | |||
| 191 | 400322 | static bool hyundai_tx_hook(const CANPacket_t *to_send) { | |
| 192 | const SteeringLimits HYUNDAI_STEERING_LIMITS = HYUNDAI_LIMITS(384, 3, 7); | ||
| 193 | const SteeringLimits HYUNDAI_STEERING_LIMITS_ALT = HYUNDAI_LIMITS(270, 2, 3); | ||
| 194 | const SteeringLimits HYUNDAI_STEERING_LIMITS_ALT_2 = HYUNDAI_LIMITS(170, 2, 3); | ||
| 195 | |||
| 196 | 400322 | bool tx = true; | |
| 197 | 400322 | int addr = GET_ADDR(to_send); | |
| 198 | |||
| 199 | // FCA11: Block any potential actuation | ||
| 200 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 400317 times.
|
400322 | if (addr == 0x38D) { |
| 201 | 5 | int CR_VSM_DecCmd = GET_BYTE(to_send, 1); | |
| 202 | 5 | bool FCA_CmdAct = GET_BIT(to_send, 20U); | |
| 203 | 5 | bool CF_VSM_DecCmdAct = GET_BIT(to_send, 31U); | |
| 204 | |||
| 205 |
6/6✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 2 times.
|
5 | if ((CR_VSM_DecCmd != 0) || FCA_CmdAct || CF_VSM_DecCmdAct) { |
| 206 | 3 | tx = false; | |
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 210 | // ACCEL: safety check | ||
| 211 |
2/2✓ Branch 0 taken 1226 times.
✓ Branch 1 taken 399096 times.
|
400322 | if (addr == 0x421) { |
| 212 | 1226 | int desired_accel_raw = (((GET_BYTE(to_send, 4) & 0x7U) << 8) | GET_BYTE(to_send, 3)) - 1023U; | |
| 213 | 1226 | int desired_accel_val = ((GET_BYTE(to_send, 5) << 3) | (GET_BYTE(to_send, 4) >> 5)) - 1023U; | |
| 214 | |||
| 215 | 1226 | int aeb_decel_cmd = GET_BYTE(to_send, 2); | |
| 216 | 1226 | bool aeb_req = GET_BIT(to_send, 54U); | |
| 217 | |||
| 218 | 1226 | bool violation = false; | |
| 219 | |||
| 220 | 1226 | violation |= longitudinal_accel_checks(desired_accel_raw, HYUNDAI_LONG_LIMITS); | |
| 221 | 1226 | violation |= longitudinal_accel_checks(desired_accel_val, HYUNDAI_LONG_LIMITS); | |
| 222 | 1226 | violation |= (aeb_decel_cmd != 0); | |
| 223 | 1226 | violation |= aeb_req; | |
| 224 | |||
| 225 |
2/2✓ Branch 0 taken 760 times.
✓ Branch 1 taken 466 times.
|
1226 | if (violation) { |
| 226 | 760 | tx = false; | |
| 227 | } | ||
| 228 | } | ||
| 229 | |||
| 230 | // LKA STEER: safety check | ||
| 231 |
2/2✓ Branch 0 taken 399032 times.
✓ Branch 1 taken 1290 times.
|
400322 | if (addr == 0x340) { |
| 232 | 399032 | int desired_torque = ((GET_BYTES(to_send, 0, 4) >> 16) & 0x7ffU) - 1024U; | |
| 233 | 399032 | bool steer_req = GET_BIT(to_send, 27U); | |
| 234 | |||
| 235 |
2/2✓ Branch 0 taken 38816 times.
✓ Branch 1 taken 360216 times.
|
759248 | const SteeringLimits limits = hyundai_alt_limits_2 ? HYUNDAI_STEERING_LIMITS_ALT_2 : |
| 236 |
2/2✓ Branch 0 taken 39416 times.
✓ Branch 1 taken 320800 times.
|
360216 | hyundai_alt_limits ? HYUNDAI_STEERING_LIMITS_ALT : HYUNDAI_STEERING_LIMITS; |
| 237 | |||
| 238 |
2/2✓ Branch 1 taken 211448 times.
✓ Branch 2 taken 187584 times.
|
399032 | if (steer_torque_cmd_checks(desired_torque, steer_req, limits)) { |
| 239 | 211448 | tx = false; | |
| 240 | } | ||
| 241 | } | ||
| 242 | |||
| 243 | // UDS: Only tester present ("\x02\x3E\x80\x00\x00\x00\x00\x00") allowed on diagnostics address | ||
| 244 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 400318 times.
|
400322 | if (addr == 0x7D0) { |
| 245 |
3/4✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
4 | if ((GET_BYTES(to_send, 0, 4) != 0x00803E02U) || (GET_BYTES(to_send, 4, 4) != 0x0U)) { |
| 246 | 3 | tx = false; | |
| 247 | } | ||
| 248 | } | ||
| 249 | |||
| 250 | // BUTTONS: used for resume spamming and cruise cancellation | ||
| 251 |
3/4✓ Branch 0 taken 48 times.
✓ Branch 1 taken 400274 times.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
|
400322 | if ((addr == 0x4F1) && !hyundai_longitudinal) { |
| 252 | 48 | int button = GET_BYTE(to_send, 0) & 0x7U; | |
| 253 | |||
| 254 |
4/4✓ Branch 0 taken 16 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 8 times.
|
48 | bool allowed_resume = (button == 1) && controls_allowed; |
| 255 |
4/4✓ Branch 0 taken 16 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 8 times.
|
48 | bool allowed_cancel = (button == 4) && cruise_engaged_prev; |
| 256 |
4/4✓ Branch 0 taken 40 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 8 times.
|
48 | if (!(allowed_resume || allowed_cancel)) { |
| 257 | 32 | tx = false; | |
| 258 | } | ||
| 259 | } | ||
| 260 | |||
| 261 | 400322 | return tx; | |
| 262 | } | ||
| 263 | |||
| 264 | 84480 | static int hyundai_fwd_hook(int bus_num, int addr) { | |
| 265 | |||
| 266 | 84480 | int bus_fwd = -1; | |
| 267 | |||
| 268 | // forward cam to ccan and viceversa, except lkas cmd | ||
| 269 |
2/2✓ Branch 0 taken 28160 times.
✓ Branch 1 taken 56320 times.
|
84480 | if (bus_num == 0) { |
| 270 | 28160 | bus_fwd = 2; | |
| 271 | } | ||
| 272 | |||
| 273 |
2/2✓ Branch 0 taken 28160 times.
✓ Branch 1 taken 56320 times.
|
84480 | if (bus_num == 2) { |
| 274 | // Stock LKAS11 messages | ||
| 275 | 28160 | bool is_lkas_11 = (addr == 0x340); | |
| 276 | // LFA and HDA cluster icons | ||
| 277 | 28160 | bool is_lfahda_mfc = (addr == 0x485); | |
| 278 | // Stock SCC messages, blocking when doing openpilot longitudinal on camera SCC cars | ||
| 279 |
8/8✓ Branch 0 taken 28150 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 28140 times.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 28130 times.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 28120 times.
|
28160 | bool is_scc_msg = (addr == 0x420) || (addr == 0x421) || (addr == 0x50A) || (addr == 0x389); |
| 280 | |||
| 281 |
10/10✓ Branch 0 taken 28150 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 28140 times.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 40 times.
✓ Branch 5 taken 28100 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 32 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 4 times.
|
28160 | bool block_msg = is_lkas_11 || is_lfahda_mfc || (is_scc_msg && hyundai_longitudinal && hyundai_camera_scc); |
| 282 |
2/2✓ Branch 0 taken 28136 times.
✓ Branch 1 taken 24 times.
|
28160 | if (!block_msg) { |
| 283 | 28136 | bus_fwd = 0; | |
| 284 | } | ||
| 285 | } | ||
| 286 | |||
| 287 | 84480 | return bus_fwd; | |
| 288 | } | ||
| 289 | |||
| 290 | 253 | static safety_config hyundai_init(uint16_t param) { | |
| 291 | static const CanMsg HYUNDAI_LONG_TX_MSGS[] = { | ||
| 292 | HYUNDAI_LONG_COMMON_TX_MSGS(0) | ||
| 293 | {0x38D, 0, 8}, // FCA11 Bus 0 | ||
| 294 | {0x483, 0, 8}, // FCA12 Bus 0 | ||
| 295 | {0x7D0, 0, 8}, // radar UDS TX addr Bus 0 (for radar disable) | ||
| 296 | }; | ||
| 297 | |||
| 298 | static const CanMsg HYUNDAI_CAMERA_SCC_TX_MSGS[] = { | ||
| 299 | HYUNDAI_COMMON_TX_MSGS(2) | ||
| 300 | }; | ||
| 301 | |||
| 302 | static const CanMsg HYUNDAI_CAMERA_SCC_LONG_TX_MSGS[] = { | ||
| 303 | HYUNDAI_LONG_COMMON_TX_MSGS(2) | ||
| 304 | }; | ||
| 305 | |||
| 306 | 253 | hyundai_common_init(param); | |
| 307 | 253 | hyundai_legacy = false; | |
| 308 | |||
| 309 | safety_config ret; | ||
| 310 |
2/2✓ Branch 0 taken 83 times.
✓ Branch 1 taken 170 times.
|
253 | if (hyundai_longitudinal) { |
| 311 | static RxCheck hyundai_long_rx_checks[] = { | ||
| 312 | HYUNDAI_COMMON_RX_CHECKS(false) | ||
| 313 | // Use CLU11 (buttons) to manage controls allowed instead of SCC cruise state | ||
| 314 | {.msg = {{0x4F1, 0, 4, .check_checksum = false, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, | ||
| 315 | }; | ||
| 316 | |||
| 317 |
2/2✓ Branch 0 taken 41 times.
✓ Branch 1 taken 42 times.
|
83 | ret = hyundai_camera_scc ? BUILD_SAFETY_CFG(hyundai_long_rx_checks, HYUNDAI_CAMERA_SCC_LONG_TX_MSGS) : \ |
| 318 | BUILD_SAFETY_CFG(hyundai_long_rx_checks, HYUNDAI_LONG_TX_MSGS); | ||
| 319 |
2/2✓ Branch 0 taken 34 times.
✓ Branch 1 taken 136 times.
|
170 | } else if (hyundai_camera_scc) { |
| 320 | static RxCheck hyundai_cam_scc_rx_checks[] = { | ||
| 321 | HYUNDAI_COMMON_RX_CHECKS(false) | ||
| 322 | HYUNDAI_SCC12_ADDR_CHECK(2) | ||
| 323 | }; | ||
| 324 | |||
| 325 | 34 | ret = BUILD_SAFETY_CFG(hyundai_cam_scc_rx_checks, HYUNDAI_CAMERA_SCC_TX_MSGS); | |
| 326 | } else { | ||
| 327 | static RxCheck hyundai_rx_checks[] = { | ||
| 328 | HYUNDAI_COMMON_RX_CHECKS(false) | ||
| 329 | HYUNDAI_SCC12_ADDR_CHECK(0) | ||
| 330 | }; | ||
| 331 | |||
| 332 | 136 | ret = BUILD_SAFETY_CFG(hyundai_rx_checks, HYUNDAI_TX_MSGS); | |
| 333 | } | ||
| 334 | 253 | return ret; | |
| 335 | } | ||
| 336 | |||
| 337 | 102 | static safety_config hyundai_legacy_init(uint16_t param) { | |
| 338 | // older hyundai models have less checks due to missing counters and checksums | ||
| 339 | static RxCheck hyundai_legacy_rx_checks[] = { | ||
| 340 | HYUNDAI_COMMON_RX_CHECKS(true) | ||
| 341 | HYUNDAI_SCC12_ADDR_CHECK(0) | ||
| 342 | }; | ||
| 343 | |||
| 344 | 102 | hyundai_common_init(param); | |
| 345 | 102 | hyundai_legacy = true; | |
| 346 | 102 | hyundai_longitudinal = false; | |
| 347 | 102 | hyundai_camera_scc = false; | |
| 348 | 102 | return BUILD_SAFETY_CFG(hyundai_legacy_rx_checks, HYUNDAI_TX_MSGS); | |
| 349 | } | ||
| 350 | |||
| 351 | const safety_hooks hyundai_hooks = { | ||
| 352 | .init = hyundai_init, | ||
| 353 | .rx = hyundai_rx_hook, | ||
| 354 | .tx = hyundai_tx_hook, | ||
| 355 | .fwd = hyundai_fwd_hook, | ||
| 356 | .get_counter = hyundai_get_counter, | ||
| 357 | .get_checksum = hyundai_get_checksum, | ||
| 358 | .compute_checksum = hyundai_compute_checksum, | ||
| 359 | }; | ||
| 360 | |||
| 361 | const safety_hooks hyundai_legacy_hooks = { | ||
| 362 | .init = hyundai_legacy_init, | ||
| 363 | .rx = hyundai_rx_hook, | ||
| 364 | .tx = hyundai_tx_hook, | ||
| 365 | .fwd = hyundai_fwd_hook, | ||
| 366 | .get_counter = hyundai_get_counter, | ||
| 367 | .get_checksum = hyundai_get_checksum, | ||
| 368 | .compute_checksum = hyundai_compute_checksum, | ||
| 369 | }; | ||
| 370 |