summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorxshu <xshu@google.com>2020-07-02 13:29:53 -0700
committerxshu <xshu@google.com>2020-08-04 22:03:08 -0700
commit50f8f0bebb76c2edb2256cffce195e06ca97ad2d (patch)
tree0e883f4bc366af951c2c2aad74536e9194a987ea /service
parentcc1e31863b17b6a02e3efb88a6493c475a60568a (diff)
Re-enable BSSID after RSSI improvement
(cherry picked from fc31bf5d9434c4703bafb9bd31499d64656e1989) Update BssidBlocklistMonitor to store the last seen RSSI when a BSSID gets blocked. Upon receiving scan results, we try to enable the BSSIDs that have significantly improved RSSIs. This new behavior also makes the previous logic to block low RSSI failures for a shorter duration obsolete. Bug: 158912030 Test: atest com.android.server.wifi Change-Id: I9b1cf3296b2469ce7f02e7f75653a5435e7b98e1 Merged-In: I9b1cf3296b2469ce7f02e7f75653a5435e7b98e1
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/BssidBlocklistMonitor.java106
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java22
-rw-r--r--service/java/com/android/server/wifi/WifiConnectivityManager.java3
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java5
-rw-r--r--service/java/com/android/server/wifi/WifiScoreReport.java3
-rw-r--r--service/res/values/config.xml10
-rw-r--r--service/res/values/overlayable.xml1
7 files changed, 85 insertions, 65 deletions
diff --git a/service/java/com/android/server/wifi/BssidBlocklistMonitor.java b/service/java/com/android/server/wifi/BssidBlocklistMonitor.java
index 96b70c39e..bc41aa929 100644
--- a/service/java/com/android/server/wifi/BssidBlocklistMonitor.java
+++ b/service/java/com/android/server/wifi/BssidBlocklistMonitor.java
@@ -20,8 +20,10 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.LocalLog;
import android.util.Log;
@@ -33,8 +35,10 @@ import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Calendar;
import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -108,7 +112,18 @@ public class BssidBlocklistMonitor {
"REASON_FRAMEWORK_DISCONNECT_FAST_RECONNECT",
"REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE"
};
+ private static final Set<Integer> LOW_RSSI_SENSITIVE_FAILURES = new ArraySet<>(Arrays.asList(
+ REASON_NETWORK_VALIDATION_FAILURE,
+ REASON_EAP_FAILURE,
+ REASON_ASSOCIATION_REJECTION,
+ REASON_ASSOCIATION_TIMEOUT,
+ REASON_AUTHENTICATION_FAILURE,
+ REASON_DHCP_FAILURE,
+ REASON_ABNORMAL_DISCONNECT,
+ REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE
+ ));
private static final long ABNORMAL_DISCONNECT_RESET_TIME_MS = TimeUnit.HOURS.toMillis(3);
+ private static final int MIN_RSSI_DIFF_TO_UNBLOCK_BSSID = 5;
private static final String TAG = "BssidBlocklistMonitor";
private final Context mContext;
@@ -118,6 +133,7 @@ public class BssidBlocklistMonitor {
private final LocalLog mLocalLog;
private final Calendar mCalendar;
private final WifiScoreCard mWifiScoreCard;
+ private final ScoringParams mScoringParams;
// Map of bssid to BssidStatus
private Map<String, BssidStatus> mBssidStatusMap = new ArrayMap<>();
@@ -130,7 +146,7 @@ public class BssidBlocklistMonitor {
*/
BssidBlocklistMonitor(Context context, WifiConnectivityHelper connectivityHelper,
WifiLastResortWatchdog wifiLastResortWatchdog, Clock clock, LocalLog localLog,
- WifiScoreCard wifiScoreCard) {
+ WifiScoreCard wifiScoreCard, ScoringParams scoringParams) {
mContext = context;
mConnectivityHelper = connectivityHelper;
mWifiLastResortWatchdog = wifiLastResortWatchdog;
@@ -138,6 +154,7 @@ public class BssidBlocklistMonitor {
mLocalLog = localLog;
mCalendar = Calendar.getInstance();
mWifiScoreCard = wifiScoreCard;
+ mScoringParams = scoringParams;
}
// A helper to log debugging information in the local log buffer, which can
@@ -174,10 +191,11 @@ public class BssidBlocklistMonitor {
}
private void addToBlocklist(@NonNull BssidStatus entry, long durationMs,
- @FailureReason int reason) {
- entry.addToBlocklist(durationMs, reason);
+ @FailureReason int reason, int rssi) {
+ entry.setAsBlocked(durationMs, reason, rssi);
localLog(TAG + " addToBlocklist: bssid=" + entry.bssid + ", ssid=" + entry.ssid
- + ", durationMs=" + durationMs + ", reason=" + getFailureReasonString(reason));
+ + ", durationMs=" + durationMs + ", reason=" + getFailureReasonString(reason)
+ + ", rssi=" + rssi);
}
/**
@@ -237,12 +255,14 @@ public class BssidBlocklistMonitor {
* @param ssid identifies the SSID the AP belongs to.
* @param durationMs duration in millis to block.
* @param blockReason reason for blocking the BSSID.
+ * @param rssi the latest RSSI observed.
*/
public void blockBssidForDurationMs(@NonNull String bssid, @NonNull String ssid,
- long durationMs, @FailureReason int blockReason) {
+ long durationMs, @FailureReason int blockReason, int rssi) {
if (durationMs <= 0 || !isValidNetworkAndFailureReason(bssid, ssid, blockReason)) {
Log.e(TAG, "Invalid input: BSSID=" + bssid + ", SSID=" + ssid
- + ", durationMs=" + durationMs + ", blockReason=" + blockReason);
+ + ", durationMs=" + durationMs + ", blockReason=" + blockReason
+ + ", rssi=" + rssi);
return;
}
BssidStatus status = getOrCreateBssidStatus(bssid, ssid);
@@ -251,7 +271,7 @@ public class BssidBlocklistMonitor {
// Return because this BSSID is already being blocked for a longer time.
return;
}
- addToBlocklist(status, durationMs, blockReason);
+ addToBlocklist(status, durationMs, blockReason, rssi);
}
private String getFailureReasonString(@FailureReason int reasonCode) {
@@ -299,7 +319,7 @@ public class BssidBlocklistMonitor {
}
private boolean handleBssidConnectionFailureInternal(String bssid, String ssid,
- @FailureReason int reasonCode, boolean isLowRssi) {
+ @FailureReason int reasonCode, int rssi) {
BssidStatus entry = incrementFailureCountForBssid(bssid, ssid, reasonCode);
int failureThreshold = getFailureThresholdForReason(reasonCode);
int currentStreak = mWifiScoreCard.getBssidBlocklistStreak(ssid, bssid, reasonCode);
@@ -311,14 +331,9 @@ public class BssidBlocklistMonitor {
}
int baseBlockDurationMs = mContext.getResources().getInteger(
R.integer.config_wifiBssidBlocklistMonitorBaseBlockDurationMs);
- if ((reasonCode == REASON_ASSOCIATION_TIMEOUT
- || reasonCode == REASON_ABNORMAL_DISCONNECT) && isLowRssi) {
- baseBlockDurationMs = mContext.getResources().getInteger(
- R.integer.config_wifiBssidBlocklistMonitorBaseLowRssiBlockDurationMs);
- }
addToBlocklist(entry,
getBlocklistDurationWithExponentialBackoff(currentStreak, baseBlockDurationMs),
- reasonCode);
+ reasonCode, rssi);
mWifiScoreCard.incrementBssidBlocklistStreak(ssid, bssid, reasonCode);
return true;
}
@@ -330,7 +345,7 @@ public class BssidBlocklistMonitor {
* @return True if the blocklist has been modified.
*/
public boolean handleBssidConnectionFailure(String bssid, String ssid,
- @FailureReason int reasonCode, boolean isLowRssi) {
+ @FailureReason int reasonCode, int rssi) {
if (!isValidNetworkAndFailureReason(bssid, ssid, reasonCode)) {
return false;
}
@@ -343,7 +358,7 @@ public class BssidBlocklistMonitor {
return false;
}
}
- return handleBssidConnectionFailureInternal(bssid, ssid, reasonCode, isLowRssi);
+ return handleBssidConnectionFailureInternal(bssid, ssid, reasonCode, rssi);
}
/**
@@ -401,7 +416,10 @@ public class BssidBlocklistMonitor {
* remove the BSSID from blocklist to make sure we are not accidentally blocking good
* BSSIDs.
**/
- status.removeFromBlocklist();
+ if (status.isInBlocklist) {
+ mBssidStatusHistoryLogger.add(status, "Network validation success");
+ mBssidStatusMap.remove(bssid);
+ }
}
/**
@@ -510,6 +528,33 @@ public class BssidBlocklistMonitor {
}
/**
+ * Attempts to re-enable BSSIDs that likely experienced failures due to low RSSI.
+ * @param scanDetails
+ */
+ public void tryEnablingBlockedBssids(List<ScanDetail> scanDetails) {
+ if (scanDetails == null) {
+ return;
+ }
+ for (ScanDetail scanDetail : scanDetails) {
+ ScanResult scanResult = scanDetail.getScanResult();
+ if (scanResult == null) {
+ continue;
+ }
+ BssidStatus status = mBssidStatusMap.get(scanResult.BSSID);
+ if (status == null || !status.isInBlocklist
+ || !LOW_RSSI_SENSITIVE_FAILURES.contains(status.blockReason)) {
+ continue;
+ }
+ int sufficientRssi = mScoringParams.getSufficientRssi(scanResult.frequency);
+ if (status.lastRssi < sufficientRssi && scanResult.level >= sufficientRssi
+ && scanResult.level - status.lastRssi >= MIN_RSSI_DIFF_TO_UNBLOCK_BSSID) {
+ mBssidStatusHistoryLogger.add(status, "rssi significantly improved");
+ mBssidStatusMap.remove(status.bssid);
+ }
+ }
+ }
+
+ /**
* Removes expired BssidStatus entries and then return remaining entries in the blocklist.
* @return Stream of BssidStatus for BSSIDs that are in the blocklist.
*/
@@ -613,7 +658,9 @@ public class BssidBlocklistMonitor {
public final String bssid;
public final String ssid;
public final int[] failureCount = new int[NUMBER_REASON_CODES];
- private int mBlockReason = INVALID_REASON; // reason of blocking this BSSID
+ public int blockReason = INVALID_REASON; // reason of blocking this BSSID
+ // The latest RSSI that's seen before this BSSID is added to blocklist.
+ public int lastRssi = 0;
// The following are used to flag how long this BSSID stays in the blocklist.
public boolean isInBlocklist;
@@ -634,27 +681,17 @@ public class BssidBlocklistMonitor {
}
/**
- * Add this BSSID to blocklist for the specified duration.
+ * Set this BSSID as blocked for the specified duration.
* @param durationMs
* @param blockReason
+ * @param rssi
*/
- public void addToBlocklist(long durationMs, @FailureReason int blockReason) {
+ public void setAsBlocked(long durationMs, @FailureReason int blockReason, int rssi) {
isInBlocklist = true;
blocklistStartTimeMs = mClock.getWallClockMillis();
blocklistEndTimeMs = blocklistStartTimeMs + durationMs;
- mBlockReason = blockReason;
- }
-
- /**
- * Remove this BSSID from the blocklist.
- */
- public void removeFromBlocklist() {
- mBssidStatusHistoryLogger.add(this, "removeFromBlocklist");
- isInBlocklist = false;
- blocklistStartTimeMs = 0;
- blocklistEndTimeMs = 0;
- mBlockReason = INVALID_REASON;
- localLog(TAG + " removeFromBlocklist BSSID=" + bssid);
+ this.blockReason = blockReason;
+ lastRssi = rssi;
}
@Override
@@ -664,7 +701,8 @@ public class BssidBlocklistMonitor {
sb.append(", SSID=" + ssid);
sb.append(", isInBlocklist=" + isInBlocklist);
if (isInBlocklist) {
- sb.append(", blockReason=" + getFailureReasonString(mBlockReason));
+ sb.append(", blockReason=" + getFailureReasonString(blockReason));
+ sb.append(", lastRssi=" + lastRssi);
mCalendar.setTimeInMillis(blocklistStartTimeMs);
sb.append(", blocklistStartTimeMs="
+ String.format("%tm-%td %tH:%tM:%tS.%tL", mCalendar, mCalendar,
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index c73fe4bae..66972d468 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -2966,13 +2966,8 @@ public class ClientModeImpl extends StateMachine {
mWifiHealthMonitor.getScanRssiValidTimeMs());
mWifiScoreCard.noteConnectionFailure(mWifiInfo, scanRssi, ssid, blocklistReason);
checkAbnormalConnectionFailureAndTakeBugReport(ssid);
- boolean isLowRssi = false;
- int sufficientRssi = getSufficientRssi(networkId, bssid);
- if (scanRssi != WifiInfo.INVALID_RSSI && sufficientRssi != WifiInfo.INVALID_RSSI) {
- isLowRssi = scanRssi < sufficientRssi;
- }
mBssidBlocklistMonitor.handleBssidConnectionFailure(bssid, ssid, blocklistReason,
- isLowRssi);
+ scanRssi);
}
}
@@ -5421,14 +5416,10 @@ public class ClientModeImpl extends StateMachine {
config.networkId,
DISABLED_NO_INTERNET_TEMPORARY);
}
- int rssi = mWifiInfo.getRssi();
- int sufficientRssi = mWifiInjector.getScoringParams()
- .getSufficientRssi(mWifiInfo.getFrequency());
- boolean isLowRssi = rssi < sufficientRssi;
mBssidBlocklistMonitor.handleBssidConnectionFailure(
mLastBssid, config.SSID,
BssidBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE,
- isLowRssi);
+ mWifiInfo.getRssi());
mWifiScoreCard.noteValidationFailure(mWifiInfo);
}
}
@@ -5484,13 +5475,10 @@ public class ClientModeImpl extends StateMachine {
boolean localGen = message.arg1 == 1;
if (!localGen) { // ignore disconnects initiated by wpa_supplicant.
mWifiScoreCard.noteNonlocalDisconnect(message.arg2);
- int rssi = mWifiInfo.getRssi();
- int sufficientRssi = mWifiInjector.getScoringParams()
- .getSufficientRssi(mWifiInfo.getFrequency());
- boolean isLowRssi = rssi < sufficientRssi;
mBssidBlocklistMonitor.handleBssidConnectionFailure(mWifiInfo.getBSSID(),
mWifiInfo.getSSID(),
- BssidBlocklistMonitor.REASON_ABNORMAL_DISCONNECT, isLowRssi);
+ BssidBlocklistMonitor.REASON_ABNORMAL_DISCONNECT,
+ mWifiInfo.getRssi());
}
config = getCurrentWifiConfiguration();
@@ -6296,7 +6284,7 @@ public class ClientModeImpl extends StateMachine {
}
// Blacklist the current BSS
mBssidBlocklistMonitor.blockBssidForDurationMs(bssid, ssid, duration,
- BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_MBO_OCE);
+ BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_MBO_OCE, 0);
}
if (frameData.mStatus != MboOceConstants.BTM_RESPONSE_STATUS_ACCEPT) {
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index a6f58fbe6..77af65400 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -304,6 +304,7 @@ public class WifiConnectivityManager {
updateUserDisabledList(scanDetails);
// Check if any blocklisted BSSIDs can be freed.
+ mBssidBlocklistMonitor.tryEnablingBlockedBssids(scanDetails);
Set<String> bssidBlocklist = mBssidBlocklistMonitor.updateAndGetBssidBlocklistForSsid(
mWifiInfo.getSSID());
@@ -1760,7 +1761,7 @@ public class WifiConnectivityManager {
// to prevent the supplicant from trying it again.
mBssidBlocklistMonitor.blockBssidForDurationMs(bssid, ssid,
TEMP_BSSID_BLOCK_DURATION,
- BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_FAST_RECONNECT);
+ BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_FAST_RECONNECT, 0);
connectToNetwork(candidate);
}
} catch (IllegalArgumentException e) {
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index b9aa0521f..b18dd6a29 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -192,6 +192,7 @@ public class WifiInjector {
mFrameworkFacade = new FrameworkFacade();
mMacAddressUtil = new MacAddressUtil();
mContext = context;
+ mScoringParams = new ScoringParams(mContext);
mSettingsMigrationDataHolder = new SettingsMigrationDataHolder(mContext);
mConnectionFailureNotificationBuilder = new ConnectionFailureNotificationBuilder(
mContext, getWifiStackPackageName(), mFrameworkFacade);
@@ -284,7 +285,6 @@ public class WifiInjector {
mWifiConnectivityHelper = new WifiConnectivityHelper(mWifiNative);
mConnectivityLocalLog = new LocalLog(
mContext.getSystemService(ActivityManager.class).isLowRamDevice() ? 256 : 512);
- mScoringParams = new ScoringParams(mContext);
mWifiMetrics.setScoringParams(mScoringParams);
mThroughputPredictor = new ThroughputPredictor(mContext);
mWifiNetworkSelector = new WifiNetworkSelector(mContext, mWifiScoreCard, mScoringParams,
@@ -615,7 +615,8 @@ public class WifiInjector {
mWifiMetrics, clientModeImpl, mWifiHandlerThread.getLooper(), mDeviceConfigFacade,
mWifiThreadRunner);
mBssidBlocklistMonitor = new BssidBlocklistMonitor(mContext, mWifiConnectivityHelper,
- mWifiLastResortWatchdog, mClock, mConnectivityLocalLog, mWifiScoreCard);
+ mWifiLastResortWatchdog, mClock, mConnectivityLocalLog, mWifiScoreCard,
+ mScoringParams);
mWifiMetrics.setBssidBlocklistMonitor(mBssidBlocklistMonitor);
mWifiChannelUtilizationScan = new WifiChannelUtilization(mClock, mContext);
return new WifiConnectivityManager(mContext, getScoringParams(),
diff --git a/service/java/com/android/server/wifi/WifiScoreReport.java b/service/java/com/android/server/wifi/WifiScoreReport.java
index 61809113c..5a1e9d378 100644
--- a/service/java/com/android/server/wifi/WifiScoreReport.java
+++ b/service/java/com/android/server/wifi/WifiScoreReport.java
@@ -632,7 +632,8 @@ public class WifiScoreReport {
mBssidBlocklistMonitor.blockBssidForDurationMs(mWifiInfo.getBSSID(),
mWifiInfo.getSSID(),
DURATION_TO_BLOCKLIST_BSSID_AFTER_FIRST_EXITING_MILLIS,
- BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE);
+ BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE,
+ mWifiInfo.getRssi());
mLastScoreBreachLowTimeMillis = INVALID_WALL_CLOCK_MILLIS;
}
}
diff --git a/service/res/values/config.xml b/service/res/values/config.xml
index cc80f608c..742cf681f 100644
--- a/service/res/values/config.xml
+++ b/service/res/values/config.xml
@@ -355,20 +355,12 @@
config_wifiBssidBlocklistMonitorFailureStreakCap is set to 7-->
<integer translatable="false" name="config_wifiBssidBlocklistMonitorBaseBlockDurationMs"> 300000 </integer>
- <!-- Base block duration for a failure at low RSSI (less than the sufficient RSSI) used for
- ASSOCIATION_TIMEOUT, ABNORMAL_DISCONNECT, and NETWORK_VALIDATION failures. The block duration
- for a BSSID that keeps failing will grow exponentially to the this base duration.
- ie. 0.5/1/2/4/8/16/32/64 minutes - capped at 64 minutes because the default for
- config_wifiBssidBlocklistMonitorFailureStreakCap is set to 7.
- This value should be configured to be less than config_wifiBssidBlocklistMonitorBaseBlockDurationMs -->
- <integer translatable="false" name="config_wifiBssidBlocklistMonitorBaseLowRssiBlockDurationMs"> 30000 </integer>
-
<!-- The failure streak is the number of times a BSSID consecutively gets blocked without ever
successfully connecting in between, and is used to calculate the exponentially growing blocklist time.
The config_wifiBssidBlocklistMonitorFailureStreakCap controls how many times the block duration
could exponentially grow when a BSSID keeps failing.
ie. A value of 0 means BSSIDs are always blocked for the flat base duration defined by
- config_wifiBssidBlocklistMonitorBaseBlockDurationMs and config_wifiBssidBlocklistMonitorBaseLowRssiBlockDurationMs. -->
+ config_wifiBssidBlocklistMonitorBaseBlockDurationMs. -->
<integer translatable="false" name="config_wifiBssidBlocklistMonitorFailureStreakCap"> 7 </integer>
<!-- If a non-locally generated disconnect happens within this time window after association,
diff --git a/service/res/values/overlayable.xml b/service/res/values/overlayable.xml
index a4b7011b0..8b592623f 100644
--- a/service/res/values/overlayable.xml
+++ b/service/res/values/overlayable.xml
@@ -114,7 +114,6 @@
<item type="integer" name="config_wifiBssidBlocklistMonitorDhcpFailureThreshold" />
<item type="integer" name="config_wifiBssidBlocklistMonitorAbnormalDisconnectThreshold" />
<item type="integer" name="config_wifiBssidBlocklistMonitorBaseBlockDurationMs" />
- <item type="integer" name="config_wifiBssidBlocklistMonitorBaseLowRssiBlockDurationMs" />
<item type="integer" name="config_wifiBssidBlocklistMonitorFailureStreakCap" />
<item type="integer" name="config_wifiBssidBlocklistAbnormalDisconnectTimeWindowMs" />
<item type="bool" name="config_wifiScanHiddenNetworksScanOnlyMode" />