From 7f3b1774dd248d4ebad91cc9de0fb1c561fab54b Mon Sep 17 00:00:00 2001 From: Adeeb <8762862+quillford@users.noreply.github.com> Date: Thu, 30 Apr 2020 14:06:26 -0700 Subject: [PATCH] Chrysler: calculate checksum in can packer/parser (#255) * calculate chrysler checksum in can packer/parser * remove comment --- can/common.cc | 32 ++++++++++++++++++++++++++++++++ can/common.h | 1 + can/common.pxd | 3 ++- can/common_dbc.h | 1 + can/dbc_template.cc | 2 ++ can/packer.cc | 3 +++ can/parser.cc | 5 +++++ can/process_dbc.py | 7 +++++++ 8 files changed, 53 insertions(+), 1 deletion(-) diff --git a/can/common.cc b/can/common.cc index 68c3ee0..b303391 100644 --- a/can/common.cc +++ b/can/common.cc @@ -35,6 +35,38 @@ unsigned int subaru_checksum(unsigned int address, uint64_t d, int l) { return s & 0xFF; } +unsigned int chrysler_checksum(unsigned int address, uint64_t d, int l) { + /* This function does not want the checksum byte in the input data. + jeep chrysler canbus checksum from http://illmatics.com/Remote%20Car%20Hacking.pdf */ + uint8_t checksum = 0xFF; + for (int j = 0; j < (l - 1); j++) { + uint8_t shift = 0x80; + uint8_t curr = (d >> 8*j) & 0xFF; + for (int i=0; i<8; i++) { + uint8_t bit_sum = curr & shift; + uint8_t temp_chk = checksum & 0x80U; + if (bit_sum != 0U) { + bit_sum = 0x1C; + if (temp_chk != 0U) { + bit_sum = 1; + } + checksum = checksum << 1; + temp_chk = checksum | 1U; + bit_sum ^= temp_chk; + } else { + if (temp_chk != 0U) { + bit_sum = 0x1D; + } + checksum = checksum << 1; + bit_sum ^= checksum; + } + checksum = bit_sum; + shift = shift >> 1; + } + } + return ~checksum & 0xFF; +} + // Static lookup table for fast computation of CRC8 poly 0x2F, aka 8H2F/AUTOSAR uint8_t crc8_lut_8h2f[256]; diff --git a/can/common.h b/can/common.h index 841c060..dd91a6c 100644 --- a/can/common.h +++ b/can/common.h @@ -14,6 +14,7 @@ unsigned int honda_checksum(unsigned int address, uint64_t d, int l); unsigned int toyota_checksum(unsigned int address, uint64_t d, int l); unsigned int subaru_checksum(unsigned int address, uint64_t d, int l); +unsigned int chrysler_checksum(unsigned int address, uint64_t d, int l); void init_crc_lookup_tables(); unsigned int volkswagen_crc(unsigned int address, uint64_t d, int l); unsigned int pedal_checksum(uint64_t d, int l); diff --git a/can/common.pxd b/can/common.pxd index 0082110..5519140 100644 --- a/can/common.pxd +++ b/can/common.pxd @@ -19,7 +19,8 @@ cdef extern from "common_dbc.h": PEDAL_COUNTER, VOLKSWAGEN_CHECKSUM, VOLKSWAGEN_COUNTER, - SUBARU_CHECKSUM + SUBARU_CHECKSUM, + CHRYSLER_CHECKSUM cdef struct Signal: const char* name diff --git a/can/common_dbc.h b/can/common_dbc.h index 317e805..e5c12ba 100644 --- a/can/common_dbc.h +++ b/can/common_dbc.h @@ -39,6 +39,7 @@ enum SignalType { VOLKSWAGEN_CHECKSUM, VOLKSWAGEN_COUNTER, SUBARU_CHECKSUM, + CHRYSLER_CHECKSUM, }; struct Signal { diff --git a/can/dbc_template.cc b/can/dbc_template.cc index 439643a..f6d4988 100644 --- a/can/dbc_template.cc +++ b/can/dbc_template.cc @@ -31,6 +31,8 @@ const Signal sigs_{{address}}[] = { .type = SignalType::VOLKSWAGEN_COUNTER, {% elif checksum_type == "subaru" and sig.name == "CHECKSUM" %} .type = SignalType::SUBARU_CHECKSUM, + {% elif checksum_type == "chrysler" and sig.name == "CHECKSUM" %} + .type = SignalType::CHRYSLER_CHECKSUM, {% elif address in [512, 513] and sig.name == "CHECKSUM_PEDAL" %} .type = SignalType::PEDAL_CHECKSUM, {% elif address in [512, 513] and sig.name == "COUNTER_PEDAL" %} diff --git a/can/packer.cc b/can/packer.cc index 7efedfa..ba675a5 100644 --- a/can/packer.cc +++ b/can/packer.cc @@ -102,6 +102,9 @@ uint64_t CANPacker::pack(uint32_t address, const std::vector &s } else if (sig.type == SignalType::SUBARU_CHECKSUM) { unsigned int chksm = subaru_checksum(address, ret, message_lookup[address].size); ret = set_value(ret, sig, chksm); + } else if (sig.type == SignalType::CHRYSLER_CHECKSUM) { + unsigned int chksm = chrysler_checksum(address, ReverseBytes(ret), message_lookup[address].size); + ret = set_value(ret, sig, chksm); } else { //WARN("CHECKSUM signal type not valid\n"); } diff --git a/can/parser.cc b/can/parser.cc index 69fe374..315fd50 100644 --- a/can/parser.cc +++ b/can/parser.cc @@ -57,6 +57,11 @@ bool MessageState::parse(uint64_t sec, uint16_t ts_, uint8_t * dat) { if (!update_counter_generic(tmp, sig.b2)) { return false; } + } else if (sig.type == SignalType::CHRYSLER_CHECKSUM) { + if (chrysler_checksum(address, dat_le, size) != tmp) { + INFO("0x%X CHECKSUM FAIL\n", address); + return false; + } } else if (sig.type == SignalType::PEDAL_CHECKSUM) { if (pedal_checksum(dat_be, size) != tmp) { INFO("0x%X PEDAL CHECKSUM FAIL\n", address); diff --git a/can/process_dbc.py b/can/process_dbc.py index c39184d..1ca0db2 100755 --- a/can/process_dbc.py +++ b/can/process_dbc.py @@ -53,6 +53,13 @@ def process(in_fn, out_fn): checksum_start_bit = 0 counter_start_bit = None little_endian = True + elif can_dbc.name.startswith(("chrysler_")): + checksum_type = "chrysler" + checksum_size = 8 + counter_size = None + checksum_start_bit = 7 + counter_start_bit = None + little_endian = False else: checksum_type = None checksum_size = None