| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "safety_declarations.h" | ||
| 4 | |||
| 5 | #define SUBARU_STEERING_LIMITS_GENERATOR(steer_max, rate_up, rate_down) \ | ||
| 6 | { \ | ||
| 7 | .max_steer = (steer_max), \ | ||
| 8 | .max_rt_delta = 940, \ | ||
| 9 | .max_rt_interval = 250000, \ | ||
| 10 | .max_rate_up = (rate_up), \ | ||
| 11 | .max_rate_down = (rate_down), \ | ||
| 12 | .driver_torque_multiplier = 50, \ | ||
| 13 | .driver_torque_allowance = 60, \ | ||
| 14 | .type = TorqueDriverLimited, \ | ||
| 15 | /* the EPS will temporary fault if the steering rate is too high, so we cut the \ | ||
| 16 | the steering torque every 7 frames for 1 frame if the steering rate is high */ \ | ||
| 17 | .min_valid_request_frames = 7, \ | ||
| 18 | .max_invalid_request_frames = 1, \ | ||
| 19 | .min_valid_request_rt_interval = 144000, /* 10% tolerance */ \ | ||
| 20 | .has_steer_req_tolerance = true, \ | ||
| 21 | } | ||
| 22 | |||
| 23 | #define MSG_SUBARU_Brake_Status 0x13c | ||
| 24 | #define MSG_SUBARU_CruiseControl 0x240 | ||
| 25 | #define MSG_SUBARU_Throttle 0x40 | ||
| 26 | #define MSG_SUBARU_Steering_Torque 0x119 | ||
| 27 | #define MSG_SUBARU_Wheel_Speeds 0x13a | ||
| 28 | |||
| 29 | #define MSG_SUBARU_ES_LKAS 0x122 | ||
| 30 | #define MSG_SUBARU_ES_Brake 0x220 | ||
| 31 | #define MSG_SUBARU_ES_Distance 0x221 | ||
| 32 | #define MSG_SUBARU_ES_Status 0x222 | ||
| 33 | #define MSG_SUBARU_ES_DashStatus 0x321 | ||
| 34 | #define MSG_SUBARU_ES_LKAS_State 0x322 | ||
| 35 | #define MSG_SUBARU_ES_Infotainment 0x323 | ||
| 36 | |||
| 37 | #define MSG_SUBARU_ES_UDS_Request 0x787 | ||
| 38 | |||
| 39 | #define MSG_SUBARU_ES_HighBeamAssist 0x121 | ||
| 40 | #define MSG_SUBARU_ES_STATIC_1 0x22a | ||
| 41 | #define MSG_SUBARU_ES_STATIC_2 0x325 | ||
| 42 | |||
| 43 | #define SUBARU_MAIN_BUS 0 | ||
| 44 | #define SUBARU_ALT_BUS 1 | ||
| 45 | #define SUBARU_CAM_BUS 2 | ||
| 46 | |||
| 47 | #define SUBARU_COMMON_TX_MSGS(alt_bus, lkas_msg) \ | ||
| 48 | {lkas_msg, SUBARU_MAIN_BUS, 8}, \ | ||
| 49 | {MSG_SUBARU_ES_Distance, alt_bus, 8}, \ | ||
| 50 | {MSG_SUBARU_ES_DashStatus, SUBARU_MAIN_BUS, 8}, \ | ||
| 51 | {MSG_SUBARU_ES_LKAS_State, SUBARU_MAIN_BUS, 8}, \ | ||
| 52 | {MSG_SUBARU_ES_Infotainment, SUBARU_MAIN_BUS, 8}, \ | ||
| 53 | |||
| 54 | #define SUBARU_COMMON_LONG_TX_MSGS(alt_bus) \ | ||
| 55 | {MSG_SUBARU_ES_Brake, alt_bus, 8}, \ | ||
| 56 | {MSG_SUBARU_ES_Status, alt_bus, 8}, \ | ||
| 57 | |||
| 58 | #define SUBARU_GEN2_LONG_ADDITIONAL_TX_MSGS() \ | ||
| 59 | {MSG_SUBARU_ES_UDS_Request, SUBARU_CAM_BUS, 8}, \ | ||
| 60 | {MSG_SUBARU_ES_HighBeamAssist, SUBARU_MAIN_BUS, 8}, \ | ||
| 61 | {MSG_SUBARU_ES_STATIC_1, SUBARU_MAIN_BUS, 8}, \ | ||
| 62 | {MSG_SUBARU_ES_STATIC_2, SUBARU_MAIN_BUS, 8}, \ | ||
| 63 | |||
| 64 | #define SUBARU_COMMON_RX_CHECKS(alt_bus) \ | ||
| 65 | {.msg = {{MSG_SUBARU_Throttle, SUBARU_MAIN_BUS, 8, .check_checksum = true, .max_counter = 15U, .frequency = 100U}, { 0 }, { 0 }}}, \ | ||
| 66 | {.msg = {{MSG_SUBARU_Steering_Torque, SUBARU_MAIN_BUS, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, \ | ||
| 67 | {.msg = {{MSG_SUBARU_Wheel_Speeds, alt_bus, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, \ | ||
| 68 | {.msg = {{MSG_SUBARU_Brake_Status, alt_bus, 8, .check_checksum = true, .max_counter = 15U, .frequency = 50U}, { 0 }, { 0 }}}, \ | ||
| 69 | {.msg = {{MSG_SUBARU_CruiseControl, alt_bus, 8, .check_checksum = true, .max_counter = 15U, .frequency = 20U}, { 0 }, { 0 }}}, \ | ||
| 70 | |||
| 71 | static bool subaru_gen2 = false; | ||
| 72 | static bool subaru_longitudinal = false; | ||
| 73 | |||
| 74 | 6260 | static uint32_t subaru_get_checksum(const CANPacket_t *to_push) { | |
| 75 | 6260 | return (uint8_t)GET_BYTE(to_push, 0); | |
| 76 | } | ||
| 77 | |||
| 78 | 6260 | static uint8_t subaru_get_counter(const CANPacket_t *to_push) { | |
| 79 | 6260 | return (uint8_t)(GET_BYTE(to_push, 1) & 0xFU); | |
| 80 | } | ||
| 81 | |||
| 82 | 6260 | static uint32_t subaru_compute_checksum(const CANPacket_t *to_push) { | |
| 83 | 6260 | int addr = GET_ADDR(to_push); | |
| 84 | 6260 | int len = GET_LEN(to_push); | |
| 85 | 6260 | uint8_t checksum = (uint8_t)(addr) + (uint8_t)((unsigned int)(addr) >> 8U); | |
| 86 |
2/2✓ Branch 0 taken 43820 times.
✓ Branch 1 taken 6260 times.
|
50080 | for (int i = 1; i < len; i++) { |
| 87 | 43820 | checksum += (uint8_t)GET_BYTE(to_push, i); | |
| 88 | } | ||
| 89 | 6260 | return checksum; | |
| 90 | } | ||
| 91 | |||
| 92 | 40012 | static void subaru_rx_hook(const CANPacket_t *to_push) { | |
| 93 | 40012 | const int bus = GET_BUS(to_push); | |
| 94 | 40012 | const int alt_main_bus = subaru_gen2 ? SUBARU_ALT_BUS : SUBARU_MAIN_BUS; | |
| 95 | |||
| 96 | 40012 | int addr = GET_ADDR(to_push); | |
| 97 |
4/4✓ Branch 0 taken 6104 times.
✓ Branch 1 taken 33908 times.
✓ Branch 2 taken 6096 times.
✓ Branch 3 taken 8 times.
|
40012 | if ((addr == MSG_SUBARU_Steering_Torque) && (bus == SUBARU_MAIN_BUS)) { |
| 98 | int torque_driver_new; | ||
| 99 | 6096 | torque_driver_new = ((GET_BYTES(to_push, 0, 4) >> 16) & 0x7FFU); | |
| 100 | 6096 | torque_driver_new = -1 * to_signed(torque_driver_new, 11); | |
| 101 | 6096 | update_sample(&torque_driver, torque_driver_new); | |
| 102 | |||
| 103 | 6096 | int angle_meas_new = (GET_BYTES(to_push, 4, 2) & 0xFFFFU); | |
| 104 | // convert Steering_Torque -> Steering_Angle to centidegrees, to match the ES_LKAS_ANGLE angle request units | ||
| 105 | 6096 | angle_meas_new = ROUND(to_signed(angle_meas_new, 16) * -2.17); | |
| 106 | 6096 | update_sample(&angle_meas, angle_meas_new); | |
| 107 | } | ||
| 108 | |||
| 109 | // enter controls on rising edge of ACC, exit controls on ACC off | ||
| 110 |
4/4✓ Branch 0 taken 36 times.
✓ Branch 1 taken 39976 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 8 times.
|
40012 | if ((addr == MSG_SUBARU_CruiseControl) && (bus == alt_main_bus)) { |
| 111 | 28 | bool cruise_engaged = GET_BIT(to_push, 41U); | |
| 112 | 28 | pcm_cruise_check(cruise_engaged); | |
| 113 | } | ||
| 114 | |||
| 115 | // update vehicle moving with any non-zero wheel speed | ||
| 116 |
4/4✓ Branch 0 taken 36 times.
✓ Branch 1 taken 39976 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 8 times.
|
40012 | if ((addr == MSG_SUBARU_Wheel_Speeds) && (bus == alt_main_bus)) { |
| 117 | 28 | uint32_t fr = (GET_BYTES(to_push, 1, 3) >> 4) & 0x1FFFU; | |
| 118 | 28 | uint32_t rr = (GET_BYTES(to_push, 3, 3) >> 1) & 0x1FFFU; | |
| 119 | 28 | uint32_t rl = (GET_BYTES(to_push, 4, 3) >> 6) & 0x1FFFU; | |
| 120 | 28 | uint32_t fl = (GET_BYTES(to_push, 6, 2) >> 3) & 0x1FFFU; | |
| 121 | |||
| 122 |
5/8✓ Branch 0 taken 20 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 20 times.
|
28 | vehicle_moving = (fr > 0U) || (rr > 0U) || (rl > 0U) || (fl > 0U); |
| 123 | |||
| 124 | 28 | UPDATE_VEHICLE_SPEED((fr + rr + rl + fl) / 4U * 0.057); | |
| 125 | } | ||
| 126 | |||
| 127 |
4/4✓ Branch 0 taken 56 times.
✓ Branch 1 taken 39956 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 8 times.
|
40012 | if ((addr == MSG_SUBARU_Brake_Status) && (bus == alt_main_bus)) { |
| 128 | 48 | brake_pressed = GET_BIT(to_push, 62U); | |
| 129 | } | ||
| 130 | |||
| 131 |
4/4✓ Branch 0 taken 48 times.
✓ Branch 1 taken 39964 times.
✓ Branch 2 taken 40 times.
✓ Branch 3 taken 8 times.
|
40012 | if ((addr == MSG_SUBARU_Throttle) && (bus == SUBARU_MAIN_BUS)) { |
| 132 | 40 | gas_pressed = GET_BYTE(to_push, 4) != 0U; | |
| 133 | } | ||
| 134 | |||
| 135 |
4/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 40000 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 8 times.
|
40012 | generic_rx_checks((addr == MSG_SUBARU_ES_LKAS) && (bus == SUBARU_MAIN_BUS)); |
| 136 | 40012 | } | |
| 137 | |||
| 138 | 489689 | static bool subaru_tx_hook(const CANPacket_t *to_send) { | |
| 139 | const SteeringLimits SUBARU_STEERING_LIMITS = SUBARU_STEERING_LIMITS_GENERATOR(2047, 50, 70); | ||
| 140 | const SteeringLimits SUBARU_GEN2_STEERING_LIMITS = SUBARU_STEERING_LIMITS_GENERATOR(1000, 40, 40); | ||
| 141 | |||
| 142 | const LongitudinalLimits SUBARU_LONG_LIMITS = { | ||
| 143 | .min_gas = 808, // appears to be engine braking | ||
| 144 | .max_gas = 3400, // approx 2 m/s^2 when maxing cruise_rpm and cruise_throttle | ||
| 145 | .inactive_gas = 1818, // this is zero acceleration | ||
| 146 | .max_brake = 600, // approx -3.5 m/s^2 | ||
| 147 | |||
| 148 | .min_transmission_rpm = 0, | ||
| 149 | .max_transmission_rpm = 3600, | ||
| 150 | }; | ||
| 151 | |||
| 152 | 489689 | bool tx = true; | |
| 153 | 489689 | int addr = GET_ADDR(to_send); | |
| 154 | 489689 | bool violation = false; | |
| 155 | |||
| 156 | // steer cmd checks | ||
| 157 |
2/2✓ Branch 0 taken 63384 times.
✓ Branch 1 taken 426305 times.
|
489689 | if (addr == MSG_SUBARU_ES_LKAS) { |
| 158 | 63384 | int desired_torque = ((GET_BYTES(to_send, 0, 4) >> 16) & 0x1FFFU); | |
| 159 | 63384 | desired_torque = -1 * to_signed(desired_torque, 13); | |
| 160 | |||
| 161 | 63384 | bool steer_req = GET_BIT(to_send, 29U); | |
| 162 | |||
| 163 |
2/2✓ Branch 0 taken 25412 times.
✓ Branch 1 taken 37972 times.
|
63384 | const SteeringLimits limits = subaru_gen2 ? SUBARU_GEN2_STEERING_LIMITS : SUBARU_STEERING_LIMITS; |
| 164 | 63384 | violation |= steer_torque_cmd_checks(desired_torque, steer_req, limits); | |
| 165 | } | ||
| 166 | |||
| 167 | // check es_brake brake_pressure limits | ||
| 168 |
2/2✓ Branch 0 taken 262154 times.
✓ Branch 1 taken 227535 times.
|
489689 | if (addr == MSG_SUBARU_ES_Brake) { |
| 169 | 262154 | int es_brake_pressure = GET_BYTES(to_send, 2, 2); | |
| 170 | 262154 | violation |= longitudinal_brake_checks(es_brake_pressure, SUBARU_LONG_LIMITS); | |
| 171 | } | ||
| 172 | |||
| 173 | // check es_distance cruise_throttle limits | ||
| 174 |
2/2✓ Branch 0 taken 65564 times.
✓ Branch 1 taken 424125 times.
|
489689 | if (addr == MSG_SUBARU_ES_Distance) { |
| 175 | 65564 | int cruise_throttle = (GET_BYTES(to_send, 2, 2) & 0x1FFFU); | |
| 176 | 65564 | bool cruise_cancel = GET_BIT(to_send, 56U); | |
| 177 | |||
| 178 |
2/2✓ Branch 0 taken 32778 times.
✓ Branch 1 taken 32786 times.
|
65564 | if (subaru_longitudinal) { |
| 179 | 32778 | violation |= longitudinal_gas_checks(cruise_throttle, SUBARU_LONG_LIMITS); | |
| 180 | } else { | ||
| 181 | // If openpilot is not controlling long, only allow ES_Distance for cruise cancel requests, | ||
| 182 | // (when Cruise_Cancel is true, and Cruise_Throttle is inactive) | ||
| 183 | 32786 | violation |= (cruise_throttle != SUBARU_LONG_LIMITS.inactive_gas); | |
| 184 | 32786 | violation |= (!cruise_cancel); | |
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | // check es_status transmission_rpm limits | ||
| 189 |
2/2✓ Branch 0 taken 32778 times.
✓ Branch 1 taken 456911 times.
|
489689 | if (addr == MSG_SUBARU_ES_Status) { |
| 190 | 32778 | int transmission_rpm = (GET_BYTES(to_send, 2, 2) & 0x1FFFU); | |
| 191 | 32778 | violation |= longitudinal_transmission_rpm_checks(transmission_rpm, SUBARU_LONG_LIMITS); | |
| 192 | } | ||
| 193 | |||
| 194 |
2/2✓ Branch 0 taken 65794 times.
✓ Branch 1 taken 423895 times.
|
489689 | if (addr == MSG_SUBARU_ES_UDS_Request) { |
| 195 | // tester present ('\x02\x3E\x80\x00\x00\x00\x00\x00') is allowed for gen2 longitudinal to keep eyesight disabled | ||
| 196 |
3/4✓ Branch 1 taken 1 times.
✓ Branch 2 taken 65793 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
65794 | bool is_tester_present = (GET_BYTES(to_send, 0, 4) == 0x00803E02U) && (GET_BYTES(to_send, 4, 4) == 0x0U); |
| 197 | |||
| 198 | // reading ES button data by identifier (b'\x03\x22\x11\x30\x00\x00\x00\x00') is also allowed (DID 0x1130) | ||
| 199 |
3/4✓ Branch 1 taken 1 times.
✓ Branch 2 taken 65793 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
65794 | bool is_button_rdbi = (GET_BYTES(to_send, 0, 4) == 0x30112203U) && (GET_BYTES(to_send, 4, 4) == 0x0U); |
| 200 | |||
| 201 |
4/4✓ Branch 0 taken 65793 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 65792 times.
✓ Branch 3 taken 1 times.
|
65794 | violation |= !(is_tester_present || is_button_rdbi); |
| 202 | } | ||
| 203 | |||
| 204 |
2/2✓ Branch 0 taken 447308 times.
✓ Branch 1 taken 42381 times.
|
489689 | if (violation){ |
| 205 | 447308 | tx = false; | |
| 206 | } | ||
| 207 | 489689 | return tx; | |
| 208 | } | ||
| 209 | |||
| 210 | 33792 | static int subaru_fwd_hook(int bus_num, int addr) { | |
| 211 | 33792 | int bus_fwd = -1; | |
| 212 | |||
| 213 |
2/2✓ Branch 0 taken 11264 times.
✓ Branch 1 taken 22528 times.
|
33792 | if (bus_num == SUBARU_MAIN_BUS) { |
| 214 | 11264 | bus_fwd = SUBARU_CAM_BUS; // to the eyesight camera | |
| 215 | } | ||
| 216 | |||
| 217 |
2/2✓ Branch 0 taken 11264 times.
✓ Branch 1 taken 22528 times.
|
33792 | if (bus_num == SUBARU_CAM_BUS) { |
| 218 | // Global platform | ||
| 219 |
2/2✓ Branch 0 taken 11256 times.
✓ Branch 1 taken 4 times.
|
11260 | bool block_lkas = ((addr == MSG_SUBARU_ES_LKAS) || |
| 220 |
2/2✓ Branch 0 taken 11252 times.
✓ Branch 1 taken 4 times.
|
11256 | (addr == MSG_SUBARU_ES_DashStatus) || |
| 221 |
4/4✓ Branch 0 taken 11260 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 11248 times.
|
22524 | (addr == MSG_SUBARU_ES_LKAS_State) || |
| 222 | (addr == MSG_SUBARU_ES_Infotainment)); | ||
| 223 | |||
| 224 |
2/2✓ Branch 0 taken 11256 times.
✓ Branch 1 taken 4 times.
|
11260 | bool block_long = ((addr == MSG_SUBARU_ES_Brake) || |
| 225 |
4/4✓ Branch 0 taken 11260 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 11252 times.
|
22524 | (addr == MSG_SUBARU_ES_Distance) || |
| 226 | (addr == MSG_SUBARU_ES_Status)); | ||
| 227 | |||
| 228 |
6/6✓ Branch 0 taken 11248 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 5624 times.
✓ Branch 3 taken 5624 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 5618 times.
|
11264 | bool block_msg = block_lkas || (subaru_longitudinal && block_long); |
| 229 |
2/2✓ Branch 0 taken 11242 times.
✓ Branch 1 taken 22 times.
|
11264 | if (!block_msg) { |
| 230 | 11242 | bus_fwd = SUBARU_MAIN_BUS; // Main CAN | |
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 234 | 33792 | return bus_fwd; | |
| 235 | } | ||
| 236 | |||
| 237 | 139 | static safety_config subaru_init(uint16_t param) { | |
| 238 | static const CanMsg SUBARU_TX_MSGS[] = { | ||
| 239 | SUBARU_COMMON_TX_MSGS(SUBARU_MAIN_BUS, MSG_SUBARU_ES_LKAS) | ||
| 240 | }; | ||
| 241 | |||
| 242 | static const CanMsg SUBARU_LONG_TX_MSGS[] = { | ||
| 243 | SUBARU_COMMON_TX_MSGS(SUBARU_MAIN_BUS, MSG_SUBARU_ES_LKAS) | ||
| 244 | SUBARU_COMMON_LONG_TX_MSGS(SUBARU_MAIN_BUS) | ||
| 245 | }; | ||
| 246 | |||
| 247 | static const CanMsg SUBARU_GEN2_TX_MSGS[] = { | ||
| 248 | SUBARU_COMMON_TX_MSGS(SUBARU_ALT_BUS, MSG_SUBARU_ES_LKAS) | ||
| 249 | }; | ||
| 250 | |||
| 251 | static const CanMsg SUBARU_GEN2_LONG_TX_MSGS[] = { | ||
| 252 | SUBARU_COMMON_TX_MSGS(SUBARU_ALT_BUS, MSG_SUBARU_ES_LKAS) | ||
| 253 | SUBARU_COMMON_LONG_TX_MSGS(SUBARU_ALT_BUS) | ||
| 254 | SUBARU_GEN2_LONG_ADDITIONAL_TX_MSGS() | ||
| 255 | }; | ||
| 256 | |||
| 257 | static RxCheck subaru_rx_checks[] = { | ||
| 258 | SUBARU_COMMON_RX_CHECKS(SUBARU_MAIN_BUS) | ||
| 259 | }; | ||
| 260 | |||
| 261 | static RxCheck subaru_gen2_rx_checks[] = { | ||
| 262 | SUBARU_COMMON_RX_CHECKS(SUBARU_ALT_BUS) | ||
| 263 | }; | ||
| 264 | |||
| 265 | 139 | const uint16_t SUBARU_PARAM_GEN2 = 1; | |
| 266 | |||
| 267 | 139 | subaru_gen2 = GET_FLAG(param, SUBARU_PARAM_GEN2); | |
| 268 | |||
| 269 | #ifdef ALLOW_DEBUG | ||
| 270 | 139 | const uint16_t SUBARU_PARAM_LONGITUDINAL = 2; | |
| 271 | 139 | subaru_longitudinal = GET_FLAG(param, SUBARU_PARAM_LONGITUDINAL); | |
| 272 | #endif | ||
| 273 | |||
| 274 | safety_config ret; | ||
| 275 |
2/2✓ Branch 0 taken 70 times.
✓ Branch 1 taken 69 times.
|
139 | if (subaru_gen2) { |
| 276 |
2/2✓ Branch 0 taken 37 times.
✓ Branch 1 taken 33 times.
|
70 | ret = subaru_longitudinal ? BUILD_SAFETY_CFG(subaru_gen2_rx_checks, SUBARU_GEN2_LONG_TX_MSGS) : \ |
| 277 | BUILD_SAFETY_CFG(subaru_gen2_rx_checks, SUBARU_GEN2_TX_MSGS); | ||
| 278 | } else { | ||
| 279 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 33 times.
|
69 | ret = subaru_longitudinal ? BUILD_SAFETY_CFG(subaru_rx_checks, SUBARU_LONG_TX_MSGS) : \ |
| 280 | BUILD_SAFETY_CFG(subaru_rx_checks, SUBARU_TX_MSGS); | ||
| 281 | } | ||
| 282 | 139 | return ret; | |
| 283 | } | ||
| 284 | |||
| 285 | const safety_hooks subaru_hooks = { | ||
| 286 | .init = subaru_init, | ||
| 287 | .rx = subaru_rx_hook, | ||
| 288 | .tx = subaru_tx_hook, | ||
| 289 | .fwd = subaru_fwd_hook, | ||
| 290 | .get_counter = subaru_get_counter, | ||
| 291 | .get_checksum = subaru_get_checksum, | ||
| 292 | .compute_checksum = subaru_compute_checksum, | ||
| 293 | }; | ||
| 294 |