ELM327: Panda safety mode for ELM327 (passes ISO 15765-4 11&29 bit messages)

This commit is contained in:
Jessy Diamond Exum 2017-08-11 16:17:43 -07:00
parent 53963c9025
commit 09ee296550
5 changed files with 91 additions and 5 deletions

View File

@ -251,7 +251,8 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
case 0xdc:
// this is the only way to leave silent mode
// and it's blocked over WiFi
if (hardwired) {
// Allow ELM security mode to be set over wifi.
if (hardwired || setup->b.wValue.w == SAFETY_ELM327) {
safety_set_mode(setup->b.wValue.w);
can_silent = (setup->b.wValue.w == SAFETY_NOOUTPUT);
can_init_all();
@ -508,4 +509,3 @@ int main() {
return 0;
}

View File

@ -20,6 +20,7 @@ int controls_allowed = 0;
// Include the actual safety policies.
#include "safety/safety_defaults.h"
#include "safety/safety_honda.h"
#include "safety/safety_elm327.h"
const safety_hooks *current_hooks = &nooutput_hooks;
@ -43,11 +44,13 @@ typedef struct {
#define SAFETY_NOOUTPUT 0
#define SAFETY_HONDA 1
#define SAFETY_ALLOUTPUT 0x1337
#define SAFETY_ELM327 0xE327
const safety_hook_config safety_hook_registry[] = {
{SAFETY_NOOUTPUT, &nooutput_hooks},
{SAFETY_HONDA, &honda_hooks},
{SAFETY_ALLOUTPUT, &alloutput_hooks},
{SAFETY_ELM327, &elm327_hooks},
};
#define HOOK_CONFIG_COUNT (sizeof(safety_hook_registry)/sizeof(safety_hook_config))
@ -56,10 +59,9 @@ int safety_set_mode(uint16_t mode){
for (int i = 0; i < HOOK_CONFIG_COUNT; i++) {
if (safety_hook_registry[i].id == mode) {
current_hooks = safety_hook_registry[i].hooks;
current_hooks->init();
if(current_hooks->init) current_hooks->init();
return 0;
}
}
return -1;
}

View File

@ -0,0 +1,31 @@
static void elm327_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {}
static int elm327_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
//All ELM traffic must appear on CAN0
if(((to_send->RDTR >> 4) & 0xf) != 0) return 0;
//All ISO 15765-4 messages must be 8 bytes long
if((to_send->RDTR & 0xf) != 8) return 0;
if(to_send->RIR & 4){
uint32_t addr = to_send->RIR >> 3;
//Check valid 29 bit send addresses for ISO 15765-4
if(!(addr == 0x18DB33F1 || (addr & 0x1FFF00FF) == 0x18DA00F1)) return 0;
} else {
uint32_t addr = to_send->RIR >> 21;
//Check valid 11 bit send addresses for ISO 15765-4
if(!(addr == 0x7DF || (addr & 0x7F8) == 0x7E0)) return 0;
}
return true;
}
//static int elm327_tx_lin_hook(int lin_num, uint8_t *data, int len) {
// return false;
//}
const safety_hooks elm327_hooks = {
.init = NULL,
.rx = elm327_rx_hook,
.tx = elm327_tx_hook,
.tx_lin = nooutput_tx_lin_hook,
};

View File

@ -828,7 +828,7 @@ static void ICACHE_FLASH_ATTR elm_process_at_cmd(char *cmd, uint16_t len) {
elm_append_rsp_const("\r\r");
elm_append_rsp_const(IDENT_MSG);
panda_set_safety_mode(0x1337);
panda_set_safety_mode(0xE327);
elm_switch_proto();
return;
default:

View File

@ -8,6 +8,8 @@ import pytest
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), ".."))
import elm_car_simulator
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", ".."))
from panda import Panda
def elm_connect():
s = socket.create_connection(("192.168.0.10", 35000))
@ -405,3 +407,54 @@ def test_elm_can_baud():
sim.stop()
sim.join()
s.close()
def test_elm_panda_safety_mode_ISO15765():
s = elm_connect()
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
p_car = Panda(serial) # Configure this so the messages will send
p_car.set_can_speed_kbps(0, 500)
p_car.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
p_elm = Panda("WIFI")
#sim = elm_car_simulator.ELMCanCarSimulator(serial)
#sim.start()
def did_send(p, addr, dat, bus):
p.can_send(addr, dat, bus)
t = time.time()
while time.time()-t < 0.5:
msg = p.can_recv()
for addrin, _, datin, busin in msg:
if (0x80 | bus) == busin and addr == addrin and datin == dat:
return True
time.sleep(0.01)
return False
try:
sync_reset(s) # Reset elm (which requests the ELM327 safety mode)
send_compare(s, b'ATSP6\r', b"ATSP6\rOK\r\r>") # Set Proto ISO 15765-4 (CAN 11/500)
#29 bit
assert not did_send(p_elm, 0x18DB33F1, b'\x02\x01\x00\x00\x00\x00\x00\x00', 1) #wrong canid
assert not did_send(p_elm, 0x18DB33F1, b'\x02\x01\x00', 0) #wrong length
assert not did_send(p_elm, 0x10000000, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) #bad addr
assert not did_send(p_elm, 0x18DAF133, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) #bad addr (phy addr)
assert not did_send(p_elm, 0x18DAF000, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) #bad addr
assert not did_send(p_elm, 0x18DAF1F3, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) #bad addr! (phys rsp to elm)
assert did_send(p_elm, 0x18DB33F1, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) #good! (obd func req)
assert did_send(p_elm, 0x18DA10F1, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) #good! (phys response)
#11 bit
assert not did_send(p_elm, 0X7DF, b'\x02\x01\x00\x00\x00\x00\x00\x00', 1) #wrong canid
assert not did_send(p_elm, 0X7DF, b'\x02\x01\x00', 0) #wrong length
assert not did_send(p_elm, 0xAA, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) #bad addr
assert not did_send(p_elm, 0x7DA, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) #bad addr (phy addr)
assert not did_send(p_elm, 0x7E8, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) #bad addr (sending 'response')
assert did_send(p_elm, 0x7DF, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) #good! (obd func req)
assert did_send(p_elm, 0x7E1, b'\x02\x01\x00\x00\x00\x00\x00\x00', 0) #good! (phys response)
finally:
s.close()