summaryrefslogtreecommitdiffstats
path: root/wifi
diff options
context:
space:
mode:
Diffstat (limited to 'wifi')
-rw-r--r--wifi/java/android/net/wifi/SupplicantState.java44
-rw-r--r--wifi/java/android/net/wifi/SupplicantStateTracker.java22
-rw-r--r--wifi/java/android/net/wifi/WifiInfo.java2
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java7
-rw-r--r--wifi/java/android/net/wifi/WifiMonitor.java11
-rw-r--r--wifi/java/android/net/wifi/WifiNative.java4
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java86
7 files changed, 126 insertions, 50 deletions
diff --git a/wifi/java/android/net/wifi/SupplicantState.java b/wifi/java/android/net/wifi/SupplicantState.java
index 6b79210..91e685f 100644
--- a/wifi/java/android/net/wifi/SupplicantState.java
+++ b/wifi/java/android/net/wifi/SupplicantState.java
@@ -39,6 +39,15 @@ public enum SupplicantState implements Parcelable {
DISCONNECTED,
/**
+ * Interface is disabled
+ * <p/>
+ * This state is entered if the network interface is disabled.
+ * wpa_supplicant refuses any new operations that would
+ * use the radio until the interface has been enabled.
+ */
+ INTERFACE_DISABLED,
+
+ /**
* Inactive state (wpa_supplicant disabled).
* <p/>
* This state is entered if there are no enabled networks in the
@@ -57,6 +66,15 @@ public enum SupplicantState implements Parcelable {
SCANNING,
/**
+ * Trying to authenticate with a BSS/SSID
+ * <p/>
+ * This state is entered when wpa_supplicant has found a suitable BSS
+ * to authenticate with and the driver is configured to try to
+ * authenticate with this BSS.
+ */
+ AUTHENTICATING,
+
+ /**
* Trying to associate with a BSS/SSID.
* <p/>
* This state is entered when wpa_supplicant has found a suitable BSS
@@ -152,8 +170,33 @@ public enum SupplicantState implements Parcelable {
return state != UNINITIALIZED && state != INVALID;
}
+
+ /* Supplicant associating or authenticating is considered a handshake state */
+ static boolean isHandshakeState(SupplicantState state) {
+ switch(state) {
+ case AUTHENTICATING:
+ case ASSOCIATING:
+ case ASSOCIATED:
+ case FOUR_WAY_HANDSHAKE:
+ case GROUP_HANDSHAKE:
+ return true;
+ case COMPLETED:
+ case DISCONNECTED:
+ case INTERFACE_DISABLED:
+ case INACTIVE:
+ case SCANNING:
+ case DORMANT:
+ case UNINITIALIZED:
+ case INVALID:
+ return false;
+ default:
+ throw new IllegalArgumentException("Unknown supplicant state");
+ }
+ }
+
static boolean isConnecting(SupplicantState state) {
switch(state) {
+ case AUTHENTICATING:
case ASSOCIATING:
case ASSOCIATED:
case FOUR_WAY_HANDSHAKE:
@@ -161,6 +204,7 @@ public enum SupplicantState implements Parcelable {
case COMPLETED:
return true;
case DISCONNECTED:
+ case INTERFACE_DISABLED:
case INACTIVE:
case SCANNING:
case DORMANT:
diff --git a/wifi/java/android/net/wifi/SupplicantStateTracker.java b/wifi/java/android/net/wifi/SupplicantStateTracker.java
index 9ae26da..0c4f9f6 100644
--- a/wifi/java/android/net/wifi/SupplicantStateTracker.java
+++ b/wifi/java/android/net/wifi/SupplicantStateTracker.java
@@ -98,12 +98,16 @@ class SupplicantStateTracker extends StateMachine {
if (DBG) Log.d(TAG, "Supplicant state: " + supState.toString() + "\n");
switch (supState) {
- case DISCONNECTED:
+ case DISCONNECTED:
transitionTo(mDisconnectState);
break;
+ case INTERFACE_DISABLED:
+ //we should have received a disconnection already, do nothing
+ break;
case SCANNING:
transitionTo(mScanState);
break;
+ case AUTHENTICATING:
case ASSOCIATING:
case ASSOCIATED:
case FOUR_WAY_HANDSHAKE:
@@ -250,10 +254,7 @@ class SupplicantStateTracker extends StateMachine {
case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT:
StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
SupplicantState state = stateChangeResult.state;
- if (state == SupplicantState.ASSOCIATING ||
- state == SupplicantState.ASSOCIATED ||
- state == SupplicantState.FOUR_WAY_HANDSHAKE ||
- state == SupplicantState.GROUP_HANDSHAKE) {
+ if (SupplicantState.isHandshakeState(state)) {
if (mLoopDetectIndex > state.ordinal()) {
mLoopDetectCount++;
}
@@ -296,12 +297,11 @@ class SupplicantStateTracker extends StateMachine {
StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
SupplicantState state = stateChangeResult.state;
sendSupplicantStateChangedBroadcast(state, 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) {
+ /* Ignore any connecting state in completed state. Group re-keying
+ * events and other auth events that do not affect connectivity are
+ * ignored
+ */
+ if (SupplicantState.isConnecting(state)) {
break;
}
transitionOnSupplicantStateChange(stateChangeResult);
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index f60ae48..e3661bf 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -41,8 +41,10 @@ public class WifiInfo implements Parcelable {
static {
stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED);
+ stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED);
stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE);
stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING);
+ stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING);
stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING);
stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING);
stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING);
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 949e80f..9d1bdd4 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1194,16 +1194,19 @@ public class WifiManager {
* Acquiring a WifiLock will keep the radio on until the lock is released. Multiple
* applications may hold WifiLocks, and the radio will only be allowed to turn off when no
* WifiLocks are held in any application.
- *
+ * <p>
* Before using a WifiLock, consider carefully if your application requires Wi-Fi access, or
* could function over a mobile network, if available. A program that needs to download large
* files should hold a WifiLock to ensure that the download will complete, but a program whose
* network usage is occasional or low-bandwidth should not hold a WifiLock to avoid adversely
* affecting battery life.
- *
+ * <p>
* Note that WifiLocks cannot override the user-level "Wi-Fi Enabled" setting, nor Airplane
* Mode. They simply keep the radio from turning off when Wi-Fi is already on but the device
* is idle.
+ * <p>
+ * Any application using a WifiLock must request the {@code android.permission.WAKE_LOCK}
+ * permission in an {@code &lt;uses-permission&gt;} element of the application's manifest.
*/
public class WifiLock {
private String mTag;
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index ce38261..4a45825 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -17,7 +17,6 @@
package android.net.wifi;
import android.util.Log;
-import android.util.Config;
import android.net.NetworkInfo;
import java.util.regex.Pattern;
@@ -182,7 +181,7 @@ public class WifiMonitor {
String eventStr = WifiNative.waitForEvent();
// Skip logging the common but mostly uninteresting scan-results event
- if (Config.LOGD && eventStr.indexOf(scanResultsEvent) == -1) {
+ if (false && eventStr.indexOf(scanResultsEvent) == -1) {
Log.v(TAG, "Event [" + eventStr + "]");
}
if (!eventStr.startsWith(eventPrefix)) {
@@ -200,7 +199,7 @@ public class WifiMonitor {
if (nameEnd != -1)
eventName = eventName.substring(0, nameEnd);
if (eventName.length() == 0) {
- if (Config.LOGD) Log.i(TAG, "Received wpa_supplicant event with empty event name");
+ if (false) Log.i(TAG, "Received wpa_supplicant event with empty event name");
continue;
}
/*
@@ -251,7 +250,7 @@ public class WifiMonitor {
* stopped the supplicant, simply exit the monitor thread
*/
if (eventData.startsWith(monitorSocketClosed)) {
- if (Config.LOGD) {
+ if (false) {
Log.d(TAG, "Monitor socket is closed, exiting thread");
}
break;
@@ -263,7 +262,7 @@ public class WifiMonitor {
*/
if (eventData.startsWith(wpaRecvError)) {
if (++mRecvErrors > MAX_RECV_ERRORS) {
- if (Config.LOGD) {
+ if (false) {
Log.d(TAG, "too many recv errors, closing connection");
}
} else {
@@ -398,7 +397,7 @@ public class WifiMonitor {
if (newState == NetworkInfo.DetailedState.CONNECTED) {
Matcher match = mConnectedEventPattern.matcher(data);
if (!match.find()) {
- if (Config.LOGD) Log.d(TAG, "Could not find BSSID in CONNECTED event string");
+ if (false) Log.d(TAG, "Could not find BSSID in CONNECTED event string");
} else {
BSSID = match.group(1);
try {
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 909605dc..6e13d0f 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -171,5 +171,7 @@ public class WifiNative {
*/
public native static String waitForEvent();
- public native static void enableBackgroundScan(boolean enable);
+ public native static void enableBackgroundScanCommand(boolean enable);
+
+ public native static void setScanIntervalCommand(int scanInterval);
}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index e03680f..bd6da64 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -351,10 +351,20 @@ public class WifiStateMachine extends StateMachine {
private int mPowerMode = POWER_MODE_AUTO;
/**
- * See {@link Settings.Secure#WIFI_SCAN_INTERVAL_MS}. This is the default value if a
- * Settings.Secure value is not present.
+ * Default framework scan interval in milliseconds. This is used in the scenario in which
+ * wifi chipset does not support background scanning to set up a
+ * periodic wake up scan so that the device can connect to a new access
+ * point on the move. {@link Settings.Secure#WIFI_FRAMEWORK_SCAN_INTERVAL_MS} can
+ * override this.
*/
- private static final long DEFAULT_SCAN_INTERVAL_MS = 60 * 1000; /* 1 minute */
+ private final int mDefaultFrameworkScanIntervalMs;
+
+ /**
+ * Default supplicant scan interval in milliseconds.
+ * {@link Settings.Secure#WIFI_SUPPLICANT_SCAN_INTERVAL_MS} can override this.
+ */
+ private final int mDefaultSupplicantScanIntervalMs;
+
private static final int MIN_RSSI = -200;
private static final int MAX_RSSI = 256;
@@ -488,6 +498,12 @@ public class WifiStateMachine extends StateMachine {
Intent scanIntent = new Intent(ACTION_START_SCAN, null);
mScanIntent = PendingIntent.getBroadcast(mContext, SCAN_REQUEST, scanIntent, 0);
+ mDefaultFrameworkScanIntervalMs = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_wifi_framework_scan_interval);
+
+ mDefaultSupplicantScanIntervalMs = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_wifi_supplicant_scan_interval);
+
mContext.registerReceiver(
new BroadcastReceiver() {
@Override
@@ -847,7 +863,7 @@ public class WifiStateMachine extends StateMachine {
sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0));
}
- public void enableBackgroundScan(boolean enabled) {
+ public void enableBackgroundScanCommand(boolean enabled) {
sendMessage(obtainMessage(CMD_ENABLE_BACKGROUND_SCAN, enabled ? 1 : 0, 0));
}
@@ -2096,6 +2112,11 @@ public class WifiStateMachine extends StateMachine {
mIsScanMode = false;
/* Wifi is available as long as we have a connection to supplicant */
mNetworkInfo.setIsAvailable(true);
+ /* Set scan interval */
+ long supplicantScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(),
+ Settings.Secure.WIFI_SUPPLICANT_SCAN_INTERVAL_MS,
+ mDefaultSupplicantScanIntervalMs);
+ WifiNative.setScanIntervalCommand((int)supplicantScanIntervalMs / 1000);
}
@Override
public boolean processMessage(Message message) {
@@ -2104,17 +2125,6 @@ public class WifiStateMachine extends StateMachine {
boolean eventLoggingEnabled = true;
switch(message.what) {
case CMD_STOP_SUPPLICANT: /* Supplicant stopped by user */
- Log.d(TAG, "stopping supplicant");
- if (!WifiNative.stopSupplicant()) {
- Log.e(TAG, "Failed to stop supplicant, issue kill");
- WifiNative.killSupplicant();
- }
- mNetworkInfo.setIsAvailable(false);
- handleNetworkDisconnect();
- setWifiState(WIFI_STATE_DISABLING);
- sendSupplicantConnectionChangedBroadcast(false);
- mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
- mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
transitionTo(mSupplicantStoppingState);
break;
case SUP_DISCONNECTION_EVENT: /* Supplicant connection lost */
@@ -2215,6 +2225,17 @@ public class WifiStateMachine extends StateMachine {
public void enter() {
if (DBG) Log.d(TAG, getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
+ Log.d(TAG, "stopping supplicant");
+ if (!WifiNative.stopSupplicant()) {
+ Log.e(TAG, "Failed to stop supplicant, issue kill");
+ WifiNative.killSupplicant();
+ }
+ mNetworkInfo.setIsAvailable(false);
+ handleNetworkDisconnect();
+ setWifiState(WIFI_STATE_DISABLING);
+ sendSupplicantConnectionChangedBroadcast(false);
+ mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
+ mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE);
}
@Override
public boolean processMessage(Message message) {
@@ -2869,17 +2890,21 @@ public class WifiStateMachine extends StateMachine {
class DisconnectedState extends State {
private boolean mAlarmEnabled = false;
- private long mScanIntervalMs;
+ /* This is set from the overlay config file or from a secure setting.
+ * A value of 0 disables scanning in the framework.
+ */
+ private long mFrameworkScanIntervalMs;
private void setScanAlarm(boolean enabled) {
if (enabled == mAlarmEnabled) return;
if (enabled) {
- mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
- System.currentTimeMillis() + mScanIntervalMs,
- mScanIntervalMs,
- mScanIntent);
-
- mAlarmEnabled = true;
+ if (mFrameworkScanIntervalMs > 0) {
+ mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
+ System.currentTimeMillis() + mFrameworkScanIntervalMs,
+ mFrameworkScanIntervalMs,
+ mScanIntent);
+ mAlarmEnabled = true;
+ }
} else {
mAlarmManager.cancel(mScanIntent);
mAlarmEnabled = false;
@@ -2891,8 +2916,9 @@ public class WifiStateMachine extends StateMachine {
if (DBG) Log.d(TAG, getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
- mScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(),
- Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS);
+ mFrameworkScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(),
+ Settings.Secure.WIFI_FRAMEWORK_SCAN_INTERVAL_MS,
+ mDefaultFrameworkScanIntervalMs);
/*
* We initiate background scanning if it is enabled, otherwise we
* initiate an infrequent scan that wakes up the device to ensure
@@ -2906,7 +2932,7 @@ public class WifiStateMachine extends StateMachine {
* cleared
*/
if (!mScanResultIsPending) {
- WifiNative.enableBackgroundScan(true);
+ WifiNative.enableBackgroundScanCommand(true);
}
} else {
setScanAlarm(true);
@@ -2928,10 +2954,10 @@ public class WifiStateMachine extends StateMachine {
case CMD_ENABLE_BACKGROUND_SCAN:
mEnableBackgroundScan = (message.arg1 == 1);
if (mEnableBackgroundScan) {
- WifiNative.enableBackgroundScan(true);
+ WifiNative.enableBackgroundScanCommand(true);
setScanAlarm(false);
} else {
- WifiNative.enableBackgroundScan(false);
+ WifiNative.enableBackgroundScanCommand(false);
setScanAlarm(true);
}
break;
@@ -2946,14 +2972,14 @@ public class WifiStateMachine extends StateMachine {
case CMD_START_SCAN:
/* Disable background scan temporarily during a regular scan */
if (mEnableBackgroundScan) {
- WifiNative.enableBackgroundScan(false);
+ WifiNative.enableBackgroundScanCommand(false);
}
/* Handled in parent state */
return NOT_HANDLED;
case SCAN_RESULTS_EVENT:
/* Re-enable background scan when a pending scan result is received */
if (mEnableBackgroundScan && mScanResultIsPending) {
- WifiNative.enableBackgroundScan(true);
+ WifiNative.enableBackgroundScanCommand(true);
}
/* Handled in parent state */
return NOT_HANDLED;
@@ -2968,7 +2994,7 @@ public class WifiStateMachine extends StateMachine {
public void exit() {
/* No need for a background scan upon exit from a disconnected state */
if (mEnableBackgroundScan) {
- WifiNative.enableBackgroundScan(false);
+ WifiNative.enableBackgroundScanCommand(false);
}
setScanAlarm(false);
}