Example #1
0
    def parse(cls, filename, search_paths=None, skip_disabled_mappings=False):
        search_paths = search_paths or []

        data = load_json_from_search_path(filename, search_paths)

        # Flatten all parent files into one dict
        while len(data.get('parents', [])) > 0:
            for parent_filename in data.get('parents', []):
                parent_data = load_json_from_search_path(
                    parent_filename, search_paths)
                # Merge data *into* parents, so we keep any overrides
                data = merge(parent_data, data)
                data['parents'].remove(parent_filename)

        message_set = cls(data.get('name', 'generic'))

        message_set.initializers = data.get('initializers', [])
        message_set.loopers = data.get('loopers', [])
        message_set.buses = cls._parse_buses(data)
        message_set.bit_numbering_inverted = data.get('bit_numbering_inverted',
                                                      None)
        message_set.extra_sources = set(data.get('extra_sources', set()))

        mapping_config = message_set._parse_mappings(data, search_paths,
                                                     skip_disabled_mappings)
        message_set.initializers.extend(mapping_config['initializers'])
        message_set.loopers.extend(mapping_config['loopers'])
        message_set.extra_sources.update(mapping_config['extra_sources'])

        # TODO could we parse the top level config file as if it were a mapping
        # and avoid duplicating this code?
        for message_id, message in list(data.get('messages', {}).items()):
            message['id'] = message_id
            mapping_config['messages'].append(message)

        mapping_config['diagnostic_messages'].extend(
            data.get('diagnostic_messages', []))
        message_set.diagnostic_messages = cls._parse_diagnostic_messages(
            message_set, mapping_config['diagnostic_messages'])

        mapping_config['commands'].extend(data.get('commands', []))
        message_set.commands = cls._parse_commands(mapping_config['commands'])
        message_set._parse_messages(mapping_config['messages'])

        return message_set
    def parse(cls, filename, search_paths=None, skip_disabled_mappings=False):
        search_paths = search_paths or []

        data = load_json_from_search_path(filename, search_paths)

        # Flatten all parent files into one dict
        while len(data.get('parents', [])) > 0:
            for parent_filename in data.get('parents', []):
                parent_data = load_json_from_search_path(parent_filename,
                        search_paths)
                # Merge data *into* parents, so we keep any overrides
                data = merge(parent_data, data)
                data['parents'].remove(parent_filename)

        message_set = cls(data.get('name', 'generic'))

        message_set.initializers = data.get('initializers', [])
        message_set.loopers = data.get('loopers', [])
        message_set.buses = cls._parse_buses(data)
        message_set.bit_numbering_inverted = data.get(
                'bit_numbering_inverted', None)
        message_set.extra_sources = set(data.get('extra_sources', set()))

        mapping_config = message_set._parse_mappings(data, search_paths,
                skip_disabled_mappings)
        message_set.initializers.extend(mapping_config['initializers'])
        message_set.loopers.extend(mapping_config['loopers'])
        message_set.extra_sources.update(mapping_config['extra_sources'])

        # TODO could we parse the top level config file as if it were a mapping
        # and avoid duplicating this code?
        for message_id, message in data.get('messages', {}).items():
            message['id'] = message_id
            mapping_config['messages'].append(message)

        mapping_config['diagnostic_messages'].extend(data.get('diagnostic_messages', []))
        message_set.diagnostic_messages = cls._parse_diagnostic_messages(
                message_set, mapping_config['diagnostic_messages'])

        mapping_config['commands'].extend(data.get('commands', []))
        message_set.commands = cls._parse_commands(mapping_config['commands'])
        message_set._parse_messages(mapping_config['messages'])

        return message_set
