From ec28f863c5e46c0a75e8bdb92283304b875ee0f2 Mon Sep 17 00:00:00 2001 From: Peter Qiu Date: Tue, 7 Mar 2017 14:25:01 -0800 Subject: hotspot2: use ScanResult to match Passpoint providers This removes ScanDetail and NetworkDetail dependencies from PasspointManager, and allows provider matching to be performed using ScanResult instead of ScanDetail. Bug: 35888100 Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh Test: manual test using Global Reach Passpoint profile Change-Id: I229f042352e2d51cfaf9c154d707f3b6b39b2c5d --- .../server/wifi/hotspot2/ANQPRequestManager.java | 13 +++-- .../server/wifi/hotspot2/PasspointManager.java | 60 +++++++++++++++------- .../wifi/hotspot2/PasspointNetworkEvaluator.java | 8 ++- .../wifi/hotspot2/PasspointNetworkScore.java | 10 ++-- 4 files changed, 58 insertions(+), 33 deletions(-) (limited to 'service') diff --git a/service/java/com/android/server/wifi/hotspot2/ANQPRequestManager.java b/service/java/com/android/server/wifi/hotspot2/ANQPRequestManager.java index fd756c3a2..dfdf4ad16 100644 --- a/service/java/com/android/server/wifi/hotspot2/ANQPRequestManager.java +++ b/service/java/com/android/server/wifi/hotspot2/ANQPRequestManager.java @@ -20,7 +20,6 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.server.wifi.Clock; -import com.android.server.wifi.ScanDetail; import com.android.server.wifi.hotspot2.anqp.Constants; import java.util.ArrayList; @@ -43,7 +42,7 @@ public class ANQPRequestManager { /** * List of pending ANQP request associated with an AP (BSSID). */ - private final Map mPendingQueries; + private final Map mPendingQueries; /** * List of hold off time information associated with APs specified by their BSSID. @@ -109,14 +108,14 @@ public class ANQPRequestManager { * supported Hotspot 2.0 release version). * * @param bssid The BSSID of the AP - * @param scanDetail The ScanDetail associated with this request + * @param anqpNetworkKey The unique network key associated with this request * @param rcOIs Flag indicating the inclusion of roaming consortium OIs. When set to true, * Roaming Consortium ANQP element will be requested * @param hsReleaseR2 Flag indicating the support of Hotspot 2.0 Release 2. When set to true, * the Release 2 ANQP elements {@link #R2_ANQP_BASE_SET} will be requested * @return true if a request was sent successfully */ - public boolean requestANQPElements(long bssid, ScanDetail scanDetail, boolean rcOIs, + public boolean requestANQPElements(long bssid, ANQPNetworkKey anqpNetworkKey, boolean rcOIs, boolean hsReleaseR2) { // Check if we are allow to send the request now. if (!canSendRequestNow(bssid)) { @@ -132,7 +131,7 @@ public class ANQPRequestManager { // the given AP. updateHoldOffInfo(bssid); - mPendingQueries.put(bssid, scanDetail); + mPendingQueries.put(bssid, anqpNetworkKey); return true; } @@ -141,9 +140,9 @@ public class ANQPRequestManager { * * @param bssid The BSSID of the AP * @param success Flag indicating the result of the query - * @return {@link ScanDetail} associated with the completed request + * @return {@link ANQPNetworkKey} associated with the completed request */ - public ScanDetail onRequestCompleted(long bssid, boolean success) { + public ANQPNetworkKey onRequestCompleted(long bssid, boolean success) { if (success) { // Query succeeded. No need to hold off request to the given AP. mHoldOffInfo.remove(bssid); diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java index ff8b50f77..f88c9d5bc 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java @@ -29,6 +29,7 @@ import static android.net.wifi.WifiManager.EXTRA_URL; import android.content.Context; import android.content.Intent; import android.net.wifi.IconInfo; +import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.hotspot2.PasspointConfiguration; @@ -39,13 +40,13 @@ import android.util.Pair; import com.android.server.wifi.Clock; import com.android.server.wifi.SIMAccessor; -import com.android.server.wifi.ScanDetail; import com.android.server.wifi.WifiConfigManager; import com.android.server.wifi.WifiConfigStore; import com.android.server.wifi.WifiKeyStore; import com.android.server.wifi.WifiNative; import com.android.server.wifi.hotspot2.anqp.ANQPElement; import com.android.server.wifi.hotspot2.anqp.Constants; +import com.android.server.wifi.util.InformationElementUtil; import java.util.ArrayList; import java.util.HashMap; @@ -103,23 +104,16 @@ public class PasspointManager { public void onANQPResponse(long bssid, Map anqpElements) { // Notify request manager for the completion of a request. - ScanDetail scanDetail = + ANQPNetworkKey anqpKey = mAnqpRequestManager.onRequestCompleted(bssid, anqpElements != null); - if (anqpElements == null || scanDetail == null) { + if (anqpElements == null || anqpKey == null) { // Query failed or the request wasn't originated from us (not tracked by the // request manager). Nothing to be done. return; } // Add new entry to the cache. - NetworkDetail networkDetail = scanDetail.getNetworkDetail(); - ANQPNetworkKey anqpKey = ANQPNetworkKey.buildKey(networkDetail.getSSID(), - networkDetail.getBSSID(), networkDetail.getHESSID(), - networkDetail.getAnqpDomainID()); mAnqpCache.addEntry(anqpKey, anqpElements); - - // Update ANQP elements in the ScanDetail. - scanDetail.propagateANQPInfo(anqpElements); } @Override @@ -286,26 +280,32 @@ public class PasspointManager { * * An empty list will returned in the case when no match is found. * - * @param scanDetail The detail information of the AP + * @param scanResult The scan result associated with the AP * @return List of {@link PasspointProvider} */ - public List> matchProvider(ScanDetail scanDetail) { + public List> matchProvider(ScanResult scanResult) { // Nothing to be done if no Passpoint provider is installed. if (mProviders.isEmpty()) { return new ArrayList>(); } + // Retrieve the relevant information elements, mainly Roaming Consortium IE and Hotspot 2.0 + // Vendor Specific IE. + InformationElementUtil.RoamingConsortium roamingConsortium = + InformationElementUtil.getRoamingConsortiumIE(scanResult.informationElements); + InformationElementUtil.Vsa vsa = InformationElementUtil.getHS2VendorSpecificIE( + scanResult.informationElements); + // Lookup ANQP data in the cache. - NetworkDetail networkDetail = scanDetail.getNetworkDetail(); - ANQPNetworkKey anqpKey = ANQPNetworkKey.buildKey(networkDetail.getSSID(), - networkDetail.getBSSID(), networkDetail.getHESSID(), - networkDetail.getAnqpDomainID()); + long bssid = Utils.parseMac(scanResult.BSSID); + ANQPNetworkKey anqpKey = ANQPNetworkKey.buildKey(scanResult.SSID, bssid, scanResult.hessid, + vsa.anqpDomainID); ANQPData anqpEntry = mAnqpCache.getEntry(anqpKey); if (anqpEntry == null) { - mAnqpRequestManager.requestANQPElements(networkDetail.getBSSID(), scanDetail, - networkDetail.getAnqpOICount() > 0, - networkDetail.getHSRelease() == NetworkDetail.HSRelease.R2); + mAnqpRequestManager.requestANQPElements(bssid, anqpKey, + roamingConsortium.anqpOICount > 0, + vsa.hsRelease == NetworkDetail.HSRelease.R2); return new ArrayList>(); } @@ -382,6 +382,28 @@ public class PasspointManager { return mHandler.requestIcon(bssid, fileName); } + /** + * Lookup the ANQP elements associated with the given AP from the cache. An empty map + * will be returned if no match found in the cache. + * + * @param scanResult The scan result associated with the AP + * @return Map of ANQP elements + */ + public Map getANQPElements(ScanResult scanResult) { + // Retrieve the Hotspot 2.0 Vendor Specific IE. + InformationElementUtil.Vsa vsa = + InformationElementUtil.getHS2VendorSpecificIE(scanResult.informationElements); + + // Lookup ANQP data in the cache. + long bssid = Utils.parseMac(scanResult.BSSID); + ANQPData anqpEntry = mAnqpCache.getEntry(ANQPNetworkKey.buildKey( + scanResult.SSID, bssid, scanResult.hessid, vsa.anqpDomainID)); + if (anqpEntry != null) { + return anqpEntry.getElements(); + } + return new HashMap(); + } + /** * Add a legacy Passpoint configuration represented by a {@link WifiConfiguration}. * diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java index f08b5de32..a1fbcffce 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java @@ -62,6 +62,9 @@ public class PasspointNetworkEvaluator implements WifiNetworkSelector.NetworkEva WifiConfiguration currentNetwork, String currentBssid, boolean connected, boolean untrustedNetworkAllowed, List> connectableNetworks) { + // Sweep the ANQP cache to remove any expired ANQP entries. + mPasspointManager.sweepCache(); + // Go through each ScanDetail and find the best provider for each ScanDetail. List>> providerList = new ArrayList<>(); @@ -72,7 +75,7 @@ public class PasspointNetworkEvaluator implements WifiNetworkSelector.NetworkEva } List> matchedProviders = - mPasspointManager.matchProvider(scanDetail); + mPasspointManager.matchProvider(scanDetail.getScanResult()); // Find the best provider for this ScanDetail. Pair bestProvider = @@ -181,7 +184,8 @@ public class PasspointNetworkEvaluator implements WifiNetworkSelector.NetworkEva boolean isActiveNetwork = TextUtils.equals(currentNetworkSsid, ScanResultUtil.createQuotedSSID(scanDetail.getSSID())); int score = PasspointNetworkScore.calculateScore(match == PasspointMatch.HomeProvider, - scanDetail, isActiveNetwork); + scanDetail, mPasspointManager.getANQPElements(scanDetail.getScanResult()), + isActiveNetwork); if (score > bestScore) { bestScanDetail = scanDetail; diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkScore.java b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkScore.java index 2dc3789f5..03f2e4c2d 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkScore.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkScore.java @@ -145,7 +145,7 @@ public class PasspointNetworkScore { * @return integer score */ public static int calculateScore(boolean isHomeProvider, ScanDetail scanDetail, - boolean isActiveNetwork) { + Map anqpElements, boolean isActiveNetwork) { NetworkDetail networkDetail = scanDetail.getNetworkDetail(); int score = 0; if (isHomeProvider) { @@ -158,9 +158,9 @@ public class PasspointNetworkScore { // Adjust score based on the network type. score += NETWORK_TYPE_SCORES.get(networkDetail.getAnt()); - Map anqp = networkDetail.getANQPElements(); - if (anqp != null) { - HSWanMetricsElement wm = (HSWanMetricsElement) anqp.get(ANQPElementType.HSWANMetrics); + if (anqpElements != null) { + HSWanMetricsElement wm = + (HSWanMetricsElement) anqpElements.get(ANQPElementType.HSWANMetrics); if (wm != null) { if (wm.getStatus() != HSWanMetricsElement.LINK_STATUS_UP || wm.isCapped()) { score -= WAN_PORT_DOWN_OR_CAPPED_PENALTY; @@ -168,7 +168,7 @@ public class PasspointNetworkScore { } IPAddressTypeAvailabilityElement ipa = (IPAddressTypeAvailabilityElement) - anqp.get(ANQPElementType.ANQPIPAddrAvailability); + anqpElements.get(ANQPElementType.ANQPIPAddrAvailability); if (ipa != null) { Integer v4Score = IPV4_SCORES.get(ipa.getV4Availability()); -- cgit v1.2.3