From ecfffce5bd216571c207978944fbbcd9c17b6382 Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Mon, 14 Jul 2014 15:40:18 -0700 Subject: Fix 2.4/5 wifi roaming. The redesign of wifi ip address optaining assumed we would never go from have-ip -> have-ip, ie we must lose our ip config before we can gain an ip config. Unfortunately at least one condition does just this: Our inter-band roaming To leave OBTAINING_IP_ADDRESS we need to tweak the code to generate the success signal even if the new address is the same. bug:16269674 Change-Id: I340b24839565fa62fd3c7d9d373695d1d4007412 --- .../com/android/server/wifi/WifiStateMachine.java | 39 ++++++++++++---------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 6f7ad27f0..a75002ae2 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -2942,31 +2942,34 @@ public class WifiStateMachine extends StateMachine { } } - if (!newLp.equals(mLinkProperties)) { + final boolean linkChanged = !newLp.equals(mLinkProperties); + final boolean wasProvisioned = mLinkProperties.isProvisioned(); + final boolean isProvisioned = newLp.isProvisioned(); + final DetailedState detailedState = getNetworkDetailedState(); + + if (linkChanged) { if (DBG) { log("Link configuration changed for netId: " + mLastNetworkId + " old: " + mLinkProperties + "new: " + newLp); } - - boolean wasProvisioned = mLinkProperties.isProvisioned(); - boolean isProvisioned = newLp.isProvisioned(); - mLinkProperties = newLp; if (mNetworkAgent != null) mNetworkAgent.sendLinkProperties(mLinkProperties); + } - // If we just configured or lost IP configuration, do the needful. - // We don't just call handleSuccessfulIpConfiguration() or handleIpConfigurationLost() - // here because those should only be called if we're attempting to connect or already - // connected, whereas updateLinkProperties can be called at any time. - if (!wasProvisioned && isProvisioned) { - sendMessage(CMD_IP_CONFIGURATION_SUCCESSFUL); - } else if (wasProvisioned && !isProvisioned) { - sendMessage(CMD_IP_CONFIGURATION_LOST); - } else if (getNetworkDetailedState() == DetailedState.CONNECTED) { - // If anything has changed, and we're already connected, send out a notification. - sendLinkConfigurationChangedBroadcast(); - } - + // If we just configured or lost IP configuration, do the needful. + // We don't just call handleSuccessfulIpConfiguration() or handleIpConfigurationLost() + // here because those should only be called if we're attempting to connect or already + // connected, whereas updateLinkProperties can be called at any time. + // Also, when roaming we don't pass through a not-provisioned state but + // still need to realize we have an IP_CONFIGURATION_SUCCESSFUL. + if (isProvisioned && + (!wasProvisioned || detailedState == DetailedState.OBTAINING_IPADDR)) { + sendMessage(CMD_IP_CONFIGURATION_SUCCESSFUL); + } else if (wasProvisioned && !isProvisioned) { + sendMessage(CMD_IP_CONFIGURATION_LOST); + } else if (linkChanged && getNetworkDetailedState() == DetailedState.CONNECTED) { + // If anything has changed, and we're already connected, send out a notification. + sendLinkConfigurationChangedBroadcast(); } } -- cgit v1.2.3 From d62d4c1eed0549127b65dfb6654db6fa8e07c5e5 Mon Sep 17 00:00:00 2001 From: Sreeram Ramachandran Date: Thu, 17 Jul 2014 17:06:30 -0700 Subject: Fix WiFi-Direct. Send explicit commands to netd to add routes for the p2p interface. This already happens via the tetherInterface() command when we are the group owner, so the new command is used only when we are not a group owner. Bug: 15413694 Change-Id: I36effc438d5ac193a77174493bf196cb68a5b97a --- .../java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java index a5a3548c5..e2324a046 100644 --- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java +++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java @@ -1893,6 +1893,12 @@ public final class WifiP2pServiceImpl extends IWifiP2pManager.Stub { sendP2pConnectionChangedBroadcast(); //Turn on power save on client mWifiNative.setP2pPowerSave(mGroup.getInterface(), true); + try { + mNwService.addInterfaceToLocalNetwork(mGroup.getInterface(), + dhcpResults.linkProperties.getRoutes()); + } catch (RemoteException e) { + loge("Failed to add iface to local network " + e); + } } else { loge("DHCP failed"); mWifiNative.p2pGroupRemove(mGroup.getInterface()); @@ -2742,6 +2748,11 @@ public final class WifiP2pServiceImpl extends IWifiP2pManager.Stub { mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP); mDhcpStateMachine.doQuit(); mDhcpStateMachine = null; + try { + mNwService.removeInterfaceFromLocalNetwork(mGroup.getInterface()); + } catch (RemoteException e) { + loge("Failed to remove iface from local network " + e); + } } try { -- cgit v1.2.3 From edb13c09f05085e402b3a09f3ff31711b4593418 Mon Sep 17 00:00:00 2001 From: vandwalle Date: Fri, 8 Aug 2014 12:39:57 -0700 Subject: handle supplicant disconnected state change in roaming state + make roaming less erratic bug: 16753407 bug: 16823537 Change-Id: I47f1073b3775880d261ec2a963732c35454173cf --- .../server/wifi/WifiAutoJoinController.java | 51 +++++++++++++++++----- .../com/android/server/wifi/WifiStateMachine.java | 29 +++++++----- 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiAutoJoinController.java b/service/java/com/android/server/wifi/WifiAutoJoinController.java index 354e39af2..d93c8b8f6 100644 --- a/service/java/com/android/server/wifi/WifiAutoJoinController.java +++ b/service/java/com/android/server/wifi/WifiAutoJoinController.java @@ -80,6 +80,8 @@ public class WifiAutoJoinController { 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 @@ public class WifiAutoJoinController { // 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 @@ public class WifiAutoJoinController { 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 @@ public class WifiAutoJoinController { } 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 d0dafae73..00c7fc7a2 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -307,7 +307,7 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { * 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); -- cgit v1.2.3 From e3dd5f00f7c3f8c067f0050e24209c87171b3e4a Mon Sep 17 00:00:00 2001 From: Vinit Deshpande Date: Wed, 13 Aug 2014 19:58:44 -0700 Subject: Fix getAdapters() hang getAdapters() hangs in certain Wifi states because there is no code to generate a default reply. This change adds default reply so it returns something in all states. Bug: 16982058 Change-Id: I07cae455c6335e622fbd9a79f3837128e73e302c --- .../com/android/server/wifi/WifiStateMachine.java | 51 +++++++++++----------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 00c7fc7a2..407e7d2ce 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -3955,6 +3955,32 @@ public class WifiStateMachine extends StateMachine { replyToMessage(message, WifiManager.RSSI_PKTCNT_FETCH_FAILED, WifiManager.BUSY); break; + case CMD_GET_ADAPTORS: + if (WifiNative.startHal()) { + List adaptors = new ArrayList(); + int featureSet = WifiNative.getSupportedFeatureSet(); + /* TODO: Get capabilities from adaptors themselves */ + for (int i = 0; i < WifiNative.getInterfaces(); i++) { + String name = WifiNative.getInterfaceName(i); + WifiAdapter adaptor; + if (name.startsWith("wlan")) { + adaptor = new WifiAdapter( + name, featureSet & ~WifiAdapter.WIFI_FEATURE_P2P); + } else if (name.startsWith("p2p")) { + adaptor = new WifiAdapter( + name, featureSet & WifiAdapter.WIFI_FEATURE_P2P); + } else { + logd("Ignoring adaptor with name" + name); + continue; + } + adaptors.add(adaptor); + } + replyToMessage(message, message.what, adaptors); + } else { + List adaptors = new ArrayList(); + replyToMessage(message, message.what, adaptors); + } + break; case WifiP2pServiceImpl.P2P_CONNECTION_CHANGED: NetworkInfo info = (NetworkInfo) message.obj; mP2pConnected.set(info.isConnected()); @@ -4228,31 +4254,6 @@ public class WifiStateMachine extends StateMachine { case CMD_SET_OPERATIONAL_MODE: mOperationalMode = message.arg1; break; - case CMD_GET_ADAPTORS: - if (WifiNative.startHal()) { - List adaptors = new ArrayList(); - int featureSet = WifiNative.getSupportedFeatureSet(); - /* TODO: Get capabilities from adaptors themselves */ - for (int i = 0; i < WifiNative.getInterfaces(); i++) { - String name = WifiNative.getInterfaceName(i); - WifiAdapter adaptor; - if (name.startsWith("wlan")) { - adaptor = new WifiAdapter( - name, featureSet & ~WifiAdapter.WIFI_FEATURE_P2P); - } else if (name.startsWith("p2p")) { - adaptor = new WifiAdapter( - name, featureSet & WifiAdapter.WIFI_FEATURE_P2P); - } else { - logd("Ignoring adaptor with name" + name); - continue; - } - adaptors.add(adaptor); - } - replyToMessage(message, message.what, adaptors); - } else { - List adaptors = new ArrayList(); - replyToMessage(message, message.what, adaptors); - } default: return NOT_HANDLED; } -- cgit v1.2.3 From 3eae8ac159dd44daed7e799bd78c22e91d7f2f73 Mon Sep 17 00:00:00 2001 From: Vinit Deshpande Date: Thu, 14 Aug 2014 12:04:35 -0700 Subject: Work around qcom hal bug (no interfaces found) for Mako Qualcomm's wifi-hal is reporting no interfaces on Mako, even after successful start of HAL. This change allows the device to boot despite that; but the root problems needs to be fixed later. Bug: 17021199 Change-Id: I826c4f41d0c02d5fc37b2ee3ab5ebcefcbf272c8 --- service/jni/com_android_server_wifi_WifiNative.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/service/jni/com_android_server_wifi_WifiNative.cpp b/service/jni/com_android_server_wifi_WifiNative.cpp index 492cce626..50b7273a1 100644 --- a/service/jni/com_android_server_wifi_WifiNative.cpp +++ b/service/jni/com_android_server_wifi_WifiNative.cpp @@ -243,8 +243,8 @@ static int android_net_wifi_getInterfaces(JNIEnv *env, jclass cls) { return result; } - if (n <= 0) { - THROW(env, "android_net_wifi_getInterfaces no interfaces"); + if (n < 0) { + THROW(env, "android_net_wifi_getInterfaces no interfaces"); return 0; } @@ -253,6 +253,11 @@ static int android_net_wifi_getInterfaces(JNIEnv *env, jclass cls) { return 0; } + if (n > 8) { + THROW(env, "Too many interfaces"); + return 0; + } + jlongArray array = (env)->NewLongArray(n); if (array == NULL) { THROW(env, "Error in accessing array"); @@ -260,11 +265,6 @@ static int android_net_wifi_getInterfaces(JNIEnv *env, jclass cls) { } jlong elems[8]; - if (n > 8) { - THROW(env, "Too many interfaces"); - return 0; - } - for (int i = 0; i < n; i++) { elems[i] = reinterpret_cast(ifaceHandles[i]); } -- cgit v1.2.3 From a64738ee18319f6b81f6a8305e20e0f389ce8df5 Mon Sep 17 00:00:00 2001 From: vandwalle Date: Wed, 20 Aug 2014 13:43:52 -0700 Subject: add roam state watchdog. Bug: 16823537 This CL is dependent on Id9411c8097337b37ac1ce1a6ac8b28b4bda31ff3 Change-Id: Iff32fae2cd67343e63046d58d75fa1e10d9775d0 --- .../server/wifi/WifiAutoJoinController.java | 13 +++--- .../com/android/server/wifi/WifiConfigStore.java | 15 +++---- .../com/android/server/wifi/WifiStateMachine.java | 49 ++++++++++++++++++---- 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiAutoJoinController.java b/service/java/com/android/server/wifi/WifiAutoJoinController.java index 353d9464d..99c5505de 100644 --- a/service/java/com/android/server/wifi/WifiAutoJoinController.java +++ b/service/java/com/android/server/wifi/WifiAutoJoinController.java @@ -208,6 +208,12 @@ public class WifiAutoJoinController { } mWifiStateMachine.sendMessage(WifiManager.SAVE_NETWORK, associatedConfig); } + } else { + // If the scan result has been blacklisted fir 18 hours -> unblacklist + long now = System.currentTimeMillis(); + if ((now - result.blackListTimestamp) > loseBlackListHardMilli) { + result.setAutoJoinStatus(ScanResult.ENABLED); + } } } @@ -823,11 +829,8 @@ public class WifiAutoJoinController { 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 - // bug as apparent - // https://b2.corp.google.com/#/issues/16504012 - // || b.status != ScanResult.ENABLED) { + || ((nowMs - b.seen) > age) + || b.autoJoinStatus != ScanResult.ENABLED) { continue; } diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java index 7d1beb545..97a610a82 100644 --- a/service/java/com/android/server/wifi/WifiConfigStore.java +++ b/service/java/com/android/server/wifi/WifiConfigStore.java @@ -1347,7 +1347,8 @@ public class WifiConfigStore extends IpConfigStore { out.writeUTF(RSSI_KEY + Integer.toString(result.level) + SEPARATOR_KEY); - out.writeUTF(BSSID_STATUS_KEY + Integer.toString(result.status) + out.writeUTF(BSSID_STATUS_KEY + + Integer.toString(result.autoJoinStatus) + SEPARATOR_KEY); if (result.seen != 0) { @@ -1645,7 +1646,7 @@ public class WifiConfigStore extends IpConfigStore { caps, rssi, freq, (long) 0); result.seen = seen; config.scanResultCache.put(bssid, result); - result.status = status; + result.autoJoinStatus = status; } } } @@ -2549,8 +2550,8 @@ public class WifiConfigStore extends IpConfigStore { if (config != null) { if (config.scanResultCache != null) { String status = ""; - if (scanResult.status > 0) { - status = " status=" + Integer.toString(scanResult.status); + if (scanResult.autoJoinStatus > 0) { + status = " status=" + Integer.toString(scanResult.autoJoinStatus); } loge(" got known scan result " + scanResult.BSSID + " key : " + key + " num: " + @@ -3098,12 +3099,12 @@ public class WifiConfigStore extends IpConfigStore { for (ScanResult result: config.scanResultCache.values()) { if (result.BSSID.equals(BSSID)) { if (enable) { - result.status = ScanResult.ENABLED; + result.setAutoJoinStatus(ScanResult.ENABLED); } else { - // Black list the BSSID we we were trying to join + // Black list the BSSID we were trying to join // so as the Roam state machine // doesn't pick it up over and over - result.status = ScanResult.AUTO_ROAM_DISABLED; + result.setAutoJoinStatus(ScanResult.AUTO_ROAM_DISABLED); found = true; } } diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index a0ab75ec6..55947ff9f 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -290,9 +290,12 @@ public class WifiStateMachine extends StateMachine { private final AtomicInteger mCountryCodeSequence = new AtomicInteger(); - //whether the state machine goes thru the Disconnecting->Disconnected->ObtainingIpAddress + // Whether the state machine goes thru the Disconnecting->Disconnected->ObtainingIpAddress private int mAutoRoaming = WifiAutoJoinController.AUTO_JOIN_IDLE; + // Roaming failure count + private int mRoamFailCount = 0; + private String mTargetRoamBSSID = "any"; private WifiConfiguration targetWificonfiguration = null; @@ -310,7 +313,7 @@ public class WifiStateMachine extends StateMachine { mTargetRoamBSSID = "any"; if (config == null || bssid == null) return; - if (config.bssidOwnerUid == 0 || config.bssidOwnerUid == Process.WIFI_UID) { + if (config.bssidOwnerUid == 0 || config.bssidOwnerUid == Process.WIFI_UID) { if (VDBG) { loge("autoRoamSetBSSID uid=" + Long.toString(config.bssidOwnerUid) + " bssid=" + bssid @@ -488,21 +491,33 @@ public class WifiStateMachine extends StateMachine { static final int CMD_ENABLE_BACKGROUND_SCAN = BASE + 91; /* Enable TDLS on a specific MAC address */ static final int CMD_ENABLE_TDLS = BASE + 92; - /* Enable TDLS on a specific MAC address */ + /* DHCP/IP configuration watchdog */ static final int CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER = BASE + 93; /** - * Make this timer 32 seconds, which is about the normal DHCP timeout. + * Make this timer 40 seconds, which is about the normal DHCP timeout. * In no valid case, the WiFiStateMachine should remain stuck in ObtainingIpAddress * for more than 30 seconds. */ - static final int OBTAINING_IP_ADDRESS_GUARD_TIMER_MSEC = 32000; + static final int OBTAINING_IP_ADDRESS_GUARD_TIMER_MSEC = 40000; int obtainingIpWatchdogCount = 0; + /* Commands from/to the SupplicantStateTracker */ /* Reset the supplicant state tracker */ static final int CMD_RESET_SUPPLICANT_STATE = BASE + 111; + + /** + * Watchdog for protecting against b/16823537 + * Leave time for 4-ways handshake to succeed + */ + static final int ROAM_GUARD_TIMER_MSEC = 15000; + + int roamWatchdogCount = 0; + /* Roam state configuration watchdog */ + static final int CMD_ROAM_WATCHDOG_TIMER = BASE + 94; + /* P2p commands */ /* We are ok with no response here since we wont do much with it anyway */ public static final int CMD_ENABLE_P2P = BASE + 131; @@ -2279,6 +2294,7 @@ public class WifiStateMachine extends StateMachine { sb.append(Integer.toString(msg.arg2)); ScanResult result = (ScanResult)msg.obj; if (result != null) { + sb.append(" bssid=").append(result.BSSID); sb.append(" rssi=").append(result.level); sb.append(" freq=").append(result.frequency); sb.append(" ").append(result.BSSID); @@ -2287,6 +2303,7 @@ public class WifiStateMachine extends StateMachine { sb.append(" ").append(mTargetRoamBSSID); } sb.append(" roam=").append(Integer.toString(mAutoRoaming)); + sb.append(" fail count=").append(Integer.toString(mRoamFailCount)); break; case CMD_ENABLE_NETWORK: sb.append(" "); @@ -5161,6 +5178,9 @@ public class WifiStateMachine extends StateMachine { case CMD_TARGET_BSSID: s = "CMD_TARGET_BSSID"; break; + case CMD_ROAM_WATCHDOG_TIMER: + s = "CMD_ROAM_WATCHDOG_TIMER"; + break; default: s = "what:" + Integer.toString(what); break; @@ -6154,7 +6174,12 @@ public class WifiStateMachine extends StateMachine { + " mScreenOn=" + mScreenOn ); } setScanAlarm(false); - //TODO: actually implement an alarm, but so as to disconnect if roaming fails + + // Make sure we disconnect if roaming fails + roamWatchdogCount++; + loge("Start Roam Watchdog " + roamWatchdogCount); + sendMessageDelayed(obtainMessage(CMD_ROAM_WATCHDOG_TIMER, + roamWatchdogCount, 0), ROAM_GUARD_TIMER_MSEC); } @Override public boolean processMessage(Message message) { @@ -6190,11 +6215,19 @@ public class WifiStateMachine extends StateMachine { } if (stateChangeResult.BSSID != null && stateChangeResult.BSSID.equals(mTargetRoamBSSID)) { - setNetworkDetailedState(DetailedState.OBTAINING_IPADDR); handleNetworkDisconnect(); + transitionTo(mDisconnectedState); } } break; + case CMD_ROAM_WATCHDOG_TIMER: + if (roamWatchdogCount == message.arg1) { + if (DBG) log("roaming watchdog! -> disconnect"); + handleNetworkDisconnect(); + mWifiNative.disconnect(); + transitionTo(mDisconnectedState); + } + break; case WifiMonitor.NETWORK_CONNECTION_EVENT: if (DBG) log("roaming and Network connection established"); mLastNetworkId = message.arg1; @@ -6212,7 +6245,7 @@ public class WifiStateMachine extends StateMachine { transitionTo(mObtainingIpState); break; case WifiMonitor.NETWORK_DISCONNECTION_EVENT: - // Throw away but only if it correspond to the network we're roaming to + // Throw away but only if it corresponds to the network we're roaming to String bssid = (String)message.obj; if (true) { String target = ""; -- cgit v1.2.3 From 99f7938b518984b2d5609df14c5bef1a8d7c7a01 Mon Sep 17 00:00:00 2001 From: vandwalle Date: Thu, 21 Aug 2014 10:32:28 -0700 Subject: fix spurious disconnect while associating, dont set AP configuration with NULL SSID Bug:14568953 Bug:17144830 Note: this CL address cases where framework sends spurious disconnect to driver while associating, this issue was only one of the root cause of 17144830, the remaining issues in this bug are "missing scan results" and "wifi chipset disconnects from AP due to missing beacons or receiving deauth from AP" Change-Id: If888f11bb3c66b55ca8ff991651f9e4457aaea31 --- .../com/android/server/wifi/WifiApConfigStore.java | 9 ++++++-- .../server/wifi/WifiAutoJoinController.java | 26 ++++++++++++++++++++++ .../java/com/android/server/wifi/WifiNative.java | 2 +- .../com/android/server/wifi/WifiStateMachine.java | 24 +++++++++++++++++++- 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiApConfigStore.java b/service/java/com/android/server/wifi/WifiApConfigStore.java index 5e28fcfe5..eb35db84d 100644 --- a/service/java/com/android/server/wifi/WifiApConfigStore.java +++ b/service/java/com/android/server/wifi/WifiApConfigStore.java @@ -100,8 +100,13 @@ class WifiApConfigStore extends StateMachine { public boolean processMessage(Message message) { switch (message.what) { case WifiStateMachine.CMD_SET_AP_CONFIG: - mWifiApConfig = (WifiConfiguration) message.obj; - transitionTo(mActiveState); + WifiConfiguration config = (WifiConfiguration) message.obj; + if (config.SSID != null) { + mWifiApConfig = (WifiConfiguration) message.obj; + transitionTo(mActiveState); + } else { + Log.e(TAG, "Try to setup AP config without SSID: " + message); + } break; default: return NOT_HANDLED; diff --git a/service/java/com/android/server/wifi/WifiAutoJoinController.java b/service/java/com/android/server/wifi/WifiAutoJoinController.java index 99c5505de..febfda487 100644 --- a/service/java/com/android/server/wifi/WifiAutoJoinController.java +++ b/service/java/com/android/server/wifi/WifiAutoJoinController.java @@ -1045,6 +1045,32 @@ public class WifiAutoJoinController { break; } } + } else if (key.contains("wpa_state=ASSOCIATING") + || key.contains("wpa_state=ASSOCIATED") + || key.contains("wpa_state=FOUR_WAY_HANDSHAKE") + || key.contains("wpa_state=GROUP_KEY_HANDSHAKE")) { + if (DBG) { + logDbg("attemptAutoJoin: bail out due to sup state " + key); + } + // After WifiStateMachine ask the supplicant to associate or reconnect + // we might still obtain scan results from supplicant + // however the supplicant state in the mWifiInfo and supplicant state tracker + // are updated when we get the supplicant state change message which can be + // processed after the SCAN_RESULT message, so at this point the framework doesn't + // know that supplicant is ASSOCIATING. + // A good fix for this race condition would be for the WifiStateMachine to add + // a new transient state where it expects to get the supplicant message indicating + // that it started the association process and within which critical operations + // like autojoin should be deleted. + + // This transient state would remove the need for the roam Wathchdog which + // basically does that. + + // At the moment, we just query the supplicant state synchronously with the + // mWifiNative.status() command, which allow us to know that + // supplicant has started association process, even though we didnt yet get the + // SUPPLICANT_STATE_CHANGE message. + return; } } if (DBG) { diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java index eb7c0fe35..4513f9d38 100644 --- a/service/java/com/android/server/wifi/WifiNative.java +++ b/service/java/com/android/server/wifi/WifiNative.java @@ -365,7 +365,7 @@ public class WifiNative { * flags=[WPA2-EAP-CCMP][ESS][P2P][HS20] * ssid=QCA-HS20-R2-TEST * p2p_device_name= - * p2p_config_methods=0x0 + * p2p_config_methods=0x0SET_NE * anqp_venue_name=02083d656e6757692d466920416c6c69616e63650a3239383920436f... * anqp_network_auth_type=010000 * anqp_roaming_consortium=03506f9a05001bc504bd diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 55947ff9f..4f5a27957 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -58,6 +58,7 @@ import android.net.RouteInfo; import android.net.StaticIpConfiguration; import android.net.TrafficStats; import android.net.wifi.*; +import android.net.wifi.SupplicantState; import android.net.wifi.WpsResult.Status; import android.net.wifi.p2p.IWifiP2pManager; import android.net.wifi.passpoint.IWifiPasspointManager; @@ -2810,9 +2811,14 @@ public class WifiStateMachine extends StateMachine { } } boolean attemptAutoJoin = true; + SupplicantState state = mWifiInfo.getSupplicantState(); if (getCurrentState() == mRoamingState || getCurrentState() == mObtainingIpState - || linkDebouncing) { + || linkDebouncing + || state == SupplicantState.ASSOCIATING + || state == SupplicantState.AUTHENTICATING + || state == SupplicantState.FOUR_WAY_HANDSHAKE + || state == SupplicantState.GROUP_HANDSHAKE) { // Dont attempt auto-joining again while we are already attempting to join // and/or obtaining Ip address attemptAutoJoin = false; @@ -5638,6 +5644,15 @@ public class WifiStateMachine extends StateMachine { transitionTo(mObtainingIpState); break; case WifiMonitor.NETWORK_DISCONNECTION_EVENT: + // Calling handleNetworkDisconnect here is redundant because we might already + // have called it when leaving L2ConnectedState to go to disconnecting state + // or thru other path + // We should normally check the mWifiInfo or mLastNetworkId so as to check + // if they are valid, and only in this case call handleNEtworkDisconnect, + // TODO: this should be fixed for a L MR release + // The side effect of calling handleNetworkDisconnect twice is that a bunch of + // idempotent commands are executed twice (stopping Dhcp, enabling the SPS mode + // at the chip etc... if (DBG) log("ConnectModeState: Network connection lost "); handleNetworkDisconnect(); transitionTo(mDisconnectedState); @@ -5726,6 +5741,13 @@ public class WifiStateMachine extends StateMachine { // For paranoia's sake, call handleNetworkDisconnect // only if BSSID is null or last networkId // is not invalid. + if (DBG) { + StringBuilder sb = new StringBuilder(); + sb.append("leaving L2ConnectedState state nid=" + Integer.toString(mLastNetworkId)); + if (mLastBssid !=null) { + sb.append(" ").append(mLastBssid); + } + } if (mLastBssid != null || mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID) { handleNetworkDisconnect(); } -- cgit v1.2.3 From 028bacd881f36731be063c197719d9b14b3b84ab Mon Sep 17 00:00:00 2001 From: vandwalle Date: Wed, 3 Sep 2014 19:14:38 -0700 Subject: adding debug logs - add debug status to WifiStatemachine message handling - tracking scan requests: add scan request counter and addl debug information - clean wifi packet stats when we disable RSSI polling - count home network as >=6 BSSID for the purpose of calculating wifi score Change-Id: Ic13ef303fdcfe60c0e27f225af4e233b9a2cffaa --- .../com/android/server/wifi/WifiServiceImpl.java | 6 +- .../com/android/server/wifi/WifiStateMachine.java | 105 ++++++++++++++++++--- 2 files changed, 95 insertions(+), 16 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index fe673d97c..a1f633312 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -111,6 +111,9 @@ public final class WifiServiceImpl extends IWifiManager.Stub { private String mInterfaceName; + // Debug counter tracking scan requests sent by WifiManager + private int scanRequestCounter = 0; + /* Tracks the open wi-fi network notification */ private WifiNotificationController mNotificationController; /* Polls traffic stats and notifies clients */ @@ -408,7 +411,8 @@ public final class WifiServiceImpl extends IWifiManager.Stub { // supplied WorkSource to allow future WorkSource combining. workSource.clearNames(); } - mWifiStateMachine.startScan(Binder.getCallingUid(), settings, workSource); + mWifiStateMachine.startScan(Binder.getCallingUid(), scanRequestCounter++, + settings, workSource); } private class BatchedScanRequest extends DeathRecipient { diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 4536c415d..93dfc8fed 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -212,6 +212,8 @@ public class WifiStateMachine extends StateMachine { private static final int SCAN_REQUEST_BUFFER_MAX_SIZE = 10; private static final String CUSTOMIZED_SCAN_SETTING = "customized_scan_settings"; private static final String CUSTOMIZED_SCAN_WORKSOURCE = "customized_scan_worksource"; + private static final String SCAN_REQUEST_TIME = "scan_request_time"; + private static final String BATCHED_SETTING = "batched_settings"; private static final String BATCHED_WORKSOURCE = "batched_worksource"; @@ -902,7 +904,7 @@ public class WifiStateMachine extends StateMachine { @Override public void onReceive(Context context, Intent intent) { sScanAlarmIntentCount++; - startScan(SCAN_ALARM_SOURCE, null, null); + startScan(SCAN_ALARM_SOURCE, -2, null, null); if (VDBG) loge("WiFiStateMachine SCAN ALARM"); } @@ -1148,11 +1150,13 @@ public class WifiStateMachine extends StateMachine { * @param workSource If not null, blame is given to workSource. * @param settings Scan settings, see {@link ScanSettings}. */ - public void startScan(int callingUid, ScanSettings settings, WorkSource workSource) { + public void startScan(int callingUid, int scanCounter, + ScanSettings settings, WorkSource workSource) { Bundle bundle = new Bundle(); bundle.putParcelable(CUSTOMIZED_SCAN_SETTING, settings); bundle.putParcelable(CUSTOMIZED_SCAN_WORKSOURCE, workSource); - sendMessage(CMD_START_SCAN, callingUid, 0, bundle); + bundle.putLong(SCAN_REQUEST_TIME, System.currentTimeMillis()); + sendMessage(CMD_START_SCAN, callingUid, scanCounter, bundle); } /** @@ -1472,14 +1476,28 @@ public class WifiStateMachine extends StateMachine { } } - //keeping track of scan requests + // Keeping track of scan requests private long lastStartScanTimeStamp = 0; private long lastScanDuration = 0; - //last connect attempt is used to prevent scan requests: - // - for a period of 10 seconds after attempting to connect + // Last connect attempt is used to prevent scan requests: + // - for a period of 10 seconds after attempting to connect private long lastConnectAttempt = 0; private String lastScanFreqs = null; + // For debugging, keep track of last message status handling + // TODO, find an equivalent mechanism as part of parent class + private static int MESSAGE_HANDLING_STATUS_OK = 1; + private static int MESSAGE_HANDLING_STATUS_UNKNOWN = 0; + private static int MESSAGE_HANDLING_STATUS_REFUSED = -1; + private static int MESSAGE_HANDLING_STATUS_FAIL = -2; + private static int MESSAGE_HANDLING_STATUS_BUFFERED = -3; + private static int MESSAGE_HANDLING_STATUS_DEFERRED = -4; + private static int MESSAGE_HANDLING_STATUS_DISCARD = -5; + private static int MESSAGE_HANDLING_STATUS_LOOPED = -6; + private static int MESSAGE_HANDLING_STATUS_HANDLING_ERROR = -7; + + private int messageHandlingStatus = 0; + //TODO: this is used only to track connection attempts, however the link state and packet per //TODO: second logic should be folded into that private boolean isScanAllowed() { @@ -1607,6 +1625,7 @@ public class WifiStateMachine extends StateMachine { // a full scan covers everything, clearing scan request buffer if (freqs == null) mBufferedScanMsg.clear(); + messageHandlingStatus = MESSAGE_HANDLING_STATUS_OK; return; } @@ -1614,26 +1633,34 @@ public class WifiStateMachine extends StateMachine { if (!mIsScanOngoing) { // if rejection is NOT due to ongoing scan (e.g. bad scan parameters), + // discard this request and pop up the next one - if (mBufferedScanMsg.size() > 0) + if (mBufferedScanMsg.size() > 0) { sendMessage(mBufferedScanMsg.remove()); + } + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; } else if (!mIsFullScanOngoing) { // if rejection is due to an ongoing scan, and the ongoing one is NOT a full scan, // buffer the scan request to make sure specified channels will be scanned eventually if (freqs == null) mBufferedScanMsg.clear(); if (mBufferedScanMsg.size() < SCAN_REQUEST_BUFFER_MAX_SIZE) { - Message msg = obtainMessage(CMD_START_SCAN, message.arg1, 0, bundle); + Message msg = obtainMessage(CMD_START_SCAN, + message.arg1, message.arg2, bundle); mBufferedScanMsg.add(msg); } else { // if too many requests in buffer, combine them into a single full scan bundle = new Bundle(); bundle.putParcelable(CUSTOMIZED_SCAN_SETTING, null); bundle.putParcelable(CUSTOMIZED_SCAN_WORKSOURCE, workSource); - Message msg = obtainMessage(CMD_START_SCAN, message.arg1, 0, bundle); + Message msg = obtainMessage(CMD_START_SCAN, message.arg1, message.arg2, bundle); mBufferedScanMsg.clear(); mBufferedScanMsg.add(msg); } + messageHandlingStatus = MESSAGE_HANDLING_STATUS_LOOPED; + } else { + // mIsScanOngoing and mIsFullScanOngoing + messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL; } } @@ -2135,6 +2162,7 @@ public class WifiStateMachine extends StateMachine { ********************************************************/ private void logStateAndMessage(Message message, String state) { + messageHandlingStatus = 0; if (mLogMessages) { //long now = SystemClock.elapsedRealtimeNanos(); //String ts = String.format("[%,d us]", now/1000); @@ -2151,24 +2179,37 @@ public class WifiStateMachine extends StateMachine { */ protected String getLogRecString(Message msg) { WifiConfiguration config; + Long now; StringBuilder sb = new StringBuilder(); if (mScreenOn) { sb.append("!"); } + if (messageHandlingStatus != MESSAGE_HANDLING_STATUS_UNKNOWN) { + sb.append("(").append(messageHandlingStatus).append(")"); + } sb.append(smToString(msg)); switch (msg.what) { case CMD_START_SCAN: + now = System.currentTimeMillis(); sb.append(" "); sb.append(Integer.toString(msg.arg1)); sb.append(" "); sb.append(Integer.toString(msg.arg2)); - sb.append(" "); + sb.append(" ic="); sb.append(Integer.toString(sScanAlarmIntentCount)); + if (msg.obj != null) { + Bundle bundle = (Bundle)msg.obj; + Long request = bundle.getLong(SCAN_REQUEST_TIME, 0); + if (request != 0) { + sb.append(" proc(ms):").append(now - request); + } + } if (mIsScanOngoing) sb.append(" onGoing"); if (mIsFullScanOngoing) sb.append(" full"); if (lastStartScanTimeStamp != 0) { sb.append(" started:").append(lastStartScanTimeStamp); + sb.append(",").append(now - lastStartScanTimeStamp); } if (lastScanDuration != 0) { sb.append(" dur:").append(lastScanDuration); @@ -2181,7 +2222,7 @@ public class WifiStateMachine extends StateMachine { sb.append(String.format(" %.1f,", mWifiInfo.txRetriesRate)); sb.append(String.format(" %.1f ", mWifiInfo.txBadRate)); sb.append(String.format(" rx=%.1f", mWifiInfo.rxSuccessRate)); - if (lastScanFreqs != null) sb.append(" ").append(lastScanFreqs); + if (lastScanFreqs != null) sb.append(" f=").append(lastScanFreqs); break; case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT: sb.append(" "); @@ -2329,7 +2370,7 @@ public class WifiStateMachine extends StateMachine { sb.append(" rs=").append(config.disableReason); } if (config.lastConnected != 0) { - long now = System.currentTimeMillis(); + now = System.currentTimeMillis(); sb.append(" lastconn=").append(now - config.lastConnected).append("(ms)"); } if (mLastBssid != null) { @@ -3063,6 +3104,14 @@ public class WifiStateMachine extends StateMachine { return false; } + // Polling has completed, hence we wont have a score anymore + private void cleanWifiScore() { + mWifiInfo.txBadRate = 0; + mWifiInfo.txSuccessRate = 0; + mWifiInfo.txRetriesRate = 0; + mWifiInfo.rxSuccessRate = 0; + } + private void calculateWifiScore(WifiLinkLayerStats stats) { if (stats == null || mWifiLinkLayerStatsSupported <= 0) { @@ -3103,11 +3152,11 @@ public class WifiStateMachine extends StateMachine { use24Thresholds = true; } } - if (currentConfiguration.scanResultCache.size() <= 4 + if (currentConfiguration.scanResultCache.size() <= 6 && currentConfiguration.allowedKeyManagement.cardinality() == 1 && currentConfiguration.allowedKeyManagement. get(WifiConfiguration.KeyMgmt.WPA_PSK) == true) { - // A PSK network with less than 4 known BSSIDs + // A PSK network with less than 6 known BSSIDs // This is most likely a home network and thus we want to stick to wifi more homeNetworkBoost = true; } @@ -4023,6 +4072,8 @@ public class WifiStateMachine extends StateMachine { break; /* Discard */ case CMD_START_SCAN: + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; + break; case CMD_START_SUPPLICANT: case CMD_STOP_SUPPLICANT: case CMD_STOP_SUPPLICANT_FAILED: @@ -4075,6 +4126,7 @@ public class WifiStateMachine extends StateMachine { case CMD_AUTO_CONNECT: case CMD_AUTO_ROAM: case CMD_AUTO_SAVE_NETWORK: + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; break; case DhcpStateMachine.CMD_ON_QUIT: mDhcpStateMachine = null; @@ -4145,6 +4197,7 @@ public class WifiStateMachine extends StateMachine { break; case CMD_IP_CONFIGURATION_SUCCESSFUL: case CMD_IP_CONFIGURATION_LOST: + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; break; case CMD_GET_CONNECTION_STATISTICS: replyToMessage(message, message.what, mWifiConnectionStatistics); @@ -4329,6 +4382,7 @@ public class WifiStateMachine extends StateMachine { case CMD_SET_FREQUENCY_BAND: case CMD_START_PACKET_FILTERING: case CMD_STOP_PACKET_FILTERING: + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED; deferMessage(message); break; default: @@ -4555,6 +4609,7 @@ public class WifiStateMachine extends StateMachine { case CMD_DISCONNECT: case CMD_REASSOCIATE: case CMD_RECONNECT: + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED; deferMessage(message); break; default: @@ -4884,6 +4939,7 @@ public class WifiStateMachine extends StateMachine { case CMD_DISCONNECT: case CMD_REASSOCIATE: case CMD_RECONNECT: + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED; deferMessage(message); break; default: @@ -4916,6 +4972,7 @@ public class WifiStateMachine extends StateMachine { case CMD_DISCONNECT: case CMD_REASSOCIATE: case CMD_RECONNECT: + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED; deferMessage(message); break; default: @@ -5871,6 +5928,7 @@ public class WifiStateMachine extends StateMachine { noteScanStart(SCAN_ALARM_SOURCE, null); // Return true } + messageHandlingStatus = MESSAGE_HANDLING_STATUS_OK; return true; } else { return false; @@ -5972,6 +6030,7 @@ public class WifiStateMachine extends StateMachine { } break; case CMD_SET_COUNTRY_CODE: + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED; deferMessage(message); break; case CMD_START_SCAN: @@ -6026,6 +6085,7 @@ public class WifiStateMachine extends StateMachine { + " tx=" + String.format("%.2f", mWifiInfo.txSuccessRate) + " rx=" + String.format("%.2f", mWifiInfo.rxSuccessRate)); } + messageHandlingStatus = MESSAGE_HANDLING_STATUS_REFUSED; return HANDLED; } } @@ -6070,8 +6130,12 @@ public class WifiStateMachine extends StateMachine { WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, message); } } + } else { + loge("CMD_START_SCAN : connected mode and no configuration"); + messageHandlingStatus = MESSAGE_HANDLING_STATUS_HANDLING_ERROR; } } else { + // Not scan alarm source handleScanRequest(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, message); } break; @@ -6125,6 +6189,8 @@ public class WifiStateMachine extends StateMachine { fetchRssiLinkSpeedAndFrequencyNative(); sendMessageDelayed(obtainMessage(CMD_RSSI_POLL, mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS); + } else { + cleanWifiScore(); } break; case WifiManager.RSSI_PKTCNT_FETCH: @@ -6251,17 +6317,21 @@ public class WifiStateMachine extends StateMachine { break; case CMD_AUTO_CONNECT: case CMD_AUTO_ROAM: + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; break; case WifiManager.SAVE_NETWORK: case WifiStateMachine.CMD_AUTO_SAVE_NETWORK: + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED; deferMessage(message); break; /* Defer any power mode changes since we must keep active power mode at DHCP */ case CMD_SET_HIGH_PERF_MODE: + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED; deferMessage(message); break; /* Defer scan request since we should not switch to other channels at DHCP */ case CMD_START_SCAN: + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED; deferMessage(message); break; case CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER: @@ -6272,6 +6342,8 @@ public class WifiStateMachine extends StateMachine { transitionTo(mDisconnectingState); break; } + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; + break; default: return NOT_HANDLED; } @@ -6770,7 +6842,7 @@ public class WifiStateMachine extends StateMachine { if (mP2pConnected.get()) break; if (message.arg1 == mPeriodicScanToken && mWifiConfigStore.getConfiguredNetworks().size() == 0) { - startScan(UNKNOWN_SCAN_SOURCE, null, null); + startScan(UNKNOWN_SCAN_SOURCE, -1, null, null); sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN, ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs); } @@ -6958,7 +7030,10 @@ public class WifiStateMachine extends StateMachine { break; case CMD_AUTO_CONNECT: case CMD_AUTO_ROAM: + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; + return HANDLED; case CMD_START_SCAN: + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; return HANDLED; case WifiMonitor.NETWORK_DISCONNECTION_EVENT: if (DBG) log("Network connection lost"); -- cgit v1.2.3 From a2c073d19aab40055022a639d0168240df0209c7 Mon Sep 17 00:00:00 2001 From: vandwalle Date: Wed, 10 Sep 2014 23:57:37 -0700 Subject: dont accept CONNECTION_EVENT until roaming is complete Change-Id: Iedde560abc9d2f4c3a3b9b9bfc5caaaa5584472e --- .../server/wifi/WifiAutoJoinController.java | 7 ++- .../com/android/server/wifi/WifiConfigStore.java | 64 +++++++++++++++++++--- .../com/android/server/wifi/WifiStateMachine.java | 43 ++++++++------- 3 files changed, 85 insertions(+), 29 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiAutoJoinController.java b/service/java/com/android/server/wifi/WifiAutoJoinController.java index 1fdad9973..a96f2600e 100644 --- a/service/java/com/android/server/wifi/WifiAutoJoinController.java +++ b/service/java/com/android/server/wifi/WifiAutoJoinController.java @@ -1475,10 +1475,13 @@ public class WifiAutoJoinController { + " RSSI=" + roamCandidate.level + " freq=" + roamCandidate.frequency); } + } else { + // We couldnt find a roam candidate + candidate.autoJoinBSSID = "any"; } - mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_CONNECT, - candidate.networkId, networkSwitchType, candidate); } + mWifiStateMachine.sendMessage(WifiStateMachine.CMD_AUTO_CONNECT, + candidate.networkId, networkSwitchType, candidate); } } diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java index 946ba65b6..5074c9d4a 100644 --- a/service/java/com/android/server/wifi/WifiConfigStore.java +++ b/service/java/com/android/server/wifi/WifiConfigStore.java @@ -258,7 +258,8 @@ public class WifiConfigStore extends IpConfigStore { = "ASSOCIATED_FULL_SCAN_BACKOFF_PERIOD: "; private static final String ALWAYS_ENABLE_SCAN_WHILE_ASSOCIATED_KEY = "ALWAYS_ENABLE_SCAN_WHILE_ASSOCIATED: "; - + private static final String ONLY_LINK_SAME_CREDENTIAL_CONFIGURATIONS_KEY + = "ONLY_LINK_SAME_CREDENTIAL_CONFIGURATIONS: "; // The Wifi verbose log is provided as a way to persist the verbose logging settings // for testing purpose. // It is not intended for normal use. @@ -314,6 +315,8 @@ public class WifiConfigStore extends IpConfigStore { public int maxNumPassiveChannelsForPartialScans = 2; public boolean roamOnAny = false; + public boolean onlyLinkSameCredentialConfigurations; + /** * Regex pattern for extracting a connect choice. @@ -391,6 +394,9 @@ public class WifiConfigStore extends IpConfigStore { associatedPartialScanPeriodMs = mContext.getResources().getInteger( R.integer.config_wifi_framework_associated_scan_interval); loge("associatedPartialScanPeriodMs set to " + associatedPartialScanPeriodMs); + + onlyLinkSameCredentialConfigurations = mContext.getResources().getBoolean( + R.bool.config_wifi_only_link_same_credential_configurations); } void enableVerboseLogging(int verbose) { @@ -862,13 +868,14 @@ public class WifiConfigStore extends IpConfigStore { * Instead mark it as deleted and completely hide it from the rest of the system. */ config.setAutoJoinStatus(WifiConfiguration.AUTO_JOIN_DELETED); + // Disable mWifiNative.disableNetwork(config.networkId); - // Since we don't delete the configuration, clean it up and loost the history + config.status = WifiConfiguration.Status.DISABLED; + // Since we don't delete the configuration, clean it up and loose the history config.linkedConfigurations = null; config.scanResultCache = null; config.connectChoices = null; config.defaultGwMacAddress = null; - config.setIpConfiguration(new IpConfiguration()); // Loose the PSK if (!mWifiNative.setNetworkVariable( @@ -876,7 +883,25 @@ public class WifiConfigStore extends IpConfigStore { WifiConfiguration.pskVarName, "\"xxxxxxxx\"")) { loge("removeNetwork, failed to clear PSK, nid=" + config.networkId); - }; + } + // Loose the BSSID + config.BSSID = null; + config.autoJoinBSSID = null; + if (!mWifiNative.setNetworkVariable( + config.networkId, + WifiConfiguration.bssidVarName, + "any")) { + loge("removeNetwork, failed to remove BSSID"); + } + // Loose the hiddenSSID flag + config.hiddenSSID = false; + if (!mWifiNative.setNetworkVariable( + config.networkId, + WifiConfiguration.hiddenSSIDVarName, + Integer.toString(0))) { + loge("removeNetwork, failed to remove hiddenSSID"); + } + mWifiNative.saveConfig(); } @@ -1825,6 +1850,18 @@ public class WifiConfigStore extends IpConfigStore { } } + if (key.startsWith(ONLY_LINK_SAME_CREDENTIAL_CONFIGURATIONS_KEY)) { + String st = key.replace(ONLY_LINK_SAME_CREDENTIAL_CONFIGURATIONS_KEY, ""); + st = st.replace(SEPARATOR_KEY, ""); + try { + onlyLinkSameCredentialConfigurations = Integer.parseInt(st) != 0; + Log.d(TAG,"readAutoJoinConfig: enabled = " + + onlyLinkSameCredentialConfigurations); + } catch (NumberFormatException e) { + Log.d(TAG,"readAutoJoinConfig: incorrect format :" + key); + } + } + if (key.startsWith(THRESHOLD_INITIAL_AUTO_JOIN_ATTEMPT_RSSI_MIN_5G_KEY)) { String st = key.replace(THRESHOLD_INITIAL_AUTO_JOIN_ATTEMPT_RSSI_MIN_5G_KEY, ""); @@ -2526,7 +2563,12 @@ public class WifiConfigStore extends IpConfigStore { } + /** + * This function run thru the Saved WifiConfigurations and check if some should be linked. + * @param config + */ public void linkConfiguration(WifiConfiguration config) { + if (config.scanResultCache != null && config.scanResultCache.size() > 6) { // Ignore configurations with large number of BSSIDs return; @@ -2558,7 +2600,7 @@ public class WifiConfigStore extends IpConfigStore { } if (config.defaultGwMacAddress != null && link.defaultGwMacAddress != null) { - // If both default GW are known, compare based on RSSI only if the GW is equal + // If both default GW are known, link only if they are equal if (config.defaultGwMacAddress.equals(link.defaultGwMacAddress)) { if (VDBG) { loge("linkConfiguration link due to same gw " + link.SSID + @@ -2591,10 +2633,18 @@ public class WifiConfigStore extends IpConfigStore { } } + if (doLink == true && onlyLinkSameCredentialConfigurations) { + String apsk = readNetworkVariableFromSupplicantFile(link.SSID, "psk"); + String bpsk = readNetworkVariableFromSupplicantFile(config.SSID, "psk"); + if (apsk == null || bpsk == null || !apsk.equals(bpsk)) { + doLink = false; + } + } + if (doLink) { if (VDBG) { - loge("linkConfiguration: will link " + link.configKey() - + " and " + config.configKey()); + loge("linkConfiguration: will link " + link.configKey() + + " and " + config.configKey()); } if (link.linkedConfigurations == null) { link.linkedConfigurations = new HashMap(); diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index b35d022d9..c2897e7da 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -5920,6 +5920,12 @@ public class WifiStateMachine extends StateMachine { config = (WifiConfiguration) message.obj; mWifiConnectionStatistics.numWifiManagerJoinAttempt++; + /* Save the network config */ + if (config != null) { + result = mWifiConfigStore.saveNetwork(config); + netId = result.getNetworkId(); + } + if (config == null) { loge("CONNECT_NETWORK id=" + Integer.toString(netId) + " " + mSupplicantStateTracker.getSupplicantStateName() + " my state " @@ -5933,7 +5939,6 @@ public class WifiStateMachine extends StateMachine { + " uid = " + message.sendingUid); } - autoRoamSetBSSID(netId, "any"); if (message.sendingUid == Process.WIFI_UID @@ -5949,11 +5954,6 @@ public class WifiStateMachine extends StateMachine { mAutoRoaming = WifiAutoJoinController.AUTO_JOIN_IDLE; - /* Save the network config */ - if (config != null) { - result = mWifiConfigStore.saveNetwork(config); - netId = result.getNetworkId(); - } /* Tell autojoin the user did try to connect to that network */ mWifiAutoJoinController.updateConfigurationHistory(netId, true, true); @@ -6689,6 +6689,7 @@ public class WifiStateMachine extends StateMachine { } class RoamingState extends State { + boolean mAssociated; @Override public void enter() { if (DBG) { @@ -6702,6 +6703,7 @@ public class WifiStateMachine extends StateMachine { loge("Start Roam Watchdog " + roamWatchdogCount); sendMessageDelayed(obtainMessage(CMD_ROAM_WATCHDOG_TIMER, roamWatchdogCount, 0), ROAM_GUARD_TIMER_MSEC); + mAssociated = false; } @Override public boolean processMessage(Message message) { @@ -6741,6 +6743,10 @@ public class WifiStateMachine extends StateMachine { transitionTo(mDisconnectedState); } } + if (stateChangeResult.state == SupplicantState.ASSOCIATED) { + // We completed the layer2 roaming part + mAssociated = true; + } break; case CMD_ROAM_WATCHDOG_TIMER: if (roamWatchdogCount == message.arg1) { @@ -6752,20 +6758,17 @@ public class WifiStateMachine extends StateMachine { } break; case WifiMonitor.NETWORK_CONNECTION_EVENT: - if (DBG) log("roaming and Network connection established"); - mLastNetworkId = message.arg1; - mLastBssid = (String) message.obj; - mWifiInfo.setBSSID(mLastBssid); - mWifiInfo.setNetworkId(mLastNetworkId); - mWifiConfigStore.handleBSSIDBlackList(mLastNetworkId, mLastBssid, true); - /** - * 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 send the state change there. */ - // setNetworkDetailedState(DetailedState.OBTAINING_IPADDR); - // sendNetworkStateChangeBroadcast(mLastBssid); - transitionTo(mObtainingIpState); + if (mAssociated) { + if (DBG) log("roaming and Network connection established"); + mLastNetworkId = message.arg1; + mLastBssid = (String) message.obj; + mWifiInfo.setBSSID(mLastBssid); + mWifiInfo.setNetworkId(mLastNetworkId); + mWifiConfigStore.handleBSSIDBlackList(mLastNetworkId, mLastBssid, true); + transitionTo(mObtainingIpState); + } else { + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; + } break; case WifiMonitor.NETWORK_DISCONNECTION_EVENT: // Throw away but only if it corresponds to the network we're roaming to -- cgit v1.2.3 From e1a599ae88eeccb05f70fb859e203ecffb3f001b Mon Sep 17 00:00:00 2001 From: Jeff Davidson Date: Thu, 13 Nov 2014 11:01:13 -0800 Subject: Fix call to startScan for untrusted setting change. Bug: 18221007 Change-Id: Idb526b1f275100ab2a004e7923a032f2e98db6de --- service/java/com/android/server/wifi/WifiStateMachine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 25d954085..78297f1dc 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -1218,7 +1218,7 @@ public class WifiStateMachine extends StateMachine { * so as to kick of autojoin. */ public void startScanForUntrustedSettingChange() { - sendMessage(CMD_START_SCAN, SET_ALLOW_UNTRUSTED_SOURCE); + startScan(SET_ALLOW_UNTRUSTED_SOURCE, 0, null, null); } /** -- cgit v1.2.3 From 4d0dc292f50502ecfcb7ea48e896b512e845154f Mon Sep 17 00:00:00 2001 From: vandwalle Date: Tue, 25 Nov 2014 17:56:47 -0800 Subject: register network factory before processing scan results Bug:18512598 Change-Id: I79aa972f686f2c4090012a36dcad13a9e53d5566 --- .../com/android/server/wifi/WifiStateMachine.java | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index f10c725e3..593d808a5 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -4537,6 +4537,19 @@ public class WifiStateMachine extends StateMachine { } } + + void maybeRegisterNetworkFactory() { + if (mNetworkFactory == null) { + checkAndSetConnectivityInstance(); + if (mCm != null) { + mNetworkFactory = new WifiNetworkFactory(getHandler().getLooper(), mContext, + NETWORKTYPE, mNetworkCapabilitiesFilter); + mNetworkFactory.setScoreFilter(60); + mNetworkFactory.register(); + } + } + } + /******************************************************** * HSM states *******************************************************/ @@ -4615,12 +4628,7 @@ public class WifiStateMachine extends StateMachine { sendMessageAtFrontOfQueue(CMD_SET_COUNTRY_CODE, sequenceNum, 0, countryCode); } - - checkAndSetConnectivityInstance(); - mNetworkFactory = new WifiNetworkFactory(getHandler().getLooper(), mContext, - NETWORKTYPE, mNetworkCapabilitiesFilter); - mNetworkFactory.setScoreFilter(60); - mCm.registerNetworkFactory(new Messenger(mNetworkFactory), NETWORKTYPE); + maybeRegisterNetworkFactory(); break; case CMD_SET_BATCHED_SCAN: recordBatchedScanSettings(message.arg1, message.arg2, (Bundle)message.obj); @@ -5010,6 +5018,7 @@ public class WifiStateMachine extends StateMachine { sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS); break; case WifiMonitor.SCAN_RESULTS_EVENT: + maybeRegisterNetworkFactory(); // Make sure our NetworkFactory is registered closeRadioScanStats(); noteScanEnd(); setScanResults(); -- cgit v1.2.3 From d1d517ce01ee82e7401878d544f407f0bf7e7c16 Mon Sep 17 00:00:00 2001 From: vandwalle Date: Mon, 1 Dec 2014 08:20:48 -0800 Subject: rework scan logic so as to make use of delayed messages instead of scan alarm Bug:18594119 Change-Id: I0d49fa2908d824de6adb125cf862de47f8ba5e91 --- .../server/wifi/WifiAutoJoinController.java | 13 +- .../com/android/server/wifi/WifiConfigStore.java | 15 +- .../com/android/server/wifi/WifiStateMachine.java | 289 ++++++++++++++------- 3 files changed, 214 insertions(+), 103 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiAutoJoinController.java b/service/java/com/android/server/wifi/WifiAutoJoinController.java index a971dcd56..f5f1eee5d 100644 --- a/service/java/com/android/server/wifi/WifiAutoJoinController.java +++ b/service/java/com/android/server/wifi/WifiAutoJoinController.java @@ -158,6 +158,7 @@ public class WifiAutoJoinController { int numScanResultsKnown = 0; // Record number of scan results we knew about WifiConfiguration associatedConfig = null; boolean didAssociate = false; + long now = System.currentTimeMillis(); ArrayList unknownScanResults = new ArrayList(); @@ -224,7 +225,11 @@ public class WifiAutoJoinController { if (associatedConfig != null && associatedConfig.SSID != null) { if (VDBG) { logDbg("addToScanCache save associated config " - + associatedConfig.SSID + " with " + result.SSID); + + associatedConfig.SSID + " with " + result.SSID + + " status " + associatedConfig.autoJoinStatus + + " reason " + associatedConfig.disableReason + + " tsp " + associatedConfig.blackListTimestamp + + " was " + (now - associatedConfig.blackListTimestamp)); } mWifiStateMachine.sendMessage( WifiStateMachine.CMD_AUTO_SAVE_NETWORK, associatedConfig); @@ -232,7 +237,6 @@ public class WifiAutoJoinController { } } else { // If the scan result has been blacklisted fir 18 hours -> unblacklist - long now = System.currentTimeMillis(); if ((now - result.blackListTimestamp) > loseBlackListHardMilli) { result.setAutoJoinStatus(ScanResult.ENABLED); } @@ -1129,6 +1133,8 @@ public class WifiAutoJoinController { didBailDueToWeakRssi = false; int networkSwitchType = AUTO_JOIN_IDLE; + long now = System.currentTimeMillis(); + String lastSelectedConfiguration = mWifiConfigStore.getLastSelectedConfiguration(); // Reset the currentConfiguration Key, and set it only if WifiStateMachine and @@ -1266,14 +1272,13 @@ public class WifiAutoJoinController { logDbg("attemptAutoJoin skip candidate due to auto join status " + Integer.toString(config.autoJoinStatus) + " key " + config.configKey(true) - + " reason " + config.disableReason); + + " reason " + config.disableReason); } continue; } // Try to un-blacklist based on elapsed time if (config.blackListTimestamp > 0) { - long now = System.currentTimeMillis(); if (now < config.blackListTimestamp) { /** * looks like there was a change in the system clock since we black listed, and diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java index c7b8ab301..0de9cf4c3 100644 --- a/service/java/com/android/server/wifi/WifiConfigStore.java +++ b/service/java/com/android/server/wifi/WifiConfigStore.java @@ -730,7 +730,7 @@ public class WifiConfigStore extends IpConfigStore { && (config.autoJoinStatus <= WifiConfiguration.AUTO_JOIN_DISABLED_ON_AUTH_FAILURE)) { - // Wait for 20 minutes before reenabling config that have known, repeated connection + // Wait for 5 minutes before reenabling config that have known, repeated connection // or DHCP failures if (config.disableReason == WifiConfiguration.DISABLED_DHCP_FAILURE || config.disableReason == WifiConfiguration.DISABLED_ASSOCIATION_REJECT @@ -3066,8 +3066,9 @@ public class WifiConfigStore extends IpConfigStore { // Try to make a non verified WifiConfiguration, but only if the original // configuration was not self already added if (VDBG) { - loge("associateWithConfiguration: will create " + - result.SSID + " and associate it with: " + link.SSID); + loge("associateWithConfiguration: try to create " + + result.SSID + " and associate it with: " + link.SSID + + " key " + link.configKey()); } config = wifiConfigurationFromScanResult(result); if (config != null) { @@ -3077,6 +3078,10 @@ public class WifiConfigStore extends IpConfigStore { config.peerWifiConfiguration = link.configKey(); if (config.allowedKeyManagement.equals(link.allowedKeyManagement) && config.allowedKeyManagement.get(KeyMgmt.WPA_PSK)) { + if (VDBG && config != null) { + loge("associateWithConfiguration: got a config from beacon" + + config.SSID + " key " + config.configKey()); + } // Transfer the credentials from the configuration we are linking from String psk = readNetworkVariableFromSupplicantFile(link.SSID, "psk"); if (psk != null) { @@ -3108,6 +3113,10 @@ public class WifiConfigStore extends IpConfigStore { } if (config != null) break; } + if (VDBG && config != null) { + loge("associateWithConfiguration: success, created: " + config.SSID + + " key " + config.configKey()); + } } } return config; diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 09920f5d1..9e283f6b9 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -862,6 +862,8 @@ public class WifiStateMachine extends StateMachine { // Used for debug and stats gathering private static int sScanAlarmIntentCount = 0; + final static int frameworkMinScanIntervalSaneValue = 10000; + public WifiStateMachine(Context context, String wlanInterface, WifiTrafficPoller trafficPoller){ super("WifiStateMachine"); @@ -910,9 +912,13 @@ public class WifiStateMachine extends StateMachine { mScanIntent = getPrivateBroadcast(ACTION_START_SCAN, SCAN_REQUEST); mBatchedScanIntervalIntent = getPrivateBroadcast(ACTION_REFRESH_BATCHED_SCAN, 0); - mDefaultFrameworkScanIntervalMs = mContext.getResources().getInteger( + // Make sure the interval is not configured less than 10 seconds + int period = mContext.getResources().getInteger( R.integer.config_wifi_framework_scan_interval); - + if (period < frameworkMinScanIntervalSaneValue) { + period = frameworkMinScanIntervalSaneValue; + } + mDefaultFrameworkScanIntervalMs = period; mDriverStopDelayMs = mContext.getResources().getInteger( R.integer.config_wifi_driver_stop_delay); @@ -949,10 +955,10 @@ public class WifiStateMachine extends StateMachine { new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - sScanAlarmIntentCount++; - startScan(SCAN_ALARM_SOURCE, -2, null, null); + sScanAlarmIntentCount++; // Used for debug only + startScan(SCAN_ALARM_SOURCE, mDelayedScanCounter.incrementAndGet(), null, null); if (VDBG) - loge("WiFiStateMachine SCAN ALARM"); + loge("WiFiStateMachine SCAN ALARM -> " + mDelayedScanCounter.get()); } }, new IntentFilter(ACTION_START_SCAN)); @@ -1123,35 +1129,27 @@ public class WifiStateMachine extends StateMachine { */ private long mFrameworkScanIntervalMs = 10000; - private long mCurrentScanAlarmMs = 10000; - private void setScanAlarm(boolean enabled, int delayMilli) { + private AtomicInteger mDelayedScanCounter = new AtomicInteger(); + + private void setScanAlarm(boolean enabled) { if (PDBG) { loge("setScanAlarm " + enabled - + " period " + mCurrentScanAlarmMs - + " initial delay " + delayMilli); + + " period " + mDefaultFrameworkScanIntervalMs + + " mBackgroundScanSupported " + mBackgroundScanSupported); + } + if (mBackgroundScanSupported == false) { + // Scan alarm is only used for background scans if they are not + // offloaded to the wifi chipset, hence enable the scan alarm + // gicing us RTC_WAKEUP of backgroundScan is NOT supported + enabled = true; } - if (mCurrentScanAlarmMs <= 0) enabled = false; + if (enabled == mAlarmEnabled) return; if (enabled) { - long initialDelayMilli; - if (delayMilli <= 0) { - // scan now - startScan(SCAN_ALARM_SOURCE, 0, null, null); - initialDelayMilli = mCurrentScanAlarmMs; - } else { - initialDelayMilli = delayMilli; - } - - int type = AlarmManager.RTC; - /* Set RTC_WAKEUP alarms if PNO is not supported - because no one is */ /* going to wake up the host processor to look for access points */ - if (mBackgroundScanSupported == false) - type = AlarmManager.RTC_WAKEUP; - - mAlarmManager.setRepeating(type, - System.currentTimeMillis() + initialDelayMilli, - mCurrentScanAlarmMs, + mAlarmManager.set(AlarmManager.RTC_WAKEUP, + System.currentTimeMillis() + mDefaultFrameworkScanIntervalMs, mScanIntent); mAlarmEnabled = true; } else { @@ -1160,6 +1158,53 @@ public class WifiStateMachine extends StateMachine { } } + private void cancelDelayedScan() { + mDelayedScanCounter.incrementAndGet(); + loge("cancelDelayedScan -> " + mDelayedScanCounter); + } + + private boolean checkAndRestartDelayedScan(int counter, boolean restart, int milli, + ScanSettings settings, WorkSource workSource) { + if (counter != mDelayedScanCounter.get()) { + return false; + } + if (restart) + startDelayedScan(milli, settings, workSource); + return true; + } + + private void startDelayedScan(int milli, ScanSettings settings, WorkSource workSource) { + if (milli <= 0) return; + /** + * The cases where the scan alarm should be run are : + * - DisconnectedState && screenOn => used delayed timer + * - DisconnectedState && !screenOn && mBackgroundScanSupported => PNO + * - DisconnectedState && !screenOn && !mBackgroundScanSupported => used RTC_WAKEUP Alarm + * - ConnectedState && screenOn => used delayed timer + */ + + mDelayedScanCounter.incrementAndGet(); + if (mScreenOn && + (getCurrentState() == mDisconnectedState + || getCurrentState() == mConnectedState)) { + Bundle bundle = new Bundle(); + bundle.putParcelable(CUSTOMIZED_SCAN_SETTING, settings); + bundle.putParcelable(CUSTOMIZED_SCAN_WORKSOURCE, workSource); + bundle.putLong(SCAN_REQUEST_TIME, System.currentTimeMillis()); + sendMessageDelayed(CMD_START_SCAN, SCAN_ALARM_SOURCE, + mDelayedScanCounter.get(), bundle, milli); + if (DBG) loge("startDelayedScan send -> " + mDelayedScanCounter + " milli " + milli); + } else if (mBackgroundScanSupported == false + && !mScreenOn && getCurrentState() == mDisconnectedState) { + setScanAlarm(true); + if (DBG) loge("startDelayedScan start scan alarm -> " + + mDelayedScanCounter + " milli " + milli); + } else { + if (DBG) loge("startDelayedScan unhandled -> " + + mDelayedScanCounter + " milli " + milli); + } + } + private boolean setRandomMacOui() { String oui = mContext.getResources().getString( R.string.config_wifi_random_mac_oui, GOOGLE_OUI); @@ -1592,7 +1637,7 @@ public class WifiStateMachine extends StateMachine { private static int MESSAGE_HANDLING_STATUS_UNKNOWN = 0; private static int MESSAGE_HANDLING_STATUS_REFUSED = -1; private static int MESSAGE_HANDLING_STATUS_FAIL = -2; - private static int MESSAGE_HANDLING_STATUS_BUFFERED = -3; + private static int MESSAGE_HANDLING_STATUS_OBSOLETE = -3; private static int MESSAGE_HANDLING_STATUS_DEFERRED = -4; private static int MESSAGE_HANDLING_STATUS_DISCARD = -5; private static int MESSAGE_HANDLING_STATUS_LOOPED = -6; @@ -1602,9 +1647,11 @@ public class WifiStateMachine extends StateMachine { //TODO: this is used only to track connection attempts, however the link state and packet per //TODO: second logic should be folded into that - private boolean isScanAllowed() { + private boolean checkOrDeferScanAllowed(Message msg) { long now = System.currentTimeMillis(); if (lastConnectAttempt != 0 && (now - lastConnectAttempt) < 10000) { + Message dmsg = Message.obtain(msg); + sendMessageDelayed(dmsg, 11000 - (now - lastConnectAttempt)); return false; } return true; @@ -1667,7 +1714,6 @@ public class WifiStateMachine extends StateMachine { mRxTime = stats.rx_time; mRunningBeaconCount = stats.beacon_rx; if (dbg) { - loge("WifiLinkLayerStats:"); loge(stats.toString()); } } @@ -1717,7 +1763,8 @@ public class WifiStateMachine extends StateMachine { loge(ts + " noteScanStart" + workSource.toString() + " uid " + Integer.toString(callingUid)); } else { - loge(ts + " noteScanstart no scan source"); + loge(ts + " noteScanstart no scan source" + + " uid " + Integer.toString(callingUid)); } } startRadioScanStats(); @@ -1742,9 +1789,11 @@ public class WifiStateMachine extends StateMachine { if (DBG) { String ts = String.format("[%,d ms]", now); if (mScanWorkSource != null) - loge(ts + " noteScanEnd " + mScanWorkSource.toString()); + loge(ts + " noteScanEnd " + mScanWorkSource.toString() + + " onTime=" + mOnTimeThisScan); else - loge(ts + " noteScanEnd no scan source"); + loge(ts + " noteScanEnd no scan source" + + " onTime=" + mOnTimeThisScan); } if (mScanWorkSource != null) { try { @@ -2412,6 +2461,7 @@ public class WifiStateMachine extends StateMachine { WifiConfiguration config; Long now; String report; + String key; StringBuilder sb = new StringBuilder(); if (mScreenOn) { sb.append("!"); @@ -2448,6 +2498,7 @@ public class WifiStateMachine extends StateMachine { if (lastScanDuration != 0) { sb.append(" dur:").append(lastScanDuration); } + sb.append(" cnt=").append(mDelayedScanCounter); sb.append(" rssi=").append(mWifiInfo.getRssi()); sb.append(" f=").append(mWifiInfo.getFrequency()); sb.append(" sc=").append(mWifiInfo.score); @@ -2568,6 +2619,11 @@ public class WifiStateMachine extends StateMachine { sb.append(",").append(mRxTime); } sb.append(String.format(" bcn=%d", mRunningBeaconCount)); + sb.append(String.format(" con=%d", mConnectionRequests)); + key = mWifiConfigStore.getLastSelectedConfiguration(); + if (key != null) { + sb.append(" last=").append(key); + } break; case WifiMonitor.NETWORK_CONNECTION_EVENT: sb.append(" "); @@ -2581,6 +2637,10 @@ public class WifiStateMachine extends StateMachine { sb.append(" ").append(config.configKey()); } sb.append(printTime()); + key = mWifiConfigStore.getLastSelectedConfiguration(); + if (key != null) { + sb.append(" last=").append(key); + } break; case CMD_TARGET_BSSID: case CMD_ASSOCIATED_BSSID: @@ -2764,7 +2824,7 @@ public class WifiStateMachine extends StateMachine { sb.append(Integer.toString(msg.arg1)); sb.append(" "); sb.append(Integer.toString(msg.arg2)); - String key = mWifiConfigStore.getLastSelectedConfiguration(); + key = mWifiConfigStore.getLastSelectedConfiguration(); if (key != null) { sb.append(" last=").append(key); } @@ -2934,7 +2994,6 @@ public class WifiStateMachine extends StateMachine { mScreenOn = screenOn; if (PDBG) { loge(" handleScreenStateChanged Enter: screenOn=" + screenOn - + " mCurrentScanAlarmMs = " + Long.toString(mCurrentScanAlarmMs) + " mUserWantsSuspendOpt=" + mUserWantsSuspendOpt + " state " + getCurrentState().getName() + " suppState:" + mSupplicantStateTracker.getSupplicantStateName()); @@ -2955,38 +3014,41 @@ public class WifiStateMachine extends StateMachine { getWifiLinkLayerStats(false); mOnTimeScreenStateChange = mOnTime; lastScreenStateChangeTimeStamp = lastLinkLayerStatsUpdate; + mEnableBackgroundScan = false; + cancelDelayedScan(); if (screenOn) { + setScanAlarm(false); clearBlacklist(); fullBandConnectedTimeIntervalMilli = mWifiConfigStore.associatedPartialScanPeriodMilli; - // Start the scan alarm so as to enable autojoin + // In either Disconnectedstate or ConnectedState, + // start the scan alarm so as to enable autojoin if (getCurrentState() == mConnectedState && mWifiConfigStore.enableAutoJoinScanWhenAssociated) { - mCurrentScanAlarmMs = mWifiConfigStore.associatedPartialScanPeriodMilli; - // Scan after 200ms - setScanAlarm(true, 200); + // Scan after 500ms + startDelayedScan(500, null, null); } else if (getCurrentState() == mDisconnectedState) { - mCurrentScanAlarmMs = mDisconnectedScanPeriodMs; // Scan after 200ms - setScanAlarm(true, 200); + startDelayedScan(200, null, null); + } + } else if (startBackgroundScanIfNeeded) { + // Screen Off and Disconnected and chipset doesn't support scan offload + // => start scan alarm + // Screen Off and Disconnected and chipset does support scan offload + // => will use scan offload (i.e. background scan) + if (!mBackgroundScanSupported) { + setScanAlarm(true); + } else { + mEnableBackgroundScan = true; } - } else { - setScanAlarm(false, 0); - } - - if (mBackgroundScanSupported) { - mEnableBackgroundScan = (screenOn == false); } - if (DBG) logd("backgroundScan enabled=" + mEnableBackgroundScan + " startBackgroundScanIfNeeded:" + startBackgroundScanIfNeeded); - if (startBackgroundScanIfNeeded) { // to scan for them in background, we need all networks enabled enableBackgroundScan(mEnableBackgroundScan); } - if (DBG) log("handleScreenStateChanged Exit: " + screenOn); } @@ -3381,10 +3443,15 @@ public class WifiStateMachine extends StateMachine { attemptAutoJoin = false; } if (DBG) { + String selection = mWifiConfigStore.getLastSelectedConfiguration(); + if (selection == null) { + selection = ""; + } loge("wifi setScanResults state" + getCurrentState() + " sup_state=" + state + " debouncing=" + linkDebouncing - + " mConnectionRequests=" + mConnectionRequests); + + " mConnectionRequests=" + mConnectionRequests + + " selection=" + selection); } if (attemptAutoJoin) { messageHandlingStatus = MESSAGE_HANDLING_STATUS_PROCESSED; @@ -4220,7 +4287,14 @@ public class WifiStateMachine extends StateMachine { linkDebouncing = false; /* Reset roaming parameters */ mAutoRoaming = WifiAutoJoinController.AUTO_JOIN_IDLE; - fullBandConnectedTimeIntervalMilli = 20 * 1000; // Start scans at 20 seconds interval + + /** + * fullBandConnectedTimeIntervalMilli: + * - start scans at mWifiConfigStore.associatedPartialScanPeriodMilli seconds interval + * - exponentially increase to mWifiConfigStore.associatedFullScanMaxIntervalMilli + * Initialize to sane value = 20 seconds + */ + fullBandConnectedTimeIntervalMilli = 20 * 1000; setNetworkDetailedState(DetailedState.DISCONNECTED); if (mNetworkAgent != null) { @@ -5227,7 +5301,7 @@ public class WifiStateMachine extends StateMachine { public void enter() { if (PDBG) { - loge("Driverstarted State enter"); + loge("DriverStartedState enter"); } mIsRunning = true; mInDelayedStop = false; @@ -6877,6 +6951,8 @@ public class WifiStateMachine extends StateMachine { if (message.arg1 == SCAN_ONLY_WITH_WIFI_OFF_MODE) { noteWifiDisabledWhileAssociated(); } + mWifiConfigStore. + setLastSelectedConfiguration(WifiConfiguration.INVALID_NETWORK_ID); } break; case CMD_SET_COUNTRY_CODE: @@ -6892,6 +6968,20 @@ public class WifiStateMachine extends StateMachine { + " RSSI=" + mWifiInfo.getRssi()); //} if (message.arg1 == SCAN_ALARM_SOURCE) { + // Check if the CMD_START_SCAN message is obsolete (and thus if it should + // not be processed) and restart the scan if needed + boolean shouldScan = + mScreenOn && mWifiConfigStore.enableAutoJoinScanWhenAssociated; + if (!checkAndRestartDelayedScan(message.arg2, + shouldScan, + mWifiConfigStore.associatedPartialScanPeriodMilli, null, null)) { + messageHandlingStatus = MESSAGE_HANDLING_STATUS_OBSOLETE; + loge("WifiStateMachine L2Connected CMD_START_SCAN source " + + message.arg1 + + " " + message.arg2 + ", " + mDelayedScanCounter + + " -> obsolete"); + return HANDLED; + } boolean tryFullBandScan = false; boolean restrictChannelList = false; long now_ms = System.currentTimeMillis(); @@ -6997,13 +7087,14 @@ public class WifiStateMachine extends StateMachine { WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, message); } } + } else { loge("CMD_START_SCAN : connected mode and no configuration"); messageHandlingStatus = MESSAGE_HANDLING_STATUS_HANDLING_ERROR; } } else { // Not scan alarm source - handleScanRequest(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, message); + return NOT_HANDLED; } break; /* Ignore connection to same network */ @@ -7147,6 +7238,8 @@ public class WifiStateMachine extends StateMachine { } obtainingIpWatchdogCount++; loge("Start Dhcp Watchdog " + obtainingIpWatchdogCount); + // Get Link layer stats so as we get fresh tx packet counters + getWifiLinkLayerStats(true); sendMessageDelayed(obtainMessage(CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER, obtainingIpWatchdogCount, 0), OBTAINING_IP_ADDRESS_GUARD_TIMER_MSEC); } else { @@ -7283,7 +7376,7 @@ public class WifiStateMachine extends StateMachine { log("RoamingState Enter" + " mScreenOn=" + mScreenOn ); } - setScanAlarm(false, 0); + setScanAlarm(false); // Make sure we disconnect if roaming fails roamWatchdogCount++; @@ -7414,11 +7507,8 @@ public class WifiStateMachine extends StateMachine { } if (mScreenOn && mWifiConfigStore.enableAutoJoinScanWhenAssociated) { - mCurrentScanAlarmMs = mWifiConfigStore.associatedPartialScanPeriodMilli; - // Scan after 200ms - setScanAlarm(true, 200); - } else { - mCurrentScanAlarmMs = 0; + // restart scan alarm + startDelayedScan(mWifiConfigStore.associatedPartialScanPeriodMilli, null, null); } registerConnected(); lastConnectAttempt = 0; @@ -7619,7 +7709,7 @@ public class WifiStateMachine extends StateMachine { @Override public void exit() { loge("WifiStateMachine: Leaving Connected state"); - setScanAlarm(false, 0); + setScanAlarm(false); mLastDriverRoamAttempt = 0; } } @@ -7628,7 +7718,6 @@ public class WifiStateMachine extends StateMachine { @Override public void enter() { - mCurrentScanAlarmMs = mDisconnectedScanPeriodMs; if (PDBG) { loge(" Enter DisconnectingState State scan interval " + mFrameworkScanIntervalMs @@ -7658,7 +7747,7 @@ public class WifiStateMachine extends StateMachine { } break; case CMD_START_SCAN: - // Ignore scans while disconnecting + deferMessage(message); return HANDLED; case CMD_DISCONNECTING_WATCHDOG_TIMER: if (disconnectingWatchdogCount == message.arg1) { @@ -7682,11 +7771,6 @@ public class WifiStateMachine extends StateMachine { } return HANDLED; } - - @Override - public void exit() { - mCurrentScanAlarmMs = 0; - } } class DisconnectedState extends State { @@ -7699,17 +7783,10 @@ public class WifiStateMachine extends StateMachine { return; } - // Loose the last selection choice - // mWifiAutoJoinController.setLastSelectedConfiguration - // (WifiConfiguration.INVALID_NETWORK_ID); - mFrameworkScanIntervalMs = Settings.Global.getLong(mContext.getContentResolver(), Settings.Global.WIFI_FRAMEWORK_SCAN_INTERVAL_MS, mDefaultFrameworkScanIntervalMs); - if (mScreenOn) - mCurrentScanAlarmMs = mDisconnectedScanPeriodMs; - if (PDBG) { loge(" Enter disconnected State scan interval " + mFrameworkScanIntervalMs + " mEnableBackgroundScan= " + mEnableBackgroundScan @@ -7720,23 +7797,28 @@ public class WifiStateMachine extends StateMachine { /** clear the roaming state, if we were roaming, we failed */ mAutoRoaming = WifiAutoJoinController.AUTO_JOIN_IDLE; - /** - * - screen dark and PNO supported => scan alarm disabled - * - everything else => scan alarm enabled with mDefaultFrameworkScanIntervalMs period - */ - if ((mScreenOn == false) && mEnableBackgroundScan) { - - /* If a regular scan result is pending, do not initiate background - * scan until the scan results are returned. This is needed because - * initiating a background scan will cancel the regular scan and - * scan results will not be returned until background scanning is - * cleared + if (mScreenOn) { + /** + * screen lit and => delayed timer */ - if (!mIsScanOngoing) { - enableBackgroundScan(true); - } + startDelayedScan(mDisconnectedScanPeriodMs, null, null); } else { - setScanAlarm(true, 200); + /** + * screen dark and PNO supported => scan alarm disabled + */ + if (mEnableBackgroundScan) { + /* If a regular scan result is pending, do not initiate background + * scan until the scan results are returned. This is needed because + * initiating a background scan will cancel the regular scan and + * scan results will not be returned until background scanning is + * cleared + */ + if (!mIsScanOngoing) { + enableBackgroundScan(true); + } + } else { + setScanAlarm(true); + } } /** @@ -7805,16 +7887,32 @@ public class WifiStateMachine extends StateMachine { ret = NOT_HANDLED; break; case CMD_START_SCAN: - if (!isScanAllowed()) { - // Ignore the scan request + if (!checkOrDeferScanAllowed(message)) { + // The scan request was rescheduled + messageHandlingStatus = MESSAGE_HANDLING_STATUS_REFUSED; return HANDLED; } /* Disable background scan temporarily during a regular scan */ if (mEnableBackgroundScan) { enableBackgroundScan(false); } - /* Handled in parent state */ - ret = NOT_HANDLED; + if (message.arg1 == SCAN_ALARM_SOURCE) { + // Check if the CMD_START_SCAN message is obsolete (and thus if it should + // not be processed) and restart the scan + if (!checkAndRestartDelayedScan(message.arg2, + true, mDisconnectedScanPeriodMs, null, null)) { + messageHandlingStatus = MESSAGE_HANDLING_STATUS_OBSOLETE; + loge("WifiStateMachine Disconnected CMD_START_SCAN source " + + message.arg1 + + " " + message.arg2 + ", " + mDelayedScanCounter + + " -> obsolete"); + return HANDLED; + } + handleScanRequest(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, message); + ret = HANDLED; + } else { + ret = NOT_HANDLED; + } break; case WifiMonitor.SCAN_RESULTS_EVENT: /* Re-enable background scan when a pending scan result is received */ @@ -7866,8 +7964,7 @@ public class WifiStateMachine extends StateMachine { if (mEnableBackgroundScan) { enableBackgroundScan(false); } - mCurrentScanAlarmMs = 0; - setScanAlarm(false, 0); + setScanAlarm(false); } } -- cgit v1.2.3 From b5093966bd03251f42d67923b223b187d6b83d24 Mon Sep 17 00:00:00 2001 From: vandwalle Date: Tue, 9 Dec 2014 15:16:34 -0800 Subject: handle beacons reported with wrong RSSI value of 0 Bug:18654243 Change-Id: Ied2fbc87c7effc23fecb68e9863153d63c0cfba4 --- .../java/com/android/server/wifi/WifiAutoJoinController.java | 12 ++++++++++++ service/java/com/android/server/wifi/WifiConfigStore.java | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/service/java/com/android/server/wifi/WifiAutoJoinController.java b/service/java/com/android/server/wifi/WifiAutoJoinController.java index 0dfa3fb7b..596a61d92 100644 --- a/service/java/com/android/server/wifi/WifiAutoJoinController.java +++ b/service/java/com/android/server/wifi/WifiAutoJoinController.java @@ -171,11 +171,23 @@ public class WifiAutoJoinController { // Fetch the previous instance for this result ScanResult sr = scanResultCache.get(result.BSSID); if (sr != null) { + if (mWifiConfigStore.scanResultRssiLevelPatchUp != 0 + && result.level == 0 + && sr.level < -20) { + // A 'zero' RSSI reading is most likely a chip problem which returns + // an unknown RSSI, hence ignore it + result.level = sr.level; + } + // If there was a previous cache result for this BSSID, average the RSSI values result.averageRssi(sr.level, sr.seen, mScanResultMaximumAge); // Remove the previous Scan Result - this is not necessary scanResultCache.remove(result.BSSID); + } else if (mWifiConfigStore.scanResultRssiLevelPatchUp != 0 && result.level == 0) { + // A 'zero' RSSI reading is most likely a chip problem which returns + // an unknown RSSI, hence initialize it to a sane value + result.level = mWifiConfigStore.scanResultRssiLevelPatchUp; } if (!mNetworkScoreCache.isScoredNetwork(result)) { diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java index 028e2bb42..cf4163557 100644 --- a/service/java/com/android/server/wifi/WifiConfigStore.java +++ b/service/java/com/android/server/wifi/WifiConfigStore.java @@ -387,6 +387,7 @@ public class WifiConfigStore extends IpConfigStore { public boolean enableWifiCellularHandoverUserTriggeredAdjustment = true; public int currentNetworkBoost = 25; + public int scanResultRssiLevelPatchUp = -85; /** * Regex pattern for extracting a connect choice. @@ -539,8 +540,12 @@ public class WifiConfigStore extends IpConfigStore { enableAutoJoinWhenAssociated = mContext.getResources().getBoolean( R.bool.config_wifi_framework_enable_associated_network_selection); + currentNetworkBoost = mContext.getResources().getInteger( R.integer.config_wifi_framework_current_network_boost); + + scanResultRssiLevelPatchUp = mContext.getResources().getInteger( + R.integer.config_wifi_framework_scan_result_rssi_level_patchup_value); } void enableVerboseLogging(int verbose) { -- cgit v1.2.3 From 25ed68e86c14fd1a6501ffb68d84a0e524be0925 Mon Sep 17 00:00:00 2001 From: vandwalle Date: Tue, 9 Dec 2014 17:52:35 -0800 Subject: autojoin scanning + P2P - discard autojoin scan when both infra and P2P are connected - reduce autojoin scan period when P2P is connected and infra is disconnected Bug:18692653 Change-Id: Id1891e6a9f2863d8876915cfefd158fb1712b8fe --- .../com/android/server/wifi/WifiStateMachine.java | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index a1ff29484..69444610a 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -7014,6 +7014,14 @@ public class WifiStateMachine extends StateMachine { + " -> obsolete"); return HANDLED; } + if (mP2pConnected.get()) { + loge("WifiStateMachine L2Connected CMD_START_SCAN source " + + message.arg1 + + " " + message.arg2 + ", " + mDelayedScanCounter + + " ignore because P2P is connected"); + messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; + return HANDLED; + } boolean tryFullBandScan = false; boolean restrictChannelList = false; long now_ms = System.currentTimeMillis(); @@ -7931,8 +7939,14 @@ public class WifiStateMachine extends StateMachine { if (message.arg1 == SCAN_ALARM_SOURCE) { // Check if the CMD_START_SCAN message is obsolete (and thus if it should // not be processed) and restart the scan + int period = mDisconnectedScanPeriodMs; + if (mP2pConnected.get()) { + period = (int)Settings.Global.getLong(mContext.getContentResolver(), + Settings.Global.WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS, + mDisconnectedScanPeriodMs); + } if (!checkAndRestartDelayedScan(message.arg2, - true, mDisconnectedScanPeriodMs, null, null)) { + true, period, null, null)) { messageHandlingStatus = MESSAGE_HANDLING_STATUS_OBSOLETE; loge("WifiStateMachine Disconnected CMD_START_SCAN source " + message.arg1 @@ -7968,6 +7982,12 @@ public class WifiStateMachine extends StateMachine { if (DBG) log("Turn on scanning after p2p disconnected"); sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN, ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs); + } else { + // If P2P is not connected and there are saved networks, then restart + // scanning at the normal period. This is necessary because scanning might + // have been disabled altogether if WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS + // was set to zero. + startDelayedScan(mDisconnectedScanPeriodMs, null, null); } case CMD_RECONNECT: case CMD_REASSOCIATE: -- cgit v1.2.3 From e3545108f6bc452dd3fb5e614c8938b6a3c95908 Mon Sep 17 00:00:00 2001 From: vandwalle Date: Wed, 10 Dec 2014 13:16:41 -0800 Subject: make sure wificonfiguration scan cache doesnt grow unbounded Bug:18703749 Change-Id: If6452e7dbaaabb164cf2a99b48b3964f4cb86ee5 --- service/java/com/android/server/wifi/WifiConfigStore.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java index cf4163557..cd7cb5789 100644 --- a/service/java/com/android/server/wifi/WifiConfigStore.java +++ b/service/java/com/android/server/wifi/WifiConfigStore.java @@ -389,6 +389,8 @@ public class WifiConfigStore extends IpConfigStore { public int currentNetworkBoost = 25; public int scanResultRssiLevelPatchUp = -85; + public static final int maxNumScanCacheEntries = 128; + /** * Regex pattern for extracting a connect choice. * Matches a strings like the following: @@ -2103,7 +2105,6 @@ public class WifiConfigStore extends IpConfigStore { } if (key.startsWith(BSSID_KEY_END)) { - if ((bssid != null) && (ssid != null)) { if (config.scanResultCache == null) { @@ -3358,6 +3359,13 @@ public class WifiConfigStore extends IpConfigStore { scanResult.untrusted = true; } + if (config.scanResultCache.size() > (maxNumScanCacheEntries+64)) { + // Trim the scan result cache to maxNumScanCacheEntries entries max + // Since this operation is expensive, make sure it is not performed + // until the cache has grown significantly above the trim treshold + config.trimScanResultsCache(maxNumScanCacheEntries); + } + // Add the scan result to this WifiConfiguration config.scanResultCache.put(scanResult.BSSID, scanResult); // Since we added a scan result to this configuration, re-attempt linking -- cgit v1.2.3 From 344c6257a90417a6ec596ab0dde4ab337c10d635 Mon Sep 17 00:00:00 2001 From: vandwalle Date: Wed, 10 Dec 2014 13:34:21 -0800 Subject: fix logspam Bug:18589606 Change-Id: Ieee0b91ab96ec9392a9b91ac1017a319605425dc --- .../com/android/server/wifi/WifiConfigStore.java | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java index cd7cb5789..ebdf40efa 100644 --- a/service/java/com/android/server/wifi/WifiConfigStore.java +++ b/service/java/com/android/server/wifi/WifiConfigStore.java @@ -1800,7 +1800,7 @@ public class WifiConfigStore extends IpConfigStore { } public void setLastSelectedConfiguration(int netId) { - if (DBG) { + if (VDBG) { loge("setLastSelectedConfiguration " + Integer.toString(netId)); } if (netId == WifiConfiguration.INVALID_NETWORK_ID) { @@ -3359,11 +3359,28 @@ public class WifiConfigStore extends IpConfigStore { scanResult.untrusted = true; } - if (config.scanResultCache.size() > (maxNumScanCacheEntries+64)) { + if (config.scanResultCache.size() > (maxNumScanCacheEntries + 64)) { + long now_dbg = 0; + if (VVDBG) { + loge(" Will trim config " + config.configKey() + + " size " + config.scanResultCache.size()); + + for (ScanResult r : config.scanResultCache.values()) { + loge(" " + result.BSSID + " " + result.seen); + } + now_dbg = SystemClock.elapsedRealtimeNanos(); + } // Trim the scan result cache to maxNumScanCacheEntries entries max // Since this operation is expensive, make sure it is not performed // until the cache has grown significantly above the trim treshold config.trimScanResultsCache(maxNumScanCacheEntries); + if (VVDBG) { + long diff = SystemClock.elapsedRealtimeNanos() - now_dbg; + loge(" Finished trimming config, time(ns) " + diff); + for (ScanResult r : config.scanResultCache.values()) { + loge(" " + r.BSSID + " " + r.seen); + } + } } // Add the scan result to this WifiConfiguration -- cgit v1.2.3 From 1a90ba674975421d9f0e6ac308ce9ee1acbada40 Mon Sep 17 00:00:00 2001 From: vandwalle Date: Wed, 10 Dec 2014 17:55:43 -0800 Subject: Apply 5GHz band preference only when comparing configurations on different bands Bug:18589301 Change-Id: I0093620c859940d993c9ea60d9d6cdc86bb2fa58 --- .../server/wifi/WifiAutoJoinController.java | 84 +++++++++++++++------- 1 file changed, 60 insertions(+), 24 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiAutoJoinController.java b/service/java/com/android/server/wifi/WifiAutoJoinController.java index 596a61d92..e30b1c789 100644 --- a/service/java/com/android/server/wifi/WifiAutoJoinController.java +++ b/service/java/com/android/server/wifi/WifiAutoJoinController.java @@ -584,30 +584,75 @@ public class WifiAutoJoinController { } } + int compareWifiConfigurationsFromVisibility(WifiConfiguration a, int aRssiBoost, + WifiConfiguration b, int bRssiBoost) { - int getScoreFromVisibility(WifiConfiguration.Visibility visibility, int rssiBoost, String dbg) { - int rssiBoost5 = 0; - int score = 0; + int aRssiBoost5 = 0; // 5GHz RSSI boost to apply for purpose band selection (5GHz pref) + int bRssiBoost5 = 0; // 5GHz RSSI boost to apply for purpose band selection (5GHz pref) + + int aScore = 0; + int bScore = 0; + + boolean aPrefers5GHz = false; + boolean bPrefers5GHz = false; /** - * Boost RSSI value of 5GHz bands iff the base value is better than threshold + * Calculate a boost to apply to RSSI value of configuration we want to join on 5GHz: + * Boost RSSI value of 5GHz bands iff the base value is better than threshold, + * penalize the RSSI value of 5GHz band iff the base value is lower than threshold * This implements band preference where we prefer 5GHz if RSSI5 is good enough, whereas * we prefer 2.4GHz otherwise. - * Note that 2.4GHz doesn't need a boost since at equal power the RSSI is typically - * at least 6-10 dB higher */ - rssiBoost5 = rssiBoostFrom5GHzRssi(visibility.rssi5, dbg+"->"); + aRssiBoost5 = rssiBoostFrom5GHzRssi(a.visibility.rssi5, a.configKey() + "->"); + bRssiBoost5 = rssiBoostFrom5GHzRssi(b.visibility.rssi5, b.configKey() + "->"); - // Select which band to use so as to score a - if (visibility.rssi5 + rssiBoost5 > visibility.rssi24) { + // Select which band to use for a + if (a.visibility.rssi5 + aRssiBoost5 > b.visibility.rssi24) { // Prefer a's 5GHz - score = visibility.rssi5 + rssiBoost5 + rssiBoost; + aPrefers5GHz = true; + } + + // Select which band to use for b + if (b.visibility.rssi5 + bRssiBoost5 > b.visibility.rssi24) { + // Prefer b's 5GHz + bPrefers5GHz = true; + } + + if (aPrefers5GHz) { + if (bPrefers5GHz) { + // If both a and b are on 5GHz then we don't apply the 5GHz RSSI boost to either + // one, but directly compare the RSSI values, this improves stability, + // since the 5GHz RSSI boost can introduce large fluctuations + aScore = a.visibility.rssi5 + aRssiBoost; + } else { + // If only a is on 5GHz, then apply the 5GHz preference boost to a + aScore = a.visibility.rssi5 + aRssiBoost + aRssiBoost5; + } } else { - // Prefer a's 2.4GHz - score = visibility.rssi24 + rssiBoost; + aScore = a.visibility.rssi24 + aRssiBoost; } - return score; + if (bPrefers5GHz) { + if (aPrefers5GHz) { + // If both a and b are on 5GHz then we don't apply the 5GHz RSSI boost to either + // one, but directly compare the RSSI values, this improves stability, + // since the 5GHz RSSI boost can introduce large fluctuations + bScore = b.visibility.rssi5 + bRssiBoost; + } else { + // If only b is on 5GHz, then apply the 5GHz preference boost to b + bScore = b.visibility.rssi5 + bRssiBoost + bRssiBoost5; + } + } else { + bScore = b.visibility.rssi24 + bRssiBoost; + } + if (VDBG) { + logDbg(" " + a.configKey() + " is5=" + aPrefers5GHz + " score=" + aScore + + b.configKey() + " is5=" + bPrefers5GHz + " score=" + bScore); + } + // Compare a and b + // If a score is higher then a > b and the order is descending (negative) + // If b score is higher then a < b and the order is ascending (positive) + return bScore - aScore; } // Compare WifiConfiguration by RSSI, and return a comparison value in the range [-50, +50] @@ -658,13 +703,7 @@ public class WifiAutoJoinController { ); } - scoreA = getScoreFromVisibility(astatus, aRssiBoost, a.configKey()); - scoreB = getScoreFromVisibility(bstatus, bRssiBoost, b.configKey()); - - // Compare a and b - // If a score is higher then a > b and the order is descending (negative) - // If b score is higher then a < b and the order is ascending (positive) - order = scoreB - scoreA; + order = compareWifiConfigurationsFromVisibility(a, aRssiBoost, b, bRssiBoost); // Normalize the order to [-50, +50] if (order > 50) order = 50; @@ -682,13 +721,11 @@ public class WifiAutoJoinController { + "," + a.visibility.rssi5 + ") num=(" + a.visibility.num24 + "," + a.visibility.num5 + ")" - + " scorea=" + scoreA + prefer + b.configKey() + " rssi=(" + b.visibility.rssi24 + "," + b.visibility.rssi5 + ") num=(" + b.visibility.num24 + "," + b.visibility.num5 + ")" - + " scoreb=" + scoreB + " -> " + order); } @@ -895,8 +932,7 @@ public class WifiAutoJoinController { int boost = mWifiConfigStore.bandPreferenceBoostFactor5 *(rssi - mWifiConfigStore.bandPreferenceBoostThreshold5); if (boost > 50) { - // 50 dB boost is set so as to overcome the hysteresis of +20 plus a difference of - // 25 dB between 2.4 and 5GHz band. This allows jumping from 2.4 to 5GHz + // 50 dB boost allows jumping from 2.4 to 5GHz // consistently boost = 50; } -- cgit v1.2.3