Loading wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +262 −13 Original line number Original line Diff line number Diff line Loading @@ -19,9 +19,18 @@ package android.net.wifi.hotspot2; import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.HomeSP; import android.net.wifi.hotspot2.pps.HomeSP; import android.net.wifi.hotspot2.pps.Policy; import android.net.wifi.hotspot2.pps.Policy; import android.net.wifi.hotspot2.pps.UpdateParameter; import android.os.Parcelable; import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; import android.os.Parcel; import android.os.Parcel; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Map; /** /** * Class representing Passpoint configuration. This contains configurations specified in * Class representing Passpoint configuration. This contains configurations specified in * PerProviderSubscription (PPS) Management Object (MO) tree. * PerProviderSubscription (PPS) Management Object (MO) tree. Loading @@ -32,10 +41,106 @@ import android.os.Parcel; * @hide * @hide */ */ public final class PasspointConfiguration implements Parcelable { public final class PasspointConfiguration implements Parcelable { private static final String TAG = "PasspointConfiguration"; /** * Number of bytes for certificate SHA-256 fingerprint byte array. */ private static final int CERTIFICATE_SHA256_BYTES = 32; /** * Maximum bytes for URL string. */ private static final int MAX_URL_BYTES = 1023; /** * Integer value used for indicating null value in the Parcel. */ private static final int NULL_VALUE = -1; public HomeSP homeSp = null; public HomeSP homeSp = null; public Credential credential = null; public Credential credential = null; public Policy policy = null; public Policy policy = null; /** * Meta data for performing subscription update. */ public UpdateParameter subscriptionUpdate = null; /** * List of HTTPS URL for retrieving trust root certificate and the corresponding SHA-256 * fingerprint of the certificate. The certificates are used for verifying AAA server's * identity during EAP authentication. */ public Map<String, byte[]> trustRootCertList = null; /** * Set by the subscription server, updated every time the configuration is updated by * the subscription server. * * Use Integer.MIN_VALUE to indicate unset value. */ public int updateIdentifier = Integer.MIN_VALUE; /** * The priority of the credential. * * Use Integer.MIN_VALUE to indicate unset value. */ public int credentialPriority = Integer.MIN_VALUE; /** * The time this subscription is created. It is in the format of number * of milliseconds since January 1, 1970, 00:00:00 GMT. * * Use Long.MIN_VALUE to indicate unset value. */ public long subscriptionCreationTimeInMs = Long.MIN_VALUE; /** * The time this subscription will expire. It is in the format of number * of milliseconds since January 1, 1970, 00:00:00 GMT. * * Use Long.MIN_VALUE to indicate unset value. */ public long subscriptionExpirationTimeInMs = Long.MIN_VALUE; /** * The type of the subscription. This is defined by the provider and the value is provider * specific. */ public String subscriptionType = null; /** * The time period for usage statistics accumulation. A value of zero means that usage * statistics are not accumulated on a periodic basis (e.g., a one-time limit for * “pay as you go” - PAYG service). A non-zero value specifies the usage interval in minutes. */ public long usageLimitUsageTimePeriodInMinutes = Long.MIN_VALUE; /** * The time at which usage statistic accumulation begins. It is in the format of number * of milliseconds since January 1, 1970, 00:00:00 GMT. * * Use Long.MIN_VALUE to indicate unset value. */ public long usageLimitStartTimeInMs = Long.MIN_VALUE; /** * The cumulative data limit in megabytes for the {@link #usageLimitUsageTimePeriodInMinutes}. * A value of zero indicate unlimited data usage. * * Use Long.MIN_VALUE to indicate unset value. */ public long usageLimitDataLimit = Long.MIN_VALUE; /** * The cumulative time limit in minutes for the {@link #usageLimitUsageTimePeriodInMinutes}. * A value of zero indicate unlimited time usage. */ public long usageLimitTimeLimitInMinutes = Long.MIN_VALUE; /** /** * Constructor for creating PasspointConfiguration with default values. * Constructor for creating PasspointConfiguration with default values. */ */ Loading @@ -47,7 +152,10 @@ public final class PasspointConfiguration implements Parcelable { * @param source The source to copy from * @param source The source to copy from */ */ public PasspointConfiguration(PasspointConfiguration source) { public PasspointConfiguration(PasspointConfiguration source) { if (source != null) { if (source == null) { return; } if (source.homeSp != null) { if (source.homeSp != null) { homeSp = new HomeSP(source.homeSp); homeSp = new HomeSP(source.homeSp); } } Loading @@ -57,7 +165,21 @@ public final class PasspointConfiguration implements Parcelable { if (source.policy != null) { if (source.policy != null) { policy = new Policy(source.policy); policy = new Policy(source.policy); } } if (source.trustRootCertList != null) { trustRootCertList = Collections.unmodifiableMap(source.trustRootCertList); } } if (source.subscriptionUpdate != null) { subscriptionUpdate = new UpdateParameter(source.subscriptionUpdate); } updateIdentifier = source.updateIdentifier; credentialPriority = source.credentialPriority; subscriptionCreationTimeInMs = source.subscriptionCreationTimeInMs; subscriptionExpirationTimeInMs = source.subscriptionExpirationTimeInMs; subscriptionType = source.subscriptionType; usageLimitDataLimit = source.usageLimitDataLimit; usageLimitStartTimeInMs = source.usageLimitStartTimeInMs; usageLimitTimeLimitInMinutes = source.usageLimitTimeLimitInMinutes; usageLimitUsageTimePeriodInMinutes = source.usageLimitUsageTimePeriodInMinutes; } } @Override @Override Loading @@ -70,6 +192,17 @@ public final class PasspointConfiguration implements Parcelable { dest.writeParcelable(homeSp, flags); dest.writeParcelable(homeSp, flags); dest.writeParcelable(credential, flags); dest.writeParcelable(credential, flags); dest.writeParcelable(policy, flags); dest.writeParcelable(policy, flags); dest.writeParcelable(subscriptionUpdate, flags); writeTrustRootCerts(dest, trustRootCertList); dest.writeInt(updateIdentifier); dest.writeInt(credentialPriority); dest.writeLong(subscriptionCreationTimeInMs); dest.writeLong(subscriptionExpirationTimeInMs); dest.writeString(subscriptionType); dest.writeLong(usageLimitUsageTimePeriodInMinutes); dest.writeLong(usageLimitStartTimeInMs); dest.writeLong(usageLimitDataLimit); dest.writeLong(usageLimitTimeLimitInMinutes); } } @Override @Override Loading @@ -82,9 +215,21 @@ public final class PasspointConfiguration implements Parcelable { } } PasspointConfiguration that = (PasspointConfiguration) thatObject; PasspointConfiguration that = (PasspointConfiguration) thatObject; return (homeSp == null ? that.homeSp == null : homeSp.equals(that.homeSp)) return (homeSp == null ? that.homeSp == null : homeSp.equals(that.homeSp)) && (credential == null ? that.credential == null : && (credential == null ? that.credential == null credential.equals(that.credential)) : credential.equals(that.credential)) && (policy == null) ? that.policy == null : policy.equals(that.policy); && (policy == null) ? that.policy == null : policy.equals(that.policy) && (subscriptionUpdate == null) ? that.subscriptionUpdate == null : subscriptionUpdate.equals(that.subscriptionUpdate) && isTrustRootCertListEquals(trustRootCertList, that.trustRootCertList) && updateIdentifier == that.updateIdentifier && credentialPriority == that.credentialPriority && subscriptionCreationTimeInMs == that.subscriptionCreationTimeInMs && subscriptionExpirationTimeInMs == that.subscriptionExpirationTimeInMs && TextUtils.equals(subscriptionType, that.subscriptionType) && usageLimitUsageTimePeriodInMinutes == that.usageLimitUsageTimePeriodInMinutes && usageLimitStartTimeInMs == that.usageLimitStartTimeInMs && usageLimitDataLimit == that.usageLimitDataLimit && usageLimitTimeLimitInMinutes == that .usageLimitTimeLimitInMinutes; } } /** /** Loading @@ -102,6 +247,34 @@ public final class PasspointConfiguration implements Parcelable { if (policy != null && !policy.validate()) { if (policy != null && !policy.validate()) { return false; return false; } } if (subscriptionUpdate != null && !subscriptionUpdate.validate()) { return false; } if (trustRootCertList != null) { for (Map.Entry<String, byte[]> entry : trustRootCertList.entrySet()) { String url = entry.getKey(); byte[] certFingerprint = entry.getValue(); if (TextUtils.isEmpty(url)) { Log.d(TAG, "Empty URL"); return false; } if (url.getBytes(StandardCharsets.UTF_8).length > MAX_URL_BYTES) { Log.d(TAG, "URL bytes exceeded the max: " + url.getBytes(StandardCharsets.UTF_8).length); return false; } if (certFingerprint == null) { Log.d(TAG, "Fingerprint not specified"); return false; } if (certFingerprint.length != CERTIFICATE_SHA256_BYTES) { Log.d(TAG, "Incorrect size of trust root certificate SHA-256 fingerprint: " + certFingerprint.length); return false; } } } return true; return true; } } Loading @@ -113,11 +286,87 @@ public final class PasspointConfiguration implements Parcelable { config.homeSp = in.readParcelable(null); config.homeSp = in.readParcelable(null); config.credential = in.readParcelable(null); config.credential = in.readParcelable(null); config.policy = in.readParcelable(null); config.policy = in.readParcelable(null); config.subscriptionUpdate = in.readParcelable(null); config.trustRootCertList = readTrustRootCerts(in); config.updateIdentifier = in.readInt(); config.credentialPriority = in.readInt(); config.subscriptionCreationTimeInMs = in.readLong(); config.subscriptionExpirationTimeInMs = in.readLong(); config.subscriptionType = in.readString(); config.usageLimitUsageTimePeriodInMinutes = in.readLong(); config.usageLimitStartTimeInMs = in.readLong(); config.usageLimitDataLimit = in.readLong(); config.usageLimitTimeLimitInMinutes = in.readLong(); return config; return config; } } @Override @Override public PasspointConfiguration[] newArray(int size) { public PasspointConfiguration[] newArray(int size) { return new PasspointConfiguration[size]; return new PasspointConfiguration[size]; } } /** * Helper function for reading trust root certificate info list from a Parcel. * * @param in The Parcel to read from * @return The list of trust root certificate URL with the corresponding certificate * fingerprint */ private Map<String, byte[]> readTrustRootCerts(Parcel in) { int size = in.readInt(); if (size == NULL_VALUE) { return null; } Map<String, byte[]> trustRootCerts = new HashMap<>(size); for (int i = 0; i < size; i++) { String key = in.readString(); byte[] value = in.createByteArray(); trustRootCerts.put(key, value); } return trustRootCerts; } }; }; /** * Helper function for writing trust root certificate information list. * * @param dest The Parcel to write to * @param trustRootCerts The list of trust root certificate URL with the corresponding * certificate fingerprint */ private static void writeTrustRootCerts(Parcel dest, Map<String, byte[]> trustRootCerts) { if (trustRootCerts == null) { dest.writeInt(NULL_VALUE); return; } dest.writeInt(trustRootCerts.size()); for (Map.Entry<String, byte[]> entry : trustRootCerts.entrySet()) { dest.writeString(entry.getKey()); dest.writeByteArray(entry.getValue()); } } /** * Helper function for comparing two trust root certificate list. Cannot use Map#equals * method since the value type (byte[]) doesn't override equals method. * * @param list1 The first trust root certificate list * @param list2 The second trust root certificate list * @return true if the two list are equal */ private static boolean isTrustRootCertListEquals(Map<String, byte[]> list1, Map<String, byte[]> list2) { if (list1 == null || list2 == null) { return list1 == list2; } if (list1.size() != list2.size()) { return false; } for (Map.Entry<String, byte[]> entry : list1.entrySet()) { if (!Arrays.equals(entry.getValue(), list2.get(entry.getKey()))) { return false; } } return true; } } } wifi/java/android/net/wifi/hotspot2/omadm/PPSMOParser.java +168 −40 File changed.Preview size limit exceeded, changes collapsed. Show changes wifi/tests/assets/pps/PerProviderSubscription.xml +97 −0 Original line number Original line Diff line number Diff line Loading @@ -7,6 +7,10 @@ <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName> <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName> </Type> </Type> </RTProperties> </RTProperties> <Node> <NodeName>UpdateIdentifier</NodeName> <Value>12</Value> </Node> <Node> <Node> <NodeName>i001</NodeName> <NodeName>i001</NodeName> <Node> <Node> Loading Loading @@ -297,6 +301,99 @@ <Value>23</Value> <Value>23</Value> </Node> </Node> </Node> </Node> <Node> <NodeName>CredentialPriority</NodeName> <Value>99</Value> </Node> <Node> <NodeName>AAAServerTrustRoot</NodeName> <Node> <NodeName>a001</NodeName> <Node> <NodeName>CertURL</NodeName> <Value>server1.trust.root.com</Value> </Node> <Node> <NodeName>CertSHA256Fingerprint</NodeName> <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value> </Node> </Node> </Node> <Node> <NodeName>SubscriptionUpdate</NodeName> <Node> <NodeName>UpdateInterval</NodeName> <Value>120</Value> </Node> <Node> <NodeName>UpdateMethod</NodeName> <Value>SSP-ClientInitiated</Value> </Node> <Node> <NodeName>Restriction</NodeName> <Value>RoamingPartner</Value> </Node> <Node> <NodeName>URI</NodeName> <Value>subscription.update.com</Value> </Node> <Node> <NodeName>UsernamePassword</NodeName> <Node> <NodeName>Username</NodeName> <Value>subscriptionUser</Value> </Node> <Node> <NodeName>Password</NodeName> <Value>subscriptionPass</Value> </Node> </Node> <Node> <NodeName>TrustRoot</NodeName> <Node> <NodeName>CertURL</NodeName> <Value>subscription.update.cert.com</Value> </Node> <Node> <NodeName>CertSHA256Fingerprint</NodeName> <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value> </Node> </Node> </Node> <Node> <NodeName>SubscriptionParameter</NodeName> <Node> <NodeName>CreationDate</NodeName> <Value>2016-02-01T10:00:00Z</Value> </Node> <Node> <NodeName>ExpirationDate</NodeName> <Value>2016-03-01T10:00:00Z</Value> </Node> <Node> <NodeName>TypeOfSubscription</NodeName> <Value>Gold</Value> </Node> <Node> <NodeName>UsageLimits</NodeName> <Node> <NodeName>DataLimit</NodeName> <Value>921890</Value> </Node> <Node> <NodeName>StartDate</NodeName> <Value>2016-12-01T10:00:00Z</Value> </Node> <Node> <NodeName>TimeLimit</NodeName> <Value>120</Value> </Node> <Node> <NodeName>UsageTimePeriod</NodeName> <Value>99910</Value> </Node> </Node> </Node> </Node> </Node> </Node> </Node> </MgmtTree> </MgmtTree> wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java +113 −1 Original line number Original line Diff line number Diff line Loading @@ -30,7 +30,9 @@ import android.util.Base64; import org.junit.Test; import org.junit.Test; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashMap; /** /** Loading @@ -38,6 +40,8 @@ import java.util.HashMap; */ */ @SmallTest @SmallTest public class PasspointConfigurationTest { public class PasspointConfigurationTest { private static final int MAX_URL_BYTES = 1023; private static final int CERTIFICATE_FINGERPRINT_BYTES = 32; /** /** * Utility function for creating a {@link android.net.wifi.hotspot2.pps.HomeSP}. * Utility function for creating a {@link android.net.wifi.hotspot2.pps.HomeSP}. Loading Loading @@ -111,11 +115,25 @@ public class PasspointConfigurationTest { policy.policyUpdate.base64EncodedPassword = policy.policyUpdate.base64EncodedPassword = Base64.encodeToString("password".getBytes(), Base64.DEFAULT); Base64.encodeToString("password".getBytes(), Base64.DEFAULT); policy.policyUpdate.trustRootCertUrl = "trust.cert.com"; policy.policyUpdate.trustRootCertUrl = "trust.cert.com"; policy.policyUpdate.trustRootCertSha256Fingerprint = new byte[32]; policy.policyUpdate.trustRootCertSha256Fingerprint = new byte[CERTIFICATE_FINGERPRINT_BYTES]; return policy; return policy; } } private static UpdateParameter createSubscriptionUpdate() { UpdateParameter subUpdate = new UpdateParameter(); subUpdate.updateIntervalInMinutes = 9021; subUpdate.updateMethod = UpdateParameter.UPDATE_METHOD_SSP; subUpdate.restriction = UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER; subUpdate.serverUri = "subscription.update.com"; subUpdate.username = "subUsername"; subUpdate.base64EncodedPassword = Base64.encodeToString("subPassword".getBytes(), Base64.DEFAULT); subUpdate.trustRootCertUrl = "subscription.trust.cert.com"; subUpdate.trustRootCertSha256Fingerprint = new byte[CERTIFICATE_FINGERPRINT_BYTES]; return subUpdate; } /** /** * Helper function for creating a {@link PasspointConfiguration} for testing. * Helper function for creating a {@link PasspointConfiguration} for testing. * * Loading @@ -126,6 +144,21 @@ public class PasspointConfigurationTest { config.homeSp = createHomeSp(); config.homeSp = createHomeSp(); config.credential = createCredential(); config.credential = createCredential(); config.policy = createPolicy(); config.policy = createPolicy(); config.subscriptionUpdate = createSubscriptionUpdate(); config.trustRootCertList = new HashMap<>(); config.trustRootCertList.put("trustRoot.cert1.com", new byte[CERTIFICATE_FINGERPRINT_BYTES]); config.trustRootCertList.put("trustRoot.cert2.com", new byte[CERTIFICATE_FINGERPRINT_BYTES]); config.updateIdentifier = 1; config.credentialPriority = 120; config.subscriptionCreationTimeInMs = 231200; config.subscriptionExpirationTimeInMs = 2134232; config.subscriptionType = "Gold"; config.usageLimitUsageTimePeriodInMinutes = 3600; config.usageLimitStartTimeInMs = 124214213; config.usageLimitDataLimit = 14121; config.usageLimitTimeLimitInMinutes = 78912; return config; return config; } } Loading Loading @@ -201,6 +234,31 @@ public class PasspointConfigurationTest { verifyParcel(config); verifyParcel(config); } } /** * Verify parcel read/write for a configuration that doesn't contain subscription update. * * @throws Exception */ @Test public void verifyParcelWithoutSubscriptionUpdate() throws Exception { PasspointConfiguration config = createConfig(); config.subscriptionUpdate = null; verifyParcel(config); } /** * Verify parcel read/write for a configuration that doesn't contain trust root certificate * list. * * @throws Exception */ @Test public void verifyParcelWithoutTrustRootCertList() throws Exception { PasspointConfiguration config = createConfig(); config.trustRootCertList = null; verifyParcel(config); } /** /** * Verify that a default/empty configuration is invalid. * Verify that a default/empty configuration is invalid. * * Loading Loading @@ -260,6 +318,60 @@ public class PasspointConfigurationTest { assertTrue(config.validate()); assertTrue(config.validate()); } } /** * Verify that a configuration without subscription update is valid, since subscription * update configurations are optional (applied for Hotspot 2.0 Release only). * * @throws Exception */ @Test public void validateConfigWithoutSubscriptionUpdate() throws Exception { PasspointConfiguration config = createConfig(); config.subscriptionUpdate = null; assertTrue(config.validate()); } /** * Verify that a configuration with a trust root certificate URL exceeding the max size * is invalid. * * @throws Exception */ @Test public void validateConfigWithInvalidTrustRootCertUrl() throws Exception { PasspointConfiguration config = createConfig(); byte[] rawUrlBytes = new byte[MAX_URL_BYTES + 1]; Arrays.fill(rawUrlBytes, (byte) 'a'); config.trustRootCertList.put(new String(rawUrlBytes, StandardCharsets.UTF_8), new byte[CERTIFICATE_FINGERPRINT_BYTES]); assertFalse(config.validate()); config.trustRootCertList = new HashMap<>(); config.trustRootCertList.put(null, new byte[CERTIFICATE_FINGERPRINT_BYTES]); assertFalse(config.validate()); } /** * Verify that a configuration with an invalid trust root certificate fingerprint is invalid. * * @throws Exception */ @Test public void validateConfigWithInvalidTrustRootCertFingerprint() throws Exception { PasspointConfiguration config = createConfig(); config.trustRootCertList = new HashMap<>(); config.trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES + 1]); assertFalse(config.validate()); config.trustRootCertList = new HashMap<>(); config.trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES - 1]); assertFalse(config.validate()); config.trustRootCertList = new HashMap<>(); config.trustRootCertList.put("test.cert.com", null); assertFalse(config.validate()); } /** /** * Verify that copy constructor works when pass in a null source. * Verify that copy constructor works when pass in a null source. * * Loading wifi/tests/src/android/net/wifi/hotspot2/omadm/PPSMOParserTest.java +32 −3 Original line number Original line Diff line number Diff line Loading @@ -85,7 +85,38 @@ public class PPSMOParserTest { * @return {@link PasspointConfiguration} * @return {@link PasspointConfiguration} */ */ private PasspointConfiguration generateConfigurationFromPPSMOTree() throws Exception { private PasspointConfiguration generateConfigurationFromPPSMOTree() throws Exception { DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); PasspointConfiguration config = new PasspointConfiguration(); PasspointConfiguration config = new PasspointConfiguration(); config.updateIdentifier = 12; config.credentialPriority = 99; // AAA Server trust root. config.trustRootCertList = new HashMap<>(); byte[] certFingerprint = new byte[32]; Arrays.fill(certFingerprint, (byte) 0x1f); config.trustRootCertList.put("server1.trust.root.com", certFingerprint); // Subscription update. config.subscriptionUpdate = new UpdateParameter(); config.subscriptionUpdate.updateIntervalInMinutes = 120; config.subscriptionUpdate.updateMethod = UpdateParameter.UPDATE_METHOD_SSP; config.subscriptionUpdate.restriction = UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER; config.subscriptionUpdate.serverUri = "subscription.update.com"; config.subscriptionUpdate.username = "subscriptionUser"; config.subscriptionUpdate.base64EncodedPassword = "subscriptionPass"; config.subscriptionUpdate.trustRootCertUrl = "subscription.update.cert.com"; config.subscriptionUpdate.trustRootCertSha256Fingerprint = new byte[32]; Arrays.fill(config.subscriptionUpdate.trustRootCertSha256Fingerprint, (byte) 0x1f); // Subscription parameters. config.subscriptionCreationTimeInMs = format.parse("2016-02-01T10:00:00Z").getTime(); config.subscriptionExpirationTimeInMs = format.parse("2016-03-01T10:00:00Z").getTime(); config.subscriptionType = "Gold"; config.usageLimitDataLimit = 921890; config.usageLimitStartTimeInMs = format.parse("2016-12-01T10:00:00Z").getTime(); config.usageLimitTimeLimitInMinutes = 120; config.usageLimitUsageTimePeriodInMinutes = 99910; // HomeSP configuration. // HomeSP configuration. config.homeSp = new HomeSP(); config.homeSp = new HomeSP(); Loading @@ -101,7 +132,6 @@ public class PPSMOParserTest { config.homeSp.otherHomePartners = new String[] {"other.fqdn.com"}; config.homeSp.otherHomePartners = new String[] {"other.fqdn.com"}; // Credential configuration. // Credential configuration. DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); config.credential = new Credential(); config.credential = new Credential(); config.credential.creationTimeInMs = format.parse("2016-01-01T10:00:00Z").getTime(); config.credential.creationTimeInMs = format.parse("2016-01-01T10:00:00Z").getTime(); config.credential.expirationTimeInMs = format.parse("2016-02-01T10:00:00Z").getTime(); config.credential.expirationTimeInMs = format.parse("2016-02-01T10:00:00Z").getTime(); Loading Loading @@ -161,8 +191,7 @@ public class PPSMOParserTest { } } /** /** * Parse and verify all supported fields under PPS MO tree (currently only fields under * Parse and verify all supported fields under PPS MO tree. * HomeSP and Credential subtree). * * * @throws Exception * @throws Exception */ */ Loading Loading
wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +262 −13 Original line number Original line Diff line number Diff line Loading @@ -19,9 +19,18 @@ package android.net.wifi.hotspot2; import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.HomeSP; import android.net.wifi.hotspot2.pps.HomeSP; import android.net.wifi.hotspot2.pps.Policy; import android.net.wifi.hotspot2.pps.Policy; import android.net.wifi.hotspot2.pps.UpdateParameter; import android.os.Parcelable; import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; import android.os.Parcel; import android.os.Parcel; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Map; /** /** * Class representing Passpoint configuration. This contains configurations specified in * Class representing Passpoint configuration. This contains configurations specified in * PerProviderSubscription (PPS) Management Object (MO) tree. * PerProviderSubscription (PPS) Management Object (MO) tree. Loading @@ -32,10 +41,106 @@ import android.os.Parcel; * @hide * @hide */ */ public final class PasspointConfiguration implements Parcelable { public final class PasspointConfiguration implements Parcelable { private static final String TAG = "PasspointConfiguration"; /** * Number of bytes for certificate SHA-256 fingerprint byte array. */ private static final int CERTIFICATE_SHA256_BYTES = 32; /** * Maximum bytes for URL string. */ private static final int MAX_URL_BYTES = 1023; /** * Integer value used for indicating null value in the Parcel. */ private static final int NULL_VALUE = -1; public HomeSP homeSp = null; public HomeSP homeSp = null; public Credential credential = null; public Credential credential = null; public Policy policy = null; public Policy policy = null; /** * Meta data for performing subscription update. */ public UpdateParameter subscriptionUpdate = null; /** * List of HTTPS URL for retrieving trust root certificate and the corresponding SHA-256 * fingerprint of the certificate. The certificates are used for verifying AAA server's * identity during EAP authentication. */ public Map<String, byte[]> trustRootCertList = null; /** * Set by the subscription server, updated every time the configuration is updated by * the subscription server. * * Use Integer.MIN_VALUE to indicate unset value. */ public int updateIdentifier = Integer.MIN_VALUE; /** * The priority of the credential. * * Use Integer.MIN_VALUE to indicate unset value. */ public int credentialPriority = Integer.MIN_VALUE; /** * The time this subscription is created. It is in the format of number * of milliseconds since January 1, 1970, 00:00:00 GMT. * * Use Long.MIN_VALUE to indicate unset value. */ public long subscriptionCreationTimeInMs = Long.MIN_VALUE; /** * The time this subscription will expire. It is in the format of number * of milliseconds since January 1, 1970, 00:00:00 GMT. * * Use Long.MIN_VALUE to indicate unset value. */ public long subscriptionExpirationTimeInMs = Long.MIN_VALUE; /** * The type of the subscription. This is defined by the provider and the value is provider * specific. */ public String subscriptionType = null; /** * The time period for usage statistics accumulation. A value of zero means that usage * statistics are not accumulated on a periodic basis (e.g., a one-time limit for * “pay as you go” - PAYG service). A non-zero value specifies the usage interval in minutes. */ public long usageLimitUsageTimePeriodInMinutes = Long.MIN_VALUE; /** * The time at which usage statistic accumulation begins. It is in the format of number * of milliseconds since January 1, 1970, 00:00:00 GMT. * * Use Long.MIN_VALUE to indicate unset value. */ public long usageLimitStartTimeInMs = Long.MIN_VALUE; /** * The cumulative data limit in megabytes for the {@link #usageLimitUsageTimePeriodInMinutes}. * A value of zero indicate unlimited data usage. * * Use Long.MIN_VALUE to indicate unset value. */ public long usageLimitDataLimit = Long.MIN_VALUE; /** * The cumulative time limit in minutes for the {@link #usageLimitUsageTimePeriodInMinutes}. * A value of zero indicate unlimited time usage. */ public long usageLimitTimeLimitInMinutes = Long.MIN_VALUE; /** /** * Constructor for creating PasspointConfiguration with default values. * Constructor for creating PasspointConfiguration with default values. */ */ Loading @@ -47,7 +152,10 @@ public final class PasspointConfiguration implements Parcelable { * @param source The source to copy from * @param source The source to copy from */ */ public PasspointConfiguration(PasspointConfiguration source) { public PasspointConfiguration(PasspointConfiguration source) { if (source != null) { if (source == null) { return; } if (source.homeSp != null) { if (source.homeSp != null) { homeSp = new HomeSP(source.homeSp); homeSp = new HomeSP(source.homeSp); } } Loading @@ -57,7 +165,21 @@ public final class PasspointConfiguration implements Parcelable { if (source.policy != null) { if (source.policy != null) { policy = new Policy(source.policy); policy = new Policy(source.policy); } } if (source.trustRootCertList != null) { trustRootCertList = Collections.unmodifiableMap(source.trustRootCertList); } } if (source.subscriptionUpdate != null) { subscriptionUpdate = new UpdateParameter(source.subscriptionUpdate); } updateIdentifier = source.updateIdentifier; credentialPriority = source.credentialPriority; subscriptionCreationTimeInMs = source.subscriptionCreationTimeInMs; subscriptionExpirationTimeInMs = source.subscriptionExpirationTimeInMs; subscriptionType = source.subscriptionType; usageLimitDataLimit = source.usageLimitDataLimit; usageLimitStartTimeInMs = source.usageLimitStartTimeInMs; usageLimitTimeLimitInMinutes = source.usageLimitTimeLimitInMinutes; usageLimitUsageTimePeriodInMinutes = source.usageLimitUsageTimePeriodInMinutes; } } @Override @Override Loading @@ -70,6 +192,17 @@ public final class PasspointConfiguration implements Parcelable { dest.writeParcelable(homeSp, flags); dest.writeParcelable(homeSp, flags); dest.writeParcelable(credential, flags); dest.writeParcelable(credential, flags); dest.writeParcelable(policy, flags); dest.writeParcelable(policy, flags); dest.writeParcelable(subscriptionUpdate, flags); writeTrustRootCerts(dest, trustRootCertList); dest.writeInt(updateIdentifier); dest.writeInt(credentialPriority); dest.writeLong(subscriptionCreationTimeInMs); dest.writeLong(subscriptionExpirationTimeInMs); dest.writeString(subscriptionType); dest.writeLong(usageLimitUsageTimePeriodInMinutes); dest.writeLong(usageLimitStartTimeInMs); dest.writeLong(usageLimitDataLimit); dest.writeLong(usageLimitTimeLimitInMinutes); } } @Override @Override Loading @@ -82,9 +215,21 @@ public final class PasspointConfiguration implements Parcelable { } } PasspointConfiguration that = (PasspointConfiguration) thatObject; PasspointConfiguration that = (PasspointConfiguration) thatObject; return (homeSp == null ? that.homeSp == null : homeSp.equals(that.homeSp)) return (homeSp == null ? that.homeSp == null : homeSp.equals(that.homeSp)) && (credential == null ? that.credential == null : && (credential == null ? that.credential == null credential.equals(that.credential)) : credential.equals(that.credential)) && (policy == null) ? that.policy == null : policy.equals(that.policy); && (policy == null) ? that.policy == null : policy.equals(that.policy) && (subscriptionUpdate == null) ? that.subscriptionUpdate == null : subscriptionUpdate.equals(that.subscriptionUpdate) && isTrustRootCertListEquals(trustRootCertList, that.trustRootCertList) && updateIdentifier == that.updateIdentifier && credentialPriority == that.credentialPriority && subscriptionCreationTimeInMs == that.subscriptionCreationTimeInMs && subscriptionExpirationTimeInMs == that.subscriptionExpirationTimeInMs && TextUtils.equals(subscriptionType, that.subscriptionType) && usageLimitUsageTimePeriodInMinutes == that.usageLimitUsageTimePeriodInMinutes && usageLimitStartTimeInMs == that.usageLimitStartTimeInMs && usageLimitDataLimit == that.usageLimitDataLimit && usageLimitTimeLimitInMinutes == that .usageLimitTimeLimitInMinutes; } } /** /** Loading @@ -102,6 +247,34 @@ public final class PasspointConfiguration implements Parcelable { if (policy != null && !policy.validate()) { if (policy != null && !policy.validate()) { return false; return false; } } if (subscriptionUpdate != null && !subscriptionUpdate.validate()) { return false; } if (trustRootCertList != null) { for (Map.Entry<String, byte[]> entry : trustRootCertList.entrySet()) { String url = entry.getKey(); byte[] certFingerprint = entry.getValue(); if (TextUtils.isEmpty(url)) { Log.d(TAG, "Empty URL"); return false; } if (url.getBytes(StandardCharsets.UTF_8).length > MAX_URL_BYTES) { Log.d(TAG, "URL bytes exceeded the max: " + url.getBytes(StandardCharsets.UTF_8).length); return false; } if (certFingerprint == null) { Log.d(TAG, "Fingerprint not specified"); return false; } if (certFingerprint.length != CERTIFICATE_SHA256_BYTES) { Log.d(TAG, "Incorrect size of trust root certificate SHA-256 fingerprint: " + certFingerprint.length); return false; } } } return true; return true; } } Loading @@ -113,11 +286,87 @@ public final class PasspointConfiguration implements Parcelable { config.homeSp = in.readParcelable(null); config.homeSp = in.readParcelable(null); config.credential = in.readParcelable(null); config.credential = in.readParcelable(null); config.policy = in.readParcelable(null); config.policy = in.readParcelable(null); config.subscriptionUpdate = in.readParcelable(null); config.trustRootCertList = readTrustRootCerts(in); config.updateIdentifier = in.readInt(); config.credentialPriority = in.readInt(); config.subscriptionCreationTimeInMs = in.readLong(); config.subscriptionExpirationTimeInMs = in.readLong(); config.subscriptionType = in.readString(); config.usageLimitUsageTimePeriodInMinutes = in.readLong(); config.usageLimitStartTimeInMs = in.readLong(); config.usageLimitDataLimit = in.readLong(); config.usageLimitTimeLimitInMinutes = in.readLong(); return config; return config; } } @Override @Override public PasspointConfiguration[] newArray(int size) { public PasspointConfiguration[] newArray(int size) { return new PasspointConfiguration[size]; return new PasspointConfiguration[size]; } } /** * Helper function for reading trust root certificate info list from a Parcel. * * @param in The Parcel to read from * @return The list of trust root certificate URL with the corresponding certificate * fingerprint */ private Map<String, byte[]> readTrustRootCerts(Parcel in) { int size = in.readInt(); if (size == NULL_VALUE) { return null; } Map<String, byte[]> trustRootCerts = new HashMap<>(size); for (int i = 0; i < size; i++) { String key = in.readString(); byte[] value = in.createByteArray(); trustRootCerts.put(key, value); } return trustRootCerts; } }; }; /** * Helper function for writing trust root certificate information list. * * @param dest The Parcel to write to * @param trustRootCerts The list of trust root certificate URL with the corresponding * certificate fingerprint */ private static void writeTrustRootCerts(Parcel dest, Map<String, byte[]> trustRootCerts) { if (trustRootCerts == null) { dest.writeInt(NULL_VALUE); return; } dest.writeInt(trustRootCerts.size()); for (Map.Entry<String, byte[]> entry : trustRootCerts.entrySet()) { dest.writeString(entry.getKey()); dest.writeByteArray(entry.getValue()); } } /** * Helper function for comparing two trust root certificate list. Cannot use Map#equals * method since the value type (byte[]) doesn't override equals method. * * @param list1 The first trust root certificate list * @param list2 The second trust root certificate list * @return true if the two list are equal */ private static boolean isTrustRootCertListEquals(Map<String, byte[]> list1, Map<String, byte[]> list2) { if (list1 == null || list2 == null) { return list1 == list2; } if (list1.size() != list2.size()) { return false; } for (Map.Entry<String, byte[]> entry : list1.entrySet()) { if (!Arrays.equals(entry.getValue(), list2.get(entry.getKey()))) { return false; } } return true; } } }
wifi/java/android/net/wifi/hotspot2/omadm/PPSMOParser.java +168 −40 File changed.Preview size limit exceeded, changes collapsed. Show changes
wifi/tests/assets/pps/PerProviderSubscription.xml +97 −0 Original line number Original line Diff line number Diff line Loading @@ -7,6 +7,10 @@ <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName> <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName> </Type> </Type> </RTProperties> </RTProperties> <Node> <NodeName>UpdateIdentifier</NodeName> <Value>12</Value> </Node> <Node> <Node> <NodeName>i001</NodeName> <NodeName>i001</NodeName> <Node> <Node> Loading Loading @@ -297,6 +301,99 @@ <Value>23</Value> <Value>23</Value> </Node> </Node> </Node> </Node> <Node> <NodeName>CredentialPriority</NodeName> <Value>99</Value> </Node> <Node> <NodeName>AAAServerTrustRoot</NodeName> <Node> <NodeName>a001</NodeName> <Node> <NodeName>CertURL</NodeName> <Value>server1.trust.root.com</Value> </Node> <Node> <NodeName>CertSHA256Fingerprint</NodeName> <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value> </Node> </Node> </Node> <Node> <NodeName>SubscriptionUpdate</NodeName> <Node> <NodeName>UpdateInterval</NodeName> <Value>120</Value> </Node> <Node> <NodeName>UpdateMethod</NodeName> <Value>SSP-ClientInitiated</Value> </Node> <Node> <NodeName>Restriction</NodeName> <Value>RoamingPartner</Value> </Node> <Node> <NodeName>URI</NodeName> <Value>subscription.update.com</Value> </Node> <Node> <NodeName>UsernamePassword</NodeName> <Node> <NodeName>Username</NodeName> <Value>subscriptionUser</Value> </Node> <Node> <NodeName>Password</NodeName> <Value>subscriptionPass</Value> </Node> </Node> <Node> <NodeName>TrustRoot</NodeName> <Node> <NodeName>CertURL</NodeName> <Value>subscription.update.cert.com</Value> </Node> <Node> <NodeName>CertSHA256Fingerprint</NodeName> <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value> </Node> </Node> </Node> <Node> <NodeName>SubscriptionParameter</NodeName> <Node> <NodeName>CreationDate</NodeName> <Value>2016-02-01T10:00:00Z</Value> </Node> <Node> <NodeName>ExpirationDate</NodeName> <Value>2016-03-01T10:00:00Z</Value> </Node> <Node> <NodeName>TypeOfSubscription</NodeName> <Value>Gold</Value> </Node> <Node> <NodeName>UsageLimits</NodeName> <Node> <NodeName>DataLimit</NodeName> <Value>921890</Value> </Node> <Node> <NodeName>StartDate</NodeName> <Value>2016-12-01T10:00:00Z</Value> </Node> <Node> <NodeName>TimeLimit</NodeName> <Value>120</Value> </Node> <Node> <NodeName>UsageTimePeriod</NodeName> <Value>99910</Value> </Node> </Node> </Node> </Node> </Node> </Node> </Node> </MgmtTree> </MgmtTree>
wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java +113 −1 Original line number Original line Diff line number Diff line Loading @@ -30,7 +30,9 @@ import android.util.Base64; import org.junit.Test; import org.junit.Test; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashMap; /** /** Loading @@ -38,6 +40,8 @@ import java.util.HashMap; */ */ @SmallTest @SmallTest public class PasspointConfigurationTest { public class PasspointConfigurationTest { private static final int MAX_URL_BYTES = 1023; private static final int CERTIFICATE_FINGERPRINT_BYTES = 32; /** /** * Utility function for creating a {@link android.net.wifi.hotspot2.pps.HomeSP}. * Utility function for creating a {@link android.net.wifi.hotspot2.pps.HomeSP}. Loading Loading @@ -111,11 +115,25 @@ public class PasspointConfigurationTest { policy.policyUpdate.base64EncodedPassword = policy.policyUpdate.base64EncodedPassword = Base64.encodeToString("password".getBytes(), Base64.DEFAULT); Base64.encodeToString("password".getBytes(), Base64.DEFAULT); policy.policyUpdate.trustRootCertUrl = "trust.cert.com"; policy.policyUpdate.trustRootCertUrl = "trust.cert.com"; policy.policyUpdate.trustRootCertSha256Fingerprint = new byte[32]; policy.policyUpdate.trustRootCertSha256Fingerprint = new byte[CERTIFICATE_FINGERPRINT_BYTES]; return policy; return policy; } } private static UpdateParameter createSubscriptionUpdate() { UpdateParameter subUpdate = new UpdateParameter(); subUpdate.updateIntervalInMinutes = 9021; subUpdate.updateMethod = UpdateParameter.UPDATE_METHOD_SSP; subUpdate.restriction = UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER; subUpdate.serverUri = "subscription.update.com"; subUpdate.username = "subUsername"; subUpdate.base64EncodedPassword = Base64.encodeToString("subPassword".getBytes(), Base64.DEFAULT); subUpdate.trustRootCertUrl = "subscription.trust.cert.com"; subUpdate.trustRootCertSha256Fingerprint = new byte[CERTIFICATE_FINGERPRINT_BYTES]; return subUpdate; } /** /** * Helper function for creating a {@link PasspointConfiguration} for testing. * Helper function for creating a {@link PasspointConfiguration} for testing. * * Loading @@ -126,6 +144,21 @@ public class PasspointConfigurationTest { config.homeSp = createHomeSp(); config.homeSp = createHomeSp(); config.credential = createCredential(); config.credential = createCredential(); config.policy = createPolicy(); config.policy = createPolicy(); config.subscriptionUpdate = createSubscriptionUpdate(); config.trustRootCertList = new HashMap<>(); config.trustRootCertList.put("trustRoot.cert1.com", new byte[CERTIFICATE_FINGERPRINT_BYTES]); config.trustRootCertList.put("trustRoot.cert2.com", new byte[CERTIFICATE_FINGERPRINT_BYTES]); config.updateIdentifier = 1; config.credentialPriority = 120; config.subscriptionCreationTimeInMs = 231200; config.subscriptionExpirationTimeInMs = 2134232; config.subscriptionType = "Gold"; config.usageLimitUsageTimePeriodInMinutes = 3600; config.usageLimitStartTimeInMs = 124214213; config.usageLimitDataLimit = 14121; config.usageLimitTimeLimitInMinutes = 78912; return config; return config; } } Loading Loading @@ -201,6 +234,31 @@ public class PasspointConfigurationTest { verifyParcel(config); verifyParcel(config); } } /** * Verify parcel read/write for a configuration that doesn't contain subscription update. * * @throws Exception */ @Test public void verifyParcelWithoutSubscriptionUpdate() throws Exception { PasspointConfiguration config = createConfig(); config.subscriptionUpdate = null; verifyParcel(config); } /** * Verify parcel read/write for a configuration that doesn't contain trust root certificate * list. * * @throws Exception */ @Test public void verifyParcelWithoutTrustRootCertList() throws Exception { PasspointConfiguration config = createConfig(); config.trustRootCertList = null; verifyParcel(config); } /** /** * Verify that a default/empty configuration is invalid. * Verify that a default/empty configuration is invalid. * * Loading Loading @@ -260,6 +318,60 @@ public class PasspointConfigurationTest { assertTrue(config.validate()); assertTrue(config.validate()); } } /** * Verify that a configuration without subscription update is valid, since subscription * update configurations are optional (applied for Hotspot 2.0 Release only). * * @throws Exception */ @Test public void validateConfigWithoutSubscriptionUpdate() throws Exception { PasspointConfiguration config = createConfig(); config.subscriptionUpdate = null; assertTrue(config.validate()); } /** * Verify that a configuration with a trust root certificate URL exceeding the max size * is invalid. * * @throws Exception */ @Test public void validateConfigWithInvalidTrustRootCertUrl() throws Exception { PasspointConfiguration config = createConfig(); byte[] rawUrlBytes = new byte[MAX_URL_BYTES + 1]; Arrays.fill(rawUrlBytes, (byte) 'a'); config.trustRootCertList.put(new String(rawUrlBytes, StandardCharsets.UTF_8), new byte[CERTIFICATE_FINGERPRINT_BYTES]); assertFalse(config.validate()); config.trustRootCertList = new HashMap<>(); config.trustRootCertList.put(null, new byte[CERTIFICATE_FINGERPRINT_BYTES]); assertFalse(config.validate()); } /** * Verify that a configuration with an invalid trust root certificate fingerprint is invalid. * * @throws Exception */ @Test public void validateConfigWithInvalidTrustRootCertFingerprint() throws Exception { PasspointConfiguration config = createConfig(); config.trustRootCertList = new HashMap<>(); config.trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES + 1]); assertFalse(config.validate()); config.trustRootCertList = new HashMap<>(); config.trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES - 1]); assertFalse(config.validate()); config.trustRootCertList = new HashMap<>(); config.trustRootCertList.put("test.cert.com", null); assertFalse(config.validate()); } /** /** * Verify that copy constructor works when pass in a null source. * Verify that copy constructor works when pass in a null source. * * Loading
wifi/tests/src/android/net/wifi/hotspot2/omadm/PPSMOParserTest.java +32 −3 Original line number Original line Diff line number Diff line Loading @@ -85,7 +85,38 @@ public class PPSMOParserTest { * @return {@link PasspointConfiguration} * @return {@link PasspointConfiguration} */ */ private PasspointConfiguration generateConfigurationFromPPSMOTree() throws Exception { private PasspointConfiguration generateConfigurationFromPPSMOTree() throws Exception { DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); PasspointConfiguration config = new PasspointConfiguration(); PasspointConfiguration config = new PasspointConfiguration(); config.updateIdentifier = 12; config.credentialPriority = 99; // AAA Server trust root. config.trustRootCertList = new HashMap<>(); byte[] certFingerprint = new byte[32]; Arrays.fill(certFingerprint, (byte) 0x1f); config.trustRootCertList.put("server1.trust.root.com", certFingerprint); // Subscription update. config.subscriptionUpdate = new UpdateParameter(); config.subscriptionUpdate.updateIntervalInMinutes = 120; config.subscriptionUpdate.updateMethod = UpdateParameter.UPDATE_METHOD_SSP; config.subscriptionUpdate.restriction = UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER; config.subscriptionUpdate.serverUri = "subscription.update.com"; config.subscriptionUpdate.username = "subscriptionUser"; config.subscriptionUpdate.base64EncodedPassword = "subscriptionPass"; config.subscriptionUpdate.trustRootCertUrl = "subscription.update.cert.com"; config.subscriptionUpdate.trustRootCertSha256Fingerprint = new byte[32]; Arrays.fill(config.subscriptionUpdate.trustRootCertSha256Fingerprint, (byte) 0x1f); // Subscription parameters. config.subscriptionCreationTimeInMs = format.parse("2016-02-01T10:00:00Z").getTime(); config.subscriptionExpirationTimeInMs = format.parse("2016-03-01T10:00:00Z").getTime(); config.subscriptionType = "Gold"; config.usageLimitDataLimit = 921890; config.usageLimitStartTimeInMs = format.parse("2016-12-01T10:00:00Z").getTime(); config.usageLimitTimeLimitInMinutes = 120; config.usageLimitUsageTimePeriodInMinutes = 99910; // HomeSP configuration. // HomeSP configuration. config.homeSp = new HomeSP(); config.homeSp = new HomeSP(); Loading @@ -101,7 +132,6 @@ public class PPSMOParserTest { config.homeSp.otherHomePartners = new String[] {"other.fqdn.com"}; config.homeSp.otherHomePartners = new String[] {"other.fqdn.com"}; // Credential configuration. // Credential configuration. DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); config.credential = new Credential(); config.credential = new Credential(); config.credential.creationTimeInMs = format.parse("2016-01-01T10:00:00Z").getTime(); config.credential.creationTimeInMs = format.parse("2016-01-01T10:00:00Z").getTime(); config.credential.expirationTimeInMs = format.parse("2016-02-01T10:00:00Z").getTime(); config.credential.expirationTimeInMs = format.parse("2016-02-01T10:00:00Z").getTime(); Loading Loading @@ -161,8 +191,7 @@ public class PPSMOParserTest { } } /** /** * Parse and verify all supported fields under PPS MO tree (currently only fields under * Parse and verify all supported fields under PPS MO tree. * HomeSP and Credential subtree). * * * @throws Exception * @throws Exception */ */ Loading