summaryrefslogtreecommitdiffstats
path: root/wifi
diff options
context:
space:
mode:
authorIrfan Sheriff <isheriff@google.com>2010-11-11 16:40:06 -0800
committerIrfan Sheriff <isheriff@google.com>2010-11-18 16:58:08 -0800
commit19d245b792e1d941fbba9b04ae20ce9d6e6e18f8 (patch)
tree4d4bd185a5b0259cd0e6eca26ca2c5c5135812c0 /wifi
parent7200ab4a8f61b4aed25f9536ae29051e02503563 (diff)
downloadframeworks_base-19d245b792e1d941fbba9b04ae20ce9d6e6e18f8.zip
frameworks_base-19d245b792e1d941fbba9b04ae20ce9d6e6e18f8.tar.gz
frameworks_base-19d245b792e1d941fbba9b04ae20ce9d6e6e18f8.tar.bz2
Split SupplicantStateTracker and refactor
- Move SupplicantStateTracker into a seperate file. In the process clean up code that needs to be present only in SupplicantStateTracker - Retry twice for password failures - Clean up supplicant state handling. Dont treat supplicant states as HSM what values. Instead, just retain SUPPLICANT_STATE_CHANGE - Add event logging in SupplicantStateTracker - Move scan handling out SupplicantStateTracker Change-Id: I083e1c40ef5a858164493b1440b82c5751b3bfb5
Diffstat (limited to 'wifi')
-rw-r--r--wifi/java/android/net/wifi/SupplicantStateTracker.java333
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java695
2 files changed, 513 insertions, 515 deletions
diff --git a/wifi/java/android/net/wifi/SupplicantStateTracker.java b/wifi/java/android/net/wifi/SupplicantStateTracker.java
new file mode 100644
index 0000000..a83a0ad
--- /dev/null
+++ b/wifi/java/android/net/wifi/SupplicantStateTracker.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import com.android.internal.util.HierarchicalState;
+import com.android.internal.util.HierarchicalStateMachine;
+
+import android.net.wifi.WifiStateMachine.StateChangeResult;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * Tracks the state changes in supplicant and provides functionality
+ * that is based on these state changes:
+ * - detect a failed WPA handshake that loops indefinitely
+ * - password failure handling
+ * - Enable networks after a WPS success/failure
+ */
+class SupplicantStateTracker extends HierarchicalStateMachine {
+
+ private static final String TAG = "SupplicantStateTracker";
+ private static final boolean DBG = false;
+
+ private WifiStateMachine mWifiStateMachine;
+ private int mPasswordFailuresCount = 0;
+ /* Indicates authentication failure in supplicant broadcast.
+ * TODO: enhance auth failure reporting to include notification
+ * for all type of failures: EAP, WPS & WPA networks */
+ private boolean mAuthFailureInSupplicantBroadcast = false;
+
+ /* Maximum retries on a password failure notification */
+ private static final int MAX_RETRIES_ON_PASSWORD_FAILURE = 2;
+
+ /* Track if WPS was started since we need to re-enable networks
+ * and load configuration afterwards */
+ private boolean mWpsStarted = false;
+
+ private Context mContext;
+
+ private HierarchicalState mUninitializedState = new UninitializedState();
+ private HierarchicalState mDefaultState = new DefaultState();
+ private HierarchicalState mInactiveState = new InactiveState();
+ private HierarchicalState mDisconnectState = new DisconnectedState();
+ private HierarchicalState mScanState = new ScanState();
+ private HierarchicalState mHandshakeState = new HandshakeState();
+ private HierarchicalState mCompletedState = new CompletedState();
+ private HierarchicalState mDormantState = new DormantState();
+
+ public SupplicantStateTracker(Context context, WifiStateMachine wsm, Handler target) {
+ super(TAG, target.getLooper());
+
+ mContext = context;
+ mWifiStateMachine = wsm;
+ addState(mDefaultState);
+ addState(mUninitializedState, mDefaultState);
+ addState(mInactiveState, mDefaultState);
+ addState(mDisconnectState, mDefaultState);
+ addState(mScanState, mDefaultState);
+ addState(mHandshakeState, mDefaultState);
+ addState(mCompletedState, mDefaultState);
+ addState(mDormantState, mDefaultState);
+
+ setInitialState(mUninitializedState);
+
+ //start the state machine
+ start();
+ }
+
+ public void resetSupplicantState() {
+ transitionTo(mUninitializedState);
+ }
+
+
+ private void transitionOnSupplicantStateChange(StateChangeResult stateChangeResult) {
+ SupplicantState supState = (SupplicantState) stateChangeResult.state;
+
+ if (DBG) Log.d(TAG, "Supplicant state: " + supState.toString() + "\n");
+
+ switch (supState) {
+ case DISCONNECTED:
+ transitionTo(mDisconnectState);
+ break;
+ case SCANNING:
+ transitionTo(mScanState);
+ break;
+ case ASSOCIATING:
+ case ASSOCIATED:
+ case FOUR_WAY_HANDSHAKE:
+ case GROUP_HANDSHAKE:
+ transitionTo(mHandshakeState);
+ break;
+ case COMPLETED:
+ transitionTo(mCompletedState);
+ break;
+ case DORMANT:
+ transitionTo(mDormantState);
+ break;
+ case INACTIVE:
+ transitionTo(mInactiveState);
+ break;
+ case UNINITIALIZED:
+ case INVALID:
+ transitionTo(mUninitializedState);
+ break;
+ default:
+ Log.e(TAG, "Unknown supplicant state " + supState);
+ break;
+ }
+ }
+
+ private void sendSupplicantStateChangedBroadcast(StateChangeResult sc, boolean failedAuth) {
+ Intent intent = new Intent(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ | Intent.FLAG_RECEIVER_REPLACE_PENDING);
+ intent.putExtra(WifiManager.EXTRA_NEW_STATE, (Parcelable)sc.state);
+ if (failedAuth) {
+ intent.putExtra(
+ WifiManager.EXTRA_SUPPLICANT_ERROR,
+ WifiManager.ERROR_AUTHENTICATING);
+ }
+ mContext.sendStickyBroadcast(intent);
+ }
+
+ /********************************************************
+ * HSM states
+ *******************************************************/
+
+ class DefaultState extends HierarchicalState {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ switch (message.what) {
+ case WifiStateMachine.PASSWORD_MAY_BE_INCORRECT_EVENT:
+ mPasswordFailuresCount++;
+ mAuthFailureInSupplicantBroadcast = true;
+ break;
+ case WifiStateMachine.CMD_START_WPS_PBC:
+ case WifiStateMachine.CMD_START_WPS_PIN_FROM_AP:
+ case WifiStateMachine.CMD_START_WPS_PIN_FROM_DEVICE:
+ mWpsStarted = true;
+ break;
+ case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT:
+ StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
+ sendSupplicantStateChangedBroadcast(stateChangeResult,
+ mAuthFailureInSupplicantBroadcast);
+ mAuthFailureInSupplicantBroadcast = false;
+ transitionOnSupplicantStateChange(stateChangeResult);
+ break;
+ default:
+ Log.e(TAG, "Ignoring " + message);
+ break;
+ }
+ return HANDLED;
+ }
+ }
+
+ class UninitializedState extends HierarchicalState {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ mWifiStateMachine.setNetworkAvailable(false);
+ }
+ @Override
+ public void exit() {
+ mWifiStateMachine.setNetworkAvailable(true);
+ }
+ }
+
+ class InactiveState extends HierarchicalState {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ /* A failed WPS connection */
+ if (mWpsStarted) {
+ Log.e(TAG, "WPS set up failed, enabling other networks");
+ WifiConfigStore.enableAllNetworks();
+ mWpsStarted = false;
+ }
+ mWifiStateMachine.setNetworkAvailable(false);
+ }
+ @Override
+ public void exit() {
+ mWifiStateMachine.setNetworkAvailable(true);
+ }
+ }
+
+
+ class DisconnectedState extends HierarchicalState {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ /* If a disconnect event happens after password key failure
+ * exceeds maximum retries, disable the network
+ */
+
+ Message message = getCurrentMessage();
+ StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
+
+ if (mPasswordFailuresCount >= MAX_RETRIES_ON_PASSWORD_FAILURE) {
+ Log.d(TAG, "Failed to authenticate, disabling network " +
+ stateChangeResult.networkId);
+ WifiConfigStore.disableNetwork(stateChangeResult.networkId);
+ mPasswordFailuresCount = 0;
+ }
+ }
+ }
+
+ class ScanState extends HierarchicalState {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ }
+ }
+
+ class HandshakeState extends HierarchicalState {
+ /**
+ * The max number of the WPA supplicant loop iterations before we
+ * decide that the loop should be terminated:
+ */
+ private static final int MAX_SUPPLICANT_LOOP_ITERATIONS = 4;
+ private int mLoopDetectIndex;
+ private int mLoopDetectCount;
+
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ mLoopDetectIndex = 0;
+ mLoopDetectCount = 0;
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ switch (message.what) {
+ case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT:
+ StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
+ SupplicantState state = (SupplicantState) stateChangeResult.state;
+ if (state == SupplicantState.ASSOCIATING ||
+ state == SupplicantState.ASSOCIATED ||
+ state == SupplicantState.FOUR_WAY_HANDSHAKE ||
+ state == SupplicantState.GROUP_HANDSHAKE) {
+ if (mLoopDetectIndex > state.ordinal()) {
+ mLoopDetectCount++;
+ }
+ if (mLoopDetectCount > MAX_SUPPLICANT_LOOP_ITERATIONS) {
+ Log.d(TAG, "Supplicant loop detected, disabling network " +
+ stateChangeResult.networkId);
+ WifiConfigStore.disableNetwork(stateChangeResult.networkId);
+ }
+ mLoopDetectIndex = state.ordinal();
+ sendSupplicantStateChangedBroadcast(stateChangeResult,
+ mAuthFailureInSupplicantBroadcast);
+ } else {
+ //Have the DefaultState handle the transition
+ return NOT_HANDLED;
+ }
+ break;
+ default:
+ return NOT_HANDLED;
+ }
+ return HANDLED;
+ }
+ }
+
+ class CompletedState extends HierarchicalState {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ /* Reset password failure count */
+ mPasswordFailuresCount = 0;
+
+ /* A successful WPS connection */
+ if (mWpsStarted) {
+ WifiConfigStore.enableAllNetworks();
+ WifiConfigStore.loadConfiguredNetworks();
+ mWpsStarted = false;
+ }
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ switch(message.what) {
+ case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT:
+ StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
+ SupplicantState state = (SupplicantState) stateChangeResult.state;
+ sendSupplicantStateChangedBroadcast(stateChangeResult,
+ mAuthFailureInSupplicantBroadcast);
+ /* Ignore a re-auth in completed state */
+ if (state == SupplicantState.ASSOCIATING ||
+ state == SupplicantState.ASSOCIATED ||
+ state == SupplicantState.FOUR_WAY_HANDSHAKE ||
+ state == SupplicantState.GROUP_HANDSHAKE ||
+ state == SupplicantState.COMPLETED) {
+ break;
+ }
+ transitionOnSupplicantStateChange(stateChangeResult);
+ break;
+ default:
+ return NOT_HANDLED;
+ }
+ return HANDLED;
+ }
+ }
+
+ //TODO: remove after getting rid of the state in supplicant
+ class DormantState extends HierarchicalState {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ }
+ }
+} \ No newline at end of file
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 95e2df3..90abd02 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -49,8 +49,6 @@ import android.net.NetworkInfo.DetailedState;
import android.net.LinkProperties;
import android.os.Binder;
import android.os.Message;
-import android.os.Parcelable;
-import android.os.Handler;
import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.PowerManager;
@@ -93,8 +91,6 @@ import java.util.regex.Pattern;
*
* @hide
*/
-//TODO: we still need frequent scanning for the case when
-// we issue disconnect but need scan results for open network notification
public class WifiStateMachine extends HierarchicalStateMachine {
private static final String TAG = "WifiStateMachine";
@@ -120,11 +116,17 @@ public class WifiStateMachine extends HierarchicalStateMachine {
private String mLastBssid;
private int mLastNetworkId;
private boolean mEnableRssiPolling = false;
- private boolean mPasswordKeyMayBeIncorrect = false;
+ private int mRssiPollToken = 0;
private int mReconnectCount = 0;
private boolean mIsScanMode = false;
/**
+ * Interval in milliseconds between polling for RSSI
+ * and linkspeed information
+ */
+ private static final int POLL_RSSI_INTERVAL_MSECS = 3000;
+
+ /**
* Instance of the bluetooth headset helper. This needs to be created
* early because there is a delay before it actually 'connects', as
* noted by its javadoc. If we check before it is connected, it will be
@@ -148,9 +150,6 @@ public class WifiStateMachine extends HierarchicalStateMachine {
/* Connection to a specific network involves disabling all networks,
* this flag tracks if networks need to be re-enabled */
private boolean mEnableAllNetworks = false;
- /* Track if WPS was started since we need to re-enable networks
- * and load configuration afterwards */
- private boolean mWpsStarted = false;
private AlarmManager mAlarmManager;
private PendingIntent mScanIntent;
@@ -166,95 +165,95 @@ public class WifiStateMachine extends HierarchicalStateMachine {
private static final int EVENTLOG_SUPPLICANT_STATE_CHANGED = 50023;
/* Load the driver */
- private static final int CMD_LOAD_DRIVER = 1;
+ static final int CMD_LOAD_DRIVER = 1;
/* Unload the driver */
- private static final int CMD_UNLOAD_DRIVER = 2;
+ static final int CMD_UNLOAD_DRIVER = 2;
/* Indicates driver load succeeded */
- private static final int CMD_LOAD_DRIVER_SUCCESS = 3;
+ static final int CMD_LOAD_DRIVER_SUCCESS = 3;
/* Indicates driver load failed */
- private static final int CMD_LOAD_DRIVER_FAILURE = 4;
+ static final int CMD_LOAD_DRIVER_FAILURE = 4;
/* Indicates driver unload succeeded */
- private static final int CMD_UNLOAD_DRIVER_SUCCESS = 5;
+ static final int CMD_UNLOAD_DRIVER_SUCCESS = 5;
/* Indicates driver unload failed */
- private static final int CMD_UNLOAD_DRIVER_FAILURE = 6;
+ static final int CMD_UNLOAD_DRIVER_FAILURE = 6;
/* Set bluetooth headset proxy */
- private static final int CMD_SET_BLUETOOTH_HEADSET_PROXY = 7;
+ static final int CMD_SET_BLUETOOTH_HEADSET_PROXY = 7;
/* Set bluetooth A2dp proxy */
- private static final int CMD_SET_BLUETOOTH_A2DP_PROXY = 8;
+ static final int CMD_SET_BLUETOOTH_A2DP_PROXY = 8;
/* Start the supplicant */
- private static final int CMD_START_SUPPLICANT = 11;
+ static final int CMD_START_SUPPLICANT = 11;
/* Stop the supplicant */
- private static final int CMD_STOP_SUPPLICANT = 12;
+ static final int CMD_STOP_SUPPLICANT = 12;
/* Start the driver */
- private static final int CMD_START_DRIVER = 13;
+ static final int CMD_START_DRIVER = 13;
/* Start the driver */
- private static final int CMD_STOP_DRIVER = 14;
+ static final int CMD_STOP_DRIVER = 14;
/* Indicates DHCP succeded */
- private static final int CMD_IP_CONFIG_SUCCESS = 15;
+ static final int CMD_IP_CONFIG_SUCCESS = 15;
/* Indicates DHCP failed */
- private static final int CMD_IP_CONFIG_FAILURE = 16;
+ static final int CMD_IP_CONFIG_FAILURE = 16;
/* Re-configure interface */
- private static final int CMD_RECONFIGURE_IP = 17;
+ static final int CMD_RECONFIGURE_IP = 17;
/* Start the soft access point */
- private static final int CMD_START_AP = 21;
+ static final int CMD_START_AP = 21;
/* Stop the soft access point */
- private static final int CMD_STOP_AP = 22;
+ static final int CMD_STOP_AP = 22;
/* Supplicant events */
/* Connection to supplicant established */
- private static final int SUP_CONNECTION_EVENT = 31;
+ static final int SUP_CONNECTION_EVENT = 31;
/* Connection to supplicant lost */
- private static final int SUP_DISCONNECTION_EVENT = 32;
+ static final int SUP_DISCONNECTION_EVENT = 32;
/* Driver start completed */
- private static final int DRIVER_START_EVENT = 33;
+ static final int DRIVER_START_EVENT = 33;
/* Driver stop completed */
- private static final int DRIVER_STOP_EVENT = 34;
+ static final int DRIVER_STOP_EVENT = 34;
/* Network connection completed */
- private static final int NETWORK_CONNECTION_EVENT = 36;
+ static final int NETWORK_CONNECTION_EVENT = 36;
/* Network disconnection completed */
- private static final int NETWORK_DISCONNECTION_EVENT = 37;
+ static final int NETWORK_DISCONNECTION_EVENT = 37;
/* Scan results are available */
- private static final int SCAN_RESULTS_EVENT = 38;
+ static final int SCAN_RESULTS_EVENT = 38;
/* Supplicate state changed */
- private static final int SUPPLICANT_STATE_CHANGE_EVENT = 39;
+ static final int SUPPLICANT_STATE_CHANGE_EVENT = 39;
/* Password may be incorrect */
- private static final int PASSWORD_MAY_BE_INCORRECT_EVENT = 40;
+ static final int PASSWORD_MAY_BE_INCORRECT_EVENT = 40;
/* Supplicant commands */
/* Is supplicant alive ? */
- private static final int CMD_PING_SUPPLICANT = 51;
+ static final int CMD_PING_SUPPLICANT = 51;
/* Add/update a network configuration */
- private static final int CMD_ADD_OR_UPDATE_NETWORK = 52;
+ static final int CMD_ADD_OR_UPDATE_NETWORK = 52;
/* Delete a network */
- private static final int CMD_REMOVE_NETWORK = 53;
+ static final int CMD_REMOVE_NETWORK = 53;
/* Enable a network. The device will attempt a connection to the given network. */
- private static final int CMD_ENABLE_NETWORK = 54;
+ static final int CMD_ENABLE_NETWORK = 54;
/* Disable a network. The device does not attempt a connection to the given network. */
- private static final int CMD_DISABLE_NETWORK = 55;
+ static final int CMD_DISABLE_NETWORK = 55;
/* Blacklist network. De-prioritizes the given BSSID for connection. */
- private static final int CMD_BLACKLIST_NETWORK = 56;
+ static final int CMD_BLACKLIST_NETWORK = 56;
/* Clear the blacklist network list */
- private static final int CMD_CLEAR_BLACKLIST = 57;
+ static final int CMD_CLEAR_BLACKLIST = 57;
/* Save configuration */
- private static final int CMD_SAVE_CONFIG = 58;
+ static final int CMD_SAVE_CONFIG = 58;
/* Supplicant commands after driver start*/
/* Initiate a scan */
- private static final int CMD_START_SCAN = 71;
+ static final int CMD_START_SCAN = 71;
/* Set scan mode. CONNECT_MODE or SCAN_ONLY_MODE */
- private static final int CMD_SET_SCAN_MODE = 72;
+ static final int CMD_SET_SCAN_MODE = 72;
/* Set scan type. SCAN_ACTIVE or SCAN_PASSIVE */
- private static final int CMD_SET_SCAN_TYPE = 73;
+ static final int CMD_SET_SCAN_TYPE = 73;
/* Disconnect from a network */
- private static final int CMD_DISCONNECT = 74;
+ static final int CMD_DISCONNECT = 74;
/* Reconnect to a network */
- private static final int CMD_RECONNECT = 75;
+ static final int CMD_RECONNECT = 75;
/* Reassociate to a network */
- private static final int CMD_REASSOCIATE = 76;
+ static final int CMD_REASSOCIATE = 76;
/* Controls power mode and suspend mode optimizations
*
* When high perf mode is enabled, power mode is set to
@@ -268,30 +267,30 @@ public class WifiStateMachine extends HierarchicalStateMachine {
* - turn off roaming
* - DTIM wake up settings
*/
- private static final int CMD_SET_HIGH_PERF_MODE = 77;
+ static final int CMD_SET_HIGH_PERF_MODE = 77;
/* Set bluetooth co-existence
* BLUETOOTH_COEXISTENCE_MODE_ENABLED
* BLUETOOTH_COEXISTENCE_MODE_DISABLED
* BLUETOOTH_COEXISTENCE_MODE_SENSE
*/
- private static final int CMD_SET_BLUETOOTH_COEXISTENCE = 78;
+ static final int CMD_SET_BLUETOOTH_COEXISTENCE = 78;
/* Enable/disable bluetooth scan mode
* true(1)
* false(0)
*/
- private static final int CMD_SET_BLUETOOTH_SCAN_MODE = 79;
+ static final int CMD_SET_BLUETOOTH_SCAN_MODE = 79;
/* Set the country code */
- private static final int CMD_SET_COUNTRY_CODE = 80;
+ static final int CMD_SET_COUNTRY_CODE = 80;
/* Request connectivity manager wake lock before driver stop */
- private static final int CMD_REQUEST_CM_WAKELOCK = 81;
+ static final int CMD_REQUEST_CM_WAKELOCK = 81;
/* Enables RSSI poll */
- private static final int CMD_ENABLE_RSSI_POLL = 82;
+ static final int CMD_ENABLE_RSSI_POLL = 82;
/* RSSI poll */
- private static final int CMD_RSSI_POLL = 83;
+ static final int CMD_RSSI_POLL = 83;
/* Set up packet filtering */
- private static final int CMD_START_PACKET_FILTERING = 84;
+ static final int CMD_START_PACKET_FILTERING = 84;
/* Clear packet filter */
- private static final int CMD_STOP_PACKET_FILTERING = 85;
+ static final int CMD_STOP_PACKET_FILTERING = 85;
/* Connect to a specified network (network id
* or WifiConfiguration) This involves increasing
* the priority of the network, enabling the network
@@ -300,32 +299,29 @@ public class WifiStateMachine extends HierarchicalStateMachine {
* an existing network. All the networks get enabled
* upon a successful connection or a failure.
*/
- private static final int CMD_CONNECT_NETWORK = 86;
+ static final int CMD_CONNECT_NETWORK = 86;
/* Save the specified network. This involves adding
* an enabled network (if new) and updating the
* config and issuing a save on supplicant config.
*/
- private static final int CMD_SAVE_NETWORK = 87;
+ static final int CMD_SAVE_NETWORK = 87;
/* Delete the specified network. This involves
* removing the network and issuing a save on
* supplicant config.
*/
- private static final int CMD_FORGET_NETWORK = 88;
+ static final int CMD_FORGET_NETWORK = 88;
/* Start Wi-Fi protected setup push button configuration */
- private static final int CMD_START_WPS_PBC = 89;
+ static final int CMD_START_WPS_PBC = 89;
/* Start Wi-Fi protected setup pin method configuration with pin obtained from AP */
- private static final int CMD_START_WPS_PIN_FROM_AP = 90;
+ static final int CMD_START_WPS_PIN_FROM_AP = 90;
/* Start Wi-Fi protected setup pin method configuration with pin obtained from device */
- private static final int CMD_START_WPS_PIN_FROM_DEVICE = 91;
+ static final int CMD_START_WPS_PIN_FROM_DEVICE = 91;
/* Set the frequency band */
- private static final int CMD_SET_FREQUENCY_BAND = 92;
+ static final int CMD_SET_FREQUENCY_BAND = 92;
- /**
- * Interval in milliseconds between polling for connection
- * status items that are not sent via asynchronous events.
- * An example is RSSI (signal strength).
- */
- private static final int POLL_RSSI_INTERVAL_MSECS = 3000;
+ /* Commands from the SupplicantStateTracker */
+ /* Indicates whether a wifi network is available for connection */
+ static final int CMD_SET_NETWORK_AVAILABLE = 111;
private static final int CONNECT_MODE = 1;
private static final int SCAN_ONLY_MODE = 2;
@@ -463,7 +459,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
mDhcpInfo = new DhcpInfo();
mWifiInfo = new WifiInfo();
mInterfaceName = SystemProperties.get("wifi.interface", "tiwlan0");
- mSupplicantStateTracker = new SupplicantStateTracker(context, getHandler());
+ mSupplicantStateTracker = new SupplicantStateTracker(context, this, getHandler());
mLinkProperties = new LinkProperties();
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -985,8 +981,6 @@ public class WifiStateMachine extends HierarchicalStateMachine {
sb.append("mLastBssid ").append(mLastBssid).append(LS);
sb.append("mLastNetworkId ").append(mLastNetworkId).append(LS);
sb.append("mEnableAllNetworks ").append(mEnableAllNetworks).append(LS);
- sb.append("mEnableRssiPolling ").append(mEnableRssiPolling).append(LS);
- sb.append("mPasswordKeyMayBeIncorrect ").append(mPasswordKeyMayBeIncorrect).append(LS);
sb.append("mReconnectCount ").append(mReconnectCount).append(LS);
sb.append("mIsScanMode ").append(mIsScanMode).append(LS);
sb.append("Supplicant status").append(LS)
@@ -1215,6 +1209,44 @@ public class WifiStateMachine extends HierarchicalStateMachine {
return null;
}
+ /*
+ * Fetch RSSI and linkspeed on current connection
+ */
+ private void fetchRssiAndLinkSpeedNative() {
+ int newRssi = WifiNative.getRssiCommand();
+ if (newRssi != -1 && -200 < newRssi && newRssi < 256) { // screen out invalid values
+ /* some implementations avoid negative values by adding 256
+ * so we need to adjust for that here.
+ */
+ if (newRssi > 0) newRssi -= 256;
+ mWifiInfo.setRssi(newRssi);
+ /*
+ * Rather then sending the raw RSSI out every time it
+ * changes, we precalculate the signal level that would
+ * be displayed in the status bar, and only send the
+ * broadcast if that much more coarse-grained number
+ * changes. This cuts down greatly on the number of
+ * broadcasts, at the cost of not mWifiInforming others
+ * interested in RSSI of all the changes in signal
+ * level.
+ */
+ // TODO: The second arg to the call below needs to be a symbol somewhere, but
+ // it's actually the size of an array of icons that's private
+ // to StatusBar Policy.
+ int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, 4);
+ if (newSignalLevel != mLastSignalLevel) {
+ sendRssiChangeBroadcast(newRssi);
+ }
+ mLastSignalLevel = newSignalLevel;
+ } else {
+ mWifiInfo.setRssi(-200);
+ }
+ int newLinkSpeed = WifiNative.getLinkSpeedCommand();
+ if (newLinkSpeed != -1) {
+ mWifiInfo.setLinkSpeed(newLinkSpeed);
+ }
+ }
+
private void setHighPerfModeEnabledNative(boolean enable) {
if(!WifiNative.setSuspendOptimizationsCommand(!enable)) {
Log.e(TAG, "set suspend optimizations failed!");
@@ -1336,19 +1368,6 @@ public class WifiStateMachine extends HierarchicalStateMachine {
mContext.sendBroadcast(intent);
}
- private void sendSupplicantStateChangedBroadcast(StateChangeResult sc, boolean failedAuth) {
- Intent intent = new Intent(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
- | Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putExtra(WifiManager.EXTRA_NEW_STATE, (Parcelable)sc.state);
- if (failedAuth) {
- intent.putExtra(
- WifiManager.EXTRA_SUPPLICANT_ERROR,
- WifiManager.ERROR_AUTHENTICATING);
- }
- mContext.sendStickyBroadcast(intent);
- }
-
private void sendSupplicantConnectionChangedBroadcast(boolean connected) {
if (!ActivityManagerNative.isSystemReady()) return;
@@ -1370,45 +1389,6 @@ public class WifiStateMachine extends HierarchicalStateMachine {
}
/**
- * Poll for info not reported via events
- * RSSI & Linkspeed
- */
- private void requestPolledInfo() {
- int newRssi = WifiNative.getRssiCommand();
- if (newRssi != -1 && -200 < newRssi && newRssi < 256) { // screen out invalid values
- /* some implementations avoid negative values by adding 256
- * so we need to adjust for that here.
- */
- if (newRssi > 0) newRssi -= 256;
- mWifiInfo.setRssi(newRssi);
- /*
- * Rather then sending the raw RSSI out every time it
- * changes, we precalculate the signal level that would
- * be displayed in the status bar, and only send the
- * broadcast if that much more coarse-grained number
- * changes. This cuts down greatly on the number of
- * broadcasts, at the cost of not mWifiInforming others
- * interested in RSSI of all the changes in signal
- * level.
- */
- // TODO: The second arg to the call below needs to be a symbol somewhere, but
- // it's actually the size of an array of icons that's private
- // to StatusBar Policy.
- int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, 4);
- if (newSignalLevel != mLastSignalLevel) {
- sendRssiChangeBroadcast(newRssi);
- }
- mLastSignalLevel = newSignalLevel;
- } else {
- mWifiInfo.setRssi(-200);
- }
- int newLinkSpeed = WifiNative.getLinkSpeedCommand();
- if (newLinkSpeed != -1) {
- mWifiInfo.setLinkSpeed(newLinkSpeed);
- }
- }
-
- /**
* Resets the Wi-Fi Connections by clearing any state, resetting any sockets
* using the interface, stopping DHCP & disabling interface
*/
@@ -1456,7 +1436,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
* WifiMonitor
* thread.
*/
- private static class StateChangeResult {
+ static class StateChangeResult {
StateChangeResult(int networkId, String BSSID, Object state) {
this.state = state;
this.BSSID = BSSID;
@@ -1548,6 +1528,9 @@ public class WifiStateMachine extends HierarchicalStateMachine {
setWifiEnabled(true);
}
+ void setNetworkAvailable(boolean available) {
+ sendMessage(CMD_SET_NETWORK_AVAILABLE, available ? 1 : 0);
+ }
/********************************************************
* HSM states
@@ -1576,7 +1559,9 @@ public class WifiStateMachine extends HierarchicalStateMachine {
break;
case CMD_ENABLE_RSSI_POLL:
mEnableRssiPolling = (message.arg1 == 1);
- mSupplicantStateTracker.sendMessage(CMD_ENABLE_RSSI_POLL);
+ break;
+ case CMD_SET_NETWORK_AVAILABLE:
+ mNetworkInfo.setIsAvailable(message.arg1 == 1);
break;
/* Discard */
case CMD_LOAD_DRIVER:
@@ -1616,6 +1601,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case CMD_FORGET_NETWORK:
case CMD_START_WPS_PBC:
case CMD_START_WPS_PIN_FROM_AP:
+ case CMD_RSSI_POLL:
break;
default:
Log.e(TAG, "Error! unhandled message" + message);
@@ -2136,6 +2122,9 @@ public class WifiStateMachine extends HierarchicalStateMachine {
WifiNative.setScanModeCommand(false);
}
break;
+ case CMD_START_SCAN:
+ WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
+ break;
case CMD_SET_HIGH_PERF_MODE:
setHighPerfModeEnabledNative(message.arg1 == 1);
break;
@@ -2278,9 +2267,6 @@ public class WifiStateMachine extends HierarchicalStateMachine {
transitionTo(mDisconnectedState);
}
break;
- case CMD_START_SCAN:
- WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
- break;
/* Ignore */
case CMD_DISCONNECT:
case CMD_RECONNECT:
@@ -2309,14 +2295,23 @@ public class WifiStateMachine extends HierarchicalStateMachine {
StateChangeResult stateChangeResult;
switch(message.what) {
case PASSWORD_MAY_BE_INCORRECT_EVENT:
- mPasswordKeyMayBeIncorrect = true;
+ mSupplicantStateTracker.sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
break;
case SUPPLICANT_STATE_CHANGE_EVENT:
stateChangeResult = (StateChangeResult) message.obj;
- mSupplicantStateTracker.handleEvent(stateChangeResult);
- break;
- case CMD_START_SCAN:
- /* We need to set scan type in completed state */
+ SupplicantState state = (SupplicantState) stateChangeResult.state;
+ // Supplicant state change
+ // [31-13] Reserved for future use
+ // [8 - 0] Supplicant state (as defined in SupplicantState.java)
+ // 50023 supplicant_state_changed (custom|1|5)
+ EventLog.writeEvent(EVENTLOG_SUPPLICANT_STATE_CHANGED, state.ordinal());
+ mWifiInfo.setSupplicantState(state);
+ mWifiInfo.setNetworkId(stateChangeResult.networkId);
+ if (state == SupplicantState.ASSOCIATING) {
+ /* BSSID is valid only in ASSOCIATING state */
+ mWifiInfo.setBSSID(stateChangeResult.BSSID);
+ }
+
Message newMsg = obtainMessage();
newMsg.copyFrom(message);
mSupplicantStateTracker.sendMessage(newMsg);
@@ -2375,7 +2370,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
* Upon success, the configuration list needs to be reloaded
*/
if (success) {
- mWpsStarted = true;
+ mSupplicantStateTracker.sendMessage(message.what);
/* Expect a disconnection from the old connection */
transitionTo(mDisconnectingState);
}
@@ -2388,7 +2383,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
success = WifiConfigStore.startWpsWithPinFromAccessPoint(bssid, apPin);
if (success) {
- mWpsStarted = true;
+ mSupplicantStateTracker.sendMessage(message.what);
/* Expect a disconnection from the old connection */
transitionTo(mDisconnectingState);
}
@@ -2400,7 +2395,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
mReplyChannel.replyToMessage(message, CMD_START_WPS_PIN_FROM_DEVICE, pin);
if (success) {
- mWpsStarted = true;
+ mSupplicantStateTracker.sendMessage(message.what);
/* Expect a disconnection from the old connection */
transitionTo(mDisconnectingState);
}
@@ -2583,6 +2578,10 @@ public class WifiStateMachine extends HierarchicalStateMachine {
deferMessage(message);
}
break;
+ /* Defer scan when IP is being fetched */
+ case CMD_START_SCAN:
+ deferMessage(message);
+ break;
case CMD_RECONFIGURE_IP:
deferMessage(message);
break;
@@ -2619,13 +2618,11 @@ public class WifiStateMachine extends HierarchicalStateMachine {
@Override
public void enter() {
if (DBG) Log.d(TAG, getName() + "\n");
- /* A successful WPS connection */
- if (mWpsStarted) {
- WifiConfigStore.enableAllNetworks();
- WifiConfigStore.loadConfiguredNetworks();
- mWpsStarted = false;
- }
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
+ mRssiPollToken++;
+ if (mEnableRssiPolling) {
+ sendMessage(obtainMessage(WifiStateMachine.CMD_RSSI_POLL, mRssiPollToken, 0));
+ }
}
@Override
public boolean processMessage(Message message) {
@@ -2650,6 +2647,15 @@ public class WifiStateMachine extends HierarchicalStateMachine {
deferMessage(message);
}
break;
+ case CMD_START_SCAN:
+ /* When the network is connected, re-scanning can trigger
+ * a reconnection. Put it in scan-only mode during scan.
+ * When scan results are received, the mode is switched
+ * back to CONNECT_MODE.
+ */
+ WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE);
+ WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
+ break;
/* Ignore connection to same network */
case CMD_CONNECT_NETWORK:
int netId = message.arg1;
@@ -2660,6 +2666,26 @@ public class WifiStateMachine extends HierarchicalStateMachine {
/* Ignore */
case NETWORK_CONNECTION_EVENT:
break;
+ case CMD_RSSI_POLL:
+ if (message.arg1 == mRssiPollToken) {
+ // Get Info and continue polling
+ fetchRssiAndLinkSpeedNative();
+ sendMessageDelayed(obtainMessage(WifiStateMachine.CMD_RSSI_POLL,
+ mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
+ } else {
+ // Polling has completed
+ }
+ break;
+ case CMD_ENABLE_RSSI_POLL:
+ mEnableRssiPolling = (message.arg1 == 1);
+ mRssiPollToken++;
+ if (mEnableRssiPolling) {
+ // first poll
+ fetchRssiAndLinkSpeedNative();
+ sendMessageDelayed(obtainMessage(WifiStateMachine.CMD_RSSI_POLL,
+ mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
+ }
+ break;
default:
return NOT_HANDLED;
}
@@ -2686,6 +2712,10 @@ public class WifiStateMachine extends HierarchicalStateMachine {
deferMessage(message);
}
break;
+ /* Handle in DisconnectedState */
+ case SUPPLICANT_STATE_CHANGE_EVENT:
+ deferMessage(message);
+ break;
default:
return NOT_HANDLED;
}
@@ -2734,6 +2764,12 @@ public class WifiStateMachine extends HierarchicalStateMachine {
/* Ignore network disconnect */
case NETWORK_DISCONNECTION_EVENT:
break;
+ case SUPPLICANT_STATE_CHANGE_EVENT:
+ StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
+ SupplicantState state = (SupplicantState) stateChangeResult.state;
+ setDetailedState(WifiInfo.getDetailedStateOf(state));
+ /* DriverStartedState does the rest of the handling */
+ return NOT_HANDLED;
default:
return NOT_HANDLED;
}
@@ -2795,375 +2831,4 @@ public class WifiStateMachine extends HierarchicalStateMachine {
return HANDLED;
}
}
-
-
- class SupplicantStateTracker extends HierarchicalStateMachine {
-
- private int mRssiPollToken = 0;
-
- /**
- * The max number of the WPA supplicant loop iterations before we
- * decide that the loop should be terminated:
- */
- private static final int MAX_SUPPLICANT_LOOP_ITERATIONS = 4;
- private int mLoopDetectIndex = 0;
- private int mLoopDetectCount = 0;
-
- /**
- * Supplicant state change commands follow
- * the ordinal values defined in SupplicantState.java
- */
- private static final int DISCONNECTED = 0;
- private static final int INACTIVE = 1;
- private static final int SCANNING = 2;
- private static final int ASSOCIATING = 3;
- private static final int ASSOCIATED = 4;
- private static final int FOUR_WAY_HANDSHAKE = 5;
- private static final int GROUP_HANDSHAKE = 6;
- private static final int COMPLETED = 7;
- private static final int DORMANT = 8;
- private static final int UNINITIALIZED = 9;
- private static final int INVALID = 10;
-
- private HierarchicalState mUninitializedState = new UninitializedState();
- private HierarchicalState mInitializedState = new InitializedState();;
- private HierarchicalState mInactiveState = new InactiveState();
- private HierarchicalState mDisconnectState = new DisconnectedState();
- private HierarchicalState mScanState = new ScanState();
- private HierarchicalState mConnectState = new ConnectState();
- private HierarchicalState mHandshakeState = new HandshakeState();
- private HierarchicalState mCompletedState = new CompletedState();
- private HierarchicalState mDormantState = new DormantState();
-
- public SupplicantStateTracker(Context context, Handler target) {
- super(TAG, target.getLooper());
-
- addState(mUninitializedState);
- addState(mInitializedState);
- addState(mInactiveState, mInitializedState);
- addState(mDisconnectState, mInitializedState);
- addState(mScanState, mInitializedState);
- addState(mConnectState, mInitializedState);
- addState(mHandshakeState, mConnectState);
- addState(mCompletedState, mConnectState);
- addState(mDormantState, mInitializedState);
-
- setInitialState(mUninitializedState);
-
- //start the state machine
- start();
- }
-
- public void handleEvent(StateChangeResult stateChangeResult) {
- SupplicantState newState = (SupplicantState) stateChangeResult.state;
-
- // Supplicant state change
- // [31-13] Reserved for future use
- // [8 - 0] Supplicant state (as defined in SupplicantState.java)
- // 50023 supplicant_state_changed (custom|1|5)
- EventLog.writeEvent(EVENTLOG_SUPPLICANT_STATE_CHANGED, newState.ordinal());
-
- sendMessage(obtainMessage(newState.ordinal(), stateChangeResult));
- }
-
- public void resetSupplicantState() {
- transitionTo(mUninitializedState);
- }
-
- private void resetLoopDetection() {
- mLoopDetectCount = 0;
- mLoopDetectIndex = 0;
- }
-
- private boolean handleTransition(Message msg) {
- if (DBG) Log.d(TAG, getName() + msg.toString() + "\n");
- switch (msg.what) {
- case DISCONNECTED:
- transitionTo(mDisconnectState);
- break;
- case SCANNING:
- transitionTo(mScanState);
- break;
- case ASSOCIATING:
- StateChangeResult stateChangeResult = (StateChangeResult) msg.obj;
- /* BSSID is valid only in ASSOCIATING state */
- mWifiInfo.setBSSID(stateChangeResult.BSSID);
- //$FALL-THROUGH$
- case ASSOCIATED:
- case FOUR_WAY_HANDSHAKE:
- case GROUP_HANDSHAKE:
- transitionTo(mHandshakeState);
- break;
- case COMPLETED:
- transitionTo(mCompletedState);
- break;
- case DORMANT:
- transitionTo(mDormantState);
- break;
- case INACTIVE:
- transitionTo(mInactiveState);
- break;
- case UNINITIALIZED:
- case INVALID:
- transitionTo(mUninitializedState);
- break;
- default:
- return NOT_HANDLED;
- }
- StateChangeResult stateChangeResult = (StateChangeResult) msg.obj;
- SupplicantState supState = (SupplicantState) stateChangeResult.state;
- setDetailedState(WifiInfo.getDetailedStateOf(supState));
- mWifiInfo.setSupplicantState(supState);
- mWifiInfo.setNetworkId(stateChangeResult.networkId);
- return HANDLED;
- }
-
- /********************************************************
- * HSM states
- *******************************************************/
-
- class InitializedState extends HierarchicalState {
- @Override
- public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
- }
- @Override
- public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
- switch (message.what) {
- case CMD_START_SCAN:
- WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
- break;
- default:
- if (DBG) Log.w(TAG, "Ignoring " + message);
- break;
- }
- return HANDLED;
- }
- }
-
- class UninitializedState extends HierarchicalState {
- @Override
- public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
- mNetworkInfo.setIsAvailable(false);
- resetLoopDetection();
- mPasswordKeyMayBeIncorrect = false;
- }
- @Override
- public boolean processMessage(Message message) {
- switch(message.what) {
- default:
- if (!handleTransition(message)) {
- if (DBG) Log.w(TAG, "Ignoring " + message);
- }
- break;
- }
- return HANDLED;
- }
- @Override
- public void exit() {
- mNetworkInfo.setIsAvailable(true);
- }
- }
-
- class InactiveState extends HierarchicalState {
- @Override
- public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
-
- /* A failed WPS connection */
- if (mWpsStarted) {
- Log.e(TAG, "WPS set up failed, enabling other networks");
- WifiConfigStore.enableAllNetworks();
- mWpsStarted = false;
- }
-
- Message message = getCurrentMessage();
- StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
-
- mNetworkInfo.setIsAvailable(false);
- resetLoopDetection();
- mPasswordKeyMayBeIncorrect = false;
-
- sendSupplicantStateChangedBroadcast(stateChangeResult, false);
- }
- @Override
- public boolean processMessage(Message message) {
- return handleTransition(message);
- }
- @Override
- public void exit() {
- mNetworkInfo.setIsAvailable(true);
- }
- }
-
-
- class DisconnectedState extends HierarchicalState {
- @Override
- public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
- Message message = getCurrentMessage();
- StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
-
- resetLoopDetection();
-
- /* If a disconnect event happens after a password key failure
- * event, disable the network
- */
- if (mPasswordKeyMayBeIncorrect) {
- Log.d(TAG, "Failed to authenticate, disabling network " +
- mWifiInfo.getNetworkId());
- WifiConfigStore.disableNetwork(mWifiInfo.getNetworkId());
- mPasswordKeyMayBeIncorrect = false;
- sendSupplicantStateChangedBroadcast(stateChangeResult, true);
- }
- else {
- sendSupplicantStateChangedBroadcast(stateChangeResult, false);
- }
- }
- @Override
- public boolean processMessage(Message message) {
- return handleTransition(message);
- }
- }
-
- class ScanState extends HierarchicalState {
- @Override
- public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
- Message message = getCurrentMessage();
- StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
-
- mPasswordKeyMayBeIncorrect = false;
- resetLoopDetection();
- sendSupplicantStateChangedBroadcast(stateChangeResult, false);
- }
- @Override
- public boolean processMessage(Message message) {
- return handleTransition(message);
- }
- }
-
- class ConnectState extends HierarchicalState {
- @Override
- public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
- }
- @Override
- public boolean processMessage(Message message) {
- switch (message.what) {
- case CMD_START_SCAN:
- WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE);
- WifiNative.scanCommand(message.arg1 == SCAN_ACTIVE);
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
- }
-
- class HandshakeState extends HierarchicalState {
- @Override
- public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
- final Message message = getCurrentMessage();
- StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
-
- if (mLoopDetectIndex > message.what) {
- mLoopDetectCount++;
- }
- if (mLoopDetectCount > MAX_SUPPLICANT_LOOP_ITERATIONS) {
- WifiConfigStore.disableNetwork(stateChangeResult.networkId);
- mLoopDetectCount = 0;
- }
-
- mLoopDetectIndex = message.what;
-
- mPasswordKeyMayBeIncorrect = false;
- sendSupplicantStateChangedBroadcast(stateChangeResult, false);
- }
- @Override
- public boolean processMessage(Message message) {
- return handleTransition(message);
- }
- }
-
- class CompletedState extends HierarchicalState {
- @Override
- public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
- Message message = getCurrentMessage();
- StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
-
- mRssiPollToken++;
- if (mEnableRssiPolling) {
- sendMessageDelayed(obtainMessage(CMD_RSSI_POLL, mRssiPollToken, 0),
- POLL_RSSI_INTERVAL_MSECS);
- }
-
- resetLoopDetection();
-
- mPasswordKeyMayBeIncorrect = false;
- sendSupplicantStateChangedBroadcast(stateChangeResult, false);
- }
- @Override
- public boolean processMessage(Message message) {
- switch(message.what) {
- case ASSOCIATING:
- case ASSOCIATED:
- case FOUR_WAY_HANDSHAKE:
- case GROUP_HANDSHAKE:
- case COMPLETED:
- break;
- case CMD_RSSI_POLL:
- if (message.arg1 == mRssiPollToken) {
- // Get Info and continue polling
- requestPolledInfo();
- sendMessageDelayed(obtainMessage(CMD_RSSI_POLL, mRssiPollToken, 0),
- POLL_RSSI_INTERVAL_MSECS);
- } else {
- // Polling has completed
- }
- break;
- case CMD_ENABLE_RSSI_POLL:
- mRssiPollToken++;
- if (mEnableRssiPolling) {
- // first poll
- requestPolledInfo();
- sendMessageDelayed(obtainMessage(CMD_RSSI_POLL, mRssiPollToken, 0),
- POLL_RSSI_INTERVAL_MSECS);
- }
- break;
- default:
- return handleTransition(message);
- }
- return HANDLED;
- }
- }
-
- class DormantState extends HierarchicalState {
- @Override
- public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
- Message message = getCurrentMessage();
- StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
-
- resetLoopDetection();
- mPasswordKeyMayBeIncorrect = false;
-
- sendSupplicantStateChangedBroadcast(stateChangeResult, false);
-
- /* TODO: reconnect is now being handled at DHCP failure handling
- * If we run into issues with staying in Dormant state, might
- * need a reconnect here
- */
- }
- @Override
- public boolean processMessage(Message message) {
- return handleTransition(message);
- }
- }
- }
}