summaryrefslogtreecommitdiffstats
path: root/wifi/java/android
diff options
context:
space:
mode:
authorVinit Deshpande <vinitd@google.com>2015-03-09 19:01:31 -0700
committerVinit Deshpande <vinitd@google.com>2015-03-09 19:01:31 -0700
commit1aa4dcee03f75df4f96ac9d3653503e0ae027117 (patch)
tree51bb87b53e2e3f85edaf22d355e29c637a684d5e /wifi/java/android
parent472cca08eb42fc198cf70ac327567c941960ea17 (diff)
parent7dd2f6b57b5ef1f14eb55b7801a3d31729ad7a0a (diff)
downloadframeworks_base-1aa4dcee03f75df4f96ac9d3653503e0ae027117.zip
frameworks_base-1aa4dcee03f75df4f96ac9d3653503e0ae027117.tar.gz
frameworks_base-1aa4dcee03f75df4f96ac9d3653503e0ae027117.tar.bz2
am "Bring in passpoint code [DO NOT MERGE]"
merged from partner/m-wireless-wifi-dev 7dd2f6b Bring in passpoint code [DO NOT MERGE]
Diffstat (limited to 'wifi/java/android')
-rw-r--r--wifi/java/android/net/wifi/ScanResult.java20
-rw-r--r--wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl45
-rw-r--r--wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.aidl19
-rw-r--r--wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.java667
-rw-r--r--wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.aidl19
-rw-r--r--wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.java1377
-rw-r--r--wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.aidl19
-rw-r--r--wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.java559
-rw-r--r--wifi/java/android/net/wifi/passpoint/WifiPasspointManager.java567
-rw-r--r--wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.aidl19
-rw-r--r--wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.java152
-rw-r--r--wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.aidl19
-rw-r--r--wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.java386
13 files changed, 3868 insertions, 0 deletions
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 9729c91..994f180 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -16,6 +16,8 @@
package android.net.wifi;
+import android.net.wifi.passpoint.WifiPasspointInfo;
+import android.net.wifi.passpoint.WifiPasspointManager;
import android.os.Parcel;
import android.os.Parcelable;
@@ -169,6 +171,13 @@ public class ScanResult implements Parcelable {
public int distanceSdCm;
/**
+ * Passpoint ANQP information. This is not fetched automatically.
+ * Use {@link WifiPasspointManager#requestAnqpInfo} to request ANQP info.
+ * {@hide}
+ */
+ public WifiPasspointInfo passpoint;
+
+ /**
* {@hide}
*/
public final static int UNSPECIFIED = -1;
@@ -264,6 +273,7 @@ public class ScanResult implements Parcelable {
distanceCm = source.distanceCm;
distanceSdCm = source.distanceSdCm;
seen = source.seen;
+ passpoint = source.passpoint;
autoJoinStatus = source.autoJoinStatus;
untrusted = source.untrusted;
numConnection = source.numConnection;
@@ -303,6 +313,7 @@ public class ScanResult implements Parcelable {
sb.append(", distanceSd: ").append((distanceSdCm != UNSPECIFIED ? distanceSdCm : "?")).
append("(cm)");
+ sb.append(", passpoint: ").append(passpoint != null ? "yes" : "no");
if (autoJoinStatus != 0) {
sb.append(", status: ").append(autoJoinStatus);
}
@@ -336,6 +347,12 @@ public class ScanResult implements Parcelable {
dest.writeInt(numUsage);
dest.writeInt(numIpConfigFailures);
dest.writeInt(isAutoJoinCandidate);
+ if (passpoint != null) {
+ dest.writeInt(1);
+ passpoint.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
if (informationElements != null) {
dest.writeInt(informationElements.length);
for (int i = 0; i < informationElements.length; i++) {
@@ -373,6 +390,9 @@ public class ScanResult implements Parcelable {
sr.numUsage = in.readInt();
sr.numIpConfigFailures = in.readInt();
sr.isAutoJoinCandidate = in.readInt();
+ if (in.readInt() == 1) {
+ sr.passpoint = WifiPasspointInfo.CREATOR.createFromParcel(in);
+ }
int n = in.readInt();
if (n != 0) {
sr.informationElements = new InformationElement[n];
diff --git a/wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl b/wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl
new file mode 100644
index 0000000..50bec33
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/IWifiPasspointManager.aidl
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2014, 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.passpoint;
+
+import android.net.wifi.ScanResult;
+import android.net.wifi.passpoint.WifiPasspointPolicy;
+import android.net.wifi.passpoint.WifiPasspointCredential;
+import android.os.Messenger;
+
+/**
+ * Interface that allows controlling and querying Wifi Passpoint connectivity.
+ *
+ * {@hide}
+ */
+interface IWifiPasspointManager
+{
+ Messenger getMessenger();
+
+ int getPasspointState();
+
+ List<WifiPasspointPolicy> requestCredentialMatch(in List<ScanResult> requested);
+
+ List<WifiPasspointCredential> getCredentials();
+
+ boolean addCredential(in WifiPasspointCredential cred);
+
+ boolean updateCredential(in WifiPasspointCredential cred);
+
+ boolean removeCredential(in WifiPasspointCredential cred);
+}
+
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.aidl b/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.aidl
new file mode 100644
index 0000000..cfd3605
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, 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.passpoint;
+
+parcelable WifiPasspointCredential;
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.java
new file mode 100644
index 0000000..0a7230f
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointCredential.java
@@ -0,0 +1,667 @@
+/*
+ * Copyright (C) 2014 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.passpoint;
+
+import android.net.wifi.WifiEnterpriseConfig;
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * A class representing a Wi-Fi Passpoint credential.
+ * @hide
+ */
+public class WifiPasspointCredential implements Parcelable {
+
+ private final static String TAG = "PasspointCredential";
+ private final static boolean DBG = true;
+
+ /** Wi-Fi nodes**/
+ private String mWifiSpFqdn;
+
+ /** PerProviderSubscription nodes **/
+ private String mCredentialName;
+
+ /** SubscriptionUpdate nodes **/
+ private String mSubscriptionUpdateInterval;
+ private String mSubscriptionUpdateMethod;
+ private String mSubscriptionUpdateRestriction;
+ private String mSubscriptionUpdateURI;
+ private String mSubscriptionUpdateUsername;
+ private String mSubscriptionUpdatePassword;
+
+ /** HomeSP nodes **/
+ private String mHomeSpFqdn;
+ private String mFriendlyName;
+ private Collection<WifiPasspointDmTree.HomeOIList> mHomeOIList;
+ private Collection<WifiPasspointDmTree.OtherHomePartners> mOtherHomePartnerList;
+
+ /** SubscriptionParameters nodes**/
+ private String mCreationDate;
+ private String mExpirationDate;
+
+ /** Credential nodes **/
+ private String mType;
+ private String mInnerMethod;
+ private String mCertType;
+ private String mCertSha256Fingerprint;
+ private String mUpdateIdentifier;
+ private String mUsername;
+ private String mPasswd;
+ private String mRealm;
+ private String mImsi;
+ private String mMcc;
+ private String mMnc;
+ private String mCaRootCert;
+ private String mClientCert;
+ private boolean mCheckAaaServerCertStatus;
+
+ /** Policy nodes **/
+ private String mPolicyUpdateUri;
+ private String mPolicyUpdateInterval;
+ private String mPolicyUpdateUsername;
+ private String mPolicyUpdatePassword;
+ private String mPolicyUpdateRestriction;
+ private String mPolicyUpdateMethod;
+ private Collection<WifiPasspointDmTree.PreferredRoamingPartnerList> mPreferredRoamingPartnerList;
+ private Collection<WifiPasspointDmTree.MinBackhaulThresholdNetwork> mMinBackhaulThresholdNetwork;
+ private Collection<WifiPasspointDmTree.SPExclusionList> mSpExclusionList;
+ private Collection<WifiPasspointDmTree.RequiredProtoPortTuple> mRequiredProtoPortTuple;
+ private String mMaxBssLoad;
+
+ /** CrednetialPriority node **/
+ private int mCrednetialPriority;
+
+ /** AAAServerTrustRoot nodes **/
+ private String mAaaCertUrl;
+ private String mAaaSha256Fingerprint;
+
+ /** Others **/
+ private boolean mIsMachineRemediation;
+ private boolean mUserPreferred = false;
+ private String mWifiTreePath;
+ private WifiEnterpriseConfig mEnterpriseConfig;
+
+ /** @hide */
+ public WifiPasspointCredential() {}
+
+ /**
+ * Constructor
+ * @param realm Realm of the passpoint credential
+ * @param fqdn Fully qualified domain name (FQDN) of the credential
+ * @param config Enterprise config, must be either EAP-TLS or EAP-TTLS
+ * @see WifiEnterpriseConfig
+ */
+ public WifiPasspointCredential(String realm, String fqdn, WifiEnterpriseConfig config) {
+ mRealm = realm;
+ switch (config.getEapMethod()) {
+ case WifiEnterpriseConfig.Eap.TLS:
+ case WifiEnterpriseConfig.Eap.TTLS:
+ mEnterpriseConfig = new WifiEnterpriseConfig(config);
+ break;
+ default:
+ // ignore
+ }
+ }
+
+ /** @hide */
+ public WifiPasspointCredential(String type,
+ String caroot,
+ String clientcert,
+ String mcc,
+ String mnc,
+ WifiPasspointDmTree.SpFqdn sp,
+ WifiPasspointDmTree.CredentialInfo credinfo) {
+
+ if (credinfo == null) {
+ return;
+ }
+
+ mType = type;
+ mCaRootCert = caroot;
+ mClientCert = clientcert;
+
+ mWifiSpFqdn = sp.nodeName;
+ mUpdateIdentifier = sp.perProviderSubscription.UpdateIdentifier;
+
+ mCredentialName = credinfo.nodeName;
+ mOtherHomePartnerList = credinfo.homeSP.otherHomePartners.values();
+
+ Set set = credinfo.aAAServerTrustRoot.entrySet();
+ Iterator i = set.iterator();
+ if (i.hasNext()) {
+ Map.Entry entry3 = (Map.Entry) i.next();
+ WifiPasspointDmTree.AAAServerTrustRoot aaa = (WifiPasspointDmTree.AAAServerTrustRoot) entry3.getValue();
+ mAaaCertUrl = aaa.CertURL;
+ mAaaSha256Fingerprint = aaa.CertSHA256Fingerprint;
+ }
+
+ mCertType = credinfo.credential.digitalCertificate.CertificateType;
+ mCertSha256Fingerprint = credinfo.credential.digitalCertificate.CertSHA256Fingerprint;
+ mUsername = credinfo.credential.usernamePassword.Username;
+ mPasswd = credinfo.credential.usernamePassword.Password;
+ mIsMachineRemediation = credinfo.credential.usernamePassword.MachineManaged;
+ mInnerMethod = credinfo.credential.usernamePassword.eAPMethod.InnerMethod;
+ mImsi = credinfo.credential.sim.IMSI;
+ mMcc = mcc;
+ mMnc = mnc;
+ mCreationDate = credinfo.credential.CreationDate;
+ mExpirationDate = credinfo.credential.ExpirationDate;
+ mRealm = credinfo.credential.Realm;
+
+ if (credinfo.credentialPriority == null) {
+ mCrednetialPriority = 128;
+ } else {
+ mCrednetialPriority = Integer.parseInt(credinfo.credentialPriority);
+ }
+
+ mHomeSpFqdn = credinfo.homeSP.FQDN;
+
+ mSubscriptionUpdateInterval = credinfo.subscriptionUpdate.UpdateInterval;
+ mSubscriptionUpdateMethod = credinfo.subscriptionUpdate.UpdateMethod;
+ mSubscriptionUpdateRestriction = credinfo.subscriptionUpdate.Restriction;
+ mSubscriptionUpdateURI = credinfo.subscriptionUpdate.URI;
+ mSubscriptionUpdateUsername = credinfo.subscriptionUpdate.usernamePassword.Username;
+ mSubscriptionUpdatePassword = credinfo.subscriptionUpdate.usernamePassword.Password;
+
+ mPolicyUpdateUri = credinfo.policy.policyUpdate.URI;
+ mPolicyUpdateInterval = credinfo.policy.policyUpdate.UpdateInterval;
+ mPolicyUpdateUsername = credinfo.policy.policyUpdate.usernamePassword.Username;
+ mPolicyUpdatePassword = credinfo.policy.policyUpdate.usernamePassword.Password;
+ mPolicyUpdateRestriction = credinfo.policy.policyUpdate.Restriction;
+ mPolicyUpdateMethod = credinfo.policy.policyUpdate.UpdateMethod;
+ mPreferredRoamingPartnerList = credinfo.policy.preferredRoamingPartnerList.values();
+ mMinBackhaulThresholdNetwork = credinfo.policy.minBackhaulThreshold.values();
+ mRequiredProtoPortTuple = credinfo.policy.requiredProtoPortTuple.values();
+ mMaxBssLoad = credinfo.policy.maximumBSSLoadValue;
+ mSpExclusionList = credinfo.policy.sPExclusionList.values();
+
+ mHomeOIList = credinfo.homeSP.homeOIList.values();
+ mFriendlyName = credinfo.homeSP.FriendlyName;
+ mCheckAaaServerCertStatus = credinfo.credential.CheckAAAServerCertStatus;
+ }
+
+ /** @hide */
+ public String getUpdateIdentifier() {
+ return mUpdateIdentifier;
+ }
+
+ /** @hide */
+ public String getUpdateMethod() {
+ return mSubscriptionUpdateMethod;
+ }
+
+ /** @hide */
+ public void setUpdateMethod(String method) {
+ mSubscriptionUpdateMethod = method;
+ }
+
+ /** @hide */
+ public String getWifiSpFqdn() {
+ return mWifiSpFqdn;
+ }
+
+ /** @hide */
+ public String getCredName() {
+ return mCredentialName;
+ }
+
+ /** @hide */
+ public String getType() {
+ return mType;
+ }
+
+ /**
+ * Get enterprise config of this Passpoint credential.
+ * @return Enterprise config
+ * @see WifiEnterpriseConfig
+ */
+ public WifiEnterpriseConfig getEnterpriseConfig() {
+ return new WifiEnterpriseConfig(mEnterpriseConfig);
+ }
+
+ /**
+ * Set enterprise config of this Passpoint credential.
+ * @param config Enterprise config, must be either EAP-TLS or EAP-TTLS
+ * @see WifiEnterpriseConfig
+ */
+ public void setEnterpriseConfig(WifiEnterpriseConfig config) {
+ // TODO
+ }
+
+ /** @hide */
+ public String getCertType() {
+ return mCertType;
+ }
+
+ /** @hide */
+ public String getCertSha256Fingerprint() {
+ return mCertSha256Fingerprint;
+ }
+
+ /** @hide */
+ public String getUserName() {
+ return mUsername;
+ }
+
+ /** @hide */
+ public String getPassword() {
+ // TODO: guarded by connectivity internal
+ return mPasswd;
+ }
+
+ /** @hide */
+ public String getImsi() {
+ return mImsi;
+ }
+
+ /** @hide */
+ public String getMcc() {
+ return mMcc;
+ }
+
+ /** @hide */
+ public String getMnc() {
+ return mMnc;
+ }
+
+ /** @hide */
+ public String getCaRootCertPath() {
+ return mCaRootCert;
+ }
+
+ /** @hide */
+ public String getClientCertPath() {
+ return mClientCert;
+ }
+
+ /**
+ * Get the realm of this Passpoint credential.
+ * @return Realm
+ */
+ public String getRealm() {
+ return mRealm;
+ }
+
+ /**
+ * Set the ream of this Passpoint credential.
+ * @param realm Realm
+ */
+ public void setRealm(String realm) {
+ mRealm = realm;
+ }
+
+ /** @hide */
+ public int getPriority() {
+ if (mUserPreferred) {
+ return 0;
+ }
+
+ return mCrednetialPriority;
+ }
+
+ /**
+ * Get the fully qualified domain name (FQDN) of this Passpoint credential.
+ * @return FQDN
+ */
+ public String getHomeSpFqdn() {
+ return mHomeSpFqdn;
+ }
+
+ /**
+ * Set the fully qualified domain name (FQDN) of this Passpoint credential.
+ * @param fqdn FQDN
+ */
+ public void setHomeFqdn(String fqdn) {
+ mHomeSpFqdn = fqdn;
+ }
+
+
+ /** @hide */
+ public Collection<WifiPasspointDmTree.OtherHomePartners> getOtherHomePartnerList() {
+ return mOtherHomePartnerList;
+ }
+
+ /** @hide */
+ public String getSubscriptionUpdateUsername() {
+ return mSubscriptionUpdateUsername;
+ }
+
+ /** @hide */
+ public String getSubscriptionUpdatePassword() {
+ return mSubscriptionUpdatePassword;
+ }
+
+ /** @hide */
+ public String getPolicyUpdateUri() {
+ return mPolicyUpdateUri;
+ }
+
+ /** @hide */
+ public String getPolicyUpdateInterval() {
+ return mPolicyUpdateInterval;
+ }
+
+ /** @hide */
+ public String getPolicyUpdateUsername() {
+ return mPolicyUpdateUsername;
+ }
+
+ /** @hide */
+ public String getPolicyUpdatePassword() {
+ return mPolicyUpdatePassword;
+ }
+
+ /** @hide */
+ public String getPolicyUpdateRestriction() {
+ return mPolicyUpdateRestriction;
+ }
+
+ /** @hide */
+ public String getPolicyUpdateMethod() {
+ return mPolicyUpdateMethod;
+ }
+
+ /** @hide */
+ public String getCreationDate() {
+ return mCreationDate;
+ }
+
+ /** @hide */
+ public String getExpirationDate() {
+ return mExpirationDate;
+ }
+
+ /** @hide */
+ public void setExpirationDate(String expirationdate) {
+ mExpirationDate = expirationdate;
+ }
+
+ /** @hide */
+ public Collection<WifiPasspointDmTree.PreferredRoamingPartnerList> getPreferredRoamingPartnerList() {
+ return mPreferredRoamingPartnerList;
+ }
+
+ /** @hide */
+ public Collection<WifiPasspointDmTree.HomeOIList> getHomeOiList() {
+ return mHomeOIList;
+ }
+
+ /** @hide */
+ public Collection<WifiPasspointDmTree.MinBackhaulThresholdNetwork> getBackhaulThresholdList() {
+ return mMinBackhaulThresholdNetwork;
+ }
+
+ /** @hide */
+ public Collection<WifiPasspointDmTree.RequiredProtoPortTuple> getRequiredProtoPortList() {
+ return mRequiredProtoPortTuple;
+ }
+
+ /** @hide */
+ public Collection<WifiPasspointDmTree.SPExclusionList> getSPExclusionList() {
+ return mSpExclusionList;
+ }
+
+ /** @hide */
+ public boolean getIsMachineRemediation() {
+ return mIsMachineRemediation;
+ }
+
+ /** @hide */
+ public String getAaaCertUrl() {
+ return mAaaCertUrl;
+ }
+
+ /** @hide */
+ public String getAaaSha256Fingerprint() {
+ return mAaaSha256Fingerprint;
+ }
+
+ /** @hide */
+ public String getSubscriptionUpdateRestriction() {
+ return mSubscriptionUpdateRestriction;
+ }
+
+ /** @hide */
+ public String getSubscriptionUpdateURI() {
+ return mSubscriptionUpdateURI;
+ }
+
+ /** @hide */
+ public String getSubscriptionUpdateInterval() {
+ return mSubscriptionUpdateInterval;
+ }
+
+ /** @hide */
+ public String getFriendlyName() {
+ return mFriendlyName;
+ }
+
+ /** @hide */
+ public String getMaxBssLoad() {
+ return mMaxBssLoad;
+ }
+
+ /** @hide */
+ public boolean getUserPreference() {
+ return mUserPreferred;
+ }
+
+ /** @hide */
+ public boolean getCheckAaaServerCertStatus() {
+ return mCheckAaaServerCertStatus;
+ }
+
+ /** @hide */
+ public void setUserPreference(boolean value) {
+ mUserPreferred = value;
+ }
+
+ @Override
+ /** @hide */
+ public boolean equals(Object obj) {
+ boolean result = false;
+ if (obj instanceof WifiPasspointCredential) {
+ final WifiPasspointCredential other = (WifiPasspointCredential) obj;
+ if (this.mType.equals(other.mType)) {
+ if (this.mType.equals("TTLS")) {
+ result = this.mUsername.equals(other.mUsername) &&
+ this.mPasswd.equals(other.mPasswd) &&
+ this.mRealm.equals(other.mRealm) &&
+ this.mHomeSpFqdn.equals(other.mHomeSpFqdn);
+ }
+ if (this.mType.equals("TLS")) {
+ result = this.mRealm.equals(other.mRealm) &&
+ this.mHomeSpFqdn.equals(other.mHomeSpFqdn) &&
+ this.mClientCert.equals(other.mClientCert);
+ }
+ if (this.mType.equals("SIM")) {
+ result = this.mMcc.equals(other.mMcc) &&
+ this.mMnc.equals(other.mMnc) &&
+ this.mImsi.equals(other.mImsi) &&
+ this.mHomeSpFqdn.equals(other.mHomeSpFqdn);
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ /** @hide */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ String none = "<none>";
+
+ if (!DBG) {
+ sb.append(none);
+ } else {
+ sb.append(", UpdateIdentifier: ")
+ .append(mUpdateIdentifier == null ? none : mUpdateIdentifier)
+ .append(", SubscriptionUpdateMethod: ")
+ .append(mSubscriptionUpdateMethod == null ? none : mSubscriptionUpdateMethod)
+ .append(", Type: ").append(mType == null ? none : mType)
+ .append(", Username: ").append(mUsername == null ? none : mUsername)
+ .append(", Passwd: ").append(mPasswd == null ? none : mPasswd)
+ .append(", SubDMAccUsername: ")
+ .append(mSubscriptionUpdateUsername == null ? none : mSubscriptionUpdateUsername)
+ .append(", SubDMAccPassword: ")
+ .append(mSubscriptionUpdatePassword == null ? none : mSubscriptionUpdatePassword)
+ .append(", PolDMAccUsername: ")
+ .append(mPolicyUpdateUsername == null ? none : mPolicyUpdateUsername)
+ .append(", PolDMAccPassword: ")
+ .append(mPolicyUpdatePassword == null ? none : mPolicyUpdatePassword)
+ .append(", Imsi: ").append(mImsi == null ? none : mImsi)
+ .append(", Mcc: ").append(mMcc == null ? none : mMcc)
+ .append(", Mnc: ").append(mMnc == null ? none : mMnc)
+ .append(", CaRootCert: ").append(mCaRootCert == null ? none : mCaRootCert)
+ .append(", Realm: ").append(mRealm == null ? none : mRealm)
+ .append(", Priority: ").append(mCrednetialPriority)
+ .append(", Fqdn: ").append(mHomeSpFqdn == null ? none : mHomeSpFqdn)
+ .append(", Otherhomepartners: ")
+ .append(mOtherHomePartnerList == null ? none : mOtherHomePartnerList)
+ .append(", ExpirationDate: ")
+ .append(mExpirationDate == null ? none : mExpirationDate)
+ .append(", MaxBssLoad: ").append(mMaxBssLoad == null ? none : mMaxBssLoad)
+ .append(", SPExclusionList: ").append(mSpExclusionList);
+
+ if (mPreferredRoamingPartnerList != null) {
+ sb.append("PreferredRoamingPartnerList:");
+ for (WifiPasspointDmTree.PreferredRoamingPartnerList prpListItem : mPreferredRoamingPartnerList) {
+ sb.append("[fqdnmatch:").append(prpListItem.FQDN_Match).
+ append(", priority:").append(prpListItem.Priority).
+ append(", country:").append(prpListItem.Country).append("]");
+ }
+ }
+
+ if (mHomeOIList != null) {
+ sb.append("HomeOIList:");
+ for (WifiPasspointDmTree.HomeOIList HomeOIListItem : mHomeOIList) {
+ sb.append("[HomeOI:").append(HomeOIListItem.HomeOI).
+ append(", HomeOIRequired:").append(HomeOIListItem.HomeOIRequired).
+ append("]");
+ }
+ }
+
+ if (mMinBackhaulThresholdNetwork != null) {
+ sb.append("BackHaulThreshold:");
+ for (WifiPasspointDmTree.MinBackhaulThresholdNetwork BhtListItem : mMinBackhaulThresholdNetwork) {
+ sb.append("[networkType:").append(BhtListItem.NetworkType).
+ append(", dlBandwidth:").append(BhtListItem.DLBandwidth).
+ append(", ulBandwidth:").append(BhtListItem.ULBandwidth).
+ append("]");
+ }
+ }
+
+ if (mRequiredProtoPortTuple != null) {
+ sb.append("WifiMORequiredProtoPortTupleList:");
+ for (WifiPasspointDmTree.RequiredProtoPortTuple RpptListItem : mRequiredProtoPortTuple) {
+ sb.append("[IPProtocol:").append(RpptListItem.IPProtocol).
+ append(", PortNumber:").append(RpptListItem.PortNumber).
+ append("]");
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mWifiSpFqdn);
+ dest.writeString(mCredentialName);
+ dest.writeString(mType);
+ dest.writeInt(mCrednetialPriority);
+ dest.writeString(mHomeSpFqdn);
+ dest.writeString(mRealm);
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public void readFromParcel(Parcel in) {
+ mWifiSpFqdn = in.readString();
+ mCredentialName = in.readString();
+ mType = in.readString();
+ mCrednetialPriority = in.readInt();
+ mHomeSpFqdn = in.readString();
+ mRealm = in.readString();
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Creator<WifiPasspointCredential> CREATOR =
+ new Creator<WifiPasspointCredential>() {
+ public WifiPasspointCredential createFromParcel(Parcel in) {
+ WifiPasspointCredential pc = new WifiPasspointCredential();
+ pc.mWifiSpFqdn = in.readString();
+ pc.mCredentialName = in.readString();
+ pc.mType = in.readString();
+ pc.mCrednetialPriority = in.readInt();
+ pc.mHomeSpFqdn = in.readString();
+ pc.mRealm = in.readString();
+ return pc;
+ }
+
+ public WifiPasspointCredential[] newArray(int size) {
+ return new WifiPasspointCredential[size];
+ }
+ };
+
+ /** @hide */
+ public int compareTo(WifiPasspointCredential another) {
+
+ //The smaller the higher
+ if (mCrednetialPriority < another.mCrednetialPriority) {
+ return -1;
+ } else if (mCrednetialPriority == another.mCrednetialPriority) {
+ return this.mType.compareTo(another.mType);
+ } else {
+ return 1;
+ }
+ }
+
+ @Override
+ /** @hide */
+ public int hashCode() {
+ int hash = 208;
+ if (mType != null) {
+ hash += mType.hashCode();
+ }
+ if (mRealm != null) {
+ hash += mRealm.hashCode();
+ }
+ if (mHomeSpFqdn != null) {
+ hash += mHomeSpFqdn.hashCode();
+ }
+ if (mUsername != null) {
+ hash += mUsername.hashCode();
+ }
+ if (mPasswd != null) {
+ hash += mPasswd.hashCode();
+ }
+
+ return hash;
+ }
+}
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.aidl b/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.aidl
new file mode 100644
index 0000000..6a88b2e
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, 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.passpoint;
+
+parcelable WifiPasspointDmTree;
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.java
new file mode 100644
index 0000000..bbf5fc6
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointDmTree.java
@@ -0,0 +1,1377 @@
+/*
+ * Copyright (C) 2014 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.passpoint;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+import android.util.Log;
+
+import java.util.HashMap;
+
+/**
+ * Required Mobile Device Management Tree Structure
+ *
+ * +----------+
+ * | ./(Root) |
+ * +----+-----+
+ * |
+ * +---------+ | +---------+ +---------+
+ * | DevInfo |-----------+---------| Wi-Fi |--|SP FQDN* |
+ * +---------+ | +---------+ +---------+
+ * +---------+ | |
+ * |DevDetail|-----------+ +-----------------------+
+ * +---------+ |PerproviderSubscription|--<X>+
+ * +-----------------------+
+ *
+ * This class contains all nodes start from Wi-Fi
+ * @hide
+ **/
+public class WifiPasspointDmTree implements Parcelable {
+ private final static String TAG = "WifiTree";
+ public int PpsMoId;//plugfest used only
+ public HashMap<String, SpFqdn> spFqdn = new HashMap<String, SpFqdn>();//Maps.newHashMap();
+
+ public SpFqdn createSpFqdn(String name) {
+ SpFqdn obj = new SpFqdn(name);
+ spFqdn.put(name, obj);
+ return obj;
+ }
+
+ public static class SpFqdn implements Parcelable {
+ public String nodeName;
+ public PerProviderSubscription perProviderSubscription = new PerProviderSubscription();
+
+ public SpFqdn(String name) {
+ nodeName = name;
+ }
+
+ public SpFqdn() {
+ }
+
+ public SpFqdn(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeParcelable(perProviderSubscription, flags);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ perProviderSubscription = in.readParcelable(PerProviderSubscription.class
+ .getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<SpFqdn> CREATOR = new Parcelable.Creator<SpFqdn>() {
+ public SpFqdn createFromParcel(Parcel in) {
+ return new SpFqdn(in);
+ }
+
+ public SpFqdn[] newArray(int size) {
+ return new SpFqdn[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription
+ **/
+ public static class PerProviderSubscription implements Parcelable {
+ /**
+ * PerProviderSubscription/UpdateIdentifier
+ **/
+ public String UpdateIdentifier;
+ public HashMap<String, CredentialInfo> credentialInfo = new HashMap<String, CredentialInfo>();
+
+ public CredentialInfo createCredentialInfo(String name) {
+ CredentialInfo obj = new CredentialInfo(name);
+ credentialInfo.put(name, obj);
+ return obj;
+ }
+
+ public PerProviderSubscription() {
+ }
+
+ public PerProviderSubscription(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(UpdateIdentifier);
+ out.writeMap(credentialInfo);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ UpdateIdentifier = in.readString();
+ in.readMap(credentialInfo, CredentialInfo.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<PerProviderSubscription> CREATOR = new Parcelable.Creator<PerProviderSubscription>() {
+ public PerProviderSubscription createFromParcel(Parcel in) {
+ return new PerProviderSubscription(in);
+ }
+
+ public PerProviderSubscription[] newArray(int size) {
+ return new PerProviderSubscription[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>
+ * This interior node contains the Home SP information, subscription policy, management and credential information.
+ **/
+ public static class CredentialInfo implements Parcelable {
+ public String nodeName;
+ public Policy policy = new Policy();
+ public String credentialPriority;
+ public HashMap<String, AAAServerTrustRoot> aAAServerTrustRoot = new HashMap<String, AAAServerTrustRoot>();
+ public SubscriptionUpdate subscriptionUpdate = new SubscriptionUpdate();
+ public HomeSP homeSP = new HomeSP();
+ public SubscriptionParameters subscriptionParameters = new SubscriptionParameters();
+ public Credential credential = new Credential();
+ public Extension extension = new Extension();
+
+ public CredentialInfo(String nn) {
+ nodeName = nn;
+ }
+
+ public AAAServerTrustRoot createAAAServerTrustRoot(String name, String url, String fp) {
+ AAAServerTrustRoot obj = new AAAServerTrustRoot(name, url, fp);
+ aAAServerTrustRoot.put(name, obj);
+ return obj;
+ }
+
+ public CredentialInfo() {
+ }
+
+ public CredentialInfo(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeParcelable(policy, flags);
+ out.writeString(credentialPriority);
+ out.writeMap(aAAServerTrustRoot);
+ out.writeParcelable(subscriptionUpdate, flags);
+ out.writeParcelable(homeSP, flags);
+ out.writeParcelable(subscriptionParameters, flags);
+ out.writeParcelable(credential, flags);
+ //out.writeParcelable(extension, flags);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ policy = in.readParcelable(Policy.class.getClassLoader());
+ credentialPriority = in.readString();
+ in.readMap(aAAServerTrustRoot, AAAServerTrustRoot.class.getClassLoader());
+ subscriptionUpdate = in.readParcelable(SubscriptionUpdate.class.getClassLoader());
+ homeSP = in.readParcelable(HomeSP.class.getClassLoader());
+ subscriptionParameters = in.readParcelable(SubscriptionParameters.class
+ .getClassLoader());
+ credential = in.readParcelable(Credential.class.getClassLoader());
+ //extension = in.readParcelable(Extension.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<CredentialInfo> CREATOR = new Parcelable.Creator<CredentialInfo>() {
+ public CredentialInfo createFromParcel(Parcel in) {
+ return new CredentialInfo(in);
+ }
+
+ public CredentialInfo[] newArray(int size) {
+ return new CredentialInfo[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy
+ **/
+ public static class Policy implements Parcelable {
+ public HashMap<String, PreferredRoamingPartnerList> preferredRoamingPartnerList = new HashMap<String, PreferredRoamingPartnerList>();
+ public HashMap<String, MinBackhaulThresholdNetwork> minBackhaulThreshold = new HashMap<String, MinBackhaulThresholdNetwork>();
+ public PolicyUpdate policyUpdate = new PolicyUpdate();
+ public HashMap<String, SPExclusionList> sPExclusionList = new HashMap<String, SPExclusionList>();
+ public HashMap<String, RequiredProtoPortTuple> requiredProtoPortTuple = new HashMap<String, RequiredProtoPortTuple>();
+ public String maximumBSSLoadValue;
+
+ public PreferredRoamingPartnerList createPreferredRoamingPartnerList(String name,
+ String fqdn, String priority, String country) {
+ PreferredRoamingPartnerList obj = new PreferredRoamingPartnerList(name, fqdn, priority,
+ country);
+ preferredRoamingPartnerList.put(name, obj);
+ return obj;
+ }
+
+ public MinBackhaulThresholdNetwork createMinBackhaulThreshold(String name, String type,
+ String dl, String ul) {
+ MinBackhaulThresholdNetwork obj = new MinBackhaulThresholdNetwork(name, type, dl, ul);
+ minBackhaulThreshold.put(name, obj);
+ return obj;
+ }
+
+ public SPExclusionList createSPExclusionList(String name, String ssid) {
+ SPExclusionList obj = new SPExclusionList(name, ssid);
+ sPExclusionList.put(name, obj);
+ return obj;
+ }
+
+ public RequiredProtoPortTuple createRequiredProtoPortTuple(String name, String proto,
+ String port) {
+ RequiredProtoPortTuple obj = new RequiredProtoPortTuple(name, proto, port);
+ requiredProtoPortTuple.put(name, obj);
+ return obj;
+ }
+
+ public Policy() {
+ }
+
+ public Policy(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeMap(preferredRoamingPartnerList);
+ out.writeMap(minBackhaulThreshold);
+ out.writeParcelable(policyUpdate, flags);
+ out.writeMap(sPExclusionList);
+ out.writeMap(requiredProtoPortTuple);
+ out.writeString(maximumBSSLoadValue);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ in.readMap(preferredRoamingPartnerList,
+ PreferredRoamingPartnerList.class.getClassLoader());
+ in.readMap(minBackhaulThreshold, MinBackhaulThresholdNetwork.class.getClassLoader());
+ policyUpdate = in.readParcelable(PolicyUpdate.class.getClassLoader());
+ in.readMap(sPExclusionList, SPExclusionList.class.getClassLoader());
+ in.readMap(requiredProtoPortTuple, RequiredProtoPortTuple.class.getClassLoader());
+ maximumBSSLoadValue = in.readString();
+
+ }
+ }
+
+ public static final Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() {
+ public Policy createFromParcel(Parcel in) {
+ return new Policy(in);
+ }
+
+ public Policy[] newArray(int size) {
+ return new Policy[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy/PreferredRoamingPartnerList/<X+>
+ **/
+ public static class PreferredRoamingPartnerList implements Parcelable {
+ public String nodeName;
+ public String FQDN_Match; //maximum 255 + ",includeSubdomains", equals 273
+ public String Priority;
+ public String Country; // maximum 600 octets
+
+ public PreferredRoamingPartnerList(String nn, String f, String p, String c) {
+ nodeName = nn;
+ FQDN_Match = f;
+ Priority = p;
+ Country = c;
+ }
+
+ public PreferredRoamingPartnerList() {
+ }
+
+ public PreferredRoamingPartnerList(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(FQDN_Match);
+ out.writeString(Priority);
+ out.writeString(Country);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ FQDN_Match = in.readString();
+ Priority = in.readString();
+ Country = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<PreferredRoamingPartnerList> CREATOR = new Parcelable.Creator<PreferredRoamingPartnerList>() {
+ public PreferredRoamingPartnerList createFromParcel(Parcel in) {
+ return new PreferredRoamingPartnerList(in);
+ }
+
+ public PreferredRoamingPartnerList[] newArray(int size) {
+ return new PreferredRoamingPartnerList[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy/MinBackhaulThreshold
+ **/
+ public static class MinBackhaulThresholdNetwork implements Parcelable {
+ public String nodeName;
+ public String NetworkType;
+ public String DLBandwidth;
+ public String ULBandwidth;
+
+ public MinBackhaulThresholdNetwork(String nn, String nt, String d, String u) {
+ nodeName = nn;
+ NetworkType = nt;
+ DLBandwidth = d;
+ ULBandwidth = u;
+ }
+
+ public MinBackhaulThresholdNetwork() {
+ }
+
+ public MinBackhaulThresholdNetwork(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(NetworkType);
+ out.writeString(DLBandwidth);
+ out.writeString(ULBandwidth);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ NetworkType = in.readString();
+ DLBandwidth = in.readString();
+ ULBandwidth = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<MinBackhaulThresholdNetwork> CREATOR = new Parcelable.Creator<MinBackhaulThresholdNetwork>() {
+ public MinBackhaulThresholdNetwork createFromParcel(Parcel in) {
+ return new MinBackhaulThresholdNetwork(in);
+ }
+
+ public MinBackhaulThresholdNetwork[] newArray(int size) {
+ return new MinBackhaulThresholdNetwork[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy/PolicyUpdate
+ **/
+ public static class PolicyUpdate implements Parcelable {
+ public String UpdateInterval;
+ public String UpdateMethod;
+ public String Restriction;
+ public String URI;
+ public UsernamePassword usernamePassword = new UsernamePassword();
+ public String Other;
+ public TrustRoot trustRoot = new TrustRoot();
+
+ public PolicyUpdate() {
+ }
+
+ public PolicyUpdate(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(UpdateInterval);
+ out.writeString(UpdateMethod);
+ out.writeString(Restriction);
+ out.writeString(URI);
+ out.writeParcelable(usernamePassword, flags);
+ out.writeString(Other);
+ out.writeParcelable(trustRoot, flags);
+
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ UpdateInterval = in.readString();
+ UpdateMethod = in.readString();
+ Restriction = in.readString();
+ URI = in.readString();
+ usernamePassword = in.readParcelable(UsernamePassword.class.getClassLoader());
+ Other = in.readString();
+ trustRoot = in.readParcelable(TrustRoot.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<PolicyUpdate> CREATOR = new Parcelable.Creator<PolicyUpdate>() {
+ public PolicyUpdate createFromParcel(Parcel in) {
+ return new PolicyUpdate(in);
+ }
+
+ public PolicyUpdate[] newArray(int size) {
+ return new PolicyUpdate[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy/SPExclusionList
+ **/
+ public static class SPExclusionList implements Parcelable {
+ public String nodeName;
+ public String SSID;
+
+ public SPExclusionList(String nn, String s) {
+ nodeName = nn;
+ SSID = s;
+ }
+
+ public SPExclusionList() {
+ }
+
+ public SPExclusionList(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(SSID);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ SSID = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<SPExclusionList> CREATOR = new Parcelable.Creator<SPExclusionList>() {
+ public SPExclusionList createFromParcel(Parcel in) {
+ return new SPExclusionList(in);
+ }
+
+ public SPExclusionList[] newArray(int size) {
+ return new SPExclusionList[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy/RequiredProtoPortTuple
+ **/
+ public static class RequiredProtoPortTuple implements Parcelable {
+ public String nodeName;
+ public String IPProtocol;
+ public String PortNumber;
+
+ public RequiredProtoPortTuple() {
+ }
+
+ public RequiredProtoPortTuple(String nn, String protocol, String port) {
+ nodeName = nn;
+ IPProtocol = protocol;
+ PortNumber = port;
+ }
+
+ public RequiredProtoPortTuple(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(IPProtocol);
+ out.writeString(PortNumber);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ IPProtocol = in.readString();
+ PortNumber = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<RequiredProtoPortTuple> CREATOR = new Parcelable.Creator<RequiredProtoPortTuple>() {
+ public RequiredProtoPortTuple createFromParcel(Parcel in) {
+ return new RequiredProtoPortTuple(in);
+ }
+
+ public RequiredProtoPortTuple[] newArray(int size) {
+ return new RequiredProtoPortTuple[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/AAAServerTrustRoot
+ **/
+ public static class AAAServerTrustRoot implements Parcelable {
+ public String nodeName;
+ public String CertURL;
+ public String CertSHA256Fingerprint;
+
+ public AAAServerTrustRoot(String nn, String url, String fp) {
+ nodeName = nn;
+ CertURL = url;
+ CertSHA256Fingerprint = fp;
+ }
+
+ public AAAServerTrustRoot() {
+ }
+
+ public AAAServerTrustRoot(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(CertURL);
+ out.writeString(CertSHA256Fingerprint);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ CertURL = in.readString();
+ CertSHA256Fingerprint = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<AAAServerTrustRoot> CREATOR = new Parcelable.Creator<AAAServerTrustRoot>() {
+ public AAAServerTrustRoot createFromParcel(Parcel in) {
+ return new AAAServerTrustRoot(in);
+ }
+
+ public AAAServerTrustRoot[] newArray(int size) {
+ return new AAAServerTrustRoot[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/SubscriptionUpdate
+ **/
+ public static class SubscriptionUpdate implements Parcelable {
+ public String UpdateInterval;
+ public String UpdateMethod;
+ public String Restriction;
+ public String URI;
+ public UsernamePassword usernamePassword = new UsernamePassword();
+ public String Other;
+ public TrustRoot trustRoot = new TrustRoot();
+
+ public SubscriptionUpdate() {
+ }
+
+ public SubscriptionUpdate(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(UpdateInterval);
+ out.writeString(UpdateMethod);
+ out.writeString(Restriction);
+ out.writeString(URI);
+ out.writeParcelable(usernamePassword, flags);
+ out.writeString(Other);
+ out.writeParcelable(trustRoot, flags);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ UpdateInterval = in.readString();
+ UpdateMethod = in.readString();
+ Restriction = in.readString();
+ URI = in.readString();
+ usernamePassword = in.readParcelable(UsernamePassword.class.getClassLoader());
+ Other = in.readString();
+ trustRoot = in.readParcelable(TrustRoot.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<SubscriptionUpdate> CREATOR = new Parcelable.Creator<SubscriptionUpdate>() {
+ public SubscriptionUpdate createFromParcel(Parcel in) {
+ return new SubscriptionUpdate(in);
+ }
+
+ public SubscriptionUpdate[] newArray(int size) {
+ return new SubscriptionUpdate[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy/PolicyUpdate/TrustRoot
+ * PerProviderSubscription/<X+>/SubscriptionUpdate/TrustRoot
+ * PerProviderSubscription/<X+>/AAAServerTrustRoot/<X+>
+ **/
+ public static class TrustRoot implements Parcelable {
+ public String CertURL;
+ public String CertSHA256Fingerprint;
+
+ public TrustRoot() {
+ }
+
+ public TrustRoot(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(CertURL);
+ out.writeString(CertSHA256Fingerprint);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ CertURL = in.readString();
+ CertSHA256Fingerprint = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<TrustRoot> CREATOR = new Parcelable.Creator<TrustRoot>() {
+ public TrustRoot createFromParcel(Parcel in) {
+ return new TrustRoot(in);
+ }
+
+ public TrustRoot[] newArray(int size) {
+ return new TrustRoot[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Policy/PolicyUpdate/UsernamePassword
+ * PerProviderSubscription/<X+>/SubscriptionUpdate/UsernamePassword
+ * PerProviderSubscription/<X+>/Credential/UsernamePassword
+ **/
+ public static class UsernamePassword implements Parcelable {
+ public String Username;
+ public String Password;
+ //following are Credential node used only
+ public boolean MachineManaged;
+ public String SoftTokenApp;
+ public String AbleToShare;
+ public EAPMethod eAPMethod = new EAPMethod();
+
+ public UsernamePassword() {
+ }
+
+ public UsernamePassword(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(Username);
+ out.writeString(Password);
+ out.writeInt(MachineManaged ? 1 : 0);
+ out.writeString(SoftTokenApp);
+ out.writeString(AbleToShare);
+ out.writeParcelable(eAPMethod, flags);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ Username = in.readString();
+ Password = in.readString();
+ MachineManaged = (in.readInt() == 1) ? true : false;
+ SoftTokenApp = in.readString();
+ AbleToShare = in.readString();
+ eAPMethod = in.readParcelable(EAPMethod.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<UsernamePassword> CREATOR = new Parcelable.Creator<UsernamePassword>() {
+ public UsernamePassword createFromParcel(Parcel in) {
+ return new UsernamePassword(in);
+ }
+
+ public UsernamePassword[] newArray(int size) {
+ return new UsernamePassword[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Credential/UsernamePassword/EAPMethod
+ **/
+ public static class EAPMethod implements Parcelable {
+ public String EAPType;
+ public String VendorId;
+ public String VendorType;
+ public String InnerEAPType;
+ public String InnerVendorId;
+ public String InnerVendorType;
+ public String InnerMethod;
+
+ public EAPMethod() {
+ }
+
+ public EAPMethod(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(EAPType);
+ out.writeString(VendorId);
+ out.writeString(VendorType);
+ out.writeString(InnerEAPType);
+ out.writeString(InnerVendorId);
+ out.writeString(InnerVendorType);
+ out.writeString(InnerMethod);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ EAPType = in.readString();
+ VendorId = in.readString();
+ VendorType = in.readString();
+ InnerEAPType = in.readString();
+ InnerVendorId = in.readString();
+ InnerVendorType = in.readString();
+ InnerMethod = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<EAPMethod> CREATOR = new Parcelable.Creator<EAPMethod>() {
+ public EAPMethod createFromParcel(Parcel in) {
+ return new EAPMethod(in);
+ }
+
+ public EAPMethod[] newArray(int size) {
+ return new EAPMethod[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/HomeSP
+ **/
+ public static class HomeSP implements Parcelable {
+ public HashMap<String, NetworkID> networkID = new HashMap<String, NetworkID>();
+ public String FriendlyName;
+ public String IconURL;
+ public String FQDN;
+ public HashMap<String, HomeOIList> homeOIList = new HashMap<String, HomeOIList>();
+ public HashMap<String, OtherHomePartners> otherHomePartners = new HashMap<String, OtherHomePartners>();
+ public String RoamingConsortiumOI;
+
+ public NetworkID createNetworkID(String name, String ssid, String hessid) {
+ NetworkID obj = new NetworkID(name, ssid, hessid);
+ networkID.put(name, obj);
+ return obj;
+ }
+
+ public HomeOIList createHomeOIList(String name, String homeoi, boolean required) {
+ HomeOIList obj = new HomeOIList(name, homeoi, required);
+ homeOIList.put(name, obj);
+ return obj;
+ }
+
+ public OtherHomePartners createOtherHomePartners(String name, String fqdn) {
+ OtherHomePartners obj = new OtherHomePartners(name, fqdn);
+ otherHomePartners.put(name, obj);
+ return obj;
+ }
+
+ public HomeSP() {
+ }
+
+ public HomeSP(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeMap(networkID);
+ out.writeString(FriendlyName);
+ out.writeString(IconURL);
+ out.writeString(FQDN);
+ out.writeMap(homeOIList);
+ out.writeMap(otherHomePartners);
+ out.writeString(RoamingConsortiumOI);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ in.readMap(networkID, NetworkID.class.getClassLoader());
+ FriendlyName = in.readString();
+ IconURL = in.readString();
+ FQDN = in.readString();
+ in.readMap(homeOIList, HomeOIList.class.getClassLoader());
+ in.readMap(otherHomePartners, OtherHomePartners.class.getClassLoader());
+ RoamingConsortiumOI = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<HomeSP> CREATOR = new Parcelable.Creator<HomeSP>() {
+ public HomeSP createFromParcel(Parcel in) {
+ return new HomeSP(in);
+ }
+
+ public HomeSP[] newArray(int size) {
+ return new HomeSP[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/HomeSP/NetworkID
+ **/
+ public static class NetworkID implements Parcelable {
+ public String nodeName;
+ public String SSID;
+ public String HESSID;
+
+ public NetworkID(String nn, String s, String h) {
+ nodeName = nn;
+ SSID = s;
+ HESSID = h;
+ }
+
+ public NetworkID() {
+ }
+
+ public NetworkID(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(SSID);
+ out.writeString(HESSID);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ SSID = in.readString();
+ HESSID = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<NetworkID> CREATOR = new Parcelable.Creator<NetworkID>() {
+ public NetworkID createFromParcel(Parcel in) {
+ return new NetworkID(in);
+ }
+
+ public NetworkID[] newArray(int size) {
+ return new NetworkID[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/HomeSP/HomeOIList
+ **/
+ public static class HomeOIList implements Parcelable {
+ public String nodeName;
+ public String HomeOI;
+ public boolean HomeOIRequired;
+
+ public HomeOIList(String nn, String h, boolean r) {
+ nodeName = nn;
+ HomeOI = h;
+ HomeOIRequired = r;
+ }
+
+ public HomeOIList() {
+ }
+
+ public HomeOIList(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(HomeOI);
+ out.writeInt(HomeOIRequired ? 1 : 0);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ HomeOI = in.readString();
+ HomeOIRequired = (in.readInt() == 1) ? true : false;
+ }
+ }
+
+ public static final Parcelable.Creator<HomeOIList> CREATOR = new Parcelable.Creator<HomeOIList>() {
+ public HomeOIList createFromParcel(Parcel in) {
+ return new HomeOIList(in);
+ }
+
+ public HomeOIList[] newArray(int size) {
+ return new HomeOIList[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/HomeSP/OtherHomePartners
+ **/
+ public static class OtherHomePartners implements Parcelable {
+ public String nodeName;
+ public String FQDN;
+
+ public OtherHomePartners(String nn, String f) {
+ nodeName = nn;
+ FQDN = f;
+ }
+
+ public OtherHomePartners() {
+ }
+
+ public OtherHomePartners(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(nodeName);
+ out.writeString(FQDN);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ nodeName = in.readString();
+ FQDN = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<OtherHomePartners> CREATOR = new Parcelable.Creator<OtherHomePartners>() {
+ public OtherHomePartners createFromParcel(Parcel in) {
+ return new OtherHomePartners(in);
+ }
+
+ public OtherHomePartners[] newArray(int size) {
+ return new OtherHomePartners[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/SubscriptionParameters
+ **/
+ public static class SubscriptionParameters implements Parcelable {
+ public String CreationDate;
+ public String ExpirationDate;
+ public String TypeOfSubscription;
+ public UsageLimits usageLimits = new UsageLimits();
+
+ public SubscriptionParameters() {
+ }
+
+ public SubscriptionParameters(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(CreationDate);
+ out.writeString(ExpirationDate);
+ out.writeString(TypeOfSubscription);
+ out.writeParcelable(usageLimits, flags);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ CreationDate = in.readString();
+ ExpirationDate = in.readString();
+ TypeOfSubscription = in.readString();
+ usageLimits = in.readParcelable(UsageLimits.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<SubscriptionParameters> CREATOR = new Parcelable.Creator<SubscriptionParameters>() {
+ public SubscriptionParameters createFromParcel(Parcel in) {
+ return new SubscriptionParameters(in);
+ }
+
+ public SubscriptionParameters[] newArray(int size) {
+ return new SubscriptionParameters[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/SubscriptionParameters/UsageLimits
+ **/
+ public static class UsageLimits implements Parcelable {
+ public String DataLimit;
+ public String StartDate;
+ public String TimeLimit;
+ public String UsageTimePeriod;
+
+ public UsageLimits() {
+ }
+
+ public UsageLimits(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(DataLimit);
+ out.writeString(StartDate);
+ out.writeString(TimeLimit);
+ out.writeString(UsageTimePeriod);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ DataLimit = in.readString();
+ StartDate = in.readString();
+ TimeLimit = in.readString();
+ UsageTimePeriod = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<UsageLimits> CREATOR = new Parcelable.Creator<UsageLimits>() {
+ public UsageLimits createFromParcel(Parcel in) {
+ return new UsageLimits(in);
+ }
+
+ public UsageLimits[] newArray(int size) {
+ return new UsageLimits[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Credential
+ **/
+ public static class Credential implements Parcelable {
+ public String CreationDate;
+ public String ExpirationDate;
+ public UsernamePassword usernamePassword = new UsernamePassword();
+ public DigitalCertificate digitalCertificate = new DigitalCertificate();
+ public String Realm;
+ public boolean CheckAAAServerCertStatus;
+ public SIM sim = new SIM();
+
+ public Credential() {
+ }
+
+ public Credential(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(CreationDate);
+ out.writeString(ExpirationDate);
+ out.writeParcelable(usernamePassword, flags);
+ out.writeParcelable(digitalCertificate, flags);
+ out.writeString(Realm);
+ out.writeInt(CheckAAAServerCertStatus ? 1 : 0);
+ out.writeParcelable(sim, flags);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ CreationDate = in.readString();
+ ExpirationDate = in.readString();
+ usernamePassword = in.readParcelable(UsernamePassword.class.getClassLoader());
+ digitalCertificate = in.readParcelable(DigitalCertificate.class.getClassLoader());
+ Realm = in.readString();
+ CheckAAAServerCertStatus = (in.readInt() == 1) ? true : false;
+ sim = in.readParcelable(SIM.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<Credential> CREATOR = new Parcelable.Creator<Credential>() {
+ public Credential createFromParcel(Parcel in) {
+ return new Credential(in);
+ }
+
+ public Credential[] newArray(int size) {
+ return new Credential[size];
+ }
+ };
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Credential/DigitalCertificate
+ **/
+ public static class DigitalCertificate implements Parcelable {
+ public String CertificateType;
+ public String CertSHA256Fingerprint;
+
+ public DigitalCertificate() {
+ }
+
+ public DigitalCertificate(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(CertificateType);
+ out.writeString(CertSHA256Fingerprint);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ CertificateType = in.readString();
+ CertSHA256Fingerprint = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<DigitalCertificate> CREATOR = new Parcelable.Creator<DigitalCertificate>() {
+ public DigitalCertificate createFromParcel(Parcel in) {
+ return new DigitalCertificate(in);
+ }
+
+ public DigitalCertificate[] newArray(int size) {
+ return new DigitalCertificate[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Credential/SIM
+ **/
+ public static class SIM implements Parcelable {
+ public String IMSI;
+ public String EAPType;
+
+ public SIM() {
+ }
+
+ public SIM(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(IMSI);
+ out.writeString(EAPType);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ IMSI = in.readString();
+ EAPType = in.readString();
+ }
+ }
+
+ public static final Parcelable.Creator<SIM> CREATOR = new Parcelable.Creator<SIM>() {
+ public SIM createFromParcel(Parcel in) {
+ return new SIM(in);
+ }
+
+ public SIM[] newArray(int size) {
+ return new SIM[size];
+ }
+ };
+
+ }
+
+ /**
+ * PerProviderSubscription/<X+>/Extension
+ **/
+ public static class Extension {
+ public String empty;
+ }
+
+ public WifiPasspointDmTree() {
+ }
+
+ public WifiPasspointDmTree(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeMap(spFqdn);
+ }
+
+ public void readFromParcel(Parcel in) {
+ if (in == null) {
+ //log here
+ } else {
+ in.readMap(spFqdn, SpFqdn.class.getClassLoader());
+ }
+ }
+
+ public static final Parcelable.Creator<WifiPasspointDmTree> CREATOR = new Parcelable.Creator<WifiPasspointDmTree>() {
+ public WifiPasspointDmTree createFromParcel(Parcel in) {
+ return new WifiPasspointDmTree(in);
+ }
+
+ public WifiPasspointDmTree[] newArray(int size) {
+ return new WifiPasspointDmTree[size];
+ }
+ };
+
+}
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.aidl b/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.aidl
new file mode 100644
index 0000000..27f23bc
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, 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.passpoint;
+
+parcelable WifiPasspointInfo;
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.java
new file mode 100644
index 0000000..33db3f5
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointInfo.java
@@ -0,0 +1,559 @@
+/*
+ * Copyright (C) 2014 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.passpoint;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** @hide */
+public class WifiPasspointInfo implements Parcelable {
+
+ /** TODO doc */
+ public static final int ANQP_CAPABILITY = 1 << 0;
+
+ /** TODO doc */
+ public static final int VENUE_NAME = 1 << 1;
+
+ /** TODO doc */
+ public static final int NETWORK_AUTH_TYPE = 1 << 2;
+
+ /** TODO doc */
+ public static final int ROAMING_CONSORTIUM = 1 << 3;
+
+ /** TODO doc */
+ public static final int IP_ADDR_TYPE_AVAILABILITY = 1 << 4;
+
+ /** TODO doc */
+ public static final int NAI_REALM = 1 << 5;
+
+ /** TODO doc */
+ public static final int CELLULAR_NETWORK = 1 << 6;
+
+ /** TODO doc */
+ public static final int DOMAIN_NAME = 1 << 7;
+
+ /** TODO doc */
+ public static final int HOTSPOT_CAPABILITY = 1 << 8;
+
+ /** TODO doc */
+ public static final int OPERATOR_FRIENDLY_NAME = 1 << 9;
+
+ /** TODO doc */
+ public static final int WAN_METRICS = 1 << 10;
+
+ /** TODO doc */
+ public static final int CONNECTION_CAPABILITY = 1 << 11;
+
+ /** TODO doc */
+ public static final int OSU_PROVIDER = 1 << 12;
+
+ /** TODO doc */
+ public static final int PRESET_CRED_MATCH =
+ ANQP_CAPABILITY |
+ HOTSPOT_CAPABILITY |
+ NAI_REALM |
+ CELLULAR_NETWORK |
+ DOMAIN_NAME;
+
+ /** TODO doc */
+ public static final int PRESET_ALL =
+ ANQP_CAPABILITY |
+ VENUE_NAME |
+ NETWORK_AUTH_TYPE |
+ ROAMING_CONSORTIUM |
+ IP_ADDR_TYPE_AVAILABILITY |
+ NAI_REALM |
+ CELLULAR_NETWORK |
+ DOMAIN_NAME |
+ HOTSPOT_CAPABILITY |
+ OPERATOR_FRIENDLY_NAME |
+ WAN_METRICS |
+ CONNECTION_CAPABILITY |
+ OSU_PROVIDER;
+
+
+ public static class WanMetrics {
+ public static final int STATUS_RESERVED = 0;
+ public static final int STATUS_UP = 1;
+ public static final int STATUS_DOWN = 2;
+ public static final int STATUS_TEST = 3;
+
+ public int wanInfo;
+ public long downlinkSpeed;
+ public long uplinkSpeed;
+ public int downlinkLoad;
+ public int uplinkLoad;
+ public int lmd;
+
+ public int getLinkStatus() {
+ return wanInfo & 0x3;
+ }
+
+ public boolean getSymmetricLink() {
+ return (wanInfo & (1 << 2)) != 0;
+ }
+
+ public boolean getAtCapacity() {
+ return (wanInfo & (1 << 3)) != 0;
+ }
+
+ @Override
+ public String toString() {
+ return wanInfo + "," + downlinkSpeed + "," + uplinkSpeed + "," +
+ downlinkLoad + "," + uplinkLoad + "," + lmd;
+ }
+ }
+
+ public static class IpProtoPort {
+ public static final int STATUS_CLOSED = 0;
+ public static final int STATUS_OPEN = 1;
+ public static final int STATUS_UNKNOWN = 2;
+
+ public int proto;
+ public int port;
+ public int status;
+
+ @Override
+ public String toString() {
+ return proto + "," + port + "," + status;
+ }
+ }
+
+ public static class NetworkAuthType {
+ public static final int TYPE_TERMS_AND_CONDITION = 0;
+ public static final int TYPE_ONLINE_ENROLLMENT = 1;
+ public static final int TYPE_HTTP_REDIRECTION = 2;
+ public static final int TYPE_DNS_REDIRECTION = 3;
+
+ public int type;
+ public String redirectUrl;
+
+ @Override
+ public String toString() {
+ return type + "," + redirectUrl;
+ }
+ }
+
+ public static class IpAddressType {
+ public static final int IPV6_NOT_AVAILABLE = 0;
+ public static final int IPV6_AVAILABLE = 1;
+ public static final int IPV6_UNKNOWN = 2;
+
+ public static final int IPV4_NOT_AVAILABLE = 0;
+ public static final int IPV4_PUBLIC = 1;
+ public static final int IPV4_PORT_RESTRICTED = 2;
+ public static final int IPV4_SINGLE_NAT = 3;
+ public static final int IPV4_DOUBLE_NAT = 4;
+ public static final int IPV4_PORT_RESTRICTED_SINGLE_NAT = 5;
+ public static final int IPV4_PORT_RESTRICTED_DOUBLE_NAT = 6;
+ public static final int IPV4_PORT_UNKNOWN = 7;
+
+ private static final int NULL_VALUE = -1;
+
+ public int availability;
+
+ public int getIpv6Availability() {
+ return availability & 0x3;
+ }
+
+ public int getIpv4Availability() {
+ return (availability & 0xFF) >> 2;
+ }
+
+ @Override
+ public String toString() {
+ return getIpv6Availability() + "," + getIpv4Availability();
+ }
+ }
+
+ public static class NaiRealm {
+ public static final int ENCODING_RFC4282 = 0;
+ public static final int ENCODING_UTF8 = 1;
+
+ public int encoding;
+ public String realm;
+
+ @Override
+ public String toString() {
+ return encoding + "," + realm;
+ }
+ }
+
+ public static class CellularNetwork {
+ public String mcc;
+ public String mnc;
+
+ @Override
+ public String toString() {
+ return mcc + "," + mnc;
+ }
+ }
+
+ /** BSSID */
+ public String bssid;
+
+ /** venue name */
+ public String venueName;
+
+ /** list of network authentication types */
+ public List<NetworkAuthType> networkAuthTypeList;
+
+ /** list of roaming consortium OIs */
+ public List<String> roamingConsortiumList;
+
+ /** IP address availability */
+ public IpAddressType ipAddrTypeAvailability;
+
+ /** list of NAI realm */
+ public List<NaiRealm> naiRealmList;
+
+ /** list of 3GPP cellular network */
+ public List<CellularNetwork> cellularNetworkList;
+
+ /** list of fully qualified domain name (FQDN) */
+ public List<String> domainNameList;
+
+ /** HS 2.0 operator friendly name */
+ public String operatorFriendlyName;
+
+ /** HS 2.0 wan metrics */
+ public WanMetrics wanMetrics;
+
+ /** list of HS 2.0 IP proto port */
+ public List<IpProtoPort> connectionCapabilityList;
+
+ /** list of HS 2.0 OSU providers */
+ public List<WifiPasspointOsuProvider> osuProviderList;
+
+ /**
+ * Convert mask to ANQP subtypes, for supplicant command use.
+ *
+ * @param mask The ANQP subtypes mask.
+ * @return String of ANQP subtypes, good for supplicant command use
+ * @hide
+ */
+ public static String toAnqpSubtypes(int mask) {
+ StringBuilder sb = new StringBuilder();
+ if ((mask & ANQP_CAPABILITY) != 0)
+ sb.append("257,");
+ if ((mask & VENUE_NAME) != 0)
+ sb.append("258,");
+ if ((mask & NETWORK_AUTH_TYPE) != 0)
+ sb.append("260,");
+ if ((mask & ROAMING_CONSORTIUM) != 0)
+ sb.append("261,");
+ if ((mask & IP_ADDR_TYPE_AVAILABILITY) != 0)
+ sb.append("262,");
+ if ((mask & NAI_REALM) != 0)
+ sb.append("263,");
+ if ((mask & CELLULAR_NETWORK) != 0)
+ sb.append("264,");
+ if ((mask & DOMAIN_NAME) != 0)
+ sb.append("268,");
+ if ((mask & HOTSPOT_CAPABILITY) != 0)
+ sb.append("hs20:2,");
+ if ((mask & OPERATOR_FRIENDLY_NAME) != 0)
+ sb.append("hs20:3,");
+ if ((mask & WAN_METRICS) != 0)
+ sb.append("hs20:4,");
+ if ((mask & CONNECTION_CAPABILITY) != 0)
+ sb.append("hs20:5,");
+ if ((mask & OSU_PROVIDER) != 0)
+ sb.append("hs20:8,");
+ if (sb.length() > 0)
+ sb.deleteCharAt(sb.length() - 1);
+ return sb.toString();
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("BSSID: ").append("(").append(bssid).append(")");
+
+ if (venueName != null)
+ sb.append(" venueName: ").append("(")
+ .append(venueName.replace("\n", "\\n")).append(")");
+
+ if (networkAuthTypeList != null) {
+ sb.append(" networkAuthType: ");
+ for (NetworkAuthType auth : networkAuthTypeList)
+ sb.append("(").append(auth.toString()).append(")");
+ }
+
+ if (roamingConsortiumList != null) {
+ sb.append(" roamingConsortium: ");
+ for (String oi : roamingConsortiumList)
+ sb.append("(").append(oi).append(")");
+ }
+
+ if (ipAddrTypeAvailability != null) {
+ sb.append(" ipAddrTypeAvaibility: ").append("(")
+ .append(ipAddrTypeAvailability.toString()).append(")");
+ }
+
+ if (naiRealmList != null) {
+ sb.append(" naiRealm: ");
+ for (NaiRealm realm : naiRealmList)
+ sb.append("(").append(realm.toString()).append(")");
+ }
+
+ if (cellularNetworkList != null) {
+ sb.append(" cellularNetwork: ");
+ for (CellularNetwork plmn : cellularNetworkList)
+ sb.append("(").append(plmn.toString()).append(")");
+ }
+
+ if (domainNameList != null) {
+ sb.append(" domainName: ");
+ for (String fqdn : domainNameList)
+ sb.append("(").append(fqdn).append(")");
+ }
+
+ if (operatorFriendlyName != null)
+ sb.append(" operatorFriendlyName: ").append("(")
+ .append(operatorFriendlyName).append(")");
+
+ if (wanMetrics != null)
+ sb.append(" wanMetrics: ").append("(")
+ .append(wanMetrics.toString()).append(")");
+
+ if (connectionCapabilityList != null) {
+ sb.append(" connectionCapability: ");
+ for (IpProtoPort ip : connectionCapabilityList)
+ sb.append("(").append(ip.toString()).append(")");
+ }
+
+ if (osuProviderList != null) {
+ sb.append(" osuProviderList: ");
+ for (WifiPasspointOsuProvider osu : osuProviderList)
+ sb.append("(").append(osu.toString()).append(")");
+ }
+
+ return sb.toString();
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(bssid);
+ out.writeString(venueName);
+
+ if (networkAuthTypeList == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(networkAuthTypeList.size());
+ for (NetworkAuthType auth : networkAuthTypeList) {
+ out.writeInt(auth.type);
+ out.writeString(auth.redirectUrl);
+ }
+ }
+
+ if (roamingConsortiumList == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(roamingConsortiumList.size());
+ for (String oi : roamingConsortiumList)
+ out.writeString(oi);
+ }
+
+ if (ipAddrTypeAvailability == null) {
+ out.writeInt(IpAddressType.NULL_VALUE);
+ } else {
+ out.writeInt(ipAddrTypeAvailability.availability);
+ }
+
+ if (naiRealmList == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(naiRealmList.size());
+ for (NaiRealm realm : naiRealmList) {
+ out.writeInt(realm.encoding);
+ out.writeString(realm.realm);
+ }
+ }
+
+ if (cellularNetworkList == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(cellularNetworkList.size());
+ for (CellularNetwork plmn : cellularNetworkList) {
+ out.writeString(plmn.mcc);
+ out.writeString(plmn.mnc);
+ }
+ }
+
+
+ if (domainNameList == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(domainNameList.size());
+ for (String fqdn : domainNameList)
+ out.writeString(fqdn);
+ }
+
+ out.writeString(operatorFriendlyName);
+
+ if (wanMetrics == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(1);
+ out.writeInt(wanMetrics.wanInfo);
+ out.writeLong(wanMetrics.downlinkSpeed);
+ out.writeLong(wanMetrics.uplinkSpeed);
+ out.writeInt(wanMetrics.downlinkLoad);
+ out.writeInt(wanMetrics.uplinkLoad);
+ out.writeInt(wanMetrics.lmd);
+ }
+
+ if (connectionCapabilityList == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(connectionCapabilityList.size());
+ for (IpProtoPort ip : connectionCapabilityList) {
+ out.writeInt(ip.proto);
+ out.writeInt(ip.port);
+ out.writeInt(ip.status);
+ }
+ }
+
+ if (osuProviderList == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(osuProviderList.size());
+ for (WifiPasspointOsuProvider osu : osuProviderList)
+ osu.writeToParcel(out, flags);
+ }
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Parcelable.Creator<WifiPasspointInfo> CREATOR =
+ new Parcelable.Creator<WifiPasspointInfo>() {
+ @Override
+ public WifiPasspointInfo createFromParcel(Parcel in) {
+ WifiPasspointInfo p = new WifiPasspointInfo();
+ int n;
+
+ p.bssid = in.readString();
+ p.venueName = in.readString();
+
+ n = in.readInt();
+ if (n > 0) {
+ p.networkAuthTypeList = new ArrayList<NetworkAuthType>();
+ for (int i = 0; i < n; i++) {
+ NetworkAuthType auth = new NetworkAuthType();
+ auth.type = in.readInt();
+ auth.redirectUrl = in.readString();
+ p.networkAuthTypeList.add(auth);
+ }
+ }
+
+ n = in.readInt();
+ if (n > 0) {
+ p.roamingConsortiumList = new ArrayList<String>();
+ for (int i = 0; i < n; i++)
+ p.roamingConsortiumList.add(in.readString());
+ }
+
+ n = in.readInt();
+ if (n != IpAddressType.NULL_VALUE) {
+ p.ipAddrTypeAvailability = new IpAddressType();
+ p.ipAddrTypeAvailability.availability = n;
+ }
+
+ n = in.readInt();
+ if (n > 0) {
+ p.naiRealmList = new ArrayList<NaiRealm>();
+ for (int i = 0; i < n; i++) {
+ NaiRealm realm = new NaiRealm();
+ realm.encoding = in.readInt();
+ realm.realm = in.readString();
+ p.naiRealmList.add(realm);
+ }
+ }
+
+ n = in.readInt();
+ if (n > 0) {
+ p.cellularNetworkList = new ArrayList<CellularNetwork>();
+ for (int i = 0; i < n; i++) {
+ CellularNetwork plmn = new CellularNetwork();
+ plmn.mcc = in.readString();
+ plmn.mnc = in.readString();
+ p.cellularNetworkList.add(plmn);
+ }
+ }
+
+ n = in.readInt();
+ if (n > 0) {
+ p.domainNameList = new ArrayList<String>();
+ for (int i = 0; i < n; i++)
+ p.domainNameList.add(in.readString());
+ }
+
+ p.operatorFriendlyName = in.readString();
+
+ n = in.readInt();
+ if (n > 0) {
+ p.wanMetrics = new WanMetrics();
+ p.wanMetrics.wanInfo = in.readInt();
+ p.wanMetrics.downlinkSpeed = in.readLong();
+ p.wanMetrics.uplinkSpeed = in.readLong();
+ p.wanMetrics.downlinkLoad = in.readInt();
+ p.wanMetrics.uplinkLoad = in.readInt();
+ p.wanMetrics.lmd = in.readInt();
+ }
+
+ n = in.readInt();
+ if (n > 0) {
+ p.connectionCapabilityList = new ArrayList<IpProtoPort>();
+ for (int i = 0; i < n; i++) {
+ IpProtoPort ip = new IpProtoPort();
+ ip.proto = in.readInt();
+ ip.port = in.readInt();
+ ip.status = in.readInt();
+ p.connectionCapabilityList.add(ip);
+ }
+ }
+
+ n = in.readInt();
+ if (n > 0) {
+ p.osuProviderList = new ArrayList<WifiPasspointOsuProvider>();
+ for (int i = 0; i < n; i++) {
+ WifiPasspointOsuProvider osu = WifiPasspointOsuProvider.CREATOR
+ .createFromParcel(in);
+ p.osuProviderList.add(osu);
+ }
+ }
+
+ return p;
+ }
+
+ @Override
+ public WifiPasspointInfo[] newArray(int size) {
+ return new WifiPasspointInfo[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointManager.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointManager.java
new file mode 100644
index 0000000..b9b17eb
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointManager.java
@@ -0,0 +1,567 @@
+/*
+ * Copyright (C) 2014 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.passpoint;
+
+import android.content.Context;
+import android.net.wifi.ScanResult;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.util.AsyncChannel;
+import com.android.internal.util.Protocol;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Provides APIs for managing Wifi Passpoint credentials.
+ * @hide
+ */
+public class WifiPasspointManager {
+
+ private static final String TAG = "PasspointManager";
+
+ private static final boolean DBG = true;
+
+ /* Passpoint states values */
+
+ /** Passpoint is in an unknown state. This should only occur in boot time */
+ public static final int PASSPOINT_STATE_UNKNOWN = 0;
+
+ /** Passpoint is disabled. This occurs when wifi is disabled */
+ public static final int PASSPOINT_STATE_DISABLED = 1;
+
+ /** Passpoint is enabled and in discovery state */
+ public static final int PASSPOINT_STATE_DISCOVERY = 2;
+
+ /** Passpoint is enabled and in access state */
+ public static final int PASSPOINT_STATE_ACCESS = 3;
+
+ /** Passpoint is enabled and in provisioning state */
+ public static final int PASSPOINT_STATE_PROVISION = 4;
+
+ /* Passpoint callback error codes */
+
+ /** Indicates that the operation failed due to an internal error */
+ public static final int REASON_ERROR = 0;
+
+ /** Indicates that the operation failed because wifi is disabled */
+ public static final int REASON_WIFI_DISABLED = 1;
+
+ /** Indicates that the operation failed because the framework is busy */
+ public static final int REASON_BUSY = 2;
+
+ /** Indicates that the operation failed because parameter is invalid */
+ public static final int REASON_INVALID_PARAMETER = 3;
+
+ /** Indicates that the operation failed because the server is not trusted */
+ public static final int REASON_NOT_TRUSTED = 4;
+
+ /**
+ * protocol supported for Passpoint
+ */
+ public static final String PROTOCOL_DM = "OMA-DM-ClientInitiated";
+
+ /**
+ * protocol supported for Passpoint
+ */
+ public static final String PROTOCOL_SOAP = "SPP-ClientInitiated";
+
+ /* Passpoint broadcasts */
+
+ /**
+ * Broadcast intent action indicating that the state of Passpoint
+ * connectivity has changed
+ */
+ public static final String PASSPOINT_STATE_CHANGED_ACTION =
+ "android.net.wifi.passpoint.STATE_CHANGE";
+
+ /**
+ * Broadcast intent action indicating that the saved Passpoint credential
+ * list has changed
+ */
+ public static final String PASSPOINT_CRED_CHANGED_ACTION =
+ "android.net.wifi.passpoint.CRED_CHANGE";
+
+ /**
+ * Broadcast intent action indicating that Passpoint online sign up is
+ * avaiable.
+ */
+ public static final String PASSPOINT_OSU_AVAILABLE_ACTION =
+ "android.net.wifi.passpoint.OSU_AVAILABLE";
+
+ /**
+ * Broadcast intent action indicating that user remediation is required
+ */
+ public static final String PASSPOINT_USER_REM_REQ_ACTION =
+ "android.net.wifi.passpoint.USER_REM_REQ";
+
+ /**
+ * Interface for callback invocation when framework channel is lost
+ */
+ public interface ChannelListener {
+ /**
+ * The channel to the framework has been disconnected. Application could
+ * try re-initializing using {@link #initialize}
+ */
+ public void onChannelDisconnected();
+ }
+
+ /**
+ * Interface for callback invocation on an application action
+ */
+ public interface ActionListener {
+ /** The operation succeeded */
+ public void onSuccess();
+
+ /**
+ * The operation failed
+ *
+ * @param reason The reason for failure could be one of
+ * {@link #WIFI_DISABLED}, {@link #ERROR} or {@link #BUSY}
+ */
+ public void onFailure(int reason);
+ }
+
+ /**
+ * Interface for callback invocation when doing OSU or user remediation
+ */
+ public interface OsuRemListener {
+ /** The operation succeeded */
+ public void onSuccess();
+
+ /**
+ * The operation failed
+ *
+ * @param reason The reason for failure could be one of
+ * {@link #WIFI_DISABLED}, {@link #ERROR} or {@link #BUSY}
+ */
+ public void onFailure(int reason);
+
+ /**
+ * Browser launch is requried for user interaction. When this callback
+ * is called, app should launch browser / webview to the given URI.
+ *
+ * @param uri URI for browser launch
+ */
+ public void onBrowserLaunch(String uri);
+
+ /**
+ * When this is called, app should dismiss the previously lanched browser.
+ */
+ public void onBrowserDismiss();
+ }
+
+ /**
+ * A channel that connects the application to the wifi passpoint framework.
+ * Most passpoint operations require a Channel as an argument.
+ * An instance of Channel is obtained by doing a call on {@link #initialize}
+ */
+ public static class Channel {
+ private final static int INVALID_LISTENER_KEY = 0;
+
+ private ChannelListener mChannelListener;
+
+ private HashMap<Integer, Object> mListenerMap = new HashMap<Integer, Object>();
+ private HashMap<Integer, Integer> mListenerMapCount = new HashMap<Integer, Integer>();
+ private Object mListenerMapLock = new Object();
+ private int mListenerKey = 0;
+
+ private List<ScanResult> mAnqpRequest = new LinkedList<ScanResult>();
+ private Object mAnqpRequestLock = new Object();
+
+ private AsyncChannel mAsyncChannel;
+ private PasspointHandler mHandler;
+ Context mContext;
+
+ Channel(Context context, Looper looper, ChannelListener l) {
+ mAsyncChannel = new AsyncChannel();
+ mHandler = new PasspointHandler(looper);
+ mChannelListener = l;
+ mContext = context;
+ }
+
+ private int putListener(Object listener) {
+ return putListener(listener, 1);
+ }
+
+ private int putListener(Object listener, int count) {
+ if (listener == null || count <= 0)
+ return INVALID_LISTENER_KEY;
+ int key;
+ synchronized (mListenerMapLock) {
+ do {
+ key = mListenerKey++;
+ } while (key == INVALID_LISTENER_KEY);
+ mListenerMap.put(key, listener);
+ mListenerMapCount.put(key, count);
+ }
+ return key;
+ }
+
+ private Object peekListener(int key) {
+ Log.d(TAG, "peekListener() key=" + key);
+ if (key == INVALID_LISTENER_KEY)
+ return null;
+ synchronized (mListenerMapLock) {
+ return mListenerMap.get(key);
+ }
+ }
+
+
+ private Object getListener(int key, boolean forceRemove) {
+ Log.d(TAG, "getListener() key=" + key + " force=" + forceRemove);
+ if (key == INVALID_LISTENER_KEY)
+ return null;
+ synchronized (mListenerMapLock) {
+ if (!forceRemove) {
+ int count = mListenerMapCount.get(key);
+ Log.d(TAG, "count=" + count);
+ mListenerMapCount.put(key, --count);
+ if (count > 0)
+ return null;
+ }
+ Log.d(TAG, "remove key");
+ mListenerMapCount.remove(key);
+ return mListenerMap.remove(key);
+ }
+ }
+
+ private void anqpRequestStart(ScanResult sr) {
+ Log.d(TAG, "anqpRequestStart sr.bssid=" + sr.BSSID);
+ synchronized (mAnqpRequestLock) {
+ mAnqpRequest.add(sr);
+ }
+ }
+
+ private void anqpRequestFinish(WifiPasspointInfo result) {
+ Log.d(TAG, "anqpRequestFinish pi.bssid=" + result.bssid);
+ synchronized (mAnqpRequestLock) {
+ for (ScanResult sr : mAnqpRequest)
+ if (sr.BSSID.equals(result.bssid)) {
+ Log.d(TAG, "find hit " + result.bssid);
+ sr.passpoint = result;
+ mAnqpRequest.remove(sr);
+ Log.d(TAG, "mAnqpRequest.len=" + mAnqpRequest.size());
+ break;
+ }
+ }
+ }
+
+ private void anqpRequestFinish(ScanResult sr) {
+ Log.d(TAG, "anqpRequestFinish sr.bssid=" + sr.BSSID);
+ synchronized (mAnqpRequestLock) {
+ for (ScanResult sr1 : mAnqpRequest)
+ if (sr1.BSSID.equals(sr.BSSID)) {
+ mAnqpRequest.remove(sr1);
+ break;
+ }
+ }
+ }
+
+ class PasspointHandler extends Handler {
+ PasspointHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message message) {
+ Object listener = null;
+
+ switch (message.what) {
+ case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
+ if (mChannelListener != null) {
+ mChannelListener.onChannelDisconnected();
+ mChannelListener = null;
+ }
+ break;
+
+ case REQUEST_ANQP_INFO_SUCCEEDED:
+ WifiPasspointInfo result = (WifiPasspointInfo) message.obj;
+ anqpRequestFinish(result);
+ listener = getListener(message.arg2, false);
+ if (listener != null) {
+ ((ActionListener) listener).onSuccess();
+ }
+ break;
+
+ case REQUEST_ANQP_INFO_FAILED:
+ anqpRequestFinish((ScanResult) message.obj);
+ listener = getListener(message.arg2, false);
+ if (listener == null)
+ getListener(message.arg2, true);
+ if (listener != null) {
+ ((ActionListener) listener).onFailure(message.arg1);
+ }
+ break;
+
+ case START_OSU_SUCCEEDED:
+ listener = getListener(message.arg2, true);
+ if (listener != null) {
+ ((OsuRemListener) listener).onSuccess();
+ }
+ break;
+
+ case START_OSU_FAILED:
+ listener = getListener(message.arg2, true);
+ if (listener != null) {
+ ((OsuRemListener) listener).onFailure(message.arg1);
+ }
+ break;
+
+ case START_OSU_BROWSER:
+ listener = peekListener(message.arg2);
+ if (listener != null) {
+ ParcelableString str = (ParcelableString) message.obj;
+ if (str == null || str.string == null)
+ ((OsuRemListener) listener).onBrowserDismiss();
+ else
+ ((OsuRemListener) listener).onBrowserLaunch(str.string);
+ }
+ break;
+
+ default:
+ Log.d(TAG, "Ignored " + message);
+ break;
+ }
+ }
+ }
+
+ }
+
+ public static class ParcelableString implements Parcelable {
+ public String string;
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(string);
+ }
+
+ public static final Parcelable.Creator<ParcelableString> CREATOR =
+ new Parcelable.Creator<ParcelableString>() {
+ @Override
+ public ParcelableString createFromParcel(Parcel in) {
+ ParcelableString ret = new ParcelableString();
+ ret.string = in.readString();
+ return ret;
+ }
+ @Override
+ public ParcelableString[] newArray(int size) {
+ return new ParcelableString[size];
+ }
+ };
+ }
+
+ private static final int BASE = Protocol.BASE_WIFI_PASSPOINT_MANAGER;
+
+ public static final int REQUEST_ANQP_INFO = BASE + 1;
+ public static final int REQUEST_ANQP_INFO_FAILED = BASE + 2;
+ public static final int REQUEST_ANQP_INFO_SUCCEEDED = BASE + 3;
+ public static final int REQUEST_OSU_ICON = BASE + 4;
+ public static final int REQUEST_OSU_ICON_FAILED = BASE + 5;
+ public static final int REQUEST_OSU_ICON_SUCCEEDED = BASE + 6;
+ public static final int START_OSU = BASE + 7;
+ public static final int START_OSU_BROWSER = BASE + 8;
+ public static final int START_OSU_FAILED = BASE + 9;
+ public static final int START_OSU_SUCCEEDED = BASE + 10;
+
+ private Context mContext;
+ IWifiPasspointManager mService;
+
+ /**
+ * TODO: doc
+ * @param context
+ * @param service
+ */
+ public WifiPasspointManager(Context context, IWifiPasspointManager service) {
+ mContext = context;
+ mService = service;
+ }
+
+ /**
+ * Registers the application with the framework. This function must be the
+ * first to be called before any async passpoint operations are performed.
+ *
+ * @param srcContext is the context of the source
+ * @param srcLooper is the Looper on which the callbacks are receivied
+ * @param listener for callback at loss of framework communication. Can be
+ * null.
+ * @return Channel instance that is necessary for performing any further
+ * passpoint operations
+ *
+ */
+ public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
+ Messenger messenger = getMessenger();
+ if (messenger == null)
+ return null;
+
+ Channel c = new Channel(srcContext, srcLooper, listener);
+ if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger)
+ == AsyncChannel.STATUS_SUCCESSFUL) {
+ return c;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * STOPSHIP: temp solution, should use supplicant manager instead, check
+ * with b/13931972
+ */
+ public Messenger getMessenger() {
+ try {
+ return mService.getMessenger();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ public int getPasspointState() {
+ try {
+ return mService.getPasspointState();
+ } catch (RemoteException e) {
+ return PASSPOINT_STATE_UNKNOWN;
+ }
+ }
+
+ public void requestAnqpInfo(Channel c, List<ScanResult> requested, int mask,
+ ActionListener listener) {
+ Log.d(TAG, "requestAnqpInfo start");
+ Log.d(TAG, "requested.size=" + requested.size());
+ checkChannel(c);
+ List<ScanResult> list = new ArrayList<ScanResult>();
+ for (ScanResult sr : requested)
+ if (sr.capabilities.contains("[HS20]")) {
+ list.add(sr);
+ c.anqpRequestStart(sr);
+ Log.d(TAG, "adding " + sr.BSSID);
+ }
+ int count = list.size();
+ Log.d(TAG, "after filter, count=" + count);
+ if (count == 0) {
+ if (DBG)
+ Log.d(TAG, "ANQP info request contains no HS20 APs, skipped");
+ listener.onSuccess();
+ return;
+ }
+ int key = c.putListener(listener, count);
+ for (ScanResult sr : list)
+ c.mAsyncChannel.sendMessage(REQUEST_ANQP_INFO, mask, key, sr);
+ Log.d(TAG, "requestAnqpInfo end");
+ }
+
+ public void requestOsuIcons(Channel c, List<WifiPasspointOsuProvider> requested,
+ int resolution, ActionListener listener) {
+ }
+
+ public List<WifiPasspointPolicy> requestCredentialMatch(List<ScanResult> requested) {
+ try {
+ return mService.requestCredentialMatch(requested);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Get a list of saved Passpoint credentials. Only those credentials owned
+ * by the caller will be returned.
+ *
+ * @return The list of credentials
+ */
+ public List<WifiPasspointCredential> getCredentials() {
+ try {
+ return mService.getCredentials();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Add a new Passpoint credential.
+ *
+ * @param cred The credential to be added
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
+ public boolean addCredential(WifiPasspointCredential cred) {
+ try {
+ return mService.addCredential(cred);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Update an existing Passpoint credential. Only system or the owner of this
+ * credential has the permission to do this.
+ *
+ * @param cred The credential to be updated
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
+ public boolean updateCredential(WifiPasspointCredential cred) {
+ try {
+ return mService.updateCredential(cred);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Remove an existing Passpoint credential. Only system or the owner of this
+ * credential has the permission to do this.
+ *
+ * @param cred The credential to be removed
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
+ public boolean removeCredential(WifiPasspointCredential cred) {
+ try {
+ return mService.removeCredential(cred);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ public void startOsu(Channel c, WifiPasspointOsuProvider osu, OsuRemListener listener) {
+ Log.d(TAG, "startOsu start");
+ checkChannel(c);
+ int key = c.putListener(listener);
+ c.mAsyncChannel.sendMessage(START_OSU, 0, key, osu);
+ Log.d(TAG, "startOsu end");
+ }
+
+ public void startRemediation(Channel c, OsuRemListener listener) {
+ }
+
+ public void connect(WifiPasspointPolicy policy) {
+ }
+
+ private static void checkChannel(Channel c) {
+ if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
+ }
+}
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.aidl b/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.aidl
new file mode 100644
index 0000000..088136f
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, 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.passpoint;
+
+parcelable WifiPasspointOsuProvider;
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.java
new file mode 100644
index 0000000..b54b70c
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointOsuProvider.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2014 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.passpoint;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/** @hide */
+public class WifiPasspointOsuProvider implements Parcelable {
+
+ /** TODO: doc
+ * @hide
+ */
+ public static final int OSU_METHOD_UNKNOWN = -1;
+
+ /** TODO: doc
+ * @hide
+ */
+ public static final int OSU_METHOD_OMADM = 0;
+
+ /** TODO: doc
+ * @hide
+ */
+ public static final int OSU_METHOD_SOAP = 1;
+
+ /** TODO: doc */
+ public String ssid;
+
+ /** TODO: doc */
+ public String friendlyName;
+
+ /** TODO: doc
+ * @hide
+ */
+ public String serverUri;
+
+ /** TODO: doc
+ * @hide
+ */
+ public int osuMethod = OSU_METHOD_UNKNOWN;
+
+ /** TODO: doc */
+ public int iconWidth;
+
+ /** TODO: doc */
+ public int iconHeight;
+
+ /** TODO: doc */
+ public String iconType;
+
+ /** TODO: doc */
+ public String iconFileName;
+
+ /** TODO: doc */
+ public Object icon; // TODO: should change to image format
+
+ /** TODO: doc */
+ public String osuNai;
+
+ /** TODO: doc */
+ public String osuService;
+
+ /** default constructor @hide */
+ public WifiPasspointOsuProvider() {
+ // TODO
+ }
+
+ /** copy constructor @hide */
+ public WifiPasspointOsuProvider(WifiPasspointOsuProvider source) {
+ // TODO
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("SSID: ").append("<").append(ssid).append(">");
+ if (friendlyName != null)
+ sb.append(" friendlyName: ").append("<").append(friendlyName).append(">");
+ if (serverUri != null)
+ sb.append(" serverUri: ").append("<").append(serverUri).append(">");
+ sb.append(" osuMethod: ").append("<").append(osuMethod).append(">");
+ if (iconFileName != null) {
+ sb.append(" icon: <").append(iconWidth).append("x")
+ .append(iconHeight).append(" ")
+ .append(iconType).append(" ")
+ .append(iconFileName).append(">");
+ }
+ if (osuNai != null)
+ sb.append(" osuNai: ").append("<").append(osuNai).append(">");
+ if (osuService != null)
+ sb.append(" osuService: ").append("<").append(osuService).append(">");
+ return sb.toString();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(ssid);
+ out.writeString(friendlyName);
+ out.writeString(serverUri);
+ out.writeInt(osuMethod);
+ out.writeInt(iconWidth);
+ out.writeInt(iconHeight);
+ out.writeString(iconType);
+ out.writeString(iconFileName);
+ out.writeString(osuNai);
+ out.writeString(osuService);
+ // TODO: icon image?
+ }
+
+ public static final Parcelable.Creator<WifiPasspointOsuProvider> CREATOR =
+ new Parcelable.Creator<WifiPasspointOsuProvider>() {
+ @Override
+ public WifiPasspointOsuProvider createFromParcel(Parcel in) {
+ WifiPasspointOsuProvider osu = new WifiPasspointOsuProvider();
+ osu.ssid = in.readString();
+ osu.friendlyName = in.readString();
+ osu.serverUri = in.readString();
+ osu.osuMethod = in.readInt();
+ osu.iconWidth = in.readInt();
+ osu.iconHeight = in.readInt();
+ osu.iconType = in.readString();
+ osu.iconFileName = in.readString();
+ osu.osuNai = in.readString();
+ osu.osuService = in.readString();
+ return osu;
+ }
+
+ @Override
+ public WifiPasspointOsuProvider[] newArray(int size) {
+ return new WifiPasspointOsuProvider[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.aidl b/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.aidl
new file mode 100644
index 0000000..1d61da0
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, 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.passpoint;
+
+parcelable WifiPasspointPolicy;
diff --git a/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.java b/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.java
new file mode 100644
index 0000000..f84ac88
--- /dev/null
+++ b/wifi/java/android/net/wifi/passpoint/WifiPasspointPolicy.java
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2014 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.passpoint;
+
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.ScanResult;
+import android.os.Parcelable;
+import android.os.Parcel;
+import android.security.Credentials;
+import android.util.Log;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+
+
+/** @hide */
+public class WifiPasspointPolicy implements Parcelable {
+
+ private final static String TAG = "PasspointPolicy";
+
+ /** @hide */
+ public static final int HOME_SP = 0;
+
+ /** @hide */
+ public static final int ROAMING_PARTNER = 1;
+
+ /** @hide */
+ public static final int UNRESTRICTED = 2;
+
+ private String mName;
+ private int mCredentialPriority;
+ private int mRoamingPriority;
+ private String mBssid;
+ private String mSsid;
+ private WifiPasspointCredential mCredential;
+ private int mRestriction;// Permitted values are "HomeSP", "RoamingPartner", or "Unrestricted"
+ private boolean mIsHomeSp;
+
+ private final String INT_PRIVATE_KEY = "private_key";
+ private final String INT_PHASE2 = "phase2";
+ private final String INT_PASSWORD = "password";
+ private final String INT_IDENTITY = "identity";
+ private final String INT_EAP = "eap";
+ private final String INT_CLIENT_CERT = "client_cert";
+ private final String INT_CA_CERT = "ca_cert";
+ private final String INT_ANONYMOUS_IDENTITY = "anonymous_identity";
+ private final String INT_SIM_SLOT = "sim_slot";
+ private final String INT_ENTERPRISEFIELD_NAME ="android.net.wifi.WifiConfiguration$EnterpriseField";
+ private final String ISO8601DATEFORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
+ private final String ENTERPRISE_PHASE2_MSCHAPV2 = "auth=MSCHAPV2";
+ private final String ENTERPRISE_PHASE2_MSCHAP = "auth=MSCHAP";
+
+ /** @hide */
+ public WifiPasspointPolicy(String name, String ssid,
+ String bssid, WifiPasspointCredential pc,
+ int restriction, boolean ishomesp) {
+ mName = name;
+ if (pc != null) {
+ mCredentialPriority = pc.getPriority();
+ }
+ //PerProviderSubscription/<X+>/Policy/PreferredRoamingPartnerList/<X+>/Priority
+ mRoamingPriority = 128; //default priority value of 128
+ mSsid = ssid;
+ mCredential = pc;
+ mBssid = bssid;
+ mRestriction = restriction;
+ mIsHomeSp = ishomesp;
+ }
+
+ public String getSsid() {
+ return mSsid;
+ }
+
+ /** @hide */
+ public void setBssid(String bssid) {
+ mBssid = bssid;
+ }
+
+ public String getBssid() {
+ return mBssid;
+ }
+
+ /** @hide */
+ public void setRestriction(int r) {
+ mRestriction = r;
+ }
+
+ /** @hide */
+ public int getRestriction() {
+ return mRestriction;
+ }
+
+ /** @hide */
+ public void setHomeSp(boolean b) {
+ mIsHomeSp = b;
+ }
+
+ /** @hide */
+ public boolean isHomeSp() {
+ return mIsHomeSp;
+ }
+
+ /** @hide */
+ public void setCredential(WifiPasspointCredential newCredential) {
+ mCredential = newCredential;
+ }
+
+ public WifiPasspointCredential getCredential() {
+ // TODO: return a copy
+ return mCredential;
+ }
+
+ /** @hide */
+ public void setCredentialPriority(int priority) {
+ mCredentialPriority = priority;
+ }
+
+ /** @hide */
+ public void setRoamingPriority(int priority) {
+ mRoamingPriority = priority;
+ }
+
+ public int getCredentialPriority() {
+ return mCredentialPriority;
+ }
+
+ public int getRoamingPriority() {
+ return mRoamingPriority;
+ }
+
+ public WifiConfiguration createWifiConfiguration() {
+ WifiConfiguration wfg = new WifiConfiguration();
+ if (mBssid != null) {
+ Log.d(TAG, "create bssid:" + mBssid);
+ wfg.BSSID = mBssid;
+ }
+
+ if (mSsid != null) {
+ Log.d(TAG, "create ssid:" + mSsid);
+ wfg.SSID = mSsid;
+ }
+ //TODO: 1. add pmf configuration
+ // 2. add ocsp configuration
+ // 3. add eap-sim configuration
+ /*Key management*/
+ wfg.status = WifiConfiguration.Status.ENABLED;
+ wfg.allowedKeyManagement.clear();
+ wfg.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
+ wfg.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
+
+ /*Group Ciphers*/
+ wfg.allowedGroupCiphers.clear();
+ wfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+ wfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
+
+ /*Protocols*/
+ wfg.allowedProtocols.clear();
+ wfg.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
+ wfg.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
+
+ Class[] enterpriseFieldArray = WifiConfiguration.class.getClasses();
+ Class<?> enterpriseFieldClass = null;
+
+
+ for(Class<?> myClass : enterpriseFieldArray) {
+ if(myClass.getName().equals(INT_ENTERPRISEFIELD_NAME)) {
+ enterpriseFieldClass = myClass;
+ break;
+ }
+ }
+ Log.d(TAG, "class chosen " + enterpriseFieldClass.getName() );
+
+
+ Field anonymousId = null, caCert = null, clientCert = null,
+ eap = null, identity = null, password = null,
+ phase2 = null, privateKey = null;
+
+ Field[] fields = WifiConfiguration.class.getFields();
+
+
+ for (Field tempField : fields) {
+ if (tempField.getName().trim().equals(INT_ANONYMOUS_IDENTITY)) {
+ anonymousId = tempField;
+ Log.d(TAG, "field " + anonymousId.getName() );
+ } else if (tempField.getName().trim().equals(INT_CA_CERT)) {
+ caCert = tempField;
+ } else if (tempField.getName().trim().equals(INT_CLIENT_CERT)) {
+ clientCert = tempField;
+ Log.d(TAG, "field " + clientCert.getName() );
+ } else if (tempField.getName().trim().equals(INT_EAP)) {
+ eap = tempField;
+ Log.d(TAG, "field " + eap.getName() );
+ } else if (tempField.getName().trim().equals(INT_IDENTITY)) {
+ identity = tempField;
+ Log.d(TAG, "field " + identity.getName() );
+ } else if (tempField.getName().trim().equals(INT_PASSWORD)) {
+ password = tempField;
+ Log.d(TAG, "field " + password.getName() );
+ } else if (tempField.getName().trim().equals(INT_PHASE2)) {
+ phase2 = tempField;
+ Log.d(TAG, "field " + phase2.getName() );
+
+ } else if (tempField.getName().trim().equals(INT_PRIVATE_KEY)) {
+ privateKey = tempField;
+ }
+ }
+
+
+ Method setValue = null;
+
+ for(Method m: enterpriseFieldClass.getMethods()) {
+ if(m.getName().trim().equals("setValue")) {
+ Log.d(TAG, "method " + m.getName() );
+ setValue = m;
+ break;
+ }
+ }
+
+ try {
+ // EAP
+ String eapmethod = mCredential.getType();
+ Log.d(TAG, "eapmethod:" + eapmethod);
+ setValue.invoke(eap.get(wfg), eapmethod);
+
+ // Username, password, EAP Phase 2
+ if ("TTLS".equals(eapmethod)) {
+ setValue.invoke(phase2.get(wfg), ENTERPRISE_PHASE2_MSCHAPV2);
+ setValue.invoke(identity.get(wfg), mCredential.getUserName());
+ setValue.invoke(password.get(wfg), mCredential.getPassword());
+ setValue.invoke(anonymousId.get(wfg), "anonymous@" + mCredential.getRealm());
+ }
+
+ // EAP CA Certificate
+ String cacertificate = null;
+ String rootCA = mCredential.getCaRootCertPath();
+ if (rootCA == null){
+ cacertificate = null;
+ } else {
+ cacertificate = "keystore://" + Credentials.WIFI + "HS20" + Credentials.CA_CERTIFICATE + rootCA;
+ }
+ Log.d(TAG, "cacertificate:" + cacertificate);
+ setValue.invoke(caCert.get(wfg), cacertificate);
+
+ //User certificate
+ if ("TLS".equals(eapmethod)) {
+ String usercertificate = null;
+ String privatekey = null;
+ String clientCertPath = mCredential.getClientCertPath();
+ if (clientCertPath != null){
+ privatekey = "keystore://" + Credentials.WIFI + "HS20" + Credentials.USER_PRIVATE_KEY + clientCertPath;
+ usercertificate = "keystore://" + Credentials.WIFI + "HS20" + Credentials.USER_CERTIFICATE + clientCertPath;
+ }
+ Log.d(TAG, "privatekey:" + privatekey);
+ Log.d(TAG, "usercertificate:" + usercertificate);
+ if (privatekey != null && usercertificate != null) {
+ setValue.invoke(privateKey.get(wfg), privatekey);
+ setValue.invoke(clientCert.get(wfg), usercertificate);
+ }
+ }
+ } catch (Exception e) {
+ Log.d(TAG, "createWifiConfiguration err:" + e);
+ }
+
+ return wfg;
+ }
+
+ /** {@inheritDoc} @hide */
+ public int compareTo(WifiPasspointPolicy another) {
+ Log.d(TAG, "this:" + this);
+ Log.d(TAG, "another:" + another);
+
+ if (another == null) {
+ return -1;
+ } else if (this.mIsHomeSp == true && another.isHomeSp() == false) {
+ //home sp priority is higher then roaming
+ Log.d(TAG, "compare HomeSP first, this is HomeSP, another isn't");
+ return -1;
+ } else if ((this.mIsHomeSp == true && another.isHomeSp() == true)) {
+ Log.d(TAG, "both HomeSP");
+ //if both home sp, compare credential priority
+ if (this.mCredentialPriority < another.getCredentialPriority()) {
+ Log.d(TAG, "this priority is higher");
+ return -1;
+ } else if (this.mCredentialPriority == another.getCredentialPriority()) {
+ Log.d(TAG, "both priorities equal");
+ //if priority still the same, compare name(ssid)
+ if (this.mName.compareTo(another.mName) != 0) {
+ Log.d(TAG, "compare mName return:" + this.mName.compareTo(another.mName));
+ return this.mName.compareTo(another.mName);
+ }
+ /**
+ *if name still the same, compare credential
+ *the device may has two more credentials(TLS,SIM..etc)
+ *it can associate to one AP(same ssid). so we should compare by credential
+ */
+ if (this.mCredential != null && another.mCredential != null) {
+ if (this.mCredential.compareTo(another.mCredential) != 0) {
+ Log.d(TAG,
+ "compare mCredential return:" + this.mName.compareTo(another.mName));
+ return this.mCredential.compareTo(another.mCredential);
+ }
+ }
+ } else {
+ return 1;
+ }
+ } else if ((this.mIsHomeSp == false && another.isHomeSp() == false)) {
+ Log.d(TAG, "both RoamingSp");
+ //if both roaming sp, compare roaming priority(preferredRoamingPartnerList/<X+>/priority)
+ if (this.mRoamingPriority < another.getRoamingPriority()) {
+ Log.d(TAG, "this priority is higher");
+ return -1;
+ } else if (this.mRoamingPriority == another.getRoamingPriority()) {//priority equals, compare name
+ Log.d(TAG, "both priorities equal");
+ //if priority still the same, compare name(ssid)
+ if (this.mName.compareTo(another.mName) != 0) {
+ Log.d(TAG, "compare mName return:" + this.mName.compareTo(another.mName));
+ return this.mName.compareTo(another.mName);
+ }
+ //if name still the same, compare credential
+ if (this.mCredential != null && another.mCredential != null) {
+ if (this.mCredential.compareTo(another.mCredential) != 0) {
+ Log.d(TAG,
+ "compare mCredential return:"
+ + this.mCredential.compareTo(another.mCredential));
+ return this.mCredential.compareTo(another.mCredential);
+ }
+ }
+ } else {
+ return 1;
+ }
+ }
+
+ Log.d(TAG, "both policies equal");
+ return 0;
+ }
+
+ @Override
+ /** @hide */
+ public String toString() {
+ return "PasspointPolicy: name=" + mName + " CredentialPriority=" + mCredentialPriority +
+ " mRoamingPriority" + mRoamingPriority +
+ " ssid=" + mSsid + " restriction=" + mRestriction +
+ " ishomesp=" + mIsHomeSp + " Credential=" + mCredential;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ // TODO
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Creator<WifiPasspointPolicy> CREATOR =
+ new Creator<WifiPasspointPolicy>() {
+ @Override
+ public WifiPasspointPolicy createFromParcel(Parcel in) {
+ return null;
+ }
+
+ @Override
+ public WifiPasspointPolicy[] newArray(int size) {
+ return new WifiPasspointPolicy[size];
+ }
+ };
+}