Copyright (c) 2016, The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
/** * Copyright (c) 2016, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
package android.net.wifi.hotspot2; import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.HomeSp; import android.net.wifi.hotspot2.pps.Policy; import android.net.wifi.hotspot2.pps.UpdateParameter; import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; import android.os.Parcel; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Objects;
Class representing Passpoint configuration. This contains configurations specified in PerProviderSubscription (PPS) Management Object (MO) tree. For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0 Release 2 Technical Specification.
/** * Class representing Passpoint configuration. This contains configurations specified in * PerProviderSubscription (PPS) Management Object (MO) tree. * * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0 * Release 2 Technical Specification. */
public final class PasspointConfiguration implements Parcelable { private static final String TAG = "PasspointConfiguration";
Number of bytes for certificate SHA-256 fingerprint byte array.
/** * Number of bytes for certificate SHA-256 fingerprint byte array. */
private static final int CERTIFICATE_SHA256_BYTES = 32;
Maximum bytes for URL string.
/** * Maximum bytes for URL string. */
private static final int MAX_URL_BYTES = 1023;
Integer value used for indicating null value in the Parcel.
/** * Integer value used for indicating null value in the Parcel. */
private static final int NULL_VALUE = -1;
Configurations under HomeSp subtree.
/** * Configurations under HomeSp subtree. */
private HomeSp mHomeSp = null;
Set the Home SP (Service Provider) information.
Params:
  • homeSp – The Home SP information to set to
/** * Set the Home SP (Service Provider) information. * * @param homeSp The Home SP information to set to */
public void setHomeSp(HomeSp homeSp) { mHomeSp = homeSp; }
Get the Home SP (Service Provider) information.
Returns:Home SP information
/** * Get the Home SP (Service Provider) information. * * @return Home SP information */
public HomeSp getHomeSp() { return mHomeSp; }
Configurations under Credential subtree.
/** * Configurations under Credential subtree. */
private Credential mCredential = null;
Set the credential information.
Params:
  • credential – The credential information to set to
/** * Set the credential information. * * @param credential The credential information to set to */
public void setCredential(Credential credential) { mCredential = credential; }
Get the credential information.
Returns:credential information
/** * Get the credential information. * * @return credential information */
public Credential getCredential() { return mCredential; }
Configurations under Policy subtree.
/** * Configurations under Policy subtree. */
private Policy mPolicy = null;
@hide
/** * @hide */
public void setPolicy(Policy policy) { mPolicy = policy; }
@hide
/** * @hide */
public Policy getPolicy() { return mPolicy; }
Meta data for performing subscription update.
/** * Meta data for performing subscription update. */
private UpdateParameter mSubscriptionUpdate = null;
@hide
/** * @hide */
public void setSubscriptionUpdate(UpdateParameter subscriptionUpdate) { mSubscriptionUpdate = subscriptionUpdate; }
@hide
/** * @hide */
public UpdateParameter getSubscriptionUpdate() { return mSubscriptionUpdate; }
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.
/** * 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. */
private Map<String, byte[]> mTrustRootCertList = null;
@hide
/** * @hide */
public void setTrustRootCertList(Map<String, byte[]> trustRootCertList) { mTrustRootCertList = trustRootCertList; }
@hide
/** * @hide */
public Map<String, byte[]> getTrustRootCertList() { return mTrustRootCertList; }
Set by the subscription server, updated every time the configuration is updated by the subscription server. Use Integer.MIN_VALUE to indicate unset value.
/** * Set by the subscription server, updated every time the configuration is updated by * the subscription server. * * Use Integer.MIN_VALUE to indicate unset value. */
private int mUpdateIdentifier = Integer.MIN_VALUE;
@hide
/** * @hide */
public void setUpdateIdentifier(int updateIdentifier) { mUpdateIdentifier = updateIdentifier; }
@hide
/** * @hide */
public int getUpdateIdentifier() { return mUpdateIdentifier; }
The priority of the credential. Use Integer.MIN_VALUE to indicate unset value.
/** * The priority of the credential. * * Use Integer.MIN_VALUE to indicate unset value. */
private int mCredentialPriority = Integer.MIN_VALUE;
@hide
/** * @hide */
public void setCredentialPriority(int credentialPriority) { mCredentialPriority = credentialPriority; }
@hide
/** * @hide */
public int getCredentialPriority() { return mCredentialPriority; }
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.
/** * 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. */
private long mSubscriptionCreationTimeInMillis = Long.MIN_VALUE;
@hide
/** * @hide */
public void setSubscriptionCreationTimeInMillis(long subscriptionCreationTimeInMillis) { mSubscriptionCreationTimeInMillis = subscriptionCreationTimeInMillis; }
@hide
/** * @hide */
public long getSubscriptionCreationTimeInMillis() { return mSubscriptionCreationTimeInMillis; }
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.
/** * 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. */
private long mSubscriptionExpirationTimeInMillis = Long.MIN_VALUE;
@hide
/** * @hide */
public void setSubscriptionExpirationTimeInMillis(long subscriptionExpirationTimeInMillis) { mSubscriptionExpirationTimeInMillis = subscriptionExpirationTimeInMillis; }
@hide
/** * @hide */
public long getSubscriptionExpirationTimeInMillis() { return mSubscriptionExpirationTimeInMillis; }
The type of the subscription. This is defined by the provider and the value is provider specific.
/** * The type of the subscription. This is defined by the provider and the value is provider * specific. */
private String mSubscriptionType = null;
@hide
/** * @hide */
public void setSubscriptionType(String subscriptionType) { mSubscriptionType = subscriptionType; }
@hide
/** * @hide */
public String getSubscriptionType() { return mSubscriptionType; }
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.
/** * 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. */
private long mUsageLimitUsageTimePeriodInMinutes = Long.MIN_VALUE;
@hide
/** * @hide */
public void setUsageLimitUsageTimePeriodInMinutes(long usageLimitUsageTimePeriodInMinutes) { mUsageLimitUsageTimePeriodInMinutes = usageLimitUsageTimePeriodInMinutes; }
@hide
/** * @hide */
public long getUsageLimitUsageTimePeriodInMinutes() { return mUsageLimitUsageTimePeriodInMinutes; }
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.
/** * 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. */
private long mUsageLimitStartTimeInMillis = Long.MIN_VALUE;
@hide
/** * @hide */
public void setUsageLimitStartTimeInMillis(long usageLimitStartTimeInMillis) { mUsageLimitStartTimeInMillis = usageLimitStartTimeInMillis; }
@hide
/** * @hide */
public long getUsageLimitStartTimeInMillis() { return mUsageLimitStartTimeInMillis; }
The cumulative data limit in megabytes for the usageLimitUsageTimePeriodInMinutes. A value of zero indicate unlimited data usage. Use Long.MIN_VALUE to indicate unset 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. */
private long mUsageLimitDataLimit = Long.MIN_VALUE;
@hide
/** * @hide */
public void setUsageLimitDataLimit(long usageLimitDataLimit) { mUsageLimitDataLimit = usageLimitDataLimit; }
@hide
/** * @hide */
public long getUsageLimitDataLimit() { return mUsageLimitDataLimit; }
The cumulative time limit in minutes for the usageLimitUsageTimePeriodInMinutes. A value of zero indicate unlimited time usage.
/** * The cumulative time limit in minutes for the {@link #usageLimitUsageTimePeriodInMinutes}. * A value of zero indicate unlimited time usage. */
private long mUsageLimitTimeLimitInMinutes = Long.MIN_VALUE;
@hide
/** * @hide */
public void setUsageLimitTimeLimitInMinutes(long usageLimitTimeLimitInMinutes) { mUsageLimitTimeLimitInMinutes = usageLimitTimeLimitInMinutes; }
@hide
/** * @hide */
public long getUsageLimitTimeLimitInMinutes() { return mUsageLimitTimeLimitInMinutes; }
Constructor for creating PasspointConfiguration with default values.
/** * Constructor for creating PasspointConfiguration with default values. */
public PasspointConfiguration() {}
Copy constructor.
Params:
  • source – The source to copy from
/** * Copy constructor. * * @param source The source to copy from */
public PasspointConfiguration(PasspointConfiguration source) { if (source == null) { return; } if (source.mHomeSp != null) { mHomeSp = new HomeSp(source.mHomeSp); } if (source.mCredential != null) { mCredential = new Credential(source.mCredential); } if (source.mPolicy != null) { mPolicy = new Policy(source.mPolicy); } if (source.mTrustRootCertList != null) { mTrustRootCertList = Collections.unmodifiableMap(source.mTrustRootCertList); } if (source.mSubscriptionUpdate != null) { mSubscriptionUpdate = new UpdateParameter(source.mSubscriptionUpdate); } mUpdateIdentifier = source.mUpdateIdentifier; mCredentialPriority = source.mCredentialPriority; mSubscriptionCreationTimeInMillis = source.mSubscriptionCreationTimeInMillis; mSubscriptionExpirationTimeInMillis = source.mSubscriptionExpirationTimeInMillis; mSubscriptionType = source.mSubscriptionType; mUsageLimitDataLimit = source.mUsageLimitDataLimit; mUsageLimitStartTimeInMillis = source.mUsageLimitStartTimeInMillis; mUsageLimitTimeLimitInMinutes = source.mUsageLimitTimeLimitInMinutes; mUsageLimitUsageTimePeriodInMinutes = source.mUsageLimitUsageTimePeriodInMinutes; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeParcelable(mHomeSp, flags); dest.writeParcelable(mCredential, flags); dest.writeParcelable(mPolicy, flags); dest.writeParcelable(mSubscriptionUpdate, flags); writeTrustRootCerts(dest, mTrustRootCertList); dest.writeInt(mUpdateIdentifier); dest.writeInt(mCredentialPriority); dest.writeLong(mSubscriptionCreationTimeInMillis); dest.writeLong(mSubscriptionExpirationTimeInMillis); dest.writeString(mSubscriptionType); dest.writeLong(mUsageLimitUsageTimePeriodInMinutes); dest.writeLong(mUsageLimitStartTimeInMillis); dest.writeLong(mUsageLimitDataLimit); dest.writeLong(mUsageLimitTimeLimitInMinutes); } @Override public boolean equals(Object thatObject) { if (this == thatObject) { return true; } if (!(thatObject instanceof PasspointConfiguration)) { return false; } PasspointConfiguration that = (PasspointConfiguration) thatObject; return (mHomeSp == null ? that.mHomeSp == null : mHomeSp.equals(that.mHomeSp)) && (mCredential == null ? that.mCredential == null : mCredential.equals(that.mCredential)) && (mPolicy == null ? that.mPolicy == null : mPolicy.equals(that.mPolicy)) && (mSubscriptionUpdate == null ? that.mSubscriptionUpdate == null : mSubscriptionUpdate.equals(that.mSubscriptionUpdate)) && isTrustRootCertListEquals(mTrustRootCertList, that.mTrustRootCertList) && mUpdateIdentifier == that.mUpdateIdentifier && mCredentialPriority == that.mCredentialPriority && mSubscriptionCreationTimeInMillis == that.mSubscriptionCreationTimeInMillis && mSubscriptionExpirationTimeInMillis == that.mSubscriptionExpirationTimeInMillis && TextUtils.equals(mSubscriptionType, that.mSubscriptionType) && mUsageLimitUsageTimePeriodInMinutes == that.mUsageLimitUsageTimePeriodInMinutes && mUsageLimitStartTimeInMillis == that.mUsageLimitStartTimeInMillis && mUsageLimitDataLimit == that.mUsageLimitDataLimit && mUsageLimitTimeLimitInMinutes == that.mUsageLimitTimeLimitInMinutes; } @Override public int hashCode() { return Objects.hash(mHomeSp, mCredential, mPolicy, mSubscriptionUpdate, mTrustRootCertList, mUpdateIdentifier, mCredentialPriority, mSubscriptionCreationTimeInMillis, mSubscriptionExpirationTimeInMillis, mUsageLimitUsageTimePeriodInMinutes, mUsageLimitStartTimeInMillis, mUsageLimitDataLimit, mUsageLimitTimeLimitInMinutes); } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("UpdateIdentifier: ").append(mUpdateIdentifier).append("\n"); builder.append("CredentialPriority: ").append(mCredentialPriority).append("\n"); builder.append("SubscriptionCreationTime: ").append( mSubscriptionCreationTimeInMillis != Long.MIN_VALUE ? new Date(mSubscriptionCreationTimeInMillis) : "Not specified").append("\n"); builder.append("SubscriptionExpirationTime: ").append( mSubscriptionExpirationTimeInMillis != Long.MIN_VALUE ? new Date(mSubscriptionExpirationTimeInMillis) : "Not specified").append("\n"); builder.append("UsageLimitStartTime: ").append(mUsageLimitStartTimeInMillis != Long.MIN_VALUE ? new Date(mUsageLimitStartTimeInMillis) : "Not specified").append("\n"); builder.append("UsageTimePeriod: ").append(mUsageLimitUsageTimePeriodInMinutes) .append("\n"); builder.append("UsageLimitDataLimit: ").append(mUsageLimitDataLimit).append("\n"); builder.append("UsageLimitTimeLimit: ").append(mUsageLimitTimeLimitInMinutes).append("\n"); if (mHomeSp != null) { builder.append("HomeSP Begin ---\n"); builder.append(mHomeSp); builder.append("HomeSP End ---\n"); } if (mCredential != null) { builder.append("Credential Begin ---\n"); builder.append(mCredential); builder.append("Credential End ---\n"); } if (mPolicy != null) { builder.append("Policy Begin ---\n"); builder.append(mPolicy); builder.append("Policy End ---\n"); } if (mSubscriptionUpdate != null) { builder.append("SubscriptionUpdate Begin ---\n"); builder.append(mSubscriptionUpdate); builder.append("SubscriptionUpdate End ---\n"); } if (mTrustRootCertList != null) { builder.append("TrustRootCertServers: ").append(mTrustRootCertList.keySet()) .append("\n"); } return builder.toString(); }
Validate the configuration data.
Returns:true on success or false on failure
@hide
/** * Validate the configuration data. * * @return true on success or false on failure * @hide */
public boolean validate() { if (mHomeSp == null || !mHomeSp.validate()) { return false; } if (mCredential == null || !mCredential.validate()) { return false; } if (mPolicy != null && !mPolicy.validate()) { return false; } if (mSubscriptionUpdate != null && !mSubscriptionUpdate.validate()) { return false; } if (mTrustRootCertList != null) { for (Map.Entry<String, byte[]> entry : mTrustRootCertList.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; } public static final Creator<PasspointConfiguration> CREATOR = new Creator<PasspointConfiguration>() { @Override public PasspointConfiguration createFromParcel(Parcel in) { PasspointConfiguration config = new PasspointConfiguration(); config.setHomeSp(in.readParcelable(null)); config.setCredential(in.readParcelable(null)); config.setPolicy(in.readParcelable(null)); config.setSubscriptionUpdate(in.readParcelable(null)); config.setTrustRootCertList(readTrustRootCerts(in)); config.setUpdateIdentifier(in.readInt()); config.setCredentialPriority(in.readInt()); config.setSubscriptionCreationTimeInMillis(in.readLong()); config.setSubscriptionExpirationTimeInMillis(in.readLong()); config.setSubscriptionType(in.readString()); config.setUsageLimitUsageTimePeriodInMinutes(in.readLong()); config.setUsageLimitStartTimeInMillis(in.readLong()); config.setUsageLimitDataLimit(in.readLong()); config.setUsageLimitTimeLimitInMinutes(in.readLong()); return config; } @Override public PasspointConfiguration[] newArray(int size) { return new PasspointConfiguration[size]; }
Helper function for reading trust root certificate info list from a Parcel.
Params:
  • in – The Parcel to read from
Returns:The list of trust root certificate URL with the corresponding certificate fingerprint
/** * 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.
Params:
  • dest – The Parcel to write to
  • trustRootCerts – The list of trust root certificate URL with the corresponding certificate fingerprint
/** * 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.
Params:
  • list1 – The first trust root certificate list
  • list2 – The second trust root certificate list
Returns:true if the two list are equal
/** * 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; } }