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