byd: spoof 508 steering feedback to camera on SEAL — fixes ADAS lockout

The Seal's camera faults (ACC + ADAS + AEB warning lights, 'unable to
activate ADAS') because panda neutralizes its intercepted 790 LKAS
commands while the camera watches the 508 feedback for execution —
seeing its requests ignored, it disables the whole ADAS suite.

The Han avoids this by echoing the camera's request back in the 792
feedback; the Seal needs the same on its 508 STEERING_TORQUE_ANGLE:

- bydcan.create_steering_torque_angle: mirrors the Han spoof logic on
  the 508 layout — when camera LKAS is active, echo its 790 torque
  request into MAIN_TORQUE and its 482 angle request into TARGET_ANGLE
  with Cruise_Activated=1; prepare -> LKSPrepare=1; passive -> neutral
- carcontroller: Seal sends the 508 spoof, Han keeps the 792 spoof
- carstate: capture the camera's 482 angle command for the spoof
- panda: whitelist 508 TX on bus 2 (absolute-limit check), stock 508
  blocked 0->2 via check_relay — one config covers both platforms
- firmware rebuilt; spoof decode-verified (camera's exact torque+angle
  echoed back); 120 safety tests + MISRA clean

NOTE: the ADAS fault latches — the car needs a full power cycle (or a
few minutes off) after flashing this build for the dash warnings to
clear.
This commit is contained in:
Quintine committed 2026-07-25 19:37:06 +10:00
1 parent 63e9aa6cc1
commit 02f1972e99
23 files changed
+81 -21

No files matched your search

+14 -5
View File
@@ -42,15 +42,22 @@ static bool byd_tx_hook(const CANPacket_t *msg) {
}
}
// STEERING_TORQUE: feedback message towards the camera, torque echoes the
// camera's own request. Only sanity-check the absolute limit so stock LKAS
// requests don't fault when openpilot is inactive.
// STEERING_TORQUE (792, HAN) / STEERING_TORQUE_ANGLE (508, SEAL):
// feedback message towards the camera, torque echoes the camera's own
// request. Only sanity-check the absolute limit so stock LKAS requests
// don't fault when openpilot is inactive.
if (msg->addr == 792U) {
int main_torque = BYD_GET_MAIN_TORQUE(msg);
if (safety_max_limit_check(main_torque, BYD_STEERING_LIMITS.max_torque, -BYD_STEERING_LIMITS.max_torque)) {
tx = false;
}
}
if (msg->addr == 508U) {
int main_torque = BYD_GET_MAIN_TORQUE_ANGLE(msg);
if (safety_max_limit_check(main_torque, BYD_STEERING_LIMITS.max_torque, -BYD_STEERING_LIMITS.max_torque)) {
tx = false;
}
}
// ACC_CMD: longitudinal actuation
if (msg->addr == 814U) {
@@ -115,12 +122,14 @@ static void byd_rx_hook(const CANPacket_t *msg) {
static safety_config byd_init(uint16_t param) {
static const CanMsg BYD_TX_MSGS[] = {
{790, 0, 8, .check_relay = true}, // MPC_LKAS_CMD
{792, 2, 8, .check_relay = true}, // STEERING_TORQUE
{792, 2, 8, .check_relay = true}, // STEERING_TORQUE (HAN)
{508, 2, 8, .check_relay = true}, // STEERING_TORQUE_ANGLE (SEAL)
};
static const CanMsg BYD_TX_LONG_MSGS[] = {
{790, 0, 8, .check_relay = true}, // MPC_LKAS_CMD
{792, 2, 8, .check_relay = true}, // STEERING_TORQUE
{792, 2, 8, .check_relay = true}, // STEERING_TORQUE (HAN)
{508, 2, 8, .check_relay = true}, // STEERING_TORQUE_ANGLE (SEAL)
{814, 0, 8, .check_relay = true}, // ACC_CMD
};