handle supplicant disconnected state change in roaming state + make roaming less erratic
bug: 16753407
bug: 16823537
Change-Id: I47f1073b3775880d261ec2a963732c35454173cf
diff --git a/service/java/com/android/server/wifi/WifiAutoJoinController.java b/service/java/com/android/server/wifi/WifiAutoJoinController.java
index 354e39a..d93c8b8 100644
--- a/service/java/com/android/server/wifi/WifiAutoJoinController.java
+++ b/service/java/com/android/server/wifi/WifiAutoJoinController.java
@@ -80,6 +80,8 @@
public static final int AUTO_JOIN_EXTENDED_ROAMING = 2;
public static final int AUTO_JOIN_OUT_OF_NETWORK_ROAMING = 3;
+ public static final int HIGH_THRESHOLD_MODIFIER = 5;
+
WifiAutoJoinController(Context c, WifiStateMachine w, WifiConfigStore s,
WifiConnectionStatistics st, WifiNative n) {
mContext = c;
@@ -814,12 +816,12 @@
// Determine which BSSID we want to associate to, taking account
// relative strength of 5 and 2.4 GHz BSSIDs
long nowMs = System.currentTimeMillis();
- int bRssiBoost5 = 0;
- int aRssiBoost5 = 0;
- int bRssiBoost = 0;
- int aRssiBoost = 0;
- for (ScanResult b : current.scanResultCache.values()) {
+ for (ScanResult b : current.scanResultCache.values()) {
+ int bRssiBoost5 = 0;
+ int aRssiBoost5 = 0;
+ int bRssiBoost = 0;
+ int aRssiBoost = 0;
if ((b.seen == 0) || (b.BSSID == null)
|| (nowMs - b.seen) > age ) {
// TODO: do not apply blacklisting right now so as to leave this
@@ -839,35 +841,61 @@
if (currentBSSID != null && currentBSSID.equals(b.BSSID)) {
// Reduce the benefit of hysteresis if RSSI <= -75
if (b.level <= WifiConfiguration.G_BAND_PREFERENCE_RSSI_THRESHOLD) {
- bRssiBoost = +6;
+ bRssiBoost = +8;
} else {
- bRssiBoost = +10;
+ bRssiBoost = +14;
}
}
if (currentBSSID != null && currentBSSID.equals(a.BSSID)) {
if (a.level <= WifiConfiguration.G_BAND_PREFERENCE_RSSI_THRESHOLD) {
// Reduce the benefit of hysteresis if RSSI <= -75
- aRssiBoost = +6;
+ aRssiBoost = +8;
} else {
- aRssiBoost = +10;
+ aRssiBoost = +14;
}
}
- // Favor 5GHz: give a boost to 5GHz BSSIDs
+ // Favor 5GHz: give a boost to 5GHz BSSIDs, with a slightly progressive curve
// Boost the BSSID if it is on 5GHz, above a threshold
// But penalize it if it is on 5GHz and below threshold
+ //
+ // With he current threshold values, 5GHz network with RSSI above -55
+ // Are given a boost of 30DB which is enough to overcome the current BSSID
+ // hysteresis (+14) plus 2.4/5 GHz signal strength difference on most cases
if (b.is5GHz() && (b.level+bRssiBoost)
+ > (WifiConfiguration.A_BAND_PREFERENCE_RSSI_THRESHOLD
+ + HIGH_THRESHOLD_MODIFIER) ) {
+ // boost by 30 if > -50
+ bRssiBoost5 = 30;
+ } else if (b.is5GHz() && (b.level+bRssiBoost)
> WifiConfiguration.A_BAND_PREFERENCE_RSSI_THRESHOLD) {
+ // boost by 20 if > -55
bRssiBoost5 = 20;
} else if (b.is5GHz() && (b.level+bRssiBoost)
+ > WifiConfiguration.A_BAND_PREFERENCE_RSSI_THRESHOLD_LOW) {
+ // boost by 10 if > -65
+ bRssiBoost5 = 10;
+ } else if (b.is5GHz() && (b.level+bRssiBoost)
< WifiConfiguration.G_BAND_PREFERENCE_RSSI_THRESHOLD) {
+ // penalize by 10 if < -75
bRssiBoost5 = -10;
}
if (a.is5GHz() && (a.level+aRssiBoost)
+ > (WifiConfiguration.A_BAND_PREFERENCE_RSSI_THRESHOLD
+ + HIGH_THRESHOLD_MODIFIER) ) {
+ // boost by 30 if > -50
+ aRssiBoost5 = 30;
+ } else if (a.is5GHz() && (a.level+aRssiBoost)
> WifiConfiguration.A_BAND_PREFERENCE_RSSI_THRESHOLD) {
+ // boost by 20 if -55
aRssiBoost5 = 20;
} else if (a.is5GHz() && (a.level+aRssiBoost)
+ > WifiConfiguration.A_BAND_PREFERENCE_RSSI_THRESHOLD_LOW) {
+ // boost by 10 if > -65
+ aRssiBoost5 = 10;
+ } else if (a.is5GHz() && (a.level+aRssiBoost)
< WifiConfiguration.G_BAND_PREFERENCE_RSSI_THRESHOLD) {
+ // penalize by 10 if -75
aRssiBoost5 = -10;
}
@@ -878,7 +906,8 @@
}
logDbg("attemptRoam: "
+ b.BSSID + " rssi=" + b.level + " boost=" + Integer.toString(bRssiBoost)
- + "/" + Integer.toString(bRssiBoost5) + " freq=" + b.frequency + comp
+ + "/" + Integer.toString(bRssiBoost5) + " freq=" + b.frequency
+ + comp
+ a.BSSID + " rssi=" + a.level + " boost=" + Integer.toString(aRssiBoost)
+ "/" + Integer.toString(aRssiBoost5) + " freq=" + a.frequency);
}
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index d0dafae..00c7fc7 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -307,7 +307,7 @@
public void autoRoamSetBSSID(WifiConfiguration config, String bssid) {
mTargetRoamBSSID = "any";
- if (config == null)
+ if (config == null || bssid == null)
return;
if (config.bssidOwnerUid == 0 || config.bssidOwnerUid == Process.WIFI_UID) {
if (VDBG) {
@@ -6115,22 +6115,31 @@
break;
case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
/**
- * If we get a SUPPLICANT_STATE_CHANGE_EVENT before NETWORK_DISCONNECTION_EVENT
+ * If we get a SUPPLICANT_STATE_CHANGE_EVENT indicating a DISCONNECT
+ * before NETWORK_DISCONNECTION_EVENT
+ * And there is an associated BSSID corresponding to our target BSSID, then
* we have missed the network disconnection, transition to mDisconnectedState
- * and handle the rest of the events there
+ * and handle the rest of the events there.
*/
StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
- setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state));
+ if (stateChangeResult.state == SupplicantState.DISCONNECTED
+ || stateChangeResult.state == SupplicantState.INACTIVE
+ || stateChangeResult.state == SupplicantState.INTERFACE_DISABLED) {
+ if (DBG) {
+ log("STATE_CHANGE_EVENT in roaming state "
+ + stateChangeResult.toString() );
+ }
+ if (stateChangeResult.BSSID != null
+ && stateChangeResult.BSSID.equals(mTargetRoamBSSID)) {
+ setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
+ handleNetworkDisconnect();
+ }
+ }
break;
case WifiMonitor.NETWORK_CONNECTION_EVENT:
if (DBG) log("roaming and Network connection established");
mLastNetworkId = message.arg1;
mLastBssid = (String) message.obj;
- /**
- * We already have an IP address, we are going to the ObtainingIpAddress
- * state to renew it. Other parts of the system interpret an
- * ObtainingIpState change as not having IP address anymore,
- * hence, don't tell it there. */
mWifiInfo.setBSSID(mLastBssid);
mWifiInfo.setNetworkId(mLastNetworkId);
mWifiConfigStore.handleBSSIDBlackList(mLastNetworkId, mLastBssid, true);
@@ -6138,7 +6147,7 @@
* We already have an IP address, we are going to the ObtainingIpAddress
* state to renew it. Other parts of the system interpret an
* ObtainingIpState change as not having IP address anymore,
- * hence, don't tell it there. */
+ * hence, don't send the state change there. */
// setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
// sendNetworkStateChangeBroadcast(mLastBssid);
transitionTo(mObtainingIpState);