1# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6import os 7import pprint 8import sys 9 10import wardmodem_exceptions as wme 11 12CONF_DIR_NAME = 'configurations' 13DEFAULT_CONF_FILE = 'base.conf' 14MODEM_CONF_FILE = { 15 'e362': 'e362.conf', 16} 17 18class ModemConfiguration(object): 19 """ 20 All modem specific configuration needed by WardModem. 21 22 This class serves the dual purpose of loading the configuration data needed 23 by different parts of wardmodem in a single place, and providing 24 documentation regarding the configuration parameters available in the file. 25 26 """ 27 28 def __init__(self, modem=None): 29 """ 30 @param modem The modem for which the configuration needs to be loaded. 31 |modem| can be None. In that case, only the configuration for 32 the base modem is loaded. 33 Otherwise, |modem| must be a key in |MODEM_CONF_FILE|. 34 """ 35 self._logger = logging.getLogger(__name__) 36 37 if modem and modem not in MODEM_CONF_FILE: 38 raise wme.WardModemSetupException('Unknown modem: |%s|' % modem) 39 40 # TODO(pprabhu) Figure out if it makes sense to use Configurable to 41 # (de)serialize configuration. See crbug.com/252475 42 # First load the default configuration 43 self._logger.info('Loading basic configuration.') 44 self.base_conf = self._load_conf(DEFAULT_CONF_FILE) 45 self._logger.debug('Basic configuration:\n%s', 46 pprint.pformat(self.base_conf)) 47 48 # Now load the plugin conf data. 49 self.plugin_conf = {} 50 if modem: 51 self._logger.info('Loading modem specific configuration for modem ' 52 '|%s|', modem) 53 self.plugin_conf = self._load_conf(MODEM_CONF_FILE[modem]) 54 self._logger.debug('Plugin configuration:\n%s', 55 pprint.pformat(self.plugin_conf)) 56 57 self._populate_config() 58 59 60 def _populate_config(self): 61 """ 62 Assign configuration data loaded into self variable for easy access. 63 64 """ 65 # The basic map from AT commands to wardmodem actions common to all 66 # modems. 67 self.base_at_to_wm_action_map = self.base_conf['at_to_wm_action_map'] 68 69 # The map from AT commands to wardmodem actions specific to the current 70 # modem. 71 self.plugin_at_to_wm_action_map = ( 72 self.plugin_conf.get('at_to_wm_action_map', {})) 73 74 # The basic map from wardmodem responses to AT commands common to all 75 # modems. 76 self.base_wm_response_to_at_map = ( 77 self.base_conf['wm_response_to_at_map']) 78 79 # The map from wardmodem responses to AT commands specific to the 80 # current modem. 81 self.plugin_wm_response_to_at_map = ( 82 self.plugin_conf.get('wm_response_to_at_map', {})) 83 84 # State-less request response map. 85 self.base_wm_request_response_map = ( 86 self.base_conf.get('wm_request_response_map', {})) 87 self.plugin_wm_request_response_map = ( 88 self.plugin_conf.get('wm_request_response_map', {})) 89 90 # The state machines loaded by all modems. 91 self.base_state_machines = self.base_conf['state_machines'] 92 93 # The state machines specific to the current modem. 94 self.plugin_state_machines = self.plugin_conf.get('state_machines', []) 95 96 # The fallback state machine for unmatched AT commands. 97 self._load_variable('fallback_machine', strict=False, default='') 98 self._load_variable('fallback_function', strict=False, default='') 99 100 101 # The modemmanager plugin to be used for the modem. 102 self._load_variable('mm_plugin') 103 104 # The string to be prepended to all AT commands from modemmanager to 105 # modem. 106 self._load_variable('mm_to_modem_at_prefix') 107 108 # The string to be appended to all AT commands from modemmanager to 109 # modem. 110 self._load_variable('mm_to_modem_at_suffix') 111 112 # The string to be prepended to all AT commands from modem to 113 # modemmanager. 114 self._load_variable('modem_to_mm_at_prefix') 115 116 # The string to be appended to all AT commands from modem to 117 # modemmanager. 118 self._load_variable('modem_to_mm_at_suffix') 119 120 # ###################################################################### 121 # Configuration data for various state machines. 122 self._load_variable('modem_power_level_allowed_levels') 123 self._load_variable('modem_power_level_initial_level') 124 self._load_variable('modem_power_level_reset_by_default') 125 126 self._load_variable('network_identity_default_mcc') 127 self._load_variable('network_identity_default_mnc') 128 self._load_variable('network_identity_default_msin') 129 self._load_variable('network_identity_default_mdn') 130 131 self._load_variable('network_operators') 132 self._load_variable('network_operator_default_index') 133 134 self._load_variable('level_indicators_items') 135 self._load_variable('level_indicators_defaults') 136 137 138 def _load_variable(self, varname, strict=True, default=None): 139 """ 140 Load a variable from the configuration files. 141 142 Implement the most common way of loading variables from configuration. 143 144 @param varname: The name of the variable to load. 145 146 @param strict: If True, we expect some value to be available. 147 148 @param default: Value to assign if none can be loaded. Only makes sense 149 when |strint| is False. 150 151 """ 152 if strict: 153 value = self.plugin_conf.get(varname, self.base_conf[varname]) 154 else: 155 value = self.plugin_conf.get(varname, 156 self.base_conf.get(varname, default)) 157 setattr(self, varname, value) 158 159 160 def _load_conf(self, conf_file): 161 """ 162 Load the configuration data from file. 163 164 @param conf_file Name of the file to load from. 165 166 @return The conf data loaded from file. 167 168 """ 169 # The configuration file is an executable python file. Since the file 170 # name is known only at run-time, we must find the module directory and 171 # manually point execfile to the directory for loading the configuration 172 # file. 173 current_module = sys.modules[__name__] 174 dir_name = os.path.dirname(current_module.__file__) 175 full_path = os.path.join(dir_name, CONF_DIR_NAME, conf_file) 176 conf = {} 177 execfile(full_path, conf) 178 # These entries added by execfile are a nuisance in pprint'ing 179 del conf['__builtins__'] 180 return conf 181