• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5import logging
6
7import pm_errors
8import state_machine
9
10from autotest_lib.client.cros.cellular import mm1_constants
11
12class 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