blob: f50192c6509cc1fe9d030f3f1d058e9902bdb696 [file] [log] [blame]
/*
* Copyright (C) 2017 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 com.android.server.wifi.hotspot2;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.HomeSp;
import android.net.wifi.hotspot2.pps.Policy;
import android.net.wifi.hotspot2.pps.UpdateParameter;
import com.android.server.wifi.util.XmlUtil;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Utility class for serialize and deserialize Passpoint related configurations to/from XML string.
*/
public class PasspointXmlUtils {
// XML section header tags.
private static final String XML_TAG_SECTION_HEADER_HOMESP = "HomeSP";
private static final String XML_TAG_SECTION_HEADER_CREDENTIAL = "Credential";
private static final String XML_TAG_SECTION_HEADER_USER_CREDENTIAL = "UserCredential";
private static final String XML_TAG_SECTION_HEADER_CERT_CREDENTIAL = "CertCredential";
private static final String XML_TAG_SECTION_HEADER_SIM_CREDENTIAL = "SimCredential";
private static final String XML_TAG_SECTION_HEADER_POLICY = "Policy";
private static final String XML_TAG_SECTION_HEADER_PREFERRED_ROAMING_PARTNER_LIST =
"RoamingPartnerList";
private static final String XML_TAG_SECTION_HEADER_ROAMING_PARTNER = "RoamingPartner";
private static final String XML_TAG_SECTION_HEADER_POLICY_UPDATE = "PolicyUpdate";
private static final String XML_TAG_SECTION_HEADER_SUBSCRIPTION_UPDATE = "SubscriptionUpdate";
private static final String XML_TAG_SECTION_HEADER_REQUIRED_PROTO_PORT_MAP =
"RequiredProtoPortMap";
private static final String XML_TAG_SECTION_HEADER_PROTO_PORT = "ProtoPort";
// XML value tags.
private static final String XML_TAG_FQDN = "FQDN";
private static final String XML_TAG_FRIENDLY_NAME = "FriendlyName";
private static final String XML_TAG_FRIENDLY_NAME_LIST = "FriendlyNameList";
private static final String XML_TAG_ICON_URL = "IconURL";
private static final String XML_TAG_HOME_NETWORK_IDS = "HomeNetworkIDs";
private static final String XML_TAG_MATCH_ALL_OIS = "MatchAllOIs";
private static final String XML_TAG_MATCH_ANY_OIS = "MatchAnyOIs";
private static final String XML_TAG_OTHER_HOME_PARTNERS = "OtherHomePartners";
private static final String XML_TAG_ROAMING_CONSORTIUM_OIS = "RoamingConsortiumOIs";
private static final String XML_TAG_CREATION_TIME = "CreationTime";
private static final String XML_TAG_EXPIRATION_TIME = "ExpirationTime";
private static final String XML_TAG_REALM = "Realm";
private static final String XML_TAG_CHECK_AAA_SERVER_CERT_STATUS = "CheckAAAServerCertStatus";
private static final String XML_TAG_USERNAME = "Username";
private static final String XML_TAG_PASSWORD = "Password";
private static final String XML_TAG_MACHINE_MANAGED = "MachineManaged";
private static final String XML_TAG_SOFT_TOKEN_APP = "SoftTokenApp";
private static final String XML_TAG_ABLE_TO_SHARE = "AbleToShare";
private static final String XML_TAG_EAP_TYPE = "EAPType";
private static final String XML_TAG_NON_EAP_INNER_METHOD = "NonEAPInnerMethod";
private static final String XML_TAG_CERT_TYPE = "CertType";
private static final String XML_TAG_CERT_SHA256_FINGERPRINT = "CertSHA256Fingerprint";
private static final String XML_TAG_IMSI = "IMSI";
private static final String XML_TAG_MIN_HOME_DOWNLINK_BANDWIDTH = "MinHomeDownlinkBandwidth";
private static final String XML_TAG_MIN_HOME_UPLINK_BANDWIDTH = "MinHomeUplinkBandwidth";
private static final String XML_TAG_MIN_ROAMING_DOWNLINK_BANDWIDTH =
"MinRoamingDownlinkBandwidth";
private static final String XML_TAG_MIN_ROAMING_UPLINK_BANDWIDTH =
"MinRoamingUplinkBandwidth";
private static final String XML_TAG_EXCLUDED_SSID_LIST = "ExcludedSSIDList";
private static final String XML_TAG_PROTO = "Proto";
private static final String XML_TAG_PORTS = "Ports";
private static final String XML_TAG_MAXIMUM_BSS_LOAD_VALUE = "MaximumBSSLoadValue";
private static final String XML_TAG_FQDN_EXACT_MATCH = "FQDNExactMatch";
private static final String XML_TAG_PRIORITY = "Priority";
private static final String XML_TAG_COUNTRIES = "Countries";
private static final String XML_TAG_UPDATE_INTERVAL = "UpdateInterval";
private static final String XML_TAG_UPDATE_METHOD = "UpdateMethod";
private static final String XML_TAG_RESTRICTION = "Restriction";
private static final String XML_TAG_SERVER_URI = "ServerURI";
private static final String XML_TAG_TRUST_ROOT_CERT_URL = "TrustRootCertURL";
private static final String XML_TAG_TRUST_ROOT_CERT_SHA256_FINGERPRINT =
"TrustRootCertSHA256Fingerprint";
private static final String XML_TAG_TRUST_ROOT_CERT_LIST = "TrustRootCertList";
private static final String XML_TAG_UPDATE_IDENTIFIER = "UpdateIdentifier";
private static final String XML_TAG_CREDENTIAL_PRIORITY = "CredentialPriority";
private static final String XML_TAG_SUBSCRIPTION_CREATION_TIME = "SubscriptionCreationTime";
private static final String XML_TAG_SUBSCRIPTION_EXPIRATION_TIME =
"SubscriptionExpirationTime";
private static final String XML_TAG_SUBSCRIPTION_TYPE = "SubscriptionType";
private static final String XML_TAG_USAGE_LIMIT_TIME_PERIOD = "UsageLimitTimePeriod";
private static final String XML_TAG_USAGE_LIMIT_START_TIME = "UsageLimitStartTime";
private static final String XML_TAG_USAGE_LIMIT_DATA_LIMIT = "UsageLimitDataLimit";
private static final String XML_TAG_USAGE_LIMIT_TIME_LIMIT = "UsageLimitTimeLimit";
private static final String XML_TAG_CARRIER_ID = "CarrierId";
private static final String XML_TAG_IS_AUTO_JOIN = "AutoJoinEnabled";
private static final String XML_TAG_IS_MAC_RANDOMIZATION_ENABLED = "IsMacRandomizationEnabled";
private static final String XML_TAG_METERED_OVERRIDE = "MeteredOverride";
/**
* Serialize a {@link PasspointConfiguration} to the output stream as a XML block.
*
* @param out The output stream to serialize to
* @param config The configuration to serialize
* @throws XmlPullParserException
* @throws IOException
*/
public static void serializePasspointConfiguration(XmlSerializer out,
PasspointConfiguration config) throws XmlPullParserException, IOException {
XmlUtil.writeNextValue(out, XML_TAG_UPDATE_IDENTIFIER, config.getUpdateIdentifier());
XmlUtil.writeNextValue(out, XML_TAG_CREDENTIAL_PRIORITY, config.getCredentialPriority());
XmlUtil.writeNextValue(out, XML_TAG_TRUST_ROOT_CERT_LIST, config.getTrustRootCertList());
XmlUtil.writeNextValue(out, XML_TAG_SUBSCRIPTION_CREATION_TIME,
config.getSubscriptionCreationTimeInMillis());
XmlUtil.writeNextValue(out, XML_TAG_SUBSCRIPTION_EXPIRATION_TIME,
config.getSubscriptionExpirationTimeMillis());
XmlUtil.writeNextValue(out, XML_TAG_SUBSCRIPTION_TYPE, config.getSubscriptionType());
XmlUtil.writeNextValue(out, XML_TAG_USAGE_LIMIT_TIME_PERIOD,
config.getUsageLimitUsageTimePeriodInMinutes());
XmlUtil.writeNextValue(out, XML_TAG_USAGE_LIMIT_START_TIME,
config.getUsageLimitStartTimeInMillis());
XmlUtil.writeNextValue(out, XML_TAG_USAGE_LIMIT_DATA_LIMIT,
config.getUsageLimitDataLimit());
XmlUtil.writeNextValue(out, XML_TAG_USAGE_LIMIT_TIME_LIMIT,
config.getUsageLimitTimeLimitInMinutes());
serializeHomeSp(out, config.getHomeSp());
serializeCredential(out, config.getCredential());
serializePolicy(out, config.getPolicy());
serializeUpdateParameter(out, XML_TAG_SECTION_HEADER_SUBSCRIPTION_UPDATE,
config.getSubscriptionUpdate());
if (config.getServiceFriendlyNames() != null) {
XmlUtil.writeNextValue(out, XML_TAG_FRIENDLY_NAME_LIST,
config.getServiceFriendlyNames());
}
XmlUtil.writeNextValue(out, XML_TAG_CARRIER_ID, config.getCarrierId());
XmlUtil.writeNextValue(out, XML_TAG_IS_AUTO_JOIN, config.isAutojoinEnabled());
XmlUtil.writeNextValue(out, XML_TAG_IS_MAC_RANDOMIZATION_ENABLED,
config.isMacRandomizationEnabled());
XmlUtil.writeNextValue(out, XML_TAG_METERED_OVERRIDE, config.getMeteredOverride());
}
/**
* Deserialize a {@link PasspointConfiguration} from an input stream containing XML block.
*
* @param in The input stream to read from
* @param outerTagDepth The tag depth of the current XML section
* @return {@link PasspointConfiguration}
* @throws XmlPullParserException
* @throws IOException
*/
public static PasspointConfiguration deserializePasspointConfiguration(XmlPullParser in,
int outerTagDepth) throws XmlPullParserException, IOException {
PasspointConfiguration config = new PasspointConfiguration();
while (XmlUtil.nextElementWithin(in, outerTagDepth)) {
if (isValueElement(in)) {
// Value elements.
String[] name = new String[1];
Object value = XmlUtil.readCurrentValue(in, name);
switch (name[0]) {
case XML_TAG_UPDATE_IDENTIFIER:
config.setUpdateIdentifier((int) value);
break;
case XML_TAG_CREDENTIAL_PRIORITY:
config.setCredentialPriority((int) value);
break;
case XML_TAG_TRUST_ROOT_CERT_LIST:
config.setTrustRootCertList((Map<String, byte[]>) value);
break;
case XML_TAG_SUBSCRIPTION_CREATION_TIME:
config.setSubscriptionCreationTimeInMillis((long) value);
break;
case XML_TAG_SUBSCRIPTION_EXPIRATION_TIME:
config.setSubscriptionExpirationTimeInMillis((long) value);
break;
case XML_TAG_SUBSCRIPTION_TYPE:
config.setSubscriptionType((String) value);
break;
case XML_TAG_USAGE_LIMIT_TIME_PERIOD:
config.setUsageLimitUsageTimePeriodInMinutes((long) value);
break;
case XML_TAG_USAGE_LIMIT_START_TIME:
config.setUsageLimitStartTimeInMillis((long) value);
break;
case XML_TAG_USAGE_LIMIT_DATA_LIMIT:
config.setUsageLimitDataLimit((long) value);
break;
case XML_TAG_USAGE_LIMIT_TIME_LIMIT:
config.setUsageLimitTimeLimitInMinutes((long) value);
break;
case XML_TAG_FRIENDLY_NAME_LIST:
config.setServiceFriendlyNames((Map<String, String>) value);
break;
case XML_TAG_CARRIER_ID:
config.setCarrierId((int) value);
break;
case XML_TAG_IS_AUTO_JOIN:
config.setAutojoinEnabled((boolean) value);
break;
case XML_TAG_IS_MAC_RANDOMIZATION_ENABLED:
config.setMacRandomizationEnabled((boolean) value);
break;
case XML_TAG_METERED_OVERRIDE:
config.setMeteredOverride((int) value);
break;
default:
throw new XmlPullParserException("Unknown value under "
+ "PasspointConfiguration: " + in.getName());
}
} else {
// Section elements.
switch (in.getName()) {
case XML_TAG_SECTION_HEADER_HOMESP:
config.setHomeSp(deserializeHomeSP(in, outerTagDepth + 1));
break;
case XML_TAG_SECTION_HEADER_CREDENTIAL:
config.setCredential(deserializeCredential(in, outerTagDepth + 1));
break;
case XML_TAG_SECTION_HEADER_POLICY:
config.setPolicy(deserializePolicy(in, outerTagDepth + 1));
break;
case XML_TAG_SECTION_HEADER_SUBSCRIPTION_UPDATE:
config.setSubscriptionUpdate(
deserializeUpdateParameter(in, outerTagDepth + 1));
break;
default:
throw new XmlPullParserException("Unknown section under "
+ "PasspointConfiguration: " + in.getName());
}
}
}
return config;
}
/**
* Serialize a {@link HomeSp} to an output stream as a XML block.
*
* @param out The output stream to serialize data to
* @param homeSp The {@link HomeSp} to serialize
* @throws XmlPullParserException
* @throws IOException
*/
private static void serializeHomeSp(XmlSerializer out, HomeSp homeSp)
throws XmlPullParserException, IOException {
if (homeSp == null) {
return;
}
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_HOMESP);
XmlUtil.writeNextValue(out, XML_TAG_FQDN, homeSp.getFqdn());
XmlUtil.writeNextValue(out, XML_TAG_FRIENDLY_NAME, homeSp.getFriendlyName());
XmlUtil.writeNextValue(out, XML_TAG_ICON_URL, homeSp.getIconUrl());
XmlUtil.writeNextValue(out, XML_TAG_HOME_NETWORK_IDS, homeSp.getHomeNetworkIds());
XmlUtil.writeNextValue(out, XML_TAG_MATCH_ALL_OIS, homeSp.getMatchAllOis());
XmlUtil.writeNextValue(out, XML_TAG_MATCH_ANY_OIS, homeSp.getMatchAnyOis());
XmlUtil.writeNextValue(out, XML_TAG_OTHER_HOME_PARTNERS, homeSp.getOtherHomePartners());
XmlUtil.writeNextValue(out, XML_TAG_ROAMING_CONSORTIUM_OIS,
homeSp.getRoamingConsortiumOis());
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_HOMESP);
}
/**
* Serialize a {@link Credential} to an output stream as a XML block.
*
* @param out The output stream to serialize to
* @param credential The {@link Credential} to serialize
* @throws XmlPullParserException
* @throws IOException
*/
private static void serializeCredential(XmlSerializer out, Credential credential)
throws XmlPullParserException, IOException {
if (credential == null) {
return;
}
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_CREDENTIAL);
XmlUtil.writeNextValue(out, XML_TAG_CREATION_TIME, credential.getCreationTimeInMillis());
XmlUtil.writeNextValue(out, XML_TAG_EXPIRATION_TIME,
credential.getExpirationTimeInMillis());
XmlUtil.writeNextValue(out, XML_TAG_REALM, credential.getRealm());
XmlUtil.writeNextValue(out, XML_TAG_CHECK_AAA_SERVER_CERT_STATUS,
credential.getCheckAaaServerCertStatus());
serializeUserCredential(out, credential.getUserCredential());
serializeCertCredential(out, credential.getCertCredential());
serializeSimCredential(out, credential.getSimCredential());
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_CREDENTIAL);
}
/**
* Serialize a {@link Policy} to an output stream as a XML block.
*
* @param out The output stream to serialize to
* @param policy The {@link Policy} to serialize
* @throws XmlPullParserException
* @throws IOException
*/
private static void serializePolicy(XmlSerializer out, Policy policy)
throws XmlPullParserException, IOException {
if (policy == null) {
return;
}
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_POLICY);
XmlUtil.writeNextValue(out, XML_TAG_MIN_HOME_DOWNLINK_BANDWIDTH,
policy.getMinHomeDownlinkBandwidth());
XmlUtil.writeNextValue(out, XML_TAG_MIN_HOME_UPLINK_BANDWIDTH,
policy.getMinHomeUplinkBandwidth());
XmlUtil.writeNextValue(out, XML_TAG_MIN_ROAMING_DOWNLINK_BANDWIDTH,
policy.getMinRoamingDownlinkBandwidth());
XmlUtil.writeNextValue(out, XML_TAG_MIN_ROAMING_UPLINK_BANDWIDTH,
policy.getMinRoamingUplinkBandwidth());
XmlUtil.writeNextValue(out, XML_TAG_EXCLUDED_SSID_LIST, policy.getExcludedSsidList());
XmlUtil.writeNextValue(out, XML_TAG_MAXIMUM_BSS_LOAD_VALUE,
policy.getMaximumBssLoadValue());
serializeProtoPortMap(out, policy.getRequiredProtoPortMap());
serializeUpdateParameter(out, XML_TAG_SECTION_HEADER_POLICY_UPDATE,
policy.getPolicyUpdate());
serializePreferredRoamingPartnerList(out, policy.getPreferredRoamingPartnerList());
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_POLICY);
}
/**
* Serialize a {@link android.net.wifi.hotspot2.pps.Credential.UserCredential} to an output
* stream as a XML block.
*
* @param out The output stream to serialize data to
* @param userCredential The UserCredential to serialize
* @throws XmlPullParserException
* @throws IOException
*/
private static void serializeUserCredential(XmlSerializer out,
Credential.UserCredential userCredential) throws XmlPullParserException, IOException {
if (userCredential == null) {
return;
}
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_USER_CREDENTIAL);
XmlUtil.writeNextValue(out, XML_TAG_USERNAME, userCredential.getUsername());
XmlUtil.writeNextValue(out, XML_TAG_PASSWORD, userCredential.getPassword());
XmlUtil.writeNextValue(out, XML_TAG_MACHINE_MANAGED, userCredential.getMachineManaged());
XmlUtil.writeNextValue(out, XML_TAG_SOFT_TOKEN_APP, userCredential.getSoftTokenApp());
XmlUtil.writeNextValue(out, XML_TAG_ABLE_TO_SHARE, userCredential.getAbleToShare());
XmlUtil.writeNextValue(out, XML_TAG_EAP_TYPE, userCredential.getEapType());
XmlUtil.writeNextValue(out, XML_TAG_NON_EAP_INNER_METHOD,
userCredential.getNonEapInnerMethod());
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_USER_CREDENTIAL);
}
/**
* Serialize a {@link android.net.wifi.hotspot2.pps.Credential.CertificateCredential} to an
* output stream as a XML block.
*
* @param out The output stream to serialize data to
* @param certCredential The CertificateCredential to serialize
* @throws XmlPullParserException
* @throws IOException
*/
private static void serializeCertCredential(XmlSerializer out,
Credential.CertificateCredential certCredential)
throws XmlPullParserException, IOException {
if (certCredential == null) {
return;
}
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_CERT_CREDENTIAL);
XmlUtil.writeNextValue(out, XML_TAG_CERT_TYPE, certCredential.getCertType());
XmlUtil.writeNextValue(out, XML_TAG_CERT_SHA256_FINGERPRINT,
certCredential.getCertSha256Fingerprint());
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_CERT_CREDENTIAL);
}
/**
* Serialize a {@link android.net.wifi.hotspot2.pps.Credential.SimCredential} to an
* output stream as a XML block.
*
* @param out The output stream to serialize data to
* @param simCredential The SimCredential to serialize
* @throws XmlPullParserException
* @throws IOException
*/
private static void serializeSimCredential(XmlSerializer out,
Credential.SimCredential simCredential) throws XmlPullParserException, IOException {
if (simCredential == null) {
return;
}
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_SIM_CREDENTIAL);
XmlUtil.writeNextValue(out, XML_TAG_IMSI, simCredential.getImsi());
XmlUtil.writeNextValue(out, XML_TAG_EAP_TYPE, simCredential.getEapType());
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_SIM_CREDENTIAL);
}
/**
* Serialize a preferred roaming partner list to an output stream as a XML block.
*
* @param out The output stream to serialize data to
* @param preferredRoamingPartnerList The partner list to serialize
* @throws XmlPullParserException
* @throws IOException
*/
private static void serializePreferredRoamingPartnerList(XmlSerializer out,
List<Policy.RoamingPartner> preferredRoamingPartnerList)
throws XmlPullParserException, IOException {
if (preferredRoamingPartnerList == null) {
return;
}
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_PREFERRED_ROAMING_PARTNER_LIST);
for (Policy.RoamingPartner partner : preferredRoamingPartnerList) {
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_ROAMING_PARTNER);
XmlUtil.writeNextValue(out, XML_TAG_FQDN, partner.getFqdn());
XmlUtil.writeNextValue(out, XML_TAG_FQDN_EXACT_MATCH, partner.getFqdnExactMatch());
XmlUtil.writeNextValue(out, XML_TAG_PRIORITY, partner.getPriority());
XmlUtil.writeNextValue(out, XML_TAG_COUNTRIES, partner.getCountries());
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_ROAMING_PARTNER);
}
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_PREFERRED_ROAMING_PARTNER_LIST);
}
/**
* Serialize a {@link UpdateParameter} to an output stream as a XML block. The
* {@link UpdateParameter} are used for describing Subscription Update and Policy Update.
*
* @param out The output stream to serialize data to
* @param type The type the {@link UpdateParameter} is used for
* @param param The {@link UpdateParameter} to serialize
* @throws XmlPullParserException
* @throws IOException
*/
private static void serializeUpdateParameter(XmlSerializer out, String type,
UpdateParameter param) throws XmlPullParserException, IOException {
if (param == null) {
return;
}
XmlUtil.writeNextSectionStart(out, type);
XmlUtil.writeNextValue(out, XML_TAG_UPDATE_INTERVAL, param.getUpdateIntervalInMinutes());
XmlUtil.writeNextValue(out, XML_TAG_UPDATE_METHOD, param.getUpdateMethod());
XmlUtil.writeNextValue(out, XML_TAG_RESTRICTION, param.getRestriction());
XmlUtil.writeNextValue(out, XML_TAG_SERVER_URI, param.getServerUri());
XmlUtil.writeNextValue(out, XML_TAG_USERNAME, param.getUsername());
XmlUtil.writeNextValue(out, XML_TAG_PASSWORD, param.getBase64EncodedPassword());
XmlUtil.writeNextValue(out, XML_TAG_TRUST_ROOT_CERT_URL, param.getTrustRootCertUrl());
XmlUtil.writeNextValue(out, XML_TAG_TRUST_ROOT_CERT_SHA256_FINGERPRINT,
param.getTrustRootCertSha256Fingerprint());
XmlUtil.writeNextSectionEnd(out, type);
}
/**
* Serialize a Protocol-to-Ports map to an output stream as a XML block. We're not able
* to use {@link XmlUtil#writeNextValue} to write this map, since that function only works for
* maps with String key.
*
* @param out The output stream to serialize data to
* @param protoPortMap The proto port map to serialize
* @throws XmlPullParserException
* @throws IOException
*/
private static void serializeProtoPortMap(XmlSerializer out, Map<Integer, String> protoPortMap)
throws XmlPullParserException, IOException {
if (protoPortMap == null) {
return;
}
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_REQUIRED_PROTO_PORT_MAP);
for (Map.Entry<Integer, String> entry : protoPortMap.entrySet()) {
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_PROTO_PORT);
XmlUtil.writeNextValue(out, XML_TAG_PROTO, entry.getKey());
XmlUtil.writeNextValue(out, XML_TAG_PORTS, entry.getValue());
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_PROTO_PORT);
}
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_REQUIRED_PROTO_PORT_MAP);
}
/**
* Deserialize a {@link HomeSp} from an input stream.
*
* @param in The input stream to read data from
* @param outerTagDepth The tag depth of the current XML section
* @return {@link HomeSp}
* @throws XmlPullParserException
* @throws IOException
*/
private static HomeSp deserializeHomeSP(XmlPullParser in, int outerTagDepth)
throws XmlPullParserException, IOException {
HomeSp homeSp = new HomeSp();
while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
String[] valueName = new String[1];
Object value = XmlUtil.readCurrentValue(in, valueName);
if (valueName[0] == null) {
throw new XmlPullParserException("Missing value name");
}
switch (valueName[0]) {
case XML_TAG_FQDN:
homeSp.setFqdn((String) value);
break;
case XML_TAG_FRIENDLY_NAME:
homeSp.setFriendlyName((String) value);
break;
case XML_TAG_ICON_URL:
homeSp.setIconUrl((String) value);
break;
case XML_TAG_HOME_NETWORK_IDS:
homeSp.setHomeNetworkIds((Map<String, Long>) value);
break;
case XML_TAG_MATCH_ALL_OIS:
homeSp.setMatchAllOis((long[]) value);
break;
case XML_TAG_MATCH_ANY_OIS:
homeSp.setMatchAnyOis((long[]) value);
break;
case XML_TAG_ROAMING_CONSORTIUM_OIS:
homeSp.setRoamingConsortiumOis((long[]) value);
break;
case XML_TAG_OTHER_HOME_PARTNERS:
homeSp.setOtherHomePartners((String[]) value);
break;
default:
throw new XmlPullParserException("Unknown data under HomeSP: " + valueName[0]);
}
}
return homeSp;
}
/**
* Deserialize a {@link Credential} from an input stream.
*
* @param in The input stream to read data from
* @param outerTagDepth The tag depth of the current XML section
* @return {@link Credential}
* @throws XmlPullParserException
* @throws IOException
*/
private static Credential deserializeCredential(XmlPullParser in, int outerTagDepth)
throws XmlPullParserException, IOException {
Credential credential = new Credential();
while (XmlUtil.nextElementWithin(in, outerTagDepth)) {
if (isValueElement(in)) {
// Value elements.
String[] name = new String[1];
Object value = XmlUtil.readCurrentValue(in, name);
switch (name[0]) {
case XML_TAG_CREATION_TIME:
credential.setCreationTimeInMillis((long) value);
break;
case XML_TAG_EXPIRATION_TIME:
credential.setExpirationTimeInMillis((long) value);
break;
case XML_TAG_REALM:
credential.setRealm((String) value);
break;
case XML_TAG_CHECK_AAA_SERVER_CERT_STATUS:
credential.setCheckAaaServerCertStatus((boolean) value);
break;
default:
throw new XmlPullParserException("Unknown value under Credential: "
+ name[0]);
}
} else {
// Subsection elements.
switch (in.getName()) {
case XML_TAG_SECTION_HEADER_USER_CREDENTIAL:
credential.setUserCredential(
deserializeUserCredential(in, outerTagDepth + 1));
break;
case XML_TAG_SECTION_HEADER_CERT_CREDENTIAL:
credential.setCertCredential(
deserializeCertCredential(in, outerTagDepth + 1));
break;
case XML_TAG_SECTION_HEADER_SIM_CREDENTIAL:
credential.setSimCredential(
deserializeSimCredential(in, outerTagDepth + 1));
break;
default:
throw new XmlPullParserException("Unknown section under Credential: "
+ in.getName());
}
}
}
return credential;
}
/**
* Deserialize a {@link Policy} from an input stream.
*
* @param in The input stream to read data from
* @param outerTagDepth The tag depth of the current XML section
* @return {@link Policy}
* @throws XmlPullParserException
* @throws IOException
*/
private static Policy deserializePolicy(XmlPullParser in, int outerTagDepth)
throws XmlPullParserException, IOException {
Policy policy = new Policy();
while (XmlUtil.nextElementWithin(in, outerTagDepth)) {
if (isValueElement(in)) {
// Value elements.
String[] name = new String[1];
Object value = XmlUtil.readCurrentValue(in, name);
switch (name[0]) {
case XML_TAG_MIN_HOME_DOWNLINK_BANDWIDTH:
policy.setMinHomeDownlinkBandwidth((long) value);
break;
case XML_TAG_MIN_HOME_UPLINK_BANDWIDTH:
policy.setMinHomeUplinkBandwidth((long) value);
break;
case XML_TAG_MIN_ROAMING_DOWNLINK_BANDWIDTH:
policy.setMinRoamingDownlinkBandwidth((long) value);
break;
case XML_TAG_MIN_ROAMING_UPLINK_BANDWIDTH:
policy.setMinRoamingUplinkBandwidth((long) value);
break;
case XML_TAG_EXCLUDED_SSID_LIST:
policy.setExcludedSsidList((String[]) value);
break;
case XML_TAG_MAXIMUM_BSS_LOAD_VALUE:
policy.setMaximumBssLoadValue((int) value);
break;
}
} else {
// Subsection elements.
switch (in.getName()) {
case XML_TAG_SECTION_HEADER_REQUIRED_PROTO_PORT_MAP:
policy.setRequiredProtoPortMap(
deserializeProtoPortMap(in, outerTagDepth + 1));
break;
case XML_TAG_SECTION_HEADER_POLICY_UPDATE:
policy.setPolicyUpdate(deserializeUpdateParameter(in, outerTagDepth + 1));
break;
case XML_TAG_SECTION_HEADER_PREFERRED_ROAMING_PARTNER_LIST:
policy.setPreferredRoamingPartnerList(
deserializePreferredRoamingPartnerList(in, outerTagDepth + 1));
break;
default:
throw new XmlPullParserException("Unknown section under Policy: "
+ in.getName());
}
}
}
return policy;
}
/**
* Deserialize a {@link android.net.wifi.hotspot2.pps.Credential.UserCredential} from an
* input stream.
*
* @param in The input stream to read data from
* @param outerTagDepth The tag depth of the current XML section
* @return {@link android.net.wifi.hotspot2.pps.Credential.UserCredential}
* @throws XmlPullParserException
* @throws IOException
*/
private static Credential.UserCredential deserializeUserCredential(XmlPullParser in,
int outerTagDepth) throws XmlPullParserException, IOException {
Credential.UserCredential userCredential = new Credential.UserCredential();
while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
String[] valueName = new String[1];
Object value = XmlUtil.readCurrentValue(in, valueName);
if (valueName[0] == null) {
throw new XmlPullParserException("Missing value name");
}
switch (valueName[0]) {
case XML_TAG_USERNAME:
userCredential.setUsername((String) value);
break;
case XML_TAG_PASSWORD:
userCredential.setPassword((String) value);
break;
case XML_TAG_MACHINE_MANAGED:
userCredential.setMachineManaged((boolean) value);
break;
case XML_TAG_SOFT_TOKEN_APP:
userCredential.setSoftTokenApp((String) value);
break;
case XML_TAG_ABLE_TO_SHARE:
userCredential.setAbleToShare((boolean) value);
break;
case XML_TAG_EAP_TYPE:
userCredential.setEapType((int) value);
break;
case XML_TAG_NON_EAP_INNER_METHOD:
userCredential.setNonEapInnerMethod((String) value);
break;
default:
throw new XmlPullParserException("Unknown value under UserCredential: "
+ valueName[0]);
}
}
return userCredential;
}
/**
* Deserialize a {@link android.net.wifi.hotspot2.pps.Credential.CertificateCredential}
* from an input stream.
*
* @param in The input stream to read data from
* @param outerTagDepth The tag depth of the current XML section
* @return {@link android.net.wifi.hotspot2.pps.Credential.CertificateCredential}
* @throws XmlPullParserException
* @throws IOException
*/
private static Credential.CertificateCredential deserializeCertCredential(XmlPullParser in,
int outerTagDepth) throws XmlPullParserException, IOException {
Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
String[] valueName = new String[1];
Object value = XmlUtil.readCurrentValue(in, valueName);
if (valueName[0] == null) {
throw new XmlPullParserException("Missing value name");
}
switch (valueName[0]) {
case XML_TAG_CERT_TYPE:
certCredential.setCertType((String) value);
break;
case XML_TAG_CERT_SHA256_FINGERPRINT:
certCredential.setCertSha256Fingerprint((byte[]) value);
break;
default:
throw new XmlPullParserException("Unknown value under CertCredential: "
+ valueName[0]);
}
}
return certCredential;
}
/**
* Deserialize a {@link android.net.wifi.hotspot2.pps.Credential.SimCredential} from an
* input stream.
*
* @param in The input stream to read data from
* @param outerTagDepth The tag depth of the current XML section
* @return {@link android.net.wifi.hotspot2.pps.Credential.SimCredential}
* @throws XmlPullParserException
* @throws IOException
*/
private static Credential.SimCredential deserializeSimCredential(XmlPullParser in,
int outerTagDepth) throws XmlPullParserException, IOException {
Credential.SimCredential simCredential = new Credential.SimCredential();
while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
String[] valueName = new String[1];
Object value = XmlUtil.readCurrentValue(in, valueName);
if (valueName[0] == null) {
throw new XmlPullParserException("Missing value name");
}
switch (valueName[0]) {
case XML_TAG_IMSI:
simCredential.setImsi((String) value);
break;
case XML_TAG_EAP_TYPE:
simCredential.setEapType((int) value);
break;
default:
throw new XmlPullParserException("Unknown value under CertCredential: "
+ valueName[0]);
}
}
return simCredential;
}
/**
* Deserialize a list of {@link android.net.wifi.hotspot2.pps.Policy.RoamingPartner} from an
* input stream.
*
* @param in The input stream to read data from
* @param outerTagDepth The tag depth of the current XML section
* @return List of {@link android.net.wifi.hotspot2.pps.Policy.RoamingPartner}
* @throws XmlPullParserException
* @throws IOException
*/
private static List<Policy.RoamingPartner> deserializePreferredRoamingPartnerList(
XmlPullParser in, int outerTagDepth) throws XmlPullParserException, IOException {
List<Policy.RoamingPartner> roamingPartnerList = new ArrayList<>();
while (XmlUtil.gotoNextSectionWithNameOrEnd(in, XML_TAG_SECTION_HEADER_ROAMING_PARTNER,
outerTagDepth)) {
roamingPartnerList.add(deserializeRoamingPartner(in, outerTagDepth + 1));
}
return roamingPartnerList;
}
/**
* Deserialize a {@link android.net.wifi.hotspot2.pps.Policy.RoamingPartner} from an input
* stream.
*
* @param in The input stream to read data from
* @param outerTagDepth The tag depth of the current XML section
* @return {@link android.net.wifi.hotspot2.pps.Policy.RoamingPartner}
* @throws XmlPullParserException
* @throws IOException
*/
private static Policy.RoamingPartner deserializeRoamingPartner(XmlPullParser in,
int outerTagDepth) throws XmlPullParserException, IOException {
Policy.RoamingPartner partner = new Policy.RoamingPartner();
while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
String[] valueName = new String[1];
Object value = XmlUtil.readCurrentValue(in, valueName);
if (valueName[0] == null) {
throw new XmlPullParserException("Missing value name");
}
switch (valueName[0]) {
case XML_TAG_FQDN:
partner.setFqdn((String) value);
break;
case XML_TAG_FQDN_EXACT_MATCH:
partner.setFqdnExactMatch((boolean) value);
break;
case XML_TAG_PRIORITY:
partner.setPriority((int) value);
break;
case XML_TAG_COUNTRIES:
partner.setCountries((String) value);
break;
default:
throw new XmlPullParserException("Unknown value under RoamingPartner: "
+ valueName[0]);
}
}
return partner;
}
/**
* Deserialize a {@link UpdateParameter} from an input stream.
*
* @param in The input stream to read data from
* @param outerTagDepth The tag depth of the current XML section
* @return {@link UpdateParameter}
* @throws XmlPullParserException
* @throws IOException
*/
private static UpdateParameter deserializeUpdateParameter(XmlPullParser in,
int outerTagDepth) throws XmlPullParserException, IOException {
UpdateParameter param = new UpdateParameter();
while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
String[] valueName = new String[1];
Object value = XmlUtil.readCurrentValue(in, valueName);
if (valueName[0] == null) {
throw new XmlPullParserException("Missing value name");
}
switch (valueName[0]) {
case XML_TAG_UPDATE_INTERVAL:
param.setUpdateIntervalInMinutes((long) value);
break;
case XML_TAG_UPDATE_METHOD:
param.setUpdateMethod((String) value);
break;
case XML_TAG_RESTRICTION:
param.setRestriction((String) value);
break;
case XML_TAG_SERVER_URI:
param.setServerUri((String) value);
break;
case XML_TAG_USERNAME:
param.setUsername((String) value);
break;
case XML_TAG_PASSWORD:
param.setBase64EncodedPassword((String) value);
break;
case XML_TAG_TRUST_ROOT_CERT_URL:
param.setTrustRootCertUrl((String) value);
break;
case XML_TAG_TRUST_ROOT_CERT_SHA256_FINGERPRINT:
param.setTrustRootCertSha256Fingerprint((byte[]) value);
break;
default:
throw new XmlPullParserException("Unknown value under UpdateParameter: "
+ valueName[0]);
}
}
return param;
}
/**
* Deserialize a Protocol-Port map from an input stream.
*
* @param in The input stream to read data from
* @param outerTagDepth The tag depth of the current XML section
* @return Proocol-Port map
* @throws XmlPullParserException
* @throws IOException
*/
private static Map<Integer, String> deserializeProtoPortMap(XmlPullParser in,
int outerTagDepth) throws XmlPullParserException, IOException {
Map<Integer, String> protoPortMap = new HashMap<>();
while (XmlUtil.gotoNextSectionWithNameOrEnd(in, XML_TAG_SECTION_HEADER_PROTO_PORT,
outerTagDepth)) {
int proto = (int) XmlUtil.readNextValueWithName(in, XML_TAG_PROTO);
String ports = (String) XmlUtil.readNextValueWithName(in, XML_TAG_PORTS);
protoPortMap.put(proto, ports);
}
return protoPortMap;
}
/**
* Determine if the current element is a value or a section. The "name" attribute of the
* element is used as the indicator, when it is present, the element is considered a value
* element.
*
* Value element:
* <int name="test">12</int>
*
* Section element:
* <Test>
* ...
* </Test>
*
* @param in XML input stream
* @return true if the current element is a value
*/
private static boolean isValueElement(XmlPullParser in) {
return in.getAttributeValue(null, "name") != null;
}
}