def disable_ecu(logcan, sendcan, bus=0, addr=0x7d0, com_cont_req=b'\x28\x83\x01', timeout=0.1, retry=10, debug=False): """Silence an ECU by disabling sending and receiving messages using UDS 0x28. The ECU will stay silent as long as openpilot keeps sending Tester Present. This is used to disable the radar in some cars. Openpilot will emulate the radar. WARNING: THIS DISABLES AEB!""" cloudlog.warning(f"ecu disable {hex(addr)} ...") for i in range(retry): try: query = IsoTpParallelQuery(sendcan, logcan, bus, [addr], [EXT_DIAG_REQUEST], [EXT_DIAG_RESPONSE], debug=debug) for _, _ in query.get_data(timeout).items(): cloudlog.warning("communication control disable tx/rx ...") query = IsoTpParallelQuery(sendcan, logcan, bus, [addr], [com_cont_req], [COM_CONT_RESPONSE], debug=debug) query.get_data(0) cloudlog.warning("ecu disabled") return True except Exception: cloudlog.exception("ecu disable exception") print(f"ecu disable retry ({i+1}) ...") cloudlog.warning("ecu disable failed") return False
def disable_radar(logcan, sendcan, bus, timeout=1, retry=5, debug=False): print(f"radar disable {hex(RADAR_ADDR)} ...") panda = Panda() panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT) for i in range(retry): try: # enter extended diagnostic session query = IsoTpParallelQuery(sendcan, logcan, bus, [RADAR_ADDR], [EXT_DIAG_REQUEST], [EXT_DIAG_RESPONSE], debug=debug) for addr, dat in query.get_data(timeout).items(): print("radar communication control disable tx/rx ...") # communication control disable tx and rx query = IsoTpParallelQuery(sendcan, logcan, bus, [RADAR_ADDR], [COM_CONT_REQUEST], [COM_CONT_RESPONSE], debug=debug) query.get_data(0) return True print(f"radar disable retry ({i+1}) ...") except Exception: cloudlog.warning( f"radar disable exception: {traceback.format_exc()}") return False
def disable_radar(logcan, sendcan, bus=1, timeout=0.1, debug=False): """Silence the radar by disabling sending and receiving messages using UDS 0x28. The radar will stay silent as long as openpilot keeps sending Tester Present. Openpilot will emulate the radar. WARNING: THIS DISABLES AEB!""" cloudlog.warning(f"radar disable {hex(RADAR_ADDR)} ...") try: query = IsoTpParallelQuery(sendcan, logcan, bus, [RADAR_ADDR], [EXT_DIAG_REQUEST], [EXT_DIAG_RESPONSE], debug=debug) for _, _ in query.get_data(timeout).items(): cloudlog.warning("radar communication control disable tx/rx ...") query = IsoTpParallelQuery(sendcan, logcan, bus, [RADAR_ADDR], [COM_CONT_REQUEST], [COM_CONT_RESPONSE], debug=debug) query.get_data(0) cloudlog.warning("radar disabled") return except Exception: cloudlog.exception("radar disable exception") cloudlog.warning("radar disable failed")
def disable_ecu(ecu_addr, logcan, sendcan, bus, timeout=0.5, retry=5, debug=False): print(f"ecu disable {hex(ecu_addr)} ...") for i in range(retry): try: # enter extended diagnostic session query = IsoTpParallelQuery(sendcan, logcan, bus, [ecu_addr], [EXT_DIAG_REQUEST], [EXT_DIAG_RESPONSE], debug=debug) for addr, dat in query.get_data(timeout).items(): # pylint: disable=unused-variable print("ecu communication control disable tx/rx ...") # communication control disable tx and rx query = IsoTpParallelQuery(sendcan, logcan, bus, [ecu_addr], [COM_CONT_REQUEST], [COM_CONT_RESPONSE], debug=debug) query.get_data(0) return True print(f"ecu disable retry ({i+1}) ...") except Exception: cloudlog.warning( f"ecu disable exception: {traceback.format_exc()}") return False
def get_vin(logcan, sendcan, bus, timeout=0.1, retry=5, debug=False): for request, response in ((UDS_VIN_REQUEST, UDS_VIN_RESPONSE), (OBD_VIN_REQUEST, OBD_VIN_RESPONSE)): for i in range(retry): try: query = IsoTpParallelQuery(sendcan, logcan, bus, FUNCTIONAL_ADDRS, [ request, ], [ response, ], functional_addr=True, debug=debug) for addr, vin in query.get_data(timeout).items(): # Honda Bosch response starts with a length, trim to correct length if vin.startswith(b'\x11'): vin = vin[1:18] return addr[0], vin.decode() print(f"vin query retry ({i+1}) ...") except Exception: cloudlog.warning( f"VIN query exception: {traceback.format_exc()}") return 0, VIN_UNKNOWN
def get_fw_versions(logcan, sendcan, extra=None, timeout=0.1, debug=False, progress=False): ecu_types = {} # Extract ECU addresses to query from fingerprints # ECUs using a subaddress need be queried one by one, the rest can be done in parallel addrs = [] parallel_addrs = [] versions = get_interface_attr('FW_VERSIONS', ignore_none=True) if extra is not None: versions.update(extra) for brand, brand_versions in versions.items(): for c in brand_versions.values(): for ecu_type, addr, sub_addr in c.keys(): a = (brand, addr, sub_addr) if a not in ecu_types: ecu_types[(addr, sub_addr)] = ecu_type if sub_addr is None: if a not in parallel_addrs: parallel_addrs.append(a) else: if [a] not in addrs: addrs.append([a]) addrs.insert(0, parallel_addrs) fw_versions = {} for i, addr in enumerate(tqdm(addrs, disable=not progress)): for addr_chunk in chunks(addr): for r in REQUESTS: try: addrs = [(a, s) for (b, a, s) in addr_chunk if b in (r.brand, 'any') and (len(r.whitelist_ecus) == 0 or ecu_types[(a, s)] in r.whitelist_ecus)] if addrs: query = IsoTpParallelQuery(sendcan, logcan, r.bus, addrs, r.request, r.response, r.rx_offset, debug=debug) t = 2 * timeout if i == 0 else timeout fw_versions.update({addr: (version, r.request, r.rx_offset) for addr, version in query.get_data(t).items()}) except Exception: cloudlog.warning(f"FW query exception: {traceback.format_exc()}") # Build capnp list to put into CarParams car_fw = [] for addr, (version, request, rx_offset) in fw_versions.items(): f = car.CarParams.CarFw.new_message() f.ecu = ecu_types[addr] f.fwVersion = version f.address = addr[0] f.responseAddress = uds.get_rx_addr_for_tx_addr(addr[0], rx_offset) f.request = request if addr[1] is not None: f.subAddress = addr[1] car_fw.append(f) return car_fw
def get_ecu_list(logcan, sendcan, bus, extra=None, timeout=0.1, debug=False, progress=False): ecu_types = {} # Extract ECU addresses to query from fingerprints # ECUs using a subadress need be queried one by one, the rest can be done in parallel addrs = [] parallel_addrs = [] versions = get_attr_from_cars('FW_VERSIONS', combine_brands=False) if extra is not None: versions.update(extra) for brand, brand_versions in versions.items(): for c in brand_versions.values(): for ecu_type, addr, sub_addr in c.keys(): a = (brand, addr, sub_addr) if a not in ecu_types: ecu_types[(addr, sub_addr)] = ecu_type if sub_addr is None: if a not in parallel_addrs: parallel_addrs.append(a) else: if [a] not in addrs: addrs.append([a]) addrs.insert(0, parallel_addrs) ecu_list = {} for i, addr in enumerate(tqdm(addrs, disable=not progress)): for addr_chunk in chunks(addr): for brand, request, response in REQUESTS: try: addrs = [(a, s) for (b, a, s) in addr_chunk if b in (brand, 'any')] if addrs: query = IsoTpParallelQuery(sendcan, logcan, bus, addrs, request, response, debug=debug) t = 2 * timeout if i == 0 else timeout ecu_list.update(query.get_data(t)) except Exception: cloudlog.warning(f"ECU query exception: {traceback.format_exc()}") # Build capnp list to put into CarParams car_fw = [] for addr, version in ecu_list.items(): f = car.CarParams.CarFw.new_message() f.ecu = ecu_types[addr] f.fwVersion = version f.address = addr[0] if addr[1] is not None: f.subAddress = addr[1] car_fw.append(f) return car_fw
def get_car_country(logcan, sendcan, bus, timeout=0.1, retry=5, debug=False): print(f"OBD2 query {hex(TX_ADDR)} ...") for i in range(retry): try: query = IsoTpParallelQuery(sendcan, logcan, bus, [TX_ADDR], [OBD_DIAG_REQUEST], [OBD_DIAG_RESPONSE], debug=debug) for addr, dat in query.get_data(timeout).items(): print("query response") print(f"{hex(addr)} {bytes.hex(dat)}") return bytes.hex(dat) print(f"query retry ({i+1}) ...") except Exception: cloudlog.warning(f"OBD2 query exception: {traceback.format_exc()}") return False
def get_vin(logcan, sendcan, bus, timeout=0.1, retry=5, debug=False): for i in range(retry): try: query = IsoTpParallelQuery(sendcan, logcan, bus, FUNCTIONAL_ADDRS, [VIN_REQUEST], [VIN_RESPONSE], functional_addr=True, debug=debug) for addr, vin in query.get_data(timeout).items(): return addr[0], vin.decode() print(f"vin query retry ({i+1}) ...") except Exception: cloudlog.warning(f"VIN query exception: {traceback.format_exc()}") return 0, VIN_UNKNOWN
def get_fw_versions(logcan, sendcan, query_brand=None, extra=None, timeout=0.1, debug=False, progress=False): versions = get_interface_attr('FW_VERSIONS', ignore_none=True) if query_brand is not None: versions = {query_brand: versions[query_brand]} if extra is not None: versions.update(extra) # Extract ECU addresses to query from fingerprints # ECUs using a subaddress need be queried one by one, the rest can be done in parallel addrs = [] parallel_addrs = [] ecu_types = {} for brand, brand_versions in versions.items(): for c in brand_versions.values(): for ecu_type, addr, sub_addr in c.keys(): a = (brand, addr, sub_addr) if a not in ecu_types: ecu_types[a] = ecu_type if sub_addr is None: if a not in parallel_addrs: parallel_addrs.append(a) else: if [a] not in addrs: addrs.append([a]) addrs.insert(0, parallel_addrs) # Get versions and build capnp list to put into CarParams car_fw = [] requests = [ r for r in REQUESTS if query_brand is None or r.brand == query_brand ] for addr in tqdm(addrs, disable=not progress): for addr_chunk in chunks(addr): for r in requests: try: addrs = [(a, s) for (b, a, s) in addr_chunk if b in (r.brand, 'any') and ( len(r.whitelist_ecus) == 0 or ecu_types[ (b, a, s)] in r.whitelist_ecus)] if addrs: query = IsoTpParallelQuery(sendcan, logcan, r.bus, addrs, r.request, r.response, r.rx_offset, debug=debug) for (addr, rx_addr ), version in query.get_data(timeout).items(): f = car.CarParams.CarFw.new_message() f.ecu = ecu_types.get((r.brand, addr[0], addr[1]), Ecu.unknown) f.fwVersion = version f.address = addr[0] f.responseAddress = rx_addr f.request = r.request f.brand = r.brand f.bus = r.bus if addr[1] is not None: f.subAddress = addr[1] car_fw.append(f) except Exception: cloudlog.warning( f"FW query exception: {traceback.format_exc()}") return car_fw
def get_fw_versions(logcan, sendcan, bus, extra=None, timeout=0.1, debug=False, progress=False): ecu_types = {} # Extract ECU adresses to query from fingerprints # ECUs using a subadress need be queried one by one, the rest can be done in parallel addrs = [] parallel_addrs = [] versions = FW_VERSIONS if extra is not None: versions.update(extra) for c in versions.values(): for ecu_type, addr, sub_addr in c.keys(): a = (addr, sub_addr) if a not in ecu_types: ecu_types[a] = ecu_type if sub_addr is None: parallel_addrs.append(a) else: addrs.append([a]) addrs.insert(0, parallel_addrs) fw_versions = {} for i, addr in enumerate(tqdm(addrs, disable=not progress)): for addr_chunk in chunks(addr): for request, response in REQUESTS: try: query = IsoTpParallelQuery(sendcan, logcan, bus, addr_chunk, request, response, debug=debug) t = 2 * timeout if i == 0 else timeout fw_versions.update(query.get_data(t)) except Exception: cloudlog.warning( f"FW query exception: {traceback.format_exc()}") # Build capnp list to put into CarParams car_fw = [] for addr, version in fw_versions.items(): f = car.CarParams.CarFw.new_message() f.ecu = ecu_types[addr] f.fwVersion = version f.address = addr[0] if addr[1] is not None: f.subAddress = addr[1] car_fw.append(f) candidates = match_fw_to_car(fw_versions) return candidates, car_fw