diff options
author | Vinit Deshpande <vinitd@google.com> | 2015-03-09 19:01:31 -0700 |
---|---|---|
committer | Vinit Deshpande <vinitd@google.com> | 2015-03-09 19:01:31 -0700 |
commit | 1aa4dcee03f75df4f96ac9d3653503e0ae027117 (patch) | |
tree | 51bb87b53e2e3f85edaf22d355e29c637a684d5e /wifi/java/android | |
parent | 472cca08eb42fc198cf70ac327567c941960ea17 (diff) | |
parent | 7dd2f6b57b5ef1f14eb55b7801a3d31729ad7a0a (diff) | |
download | frameworks_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')
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]; + } + }; +} |