import csv # 1. Load the raw edges from the CSV edges = [] with open('capture.csv', 'r') as f: reader = csv.reader(f) next(reader) # Skip the header row for row in reader: # row[0] is time in seconds, row[1] is logic state (0 or 1) edges.append((float(row[0]), int(row[1]))) # 2. Reconstruct the physical bitstream (1 Mbps = 1 microsecond per bit) bit_time = 1e-6 bits = [] for i in range(len(edges)-1): duration = edges[i+1][0] - edges[i][0] num_bits = int(round(duration / bit_time)) bits.extend([edges[i][1]] * num_bits) # 3. Parse the CAN frames directly (Ignoring Bit Stuffing Rules) idx = 0 print("Hunting for payloads...\n") while idx < len(bits) - 50: # Look for Start of Frame (0) after an idle bus (1) if bits[idx] == 0 and (idx == 0 or bits[idx-1] == 1): idx += 1 # Skip SOF id_bits = bits[idx : idx+11] # 11-bit ID idx += 11 idx += 3 # Skip RTR, IDE, and r0 control bits dlc_bits = bits[idx : idx+4] # 4-bit Data Length Code dlc = int("".join(map(str, dlc_bits)), 2) idx += 4 # If payload exists, decode it into ASCII if 0 < dlc <= 8: payload = [] for _ in range(dlc): byte_bits = bits[idx : idx+8] byte_val = int("".join(map(str, byte_bits)), 2) payload.append(chr(byte_val)) idx += 8 print(f"Decoded Payload: {''.join(payload)}") else: idx += 1 # Step forward if it was a false start else: idx += 1