1451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray# Use of this source code is governed by a BSD-style license that can be
3451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray# found in the LICENSE file.
4451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray
5451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Ugurayimport logging
6c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le
7c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Leimport pm_errors
8451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Ugurayimport state_machine
9451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray
10c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Lefrom autotest_lib.client.cros.cellular import mm1_constants
11c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le
12451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Ugurayclass EnableMachine(state_machine.StateMachine):
135555f62fedfdc36cc8c4911eb24299008d961263Arman Uguray    """
145555f62fedfdc36cc8c4911eb24299008d961263Arman Uguray    EnableMachine handles the state transitions involved in bringing the modem
155555f62fedfdc36cc8c4911eb24299008d961263Arman Uguray    to the ENABLED state.
165555f62fedfdc36cc8c4911eb24299008d961263Arman Uguray
175555f62fedfdc36cc8c4911eb24299008d961263Arman Uguray    """
18e94efecceed2a21d35c7a56b306498b53f0fa68eArman Uguray    def __init__(self, modem, return_cb, raise_cb):
19e94efecceed2a21d35c7a56b306498b53f0fa68eArman Uguray        super(EnableMachine, self).__init__(modem)
20e94efecceed2a21d35c7a56b306498b53f0fa68eArman Uguray        self.return_cb = return_cb
21e94efecceed2a21d35c7a56b306498b53f0fa68eArman Uguray        self.raise_cb = raise_cb
22e94efecceed2a21d35c7a56b306498b53f0fa68eArman Uguray
235555f62fedfdc36cc8c4911eb24299008d961263Arman Uguray
24c43ea562a0447330b26eeec3c7b1fb935958e985Prathmesh Prabhu    def Cancel(self):
25c43ea562a0447330b26eeec3c7b1fb935958e985Prathmesh Prabhu        """ Overriden from superclass. """
26a5b80d9fdb4d8a54bad447d9e78a6e0b6d4c2d23Arman Uguray        logging.info('EnableMachine: Canceling enable.')
27a5b80d9fdb4d8a54bad447d9e78a6e0b6d4c2d23Arman Uguray        super(EnableMachine, self).Cancel()
28c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le        state = self._modem.Get(mm1_constants.I_MODEM, 'State')
29c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le        reason = mm1_constants.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED
30c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le        if state == mm1_constants.MM_MODEM_STATE_ENABLING:
31a5b80d9fdb4d8a54bad447d9e78a6e0b6d4c2d23Arman Uguray            logging.info('EnableMachine: Setting state to DISABLED.')
32c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le            self._modem.ChangeState(mm1_constants.MM_MODEM_STATE_DISABLED,
33c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le                                    reason)
34a5b80d9fdb4d8a54bad447d9e78a6e0b6d4c2d23Arman Uguray        self._modem.enable_step = None
35bcbd42836b870f3e84d851eab4bb64c90cdb6afeArman Uguray        if self.raise_cb:
36c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le            self.raise_cb(pm_errors.MMCoreError(
37c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le                    pm_errors.MMCoreError.CANCELLED, 'Operation cancelled'))
38a5b80d9fdb4d8a54bad447d9e78a6e0b6d4c2d23Arman Uguray
39c43ea562a0447330b26eeec3c7b1fb935958e985Prathmesh Prabhu
40451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray    def _HandleDisabledState(self):
41451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        assert self._modem.disable_step is None
42451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        assert self._modem.disconnect_step is None
433ecbf9e5d6b26e75b59f7f631fae9e6150f6e936Arman Uguray        logging.info('EnableMachine: Setting power state to ON')
44c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le        self._modem.SetUInt32(mm1_constants.I_MODEM, 'PowerState',
45c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le                              mm1_constants.MM_MODEM_POWER_STATE_ON)
46451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        logging.info('EnableMachine: Setting state to ENABLING')
47c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le        reason = mm1_constants.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED
48c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le        self._modem.ChangeState(mm1_constants.MM_MODEM_STATE_ENABLING, reason)
49451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        return True
50451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray
51c43ea562a0447330b26eeec3c7b1fb935958e985Prathmesh Prabhu
52451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray    def _HandleEnablingState(self):
53451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        assert self._modem.disable_step is None
54451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        assert self._modem.disconnect_step is None
55451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        logging.info('EnableMachine: Setting state to ENABLED.')
56c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le        reason = mm1_constants.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED
57c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le        self._modem.ChangeState(mm1_constants.MM_MODEM_STATE_ENABLED, reason)
58451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        return True
59451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray
60c43ea562a0447330b26eeec3c7b1fb935958e985Prathmesh Prabhu
61451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray    def _HandleEnabledState(self):
62451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        assert self._modem.disable_step is None
63451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        assert self._modem.disconnect_step is None
64451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        logging.info('EnableMachine: Searching for networks.')
65451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        self._modem.enable_step = None
66e94efecceed2a21d35c7a56b306498b53f0fa68eArman Uguray        if self.return_cb:
67e94efecceed2a21d35c7a56b306498b53f0fa68eArman Uguray            self.return_cb()
68451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        self._modem.RegisterWithNetwork()
69451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        return False
70451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray
71c43ea562a0447330b26eeec3c7b1fb935958e985Prathmesh Prabhu
72451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray    def _GetModemStateFunctionMap(self):
73451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        return {
74c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le            mm1_constants.MM_MODEM_STATE_DISABLED:
75c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le                    EnableMachine._HandleDisabledState,
76c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le            mm1_constants.MM_MODEM_STATE_ENABLING:
77c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le                    EnableMachine._HandleEnablingState,
78c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le            mm1_constants.MM_MODEM_STATE_ENABLED:
79c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le                    EnableMachine._HandleEnabledState
80451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        }
81451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray
82c43ea562a0447330b26eeec3c7b1fb935958e985Prathmesh Prabhu
83451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray    def _ShouldStartStateMachine(self):
84c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le        state = self._modem.Get(mm1_constants.I_MODEM, 'State')
8533b35f950ee30c7bd5e969b73d00239aefa7ea63Arman Uguray        # Return success if already enabled.
86c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le        if state >= mm1_constants.MM_MODEM_STATE_ENABLED:
8733b35f950ee30c7bd5e969b73d00239aefa7ea63Arman Uguray            logging.info('Modem is already enabled. Nothing to do.')
8833b35f950ee30c7bd5e969b73d00239aefa7ea63Arman Uguray            if self.return_cb:
8933b35f950ee30c7bd5e969b73d00239aefa7ea63Arman Uguray                self.return_cb()
9033b35f950ee30c7bd5e969b73d00239aefa7ea63Arman Uguray            return False
91451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        if self._modem.enable_step and self._modem.enable_step != self:
92451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray            # There is already an enable operation in progress.
93b718932651a1f46e975d3a8aff3fae20c838bcbcArman Uguray            # Note: ModemManager currently returns "WrongState" for this case.
94b718932651a1f46e975d3a8aff3fae20c838bcbcArman Uguray            # The API suggests that "InProgress" should be returned, so that's
95b718932651a1f46e975d3a8aff3fae20c838bcbcArman Uguray            # what we do here.
96c45d1da740fbeeacedc7a1e605a3cc6d7505203eArman Uguray            logging.error('There is already an ongoing enable operation')
97c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le            if state == mm1_constants.MM_MODEM_STATE_ENABLING:
98451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray                message = 'Modem enable already in progress.'
99451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray            else:
100451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray                message = 'Modem enable has already been initiated' \
101451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray                          ', ignoring.'
102c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le            raise pm_errors.MMCoreError(pm_errors.MMCoreError.IN_PROGRESS,
103c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le                                        message)
104451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        elif self._modem.enable_step is None:
105451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray            # There is no enable operation going on, cancelled or otherwise.
106c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le            if state != mm1_constants.MM_MODEM_STATE_DISABLED:
107451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray                message = 'Modem cannot be enabled if not in the DISABLED' \
108451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray                          ' state.'
109c45d1da740fbeeacedc7a1e605a3cc6d7505203eArman Uguray                logging.error(message)
110c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le                raise pm_errors.MMCoreError(pm_errors.MMCoreError.WRONG_STATE,
111c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le                                            message)
112451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray            logging.info('Starting Enable')
113451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray            self._modem.enable_step = self
114451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray        return True
115