From 631055fa3987d4cd99c1b50b2ad530a629e6edf8 Mon Sep 17 00:00:00 2001 From: Drew Hintz Date: Fri, 10 Nov 2017 22:35:04 -0800 Subject: [PATCH] Given an interesting CSV file of CAN messages and a list of background CAN messages, print which bits in the interesting file have never appeared in the background files. --- examples/can_unique.py | 80 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 examples/can_unique.py diff --git a/examples/can_unique.py b/examples/can_unique.py new file mode 100644 index 000000000..8b836cc40 --- /dev/null +++ b/examples/can_unique.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python + +# Given an interesting CSV file of CAN messages and a list of background CAN +# messages, print which bits in the interesting file have never appeared +# in the background files. + +# Expects the CSV file to be in the format from can_logger.py +# Bus,MessageID,Message +# 0,344,c000c00000000000 + +import binascii +import csv +import sys +from panda import Panda + +class Message(): + """Details about a specific message ID.""" + def __init__(self, message_id): + self.message_id = message_id + self.data = {} # keyed by hex string encoded message data + self.ones = [0] * 8 # bit set if 1 is seen + self.zeros = [0] * 8 # bit set if 0 has been seen + + def printBitDiff(self, other): + """Prints bits that are set or cleared compared to other background.""" + for i in xrange(len(self.ones)): + new_ones = ((~other.ones[i]) & 0xff) & self.ones[i] + if new_ones: + print 'id %s new one at byte %d bitmask %d' % ( + self.message_id, i, new_ones) + new_zeros = ((~other.zeros[i]) & 0xff) & self.zeros[i] + if new_zeros: + print 'id %s new zero at byte %d bitmask %d' % ( + self.message_id, i, new_zeros) + + +class Info(): + """A collection of Messages.""" + + def __init__(self): + self.messages = {} # keyed by MessageID + + def load(self, filename): + """Given a CSV file, adds information about message IDs and their values.""" + with open(filename, 'rb') as input: + reader = csv.reader(input) + next(reader, None) # skip the CSV header + for row in reader: + message_id = row[1] + data = row[2] + if message_id not in self.messages: + self.messages[message_id] = Message(message_id) + message = self.messages[message_id] + if data not in self.messages[message_id].data: + message.data[data] = True + bytes = bytearray.fromhex(data) + for i in xrange(len(bytes)): + message.ones[i] = message.ones[i] | int(bytes[i]) + # Inverts the data and masks it to a byte to get the zeros as ones. + message.zeros[i] = message.zeros[i] | ( (~int(bytes[i])) & 0xff) + +def PrintUnique(interesting_file, background_files): + background = Info() + for background_file in background_files: + background.load(background_file) + interesting = Info() + interesting.load(interesting_file) + for message_id in interesting.messages: + if message_id not in background.messages: + print 'New message_id: %s' % message_id + else: + interesting.messages[message_id].printBitDiff( + background.messages[message_id]) + + +if __name__ == "__main__": + if len(sys.argv) < 3: + print 'Usage:\n%s interesting.csv background*.csv' % sys.argv[0] + sys.exit(0) + PrintUnique(sys.argv[1], sys.argv[2:])