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 5# Setup wardmodem package root and other autotest paths. 6import common 7 8import state_machine 9 10class ModemPowerLevelMachine(state_machine.StateMachine): 11 """ 12 The state machine that determines the functionality level of the modem. 13 14 Setting the funtionality to different levels enables/disables various 15 operations one can perform with the modem. 16 17 """ 18 19 def __init__(self, state, transceiver, modem_conf): 20 """ 21 @param state: The GlobalState object shared by all state machines. 22 23 @param transceiver: The ATTransceiver object to interact with. 24 25 @param modem_conf: A ModemConfiguration object containing the 26 configuration data for the current modem. 27 28 """ 29 super(ModemPowerLevelMachine, self).__init__(state, transceiver, 30 modem_conf) 31 32 # Register all wardmodem responses used. 33 self._add_response_function('wm_response_power_level_minimal') 34 self._add_response_function('wm_response_power_level_full') 35 self._add_response_function('wm_response_power_level_low') 36 self._add_response_function('wm_response_power_level_factory_test') 37 self._add_response_function('wm_response_power_level_offline') 38 39 # Load configuration for this state machine. 40 self._allowed_levels = modem_conf.modem_power_level_allowed_levels 41 self._reset_by_default = modem_conf.modem_power_level_reset_by_default 42 43 self._state['power_level'] = modem_conf.modem_power_level_initial_level 44 self._logger.debug(self._tag_with_name('Initialized power level to %s' % 45 self._state['power_level'])) 46 47 48 def get_well_known_name(self): 49 """ Returns the well known name for this machine. """ 50 return 'modem_power_level_machine' 51 52 53 # ########################################################################## 54 # State machine API functions. 55 def soft_reset(self): 56 """ 57 Soft reset the modem. 58 """ 59 # In the future, we might want to simulate a reset by hiding the udev 60 # device exposed to the modemmanager. 61 self._logger.info(self._tag_with_name('Soft reset called.')) 62 pass 63 64 65 def get_current_level(self): 66 """ Return the current power level. """ 67 level = self._state['power_level'] 68 if level == 'MINIMUM': 69 self._respond(self.wm_response_power_level_minimum) 70 elif level == 'FULL': 71 self._respond(self.wm_response_power_level_full) 72 elif level == 'LOW': 73 self._respond(self.wm_response_power_level_low) 74 elif level == 'FACTORY_TEST': 75 self._respond(self.wm_response_power_level_factory_test) 76 elif level == 'OFFLINE': 77 self._respond(self.wm_response_power_level_offline) 78 else: 79 self._raise_runtime_error('Read invalid current power level value ' 80 '|%s|', level) 81 self._respond_ok() 82 83 84 def set_level_minimum(self): 85 """ Set the power level to MINIMUM. """ 86 self._set_level('MINIMUM') 87 self._task_loop.post_task( 88 self._registration_machine().deregister) 89 90 91 def set_level_full(self): 92 """ Set the power level to FULL. """ 93 self._set_level('FULL') 94 if self._state['automatic_registration'] == 'TRUE': 95 self._task_loop.post_task( 96 self._registration_machine().register) 97 98 99 100 def set_level_low(self): 101 """ Set the power level to LOW. """ 102 self._set_level('LOW') 103 self._task_loop.post_task( 104 self._registration_machine().deregister) 105 106 107 # ########################################################################## 108 # Helper functions. 109 def _set_level(self, level, reset_code=None): 110 """ 111 Set the power/functionality level to the specified value. 112 113 @param level: Integer level to set the power to. 114 115 @param reset_code: If '1', a soft reset is called on the device. Default 116 value used is specified in the configuration file. 117 118 """ 119 if reset_code is None: 120 reset = self._reset_by_default 121 elif reset_code not in ['0', '1']: 122 self._raise_runtime_error("Expected reset to be '0' or '1', found " 123 "|%s|" % str(reset)) 124 else: 125 reset = (reset_code == '1') 126 127 if level not in self._allowed_levels: 128 self._respond_error() 129 return 130 131 if reset or level == 'RESET': 132 self.soft_reset() 133 if level == 'FULL': 134 self._update_state({'power_level': level}) 135 elif level == 'LOW' or level == 'MINIMUM': 136 self._update_state({ 137 'power_level': level, 138 'registration_status': 'NOT_REGISTERED', 139 'call_status': 'DISCONNECTED', 140 'level_call': 0}) 141 self._respond_ok() 142 143 144 # ########################################################################## 145 # Helper methods. 146 def _registration_machine(self): 147 # This machine may not have been created when __init__ is executed. 148 # Obtain a fresh handle everytime we want to use it. 149 return self._transceiver.get_state_machine( 150 'network_registration_machine') 151