def test_ecu_did_scan(self): c = CanInterface('') testclass_ecus = [ ECUAddress(0x711, 0x719, 0), ECUAddress(0x7e0, 0x7e8, 0) ] ecus = ecu_did_scan(c, range(0, 0x100), udscls=FakeUDS) self.assertEqual(testclass_ecus, ecus)
def test_did_scan(self): c = CanInterface('') testclass_ecus = [ { 'ecu': ECU(c, ECUAddress(0x711, 0x719, 0), scancls=FakeUDS), 'dids': { 0x0042: b'\x62\x00\x42ANSWER', }, }, { 'ecu': ECU(c, ECUAddress(0x7e0, 0x7e8, 0), scancls=FakeUDS), 'dids': { 0xE010: b'\x62\xE0\x10VERSION 1.2.3', 0xF190: b'\x62\xF1\x901AB123CD1EF123456', }, }, ] for test in testclass_ecus: ecu = test['ecu'] test_dids = list(test['dids'].keys()) before_scan_sessions = list(ecu._sessions.keys()) self.assertEqual([1], before_scan_sessions) before_scan_dids = list(ecu._sessions[1]['dids'].keys()) self.assertEqual([], before_scan_dids) ecu.did_read_scan(range(0, 0x10000)) after_scan_sessions = list(ecu._sessions.keys()) self.assertEqual([1], after_scan_sessions) dids = list(ecu._sessions[1]['dids'].keys()) self.assertEqual(test_dids, dids) for did in test['dids'].keys(): self.assertEqual(test['dids'][did], ecu._sessions[1]['dids'][did]['resp'])
def import_results(args, c, scancls): if args.input_file is not None: # TODO: support multiple in/out file types? import yaml try: from yaml import CLoader as yamlLoader except ImportError: from yaml import Loader as yamlLoader with open(args.input_file, 'r') as f: imported_data = yaml.load(f, Loader=yamlLoader) config = { 'config': imported_data['config'], 'notes': imported_data['notes'], 'ECUs': {}, } if not config['notes']: config['notes'] = {} # If the input baudrate is AUTO (the default), and the input config # file has a baud rate, use the value from the config file, otherwise # override the config file. if args.baud != 'AUTO' or 'baud' not in config['config']: config['config']['baud'] = args.baud if 'no_recursive_session_scanning' not in config['config']: config['config']['no_recursive_session_scanning'] = args.no_recursive_session_scanning if 'timeout' not in config['config']: config['config']['timeout'] = args.timeout for e in imported_data['ECUs']: addr = ECUAddress(**e) config['ECUs'][addr] = ECU(c, addr, uds_class=scancls, timeout=config['config']['timeout'], delay=args.scan_delay, **e) return config
def ecu_session_scan( c, arb_id_range, ext=0, session=1, udscls=None, timeout=3.0, # noqa: C901 delay=None, verbose_flag=False): scan_type = '' if ext: scan_type = ' ext' if udscls is None: udscls = UDS log.debug('Starting{} Session ECU scan for range: {}'.format( scan_type, arb_id_range)) c.placeCanBookmark( 'ecu_session_scan({}, ext={}, session={}, timeout={}, delay={})'. format(arb_id_range, ext, session, timeout, delay)) ecus = [] possible_ecus = [] for i in arb_id_range: tester_id = uds.ARBID_CONSTS[ext]['tester'] if i == tester_id: # Skip i == 0xF1 because in that case the sender and receiver IDs # are the same log.detail( 'Skipping {} in ext ECU scan: invalid ECU address'.format( hex(tester_id))) continue arb_id, resp_id = gen_arbids(i, ext) addr = ECUAddress(arb_id, resp_id, ext) u = udscls(c, addr.tx_arbid, addr.rx_arbid, extflag=addr.extflag, verbose=verbose_flag, timeout=timeout) log.detail('Trying {}'.format(addr)) try: start_index = u.c.getCanMsgCount() with new_session(u, session) as msg: if msg is not None: log.debug('{} session {}: {}'.format( addr, session, repr(msg))) log.msg('found {}'.format(addr)) ecus.append(addr) else: tx_msg, responses = find_possible_resp( u, start_index, arb_id, uds.SVC_DIAGNOSTICS_SESSION_CONTROL, session, timeout) if responses: log.warn( 'Possible non-standard responses for {} found:'. format(hex(addr.tx_arbid))) for rx_arbid, msg in responses: log.warn('{}: {}'.format(hex(rx_arbid), msg.hex())) possible_ecus.append(ECUAddress(arb_id, rx_arbid, ext)) except uds.NegativeResponseException as e: log.debug('{} session {}: {}'.format(addr, session, e)) log.msg('found {}'.format(addr)) # If a negative response happened, that means an ECU is present # to respond at this address. ecus.append(addr) if delay: time.sleep(delay) # Double check any non-standard responses that were found if possible_ecus: log.detail('Retrying possible non-standard ECU addresses') for addr in possible_ecus: # if the TX ID is the OBD2 request ID, skip it if addr.tx_arbid == uds.ARBID_CONSTS[addr.extflag]['obd2_broadcast']: log.detail('Skipping OBD2 broadcast address ECU {}'.format(addr)) continue u = udscls(c, addr.tx_arbid, addr.rx_arbid, extflag=addr.extflag, verbose=verbose_flag, timeout=timeout) log.detail('Trying {}'.format(addr)) try: with new_session(u, session) as msg: if msg is not None: log.debug('{} session {}: {}'.format( addr, session, repr(msg))) log.msg('found {}'.format(addr)) ecus.append(addr) except uds.NegativeResponseException as e: log.debug('{} session {}: {}'.format(addr, session, e)) log.msg('found {}'.format(addr)) # If a negative response happened, that means an ECU is present # to respond at this address. ecus.append(addr) if delay: time.sleep(delay) return ecus