Example #3
0
    def _parse_mappings(self, data, search_paths, skip_disabled_mappings):
        all_messages = []
        all_diagnostic_messages = []
        all_commands = []
        all_extra_sources = set()
        all_initializers = []
        all_loopers = []

        for mapping in data.get('mappings', []):
            if 'mapping' not in mapping:
                fatal_error("Mapping is missing the mapping file path")

            mapping_enabled = mapping.get('enabled', True)
            if not mapping_enabled:
                LOG.warning("Mapping '%s' is disabled" % mapping['mapping'])
                if skip_disabled_mappings:
                    continue
            LOG.warning("Adding mapping '%s'" % mapping['mapping'])

            bus_name = mapping.get('bus', None)
            if bus_name is None:
                LOG.warning("No default bus associated with '%s' mapping" %
                            mapping['mapping'])
            elif bus_name not in self.buses:
                fatal_error("Bus '%s' (from mapping %s) is not defined" %
                            (bus_name, mapping['mapping']))
            elif not self.buses[bus_name].valid():
                LOG.warning("Mapping '%s' is disabled because bus '%s' " %
                            (mapping['mapping'], bus_name) +
                            "is not associated with a CAN controller")
                mapping['enabled'] = False
                if skip_disabled_mappings:
                    continue

            mapping_data = load_json_from_search_path(mapping['mapping'],
                                                      search_paths)

            commands = mapping_data.get('commands', [])
            for command in commands:
                command.setdefault('enabled', mapping_enabled)
            all_commands.extend(commands)

            diagnostic_messages = mapping_data.get('diagnostic_messages', [])
            for message in diagnostic_messages:
                message.setdefault('bus', bus_name)
                message.setdefault('enabled', mapping_enabled)
            all_diagnostic_messages.extend(diagnostic_messages)

            if mapping_enabled:
                all_initializers.extend(mapping_data.get('initializers', []))
                all_loopers.extend(mapping_data.get('loopers', []))
                all_extra_sources.update(
                    set(mapping_data.get('extra_sources', set())))

            messages = mapping_data.get('messages', {})
            if len(messages) == 0:
                LOG.warning("Mapping file '%s' doesn't define any messages" %
                            mapping['mapping'])

            if 'database' in mapping:
                database_filename, database_tree = self._parse_database(
                    find_file(mapping['database'], search_paths))
                messages = merge(
                    merge_database_into_mapping(database_filename,
                                                database_tree,
                                                messages).get('messages', {}),
                    messages)
                if mapping.get('bit_numbering_inverted', None) is None:
                    LOG.warning(
                        "The bit number inversion setting is undefined "
                        "for the mapping '%s', but it " % mapping['mapping'] +
                        "is database-backed - assuming inverted")
                    for message in list(messages.values()):
                        message.setdefault('bit_numbering_inverted', True)

            for message_id, message in list(messages.items()):
                message['id'] = message_id
                message.setdefault('bus', bus_name)
                message.setdefault('enabled', mapping_enabled)
            all_messages.extend(list(messages.values()))

        return {
            'messages': all_messages,
            'commands': all_commands,
            'diagnostic_messages': all_diagnostic_messages,
            'initializers': all_initializers,
            'extra_sources': all_extra_sources,
            'loopers': all_loopers
        }
    def _parse_mappings(self, data, search_paths, skip_disabled_mappings):
        all_messages = []
        all_commands = []
        all_extra_sources = set()
        all_initializers = []
        all_loopers = []

        for mapping in data.get('mappings', []):
            if 'mapping' not in mapping:
                fatal_error("Mapping is missing the mapping file path")

            mapping_enabled = mapping.get('enabled', True)
            if not mapping_enabled:
                LOG.warning("Mapping '%s' is disabled" % mapping['mapping'])
                if skip_disabled_mappings:
                    continue
            LOG.warning("Adding mapping '%s'" % mapping['mapping'])

            bus_name = mapping.get('bus', None)
            if bus_name is None:
                LOG.warning("No default bus associated with '%s' mapping" %
                        mapping['mapping'])
            elif bus_name not in self.buses:
                fatal_error("Bus '%s' (from mapping %s) is not defined" %
                        (bus_name, mapping['mapping']))
            elif not self.buses[bus_name].valid():
                LOG.warning("Mapping '%s' is disabled because bus '%s' " % (
                    mapping['mapping'], bus_name) +
                        "is not associated with a CAN controller")
                mapping['enabled'] = False
                if skip_disabled_mappings:
                    continue

            mapping_data = load_json_from_search_path(mapping['mapping'],
                    search_paths)

            commands = mapping_data.get('commands', [])
            if not mapping_enabled:
                for command in commands:
                    command['enabled'] = False
            all_commands.extend(commands)

            if mapping_enabled:
                all_initializers.extend(mapping_data.get('initializers', []))
                all_loopers.extend(mapping_data.get('loopers', []))
                all_extra_sources.update(
                        set(mapping_data.get('extra_sources', set())))

            messages = mapping_data.get('messages', {})
            if len(messages) == 0:
                LOG.warning("Mapping file '%s' doesn't define any messages"
                        % mapping['mapping'])

            if 'database' in mapping:
                database_filename, database_tree = self._parse_database(
                                find_file(mapping['database'], search_paths))
                messages = merge(merge_database_into_mapping(database_filename,
                    database_tree, messages).get('messages', {}), messages)
                if mapping.get('bit_numbering_inverted', None) is None:
                    LOG.warning("The bit number inversion setting is undefined "
                            "for the mapping '%s', but it " % mapping['mapping'] +
                            "is database-backed - assuming inverted")
                    for message in messages.values():
                        message.setdefault('bit_numbering_inverted',
                                True)

            for message_id, message in messages.items():
                message['id'] = message_id
                message.setdefault('bus', bus_name)
                message.setdefault('enabled', mapping_enabled)
            all_messages.extend(messages.values())

        return {'messages': all_messages,
                'commands': all_commands,
                'initializers': all_initializers,
                'extra_sources': all_extra_sources,
                'loopers': all_loopers}
    def _parse_mappings(self, data, search_paths, skip_disabled_mappings):
        all_messages = []
        all_commands = []
        all_extra_sources = set()
        all_initializers = []
        all_loopers = []

        for mapping in data.get('mappings', []):
            if 'mapping' not in mapping:
                fatal_error("Mapping is missing the mapping file path")

            mapping_enabled = mapping.get('enabled', True)
            if not mapping_enabled:
                LOG.warning("Mapping '%s' is disabled" % mapping['mapping'])
                if skip_disabled_mappings:
                    continue

            bus_name = mapping.get('bus', None)
            if bus_name is None:
                LOG.warning("No default bus associated with '%s' mapping" %
                        mapping['mapping'])
            elif bus_name not in self.buses:
                fatal_error("Bus '%s' (from mapping %s) is not defined" %
                        (bus_name, mapping['mapping']))

            mapping_data = load_json_from_search_path(mapping['mapping'],
                    search_paths)

            commands = mapping_data.get('commands', [])
            if not mapping_enabled:
                for command in commands:
                    command['enabled'] = False
            all_commands.extend(commands)

            if mapping_enabled:
                all_initializers.extend(mapping_data.get('initializers', []))
                all_loopers.extend(mapping_data.get('loopers', []))
                all_extra_sources.update(
                        set(mapping_data.get('extra_sources', set())))

            messages = mapping_data.get('messages', [])
            if len(messages) == 0:
                LOG.warning("Mapping file '%s' doesn't define any messages"
                        % mapping['mapping'])

            if 'database' in mapping:
                messages = merge(merge_database_into_mapping(
                                find_file(mapping['database'], search_paths),
                                messages)['messages'],
                            messages)

            for message_id, message in messages.items():
                message['id'] = message_id
                message.setdefault('bus', bus_name)
                message.setdefault('enabled', mapping_enabled)
            all_messages.extend(messages.values())

        return {'messages': all_messages,
                'commands': all_commands,
                'initializers': all_initializers,
                'extra_sources': all_extra_sources,
                'loopers': all_loopers}