diff options
4 files changed, 275 insertions, 26 deletions
diff --git a/service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java b/service/java/com/android/server/wifi/hotspot2/ANQPMatcher.java index a920c5ec1..6bb834d4b 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; } /** diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java index 205c71f78..690671657 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java @@ -691,6 +691,57 @@ 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 for FQDN and RCOI * * @param anqpElements List of ANQP elements @@ -726,31 +777,39 @@ public class PasspointProvider { } } - // ANQP Roaming Consortium OI matching. - long[] providerOIs = mConfig.getHomeSp().getRoamingConsortiumOis(); - if (ANQPMatcher.matchRoamingConsortium( - (RoamingConsortiumElement) anqpElements.get(ANQPElementType.ANQPRoamingConsortium), - providerOIs)) { - if (mVerboseLoggingEnabled) { - Log.e(TAG, "ANQP RCOI match: 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; } - return PasspointMatch.RoamingProvider; } - // AP Roaming Consortium OI matching. - long[] roamingConsortiums = roamingConsortiumFromAp.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) { - if (mVerboseLoggingEnabled) { - Log.e(TAG, "AP RCOI match: RoamingProvider"); - } - return PasspointMatch.RoamingProvider; - } - } + // 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"); diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java index a3a2bd19a..b7bb8afc1 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java @@ -97,7 +97,7 @@ public class ANQPMatcherTest extends WifiBaseTest { */ @Test public void matchRoamingConsortiumWithNullElement() throws Exception { - assertFalse(ANQPMatcher.matchRoamingConsortium(null, new long[0])); + assertFalse(ANQPMatcher.matchRoamingConsortium(null, new long[0], false)); } /** @@ -111,7 +111,7 @@ public class ANQPMatcherTest extends WifiBaseTest { long oi = 0x1234L; RoamingConsortiumElement element = new RoamingConsortiumElement(Arrays.asList(new Long[] {oi})); - assertTrue(ANQPMatcher.matchRoamingConsortium(element, new long[] {oi})); + assertTrue(ANQPMatcher.matchRoamingConsortium(element, new long[] {oi}, false)); } /** @@ -360,4 +360,64 @@ public class ANQPMatcherTest extends WifiBaseTest { DomainNameElement element = new DomainNameElement(Arrays.asList(domains)); assertFalse(ANQPMatcher.matchDomainName(element, null, imsiParam, simImsi)); } + + /** + * Verify that match is found when HomeOI contains some of the RCOIs advertised by an AP marked + * as not required. + * + * @throws Exception + */ + @Test + public void matchAnyHomeOi() throws Exception { + long[] providerOis = new long[] {0x1234L, 0x5678L, 0xabcdL}; + Long[] anqpOis = new Long[] {0x1234L, 0x5678L, 0xdeadL, 0xf0cdL}; + RoamingConsortiumElement element = + new RoamingConsortiumElement(Arrays.asList(anqpOis)); + assertTrue(ANQPMatcher.matchRoamingConsortium(element, providerOis, false)); + } + + /** + * Verify that no match is found when HomeOI does not contain any of the RCOIs advertised by an + * AP marked as not required. + * + * @throws Exception + */ + @Test + public void matchAnyHomeOiNegative() throws Exception { + long[] providerOis = new long[] {0x1234L, 0x5678L, 0xabcdL}; + Long[] anqpOis = new Long[] {0xabc2L, 0x1232L}; + RoamingConsortiumElement element = + new RoamingConsortiumElement(Arrays.asList(anqpOis)); + assertFalse(ANQPMatcher.matchRoamingConsortium(element, providerOis, false)); + } + + /** + * Verify that match is found when HomeOI contains all of the RCOIs advertised by an AP marked + * as required. + * + * @throws Exception + */ + @Test + public void matchAllHomeOi() throws Exception { + long[] providerOis = new long[] {0x1234L, 0x5678L, 0xabcdL}; + Long[] anqpOis = new Long[] {0x1234L, 0x5678L, 0xabcdL, 0xdeadL, 0xf0cdL}; + RoamingConsortiumElement element = + new RoamingConsortiumElement(Arrays.asList(anqpOis)); + assertTrue(ANQPMatcher.matchRoamingConsortium(element, providerOis, true)); + } + + /** + * Verify that match is not found when HomeOI does not contain all of the RCOIs advertised by an + * AP marked as required. + * + * @throws Exception + */ + @Test + public void matchAllHomeOiNegative() throws Exception { + long[] providerOis = new long[] {0x1234L, 0x5678L, 0xabcdL}; + Long[] anqpOis = new Long[] {0x1234L, 0x5678L, 0xdeadL, 0xf0cdL}; + RoamingConsortiumElement element = + new RoamingConsortiumElement(Arrays.asList(anqpOis)); + assertFalse(ANQPMatcher.matchRoamingConsortium(element, providerOis, true)); + } } diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java index 4ebc6bd23..0f8b1b0ca 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java @@ -1456,4 +1456,129 @@ public class PasspointProviderTest extends WifiBaseTest { assertEquals(PasspointMatch.HomeProvider, mProvider.match(anqpElementMap, mRoamingConsortium)); } + + /** + * Verify that matching Any HomeOI results in a Home Provider match + * + * @throws Exception + */ + @Test + public void matchAnyHomeOi() throws Exception { + // Setup test provider. + PasspointConfiguration config = generateTestPasspointConfiguration( + CredentialType.USER, false); + Long[] anqpOis = new Long[] {0x1234L, 0xdeadL, 0xf0cdL}; + + // Configuration was created with TEST_FQDN as the FQDN + HomeSp homeSp = config.getHomeSp(); + homeSp.setMatchAnyOis(TEST_RC_OIS); + homeSp.setRoamingConsortiumOis(null); + config.setHomeSp(homeSp); + mProvider = createProvider(config); + + // Setup Domain Name ANQP element to TEST_FQDN2 and TEST_FQDN3 + Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + createDomainNameElement(new String[] {TEST_FQDN2, TEST_FQDN3})); + // Setup RCOIs advertised by the AP + anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, + createRoamingConsortiumElement(anqpOis)); + + assertEquals(PasspointMatch.HomeProvider, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** + * Verify that non-matching Any HomeOI results in a None Provider match + * + * @throws Exception + */ + @Test + public void matchAnyHomeOiNegative() throws Exception { + // Setup test provider. + PasspointConfiguration config = generateTestPasspointConfiguration( + CredentialType.USER, false); + Long[] anqpOis = new Long[] {0x12a4L, 0xceadL, 0xf0cdL}; + + // Configuration was created with TEST_FQDN as the FQDN + HomeSp homeSp = config.getHomeSp(); + homeSp.setMatchAnyOis(TEST_RC_OIS); + homeSp.setRoamingConsortiumOis(null); + config.setHomeSp(homeSp); + mProvider = createProvider(config); + + // Setup Domain Name ANQP element to TEST_FQDN2 and TEST_FQDN3 + Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + createDomainNameElement(new String[] {TEST_FQDN2, TEST_FQDN3})); + // Setup RCOIs advertised by the AP + anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, + createRoamingConsortiumElement(anqpOis)); + + assertEquals(PasspointMatch.None, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** + * Verify that matching All HomeOI results in a Home Provider match + * + * @throws Exception + */ + @Test + public void matchAllHomeOi() throws Exception { + // Setup test provider. + PasspointConfiguration config = generateTestPasspointConfiguration( + CredentialType.USER, false); + Long[] anqpOis = new Long[] {0x1234L, 0x2345L, 0xabcdL, 0xdeadL, 0xf0cdL}; + + // Configuration was created with TEST_FQDN as the FQDN + HomeSp homeSp = config.getHomeSp(); + homeSp.setMatchAllOis(TEST_RC_OIS); + homeSp.setRoamingConsortiumOis(null); + config.setHomeSp(homeSp); + mProvider = createProvider(config); + + // Setup Domain Name ANQP element to TEST_FQDN2 and TEST_FQDN3 + Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + createDomainNameElement(new String[] {TEST_FQDN2, TEST_FQDN3})); + // Setup RCOIs advertised by the AP + anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, + createRoamingConsortiumElement(anqpOis)); + + assertEquals(PasspointMatch.HomeProvider, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** + * Verify that non-matching All HomeOI results in a None Provider match + * + * @throws Exception + */ + @Test + public void matchAllHomeOiNegative() throws Exception { + // Setup test provider. + PasspointConfiguration config = generateTestPasspointConfiguration( + CredentialType.USER, false); + // 0x1234 matches, but 0x2345 does not + Long[] anqpOis = new Long[] {0x1234L, 0x5678L, 0xdeadL, 0xf0cdL}; + + // Configuration was created with TEST_FQDN as the FQDN + HomeSp homeSp = config.getHomeSp(); + homeSp.setMatchAllOis(TEST_RC_OIS); + homeSp.setRoamingConsortiumOis(null); + config.setHomeSp(homeSp); + mProvider = createProvider(config); + + // Setup Domain Name ANQP element to TEST_FQDN2 and TEST_FQDN3 + Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + createDomainNameElement(new String[] {TEST_FQDN2, TEST_FQDN3})); + // Setup RCOIs advertised by the AP + anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, + createRoamingConsortiumElement(anqpOis)); + + assertEquals(PasspointMatch.None, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } } |