1155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/* 2155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Copyright (C) 2010 The Android Open Source Project 3155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * 4155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Licensed under the Apache License, Version 2.0 (the "License"); 5155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * you may not use this file except in compliance with the License. 6155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * You may obtain a copy of the License at 7155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * 8155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * http://www.apache.org/licenses/LICENSE-2.0 9155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * 10155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Unless required by applicable law or agreed to in writing, software 11155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * distributed under the License is distributed on an "AS IS" BASIS, 12155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * See the License for the specific language governing permissions and 14155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * limitations under the License. 15155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 16155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 17155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandepackage com.android.server.wifi; 18155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 19155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.Context; 20155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.content.Intent; 21155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.SupplicantState; 22155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.WifiConfiguration; 23155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.net.wifi.WifiManager; 24eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpandeimport android.os.BatteryStats; 25155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Handler; 26155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Message; 27155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.Parcelable; 28eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpandeimport android.os.RemoteException; 29eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpandeimport android.os.ServiceManager; 30155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.os.UserHandle; 31155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.util.Log; 32eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpandeimport android.util.Slog; 33eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpande 34eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpandeimport com.android.internal.app.IBatteryStats; 35eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpandeimport com.android.internal.util.State; 36eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpandeimport com.android.internal.util.StateMachine; 37155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 38155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.FileDescriptor; 39155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.io.PrintWriter; 40155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 41155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/** 42155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Tracks the state changes in supplicant and provides functionality 43155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * that is based on these state changes: 44155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * - detect a failed WPA handshake that loops indefinitely 45155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * - authentication failure handling 46155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 47eee1d479d8d402a2e78e2f143e957030cfc77749Vinit Deshpandepublic class SupplicantStateTracker extends StateMachine { 48155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 49155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private static final String TAG = "SupplicantStateTracker"; 500888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle private static boolean DBG = false; 51c2a0ff06d58e1cfb9b69fa5b6a8fef5929812f27Roshan Pius private final WifiConfigManager mWifiConfigManager; 5251991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn private final IBatteryStats mBatteryStats; 53155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* Indicates authentication failure in supplicant broadcast. 54155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * TODO: enhance auth failure reporting to include notification 55155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * for all type of failures: EAP, WPS & WPA networks */ 56155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private boolean mAuthFailureInSupplicantBroadcast = false; 57155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 58155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* Maximum retries on a authentication failure notification */ 59155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private static final int MAX_RETRIES_ON_AUTHENTICATION_FAILURE = 2; 60155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 61155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* Maximum retries on assoc rejection events */ 62155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private static final int MAX_RETRIES_ON_ASSOCIATION_REJECT = 16; 63155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 64155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* Tracks if networks have been disabled during a connection */ 65155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private boolean mNetworksDisabledDuringConnect = false; 66155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 6751991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn private final Context mContext; 68155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 6951991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn private final State mUninitializedState = new UninitializedState(); 7051991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn private final State mDefaultState = new DefaultState(); 7151991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn private final State mInactiveState = new InactiveState(); 7251991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn private final State mDisconnectState = new DisconnectedState(); 7351991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn private final State mScanState = new ScanState(); 7451991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn private final State mHandshakeState = new HandshakeState(); 7551991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn private final State mCompletedState = new CompletedState(); 7651991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn private final State mDormantState = new DormantState(); 77155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 780888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle void enableVerboseLogging(int verbose) { 790888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle if (verbose > 0) { 800888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle DBG = true; 810888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle } else { 820888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle DBG = false; 830888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle } 840888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle } 850888ce6f90bdaeee799dd8361ea4781e23a33b87vandwalle 86f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle public String getSupplicantStateName() { 87f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle return getCurrentState().getName(); 88f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 89f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 9054c9cf8d299b99f8b999bc2cf4adcda1eba81469Glen Kuhne public SupplicantStateTracker(Context c, WifiConfigManager wcs, Handler t) { 91155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande super(TAG, t.getLooper()); 92155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 93155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mContext = c; 94c2a0ff06d58e1cfb9b69fa5b6a8fef5929812f27Roshan Pius mWifiConfigManager = wcs; 9551991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn mBatteryStats = (IBatteryStats)ServiceManager.getService(BatteryStats.SERVICE_NAME); 96155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mDefaultState); 97155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mUninitializedState, mDefaultState); 98155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mInactiveState, mDefaultState); 99155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mDisconnectState, mDefaultState); 100155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mScanState, mDefaultState); 101155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mHandshakeState, mDefaultState); 102155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mCompletedState, mDefaultState); 103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande addState(mDormantState, mDefaultState); 104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 105155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande setInitialState(mUninitializedState); 106155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande setLogRecSize(50); 107155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande setLogOnlyTransitions(true); 108155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande //start the state machine 109155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande start(); 110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 111155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private void handleNetworkConnectionFailure(int netId, int disableReason) { 113f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle if (DBG) { 114f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle Log.d(TAG, "handleNetworkConnectionFailure netId=" + Integer.toString(netId) 115f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + " reason " + Integer.toString(disableReason) 116f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle + " mNetworksDisabledDuringConnect=" + mNetworksDisabledDuringConnect); 117f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle } 118f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle 119155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* If other networks disabled during connection, enable them */ 120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mNetworksDisabledDuringConnect) { 121c2a0ff06d58e1cfb9b69fa5b6a8fef5929812f27Roshan Pius mWifiConfigManager.enableAllNetworks(); 122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mNetworksDisabledDuringConnect = false; 123155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 1248f0f666c8bdaf508f191f8590755140b92d970eaxinhe /* update network status */ 125c2a0ff06d58e1cfb9b69fa5b6a8fef5929812f27Roshan Pius mWifiConfigManager.updateNetworkSelectionStatus(netId, disableReason); 126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 128155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private void transitionOnSupplicantStateChange(StateChangeResult stateChangeResult) { 129155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande SupplicantState supState = (SupplicantState) stateChangeResult.state; 130155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 131155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) Log.d(TAG, "Supplicant state: " + supState.toString() + "\n"); 132155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande switch (supState) { 134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case DISCONNECTED: 135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mDisconnectState); 136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 137155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case INTERFACE_DISABLED: 138155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande //we should have received a disconnection already, do nothing 139155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 140155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case SCANNING: 141155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mScanState); 142155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 143155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case AUTHENTICATING: 144155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case ASSOCIATING: 145155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case ASSOCIATED: 146155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case FOUR_WAY_HANDSHAKE: 147155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case GROUP_HANDSHAKE: 148155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mHandshakeState); 149155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 150155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case COMPLETED: 151155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mCompletedState); 152155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case DORMANT: 154155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mDormantState); 155155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case INACTIVE: 157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mInactiveState); 158155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 159155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case UNINITIALIZED: 160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case INVALID: 161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mUninitializedState); 162155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 163155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande default: 164155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Log.e(TAG, "Unknown supplicant state " + supState); 165155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 166155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 167155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 169155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private void sendSupplicantStateChangedBroadcast(SupplicantState state, boolean failedAuth) { 17051991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn int supplState; 17151991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn switch (state) { 17251991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn case DISCONNECTED: supplState = BatteryStats.WIFI_SUPPL_STATE_DISCONNECTED; break; 17351991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn case INTERFACE_DISABLED: 17451991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn supplState = BatteryStats.WIFI_SUPPL_STATE_INTERFACE_DISABLED; break; 17551991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn case INACTIVE: supplState = BatteryStats.WIFI_SUPPL_STATE_INACTIVE; break; 17651991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn case SCANNING: supplState = BatteryStats.WIFI_SUPPL_STATE_SCANNING; break; 17751991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn case AUTHENTICATING: supplState = BatteryStats.WIFI_SUPPL_STATE_AUTHENTICATING; break; 17851991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn case ASSOCIATING: supplState = BatteryStats.WIFI_SUPPL_STATE_ASSOCIATING; break; 17951991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn case ASSOCIATED: supplState = BatteryStats.WIFI_SUPPL_STATE_ASSOCIATED; break; 18051991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn case FOUR_WAY_HANDSHAKE: 18151991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn supplState = BatteryStats.WIFI_SUPPL_STATE_FOUR_WAY_HANDSHAKE; break; 18251991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn case GROUP_HANDSHAKE: supplState = BatteryStats.WIFI_SUPPL_STATE_GROUP_HANDSHAKE; break; 18351991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn case COMPLETED: supplState = BatteryStats.WIFI_SUPPL_STATE_COMPLETED; break; 18451991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn case DORMANT: supplState = BatteryStats.WIFI_SUPPL_STATE_DORMANT; break; 18551991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn case UNINITIALIZED: supplState = BatteryStats.WIFI_SUPPL_STATE_UNINITIALIZED; break; 18651991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn case INVALID: supplState = BatteryStats.WIFI_SUPPL_STATE_INVALID; break; 18751991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn default: 18851991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn Slog.w(TAG, "Unknown supplicant state " + state); 18951991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn supplState = BatteryStats.WIFI_SUPPL_STATE_INVALID; 19051991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn break; 19151991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn } 19251991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn try { 19351991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn mBatteryStats.noteWifiSupplicantStateChanged(supplState, failedAuth); 19451991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn } catch (RemoteException e) { 19551991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn // Won't happen. 19651991e784c605a7432a90c9e9a91b080fb106197Dianne Hackborn } 197155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Intent intent = new Intent(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); 198155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 199155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande | Intent.FLAG_RECEIVER_REPLACE_PENDING); 200155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande intent.putExtra(WifiManager.EXTRA_NEW_STATE, (Parcelable) state); 201155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (failedAuth) { 202155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande intent.putExtra( 203155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande WifiManager.EXTRA_SUPPLICANT_ERROR, 204155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande WifiManager.ERROR_AUTHENTICATING); 205155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 206155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 207155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 208155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 209155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /******************************************************** 210155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * HSM states 211155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *******************************************************/ 212155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 213155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class DefaultState extends State { 214155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 215155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 216155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) Log.d(TAG, getName() + "\n"); 217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public boolean processMessage(Message message) { 220155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) Log.d(TAG, getName() + message.toString() + "\n"); 221155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande switch (message.what) { 222155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case WifiMonitor.AUTHENTICATION_FAILURE_EVENT: 223155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mAuthFailureInSupplicantBroadcast = true; 224155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 225155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT: 226155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande StateChangeResult stateChangeResult = (StateChangeResult) message.obj; 227155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande SupplicantState state = stateChangeResult.state; 228155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande sendSupplicantStateChangedBroadcast(state, mAuthFailureInSupplicantBroadcast); 229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mAuthFailureInSupplicantBroadcast = false; 230155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionOnSupplicantStateChange(stateChangeResult); 231155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 232155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case WifiStateMachine.CMD_RESET_SUPPLICANT_STATE: 233155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mUninitializedState); 234155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 235155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case WifiManager.CONNECT_NETWORK: 236155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mNetworksDisabledDuringConnect = true; 237155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 238155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case WifiMonitor.ASSOCIATION_REJECTION_EVENT: 239155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande default: 240155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Log.e(TAG, "Ignoring " + message); 241155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 243155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return HANDLED; 244155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 245155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 246155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 247155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* 248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * This indicates that the supplicant state as seen 249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * by the framework is not initialized yet. We are 250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * in this state right after establishing a control 251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * channel connection before any supplicant events 252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * or after we have lost the control channel 253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * connection to the supplicant 254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class UninitializedState extends State { 256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) Log.d(TAG, getName() + "\n"); 259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class InactiveState extends State { 263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 265155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) Log.d(TAG, getName() + "\n"); 266155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 267155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 268155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 269155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class DisconnectedState extends State { 270155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) Log.d(TAG, getName() + "\n"); 273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 275155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class ScanState extends State { 277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) Log.d(TAG, getName() + "\n"); 280155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 281155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 282155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class HandshakeState extends State { 284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /** 285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * The max number of the WPA supplicant loop iterations before we 286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * decide that the loop should be terminated: 287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private static final int MAX_SUPPLICANT_LOOP_ITERATIONS = 4; 289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private int mLoopDetectIndex; 290155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande private int mLoopDetectCount; 291155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 292155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 293155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 294155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) Log.d(TAG, getName() + "\n"); 295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mLoopDetectIndex = 0; 296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mLoopDetectCount = 0; 297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public boolean processMessage(Message message) { 300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) Log.d(TAG, getName() + message.toString() + "\n"); 301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande switch (message.what) { 302155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT: 303155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande StateChangeResult stateChangeResult = (StateChangeResult) message.obj; 304155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande SupplicantState state = stateChangeResult.state; 305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (SupplicantState.isHandshakeState(state)) { 306155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mLoopDetectIndex > state.ordinal()) { 307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mLoopDetectCount++; 308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mLoopDetectCount > MAX_SUPPLICANT_LOOP_ITERATIONS) { 310155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande Log.d(TAG, "Supplicant loop detected, disabling network " + 311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande stateChangeResult.networkId); 312155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande handleNetworkConnectionFailure(stateChangeResult.networkId, 3138f0f666c8bdaf508f191f8590755140b92d970eaxinhe WifiConfiguration.NetworkSelectionStatus 3148f0f666c8bdaf508f191f8590755140b92d970eaxinhe .DISABLED_AUTHENTICATION_FAILURE); 315155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 316155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mLoopDetectIndex = state.ordinal(); 317155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande sendSupplicantStateChangedBroadcast(state, 318155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mAuthFailureInSupplicantBroadcast); 319155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } else { 320155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande //Have the DefaultState handle the transition 321155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return NOT_HANDLED; 322155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 323155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 324155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande default: 325155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return NOT_HANDLED; 326155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return HANDLED; 328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 330155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class CompletedState extends State { 332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) Log.d(TAG, getName() + "\n"); 335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* Reset authentication failure count */ 336155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (mNetworksDisabledDuringConnect) { 337c2a0ff06d58e1cfb9b69fa5b6a8fef5929812f27Roshan Pius mWifiConfigManager.enableAllNetworks(); 338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande mNetworksDisabledDuringConnect = false; 339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 341155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 342155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public boolean processMessage(Message message) { 343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) Log.d(TAG, getName() + message.toString() + "\n"); 344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande switch(message.what) { 345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT: 346155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande StateChangeResult stateChangeResult = (StateChangeResult) message.obj; 347155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande SupplicantState state = stateChangeResult.state; 348155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande sendSupplicantStateChangedBroadcast(state, mAuthFailureInSupplicantBroadcast); 349155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande /* Ignore any connecting state in completed state. Group re-keying 350155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * events and other auth events that do not affect connectivity are 351155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * ignored 352155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */ 353155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (SupplicantState.isConnecting(state)) { 354155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 356155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionOnSupplicantStateChange(stateChangeResult); 357155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 358155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande case WifiStateMachine.CMD_RESET_SUPPLICANT_STATE: 359155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande sendSupplicantStateChangedBroadcast(SupplicantState.DISCONNECTED, false); 360155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande transitionTo(mUninitializedState); 361155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande break; 362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande default: 363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return NOT_HANDLED; 364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande return HANDLED; 366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande //TODO: remove after getting rid of the state in supplicant 370155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande class DormantState extends State { 371155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 372155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void enter() { 373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande if (DBG) Log.d(TAG, getName() + "\n"); 374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande 377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande @Override 378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande super.dump(fd, pw, args); 380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande pw.println("mAuthFailureInSupplicantBroadcast " + mAuthFailureInSupplicantBroadcast); 381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande pw.println("mNetworksDisabledDuringConnect " + mNetworksDisabledDuringConnect); 382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande pw.println(); 383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande } 384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande} 385