def test_udsSendFunctionalRequest(self, testTp_send): testTp_send.return_value = False udsConnection = Uds(transportProtocol="TEST") a = udsConnection.send([0x10, 0x01], functionalReq=True) self.assertEqual(None, None)
def test_udsSendWithResponse(self, tp_recv, tp_send): tp_send.return_value = False tp_recv.return_value = [0x50, 0x01] udsConnection = Uds() a = udsConnection.send([0x10, 0x01]) self.assertEqual([0x50, 0x01], a)
def test_udsSendWithoutResponse(self, testTp_send): testTp_send.return_value = False udsConnection = Uds(transportProtocol="TEST") a = udsConnection.send([0x10, 0x01], responseRequired=False) self.assertEqual(None, None)
def test_udsSendWithResponse(self, testTp_send, testTp_recv): testTp_send.return_value = False testTp_recv.return_value = [0x50, 0x01] udsConnection = Uds(transportProtocol="TEST") a = udsConnection.send([0x10, 0x01]) self.assertEqual([0x50, 0x01], a)
bus1.send(outMsg) lastTime = startTime if __name__ == "__main__": bus1 = can.interface.Bus('virtualInterface', bustype="virtual") listener = can.Listener() notifier = can.Notifier(bus1, [listener], 0) uds = Uds(reqId=0x600, resId=0x650, interface="virtual") testEcu = createUdsConnection('Bootloader.odx', 'bootloader', interface="virtual") print("Test 1") listener.on_message_received = callback_onReceive_singleFrame resp = uds.send([0x22, 0xF1, 0x8C]) print(resp) time.sleep(1) print("Test 2") listener.on_message_received = callback_onReceive_multiFrameResponse_noBs a = testEcu.readDataByIdentifier('ECU Serial Number') print(a) time.sleep(1) # print("Test 3") # listener.on_message_received = callback_onReceive_multiFrameSend # payloadRequest = [] # for i in range(0, 200):
from uds import Uds from can import Bus, Listener, Notifier from time import sleep def callback_onReceive(msg): if (msg.arbitration_id == 0x600): print("Bootloader Receive:", list(msg.data)) if (msg.arbitration_id == 0x7E0): print("PCM Receive:", list(msg.data)) if __name__ == "__main__": recvBus = Bus("virtualInterface", bustype="virtual") listener = Listener() notifier = Notifier(recvBus, [listener], 0) listener.on_message_received = callback_onReceive a = Uds() a.send([0x22, 0xf1, 0x8C], responseRequired=False) sleep(2)
if __name__ == "__main__": bus = can.interface.Bus('virtualInterface', bustype='virtual') bus2 = can.interface.Bus('anotherBus', bustype='virtual') listener = Listener() listener.on_message_received = onCallback_receive notifier = Notifier(bus, [listener], 0) listener2 = Listener() listener2.on_message_received = onCallback_receive2 notifier2 = Notifier(bus2, [listener2], 0) a = Uds() a.send([0x22, 0xF1, 0x8C], responseRequired=False) b = Uds("bootloader.ini") b.send([0x22, 0xF1, 0x80], responseRequired=False) c = Uds("bootloader2.ini") c.send([0x22, 0xF1, 0x81], responseRequired=False) try: d = Uds("subaruEcm.ini") except: print("Subaru ECM test passed, using doip, exception caught") e = Uds(reqId=0x620, resId=0x670) e.send([0x22, 0xf1, 0x83], responseRequired=False)
class Main(object): """docstring for main""" def __init__(self): super(Main, self).__init__() # This creates a Uds object manually self.rawUDS = Uds() self.rawCAN = can.interface.Bus(bustype='vector', app_name='canoe', channel=0, bitrate=500000) self.periodMsgTasks = {} self.msgs = {} self.resData = [] self.sa_seed = [] self.sa_key = [0x0, 0x0, 0x0, 0x0] self.varsDict = {} self.cmdsDict = {} self.dataLogList = [] self.errorLogList = [] def creat_msg(self, msgId: int, msgDataDlc: int = 8, msgData: list = [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]): '''''' try: self.msgs[msgId] = can.Message(arbitration_id=msgId, dlc=msgDataDlc, data=msgData) print("Message 0x{0:X} creat ok ".format(msgId)) except Exception as ex: print(ex) print("Message 0x{0:X} creat fail ".format(msgId)) def send_msg(self, msg: can.Message): '''''' try: self.rawCAN.send(msg) print(f"Message sent on {self.rawCAN.channel_info}") except can.CanError: print("Message NOT sent") def create_periodic_msg_task(self, msgId: int, period: float): '''''' try: self.periodMsgTasks[msgId] = self.rawCAN.send_periodic( self.msgs[msgId], period) print("Task 0x{0:X} creat ok ".format(msgId)) except Exception as ex: print(ex) print("Task 0x{0:X} creat fail ".format(msgId)) def periodic_msg_task_start(self, msgId): '''''' main.periodMsgTasks[msgId].start() def periodic_msg_task_stop(self, msgId): '''''' main.periodMsgTasks[msgId].stop() def modify_msg(self, msgId: int, data: list, **kwargs): '''''' self.msgs[msgId].data = data def periodic_msg_task_modify_msg(self, msgId: int): '''''' self.periodMsgTasks[msgId].modify_data(self.msgs[msgId]) def diag_send(self, reqData: list, resDataPattern: str, logSuccessed: str = "", logFailed: str = "", responseRequired=True, funcReq=False) -> bool: '''''' ret = False print(["{0:02X}".format(ele) for ele in reqData]) # print(resDataPattern) try: self.resData = [] self.resData = self.rawUDS.send(reqData, functionalReq=funcReq) print(["{0:02X}".format(ele) for ele in self.resData]) resDataStr = ' '.join( ['{0:02X}'.format(ele) for ele in self.resData]) # print(resDataStr) if re.match(resDataPattern, resDataStr): ret = True if logSuccessed: print(re.findall(r"^.*Log\((.*?)\).*$", logSuccessed)[0]) if self.resData[0] == 0x67 and re.match( ".*-Seed.*", logSuccessed): self.sa_seed = self.resData[2:] self.calckey(len(self.sa_seed)) # print(self.sa_seed) else: ret = False if logFailed: print(re.findall(r"^.*Log\((.*?)\).*$", logFailed)[0]) except Exception as ex: if str(ex) == "Timeout in waiting for message": if resDataPattern == "^$": ret = True if logSuccessed: print( re.findall(r"^.*Log\((.*?)\).*$", logSuccessed)[0]) else: ret = False if logFailed: print(re.findall(r"^.*Log\((.*?)\).*$", logFailed)[0]) else: ret = False print(ex) print("Diagnostic send fail") return ret def calckey(self, sa_len): '''''' securitydll = cdll.LoadLibrary("config/SecurityDll/sdll.dll") seed = (ctypes.c_ubyte * sa_len)() key = (ctypes.c_ubyte * sa_len)() for i in range(sa_len): seed[i] = self.sa_seed[i] securitydll.CalcKeys(seed, key, sa_len) self.sa_key = [ele for ele in key] def precompile(self, dataDict): '''''' keymin = min(sorted(dataDict.keys())) keymax = max(sorted(dataDict.keys())) for key in range(keymin, keymax + 1): dataDict[key] = re.split(r"([#]+|[/]{2,})", dataDict[key].strip(' '))[0].strip(' ') if re.match(r"^\t* *\t* *$", dataDict[key].strip(' ')): dataDict[key] = "" # print(dataDict[key]) key = keymin while True: if re.match(r"^:<<EOF$", dataDict[key].strip(' ')): dataDict[key] = "" key += 1 while True: if re.match(r"^EOF$", dataDict[key].strip(' ')): dataDict[key] = "" break dataDict[key] = "" key += 1 if key > keymax: raise Exception(":<<EOF...EOF error") key += 1 if key > keymax: break print(dataDict) def preprocessing(self, dataDict): '''''' if not dataDict: return keymin = min(sorted(dataDict.keys())) keymax = max(sorted(dataDict.keys())) key = keymin while True: if re.match(r"^while +.*$", dataDict[key].strip(' ')): commands = re.findall(r"^while +(.+?)$", dataDict[key].strip(' '))[0] if re.match(r"^\[ ((\$[A-Za-z]+)|([0-9]+)) -(eq|ne|gt|ge|lt|le) ((\$[A-Za-z]+)|([0-9]+)) \]$", commands)\ or re.match(r"^\({2} ?((\$[A-Za-z]+)|([0-9]+)) ((==)|(!=)|(>)|(>=)|(<)|(<=)) ((\$[A-Za-z]+)|([0-9]+)) ?\){2}$", commands): self.cmdsDict[key] = commands else: raise Exception( "line {0} commands syntax errors".format(key + 1)) whilekey = key key += 1 if re.match(r"^do$", dataDict[key].strip(' ')): self.cmdsDict[key] = "" else: raise Exception("while do ... done do error") key += 1 subDataDict = {} while True: if re.match(r"^\t.*$", dataDict[key].strip(' ')): subDataDict[key] = dataDict[key][1:] elif re.match(r"^\t* *\t* *$", dataDict[key].strip(' ')): subDataDict[key] = "" else: break key += 1 self.preprocessing(subDataDict) if re.match(r"^done$", dataDict[key].strip(' ')): self.cmdsDict[key] = " goto " + str(whilekey) self.cmdsDict[whilekey] += " ? : goto " + str(key + 1) else: raise Exception("while do ... done done error") elif re.match(r"^if +.*; *then$", dataDict[key].strip(' ')): commands = re.findall(r"^if *(.+?); *then$", dataDict[key].strip(' '))[0] if re.match(r"^\[ ((\$[A-Za-z]+)|([0-9]+)) -(eq|ne|gt|ge|lt|le) ((\$[A-Za-z]+)|([0-9]+)) \]$", commands)\ or re.match(r"^\({2} ?((\$[A-Za-z]+)|([0-9]+)) ((==)|(!=)|(>)|(>=)|(<)|(<=)) ((\$[A-Za-z]+)|([0-9]+)) ?\){2}$", commands): self.cmdsDict[key] = commands else: raise Exception( "line {0} commands syntax errors".format(key + 1)) # print(self.cmdsDict[key]) ifkey = key gotofikey = [] key += 1 subDataDict = {} while True: if re.match(r"^\t.*$", dataDict[key].strip(' ')): subDataDict[key] = dataDict[key][1:] elif re.match(r"^\t* *\t* *$", dataDict[key].strip(' ')): subDataDict[key] = "" else: gotofikey.append(key - 1) break key += 1 self.preprocessing(subDataDict) while True: if re.match(r"^elif +.*; *then$", dataDict[key].strip(' ')): self.cmdsDict[ifkey] += " ? : goto " + str(key) ifkey = key commands = re.findall(r"^elif +(.+?); *then$", dataDict[key].strip(' '))[0] if re.match(r"^\[ ((\$[A-Za-z]+)|([0-9]+)) -(eq|ne|gt|ge|lt|le) ((\$[A-Za-z]+)|([0-9]+)) \]$", commands)\ or re.match(r"^\({2} ?((\$[A-Za-z]+)|([0-9]+)) ((==)|(!=)|(>)|(>=)|(<)|(<=)) ((\$[A-Za-z]+)|([0-9]+)) ?\){2}$", commands): self.cmdsDict[key] = commands else: raise Exception( "line {0} commands syntax errors".format(key + 1)) key += 1 subDataDict = {} while True: if re.match(r"^\t.*$", dataDict[key].strip(' ')): subDataDict[key] = dataDict[key][1:] elif re.match(r"^\t* *\t* *$", dataDict[key].strip(' ')): subDataDict[key] = "" else: gotofikey.append(key - 1) break key += 1 self.preprocessing(subDataDict) elif re.match(r"^else$", dataDict[key].strip(' ')): self.cmdsDict[ifkey] += " ? : goto " + str(key) ifkey = -1 self.cmdsDict[key] = "" key += 1 subDataDict = {} while True: if re.match(r"^\t.*$", dataDict[key].strip(' ')): subDataDict[key] = dataDict[key][1:] elif re.match(r"^\t* *\t* *$", dataDict[key].strip(' ')): subDataDict[key] = "" else: break key += 1 self.preprocessing(subDataDict) elif re.match(r"^fi$", dataDict[key].strip(' ')): if ifkey != -1: self.cmdsDict[ifkey] += " ? : goto " + str(key) self.cmdsDict[key] = "" for subkey in gotofikey: self.cmdsDict[subkey] += " ; goto " + str(key) break else: raise Exception("if...elif...else...fi error") else: self.cmdsDict[key] = dataDict[key].strip(' ') key += 1 if key > keymax: break def __parse_conditions_judgment_square_brackets(self, cmd) -> tuple: '''[[commands]]''' ret = False extractionData = re.findall( r"^\[ (.*?) (.*?) (.*?) \] \? : goto (.*?)$", cmd) lValue = int(extractionData[0][0] if not re.match(r"^\$[A-Za-z]+$", extractionData[0][0]) else self.varsDict[extractionData[0][0][1:]]) comparisonOperator = extractionData[0][1] rValue = int(extractionData[0][2] if not re.match(r"^\$[A-Za-z]+$", extractionData[0][2]) else self.varsDict[extractionData[0][2][1:]]) PCJump = int(extractionData[0][3]) if (comparisonOperator == "-eq" and lValue == rValue)\ or (comparisonOperator == "-ne" and lValue != rValue)\ or (comparisonOperator == "-gt" and lValue > rValue)\ or (comparisonOperator == "-ge" and lValue >= rValue)\ or (comparisonOperator == "-lt" and lValue < rValue)\ or (comparisonOperator == "-le" and lValue <= rValue): ret = True else: pass return (ret, PCJump) def __parse_conditions_judgment_parenthesis(self, cmd) -> tuple: '''((commands))''' ret = False extractionData = re.findall( r"^\({2} ?(.*?) (.*?) (.*?) ?\){2} \? : goto (.*?)$", cmd) lValue = int(extractionData[0][0] if not re.match(r"^\$[A-Za-z]+$", extractionData[0][0]) else self.varsDict[extractionData[0][0][1:]]) comparisonOperator = extractionData[0][1] rValue = int(extractionData[0][2] if not re.match(r"^\$[A-Za-z]+$", extractionData[0][2]) else self.varsDict[extractionData[0][2][1:]]) PCJump = int(extractionData[0][3]) if (comparisonOperator == "==" and lValue == rValue)\ or (comparisonOperator == "!=" and lValue != rValue)\ or (comparisonOperator == ">" and lValue > rValue)\ or (comparisonOperator == ">=" and lValue >= rValue)\ or (comparisonOperator == "<" and lValue < rValue)\ or (comparisonOperator == "<=" and lValue <= rValue): ret = True else: pass return (ret, PCJump) def __parse_diag_msg(self, cmd): '''''' if re.match(r".*Key[(]\d+[)].*", cmd): cmd = re.sub( r"Key[(]\d+[)]", ' '.join(["{0:02X}".format(ele) for ele in self.sa_key]), cmd) validData = [ele.strip(' ') for ele in re.split("[?|:]", cmd)] validData[0] = re.split("==", validData[0]) # print(type(validData)) # print(len(validData)) # print(validData) # print(re.split(' +', validData[0][0])) # print(validData[0][1]) # print(re.split(' +', validData[0][1])) reqData = [ int( ele if not re.match("^\$[A-Za-z]+", ele) else str( self.varsDict[ele[1:]]), 16) for ele in re.split(' +', validData[0][0]) ] if not re.match('^FUN', validData[0][0]) else [ int( ele if not re.match("^\$[A-Za-z]+", ele) else str( self.varsDict[ele[1:]]), 16) for ele in re.split(' +', validData[0][0])[1:] ] # print(reqData) resDataPattern = '^' + validData[0][1] + '$' logSuccessed = validData[1] logFailed = validData[2] funcReq = False if not re.match('^FUN', validData[0][0]) else True if self.diag_send(reqData, resDataPattern, logSuccessed, logFailed, funcReq=funcReq): self.dataLogList.append(logSuccessed) else: self.dataLogList.append(logFailed) self.errorLogList.append(logFailed) def cmd_parse(self): '''''' PC = 0 print(self.cmdsDict) while True: jump = False for cmd in [ sub.strip(' ') for sub in self.cmdsDict[PC].split(';') ]: if re.match(r"^[A-Za-z]+=[0-9]+$", cmd): self.varsDict[re.split("=", cmd)[0]] = int( re.split("=", cmd)[1]) elif re.match(r"^[A-Za-z]+\+{2}$", cmd): self.varsDict[(re.findall(r"^(.*?)\+{2}$", cmd)[0])] += 1 elif re.match(r"^[A-Za-z]+\-{2}$", cmd): self.varsDict[(re.findall(r"^(.*?)\-{2}$", cmd)[0])] -= 1 elif re.match(r"^[A-Za-z]+\+=[0-9]+$", cmd): self.varsDict[re.split("=", cmd)[0]] += int( re.split("=", cmd)[1]) elif re.match(r"^[A-Za-z]+\-=[0-9]+$", cmd): self.varsDict[re.split("=", cmd)[0]] -= int( re.split("=", cmd)[1]) elif re.match( r"^\[ ((\$[A-Za-z]+)|([0-9]+)) -(eq|ne|gt|ge|lt|le) ((\$[A-Za-z]+)|([0-9]+)) \] \? : goto [0-9]+$", cmd): ret = self.__parse_conditions_judgment_square_brackets(cmd) if not ret[0]: PC = ret[1] jump = True break elif re.match( r"^\({2} ?((\$[A-Za-z]+)|([0-9]+)) ((==)|(!=)|(>)|(>=)|(<)|(<=)) ((\$[A-Za-z]+)|([0-9]+)) ?\){2} \? : goto [0-9]+$", cmd): ret = self.__parse_conditions_judgment_parenthesis(cmd) if not ret[0]: PC = ret[1] jump = True break elif re.match(r"^goto [0-9]+$", cmd): PC = int(re.findall(r"^goto (.*?)$", cmd)[0]) jump = True break elif re.match(r"^Sleep\([0-9]+([.][0-9]+)?\)$", cmd): sleep(float(re.findall(r"^Sleep[(](.+?)[)]$", cmd)[0])) elif re.match( r"^CreateMessage\(0x(([0-9 A-F]{1,2})|([0-7]{1}[0-9 A-F]{2})), [1-8]{1}, \[0x[0-9A-Fa-f]{2}(, 0x[0-9A-Fa-f]{2}){0,7}\]\)$", cmd): extractionData = re.findall( r"^CreateMessage\((.*?), (.*?), (.*?)\)$", cmd) self.creat_msg(int(extractionData[0][0], 16), int(extractionData[0][1]), eval(extractionData[0][2])) # print(self.msgs) elif re.match( r"^StartMessage\(0x(([0-9 A-F]{1,2})|([0-7]{1}[0-9 A-F]{2})), [0-9]+([.][0-9]+)?\)$", cmd): extractionData = re.findall( r"^StartMessage\((.*?), (.*?)\)$", cmd) self.create_periodic_msg_task( int(extractionData[0][0], 16), float(extractionData[0][1])) self.periodic_msg_task_start(int(extractionData[0][0], 16)) elif re.match( r"^StopMessage\(0x(([0-9 A-F]{1,2})|([0-7]{1}[0-9 A-F]{2}))\)$", cmd): self.periodic_msg_task_stop( int(re.findall(r"^StopMessage\((.*?)\)$", cmd)[0], 16)) # print(self.msgs) elif re.match( r"^SetMessage\(0x(([0-9 A-F]{1,2})|([0-7]{1}[0-9 A-F]{2})), \[0x[0-9A-Fa-f]{2}(, 0x[0-9A-Fa-f]{2}){0,7}\]\)$", cmd): extractionData = re.findall( r"^SetMessage\((.*?), (.*?)\)$", cmd) self.modify_msg(int(extractionData[0][0], 16), eval(extractionData[0][1])) self.periodic_msg_task_modify_msg( int(extractionData[0][0], 16)) elif re.match( r"^SendMessage\(0x(([0-9 A-F]{1,2})|([0-7]{1}[0-9 A-F]{2})), [1-8]{1}, \[0x[0-9A-Fa-f]{2}(, 0x[0-9A-Fa-f]{2}){0,7}\]\)$", cmd): extractionData = re.findall( r"^SendMessage\((.*?), (.*?), (.*?)\)$", cmd) self.send_msg( can.Message(arbitration_id=int(extractionData[0][0], 16), dlc=int(extractionData[0][1]), data=eval(extractionData[0][2]))) elif re.match(r"^echo *\".*\"$", cmd): extractionData = re.findall(r"^echo *(.*?)$", cmd) print(extractionData[0]) elif re.match(r"^.*\?.*:.*$", cmd): self.__parse_diag_msg(cmd) elif re.match(r"^$", cmd): pass else: raise Exception( "line {0}: Unrecognized Command".format(PC + 1)) if not jump: PC += 1 if PC >= len(self.cmdsDict): break def main(self, dataDict): '''''' self.precompile(dataDict) self.preprocessing(dataDict) self.cmd_parse()
class App(tk.Frame): def __init__(self, master): tk.Frame.__init__(self, master) self.winfo_toplevel().title(" UDS on Python") master.iconphoto(False, tk.PhotoImage(file='logo.png')) self.frame = tk.Frame(master) self.frame.pack(fill=tk.BOTH, expand=True) self.tpTime = 0 self.tpTimee = 0 # ------ connection title self.connectionTitleMenu = tk.Canvas(self.frame, width=600, height=100, bd=0, highlightthickness=0) self.requestTitleLabel = tk.Label(self.connectionTitleMenu, text='Configure the connection', relief=tk.RIDGE, font=('verdana', 10, 'bold')) self.requestTitleLabel.pack(pady=15) # self.connectionTitleMenu.pack(side=tk.TOP) self.connectionTitleMenu.grid(row=0, column=0) # ------ communication menu self.communicationMenu = tk.Canvas(self.frame, width=600, height=100, bd=0, highlightthickness=0) self.reqIdLabel = tk.Label(self.communicationMenu, text='Request ID:') self.reqId = tk.Entry(self.communicationMenu, bd=5, width=10, justify='center') self.reqId.insert(0, '757') self.reqId.config(state='disabled') self.resIdLabel = tk.Label(self.communicationMenu, text='Response ID:') self.resId = tk.Entry(self.communicationMenu, bd=5, width=10, justify='center') self.resId.insert(0, '7C1') self.resId.config(state='disabled') self.interface = tk.StringVar(window) self.interfaces = ('peak',) self.interface.set(self.interfaces[0]) self.interfaceLabel = tk.Label(self.communicationMenu, text='Interface:') self.interfaceOptions = tk.OptionMenu(self.communicationMenu, self.interface, self.interfaces[0]) self.interfaceOptions.config(state='disabled') self.device = tk.StringVar(window) self.devices = ('PCAN_USBBUS1',) self.device.set(self.devices[0]) self.deviceLabel = tk.Label(self.communicationMenu, text='Device:') self.deviceOptions = tk.OptionMenu(self.communicationMenu, self.device, self.devices[0]) self.deviceOptions.config(state='disabled') self.sensor = tk.StringVar(window) self.sensors = ('SGU', 'BEG') self.sensor.set(self.sensors[0]) self.sensorLabel = tk.Label(self.communicationMenu, text='Sensor:') self.sensorOptions = tk.OptionMenu(self.communicationMenu, self.sensor, *self.sensors) # self.sensorOptions.config(state='disabled') self.bdLabel = tk.Label(self.communicationMenu, text='Baudrate:') self.baudRate = tk.Entry(self.communicationMenu, bd=5, width=6, justify='center') self.baudRate.insert(0, '500000') self.baudRate.config(state='disabled') self.reqIdLabel.grid(row=2, column=0) self.reqId.grid(row=2, column=1) self.resIdLabel.grid(row=2, column=2) self.resId.grid(row=2, column=3) self.interfaceLabel.grid(row=1, column=0) self.interfaceOptions.grid(row=1, column=1) self.deviceLabel.grid(row=1, column=2) self.deviceOptions.grid(row=1, column=3) self.sensorLabel.grid(row=0, column=0) self.sensorOptions.grid(row=0, column=1) self.bdLabel.grid(row=0, column=2) self.baudRate.grid(row=0, column=3) # self.communicationMenu.pack(side=tk.TOP) self.communicationMenu.grid(row=1, column=0, pady=5) # ------ comm status self.commStatus = False self.commButton = tk.Button(self.communicationMenu, text="Connect", command=self.configComm) self.commLabel = tk.Label(self.communicationMenu, text='Comm status:') self.commStatuss = tk.Label(self.communicationMenu, text=str(self.commStatus)) self.commLabel.grid(row=3, column=2) self.commStatuss.grid(row=3, column=3) self.commButton.grid(row=3, column=1) # ------ request title self.requestTitleMenu = tk.Canvas(self.frame, width=600, height=100, bd=0, highlightthickness=0) self.requestTitle = tk.Label(self.requestTitleMenu, text='Select a service', relief=tk.RIDGE, font=('verdana', 10, 'bold')) self.requestTitle.pack(side=tk.TOP, pady=15) # self.requestTitleMenu.pack(side=tk.TOP) # ------ request menu for BEG self.begRequestMenu = tk.Canvas(self.frame, width=600, height=400, bd=0, highlightthickness=0) self.begServices = { 'Diagnostic Session Control': 0x10, 'ECU Reset': 0x11, 'Comunication Control': 0x28, 'Tester Present': [0x3E, 0x00], 'Read Data': 0x22, 'Write Data': 0x2E, 'Read DTC Information': 0x19, 'Clear Diagnostics Information': 0x14, 'Control DTC Setting': 0x85, 'Security Access': 0x27} self.begDataToRead = { 'Read active diagnostic session': 0xF186, 'Read system supplier identifier': 0xF18A, 'Read ECU manufacturing date': 0xF18B, 'Read ECU serial number': 0xF18C, 'Read supplier ECU hardware number': 0xF192, 'Read system supplier ECU HW version number': 0xF193, 'Read system supplier ECU software number': 0xF194, 'Read ODXFileDataIdentifier': 0xF19E, 'Read enable/disable B messages': 0xFD11, 'Read configured CAN1 baud rate': 0xFD12, 'Read current CAN1 baud rate': 0xFD13, 'Read CAN1 diagnostics messages IDs': 0xFD14, 'Read object/filtered object message IDs': 0xFD15, 'Read last configured single CAN message ID': 0xFD16, 'Read radar ECU CAN message Ids': 0xFD17, 'Read object/filtered object message prioritization': 0xFD18, 'Read configured number of sent objects/filtered objects': 0xFD19, 'Read antenna modulation combinations': 0xFD26, 'Read CAN communication protocol': 0xFD27, 'Read mounting position': 0xFD28, 'Read current number of sent objects/filtered': 0xFD29, 'Read zone configuration': 0xFD60, 'Read layer': 0xFD61, 'Read enable/disable object/filtered object and/or zone message': 0xFD62, # noqa: E501 'Read radar wave emission stop': 0xFD63, 'Read output coordinate system': 0xFD64} self.dataToWrite = { 'Write enable/disable B messages': 0xFD11, 'Write CAN1 baud rate': 0xFD12, 'Write CAN1 diagnostics messages IDs': 0xFD14, 'Write configure object/filtered object message IDs': 0xFD15, 'Write configure single CAN message ID': 0xFD16, 'Write configure object/filtered object message prioritization': 0xFD18, # noqa: E501 'Write configure number of objects/filtered objects to be sent': 0xFD19, # noqa: E501 'Configure antenna modulation combinations': 0xFD26, 'Configure CAN communication protocol': 0xFD27, 'Configure mounting position': 0xFD28, 'Configure zone configuration': 0xFD60, 'Configure layer': 0xFD61, 'Configure enable/disable object/filtered object and/or zone message': 0xFD62, # noqa: E501 'Configure radar wave emission stop': 0xFD63, 'Configure output coordinate system': 0xFD64} self.dataOptions = {'Read Data': self.begDataToRead, 'Write Data': self.dataToWrite} self.service = tk.StringVar(window) self.service.trace('w', self.updateData) self.serviceLabel = tk.Label(self.begRequestMenu, text='SID') self.serviceOptions = tk.OptionMenu(self.begRequestMenu, self.service, *self.begServices.keys()) # self.serviceOptions.config(state='disabled') self.DSCSF = { 'Default diagnostic session': 0x01, 'Extended diagnostic session': 0x03 } self.ECUR = { 'Hard Reset': 0x01 } self.RDTCI = { 'reportDTCByStatusMask': 0x02, 'reportDTCExtDataRecordByDTCNumber': 0x06} self.sfOptions = { 'Diagnostic Session Control': self.DSCSF, 'ECU Reset': self.ECUR, 'Read DTC Information': self.RDTCI} self.sFunction = tk.StringVar(self) self.sFunctionLabel = tk.Label(self.begRequestMenu, text='SubFn') self.sFunctionOptions = tk.OptionMenu(self.begRequestMenu, self.sFunction, '') self.sFunctionOptions['menu'].delete(0, tk.END) self.dataIdentifier = tk.StringVar(self) self.dIdentifierLabel = tk.Label(self.begRequestMenu, text='DID') self.dIdentifierOptions = tk.OptionMenu(self.begRequestMenu, self.dataIdentifier, '') self.dIdentifierOptions['menu'].delete(0, tk.END) self.dRecordLabel = tk.Label(self.begRequestMenu, text='DataRec') self.dataRecord = tk.Entry(self.begRequestMenu, bd=5, width=20, state=tk.DISABLED) self.B3 = tk.Button(self.begRequestMenu, text="Send", command=self.sendRequest) self.B3.config(state='disabled') self.serviceLabel.pack(side=tk.LEFT) self.serviceOptions.pack(side=tk.LEFT) self.sFunctionLabel.pack(side=tk.LEFT) self.sFunctionOptions.pack(side=tk.LEFT) self.dIdentifierLabel.pack(side=tk.LEFT) self.dIdentifierOptions.pack(side=tk.LEFT) self.dRecordLabel.pack(side=tk.LEFT) self.dataRecord.pack(side=tk.LEFT) self.B3.pack(side=tk.LEFT) # self.begRequestMenu.pack(side=tk.TOP) # ------ request menu for SGU self.sguDIDS = { 'Programming Attempt Counter': [0x22, 0xf1, 0x10], 'Boot Software Identification': [0x22, 0xf1, 0x80], 'Application Software Identification': [0x22, 0xf1, 0x81], 'Active Diagnostic Session': [0x22, 0xf1, 0x86], 'ECU Voltage': [0x22, 0xf1, 0x87], 'ECU Software Number': [0x22, 0xf1, 0x88], 'ECU Manufacturing Date': [0x22, 0xf1, 0x8b], 'Serial Number': [0x22, 0xf1, 0x8c], 'ECU Hardware Partnumber': [0x22, 0xf1, 0x91], 'ECU Hardware Version Information': [0x22, 0xf1, 0x93], 'ECU Temperature': [0x22, 0xf1, 0x94], 'SDA Horizontal Misalignment Angle': [0x22, 0xfc, 0x01], 'SDA Vertical Alignment Angle': [0x22, 0xfc, 0x02], 'SDA Status': [0x22, 0xfc, 0x03]} self.sguTPS = { 'ON - With response': [0x3e, 0x00], 'ON - Without response': [0x3e, 0x80], 'OFF': ''} self.sguRequestMenu = tk.Canvas(self.frame, width=600, height=400, bd=0, highlightthickness=0) self.sguDID = tk.StringVar(self) self.sguDIDLabel = tk.Label(self.sguRequestMenu, text='Read Data By Identifier: ') self.sguDIDOptions = tk.OptionMenu(self.sguRequestMenu, self.sguDID, *self.sguDIDS.keys()) self.sguTP = tk.StringVar(self) self.sguTP.set('OFF') self.sguTP.trace('w', self.startTrd) self.sguTPLabel = tk.Label(self.sguRequestMenu, text='Tester Present: ') self.sguTPOptions = tk.OptionMenu(self.sguRequestMenu, self.sguTP, *self.sguTPS.keys()) self.sguSend = tk.Button(self.sguRequestMenu, text="Send", command=self.sguSend) self.sguResponse = tk.Label(self.sguRequestMenu, text='Response: ') self.sguDIDLabel.grid(row=1, column=0) self.sguDIDOptions.grid(row=1, column=1) self.sguSend.grid(row=2, column=0) self.sguResponse.grid(row=2, column=1) self.sguTPLabel.grid(row=0, column=0) self.sguTPOptions.grid(row=0, column=1) # self.sguRequestMenu.pack(side=tk.TOP) # ------ response menu self.responseMenu = tk.Canvas(self.frame, width=600, height=100, bd=0, highlightthickness=0) self.response = tk.Label(self.responseMenu, text='Response: ') # self.response.pack(side=tk.TOP) # self.responseMenu.pack(side=tk.TOP) # ------ log menu self.terminalMenu = tk.Canvas(self.frame, width=100, height=50, bd=0, highlightthickness=0) self.term = tkst.ScrolledText(master=self.terminalMenu, wrap=tk.WORD, width=40, height=10) self.term.pack() # ------ def updateData(self, *args): try: if self.service.get() == 'Write Data': self.dataRecord.config(state=tk.NORMAL) else: self.dataRecord.delete(0, tk.END) self.dataRecord.config(state=tk.DISABLED) menu = self.dIdentifierOptions['menu'] menu1 = self.sFunctionOptions['menu'] menu.delete(0, 'end') menu1.delete(0, 'end') self.dataIdentifier.set('') self.sFunction.set('') if self.service.get() == 'Write Data' or self.service.get() == 'Read Data': # noqa: E501 didOptions = (self.dataOptions.get(self.service.get(), '')).keys() # noqa: E501 for option in didOptions: menu.add_command(label=option, command=lambda selected=option: self.dataIdentifier.set(selected)) # noqa: E501 elif self.service.get() == 'Diagnostic Session Control' or self.service.get() == 'ECU Reset' or self.service.get() == 'Read DTC Information': # noqa: E501 sfOptions = (self.sfOptions.get(self.service.get(), '')).keys() for option in sfOptions: menu1.add_command(label=option, command=lambda selected=option: self.sFunction.set(selected)) # noqa: E501''' except Exception: self.dataIdentifier.set('') menu = self.dIdentifierOptions['menu'] menu.delete(0, 'end') self.sFunction.set('') menu1 = self.sFunctionOptions['menu'] menu1.delete(0, 'end') def sendRequest(self): if self.service.get() == '': messagebox.showinfo("Error", 'Select a SID') else: if self.service.get() == 'Read Data': if self.dataIdentifier.get() != '': message = (hex(self.begServices.get(self.service.get(), '')), hex(self.begDataToRead.get(self.dataIdentifier.get(), # noqa: E501 ''))) if tk.messagebox.askyesno('Confirm', "SID: " + self.service.get() + "\n" + "DID: " + self.dataIdentifier.get()): # noqa: E501 self.response['text'] = 'Request: ' + str(message) # print(message) else: messagebox.showinfo("Error", 'DID is missing') elif self.service.get() == 'Write Data': if self.dataRecord.get() != '' and self.dataIdentifier.get() != '': # noqa: E501 message = (hex(self.begServices.get(self.service.get(), '')), hex(self.dataToWrite.get(self.dataIdentifier.get(), # noqa: E501 '')), self.dataRecord.get()) if tk.messagebox.askyesno('Confirm the content', "SID: " + self.service.get() + "\n" + "DID: " + self.dataIdentifier.get() + "\n" + "Data: " + self.dataRecord.get()): # noqa: E501 self.response['text'] = 'Request: ' + str(message) # print(message) elif self.dataIdentifier.get() == '': messagebox.showinfo("Error", 'DID is missing') elif self.dataRecord.get() == '': messagebox.showinfo("Error", 'Data Record is missing') elif self.service.get() == 'Diagnostic Session Control' or self.service.get() == 'ECU Reset' or self.service.get() == 'Read DTC Information': # noqa: E501 message = (hex(self.begServices.get(self.service.get(), '')), hex((self.sfOptions.get(self.service.get())).get(self.sFunction.get()))) # noqa: E501 if tk.messagebox.askyesno('Confirm the content', "SID: " + self.service.get() + "\n" + "SubFn: " + self.sFunction.get()): # noqa: E501 self.response['text'] = 'Request: ' + str(message) # print(hex((self.sfOptions.get(self.service.get())).get(self.sFunction.get()))) # noqa: E501 else: if tk.messagebox.askyesno('Confirm the content', self.service.get()): # self.response['text'] = 'Request: ' + str(message) msg = self.a.send(self.begServices.get(self.service.get())) '''if msg[0] == 0x7e: msg[1] = 'Positive response ' else: msg[1] = 'Negative response ''' self.response['text'] = 'Response: ' + str(msg) def configComm(self): if not self.commStatus: aux = True reqId, resId = self.reqId.get(), self.resId.get() interface, device = self.interface.get(), self.device.get() baudrate = self.baudRate.get() msg = '' if not all(c in string.hexdigits for c in reqId) or reqId == '': msg = 'Invalid redId' aux = False else: reqId = int(reqId, 16) if not all(c in string.hexdigits for c in resId) or resId == '': msg = 'Invalid resId' aux = False else: resId = int(resId, 16) if interface not in self.interfaces or interface == '': msg = 'Invalid interface' aux = False if device not in self.devices or device == '': msg = 'Invalid device' aux = False if not all(c in string.digits for c in baudrate) or baudrate == '': msg = 'Invalid baudrate' aux = False if aux: try: self.a = Uds(reqId=reqId, resId=resId, interface=interface, device=device, baudrate=baudrate) print(self.a) self.commStatus = True self.commButton.config(text='Disconnect') self.requestTitleMenu.grid(row=2, column=0) self.sguRequestMenu.grid(row=3, column=0, pady=5) self.terminalMenu.grid(row=4, column=0) self.termPrint('connected') except Exception: messagebox.showinfo('Error', 'There is no connection') self.commStatus = False else: messagebox.showinfo('Error', msg) else: try: self.a.disconnect() self.commButton.config(text='Connect') self.requestTitleMenu.grid_forget() self.sguRequestMenu.grid_forget() self.terminalMenu.grid_forget() self.commStatus = False except Exception: messagebox.showinfo('Error', 'Unable to disconnect') self.commStatuss.config(text=str(self.commStatus)) '''if not self.commStatus: self.commButton.config(text='Connect') self.requestTitleMenu.grid_forget() self.sguRequestMenu.grid_forget() self.terminalMenu.grid_forget() else: self.commButton.config(text='Disconnect') self.requestTitleMenu.grid(row=2, column=0) self.sguRequestMenu.grid(row=3, column=0, pady=5) self.terminalMenu.grid(row=4, column=0) self.termPrint('connected')''' def sguSend(self): msg = self.sguDIDS.get(self.sguDID.get()) self.termPrint(msg) try: msg = self.a.send(msg) self.termPrint(msg) except Exception: self.termPrint('No response') def testerPresent(self, *args): self.tpTimee += 4 while self.commStatus and self.sguTP.get() == 'ON - With response' or self.sguTP.get() == 'ON - Without response': # noqa: E501 if self.tpTimee - self.tpTime >= 4: self.tpTime, self.tpTimee = time(), time() msg = self.sguTPS.get(self.sguTP.get()) self.termPrint(msg) try: msg = self.a.send(self.sguTPS.get(self.sguTP.get())) self.termPrint(msg) except Exception: self.termPrint('No response') else: self.tpTimee = time() def termPrint(self, info): if type(info) is list: _msg = [] for inf in info: _msg.append(hex(inf)) info = str(_msg) now = datetime.now() now = now.strftime('%m/%d/%Y, %H:%M:%S') self.term.config(state=tk.NORMAL) self.term.insert('insert', now + ': ' + '\n' + (info) + '\n') self.term.see("end") self.term.config(state=tk.DISABLED) def startTrd(self, *args): Thread(target=self.testerPresent, daemon=True).start()
from uds import Uds E400 = Uds(resId=0x600, reqId=0x650, transportProtocol='CAN', interface='peak', device='PCAN_USBBUS1', baudrate='500000') try: response = E400.send( [0x22, 0xF1, 0x8C]) # gets the entire response from the ECU # noqa: E501 except Exception: print('Send did not complete') if (response[0] == 0x7F): print('Negative response') else: serialNumberArray = response[ 3:] # cuts the response down to just the serial number serialNumberString = “” # initialises the string for i in serialNumberArray: serialNumberString += chr(i) # Iterates over each element and converts the array element into an ASCII string print(serialNumberString) # prints the ASCII string # noqa: E501 print(serialNumberArray)
if __name__ == "__main__": listener = can.Listener() notifier = can.Notifier(bus, [listener], 0) listener.on_message_received = onReceiveCallback udsConnection = Uds() print("Test 1") clearReceiveBuffer() receiveThread = Thread(target=singleFrameResponse_target) receiveThread.start() sleep(0.2) a = udsConnection.send([0x22, 0xF1, 0x8C]) print(a) while(receiveThread.is_alive()): pass print("Test 2") clearReceiveBuffer() receiveThread = Thread(target=multiFrameResponse_target) receiveThread.start() a = udsConnection.send([0x22, 0xF1, 0x8C]) print(a) while(receiveThread.is_alive()): pass
import uds from uds import Uds if __name__ == "__main__": # This creates an Uds object from the Bootloader.odx file odxEcu = uds.createUdsConnection("Bootloader.odx", "", inteface="peak") # This sends a request for Ecu Serial number and stores the result esn = odxEcu.readDataByIdentifier("ECU Serial Number") # This will be the printed ASCII string print(esn) # This creates a Uds object manually rawEcu = Uds(reqId=0x7E0, resId=0x7E8, interface="peak") # This sends the request for Ecu Serial Number esnRaw = rawEcu.send([0x22, 0xF1, 0x8C]) # This prints the raw payload returned from the ECU print(esnRaw)
from uds import Uds if __name__ == "__main__": a = Uds(reqId=0x7E0, resId=0x7E8, interface="peak", device="PCAN_USBBUS1") ## transmit a standard tester present TesterPresent = a.send([0x3E, 0x00]) print(TesterPresent) # This should be [0x7E, 0x00] ## transmit a request for ECU Serial Number SerialNumber = a.send([0x22, 0xF1, 0x8C]) print(SerialNumber) # this will vary depending on the ECU, but should start with [0x6E, 0xF1, 0x8C]
from time import sleep # noqa: F401 # sgu '''a = Uds(reqId=0x757, resId=0x7C1, interface='peak', device="PCAN_USBBUS1", baudrate='500000') print(a) TesterPresent = a.send([0x14, 0x00]) print('Tester Present request: [0x3E, 0x00]') tPResponse = [] for _hex in TesterPresent: tPResponse.append(hex(_hex)) print('Tester Present response: ' + str(tPResponse)) SerialNumber = a.send([0x22, 0xF1, 0x94]) print(SerialNumber) print('Serial Number request: [0x22, 0xF1, 0x81]') sNResponse = [] for _hex in SerialNumber: sNResponse.append(hex(_hex)) print('Serial Number response: ' + str(sNResponse))''' a = Uds(reqId=0x18DA2AF1, resId=0x18DAFA2A, interface='peak', device="PCAN_USBBUS1", baudrate='500000') print(a) try: sn = a.send([0x02, 0x3E, 0x00]) print(sn) except Exception as e: print(e)