| # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import logging |
| import os |
| import pprint |
| import sys |
| |
| import wardmodem_exceptions as wme |
| |
| CONF_DIR_NAME = 'configurations' |
| DEFAULT_CONF_FILE = 'base.conf' |
| MODEM_CONF_FILE = { |
| 'e362': 'e362.conf', |
| } |
| |
| class ModemConfiguration(object): |
| """ |
| All modem specific configuration needed by WardModem. |
| |
| This class serves the dual purpose of loading the configuration data needed |
| by different parts of wardmodem in a single place, and providing |
| documentation regarding the configuration parameters available in the file. |
| |
| """ |
| |
| def __init__(self, modem=None): |
| """ |
| @param modem The modem for which the configuration needs to be loaded. |
| |modem| can be None. In that case, only the configuration for |
| the base modem is loaded. |
| Otherwise, |modem| must be a key in |MODEM_CONF_FILE|. |
| """ |
| self._logger = logging.getLogger(__name__) |
| |
| if modem and modem not in MODEM_CONF_FILE: |
| raise wme.WardModemSetupException('Unknown modem: |%s|' % modem) |
| |
| # TODO(pprabhu) Figure out if it makes sense to use Configurable to |
| # (de)serialize configuration. See crbug.com/252475 |
| # First load the default configuration |
| self._logger.info('Loading basic configuration.') |
| self.base_conf = self._load_conf(DEFAULT_CONF_FILE) |
| self._logger.debug('Basic configuration:\n%s', |
| pprint.pformat(self.base_conf)) |
| |
| # Now load the plugin conf data. |
| self.plugin_conf = {} |
| if modem: |
| self._logger.info('Loading modem specific configuration for modem ' |
| '|%s|', modem) |
| self.plugin_conf = self._load_conf(MODEM_CONF_FILE[modem]) |
| self._logger.debug('Plugin configuration:\n%s', |
| pprint.pformat(self.plugin_conf)) |
| |
| self._populate_config() |
| |
| |
| def _populate_config(self): |
| """ |
| Assign configuration data loaded into self variable for easy access. |
| |
| """ |
| # The basic map from AT commands to wardmodem actions common to all |
| # modems. |
| self.base_at_to_wm_action_map = self.base_conf['at_to_wm_action_map'] |
| |
| # The map from AT commands to wardmodem actions specific to the current |
| # modem. |
| self.plugin_at_to_wm_action_map = ( |
| self.plugin_conf.get('at_to_wm_action_map', {})) |
| |
| # The basic map from wardmodem responses to AT commands common to all |
| # modems. |
| self.base_wm_response_to_at_map = ( |
| self.base_conf['wm_response_to_at_map']) |
| |
| # The map from wardmodem responses to AT commands specific to the |
| # current modem. |
| self.plugin_wm_response_to_at_map = ( |
| self.plugin_conf.get('wm_response_to_at_map', {})) |
| |
| # State-less request response map. |
| self.base_wm_request_response_map = ( |
| self.base_conf.get('wm_request_response_map', {})) |
| self.plugin_wm_request_response_map = ( |
| self.plugin_conf.get('wm_request_response_map', {})) |
| |
| # The state machines loaded by all modems. |
| self.base_state_machines = self.base_conf['state_machines'] |
| |
| # The state machines specific to the current modem. |
| self.plugin_state_machines = self.plugin_conf.get('state_machines', []) |
| |
| # The fallback state machine for unmatched AT commands. |
| self._load_variable('fallback_machine', strict=False, default='') |
| self._load_variable('fallback_function', strict=False, default='') |
| |
| |
| # The modemmanager plugin to be used for the modem. |
| self._load_variable('mm_plugin') |
| |
| # The string to be prepended to all AT commands from modemmanager to |
| # modem. |
| self._load_variable('mm_to_modem_at_prefix') |
| |
| # The string to be appended to all AT commands from modemmanager to |
| # modem. |
| self._load_variable('mm_to_modem_at_suffix') |
| |
| # The string to be prepended to all AT commands from modem to |
| # modemmanager. |
| self._load_variable('modem_to_mm_at_prefix') |
| |
| # The string to be appended to all AT commands from modem to |
| # modemmanager. |
| self._load_variable('modem_to_mm_at_suffix') |
| |
| # ###################################################################### |
| # Configuration data for various state machines. |
| self._load_variable('modem_power_level_allowed_levels') |
| self._load_variable('modem_power_level_initial_level') |
| self._load_variable('modem_power_level_reset_by_default') |
| |
| self._load_variable('network_identity_default_mcc') |
| self._load_variable('network_identity_default_mnc') |
| self._load_variable('network_identity_default_msin') |
| self._load_variable('network_identity_default_mdn') |
| |
| self._load_variable('network_operators') |
| self._load_variable('network_operator_default_index') |
| |
| self._load_variable('level_indicators_items') |
| self._load_variable('level_indicators_defaults') |
| |
| |
| def _load_variable(self, varname, strict=True, default=None): |
| """ |
| Load a variable from the configuration files. |
| |
| Implement the most common way of loading variables from configuration. |
| |
| @param varname: The name of the variable to load. |
| |
| @param strict: If True, we expect some value to be available. |
| |
| @param default: Value to assign if none can be loaded. Only makes sense |
| when |strint| is False. |
| |
| """ |
| if strict: |
| value = self.plugin_conf.get(varname, self.base_conf[varname]) |
| else: |
| value = self.plugin_conf.get(varname, |
| self.base_conf.get(varname, default)) |
| setattr(self, varname, value) |
| |
| |
| def _load_conf(self, conf_file): |
| """ |
| Load the configuration data from file. |
| |
| @param conf_file Name of the file to load from. |
| |
| @return The conf data loaded from file. |
| |
| """ |
| # The configuration file is an executable python file. Since the file |
| # name is known only at run-time, we must find the module directory and |
| # manually point execfile to the directory for loading the configuration |
| # file. |
| current_module = sys.modules[__name__] |
| dir_name = os.path.dirname(current_module.__file__) |
| full_path = os.path.join(dir_name, CONF_DIR_NAME, conf_file) |
| conf = {} |
| execfile(full_path, conf) |
| # These entries added by execfile are a nuisance in pprint'ing |
| del conf['__builtins__'] |
| return conf |