disable_machine.py revision e94efecceed2a21d35c7a56b306498b53f0fa68e
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 6import mm1 7import state_machine 8 9class DisableMachine(state_machine.StateMachine): 10 def __init__(self, modem, return_cb, raise_cb): 11 super(DisableMachine, self).__init__(modem) 12 self.return_cb = return_cb 13 self.raise_cb = raise_cb 14 15 def _HandleConnectedState(self): 16 logging.info('DisableMachine: Modem is CONNECTED.') 17 assert self._modem.connect_step is None 18 # TODO(armansito): Pass a different raise_cb here to handle 19 # disconnect failure 20 logging.info('DisableMachine: Starting Disconnect.') 21 self._modem.Disconnect( 22 mm1.ROOT_PATH, DisableMachine.Step, DisableMachine.Step, self) 23 return True 24 25 def _HandleConnectingState(self): 26 logging.info('DisableMachine: Modem is CONNECTING.') 27 assert self._modem.connect_step 28 logging.info('DisableMachine: Canceling connect.') 29 self._modem.connect_step.Cancel() 30 return True 31 32 def _HandleDisconnectingState(self): 33 logging.info('DisableMachine: Modem is DISCONNECTING.') 34 assert self._modem.disconnect_step 35 logging.info('DisableMachine: Waiting for disconnect.') 36 # wait until disconnect ends 37 return True 38 39 def _HandleRegisteredState(self): 40 logging.info('DisableMachine: Modem is REGISTERED.') 41 assert not self._modem.IsPendingRegister() 42 assert not self._modem.IsPendingEnable() 43 assert not self._modem.IsPendingConnect() 44 assert not self._modem.IsPendingDisconnect() 45 self._modem.UnregisterWithNetwork() 46 logging.info('DisableMachine: Setting state to DISABLING.') 47 reason = mm1.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED 48 self._modem.ChangeState(mm1.MM_MODEM_STATE_DISABLING, reason) 49 return True 50 51 def _HandleSearchingState(self): 52 logging.info('DisableMachine: Modem is SEARCHING.') 53 assert self._modem.register_step 54 assert not self._modem.IsPendingEnable() 55 assert not self._modem.IsPendingConnect() 56 logging.info('DisableMachine: Canceling register.') 57 self._modem.register_step.Cancel() 58 return True 59 60 def _HandleEnabledState(self): 61 logging.info('DisableMachine: Modem is ENABLED.') 62 assert not self._modem.IsPendingRegister() 63 assert not self._modem.IsPendingEnable() 64 assert not self._modem.IsPendingConnect() 65 logging.info('DisableMachine: Setting state to DISABLING.') 66 reason = mm1.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED 67 self._modem.ChangeState(mm1.MM_MODEM_STATE_DISABLING, reason) 68 return True 69 70 def _HandleDisablingState(self): 71 logging.info('DisableMachine: Modem is DISABLING.') 72 assert not self._modem.IsPendingRegister() 73 assert not self._modem.IsPendingEnable() 74 assert not self._modem.IsPendingConnect() 75 assert not self._modem.IsPendingDisconnect() 76 logging.info('DisableMachine: Setting state to DISABLED.') 77 reason = mm1.MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED 78 self._modem.ChangeState(mm1.MM_MODEM_STATE_DISABLED, reason) 79 self._modem.disable_step = None 80 if self.return_cb: 81 self.return_cb() 82 return False 83 84 def _GetModemStateFunctionMap(self): 85 return { 86 mm1.MM_MODEM_STATE_CONNECTED: DisableMachine._HandleConnectedState, 87 mm1.MM_MODEM_STATE_CONNECTING: \ 88 DisableMachine._HandleConnectingState, 89 mm1.MM_MODEM_STATE_DISCONNECTING: \ 90 DisableMachine._HandleDisconnectingState, 91 mm1.MM_MODEM_STATE_REGISTERED: \ 92 DisableMachine._HandleRegisteredState, 93 mm1.MM_MODEM_STATE_SEARCHING: DisableMachine._HandleSearchingState, 94 mm1.MM_MODEM_STATE_ENABLED: DisableMachine._HandleEnabledState, 95 mm1.MM_MODEM_STATE_DISABLING: DisableMachine._HandleDisablingState 96 } 97 98 def _ShouldStartStateMachine(self): 99 if self._modem.disable_step and self._modem.disable_step != self: 100 # There is already a disable operation in progress. 101 message = 'Modem disable already in progress.' 102 logging.info(message) 103 raise mm1.MMCoreError(mm1.MMCoreError.IN_PROGRESS, message) 104 elif self._modem.disable_step is None: 105 # There is no disable operation going in, cancelled or otherwise. 106 state = self._modem.Get(mm1.I_MODEM, 'State') 107 if state == mm1.MM_MODEM_STATE_DISABLED: 108 # The reason we're not raising an error here is that 109 # shill will make multiple successive calls to disable 110 # but WON'T check for raised errors, which causes 111 # problems. Treat this particular case as success. 112 logging.info('Already in a disabled state. Ignoring.') 113 if self.return_cb: 114 self.return_cb() 115 return False 116 117 invalid_states = [ 118 mm1.MM_MODEM_STATE_FAILED, 119 mm1.MM_MODEM_STATE_UNKNOWN, 120 mm1.MM_MODEM_STATE_INITIALIZING, 121 mm1.MM_MODEM_STATE_LOCKED 122 ] 123 if state in invalid_states: 124 raise mm1.MMCoreError( 125 mm1.MMCoreError.WRONG_STATE, 126 ('Modem disable cannot be initiated while in state' 127 ' %u.') % state) 128 if self._modem.enable_step: 129 # This needs to be done here, because the case where an enable 130 # cycle has been initiated but it hasn't triggered any state 131 # transitions yet would not be detected in a state handler. 132 logging.info('There is an ongoing Enable, canceling it.') 133 self._modem.enable_step.Cancel() 134 if self._modem.connect_step: 135 logging.info('There is an ongoing Connect, canceling it.') 136 self._modem.connect_step.Cancel() 137 138 logging.info('Starting Disable.') 139 self._modem.disable_step = self 140 return True 141