Exemple #1
0
    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)
Exemple #2
0
    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'])
Exemple #3
0
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
Exemple #4
0
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