def clientSetUp(self): self.udsclient = Client(self.conn, request_timeout=0.2) self.udsclient.set_config('logger_name', 'unittest') self.udsclient.set_config('exception_on_invalid_response', True) self.udsclient.set_config('exception_on_unexpected_response', True) self.udsclient.set_config('exception_on_negative_response', True) self.udsclient.open() if hasattr(self, "postClientSetUp"): self.postClientSetUp()
def testerPresent(self, *args): try: with Client(self.conn, request_timeout=1, config={'exception_on_unexpected_response': False}) as client: # noqa: F841 self.conn.send(b'\x10\x03') self.termPrint('Request', b'\x10\x03') payload = self.conn.wait_frame(timeout=1) response = Response.\ from_payload(payload) # noqa: F841, E501 response = str(response).split('<') response = (response[1].split('-'))[0] self.termPrint(response) self.conn.send(b'\x27\x63') self.termPrint('Request', b'\x27\x63') payload = self.conn.wait_frame(timeout=1) response = Response.from_payload(payload) seed = (response.data.hex()[2:]) sA = sec.securityAlgo(seed, 'series') sleep(.1) key = b'\x27\x64' + sA.calculatedKey response = str(response).split('<') response = (response[1].split('-'))[0] self.conn.send(key) payload = self.conn.wait_frame(timeout=1) response = Response.from_payload(payload) response = str(response).split('<') response = (response[1].split('-'))[0] self.termPrint(response) self.tpTime += 4 service = (self.begServicesList[self.begService.get()])[0] while self.commStatus and service == 'Write Data': if time() - self.tpTime >= 4: self.tpTime = time() with Client( self.conn, request_timeout=1, config={'exception_on_unexpected_response': False}) as client: # noqa: F841 msg = b'\x3E\x00' self.conn.send(msg) self.termPrint('Request', msg) '''payload = self.conn.wait_frame(timeout=1) response = Response.\ from_payload(payload) # noqa: F841, E501 self.termPrint('Response', response.data)''' service = (self.begServicesList[self.begService.get()])[0] self.begService.set(0) except Exception as e: messagebox.showinfo('Function unavailable', e) self.begService.set(0)
def get_DTC_byStatusMask(candevice='can0', txid=0x7E0, rxid=0x7E8, statusMask=0xae): dtcdict = {} isotp_params = { 'stmin': 32, # Will request the sender to wait 32ms between consecutive frame. 0-127ms or 100-900ns with values from 0xF1-0xF9 'blocksize': 8, # Request the sender to send 8 consecutives frames before sending a new flow control message 'wftmax': 0, # Number of wait frame allowed before triggering an error 'll_data_length': 8, # Link layer (CAN layer) works with 8 byte payload (CAN 2.0) 'tx_padding': 0x00, # Will pad all transmitted CAN messages with byte 0x00. None means no padding # VW-AG need Padding !! M.M. 'rx_flowcontrol_timeout': 1000, # Triggers a timeout if a flow control is awaited for more than 1000 milliseconds 'rx_consecutive_frame_timeout': 1000, # Triggers a timeout if a consecutive frame is awaited for more than 1000 milliseconds 'squash_stmin_requirement': True # When sending, respect the stmin requirement of the receiver. If set to True, go as fast as possible. } config = dict(udsoncan.configs.default_client_config) bus = can.interface.Bus(candevice, bustype='socketcan') tp_addr = isotp.Address(isotp.AddressingMode.Normal_11bits, txid=txid, rxid=rxid) stack = isotp.CanStack(bus=bus, address=tp_addr, params=isotp_params) conn = PythonIsoTpConnection(stack) try: with Client( conn, request_timeout=2, config=config) as client: # Application layer (UDS protocol) #DiagnosticSessionControl.Session.extendedDiagnosticSession ->überschneidung mit pyvituds client.change_session(3) response = client.get_dtc_by_status_mask(statusMask) print( response.service_data.dtc_count, response.service_data.dtcs ) # [<DTC ID=0x001ca4, Status=0x20, Severity=0x00 at 0xb3dceed0>] if response.service_data.dtc_count > 0: dtclist_str = [] for el in response.service_data.dtcs: dtclist_str.append("{}".format(el)) dtcdict["DTC"] = dtclist_str else: dtcdict["DTC"] = [""] return dtcdict except NegativeResponseException as e: print( "NegativeResponseException" ) # print('Server refused our request for service %s with code "%s" (0x%02x)' % (e.response.service.get_name(), e.response.code_name, e.response.code)) except (InvalidResponseException, UnexpectedResponseException) as e: print('Server sent an invalid payload : %s' % e.response.original_payload) except TimeoutException as e: print("Timeout")
def ecuReset(self, reset_type=0x01): # reset_type = 0x01(Hard Reset), 0x10(Reset to App), 0x20(Reset to BT) with Client(self.Phys_conn, request_timeout=2, config=config) as client: client.logger.info( '============================================================') client.logger.info( '========================= ECU Reset ========================') client.logger.info( '============================================================') try: client.ecu_reset(reset_type) except: exc = sys.exc_info()[1] self.set_statusText(color='red', text=str(exc)) else: if reset_type == 0x01: text = "Reset ECU - Hard Reset." elif reset_type == 0x10: text = "Reset ECU - Reset to Application." elif reset_type == 0x20: text = "Reset ECU - Reset to BootLoader." else: pass self.set_statusText(color='green', text=text)
def routineControl(self, rtid=0x0000, control_type=0x01, spr=False): # control_type = 1(start routine), 2(stop routine), 3(requestRoutineResult) with Client(self.Phys_conn, request_timeout=5, config=config) as client: client.logger.info( '============================================================') client.logger.info( '===================== Erase Application ====================') client.logger.info( '============================================================') try: if spr == True: with client.suppress_positive_response: client.routine_control(rtid, control_type) time.sleep(0.1) else: client.routine_control(rtid, control_type) except: exc = sys.exc_info()[1] self.set_statusText(color='red', text=str(exc)) else: if rtid == 0xFF00: self.set_statusText( color='green', text='Routine Control - Erase Application - Success.') else: self.set_statusText(color='green', text='Routine Control Send - Success.')
def readAppVersion(self): with Client(self.Phys_conn, request_timeout=1, config=config) as client: client.logger.info( '============================================================') client.logger.info( '================= Read Application Version =================') client.logger.info( '============================================================') try: response = client.read_data_by_identifier_first(0xF189) except: exc = sys.exc_info()[1] self.parent.lineEdit_AppVersion.setPalette( self.parent.palette_red) self.parent.lineEdit_AppVersion.setText(str(exc)) self.set_statusText( color='red', text= 'Read Application Version - Fail. Application may not exist.' ) else: self.parent.lineEdit_AppVersion.setPalette( self.parent.palette_blue) self.parent.lineEdit_AppVersion.setText(response) self.set_statusText(color='green', text='Read Application Version - Success.')
def runFlashData(self): self.Repro_numTotal = 0 self.Repro_num = 0 self.Repro_completeflag = False timeStart = time.time() for index in self.parent.srecs: if index.type == "S2": self.Repro_numTotal = self.Repro_numTotal + 1 self.parent.progressBarDN.setMaximum(self.Repro_numTotal) with Client(self.parent.uds.Phys_conn, request_timeout=1, config=config) as client: client.logger.info( '============================================================') client.logger.info( '====================== Start Reprogram =====================') client.logger.info( '============================================================') self.Repro_completeflag = True for index in self.parent.srecs: if index.type == "S2": data = index.addr.to_bytes(4, byteorder='big') + index.data try: sequenceNum = self.Repro_num % 100 client.transfer_data(sequenceNum, data) except: exc = sys.exc_info()[1] self.set_statusText(color='red', text=str(exc)) self.Repro_completeflag = False print('... Exception FlashData Thread ...') break else: self.Repro_num = self.Repro_num + 1 text = str(self.Repro_num) + "/" + str( self.Repro_numTotal) + " Data is sent." self.set_statusText(color='green', text=text) client.logger.info(text) if self.Repro_completeflag is True: text = "Flash is complete." + "(" + str( round((time.time() - timeStart), 3)) + " sec)" self.set_statusText(color='green', text=text) else: text = "Flash is not complete." + "(" + str( round((time.time() - timeStart), 3)) + " sec)" self.set_statusText(color='red', text=text) client.logger.info( '============================================================') client.logger.info( '======================= End Reprogram ======================') client.logger.info( '============================================================') print('... End FlashData Thread ...')
def diagSessionControl(self, Reqtype=0, session=0, spr=False): if Reqtype == 0: # Functional Request with Client(self.Func_conn, request_timeout=1, config=config) as client: try: if spr == True: with client.suppress_positive_response: client.change_session(session) time.sleep(0.1) else: client.change_session(session) except: exc = sys.exc_info()[1] self.set_statusText(color='red', text=str(exc)) else: self.set_statusText( color='green', text='Diagnostic session change - Success.') elif Reqtype == 1: # Physical Request with Client(self.Phys_conn, request_timeout=1, config=config) as client: try: if spr == True: with client.suppress_positive_response: client.change_session(session) time.sleep(0.1) else: client.change_session(session) except: exc = sys.exc_info()[1] self.set_statusText(color='red', text=str(exc)) else: self.set_statusText( color='green', text='Diagnostic session change - Success.') else: self.set_statusText(color='red', text='Diagnostic session change - Fail.')
def tester_Present(self, spr=False): with Client(self.Func_conn, request_timeout=1, config=config) as client: try: if spr == True: with client.suppress_positive_response: client.tester_present() time.sleep(0.1) else: client.tester_present() except: exc = sys.exc_info()[1] self.set_statusText(color='red', text=str(exc)) else: pass
def communicationControl(self, control_type=0): communication_type = udsoncan.CommunicationType( subnet=0, normal_msg=True, network_management_msg=False) with Client(self.Func_conn, request_timeout=1, config=config) as client: try: with client.suppress_positive_response: client.communication_control(control_type, communication_type) time.sleep(0.1) except: exc = sys.exc_info()[1] self.set_statusText(color='red', text=str(exc)) else: self.set_statusText(color='green', text='Communication Control - Success.')
def sendMsg(self): msg: str if self.sensor.get() == 'BEG': service = (self.begServicesList[self.begService.get()]) if service[0] == 'Read Data' and self.begDID.get() != '': msg = self.begRDBIList.get(self.begDID.get()) self.termPrint('Request', msg) elif service[0] == 'Write Data' and self.begDID.get() != '': did = self.begWDBIList.get(self.begDID.get()) if self.begDTW.get() != '': dtw = self.begDTWList.get(did) dtw = dtw.get(self.begDTW.get()) msg = did + dtw self.termPrint('Request', msg) elif self.begDataEntry.get != '': try: dtw = self.begDataEntry.get() msg = did + bytes.fromhex(dtw) self.termPrint('Request', msg) except Exception: messagebox.showinfo('Error', 'Incorrect data provided.') else: messagebox.showinfo('Error', 'Complete the request') else: messagebox.showinfo('Error', 'Complete the request') with Client(self.conn, request_timeout=1, config={'exception_on_unexpected_response': False}) as client: # noqa: F841 if self.sensor.get() == 'BEG': if self.begDID.get() != '': msg = self.begRDBIList.get(self.begDID.get()) try: self.conn.send(msg) self.termPrint('Request', msg) payload = self.conn.wait_frame(timeout=1) response = Response.\ from_payload(payload) # noqa: F841, E501 self.termPrint('Response', response.data) except Exception as e: print(e) else: messagebox.showinfo('Error', 'No service selected')
def read_dtcs( flash_info: constants.FlashInfo, interface="CAN", callback=None, interface_path=None, status_mask=None, ): if status_mask is None: # Try to filter to reasonable failures only. status_mask = Dtc.Status( test_failed=True, test_failed_this_operation_cycle=True, pending=False, confirmed=True, test_not_completed_since_last_clear=False, test_failed_since_last_clear=True, test_not_completed_this_operation_cycle=False, warning_indicator_requested=True, ) conn = connection_setup( interface=interface, rxid=flash_info.control_module_identifier.rxid, txid=flash_info.control_module_identifier.txid, interface_path=interface_path, ) with Client(conn, request_timeout=5, config=configs.default_client_config) as client: if callback: callback( flasher_step="READING", flasher_status="Connected", flasher_progress=50, ) client.change_session(services.DiagnosticSessionControl.Session. extendedDiagnosticSession) response = client.get_dtc_by_status_mask(status_mask.get_byte_as_int()) if callback: callback( flasher_step="DONE", flasher_status="Read " + str(len(response.service_data.dtcs)) + " DTCs", flasher_progress=100, ) return dtc_handler.dtcs_to_human(response.service_data.dtcs)
def flash_block( client: Client, filename: str, block: constants.PreparedBlockData, vin: str, flash_info: constants.FlashInfo, tuner_tag: str = "", callback=None, ): block_number = block.block_number data = block.block_encrypted_bytes block_identifier = flash_info.block_identifiers[block_number] logger.info(vin + ": Flashing block: " + str(block_number) + " from file " + filename) detailedLogger.info("Beginning block flashing process for block " + str(block_number) + " : " + block.block_name + " - with file named " + filename + " ...") if callback: callback( flasher_step="FLASHING", flasher_status="Erasing block " + str(block_number), flasher_progress=0, ) # Erase Flash if block.should_erase: detailedLogger.info("Erasing block " + str(block_number) + ", routine 0xFF00...") client.start_routine(Routine.EraseMemory, data=bytes([0x1, block_identifier])) if callback: callback( flasher_step="FLASHING", flasher_status="Requesting Download for block " + str(block_number), flasher_progress=0, ) detailedLogger.info("Requesting download for block " + str(block_number) + " of length " + str(flash_info.block_lengths[block_number]) + " with block identifier: " + str(block_identifier)) # Request Download dfi = udsoncan.DataFormatIdentifier(compression=block.compression_type, encryption=block.encryption_type) memloc = udsoncan.MemoryLocation( block_identifier, flash_info.block_lengths[block_number], address_format=8, memorysize_format=32, ) client.request_download(memloc, dfi=dfi) if callback: callback( flasher_step="FLASHING", flasher_status="Transferring data... " + str(len(data)), flasher_progress=0, ) detailedLogger.info("Transferring data... " + str(len(data)) + " bytes to write") # Transfer Data counter = 1 for block_base_address in range( 0, len(data), flash_info.block_transfer_sizes[block_number]): if callback: progress = (100 * counter * flash_info.block_transfer_sizes[block_number] / len(data)) callback( flasher_step="FLASHING", flasher_status="Transferring data... ", flasher_progress=str(progress), ) block_end = min( len(data), block_base_address + flash_info.block_transfer_sizes[block_number], ) client.transfer_data(counter, data[block_base_address:block_end]) counter = next_counter(counter) if callback: callback( flasher_step="FLASHING", flasher_status="Exiting transfer... ", flasher_progress=100, ) detailedLogger.info("Exiting transfer...") # Exit Transfer client.request_transfer_exit() if (len(tuner_tag) > 0) and (block_number > 1): detailedLogger.info("Sending tuner ASW magic number...") # Send Magic # In the case of a tuned CBOOT, send tune-specific magic bytes after this 3E to force-overwrite the CAL validity area. def tuner_payload(payload, tune_block_number=block_number): return payload + bytes(tuner_tag, "ascii") + bytes( [tune_block_number]) with client.payload_override(tuner_payload): client.tester_present() else: client.tester_present() if callback: callback( flasher_step="FLASHING", flasher_status="Checksumming block... ", flasher_progress=100, ) detailedLogger.info("Checksumming block " + str(block_number) + " , routine 0x0202...") # Checksum checksum_data = bytearray([0x01, block_identifier, 0, 0x4]) checksum_data.extend(block.uds_checksum) client.start_routine(0x0202, data=bytes(checksum_data)) if callback: callback( flasher_step="FLASHING", flasher_status="Success flashing block... ", flasher_progress=100, ) logger.info(vin + ": Success flashing block: " + str(block_number) + " with " + filename) detailedLogger.info("Successfully flashed " + filename + " to block " + str(block_number))
def flash_blocks( flash_info: constants.FlashInfo, block_files: dict[str, constants.PreparedBlockData], tuner_tag=None, callback=None, interface: str = "CAN", interface_path: str = None, workshop_code=bytes([ 0x20, # Year (BCD/HexDecimal since 2000) 0x4, # Month (BCD) 0x20, # Day (BCD) 0x42, # Workshop code 0x04, 0x20, 0x42, 0xB1, 0x3D, ]), ): class GenericStringCodec(udsoncan.DidCodec): def encode(self, val): return bytes(val) def decode(self, payload): return str(payload, "ascii") def __len__(self): raise udsoncan.DidCodec.ReadAllRemainingData class GenericBytesCodec(udsoncan.DidCodec): def encode(self, val): return bytes(val) def decode(self, payload): return payload.hex() def __len__(self): raise udsoncan.DidCodec.ReadAllRemainingData if callback: callback( flasher_step="SETUP", flasher_status="In Flasher util ", flasher_progress=100, ) else: detailedLogger.info( "No callback function specified, only local feedback provided") logger.info("Preparing to flash the following blocks:\n " + " \n".join([ " : ".join([ filename, str(block_files[filename].block_number), str(block_files[filename].boxcode), ]) for filename in block_files ])) def send_obd(data): conn2 = connection_setup(interface=interface, rxid=0x7E8, txid=0x700, interface_path=interface_path) conn2.open() conn2.send(data) conn2.wait_frame() conn2.wait_frame() conn2.close() if callback: callback(flasher_step="SETUP", flasher_status="Clearing DTCs ", flasher_progress=100) detailedLogger.info("Sending 0x4 Clear Emissions DTCs over OBD-2") send_obd(bytes([0x4])) conn = connection_setup( interface=interface, rxid=flash_info.control_module_identifier.rxid, txid=flash_info.control_module_identifier.txid, interface_path=interface_path, ) with Client(conn, request_timeout=5, config=configs.default_client_config) as client: try: def volkswagen_security_algo(level: int, seed: bytes, params=None) -> bytes: vs = Sa2SeedKey(flash_info.sa2_script, int.from_bytes(seed, "big")) return vs.execute().to_bytes(4, "big") client.config["security_algo"] = volkswagen_security_algo client.config["data_identifiers"] = {} for data_record in constants.data_records: if data_record.parse_type == 0: client.config["data_identifiers"][ data_record.address] = GenericStringCodec else: client.config["data_identifiers"][ data_record.address] = GenericBytesCodec client.config["data_identifiers"][0xF15A] = GenericBytesCodec if callback: callback( flasher_step="SETUP", flasher_status="Entering extended diagnostic session... ", flasher_progress=0, ) detailedLogger.info("Opening extended diagnostic session...") client.change_session(services.DiagnosticSessionControl.Session. extendedDiagnosticSession) vin_did = constants.data_records[0] vin: str = client.read_data_by_identifier_first(vin_did.address) if callback: callback( flasher_step="SETUP", flasher_status="Connected to vehicle with VIN: " + vin, flasher_progress=100, ) detailedLogger.info( "Extended diagnostic session connected to vehicle with VIN: " + vin) logger.info(vin + " Connected: Flashing blocks: " + str([ block_files[filename].block_number for filename in block_files ])) # Check Programming Precondition if callback: callback( flasher_step="SETUP", flasher_status="Checking programming precondition", flasher_progress=100, ) detailedLogger.info( "Checking programming precondition, routine 0x0203...") client.start_routine(0x0203) client.tester_present() # Upgrade to Programming Session if callback: callback( flasher_step="SETUP", flasher_status="Upgrading to programming session...", flasher_progress=100, ) detailedLogger.info("Upgrading to programming session...") client.change_session( services.DiagnosticSessionControl.Session.programmingSession) # Fix timeouts to work around overly smart library client.session_timing["p2_server_max"] = 30 client.config["request_timeout"] = 30 client.tester_present() if callback: callback( flasher_step="SETUP", flasher_status="Performing Seed/Key authentication...", flasher_progress=100, ) # Perform Seed/Key Security Level 17. This will call volkswagen_security_algo above to perform the Seed/Key auth against the SA2 script. detailedLogger.info("Performing Seed/Key authentication...") client.unlock_security_access(17) client.tester_present() if callback: callback( flasher_step="SETUP", flasher_status="Writing Workshop data...", flasher_progress=100, ) detailedLogger.info( "Writing flash tool log to LocalIdentifier 0xF15A...") # Write Flash Tool Workshop Log client.write_data_by_identifier(0xF15A, workshop_code) client.tester_present() for filename in block_files: block = block_files[filename] blocknum = block.block_number if blocknum <= 5: flash_block( client=client, filename=filename, block=block, vin=vin, callback=callback, flash_info=flash_info, ) if blocknum > 5: patch_block( client=client, filename=filename, block=block, vin=vin, callback=callback, flash_info=flash_info, ) if callback: callback( flasher_step="SETUP", flasher_status="Verifying reprogramming dependencies...", flasher_progress=100, ) detailedLogger.info( "Verifying programming dependencies, routine 0xFF01...") # Verify Programming Dependencies client.start_routine(Routine.CheckProgrammingDependencies) client.tester_present() # If a periodic task was patched or altered as part of the process, let's give it a few seconds to run time.sleep(5) if callback: callback( flasher_step="SETUP", flasher_status="Finalizing...", flasher_progress=100, ) detailedLogger.info("Rebooting ECU...") # Reboot client.ecu_reset(services.ECUReset.ResetType.hardReset) conn.close() detailedLogger.info("Sending 0x4 Clear Emissions DTCs over OBD-2") send_obd(bytes([0x4])) if callback: callback( flasher_step="SETUP", flasher_status="DONE!...", flasher_progress=100, ) detailedLogger.info("Done!") except exceptions.NegativeResponseException as e: logger.error( 'Server refused our request for service %s with code "%s" (0x%02x)' % (e.response.service.get_name(), e.response.code_name, e.response.code)) except exceptions.InvalidResponseException as e: logger.error("Server sent an invalid payload : %s" % e.response.original_payload) except exceptions.UnexpectedResponseException as e: logger.error("Server sent an invalid payload : %s" % e.response.original_payload) except exceptions.TimeoutException as e: logger.error("Service request timed out! : %s" % repr(e))
def patch_block( client: Client, filename: str, block: constants.PreparedBlockData, vin: str, flash_info: constants.FlashInfo, callback=None, ): block_number = block.block_number block_number = block_number - 5 data = block.block_encrypted_bytes detailedLogger.info( "Erasing next block for PATCH process - erasing block " + str(block_number + 1) + " to patch " + str(block_number) + " routine 0xFF00...") # Erase Flash # Hardcoded to erase block 5 (CAL) prior to patch. This means we must ALWAYS flash CAL after patching. client.start_routine(Routine.EraseMemory, data=bytes([0x1, 5])) logger.info(vin + ": PATCHING block: " + str(block_number) + " with " + filename) detailedLogger.info("Requesting download to PATCH block " + str(block_number) + " of length " + str(flash_info.block_lengths[block_number]) + " using file " + filename + " ...") # Request Download dfi = udsoncan.DataFormatIdentifier(compression=0x0, encryption=0xA) memloc = udsoncan.MemoryLocation(block_number, flash_info.block_lengths[block_number], memorysize_format=32) client.request_download(memloc, dfi=dfi) detailedLogger.info("Transferring PATCH data... " + str(len(data)) + " bytes to write") # Transfer Data counter = 1 transfer_address = 0 while transfer_address < len(data): transfer_size = flash_info.patch_info.block_transfer_sizes_patch( block_number, transfer_address) block_end = min(len(data), transfer_address + transfer_size) transfer_data = data[transfer_address:block_end] if callback: progress = transfer_address * 100 / len(data) callback( flasher_step="PATCHING", flasher_status="Patching data... ", flasher_progress=str(progress), ) success = False while not success: try: time.sleep(0.025) client.transfer_data(counter, transfer_data) success = True counter = next_counter(counter) except exceptions.NegativeResponseException: success = False counter = next_counter(counter) transfer_address += transfer_size detailedLogger.info("Exiting PATCH transfer...") # Exit Transfer client.request_transfer_exit() detailedLogger.info("PATCH successful.") logger.info(vin + ": PATCHED block: " + str(block_number) + " with " + filename)
from can.interfaces.vector import VectorBus from udsoncan.connections import PythonIsoTpConnection from udsoncan.client import Client import isotp # Refer to isotp documentation for full details about parameters isotp_params = { 'stmin' : 32, # Will request the sender to wait 32ms between consecutive frame. 0-127ms or 100-900ns with values from 0xF1-0xF9 'blocksize' : 8, # Request the sender to send 8 consecutives frames before sending a new flow control message 'wftmax' : 0, # Number of wait frame allowed before triggering an error 'll_data_length' : 8, # Link layer (CAN layer) works with 8 byte payload (CAN 2.0) 'tx_padding' : 0, # Will pad all transmitted CAN messages with byte 0x00. None means no padding 'rx_flowcontrol_timeout' : 1000, # Triggers a timeout if a flow control is awaited for more than 1000 milliseconds 'rx_consecutive_frame_timeout' : 1000, # Triggers a timeout if a consecutive frame is awaited for more than 1000 milliseconds 'squash_stmin_requirement' : False # When sending, respect the stmin requirement of the receiver. If set to True, go as fast as possible. } bus = VectorBus(channel=0, bitrate=9600) # Link Layer (CAN protocol) tp_addr = isotp.Address(isotp.AddressingMode.Normal_11bits, txid=0x123, rxid=0x79D) # Network layer addressing scheme stack = isotp.CanStack(bus=bus, address=tp_addr, params=isotp_params) # Network/Transport layer (IsoTP protocol) conn = PythonIsoTpConnection(stack) # interface between Application and Transport layer with Client(conn, request_timeout=1) as client: # Application layer (UDS protocol) client.change_session(1) # ...
import can import isotp import udsoncan from udsoncan.connections import PythonIsoTpConnection from udsoncan.client import Client from udsoncan.exceptions import * from udsoncan.services import * udsoncan.setup_logging() bus = can.interface.Bus(bustype="cantact", channel="0", bitrate=500000) addr = isotp.Address(addressing_mode=isotp.AddressingMode.Normal_11bits, txid=0x123, rxid=0x456) tp = isotp.CanStack(bus, address=addr) conn = PythonIsoTpConnection(tp) client = Client(conn) conn.open() client.ecu_reset(ECUReset.ResetType.hardReset) print("done") conn.close()
import random, datetime #udsoncan.setup_logging() aqua_patch.PatchMessageFormat() if __name__ == '__main__': isotp_socket = isotp.socket() isotp_socket.set_opts(txpad=CarConfig.TXPADSIZE, rxpad=CarConfig.RXPADSIZE) conn = IsoTPSocketConnection('can0', rxid=CarConfig.RXID, txid=CarConfig.TXID, tpsock=isotp_socket) with Client(conn, request_timeout=2, config=CarConfig.car_client_config) as client: try: client.change_session( DiagnosticSessionControl.Session.defaultSession) client.unlock_security_access(CarConfig.SECURITY_LEVEL) client.change_session( DiagnosticSessionControl.Session.programmingSession) except NegativeResponseException as e: print( 'Server refused our request for service %s with code "%s" (0x%02x)' % (e.response.service.get_name(), e.response.code_name, e.response.code)) except UnexpectedResponseException as e: print('Server sent an invalid payload : %s' % e.response.original_payload)
def start_logger(self): # If testing is true, we'll run the main thread now without defining the # uds client if self.TESTING: self.activityLogger.debug("Starting main thread in testing mode") self.main() else: with Client(self.conn, request_timeout=2, config=configs.default_client_config) as client: try: # Set up the security algorithm for the uds connection client.config["security_algo"] = self.gainSecurityAccess self.main(client=client) except exceptions.NegativeResponseException as e: self.activityLogger.critical( 'Server refused our request for service %s with code "%s" (0x%02x)' % ( e.response.service.get_name(), e.response.code_name, e.response.code, )) if (self.configuration is not None and "notification" in self.configuration): with open(self.logfile) as activityLog: msg = activityLog.read() self.notificationEmail( self.configuration["notification"], msg) except exceptions.InvalidResponseException as e: self.activityLogger.critical( "Server sent an invalid payload : %s" % e.response.original_payload) if (self.configuration is not None and "notification" in self.configuration): with open(self.logfile) as activityLog: msg = activityLog.read() self.notificationEmail( self.configuration["notification"], msg) except exceptions.UnexpectedResponseException as e: self.activityLogger.critical( "Server sent an invalid payload : %s" % e.response.original_payload) if (self.configuration is not None and "notification" in self.configuration): with open(self.logfile) as activityLog: msg = activityLog.read() self.notificationEmail( self.configuration["notification"], msg) except exceptions.TimeoutException as e: self.activityLogger.critical( "Timeout waiting for response on can: " + str(e)) if (self.configuration is not None and "notification" in self.configuration): with open(self.logfile) as activityLog: msg = activityLog.read() self.notificationEmail( self.configuration["notification"], msg) except Exception as e: self.activityLogger.critical("Unhandled exception: " + str(e)) if (self.configuration is not None and "notification" in self.configuration): with open(self.logfile) as activityLog: msg = activityLog.read() self.notificationEmail( self.configuration["notification"], msg) raise
def read_ecu_data(flash_info: constants.FlashInfo, interface="CAN", callback=None, interface_path=None): class GenericStringCodec(udsoncan.DidCodec): def encode(self, val): return bytes(val) def decode(self, payload): return str(payload, "ascii") def __len__(self): raise udsoncan.DidCodec.ReadAllRemainingData class GenericBytesCodec(udsoncan.DidCodec): def encode(self, val): return bytes(val) def decode(self, payload): return payload.hex() def __len__(self): raise udsoncan.DidCodec.ReadAllRemainingData conn = connection_setup( interface=interface, rxid=flash_info.control_module_identifier.rxid, txid=flash_info.control_module_identifier.txid, interface_path=interface_path, ) with Client(conn, request_timeout=5, config=configs.default_client_config) as client: try: ecuInfo = {} client.config["data_identifiers"] = {} for data_record in constants.data_records: if data_record.parse_type == 0: client.config["data_identifiers"][ data_record.address] = GenericStringCodec elif data_record.parse_type == 2: client.config["data_identifiers"][ data_record.address] = WorkshopCodeCodec else: client.config["data_identifiers"][ data_record.address] = GenericBytesCodec client.config["data_identifiers"][0xF15A] = GenericBytesCodec if callback: callback( flasher_step="READING", flasher_status="Entering extended diagnostic session... ", flasher_progress=0, ) detailedLogger.info("Opening extended diagnostic session...") client.change_session(services.DiagnosticSessionControl.Session. extendedDiagnosticSession) vin_did = constants.data_records[0] vin: str = client.read_data_by_identifier_first(vin_did.address) if callback: callback( flasher_step="READING", flasher_status="Connected to vehicle with VIN: " + vin, flasher_progress=100, ) detailedLogger.info( "Extended diagnostic session connected to vehicle with VIN: " + vin) detailedLogger.info("Reading ECU information...") for i in range(33, 48): did = constants.data_records[i] response = client.read_data_by_identifier_first(did.address) detailedLogger.info(did.description + " : " + response) logger.info(vin + " " + did.description + " : " + response) ecuInfo[did.description] = response if callback: callback( flasher_step="READING", flasher_status="GET INFO COMPLETE...", flasher_progress=100, ) return ecuInfo except exceptions.NegativeResponseException as e: logger.error( 'Server refused our request for service %s with code "%s" (0x%02x)' % (e.response.service.get_name(), e.response.code_name, e.response.code)) return ecuInfo except exceptions.InvalidResponseException as e: logger.error("Server sent an invalid payload : %s" % e.response.original_payload) except exceptions.UnexpectedResponseException as e: logger.error("Server sent an invalid payload : %s" % e.response.original_payload) except exceptions.TimeoutException as e: logger.error("Service request timed out! : %s" % repr(e))
import udsoncan from udsoncan.connections import IsoTPSocketConnection from udsoncan.client import Client from udsoncan.exceptions import * from udsoncan.services import * udsoncan.setup_logging() conn = IsoTPSocketConnection('can0', rxid=0x79D, txid=0x79D) with Client(conn, request_timeout=2) as client: try: client.change_session( DiagnosticSessionControl.Session.extendedDiagnosticSession ) # integer with value of 3 # client.unlock_security_access(MyCar.debug_level) # Fictive security level. Integer coming from fictive lib, let's say its value is 5 client.write_data_by_identifier( udsoncan.DataIdentifier.VIN, 'ABC123456789' ) # Standard ID for VIN is 0xF190. Codec is set in the client configuration print('Vehicle Identification Number successfully changed.') client.ecu_reset(ECUReset.ResetType.hardReset) # HardReset = 0x01 except NegativeResponseException as e: print( 'Server refused our request for service %s with code "%s" (0x%02x)' % (e.response.service.get_name(), e.response.code_name, e.response.code)) # except InvalidResponseException , UnexpectedResponseException as e: except InvalidResponseException as e: print('Server sent an invalid payload : %s' % e.response.original_payload) except UnexpectedResponseException as e: print('Server sent an invalid payload : %s' %
from can.interface import Bus from udsoncan.connections import PythonIsoTpConnection from udsoncan.client import Client import isotp from udsoncan import Response import securityAlgo as sec from time import sleep tp_addr = isotp.Address(isotp.AddressingMode.Normal_29bits, txid=0x18DA2AF1, rxid=0x18DAFA2A) bus = Bus(bustype='pcan', channel='PCAN_USBBUS1', bitrate=500000) stack = isotp.CanStack(bus=bus, address=tp_addr) conn = PythonIsoTpConnection(stack) with Client(conn, request_timeout=1, config={'exception_on_unexpected_response': False}) as client: try: conn.send(b'\x10\x03') payload = conn.wait_frame(timeout=1) response = Response.from_payload(payload) print(response) conn.send(b'\x27\x63') payload = conn.wait_frame(timeout=1) response = Response.from_payload(payload) print('key: ' + response.data.hex()[2:]) seed = (response.data.hex()[2:]) sA = sec.securityAlgo(seed, 'series') sleep(.1) print('calculated key: ' + (sA.calculatedKey).hex()) conn.send(b'\x27\x64' + sA.calculatedKey)
txid=0x700, params=params) conn2.tpsock.set_opts(txpad=0x55, tx_stmin=2500000) conn2.open() conn2.send(data) conn2.wait_frame() conn2.wait_frame() conn2.close() print("Sending 0x4 Clear Emissions DTCs over OBD-2") send_obd(bytes([0x4])) conn = IsoTPSocketConnection('can0', rxid=0x7E8, txid=0x7E0, params=params) conn.tpsock.set_opts(txpad=0x55, tx_stmin=2500000) with Client(conn, request_timeout=5, config=configs.default_client_config) as client: try: client.config['security_algo'] = volkswagen_security_algo client.config['data_identifiers'] = {} for data_record in data_records: if (data_record.parse_type == 0): client.config['data_identifiers'][ data_record.address] = GenericStringCodec else: client.config['data_identifiers'][ data_record.address] = GenericBytesCodec client.config['data_identifiers'][0xF15A] = GenericBytesCodec print("Opening extended diagnostic session...")
class ClientServerTest(ThreadableTest): def __init__(self, *args, **kwargs): ThreadableTest.__init__(self, *args, **kwargs) def setUp(self): self.conn = QueueConnection(name='unittest', mtu=4095) def clientSetUp(self): self.udsclient = Client(self.conn, request_timeout=0.2) self.udsclient.set_config('logger_name', 'unittest') self.udsclient.set_config('exception_on_invalid_response', True) self.udsclient.set_config('exception_on_unexpected_response', True) self.udsclient.set_config('exception_on_negative_response', True) self.udsclient.open() if hasattr(self, "postClientSetUp"): self.postClientSetUp() def clientTearDown(self): self.udsclient.close() def wait_request_and_respond(self, bytes): self.conn.touserqueue.get(timeout=0.2) self.conn.fromuserqueue.put(bytes)
import SomeLib.SomeCar.SomeModel as MyCar import udsoncan from udsoncan.connections import IsoTPSocketConnection from udsoncan.client import Client from udsoncan.exceptions import * from udsoncan.services import * udsoncan.setup_logging() conn = IsoTPSocketConnection('can0', rxid=0x123, txid=0x456) with Client(conn, request_timeout=2, config=MyCar.config) as client: try: client.change_session( DiagnosticSessionControl.Session.extendedDiagnosticSession ) # integer with value of 3 client.unlock_security_access( MyCar.debug_level ) # Fictive security level. Integer coming from fictive lib, let's say its value is 5 client.write_data_by_identifier( udsoncan.DataIdentifier.VIN, 'ABC123456789' ) # Standard ID for VIN is 0xF190. Codec is set in the client configuration print('Vehicle Identification Number successfully changed.') client.ecu_reset(ECUReset.ResetType.hardReset) # HardReset = 0x01 except NegativeResponseException as e: print( 'Server refused our request for service %s with code "%s" (0x%02x)' % (e.response.service.get_name(), e.response.code_name, e.response.code)) # except InvalidResponseException , UnexpectedResponseException as e: except InvalidResponseException as e: