def read_process(intf, is_isotp, end, auto_end, test, lock, queue): '''Process to read to CAN interface :param intf: the socket can interface :param is_isotp: to indicate if the write is at isotp stack level :param end: the flag to indicate the end of the process :param auto_end: RFU :param test: the flag to indicate the end of the test :param lock: RFU :param queue: the queue to exchange data ''' read_ctx = context.create_ctx(channel=intf, bustype=BusType.SOCKETCAN, bitrate=0, canid_recv=0, canid_send=0, timeout=1, trace=1) while not end.value: if test.value: read_data = [] while True: if is_isotp: ret, msg = isotp.read(read_ctx) else: ret, msg = vcan.read(read_ctx) if msg is None: break else: data = [msg.arbitration_id] + list(msg.data) read_data.append(list(data)) if read_data: queue.put(read_data) else: time.sleep(1)
def ecu_process(intf, end, test, lock): ctx = context.create_ctx(channel=intf, bustype=BusType.SOCKETCAN, bitrate=0, canid_recv=0x10, canid_send=0x10, timeout=2, trace=1) check = 0 lock.acquire() while not end.value: if check != 3: ret, msg = vcan.read(ctx) if msg is None: continue else: data = list(msg.data) # Generate an ECU response if data == [0x02, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00]: print("OK received single frame") msg = can.Message(data=[0x30, 0x02, 0x14]) vcan.write(ctx, msg, 0x10) check += 1 elif data == [0x10, 0x0B, 0x27, 0x02, 0x01, 0x02, 0x03, 0x04]: print("OK received Multiple frame (part 1)") msg = can.Message(data=[0x30, 0x01, 0x14]) vcan.write(ctx, msg, 0x10) check += 1 elif data == [0x21, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00]: print("OK received Multiple frame (part 2)") msg = can.Message(data=[0x30, 0x01, 0x14]) vcan.write(ctx, msg, 0x10) check += 1 continue else: lock.release() time.sleep(1) print("ECU send ISO TP start") vcan.write( ctx, can.Message( data=[0x10, 0x0B, 0x27, 0x02, 0x01, 0x02, 0x03, 0x04])) vcan.write( ctx, can.Message( data=[0x21, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00])) break
def _canwrite_process(intfs, calibration, end_process): print("canwrite_process: START") for k, v in intfs.items(): try: v['ctx'] = context.create_ctx(channel=v['channel'], bustype=BusType.SOCKETCAN, bitrate=v['bitrate'], canid_recv=0, canid_send=0, timeout=None, trace=0) except: print("Error creating context on interface {}".format( v['channel'])) while not end_process.value: try: e = forward_queue.get(timeout=2) except queue.Empty: pass except EOFError: return else: i = e['intf'] if i in intfs: # Memorize message that will be written ecache = {'msg': e, 'time': time.time()} write_cache.append(ecache) msg = can.Message(data=e['data']) out = "W: {} [0x{:03x} - {}]".format( i, e['canid'], codecs.encode(msg.data, 'hex')) print(colored(out, 'green')) vcan.write(intfs[i]['ctx'], msg, can_id=e['canid']) else: print("Warning interface {} doesn't exist".format(i))
def write_process(intf, is_isotp, end, auto_end, test, lock, queue): '''Process to write to CAN interface :param intf: the socket can interface :param is_isotp: to indicate if the write is at isotp stack level :param end: the flag to indicate the end of the process :param auto_end: the flag to indicate that the process auto stop the test when all data have been written :param test: the flag to indicate the end of the test :param lock: RFU :param queue: the queue to exchange data ''' write_ctx = context.create_ctx(channel=intf, bustype=BusType.SOCKETCAN, bitrate=0, canid_recv=0, canid_send=0, timeout=2, trace=1) while not end.value: if test.value: if not queue.empty(): for d in queue.get(): if is_isotp: set_canid_send(write_ctx, d[0]) isotp.write(write_ctx, d[1:]) else: msg = can.Message(data=d[1:]) vcan.write(write_ctx, msg, can_id=d[0]) time.sleep(0.01) if auto_end: test.value = False else: time.sleep(1) else: time.sleep(1)
class TestUDS(unittest.TestCase): ctxECU = None ctxt = None def test_session_supported(self): p = Process(target=virtualECU, args=(self.ctxECU,)) p.start() time.sleep(0.5) ret = diag.start(self.ctxt, 0x01, False) self.assertEqual(ret, 0) p.join() def test_session_notsupported(self): p = Process(target=virtualECU, args=(self.ctxECU,)) p.start() ret = diag.start(self.ctxt, 0x80, False) self.assertEqual(ret, -1) p.join() if __name__ == '__main__': ctx1 = context.create_ctx (channel = intf, bustype = 'socketcan', bitrate = 115200, canid_recv = 0x400, canid_send = 0x450, timeout = 1) ctx2 = context.create_ctx (channel = intf, bustype = 'socketcan', bitrate = 115200, canid_recv = 0x450, canid_send = 0x400, timeout = 1) TestUDS.ctxECU = ctx1 TestUDS.ctxt = ctx2 unittest.main(exit=False)
from array import array, ArrayType import time import can import argparse import cananalyze.abstract_can as vcan import cananalyze.isotp as isotp import cananalyze.context as context from cananalyze.context import BusType if __name__ == "__main__": parser = argparse.ArgumentParser( description="dump all ISOTP messages from an interface") parser.add_argument( "channel", help= "\"A\", \"B\", \"vcanX\" depending if bustype is komodo or socketcan") parser.add_argument("bustype", help="\"komodo\", \"socketcan\", ... ") args = parser.parse_args() ctx_read = context.create_ctx(channel=args.channel, bustype=args.bustype, bitrate=0, canid_recv=0, canid_send=0, timeout=2) while True: err, msg = isotp.read(ctx_read) print("RetCode=%u, Message=%s" % (err, msg))
def _canread_process(intf, intfs, calibration, end_process): intf_phy = intf intf_virt = intfs[intf]['channel'] print("canread_process: START [physical={} virtual={}]".format( intf_phy, intf_virt)) # Create the read context try: ctx_read = context.create_ctx(channel=intf_virt, bustype=BusType.SOCKETCAN, bitrate=intfs[intf]['bitrate'], canid_recv=0, canid_send=0, timeout=2, trace=0) except: print("Error creating context on interface {}".format(intf_virt)) return while not end_process.value: ret, msg = vcan.read(ctx_read) if msg is not None: canid = msg.arbitration_id if len(msg.data) == 0: print("R: {} [0x{:03x} - empty]".format( intf_phy, msg.arbitration_id)) continue # Check if GW write the same message on the same interface recently found = False for e in write_cache: # Clean very old cache try: if e['time'] > msg.timestamp + CACHE_TIMEOUT: write_cache.remove(e) elif e['msg']['intf'] == intf_phy and \ e['msg']['canid'] == msg.arbitration_id and \ e['msg']['data'] == msg.data: found = True write_cache.remove(e) break except ValueError: break if found: if verbose: print("R: {} [0x{:03x} - 0x{}] (from GW)".format( intf_phy, msg.arbitration_id, codecs.encode(msg.data, 'hex'))) continue print("R: {} [0x{:03x} - 0x{}]".format( intf_phy, msg.arbitration_id, codecs.encode(msg.data, 'hex'))) # for each output interface for k, v in intfs.items(): # Ignore the same interface if k == intf_phy: continue # Check rules if cal.calibration_matches(calibration, intf_phy, k, msg.arbitration_id, list(msg.data)): out = " F: {} -> {} [0x{:03x} - 0x{}]".format( intf_phy, k, msg.arbitration_id, codecs.encode(msg.data, 'hex')) print(colored(out, 'green')) forward_queue.put({ 'intf': k, 'canid': msg.arbitration_id, 'data': msg.data })
def _can_process(intf, intfs, calibration, end_validation, sync, gctx_op, gctx_data, gdata): intf_phy = intf intf_virt = intfs[intf]['channel'] print("can_process: START [physical={} virtual={}]".format( intf_phy, intf_virt)) # Create the read/write context ctx = context.create_ctx(channel=intf_virt, port_nr=intfs[intf]['port_nr'], bustype=intfs[intf]['bustype'], bitrate=intfs[intf]['bitrate'], canid_recv=0, canid_send=0, timeout=0.010, trace=0) if ctx == None: print("Error creating context on interface {}".format(intf_virt)) return # Wait for synch processes started sync.wait() while not end_validation.value: # Wait for synch for updated context, before operation sync.wait() dataReceived = gdata[0].copy() if gctx_op[intf] and len(gctx_data[intf]) > 0: data = list(gctx_data[intf]) ctx.set_canid_send(data[0]) msg = can.Message(data=data[1:], arbitration_id=data[0], dlc=len(data[1:])) vcan.write(ctx, msg) else: for i in range(2): ret, msg = vcan.read(ctx) if msg is not None and msg.dlc >= len(dataReceived): size = len(dataReceived) match = True for i in range(size): if dataReceived[i] != msg.data[i]: match = False if match == True: gctx_data[intf] = [ msg.arbitration_id, ] + list(msg.data) break else: print("{} R: {} [{}] expected [{}]".format( colored('[WARNING]', 'yellow'), intf, ','.join(hex(x) for x in msg.data), ','.join(hex(x) for x in dataReceived))) # Wait for synch for end operation sync.wait() print("can_process: END [physical={} virtual={}]".format( intf_phy, intf_virt))
import argparse import cananalyze.scan as scan import cananalyze.context as context import cananalyze.diag_session as session if __name__ == "__main__": parser = argparse.ArgumentParser(description="detect the UDS services") parser.add_argument( "channel", help= "\"A\", \"B\", \"vcanX\" depending if bustype is komodo or socketcan") parser.add_argument("bustype", help="\"komodo\", \"socketcan\", ... ") parser.add_argument("--count", help="the number of packets to get") args = parser.parse_args() ctx = context.create_ctx(channel=args.channel, bustype=args.bustype, port_nr=0, bitrate=500000, canid_recv=0x7da, canid_send=0x7ca, timeout=1) if ctx == None: context.output("Error occured during create_ctx") sys.exit(-1) session.pause_tester_present(ctx) scan.sessions(ctx) #scan.services(ctx)
import can import argparse import cananalyze.abstract_can as vcan import cananalyze.context as context from cananalyze.context import BusType if __name__ == "__main__": parser = argparse.ArgumentParser( description="dump all CAN messages read from an interface") parser.add_argument( "channel", help= "\"A\", \"B\", \"vcanX\" depending if bustype is komodo or socketcan") parser.add_argument("bustype", help="\"komodo\", \"socketcan\", ... ") parser.add_argument("--count", help="the number of packets to get") args = parser.parse_args() ctx_read = context.create_ctx(channel=args.channel, bustype=args.bustype, port_nr=0, bitrate=500000, canid_recv=0, canid_send=0, timeout=None) if args.count: vcan.sniff(ctx_read, max=int(args.count)) else: vcan.sniff(ctx_read)