# Copyright (c) 2012 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 pm_errors import state_machine from autotest_lib.client.cros.cellular import mm1_constants class EnableMachine(state_machine.StateMachine): """ EnableMachine handles the state transitions involved in bringing the modem to the ENABLED state. """ def __init__(self, modem, return_cb, raise_cb): super(EnableMachine, self).__init__(modem) self.return_cb = return_cb self.raise_cb = raise_cb def Cancel(self): """ Overriden from superclass. """ logging.info('EnableMachine: Canceling enable.') super(EnableMachine, self).Cancel() state = self._modem.Get(mm1_constants.I_MODEM, 'State') reason = mm1_constants.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED if state == mm1_constants.MM_MODEM_STATE_ENABLING: logging.info('EnableMachine: Setting state to DISABLED.') self._modem.ChangeState(mm1_constants.MM_MODEM_STATE_DISABLED, reason) self._modem.enable_step = None if self.raise_cb: self.raise_cb(pm_errors.MMCoreError( pm_errors.MMCoreError.CANCELLED, 'Operation cancelled')) def _HandleDisabledState(self): assert self._modem.disable_step is None assert self._modem.disconnect_step is None logging.info('EnableMachine: Setting power state to ON') self._modem.SetUInt32(mm1_constants.I_MODEM, 'PowerState', mm1_constants.MM_MODEM_POWER_STATE_ON) logging.info('EnableMachine: Setting state to ENABLING') reason = mm1_constants.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED self._modem.ChangeState(mm1_constants.MM_MODEM_STATE_ENABLING, reason) return True def _HandleEnablingState(self): assert self._modem.disable_step is None assert self._modem.disconnect_step is None logging.info('EnableMachine: Setting state to ENABLED.') reason = mm1_constants.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED self._modem.ChangeState(mm1_constants.MM_MODEM_STATE_ENABLED, reason) return True def _HandleEnabledState(self): assert self._modem.disable_step is None assert self._modem.disconnect_step is None logging.info('EnableMachine: Searching for networks.') self._modem.enable_step = None if self.return_cb: self.return_cb() self._modem.RegisterWithNetwork() return False def _GetModemStateFunctionMap(self): return { mm1_constants.MM_MODEM_STATE_DISABLED: EnableMachine._HandleDisabledState, mm1_constants.MM_MODEM_STATE_ENABLING: EnableMachine._HandleEnablingState, mm1_constants.MM_MODEM_STATE_ENABLED: EnableMachine._HandleEnabledState } def _ShouldStartStateMachine(self): state = self._modem.Get(mm1_constants.I_MODEM, 'State') # Return success if already enabled. if state >= mm1_constants.MM_MODEM_STATE_ENABLED: logging.info('Modem is already enabled. Nothing to do.') if self.return_cb: self.return_cb() return False if self._modem.enable_step and self._modem.enable_step != self: # There is already an enable operation in progress. # Note: ModemManager currently returns "WrongState" for this case. # The API suggests that "InProgress" should be returned, so that's # what we do here. logging.error('There is already an ongoing enable operation') if state == mm1_constants.MM_MODEM_STATE_ENABLING: message = 'Modem enable already in progress.' else: message = 'Modem enable has already been initiated' \ ', ignoring.' raise pm_errors.MMCoreError(pm_errors.MMCoreError.IN_PROGRESS, message) elif self._modem.enable_step is None: # There is no enable operation going on, cancelled or otherwise. if state != mm1_constants.MM_MODEM_STATE_DISABLED: message = 'Modem cannot be enabled if not in the DISABLED' \ ' state.' logging.error(message) raise pm_errors.MMCoreError(pm_errors.MMCoreError.WRONG_STATE, message) logging.info('Starting Enable') self._modem.enable_step = self return True