Allow to lock safety mode to keep gm/tesla cars supported (#844)

rbiasini 2019-10-11 17:35:07 -07:00 committed by GitHub
parent 6b62dd2308
commit 069e337bea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 16 deletions

View File

@ -80,6 +80,7 @@ keys = {
"Passive": [TxType.PERSISTENT],
"RecordFront": [TxType.PERSISTENT],
"ReleaseNotes": [TxType.PERSISTENT],
"SafetyModelLock": [TxType.PERSISTENT],
"ShouldDoUpdate": [TxType.CLEAR_ON_MANAGER_START],
"SpeedLimitOffset": [TxType.PERSISTENT],
"SubscriberInfo": [TxType.PERSISTENT],

View File

@ -49,6 +49,7 @@ const uint32_t NO_IGNITION_CNT_MAX = 2 * 60 * 60 * 24 * 3; // turn off charge a
uint32_t no_ignition_cnt = 0;
bool connected_once = false;
uint8_t ignition_last = 0;
bool safety_model_locked = false;
pthread_t safety_setter_thread_handle = -1;
pthread_t pigeon_thread_handle = -1;
@ -74,12 +75,12 @@ void *safety_setter_thread(void *s) {
}
LOGW("got CarVin %s", value_vin);
pthread_mutex_lock(&usb_lock);
// VIN query done, stop listening to OBDII
libusb_control_transfer(dev_handle, 0x40, 0xdc, (uint16_t)(cereal::CarParams::SafetyModel::NO_OUTPUT), 0, NULL, 0, TIMEOUT);
pthread_mutex_unlock(&usb_lock);
if (!safety_model_locked) {
pthread_mutex_lock(&usb_lock);
libusb_control_transfer(dev_handle, 0x40, 0xdc, (uint16_t)(cereal::CarParams::SafetyModel::NO_OUTPUT), 0, NULL, 0, TIMEOUT);
pthread_mutex_unlock(&usb_lock);
}
char *value;
size_t value_sz = 0;
@ -125,6 +126,11 @@ void *safety_setter_thread(void *s) {
bool usb_connect() {
int err;
unsigned char hw_query[1] = {0};
char *value_safety_model;
size_t value_safety_model_sz = 0;
int safety_model;
const int result = read_db_value(NULL, "SafetyModelLock", &value_safety_model, &value_safety_model_sz);
ignition_last = 0;
dev_handle = libusb_open_device_with_vid_pid(ctx, 0xbbaa, 0xddcc);
@ -140,6 +146,16 @@ bool usb_connect() {
libusb_control_transfer(dev_handle, 0xc0, 0xe5, 1, 0, NULL, 0, TIMEOUT);
}
// check if safety mode is forced (needed to support gm)
if (value_safety_model_sz > 0) {
sscanf(value_safety_model, "%d", &safety_model);
// sanity check that we are not setting all output
assert(safety_model != (int)(cereal::CarParams::SafetyModel::ALL_OUTPUT));
safety_model_locked = true;
LOGW("Setting Locked Safety Model %s", value_safety_model);
libusb_control_transfer(dev_handle, 0x40, 0xdc, (uint16_t)(cereal::CarParams::SafetyModel(safety_model)), 0, NULL, 0, TIMEOUT);
}
// power off ESP
libusb_control_transfer(dev_handle, 0xc0, 0xd9, 0, 0, NULL, 0, TIMEOUT);
@ -297,10 +313,11 @@ void can_health(void *s) {
assert((result == 0) || (result == ERR_NO_VALUE));
// diagnostic only is the default, needed for VIN query
pthread_mutex_lock(&usb_lock);
libusb_control_transfer(dev_handle, 0x40, 0xdc, (uint16_t)(cereal::CarParams::SafetyModel::ELM327), 0, NULL, 0, TIMEOUT);
pthread_mutex_unlock(&usb_lock);
if (!safety_model_locked) {
pthread_mutex_lock(&usb_lock);
libusb_control_transfer(dev_handle, 0x40, 0xdc, (uint16_t)(cereal::CarParams::SafetyModel::ELM327), 0, NULL, 0, TIMEOUT);
pthread_mutex_unlock(&usb_lock);
}
if (safety_setter_thread_handle == -1) {
err = pthread_create(&safety_setter_thread_handle, NULL, safety_setter_thread, NULL);
assert(err == 0);

View File

@ -0,0 +1,27 @@
#!/usr/bin/env python3
import sys
from cereal import car
from common.params import Params
# This script locks the safety model to a given value.
# When the safety model is locked, boardd will preset panda to the locked safety model
# run example:
# ./lock_safety_model.py gm
if __name__ == "__main__":
params = Params()
if len(sys.argv) < 2:
params.delete("SafetyModelLock")
print("Clear locked safety model")
else:
safety_model = getattr(car.CarParams.SafetyModel, sys.argv[1])
if type(safety_model) != int:
raise Exception("Invalid safety model: " + sys.argv[1])
if safety_model == car.CarParams.SafetyModel.allOutput:
raise Exception("Locking the safety model to allOutput is not allowed")
params.put("SafetyModelLock", str(safety_model))
print("Locked safety model: " + sys.argv[1])

View File

@ -129,7 +129,6 @@ def thermald_thread():
off_ts = None
started_ts = None
ignition_seen = False
started_seen = False
thermal_status = ThermalStatus.green
thermal_status_prev = ThermalStatus.green
@ -151,7 +150,6 @@ def thermald_thread():
# clear car params when panda gets disconnected
if health is None and health_prev is not None:
params.panda_disconnect()
ignition_seen = False
health_prev = health
if health is not None:
@ -233,11 +231,6 @@ def thermald_thread():
# start constellation of processes when the car starts
ignition = health is not None and health.health.started
ignition_seen = ignition_seen or ignition
# add voltage check for ignition
if not ignition_seen and health is not None and health.health.voltage > 13500:
ignition = True
do_uninstall = params.get("DoUninstall") == b"1"
accepted_terms = params.get("HasAcceptedTerms") == terms_version