summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorRandy Pan <zpan@google.com>2017-02-24 15:08:35 -0800
committerRandy Pan <zpan@google.com>2017-03-21 16:11:22 -0700
commit167b90b5e002698378728a54a417a08c317d29dc (patch)
tree3a2fbe45da70fae0e0e3f8d16de0e3d4057473b3 /service
parent168fba718720b54cf0a88cfad7f96948925fb1e3 (diff)
Move BSSID blacklist to WifiConnectivityManager
Now the BSSID blacklist is managed by WifiConnectivityManager and passed to WifiNetworkSelector for scan results filtration. Bug: 35642214 Test: runtests.sh and manual tests Change-Id: I7afb5e66be471f3582075adb687a7d85ba49a80b
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/WifiConnectivityManager.java121
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkSelector.java109
2 files changed, 132 insertions, 98 deletions
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 4ae3a96a2..86b9782a4 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -39,9 +39,12 @@ import com.android.server.wifi.util.ScanResultUtil;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Set;
/**
@@ -162,6 +165,24 @@ public class WifiConnectivityManager {
private int mSecureBonus;
private int mBand5GHzBonus;
+ // BSSID blacklist
+ @VisibleForTesting
+ public static final int BSSID_BLACKLIST_THRESHOLD = 3;
+ @VisibleForTesting
+ public static final int BSSID_BLACKLIST_EXPIRE_TIME_MS = 5 * 60 * 1000;
+ private static class BssidBlacklistStatus {
+ // Number of times this BSSID has been rejected for association.
+ public int counter;
+ public boolean isBlacklisted;
+ public long blacklistedTimeStamp = RESET_TIME_STAMP;
+ }
+ private Map<String, BssidBlacklistStatus> mBssidBlacklist =
+ new HashMap<>();
+
+ // Association failure reason codes
+ @VisibleForTesting
+ public static final int REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA = 17;
+
// A helper to log debugging information in the local log buffer, which can
// be retrieved in bugreport.
private void localLog(String log) {
@@ -221,6 +242,9 @@ public class WifiConnectivityManager {
* false - if no candidate is selected by WifiNetworkSelector
*/
private boolean handleScanResults(List<ScanDetail> scanDetails, String listenerName) {
+ // Check if any blacklisted BSSIDs can be freed.
+ refreshBssidBlacklist();
+
if (mStateMachine.isLinkDebouncing() || mStateMachine.isSupplicantTransientState()) {
localLog(listenerName + " onResults: No network selection because linkDebouncing is "
+ mStateMachine.isLinkDebouncing() + " and supplicantTransient is "
@@ -231,7 +255,7 @@ public class WifiConnectivityManager {
localLog(listenerName + " onResults: start network selection");
WifiConfiguration candidate =
- mNetworkSelector.selectNetwork(scanDetails, mWifiInfo,
+ mNetworkSelector.selectNetwork(scanDetails, buildBssidBlacklist(), mWifiInfo,
mStateMachine.isConnected(), mStateMachine.isDisconnected(),
mUntrustedConnectionAllowed);
mWifiLastResortWatchdog.updateAvailableNetworks(
@@ -987,23 +1011,110 @@ public class WifiConnectivityManager {
}
/**
+ * Update the BSSID blacklist when a BSSID is enabled or disabled
+ *
+ * @param bssid the bssid to be enabled/disabled
+ * @param enable -- true enable the bssid
+ * -- false disable the bssid
+ * @param reasonCode enable/disable reason code
+ * @return true if blacklist is updated; false otherwise
+ */
+ private boolean updateBssidBlacklist(String bssid, boolean enable, int reasonCode) {
+ // Remove the bssid from blacklist when it is enabled.
+ if (enable) {
+ return mBssidBlacklist.remove(bssid) != null;
+ }
+
+ // Update the bssid's blacklist status when it is disabled because of
+ // assocation rejection.
+ BssidBlacklistStatus status = mBssidBlacklist.get(bssid);
+ if (status == null) {
+ // First time for this BSSID
+ status = new BssidBlacklistStatus();
+ mBssidBlacklist.put(bssid, status);
+ }
+
+ status.blacklistedTimeStamp = mClock.getElapsedSinceBootMillis();
+ status.counter++;
+ if (!status.isBlacklisted) {
+ if (status.counter >= BSSID_BLACKLIST_THRESHOLD
+ || reasonCode == REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA) {
+ status.isBlacklisted = true;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Track whether a BSSID should be enabled or disabled for WifiNetworkSelector
+ *
+ * @param bssid the bssid to be enabled/disabled
+ * @param enable -- true enable the bssid
+ * -- false disable the bssid
+ * @param reasonCode enable/disable reason code
+ * @return true if blacklist is updated; false otherwise
*/
public boolean trackBssid(String bssid, boolean enable, int reasonCode) {
localLog("trackBssid: " + (enable ? "enable " : "disable ") + bssid + " reason code "
+ reasonCode);
- boolean ret = mNetworkSelector
- .enableBssidForNetworkSelection(bssid, enable, reasonCode);
+ if (bssid == null) {
+ return false;
+ }
- if (ret && !enable) {
+ boolean updated = updateBssidBlacklist(bssid, enable, reasonCode);
+
+ if (updated && !enable) {
// Disabling a BSSID can happen when the AP candidate to connect to has
// no capacity for new stations. We start another scan immediately so that
// WifiNetworkSelector can give us another candidate to connect to.
startConnectivityScan(SCAN_IMMEDIATELY);
}
- return ret;
+ return updated;
+ }
+
+ /**
+ * Check whether a bssid is disabled
+ */
+ @VisibleForTesting
+ public boolean isBssidDisabled(String bssid) {
+ BssidBlacklistStatus status = mBssidBlacklist.get(bssid);
+ return status == null ? false : status.isBlacklisted;
+ }
+
+ /**
+ * Compile and return a hashset of the blacklisted BSSIDs
+ */
+ private HashSet<String> buildBssidBlacklist() {
+ HashSet<String> blacklistedBssids = new HashSet<String>();
+ for (String bssid : mBssidBlacklist.keySet()) {
+ if (isBssidDisabled(bssid)) {
+ blacklistedBssids.add(bssid);
+ }
+ }
+
+ return blacklistedBssids;
+ }
+
+ /**
+ * Refresh the BSSID blacklist
+ *
+ * Go through the BSSID blacklist and check if a BSSID has been blacklisted for
+ * BSSID_BLACKLIST_EXPIRE_TIME_MS. If yes, re-enable it.
+ */
+ private void refreshBssidBlacklist() {
+ Iterator<BssidBlacklistStatus> iter = mBssidBlacklist.values().iterator();
+ Long currentTimeStamp = mClock.getElapsedSinceBootMillis();
+
+ while (iter.hasNext()) {
+ BssidBlacklistStatus status = iter.next();
+ if (status.isBlacklisted && ((currentTimeStamp - status.blacklistedTimeStamp)
+ >= BSSID_BLACKLIST_EXPIRE_TIME_MS)) {
+ iter.remove();
+ }
+ }
}
/**
diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java
index 956fe629c..5b3bc24ed 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSelector.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java
@@ -34,10 +34,8 @@ import com.android.internal.annotations.VisibleForTesting;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
+import java.util.HashSet;
import java.util.List;
-import java.util.Map;
/**
* This class looks at all the connectivity scan results then
@@ -50,24 +48,8 @@ public class WifiNetworkSelector {
@VisibleForTesting
public static final int MINIMUM_NETWORK_SELECTION_INTERVAL_MS = 10 * 1000;
- // Constants for BSSID blacklist.
- public static final int BSSID_BLACKLIST_THRESHOLD = 3;
- public static final int BSSID_BLACKLIST_EXPIRE_TIME_MS = 5 * 60 * 1000;
-
- // Association success/failure reason codes
- @VisibleForTesting
- public static final int REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA = 17;
-
private WifiConfigManager mWifiConfigManager;
private Clock mClock;
- private static class BssidBlacklistStatus {
- // Number of times this BSSID has been rejected for association.
- public int counter;
- public boolean isBlacklisted;
- public long blacklistedTimeStamp = INVALID_TIME_STAMP;
- }
- private Map<String, BssidBlacklistStatus> mBssidBlacklist =
- new HashMap<>();
private final LocalLog mLocalLog =
new LocalLog(ActivityManager.isLowRamDeviceStatic() ? 256 : 512);
@@ -258,8 +240,8 @@ public class WifiNetworkSelector {
return (network.SSID + ":" + network.networkId);
}
- private List<ScanDetail> filterScanResults(List<ScanDetail> scanDetails, boolean isConnected,
- String currentBssid) {
+ private List<ScanDetail> filterScanResults(List<ScanDetail> scanDetails,
+ HashSet<String> bssidBlacklist, boolean isConnected, String currentBssid) {
ArrayList<NetworkKey> unscoredNetworks = new ArrayList<NetworkKey>();
List<ScanDetail> validScanDetails = new ArrayList<ScanDetail>();
StringBuffer noValidSsid = new StringBuffer();
@@ -282,7 +264,7 @@ public class WifiNetworkSelector {
final String scanId = toScanId(scanResult);
- if (isBssidDisabled(scanResult.BSSID)) {
+ if (bssidBlacklist.contains(scanResult.BSSID)) {
blacklistedBssid.append(scanId).append(" / ");
continue;
}
@@ -433,75 +415,19 @@ public class WifiNetworkSelector {
}
/**
- * Enable/disable a BSSID for Network Selection
- * When an association rejection event is obtained, Network Selector will disable this
- * BSSID but supplicant still can try to connect to this bssid. If supplicant connect to it
- * successfully later, this bssid can be re-enabled.
- *
- * @param bssid the bssid to be enabled / disabled
- * @param enable -- true enable a bssid if it has been disabled
- * -- false disable a bssid
- * @param reasonCode enable/disable reason code
- */
- public boolean enableBssidForNetworkSelection(String bssid, boolean enable, int reasonCode) {
- if (enable) {
- return (mBssidBlacklist.remove(bssid) != null);
- } else {
- if (bssid != null) {
- BssidBlacklistStatus status = mBssidBlacklist.get(bssid);
- if (status == null) {
- // First time for this BSSID
- status = new BssidBlacklistStatus();
- mBssidBlacklist.put(bssid, status);
- }
-
- if (!status.isBlacklisted) {
- status.counter++;
- if (status.counter >= BSSID_BLACKLIST_THRESHOLD
- || reasonCode == REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA) {
- status.isBlacklisted = true;
- status.blacklistedTimeStamp = mClock.getElapsedSinceBootMillis();
- return true;
- }
- }
- }
- }
- return false;
- }
-
- /**
- * Update the BSSID blacklist
- *
- * Go through the BSSID blacklist and check when a BSSID was blocked. If it
- * has been blacklisted for BSSID_BLACKLIST_EXPIRE_TIME_MS, then re-enable it.
- */
- private void updateBssidBlacklist() {
- Iterator<BssidBlacklistStatus> iter = mBssidBlacklist.values().iterator();
- while (iter.hasNext()) {
- BssidBlacklistStatus status = iter.next();
- if (status != null && status.isBlacklisted) {
- if (mClock.getElapsedSinceBootMillis() - status.blacklistedTimeStamp
- >= BSSID_BLACKLIST_EXPIRE_TIME_MS) {
- iter.remove();
- }
- }
- }
- }
-
- /**
- * Check whether a bssid is disabled
- * @param bssid -- the bssid to check
- */
- private boolean isBssidDisabled(String bssid) {
- BssidBlacklistStatus status = mBssidBlacklist.get(bssid);
- return status == null ? false : status.isBlacklisted;
- }
-
- /**
+ * Select the best network from the ones in range.
*
+ * @param scanDetails List of ScanDetail for all the APs in range
+ * @param bssidBlacklist Blacklisted BSSIDs
+ * @param wifiInfo Currently connected network
+ * @param connected True if the device is connected
+ * @param disconnected True if the device is disconnected
+ * @param untrustedNetworkAllowed True if untrusted networks are allowed for connection
+ * @return Configuration of the selected network, or Null if nothing
*/
@Nullable
- public WifiConfiguration selectNetwork(List<ScanDetail> scanDetails, WifiInfo wifiInfo,
+ public WifiConfiguration selectNetwork(List<ScanDetail> scanDetails,
+ HashSet<String> bssidBlacklist, WifiInfo wifiInfo,
boolean connected, boolean disconnected, boolean untrustedNetworkAllowed) {
mConnectableNetworks.clear();
if (scanDetails.size() == 0) {
@@ -528,12 +454,9 @@ public class WifiNetworkSelector {
}
}
- // Check if any BSSID can be freed from the blacklist.
- updateBssidBlacklist();
-
// Filter out unwanted networks.
- List<ScanDetail> filteredScanDetails = filterScanResults(scanDetails, connected,
- currentBssid);
+ List<ScanDetail> filteredScanDetails = filterScanResults(scanDetails, bssidBlacklist,
+ connected, currentBssid);
if (filteredScanDetails.size() == 0) {
return null;
}