ELM327: Ignore received messages not related to sent command.

master
Jessy Diamond Exum 2017-08-10 05:01:35 -07:00
parent 113ce67e83
commit 7dc3e2568c
3 changed files with 74 additions and 15 deletions

View File

@ -298,6 +298,9 @@ static volatile os_timer_t elm_timeout;
static bool did_multimessage = false;
static bool got_msg_this_run = false;
static bool can_tx_worked = false;
static uint8_t elm_msg_mode;
static uint8_t elm_msg_pid;
void ICACHE_FLASH_ATTR elm_timer_cb(void *arg){
loopcount--;
@ -319,7 +322,8 @@ void ICACHE_FLASH_ATTR elm_timer_cb(void *arg){
//TODO make elm only print messages that have the same PID
if (recv->bus==0 && (panda_get_can_addr(recv) & 0x7F8) == 0x7E8 && recv->len == 8) {
if(recv->data[0] <= 7) {
if(recv->data[0] <= 7 &&
recv->data[1] == (0x40|elm_msg_mode) && recv->data[2] == elm_msg_pid) {
got_msg_this_run = true;
loopcount = LOOPCOUNT_FULL;
os_printf(" CAN msg response, index: %d\n", i);
@ -336,7 +340,8 @@ void ICACHE_FLASH_ATTR elm_timer_cb(void *arg){
elm_tcp_tx_flush();
//return;
} else if((recv->data[0] & 0xF0) == 0x10) {
} else if((recv->data[0] & 0xF0) == 0x10 &&
recv->data[2] == (0x40|elm_msg_mode) && recv->data[3] == elm_msg_pid) {
got_msg_this_run = true;
loopcount = LOOPCOUNT_FULL;
panda_usbemu_can_write(0, 0x7E0 | (panda_get_can_addr(recv)&0x7), "\x30\x00\x00", 3);
@ -420,6 +425,11 @@ static void ICACHE_FLASH_ATTR elm_process_obd_cmd(char *cmd, uint16_t len) {
for(int i = 0; i < msg.len; i++)
msg.dat[i] = elm_decode_hex_byte(&cmd[i*2]);
elm_msg_mode = msg.dat[0];
elm_msg_pid = msg.dat[1];
os_printf("Stored Mode: %02x; Pid: %02x\n", elm_msg_mode, elm_msg_pid);
os_printf("ELM CAN tx dat: %d.\r\n ", msg.len);
for(int i = 0; i < 7; i++)
os_printf("%02x ", msg.dat[i]);
@ -437,7 +447,7 @@ static void ICACHE_FLASH_ATTR elm_process_obd_cmd(char *cmd, uint16_t len) {
}
void ICACHE_FLASH_ATTR elm_switch_proto(){
elm_protocol_t* proto = elm_current_proto();
const elm_protocol_t* proto = elm_current_proto();
if(!proto->supported) return;
switch(proto->type) {
case AUTO:
@ -626,7 +636,7 @@ static void ICACHE_FLASH_ATTR elm_process_at_cmd(char *cmd, uint16_t len) {
elm_mode_additional_headers = true;
break;
case AT_I: //IDENTIFY SELF
elm_append_rsp(IDENT_MSG, sizeof(IDENT_MSG)-1);
elm_append_rsp_const(IDENT_MSG);
return;
case AT_L0: //LINEFEED OFF
elm_mode_linefeed = false;
@ -688,7 +698,7 @@ static void ICACHE_FLASH_ATTR elm_process_at_cmd(char *cmd, uint16_t len) {
elm_mode_timeout = ELM_MODE_TIMEOUT_DEFAULT;
elm_append_rsp_const("\r\r");
elm_append_rsp(IDENT_MSG, sizeof(IDENT_MSG)-1);
elm_append_rsp_const(IDENT_MSG);
panda_set_safety_mode(0x1337);
elm_switch_proto();
return;
@ -724,7 +734,7 @@ static void ICACHE_FLASH_ATTR elm_rx_cb(void *arg, char *data, uint16_t len) {
if(loopcount){
os_timer_disarm(&elm_timeout);
loopcount = 0;
os_printf("Tearing down timer. msg len: %d\n", len);
os_printf("Interrupting operation, stopping timer. msg len: %d\n", len);
elm_append_rsp_const("STOPPED\r\r>");
if(len == 1 && data[0] == '\r') {
os_printf("Empty msg source of interrupt.\n");

View File

@ -154,6 +154,49 @@ def test_elm_send_can_multimsg():
sim = elm_car_simulator.ELMCanCarSimulator(serial)
sim.start()
try:
sync_reset(s)
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
send_compare(s, b'ATS1\r', b'OK\r\r>') # Spaces OFF
send_compare(s, b'ATH1\r', b'OK\r\r>') # Headers ON
send_compare(s, b'ATSP6\r', b"OK\r\r>") # Set Proto ISO 15765-4 (CAN 11/500)
sim.add_extra_noise(b'\x03\x41\x0D\xFA', addr=0x7E9)# Inject message into the stream
send_compare(s, b'010D\r',
b"7E8 03 41 0D 53 \r"
"7E9 03 41 0D FA \r\r>") # Check it was ignored.
finally:
sim.stop()
sim.join()
s.close()
def test_elm_can_check_mode_pid():
s = elm_connect()
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
sim = elm_car_simulator.ELMCanCarSimulator(serial)
sim.start()
try:
sync_reset(s)
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces OFF
send_compare(s, b'ATH0\r', b'OK\r\r>') # Headers OFF
send_compare(s, b'ATSP6\r', b"OK\r\r>") # Set Proto ISO 15765-4 (CAN 11/500)
sim.add_extra_noise(b'\x03\x41\x0E\xFA')# Inject message into the stream
send_compare(s, b'010D\r', b"410D53\r\r>") # Check it was ignored.
send_compare(s, b'0100\r', b"4100FFFFFFFE\r\r>") # Check it was ignored again.
finally:
sim.stop()
sim.join()
s.close()
def test_elm_send_can_multiline_msg():
s = elm_connect()
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
sim = elm_car_simulator.ELMCanCarSimulator(serial)
sim.start()
try:
sync_reset(s)
send_compare(s, b'ATSP6\r', b"ATSP6\rOK\r\r>") # Set Proto
@ -190,7 +233,7 @@ def test_elm_send_can_multimsg():
# TODO: Expand test to full throughput.
# Max throughput currently causes dropped wifi packets
def test_elm_send_can_multimsg_throughput():
def test_elm_send_can_multiline_msg_throughput():
s = elm_connect()
serial = os.getenv("CANSIMSERIAL") if os.getenv("CANSIMSERIAL") else None
sim = elm_car_simulator.ELMCanCarSimulator(serial)
@ -225,25 +268,22 @@ def test_elm_can_baud():
sync_reset(s)
send_compare(s, b'ATE0\r', b'ATE0\rOK\r\r>') # Echo OFF
send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces OFF
send_compare(s, b'ATH0\r', b'OK\r\r>') # Headers ON
send_compare(s, b'ATH1\r', b'OK\r\r>') # Headers ON
send_compare(s, b'ATSP6\r', b"OK\r\r>") # Set Proto ISO 15765-4 (CAN 11/500)
send_compare(s, b'0100\r', b"4100FFFFFFFE\r\r>")
send_compare(s, b'0100\r', b"7E8064100FFFFFFFE\r\r>")
send_compare(s, b'ATSP8\r', b"OK\r\r>") # Set Proto ISO 15765-4 (CAN 11/250)
send_compare(s, b'0100\r', b"CAN ERROR\r\r>")
#sim.stop()
#sim.join()
#sim = elm_car_simulator.ELMCanCarSimulator(serial, can_kbaud=250)
#sim.start()
sim.change_can_baud(250)
send_compare(s, b'ATSP6\r', b"OK\r\r>") # Set Proto ISO 15765-4 (CAN 11/500)
send_compare(s, b'0100\r', b"CAN ERROR\r\r>")
send_compare(s, b'ATSP8\r', b"OK\r\r>") # Set Proto ISO 15765-4 (CAN 11/250)
send_compare(s, b'0100\r', b"4100FFFFFFFE\r\r>")
send_compare(s, b'0100\r', b"7E8064100FFFFFFFE\r\r>")
finally:
sim.stop()
sim.join()

View File

@ -7,6 +7,7 @@ import struct
import binascii
import time
import threading
from collections import deque
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), ".."))
from panda import Panda
@ -18,6 +19,7 @@ class ELMCanCarSimulator(threading.Thread):
self.__stop = False
self._multipart_data = None
self._can_kbaud = can_kbaud
self._extra_noise_msgs = deque()
self._p.can_recv() # Toss whatever was already there
@ -26,7 +28,11 @@ class ELMCanCarSimulator(threading.Thread):
def _can_send(self, addr, msg):
print(" Reply (%x)" % addr, binascii.hexlify(msg))
return self._p.can_send(addr, msg + b'\x00'*(8-len(msg)), 0)
self._p.can_send(addr, msg + b'\x00'*(8-len(msg)), 0)
if self._extra_noise_msgs:
noise = self._extra_noise_msgs.popleft()
self._p.can_send(noise[0] if noise[0] is not None else addr,
noise[1] + b'\x00'*(8-len(noise[1])), 0)
def _addr_matches(self, addr):
return addr in (0x7DF, 0x7E0, 0x18db33f1)
@ -44,6 +50,9 @@ class ELMCanCarSimulator(threading.Thread):
self._can_kbaud = kbaud
self._p.set_can_speed_kbps(0, self._can_kbaud)
def add_extra_noise(self, noise_msg, addr=None):
self._extra_noise_msgs.append((addr, noise_msg))
def _process_msg(self, mode, pid, address, ts, data, src):
#Check functional address of 11 bit and 29 bit CAN
#if address == 0x18db33f1: return