Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- import json
- import sys
- from itertools import cycle
- from collections import defaultdict
- # 7-bit temperature sensor address
- SENSOR_ADDR_7BIT = 0x30
- # XOR key for decrypting the I2C payload
- XOR_KEY = "bananza"
- def load_events(path):
- events = []
- with open(path, "r") as f:
- for line in f:
- line = line.strip()
- if not line:
- continue
- events.append(json.loads(line))
- return events
- def bits_map_to_bytes(bits_map):
- """
- bits_map: {byteIndex: {bitIndex: bit_value}}
- bitIndex 0 is treated as MSB (bit7), I²C is MSB-first.
- """
- out = {}
- for byte_index, bit_dict in bits_map.items():
- # Ensure bits are in ascending bitIndex order
- bits = [bit_dict[i] for i in sorted(bit_dict.keys())]
- val = 0
- for i, b in enumerate(bits):
- # MSB-first: bitIndex 0 -> bit7, 1 -> bit6, ..., 7 -> bit0
- val |= (b & 1) << (7 - i)
- out[byte_index] = val
- return out
- def parse_i2c_bytes_from_sda(events):
- """
- Uses only SDA markers:
- - 'address-bit' for the address byte
- - 'data-bit' for the data bytes
- """
- addr_bits = defaultdict(dict) # {byteIndex: {bitIndex: v}}
- data_bits = defaultdict(dict)
- for e in events:
- marker = e.get("marker", "")
- etype = e.get("type", "")
- if marker == "address-bit" and etype == "address":
- addr_bits[e["byteIndex"]][e["bitIndex"]] = e["v"]
- elif marker == "data-bit" and etype == "data":
- data_bits[e["byteIndex"]][e["bitIndex"]] = e["v"]
- addr_bytes = bits_map_to_bytes(addr_bits)
- data_bytes = bits_map_to_bytes(data_bits)
- return addr_bytes, data_bytes
- def bytes_to_ascii(data_bytes):
- return "".join(chr(b) if 32 <= b < 127 else "." for b in data_bytes)
- def xor_decrypt(data_bytes, key_str):
- key_bytes = key_str.encode("ascii")
- return [b ^ k for b, k in zip(data_bytes, cycle(key_bytes))]
- def main():
- if len(sys.argv) != 2:
- print(f"Usage: {sys.argv[0]} sda.json", file=sys.stderr)
- sys.exit(1)
- sda_path = sys.argv[1]
- # 1. Load SDA events
- events = load_events(sda_path)
- if not events:
- print("No events found in SDA file.", file=sys.stderr)
- sys.exit(1)
- # 2. Rebuild address + data bytes from bit markers
- addr_bytes, data_bytes_map = parse_i2c_bytes_from_sda(events)
- if 0 not in addr_bytes:
- print("No address byte decoded (byteIndex 0 missing).", file=sys.stderr)
- sys.exit(1)
- addr_byte = addr_bytes[0]
- addr_7bit = (addr_byte >> 1) & 0x7F
- rw_bit = addr_byte & 1
- print(f"I2C address byte: 0x{addr_byte:02X}")
- print(f" -> 7-bit address: 0x{addr_7bit:02X}")
- print(f" -> R/W bit : {rw_bit} ({'read' if rw_bit else 'write'})")
- if addr_7bit != SENSOR_ADDR_7BIT:
- print(
- f"WARNING: decoded 7-bit address 0x{addr_7bit:02X} "
- f"!= expected temperature sensor address 0x{SENSOR_ADDR_7BIT:02X}"
- )
- # 3. Collect data bytes in byteIndex order
- if not data_bytes_map:
- print("No data bytes decoded.", file=sys.stderr)
- sys.exit(1)
- data_bytes = [data_bytes_map[i] for i in sorted(data_bytes_map.keys())]
- print("\nRaw I2C data (from sensor):")
- print("HEX :", " ".join(f"{b:02X}" for b in data_bytes))
- print("ASCII:", bytes_to_ascii(data_bytes))
- # 4. Read and decrypt the I2C bus data using the XOR key: bananza
- decrypted = xor_decrypt(data_bytes, XOR_KEY)
- print(f"\nDecrypted I2C data using XOR key '{XOR_KEY}':")
- print("HEX :", " ".join(f"{b:02X}" for b in decrypted))
- print("ASCII:", bytes_to_ascii(decrypted))
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment