Home | History | Annotate | Download | only in pseudomodem
      1 # Copyright (c) 2012 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 import logging
      6 
      7 import pm_errors
      8 import state_machine
      9 
     10 from autotest_lib.client.cros.cellular import mm1_constants
     11 
     12 class EnableMachine(state_machine.StateMachine):
     13     """
     14     EnableMachine handles the state transitions involved in bringing the modem
     15     to the ENABLED state.
     16 
     17     """
     18     def __init__(self, modem, return_cb, raise_cb):
     19         super(EnableMachine, self).__init__(modem)
     20         self.return_cb = return_cb
     21         self.raise_cb = raise_cb
     22 
     23 
     24     def Cancel(self):
     25         """ Overriden from superclass. """
     26         logging.info('EnableMachine: Canceling enable.')
     27         super(EnableMachine, self).Cancel()
     28         state = self._modem.Get(mm1_constants.I_MODEM, 'State')
     29         reason = mm1_constants.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED
     30         if state == mm1_constants.MM_MODEM_STATE_ENABLING:
     31             logging.info('EnableMachine: Setting state to DISABLED.')
     32             self._modem.ChangeState(mm1_constants.MM_MODEM_STATE_DISABLED,
     33                                     reason)
     34         self._modem.enable_step = None
     35         if self.raise_cb:
     36             self.raise_cb(pm_errors.MMCoreError(
     37                     pm_errors.MMCoreError.CANCELLED, 'Operation cancelled'))
     38 
     39 
     40     def _HandleDisabledState(self):
     41         assert self._modem.disable_step is None
     42         assert self._modem.disconnect_step is None
     43         logging.info('EnableMachine: Setting power state to ON')
     44         self._modem.SetUInt32(mm1_constants.I_MODEM, 'PowerState',
     45                               mm1_constants.MM_MODEM_POWER_STATE_ON)
     46         logging.info('EnableMachine: Setting state to ENABLING')
     47         reason = mm1_constants.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED
     48         self._modem.ChangeState(mm1_constants.MM_MODEM_STATE_ENABLING, reason)
     49         return True
     50 
     51 
     52     def _HandleEnablingState(self):
     53         assert self._modem.disable_step is None
     54         assert self._modem.disconnect_step is None
     55         logging.info('EnableMachine: Setting state to ENABLED.')
     56         reason = mm1_constants.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED
     57         self._modem.ChangeState(mm1_constants.MM_MODEM_STATE_ENABLED, reason)
     58         return True
     59 
     60 
     61     def _HandleEnabledState(self):
     62         assert self._modem.disable_step is None
     63         assert self._modem.disconnect_step is None
     64         logging.info('EnableMachine: Searching for networks.')
     65         self._modem.enable_step = None
     66         if self.return_cb:
     67             self.return_cb()
     68         self._modem.RegisterWithNetwork()
     69         return False
     70 
     71 
     72     def _GetModemStateFunctionMap(self):
     73         return {
     74             mm1_constants.MM_MODEM_STATE_DISABLED:
     75                     EnableMachine._HandleDisabledState,
     76             mm1_constants.MM_MODEM_STATE_ENABLING:
     77                     EnableMachine._HandleEnablingState,
     78             mm1_constants.MM_MODEM_STATE_ENABLED:
     79                     EnableMachine._HandleEnabledState
     80         }
     81 
     82 
     83     def _ShouldStartStateMachine(self):
     84         state = self._modem.Get(mm1_constants.I_MODEM, 'State')
     85         # Return success if already enabled.
     86         if state >= mm1_constants.MM_MODEM_STATE_ENABLED:
     87             logging.info('Modem is already enabled. Nothing to do.')
     88             if self.return_cb:
     89                 self.return_cb()
     90             return False
     91         if self._modem.enable_step and self._modem.enable_step != self:
     92             # There is already an enable operation in progress.
     93             # Note: ModemManager currently returns "WrongState" for this case.
     94             # The API suggests that "InProgress" should be returned, so that's
     95             # what we do here.
     96             logging.error('There is already an ongoing enable operation')
     97             if state == mm1_constants.MM_MODEM_STATE_ENABLING:
     98                 message = 'Modem enable already in progress.'
     99             else:
    100                 message = 'Modem enable has already been initiated' \
    101                           ', ignoring.'
    102             raise pm_errors.MMCoreError(pm_errors.MMCoreError.IN_PROGRESS,
    103                                         message)
    104         elif self._modem.enable_step is None:
    105             # There is no enable operation going on, cancelled or otherwise.
    106             if state != mm1_constants.MM_MODEM_STATE_DISABLED:
    107                 message = 'Modem cannot be enabled if not in the DISABLED' \
    108                           ' state.'
    109                 logging.error(message)
    110                 raise pm_errors.MMCoreError(pm_errors.MMCoreError.WRONG_STATE,
    111                                             message)
    112             logging.info('Starting Enable')
    113             self._modem.enable_step = self
    114         return True
    115