summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxinhe <xinhe@google.com>2016-02-16 11:28:39 -0800
committerxinhe <xinhe@google.com>2016-02-16 14:46:11 -0800
commit6ed97affc9bbce6497b6155285ba4a71196d69e1 (patch)
treeab42d21484cd8709df5c78bb5240cb9d0e4d931e
parentd2995af00d433ea6f952e8ff1c82c0ed2c71a274 (diff)
Modify BSSID blacklist behavior
The new behaviors are: (1) If a BSSID get association rejection three times, blacklist it (2) After 30 min of blacklist, we re-enable it again. (3) If any connect successfully to the BSSID, re-enable it BUG=27166673 Change-Id: I70f439b524ffc304d6c61744f90389f47006341b
-rw-r--r--service/java/com/android/server/wifi/WifiQualifiedNetworkSelection.java65
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java6
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiQualifiedNetworkSelectionTest.java139
3 files changed, 178 insertions, 32 deletions
diff --git a/service/java/com/android/server/wifi/WifiQualifiedNetworkSelection.java b/service/java/com/android/server/wifi/WifiQualifiedNetworkSelection.java
index 869bbc7ba..82e82fdc3 100644
--- a/service/java/com/android/server/wifi/WifiQualifiedNetworkSelection.java
+++ b/service/java/com/android/server/wifi/WifiQualifiedNetworkSelection.java
@@ -31,8 +31,10 @@ import com.android.internal.R;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.util.HashSet;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
class WifiQualifiedNetworkSelector {
private WifiConfigStore mWifiConfigStore;
@@ -72,6 +74,8 @@ class WifiQualifiedNetworkSelector {
public static final int LAST_SELECTION_AWARD = 480;
public static final int PASSPOINT_SECURITY_AWARD = 40;
public static final int SECURITY_AWARD = 80;
+ public static final int BSSID_BLACKLIST_THRESHOLD = 3;
+ public static final int BSSID_BLACKLIST_EXPIRE_TIME = 30 * 60 * 1000;
private final int mNoIntnetPenalty;
//TODO: check whether we still need this one when we update the scan manager
public static final int SCAN_RESULT_MAXIMUNM_AGE = 40000;
@@ -87,7 +91,19 @@ class WifiQualifiedNetworkSelector {
private int mPasspointSecurityAward = PASSPOINT_SECURITY_AWARD;
private int mSecurityAward = SECURITY_AWARD;
private int mUserPreferedBand = WifiManager.WIFI_FREQUENCY_BAND_AUTO;
- private HashSet<String> mBssidBlacklist = new HashSet<String>();
+ private Map<String, BssidBlacklistStatus> mBssidBlacklist =
+ new HashMap<String, BssidBlacklistStatus>();
+
+ /**
+ * class save the blacklist status of a given BSSID
+ */
+ private static class BssidBlacklistStatus {
+ //how many times it is requested to be blacklisted (association rejection trigger this)
+ int mCounter;
+ boolean mIsBlacklisted;
+ long mBlacklistedTimeStamp = INVALID_TIME_STAMP;
+ }
+
private void qnsLog(String log) {
if (mDbg) {
mLocalLog.log(log);
@@ -512,26 +528,60 @@ class WifiQualifiedNetworkSelector {
* @param enable -- true enable a bssid if it has been disabled
* -- false disable a bssid
*/
- public boolean enableBssidForQualitynetworkSelection(String bssid, boolean enable) {
+ public boolean enableBssidForQualityNetworkSelection(String bssid, boolean enable) {
if (enable) {
- return mBssidBlacklist.remove(bssid);
+ return (mBssidBlacklist.remove(bssid) != null);
} else {
if (bssid != null) {
- mBssidBlacklist.add(bssid);
- return true;
+ BssidBlacklistStatus status = mBssidBlacklist.get(bssid);
+ if (status == null) {
+ //first time
+ BssidBlacklistStatus newStatus = new BssidBlacklistStatus();
+ newStatus.mCounter++;
+ mBssidBlacklist.put(bssid, newStatus);
+ } else if (!status.mIsBlacklisted) {
+ status.mCounter++;
+ if (status.mCounter >= BSSID_BLACKLIST_THRESHOLD) {
+ status.mIsBlacklisted = true;
+ status.mBlacklistedTimeStamp = mClock.currentTimeMillis();
+ return true;
+ }
+ }
}
}
return false;
}
/**
+ * update the buffered BSSID blacklist
+ *
+ * Go through the whole buffered BSSIDs blacklist and check when the BSSIDs is blocked. If they
+ * were blacked before BSSID_BLACKLIST_EXPIRE_TIME, re-enable it again.
+ */
+ private void updateBssidBlacklist() {
+ Set<String> keys = mBssidBlacklist.keySet();
+ if (keys != null && keys.size() > 0) {
+ for (String bssid : keys) {
+ BssidBlacklistStatus status = mBssidBlacklist.get(bssid);
+ if (status != null && status.mIsBlacklisted) {
+ if (mClock.currentTimeMillis() - status.mBlacklistedTimeStamp
+ >= BSSID_BLACKLIST_EXPIRE_TIME) {
+ enableBssidForQualityNetworkSelection(bssid, true);
+ }
+ }
+ }
+ }
+ }
+
+ /**
* Check whether a bssid is disabled
* @param bssid -- the bssid to check
* @return true -- bssid is disabled
* false -- bssid is not disabled
*/
public boolean isBssidDisabled(String bssid) {
- return mBssidBlacklist.contains(bssid);
+ BssidBlacklistStatus status = mBssidBlacklist.get(bssid);
+ return status == null ? false : status.mIsBlacklisted;
}
/**
@@ -595,6 +645,7 @@ class WifiQualifiedNetworkSelector {
}
updateSavedNetworkSelectionStatus();
+ updateBssidBlacklist();
StringBuffer lowSignalScan = new StringBuffer();
StringBuffer notSavedScan = new StringBuffer();
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index aad147161..a57d55a38 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -6953,7 +6953,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
// If we have a BSSID, tell configStore to black list it
synchronized(mScanResultCache) {
didBlackListBSSID = mWifiQualifiedNetworkSelector
- .enableBssidForQualitynetworkSelection(bssid, false);
+ .enableBssidForQualityNetworkSelection(bssid, false);
}
}
@@ -7775,6 +7775,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
mWifiInfo.setBSSID(mLastBssid);
mWifiInfo.setNetworkId(mLastNetworkId);
+ mWifiQualifiedNetworkSelector
+ .enableBssidForQualityNetworkSelection(mLastBssid, true);
sendNetworkStateChangeBroadcast(mLastBssid);
transitionTo(mObtainingIpState);
break;
@@ -8671,7 +8673,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
mLastBssid = (String) message.obj;
mWifiInfo.setBSSID(mLastBssid);
mWifiInfo.setNetworkId(mLastNetworkId);
- mWifiQualifiedNetworkSelector.enableBssidForQualitynetworkSelection(
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(
mLastBssid, true);
sendNetworkStateChangeBroadcast(mLastBssid);
transitionTo(mObtainingIpState);
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiQualifiedNetworkSelectionTest.java b/tests/wifitests/src/com/android/server/wifi/WifiQualifiedNetworkSelectionTest.java
index 987246566..ce2a53cf0 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiQualifiedNetworkSelectionTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiQualifiedNetworkSelectionTest.java
@@ -677,22 +677,29 @@ public class WifiQualifiedNetworkSelectionTest {
assertEquals("bssidB should be enabled by default",
mWifiQualifiedNetworkSelector.isBssidDisabled(bssidB), false);
- //disable bssidA, check whether A is dsiabled and B is still enabled
- mWifiQualifiedNetworkSelector.enableBssidForQualitynetworkSelection(bssidA, false);
+ //disable bssidA 3 times, check whether A is dsiabled and B is still enabled
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssidA, false);
+ assertEquals("bssidA should be disabled",
+ mWifiQualifiedNetworkSelector.isBssidDisabled(bssidA), false);
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssidA, false);
+ assertEquals("bssidA should be disabled",
+ mWifiQualifiedNetworkSelector.isBssidDisabled(bssidA), false);
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssidA, false);
assertEquals("bssidA should be disabled",
mWifiQualifiedNetworkSelector.isBssidDisabled(bssidA), true);
assertEquals("bssidB should still be enabled",
mWifiQualifiedNetworkSelector.isBssidDisabled(bssidB), false);
//re-enable bssidA, check whether A is dsiabled and B is still enabled
- mWifiQualifiedNetworkSelector.enableBssidForQualitynetworkSelection(bssidA, true);
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssidA, true);
assertEquals("bssidA should be enabled by default",
mWifiQualifiedNetworkSelector.isBssidDisabled(bssidA), false);
assertEquals("bssidB should be enabled by default",
mWifiQualifiedNetworkSelector.isBssidDisabled(bssidB), false);
//make sure illegal input will not cause crash
- mWifiQualifiedNetworkSelector.enableBssidForQualitynetworkSelection(null, true);
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(null, false);
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(null, true);
}
/**
@@ -726,7 +733,51 @@ public class WifiQualifiedNetworkSelectionTest {
scanResultLinkConfiguration(savedConfigs, scanDetails);
ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
- mWifiQualifiedNetworkSelector.enableBssidForQualitynetworkSelection(bssids[1], false);
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssids[1], false);
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssids[1], false);
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssids[1], false);
+ WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
+ false, scanDetails, false, false, true, false);
+
+ verifySelectedResult(chosenScanResult, candidate);
+ }
+
+ /**
+ * Case #14 re-choose the disabled BSSID after it is re-enabled
+ *
+ * In this test. we simulate following scenario:
+ * WifiStateMachine is under disconnected state
+ * Two networks test1, test2 are secured network and found in scan results
+ * Both network are enabled
+ * test1 is @ 2GHz with RSSI -65
+ * test2 is @ 5Ghz with RSSI -50
+ * test2's BSSID is disabled
+ *
+ * expected return test2 since test2's BSSID has been enabled again
+ */
+ @Test
+ public void networkChooseWithOneBssidReenaabled() {
+ String[] ssids = DEFAULT_SSIDS;
+ String[] bssids = DEFAULT_BSSIDS;
+ int[] frequencies = {2437, 5180};
+ String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS][ESS]"};
+ int[] levels = {-65, -50};
+ int[] security = {SECURITY_PSK, SECURITY_PSK};
+
+ List<ScanDetail> scanDetails = getScanDetails(ssids, bssids, frequencies, caps, levels);
+ WifiConfiguration[] savedConfigs = generateWifiConfigurations(ssids, security);
+ prepareConfigStore(savedConfigs);
+
+ final List<WifiConfiguration> savedNetwork = Arrays.asList(savedConfigs);
+ when(mWifiConfigStore.getConfiguredNetworks()).thenReturn(savedNetwork);
+ scanResultLinkConfiguration(savedConfigs, scanDetails);
+ ScanResult chosenScanResult = scanDetails.get(1).getScanResult();
+
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssids[1], false);
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssids[1], false);
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssids[1], false);
+ //re-enable it
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssids[1], true);
WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
false, scanDetails, false, false, true, false);
@@ -734,7 +785,49 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #14 do not choose the SSID has been disabled
+ * Case #15 re-choose the disabled BSSID after its disability has expired
+ *
+ * In this test. we simulate following scenario:
+ * WifiStateMachine is under disconnected state
+ * Two networks test1, test2 are secured network and found in scan results
+ * Both network are enabled
+ * test1 is @ 2GHz with RSSI -65
+ * test2 is @ 5Ghz with RSSI -50
+ * test2's BSSID is disabled
+ *
+ * expected return test2 since test2's BSSID has been enabled again
+ */
+ @Test
+ public void networkChooseWithOneBssidDisableExpire() {
+ String[] ssids = DEFAULT_SSIDS;
+ String[] bssids = DEFAULT_BSSIDS;
+ int[] frequencies = {2437, 5180};
+ String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS][ESS]"};
+ int[] levels = {-65, -50};
+ int[] security = {SECURITY_PSK, SECURITY_PSK};
+
+ List<ScanDetail> scanDetails = getScanDetails(ssids, bssids, frequencies, caps, levels);
+ WifiConfiguration[] savedConfigs = generateWifiConfigurations(ssids, security);
+ prepareConfigStore(savedConfigs);
+
+ final List<WifiConfiguration> savedNetwork = Arrays.asList(savedConfigs);
+ when(mWifiConfigStore.getConfiguredNetworks()).thenReturn(savedNetwork);
+ scanResultLinkConfiguration(savedConfigs, scanDetails);
+ ScanResult chosenScanResult = scanDetails.get(1).getScanResult();
+
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssids[1], false);
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssids[1], false);
+ mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssids[1], false);
+ //re-enable it
+ when(mClock.currentTimeMillis()).thenReturn(System.currentTimeMillis()
+ + WifiQualifiedNetworkSelector.BSSID_BLACKLIST_EXPIRE_TIME);
+ WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
+ false, scanDetails, false, false, true, false);
+
+ verifySelectedResult(chosenScanResult, candidate);
+ }
+ /**
+ * Case #16 do not choose the SSID has been disabled
*
* In this test. we simulate following scenario:
* WifiStateMachine is under disconnected state
@@ -744,7 +837,7 @@ public class WifiQualifiedNetworkSelectionTest {
* test2 is @ 5Ghz with RSSI -50
* test2's SSID is disabled
*
- * expected return test1 since test2's BSSID has been disabled
+ * expected return test1 since test2's SSID has been disabled
*/
@Test
public void networkChooseWithOneSsidDisabled() {
@@ -773,7 +866,7 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #15 do not make QNS is link is bouncing now
+ * Case #17 do not make QNS is link is bouncing now
*
* In this test. we simulate following scenario:
* WifiStateMachine is under disconnected state and currently is under link bouncing
@@ -809,7 +902,7 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #16 QNS with very short gap
+ * Case #18 QNS with very short gap
*
* In this test. we simulate following scenario:
* WifiStateMachine is under disconnected state
@@ -848,7 +941,7 @@ public class WifiQualifiedNetworkSelectionTest {
//Unit test for Connected State
/**
- * Case #17 no QNS with very short gap when connected
+ * Case #19 no QNS with very short gap when connected
* In this test. we simulate following scenario:
* WifiStateMachine is under connected state and test2 is connected
* When WifiStateMachine is already in connected state, if last QNS is made in less than
@@ -883,7 +976,7 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #18 force QNS with very short gap under connection
+ * Case #20 force QNS with very short gap under connection
* In this test. we simulate following scenario:
* WifiStateMachine is under connected state and test2 is connected
* When WifiStateMachine is already in connected state, if last QNS is made in less than
@@ -920,7 +1013,7 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #19 no QNS when connected and user do not allow switch when connected
+ * Case #21 no QNS when connected and user do not allow switch when connected
*
* In this test. we simulate following scenario:
* WifiStateMachine is under connected state and test2 is connected
@@ -951,7 +1044,7 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #20 no new QNS if current network is qualified already
+ * Case #22 no new QNS if current network is qualified already
*
* In this test. we simulate following scenario:
* WifiStateMachine is under connected state and test2 is connected
@@ -997,7 +1090,7 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #21 No new QNS when link bouncing when connected
+ * Case #23 No new QNS when link bouncing when connected
*
* In this test. we simulate following scenario:
* WifiStateMachine is under connected state and test2 is connected
@@ -1037,7 +1130,7 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #22 Qualified network need to be on 5GHz
+ * Case #24 Qualified network need to be on 5GHz
*
* In this test. we simulate following scenario:
* WifiStateMachine is under connected state and connected to test2
@@ -1078,7 +1171,7 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #23 Qualified network need to be secured
+ * Case #25 Qualified network need to be secured
*
* In this test. we simulate following scenario:
* WifiStateMachine is under connected state and current connects to test2
@@ -1125,7 +1218,7 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #24 ephemeral network can not be qualified network
+ * Case #26 ephemeral network can not be qualified network
*
* In this test. we simulate following scenario:
* WifiStateMachine is under connected state and current connected to test2
@@ -1172,7 +1265,7 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #25 low signal network can not be Qualified network (5GHz)
+ * Case #27 low signal network can not be Qualified network (5GHz)
*
* In this test. we simulate following scenario:
* WifiStateMachine is under connected state and current connected to test2
@@ -1219,7 +1312,7 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #26 low signal network can not be Qualified network (2.4GHz)
+ * Case #28 low signal network can not be Qualified network (2.4GHz)
*
* In this test. we simulate following scenario:
* WifiStateMachine is under connected state and current connected to test2
@@ -1266,7 +1359,7 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #27 Choose current network due to current network bonus
+ * Case #29 Choose current network due to current network bonus
*
* In this test. we simulate following scenario:
* WifiStateMachine is under connected state and current connected to test2
@@ -1313,7 +1406,7 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #28 choose another network due to current network's signal is too low
+ * Case #30 choose another network due to current network's signal is too low
*
* In this test. we simulate following scenario:
* WifiStateMachine is under connected state and current connected to test2
@@ -1359,7 +1452,7 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #29 Choose current BSSID due to current BSSID bonus
+ * Case #31 Choose current BSSID due to current BSSID bonus
*
* In this test. we simulate following scenario:
* WifiStateMachine is under connected state and current connected to test2
@@ -1410,7 +1503,7 @@ public class WifiQualifiedNetworkSelectionTest {
}
/**
- * Case #30 Choose another BSSID due to current BSSID's rssi is too low
+ * Case #32 Choose another BSSID due to current BSSID's rssi is too low
*
* In this test. we simulate following scenario:
* WifiStateMachine is under connected state and current connected to test2