diff options
Diffstat (limited to 'service/java/com')
7 files changed, 272 insertions, 92 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index c617b9e1f..9472367fb 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -1230,12 +1230,11 @@ public class WifiConfigManager { return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } - // Update the keys for non-Passpoint enterprise networks. For Passpoint, the certificates - // and keys are installed at the time the provider is installed. - if (config.enterpriseConfig != null - && config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE - && !config.isPasspoint()) { - if (!(mWifiKeyStore.updateNetworkKeys(newInternalConfig, existingInternalConfig))) { + // Update the keys for saved enterprise networks. For Passpoint, the certificates + // and keys are installed at the time the provider is installed. For suggestion enterprise + // network the certificates and keys are installed at the time the suggestion is added + if (!config.isPasspoint() && !config.fromWifiNetworkSuggestion && config.isEnterprise()) { + if (!mWifiKeyStore.updateNetworkKeys(newInternalConfig, existingInternalConfig)) { return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } } @@ -1372,9 +1371,10 @@ public class WifiConfigManager { if (mVerboseLoggingEnabled) { Log.v(TAG, "Removing network " + config.getPrintableSsid()); } - // Remove any associated enterprise keys for non-Passpoint networks. - if (!config.isPasspoint() && config.enterpriseConfig != null - && config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) { + // Remove any associated enterprise keys for saved enterprise networks. Passpoint network + // will remove the enterprise keys when provider is uninstalled. Suggestion enterprise + // networks will remove the enterprise keys when suggestion is removed. + if (!config.isPasspoint() && !config.fromWifiNetworkSuggestion && config.isEnterprise()) { mWifiKeyStore.removeKeys(config.enterpriseConfig); } @@ -1558,6 +1558,12 @@ public class WifiConfigManager { */ private void setNetworkSelectionEnabled(WifiConfiguration config) { NetworkSelectionStatus status = config.getNetworkSelectionStatus(); + if (status.getNetworkSelectionStatus() + != NetworkSelectionStatus.NETWORK_SELECTION_ENABLED) { + localLog("setNetworkSelectionEnabled: configKey=" + config.configKey() + + " old networkStatus=" + status.getNetworkStatusString() + + " disableReason=" + status.getNetworkDisableReasonString()); + } status.setNetworkSelectionStatus( NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); status.setDisableTime( diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index 339e169f6..a234d4d81 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -277,8 +277,8 @@ public class WifiInjector { mWifiConfigManager, mClock, mConnectivityLocalLog, mWifiConnectivityHelper, subscriptionManager); mWifiNetworkSuggestionsManager = new WifiNetworkSuggestionsManager(mContext, - new Handler(mWifiCoreHandlerThread.getLooper()), this, - mWifiPermissionsUtil, mWifiConfigManager, mWifiConfigStore, mWifiMetrics); + new Handler(mWifiCoreHandlerThread.getLooper()), this, mWifiPermissionsUtil, + mWifiConfigManager, mWifiConfigStore, mWifiMetrics, mWifiKeyStore); mNetworkSuggestionEvaluator = new NetworkSuggestionEvaluator(mWifiNetworkSuggestionsManager, mWifiConfigManager, mConnectivityLocalLog); mScoredNetworkEvaluator = new ScoredNetworkEvaluator(context, clientModeImplLooper, diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java index 7578d3723..6db4e9955 100644 --- a/service/java/com/android/server/wifi/WifiMetrics.java +++ b/service/java/com/android/server/wifi/WifiMetrics.java @@ -26,6 +26,7 @@ import android.net.wifi.IOnWifiUsabilityStatsListener; import android.net.wifi.ScanResult; import android.net.wifi.SupplicantState; import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.DeviceMobilityState; @@ -480,6 +481,8 @@ public class WifiMetrics { sb.append(", mHidden=" + mRouterFingerPrintProto.hidden); sb.append(", mRouterTechnology=" + mRouterFingerPrintProto.routerTechnology); sb.append(", mSupportsIpv6=" + mRouterFingerPrintProto.supportsIpv6); + sb.append(", mEapMethod=" + mRouterFingerPrintProto.eapMethod); + sb.append(", mAuthPhase2Method=" + mRouterFingerPrintProto.authPhase2Method); } return sb.toString(); } @@ -516,9 +519,61 @@ public class WifiMetrics { if (candidate != null) { updateMetricsFromScanResult(candidate); } + if (mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto + .authentication == WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE + && config.enterpriseConfig != null) { + int eapMethod = config.enterpriseConfig.getEapMethod(); + mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto + .eapMethod = getEapMethodProto(eapMethod); + int phase2Method = config.enterpriseConfig.getPhase2Method(); + mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto + .authPhase2Method = getAuthPhase2MethodProto(phase2Method); + } } } } + private int getEapMethodProto(int eapMethod) { + switch (eapMethod) { + case WifiEnterpriseConfig.Eap.TLS: + return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_TLS; + case WifiEnterpriseConfig.Eap.UNAUTH_TLS: + return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_UNAUTH_TLS; + case WifiEnterpriseConfig.Eap.PEAP: + return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_PEAP; + case WifiEnterpriseConfig.Eap.PWD: + return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_PWD; + case WifiEnterpriseConfig.Eap.TTLS: + return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_TTLS; + case WifiEnterpriseConfig.Eap.SIM: + return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_SIM; + case WifiEnterpriseConfig.Eap.AKA: + return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_AKA; + case WifiEnterpriseConfig.Eap.AKA_PRIME: + return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_AKA_PRIME; + default: + return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_UNKNOWN; + } + } + private int getAuthPhase2MethodProto(int phase2Method) { + switch (phase2Method) { + case WifiEnterpriseConfig.Phase2.PAP: + return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_PAP; + case WifiEnterpriseConfig.Phase2.MSCHAP: + return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_MSCHAP; + case WifiEnterpriseConfig.Phase2.MSCHAPV2: + return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_MSCHAPV2; + case WifiEnterpriseConfig.Phase2.GTC: + return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_GTC; + case WifiEnterpriseConfig.Phase2.SIM: + return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_SIM; + case WifiEnterpriseConfig.Phase2.AKA: + return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_AKA; + case WifiEnterpriseConfig.Phase2.AKA_PRIME: + return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_AKA_PRIME; + default: + return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_NONE; + } + } } /** diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java index 644eb6523..426dddb8e 100644 --- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java +++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java @@ -108,6 +108,7 @@ public class WifiNetworkSuggestionsManager { private final WifiMetrics mWifiMetrics; private final WifiInjector mWifiInjector; private final FrameworkFacade mFrameworkFacade; + private final WifiKeyStore mWifiKeyStore; /** * Per app meta data to store network suggestions, status, etc for each app providing network @@ -166,6 +167,10 @@ public class WifiNetworkSuggestionsManager { @NonNull PerAppInfo perAppInfo) { this.wns = wns; this.perAppInfo = perAppInfo; + this.wns.wifiConfiguration.fromWifiNetworkSuggestion = true; + this.wns.wifiConfiguration.ephemeral = true; + this.wns.wifiConfiguration.creatorName = perAppInfo.packageName; + this.wns.wifiConfiguration.creatorUid = wns.suggestorUid; } @Override @@ -384,7 +389,8 @@ public class WifiNetworkSuggestionsManager { WifiPermissionsUtil wifiPermissionsUtil, WifiConfigManager wifiConfigManager, WifiConfigStore wifiConfigStore, - WifiMetrics wifiMetrics) { + WifiMetrics wifiMetrics, + WifiKeyStore keyStore) { mContext = context; mResources = context.getResources(); mHandler = handler; @@ -397,6 +403,7 @@ public class WifiNetworkSuggestionsManager { mWifiPermissionsUtil = wifiPermissionsUtil; mWifiConfigManager = wifiConfigManager; mWifiMetrics = wifiMetrics; + mWifiKeyStore = keyStore; // register the data store for serializing/deserializing data. wifiConfigStore.registerStoreData( @@ -595,6 +602,19 @@ public class WifiNetworkSuggestionsManager { // Start tracking app-op changes from the app if they have active suggestions. startTrackingAppOpsChange(packageName, uid); } + Iterator<ExtendedWifiNetworkSuggestion> iterator = extNetworkSuggestions.iterator(); + // Install enterprise network suggestion catificate. + while (iterator.hasNext()) { + WifiConfiguration config = iterator.next().wns.wifiConfiguration; + if (!config.isEnterprise()) { + continue; + } + if (!mWifiKeyStore.updateNetworkKeys(config, null)) { + Log.e(TAG, "Enterprise network install failure for SSID: " + + config.SSID); + iterator.remove(); + } + } perAppInfo.extNetworkSuggestions.addAll(extNetworkSuggestions); // Update the max size for this app. perAppInfo.maxSize = Math.max(perAppInfo.extNetworkSuggestions.size(), perAppInfo.maxSize); @@ -619,11 +639,15 @@ public class WifiNetworkSuggestionsManager { @NonNull Collection<ExtendedWifiNetworkSuggestion> extNetworkSuggestions, @NonNull String packageName, @NonNull PerAppInfo perAppInfo) { + // Get internal suggestions + Set<ExtendedWifiNetworkSuggestion> removingSuggestions = + new HashSet<>(perAppInfo.extNetworkSuggestions); if (!extNetworkSuggestions.isEmpty()) { + // Keep the internal suggestions need to remove. + removingSuggestions.retainAll(extNetworkSuggestions); perAppInfo.extNetworkSuggestions.removeAll(extNetworkSuggestions); } else { // empty list is used to clear everything for the app. Store a copy for use below. - extNetworkSuggestions = new HashSet<>(perAppInfo.extNetworkSuggestions); perAppInfo.extNetworkSuggestions.clear(); } if (perAppInfo.extNetworkSuggestions.isEmpty()) { @@ -634,8 +658,16 @@ public class WifiNetworkSuggestionsManager { // Stop tracking app-op changes from the app if they don't have active suggestions. stopTrackingAppOpsChange(packageName); } + // Clean the enterprise certifiacte. + for (ExtendedWifiNetworkSuggestion ewns : removingSuggestions) { + WifiConfiguration config = ewns.wns.wifiConfiguration; + if (!config.isEnterprise()) { + continue; + } + mWifiKeyStore.removeKeys(config.enterpriseConfig); + } // Clear the scan cache. - removeFromScanResultMatchInfoMap(extNetworkSuggestions); + removeFromScanResultMatchInfoMap(removingSuggestions); } /** diff --git a/service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java b/service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java index d95ab3831..69f98b0ef 100644 --- a/service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java +++ b/service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java @@ -75,10 +75,11 @@ public class ANQPMatcher { * * @param element The Roaming Consortium ANQP element * @param providerOIs The roaming consortium OIs of the provider + * @param matchAll Indicates if a match with all OIs must be done * @return true if a match is found */ public static boolean matchRoamingConsortium(RoamingConsortiumElement element, - long[] providerOIs) { + long[] providerOIs, boolean matchAll) { if (element == null) { return false; } @@ -88,10 +89,14 @@ public class ANQPMatcher { List<Long> rcOIs = element.getOIs(); for (long oi : providerOIs) { if (rcOIs.contains(oi)) { - return true; + if (!matchAll) { + return true; + } + } else if (matchAll) { + return false; } } - return false; + return matchAll; } /** @@ -100,27 +105,19 @@ public class ANQPMatcher { * * @param element The NAI Realm ANQP element * @param realm The realm of the provider's credential - * @param eapMethodID The EAP Method ID of the provider's credential - * @param authParam The authentication parameter of the provider's credential * @return an integer indicating the match status */ - public static int matchNAIRealm(NAIRealmElement element, String realm, int eapMethodID, - AuthParam authParam) { + public static boolean matchNAIRealm(NAIRealmElement element, String realm) { if (element == null || element.getRealmDataList().isEmpty()) { - return AuthMatch.INDETERMINATE; + return false; } - int bestMatch = AuthMatch.NONE; for (NAIRealmData realmData : element.getRealmDataList()) { - int match = matchNAIRealmData(realmData, realm, eapMethodID, authParam); - if (match > bestMatch) { - bestMatch = match; - if (bestMatch == AuthMatch.EXACT) { - break; - } + if (matchNAIRealmData(realmData, realm)) { + return true; } } - return bestMatch; + return false; } /** @@ -172,42 +169,16 @@ public class ANQPMatcher { * * @param realmData The NAI Realm data * @param realm The realm of the provider's credential - * @param eapMethodID The EAP Method ID of the provider's credential - * @param authParam The authentication parameter of the provider's credential - * @return an integer indicating the match status + * @return true if a match is found */ - private static int matchNAIRealmData(NAIRealmData realmData, String realm, int eapMethodID, - AuthParam authParam) { + private static boolean matchNAIRealmData(NAIRealmData realmData, String realm) { // Check for realm domain name match. - int realmMatch = AuthMatch.NONE; for (String realmStr : realmData.getRealms()) { if (DomainMatcher.arg2SubdomainOfArg1(realm, realmStr)) { - realmMatch = AuthMatch.REALM; - break; - } - } - - if (realmData.getEAPMethods().isEmpty()) { - return realmMatch; - } - - // Check for EAP method match. - int eapMethodMatch = AuthMatch.NONE; - for (EAPMethod eapMethod : realmData.getEAPMethods()) { - eapMethodMatch = matchEAPMethod(eapMethod, eapMethodID, authParam); - if (eapMethodMatch != AuthMatch.NONE) { - break; + return true; } } - - if (eapMethodMatch == AuthMatch.NONE) { - return AuthMatch.NONE; - } - - if (realmMatch == AuthMatch.NONE) { - return eapMethodMatch; - } - return realmMatch | eapMethodMatch; + return false; } private static int getEapMethodForNAIRealmWithCarrier(String realm, diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java index c46873761..172d1a13d 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java @@ -217,6 +217,7 @@ public class PasspointManager { public void setProviders(List<PasspointProvider> providers) { mProviders.clear(); for (PasspointProvider provider : providers) { + provider.enableVerboseLogging(mVerboseLoggingEnabled ? 1 : 0); mProviders.put(provider.getConfig().getHomeSp().getFqdn(), provider); if (provider.getPackageName() != null) { startTrackingAppOpsChange(provider.getPackageName(), @@ -377,6 +378,9 @@ public class PasspointManager { public void enableVerboseLogging(int verbose) { mVerboseLoggingEnabled = (verbose > 0) ? true : false; mPasspointProvisioner.enableVerboseLogging(verbose); + for (PasspointProvider provider : mProviders.values()) { + provider.enableVerboseLogging(verbose); + } } /** @@ -433,6 +437,7 @@ public class PasspointManager { mProviders.get(config.getHomeSp().getFqdn()).uninstallCertsAndKeys(); mProviders.remove(config.getHomeSp().getFqdn()); } + newProvider.enableVerboseLogging(mVerboseLoggingEnabled ? 1 : 0); mProviders.put(config.getHomeSp().getFqdn(), newProvider); mWifiConfigManager.saveToStore(true /* forceWrite */); if (newProvider.getPackageName() != null) { @@ -1165,6 +1170,7 @@ public class PasspointManager { Arrays.asList(enterpriseConfig.getCaCertificateAlias()), enterpriseConfig.getClientCertificateAlias(), enterpriseConfig.getClientCertificateAlias(), null, false, false); + provider.enableVerboseLogging(mVerboseLoggingEnabled ? 1 : 0); mProviders.put(passpointConfig.getHomeSp().getFqdn(), provider); return true; } diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java index ca9814aa6..8db71d3e6 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java @@ -95,6 +95,7 @@ public class PasspointProvider { private boolean mHasEverConnected; private boolean mIsShared; + private boolean mVerboseLoggingEnabled; /** * This is a flag to indicate if the Provider is created temporarily. @@ -327,39 +328,53 @@ public class PasspointProvider { * Return the matching status with the given AP, based on the ANQP elements from the AP. * * @param anqpElements ANQP elements from the AP - * @param roamingConsortium Roaming Consortium information element from the AP + * @param roamingConsortiumFromAp Roaming Consortium information element from the AP * @return {@link PasspointMatch} */ public PasspointMatch match(Map<ANQPElementType, ANQPElement> anqpElements, - RoamingConsortium roamingConsortium) { - PasspointMatch providerMatch = matchProviderExceptFor3GPP(anqpElements, roamingConsortium); + RoamingConsortium roamingConsortiumFromAp) { + // Match FQDN for Home provider or RCOI(s) for Roaming provider + // For SIM credential, the FQDN is in the format of wlan.mnc*.mcc*.3gppnetwork.org + PasspointMatch providerMatch = matchFqdnAndRcoi(anqpElements, roamingConsortiumFromAp); // 3GPP Network matching. if (providerMatch == PasspointMatch.None && ANQPMatcher.matchThreeGPPNetwork( (ThreeGPPNetworkElement) anqpElements.get(ANQPElementType.ANQP3GPPNetwork), mImsiParameter, mMatchingSIMImsiList)) { + if (mVerboseLoggingEnabled) { + Log.d(TAG, "Final RoamingProvider match with " + + anqpElements.get(ANQPElementType.ANQP3GPPNetwork)); + } return PasspointMatch.RoamingProvider; } - // Perform authentication match against the NAI Realm. - int authMatch = ANQPMatcher.matchNAIRealm( + // Perform NAI Realm matching + boolean realmMatch = ANQPMatcher.matchNAIRealm( (NAIRealmElement) anqpElements.get(ANQPElementType.ANQPNAIRealm), - mConfig.getCredential().getRealm(), mEAPMethodID, mAuthParam); - - // In case of Auth mismatch, demote provider match. - if (authMatch == AuthMatch.NONE) { - return PasspointMatch.None; - } + mConfig.getCredential().getRealm()); // In case of no realm match, return provider match as is. - if ((authMatch & AuthMatch.REALM) == 0) { + if (!realmMatch) { + if (mVerboseLoggingEnabled) { + Log.d(TAG, "No NAI realm match, final match: " + providerMatch); + } return providerMatch; } - // Promote the provider match to roaming provider if provider match is not found, but NAI + if (mVerboseLoggingEnabled) { + Log.d(TAG, "NAI realm match with " + mConfig.getCredential().getRealm()); + } + + // Promote the provider match to RoamingProvider if provider match is not found, but NAI // realm is matched. - return providerMatch == PasspointMatch.None ? PasspointMatch.RoamingProvider - : providerMatch; + if (providerMatch == PasspointMatch.None) { + providerMatch = PasspointMatch.RoamingProvider; + } + + if (mVerboseLoggingEnabled) { + Log.d(TAG, "Final match: " + providerMatch); + } + return providerMatch; } /** @@ -570,42 +585,129 @@ public class PasspointProvider { } /** + * Match given OIs to the Roaming Consortium OIs + * + * @param providerOis Provider OIs to match against + * @param roamingConsortiumElement RCOIs in the ANQP element + * @param roamingConsortiumFromAp RCOIs in the AP scan results + * @param matchAll Indicates if all providerOis must match the RCOIs elements + * @return {@code true} if there is a match, {@code false} otherwise. + */ + private boolean matchOis(long[] providerOis, + RoamingConsortiumElement roamingConsortiumElement, + RoamingConsortium roamingConsortiumFromAp, + boolean matchAll) { + + + // ANQP Roaming Consortium OI matching. + if (ANQPMatcher.matchRoamingConsortium(roamingConsortiumElement, providerOis, matchAll)) { + if (mVerboseLoggingEnabled) { + Log.e(TAG, "ANQP RCOI match " + roamingConsortiumElement); + } + return true; + } + + // AP Roaming Consortium OI matching. + long[] apRoamingConsortiums = roamingConsortiumFromAp.getRoamingConsortiums(); + if (apRoamingConsortiums == null || providerOis == null) { + return false; + } + // Roaming Consortium OI information element matching. + for (long apOi: apRoamingConsortiums) { + boolean matched = false; + for (long providerOi: providerOis) { + if (apOi == providerOi) { + if (mVerboseLoggingEnabled) { + Log.e(TAG, "AP RCOI match: " + apOi); + } + if (!matchAll) { + return true; + } else { + matched = true; + break; + } + } + } + if (matchAll && !matched) { + return false; + } + } + return matchAll; + } + + /** * Perform a provider match based on the given ANQP elements except for matching 3GPP Network. * * @param anqpElements List of ANQP elements - * @param roamingConsortium Roaming Consortium information element from the AP + * @param roamingConsortiumFromAp Roaming Consortium information element from the AP * @return {@link PasspointMatch} */ - private PasspointMatch matchProviderExceptFor3GPP( + private PasspointMatch matchFqdnAndRcoi( Map<ANQPElementType, ANQPElement> anqpElements, - RoamingConsortium roamingConsortium) { + RoamingConsortium roamingConsortiumFromAp) { // Domain name matching. if (ANQPMatcher.matchDomainName( (DomainNameElement) anqpElements.get(ANQPElementType.ANQPDomName), mConfig.getHomeSp().getFqdn(), mImsiParameter, mMatchingSIMImsiList)) { + if (mVerboseLoggingEnabled) { + Log.d(TAG, "Domain name " + mConfig.getHomeSp().getFqdn() + + " match: HomeProvider"); + } return PasspointMatch.HomeProvider; } - // ANQP Roaming Consortium OI matching. - long[] providerOIs = mConfig.getHomeSp().getRoamingConsortiumOis(); - if (ANQPMatcher.matchRoamingConsortium( - (RoamingConsortiumElement) anqpElements.get(ANQPElementType.ANQPRoamingConsortium), - providerOIs)) { - return PasspointMatch.RoamingProvider; + // Other Home Partners matching. + if (mConfig.getHomeSp().getOtherHomePartners() != null) { + for (String otherHomePartner : mConfig.getHomeSp().getOtherHomePartners()) { + if (ANQPMatcher.matchDomainName( + (DomainNameElement) anqpElements.get(ANQPElementType.ANQPDomName), + otherHomePartner, null, null)) { + if (mVerboseLoggingEnabled) { + Log.d(TAG, "Other Home Partner " + otherHomePartner + + " match: HomeProvider"); + } + return PasspointMatch.HomeProvider; + } + } } - long[] roamingConsortiums = roamingConsortium.getRoamingConsortiums(); - // Roaming Consortium OI information element matching. - if (roamingConsortiums != null && providerOIs != null) { - for (long sta_oi: roamingConsortiums) { - for (long ap_oi: providerOIs) { - if (sta_oi == ap_oi) { - return PasspointMatch.RoamingProvider; - } + // HomeOI matching + if (mConfig.getHomeSp().getMatchAllOis() != null) { + // Ensure that every HomeOI whose corresponding HomeOIRequired value is true shall match + // an OI in the Roaming Consortium advertised by the hotspot operator. + if (matchOis(mConfig.getHomeSp().getMatchAllOis(), (RoamingConsortiumElement) + anqpElements.get(ANQPElementType.ANQPRoamingConsortium), + roamingConsortiumFromAp, true)) { + if (mVerboseLoggingEnabled) { + Log.e(TAG, "All HomeOI RCOI match: HomeProvider"); + } + return PasspointMatch.HomeProvider; + } + } else if (mConfig.getHomeSp().getMatchAnyOis() != null) { + // Ensure that any HomeOI whose corresponding HomeOIRequired value is false shall match + // an OI in the Roaming Consortium advertised by the hotspot operator. + if (matchOis(mConfig.getHomeSp().getMatchAnyOis(), (RoamingConsortiumElement) + anqpElements.get(ANQPElementType.ANQPRoamingConsortium), + roamingConsortiumFromAp, false)) { + if (mVerboseLoggingEnabled) { + Log.e(TAG, "Any HomeOI RCOI match: HomeProvider"); } + return PasspointMatch.HomeProvider; } } + // Roaming Consortium OI matching. + if (matchOis(mConfig.getHomeSp().getRoamingConsortiumOis(), (RoamingConsortiumElement) + anqpElements.get(ANQPElementType.ANQPRoamingConsortium), + roamingConsortiumFromAp, false)) { + if (mVerboseLoggingEnabled) { + Log.e(TAG, "ANQP RCOI match: RoamingProvider"); + } + return PasspointMatch.RoamingProvider; + } + if (mVerboseLoggingEnabled) { + Log.e(TAG, "No domain name or RCOI match"); + } return PasspointMatch.None; } @@ -768,4 +870,12 @@ public class PasspointProvider { simCredential.setEapType(eapType); return simCredential; } + + /** + * Enable verbose logging + * @param verbose more than 0 enables verbose logging + */ + public void enableVerboseLogging(int verbose) { + mVerboseLoggingEnabled = (verbose > 0) ? true : false; + } } |