xref: /aosp_15_r20/external/autotest/client/cros/cellular/pseudomodem/cdma_activate_machine.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
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
5import logging
6
7import common
8
9# AU tests use ToT client code, but ToT -3 client version.
10try:
11    from gi.repository import GObject
12except ImportError:
13    import gobject as GObject
14from . import pm_errors
15from . import state_machine
16
17from autotest_lib.client.cros.cellular import mm1_constants
18
19class CdmaActivateMachine(state_machine.StateMachine):
20    """
21    CdmaActivationMachine implements the asynchronous state updates for a fake
22    OTASP "automatic activation".
23
24    """
25    def __init__(self, modem, return_cb, raise_cb):
26        super(CdmaActivateMachine, self).__init__(modem)
27        self._return_cb = return_cb
28        self._raise_cb = raise_cb
29        self._step_delay = 1
30
31
32    def Cancel(self, message='Activation canceled.'):
33        """ Cancel the CdmaActivateMachine. """
34        logging.info('CdmaActivateMachine: Canceling activate.')
35        super(CdmaActivateMachine, self).Cancel()
36        state = self._modem.Get(mm1_constants.I_MODEM_CDMA, 'ActivationState')
37
38        # If activated, return success.
39        if state == mm1_constants.MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED:
40            logging.info('CdmaActivateMachine: Already activated. '
41                         'Returning success.')
42            if self._return_cb:
43                self._return_cb()
44            return
45
46        self._modem.ChangeActivationState(
47            mm1_constants.MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED,
48            pm_errors.MMCdmaActivationError.UNKNOWN)
49
50        self._modem.cdma_activate_step = None
51
52        if self._raise_cb:
53            self._raise_cb(
54                pm_errors.MMCoreError(pm_errors.MMCoreError.CANCELLED, message))
55
56
57    def _GetDefaultHandler(self):
58        return CdmaActivateMachine._HandleInvalidState
59
60
61    def _ScheduleNextStep(self):
62        def _DelayedStep():
63            self.Step()
64            return False
65        GObject.timeout_add(self._step_delay * 1000, _DelayedStep)
66
67    def _HandleInvalidState(self):
68        state = self._modem.Get(mm1_constants.I_MODEM, 'State')
69        message = 'Modem transitioned to invalid state: ' + \
70            mm1_constants.ModemStateToString(state)
71        logging.info('CdmaActivateMachine: ' + message)
72        self.Cancel(message)
73        return False
74
75
76    def _StepFunction(self):
77        state = self._modem.Get(mm1_constants.I_MODEM_CDMA, 'ActivationState')
78        if state == mm1_constants.MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED:
79            return self._HandleNotActivated()
80        if state == mm1_constants.MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING:
81            return self._HandleActivating()
82        message = 'Modem is in invalid activation state: ' + state
83        logging.error(message)
84        self.Cancel(message)
85        return False
86
87
88    def _HandleNotActivated(self):
89        logging.info('CdmaActivationMachine: Modem is NOT_ACTIVATED.')
90        logging.info('CdmaActivationMachine: Setting state to ACTIVATING')
91        self._modem.ChangeActivationState(
92            mm1_constants.MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING,
93            pm_errors.MMCdmaActivationError.NONE)
94
95        # Make the modem reset after 5 seconds.
96        self._step_delay = 5
97        return True
98
99
100    def _HandleActivating(self):
101        logging.info('CdmaActivationMachine: Modem is ACTIVATING.')
102        logging.info('CdmaActivationMachine: Resetting modem.')
103        self._modem.ChangeActivationState(
104            mm1_constants.MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED,
105            pm_errors.MMCdmaActivationError.NONE)
106        self._modem.Reset()
107        self._modem.cdma_activate_step = None
108        if self._return_cb:
109            self._return_cb()
110        return False
111
112
113    def _GetModemStateFunctionMap(self):
114        return {
115            mm1_constants.MM_MODEM_STATE_REGISTERED:
116                CdmaActivateMachine._StepFunction
117        }
118
119
120    def _ShouldStartStateMachine(self):
121        if self._modem.cdma_activate_step and \
122            self._modem.cdma_activate_step != self:
123            # There is already an activate operation in progress.
124            logging.error('There is already an ongoing activate operation.')
125            raise pm_errors.MMCoreError(pm_errors.MMCoreError.IN_PROGRESS,
126                                        "Activation already in progress.")
127
128
129        if self._modem.cdma_activate_step is None:
130            # There is no activate operation going on, cancelled or otherwise.
131            state = self._modem.Get(mm1_constants.I_MODEM_CDMA,
132                                    'ActivationState')
133            if (state !=
134                mm1_constants.MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED):
135                message = "Modem is not in state 'NOT_ACTIVATED'."
136                logging.error(message)
137                raise pm_errors.MMCoreError(pm_errors.MMCoreError.WRONG_STATE,
138                                            message)
139
140            state = self._modem.Get(mm1_constants.I_MODEM, 'State')
141            if state != mm1_constants.MM_MODEM_STATE_REGISTERED:
142                message = 'Modem cannot be activated if not in the ' \
143                          'REGISTERED state.'
144                logging.error(message)
145                raise pm_errors.MMCoreError(pm_errors.MMCoreError.WRONG_STATE,
146                                            message)
147
148            self._modem.cdma_activate_step = self
149        return True
150