/*
* 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];
}
};
}