XmlUtil.java revision 9ef555a48ac600c8766f703fa60db15b69e20301
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.wifi.util;
18
19import android.net.IpConfiguration;
20import android.net.IpConfiguration.IpAssignment;
21import android.net.IpConfiguration.ProxySettings;
22import android.net.LinkAddress;
23import android.net.NetworkUtils;
24import android.net.ProxyInfo;
25import android.net.RouteInfo;
26import android.net.StaticIpConfiguration;
27import android.net.wifi.WifiConfiguration;
28import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
29import android.net.wifi.WifiEnterpriseConfig;
30import android.util.Log;
31import android.util.Pair;
32
33import com.android.internal.util.XmlUtils;
34
35import org.xmlpull.v1.XmlPullParser;
36import org.xmlpull.v1.XmlPullParserException;
37import org.xmlpull.v1.XmlSerializer;
38
39import java.io.IOException;
40import java.net.Inet4Address;
41import java.net.InetAddress;
42import java.util.Arrays;
43import java.util.BitSet;
44import java.util.HashMap;
45
46/**
47 * Utils for manipulating XML data. This is essentially a wrapper over XmlUtils provided by core.
48 * The utility provides methods to write/parse section headers and write/parse values.
49 * This utility is designed for formatting the XML into the following format:
50 * <Document Header>
51 *  <Section 1 Header>
52 *   <Value 1>
53 *   <Value 2>
54 *   ...
55 *   <Sub Section 1 Header>
56 *    <Value 1>
57 *    <Value 2>
58 *    ...
59 *   </Sub Section 1 Header>
60 *  </Section 1 Header>
61 * </Document Header>
62 */
63public class XmlUtil {
64    private static final String TAG = "WifiXmlUtil";
65
66    /**
67     * Ensure that the XML stream is at a start tag or the end of document.
68     *
69     * @throws XmlPullParserException if parsing errors occur.
70     */
71    private static void gotoStartTag(XmlPullParser in)
72            throws XmlPullParserException, IOException {
73        int type = in.getEventType();
74        while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) {
75            type = in.next();
76        }
77    }
78
79    /**
80     * Ensure that the XML stream is at an end tag or the end of document.
81     *
82     * @throws XmlPullParserException if parsing errors occur.
83     */
84    private static void gotoEndTag(XmlPullParser in)
85            throws XmlPullParserException, IOException {
86        int type = in.getEventType();
87        while (type != XmlPullParser.END_TAG && type != XmlPullParser.END_DOCUMENT) {
88            type = in.next();
89        }
90    }
91
92    /**
93     * Start processing the XML stream at the document header.
94     *
95     * @param in         XmlPullParser instance pointing to the XML stream.
96     * @param headerName expected name for the start tag.
97     * @throws XmlPullParserException if parsing errors occur.
98     */
99    public static void gotoDocumentStart(XmlPullParser in, String headerName)
100            throws XmlPullParserException, IOException {
101        XmlUtils.beginDocument(in, headerName);
102    }
103
104    /**
105     * Move the XML stream to the next section header or indicate if there are no more sections.
106     * The provided outerDepth is used to find sub sections within that depth.
107     *
108     * Use this to move across sections if the ordering of sections are variable. The returned name
109     * can be used to decide what section is next.
110     *
111     * @param in         XmlPullParser instance pointing to the XML stream.
112     * @param headerName An array of one string, used to return the name of the next section.
113     * @param outerDepth Find section within this depth.
114     * @return {@code true} if a next section is found, {@code false} if there are no more sections.
115     * @throws XmlPullParserException if parsing errors occur.
116     */
117    public static boolean gotoNextSectionOrEnd(
118            XmlPullParser in, String[] headerName, int outerDepth)
119            throws XmlPullParserException, IOException {
120        if (XmlUtils.nextElementWithin(in, outerDepth)) {
121            headerName[0] = in.getName();
122            return true;
123        }
124        return false;
125    }
126
127    /**
128     * Move the XML stream to the next section header or indicate if there are no more sections.
129     * If a section, exists ensure that the name matches the provided name.
130     * The provided outerDepth is used to find sub sections within that depth.
131     *
132     * Use this to move across repeated sections until the end.
133     *
134     * @param in           XmlPullParser instance pointing to the XML stream.
135     * @param expectedName expected name for the section header.
136     * @param outerDepth   Find section within this depth.
137     * @return {@code true} if a next section is found, {@code false} if there are no more sections.
138     * @throws XmlPullParserException if the section header name does not match |expectedName|,
139     *                                or if parsing errors occur.
140     */
141    public static boolean gotoNextSectionWithNameOrEnd(
142            XmlPullParser in, String expectedName, int outerDepth)
143            throws XmlPullParserException, IOException {
144        String[] headerName = new String[1];
145        if (gotoNextSectionOrEnd(in, headerName, outerDepth)) {
146            if (headerName[0].equals(expectedName)) {
147                return true;
148            }
149            throw new XmlPullParserException(
150                    "Next section name does not match expected name: " + expectedName);
151        }
152        return false;
153    }
154
155    /**
156     * Move the XML stream to the next section header and ensure that the name matches the provided
157     * name.
158     * The provided outerDepth is used to find sub sections within that depth.
159     *
160     * Use this to move across sections if the ordering of sections are fixed.
161     *
162     * @param in           XmlPullParser instance pointing to the XML stream.
163     * @param expectedName expected name for the section header.
164     * @param outerDepth   Find section within this depth.
165     * @throws XmlPullParserException if the section header name does not match |expectedName|,
166     *                                there are no more sections or if parsing errors occur.
167     */
168    public static void gotoNextSectionWithName(
169            XmlPullParser in, String expectedName, int outerDepth)
170            throws XmlPullParserException, IOException {
171        if (!gotoNextSectionWithNameOrEnd(in, expectedName, outerDepth)) {
172            throw new XmlPullParserException("Section not found. Expected: " + expectedName);
173        }
174    }
175
176    /**
177     * Checks if the stream is at the end of a section of values. This moves the stream to next tag
178     * and checks if it finds an end tag at the specified depth.
179     *
180     * @param in           XmlPullParser instance pointing to the XML stream.
181     * @param sectionDepth depth of the start tag of this section. Used to match the end tag.
182     * @return {@code true} if a end tag at the provided depth is found, {@code false} otherwise
183     * @throws XmlPullParserException if parsing errors occur.
184     */
185    public static boolean isNextSectionEnd(XmlPullParser in, int sectionDepth)
186            throws XmlPullParserException, IOException {
187        return !XmlUtils.nextElementWithin(in, sectionDepth);
188    }
189
190    /**
191     * Read the current value in the XML stream using core XmlUtils and stores the retrieved
192     * value name in the string provided. This method reads the value contained in current start
193     * tag.
194     * Note: Because there could be genuine null values being read from the XML, this method raises
195     * an exception to indicate errors.
196     *
197     * @param in        XmlPullParser instance pointing to the XML stream.
198     * @param valueName An array of one string, used to return the name attribute
199     *                  of the value's tag.
200     * @return value retrieved from the XML stream.
201     * @throws XmlPullParserException if parsing errors occur.
202     */
203    public static Object readCurrentValue(XmlPullParser in, String[] valueName)
204            throws XmlPullParserException, IOException {
205        Object value = XmlUtils.readValueXml(in, valueName);
206        // XmlUtils.readValue does not always move the stream to the end of the tag. So, move
207        // it to the end tag before returning from here.
208        gotoEndTag(in);
209        return value;
210    }
211
212    /**
213     * Read the next value in the XML stream using core XmlUtils and ensure that it matches the
214     * provided name. This method moves the stream to the next start tag and reads the value
215     * contained in it.
216     * Note: Because there could be genuine null values being read from the XML, this method raises
217     * an exception to indicate errors.
218     *
219     * @param in XmlPullParser instance pointing to the XML stream.
220     * @return value retrieved from the XML stream.
221     * @throws XmlPullParserException if the value read does not match |expectedName|,
222     *                                or if parsing errors occur.
223     */
224    public static Object readNextValueWithName(XmlPullParser in, String expectedName)
225            throws XmlPullParserException, IOException {
226        String[] valueName = new String[1];
227        XmlUtils.nextElement(in);
228        Object value = readCurrentValue(in, valueName);
229        if (valueName[0].equals(expectedName)) {
230            return value;
231        }
232        throw new XmlPullParserException(
233                "Value not found. Expected: " + expectedName + ", but got: " + valueName[0]);
234    }
235
236    /**
237     * Write the XML document start with the provided document header name.
238     *
239     * @param out        XmlSerializer instance pointing to the XML stream.
240     * @param headerName name for the start tag.
241     */
242    public static void writeDocumentStart(XmlSerializer out, String headerName)
243            throws IOException {
244        out.startDocument(null, true);
245        out.startTag(null, headerName);
246    }
247
248    /**
249     * Write the XML document end with the provided document header name.
250     *
251     * @param out        XmlSerializer instance pointing to the XML stream.
252     * @param headerName name for the end tag.
253     */
254    public static void writeDocumentEnd(XmlSerializer out, String headerName)
255            throws IOException {
256        out.endTag(null, headerName);
257        out.endDocument();
258    }
259
260    /**
261     * Write a section start header tag with the provided section name.
262     *
263     * @param out        XmlSerializer instance pointing to the XML stream.
264     * @param headerName name for the start tag.
265     */
266    public static void writeNextSectionStart(XmlSerializer out, String headerName)
267            throws IOException {
268        out.startTag(null, headerName);
269    }
270
271    /**
272     * Write a section end header tag with the provided section name.
273     *
274     * @param out        XmlSerializer instance pointing to the XML stream.
275     * @param headerName name for the end tag.
276     */
277    public static void writeNextSectionEnd(XmlSerializer out, String headerName)
278            throws IOException {
279        out.endTag(null, headerName);
280    }
281
282    /**
283     * Write the value with the provided name in the XML stream using core XmlUtils.
284     *
285     * @param out   XmlSerializer instance pointing to the XML stream.
286     * @param name  name of the value.
287     * @param value value to be written.
288     */
289    public static void writeNextValue(XmlSerializer out, String name, Object value)
290            throws XmlPullParserException, IOException {
291        XmlUtils.writeValueXml(value, name, out);
292    }
293
294    /**
295     * Utility class to serialize and deseriaize {@link WifiConfiguration} object to XML &
296     * vice versa.
297     * This is used by both {@link com.android.server.wifi.WifiConfigStore} &
298     * {@link com.android.server.wifi.WifiBackupRestore} modules.
299     * The |writeConfigurationToXml| has 2 versions, one for backup and one for config store.
300     * There is only 1 version of |parseXmlToConfiguration| for both backup & config store.
301     * The parse method is written so that any element added/deleted in future revisions can
302     * be easily handled.
303     */
304    public static class WifiConfigurationXmlUtil {
305        /**
306         * List of XML tags corresponding to WifiConfiguration object elements.
307         */
308        public static final String XML_TAG_SSID = "SSID";
309        public static final String XML_TAG_BSSID = "BSSID";
310        public static final String XML_TAG_CONFIG_KEY = "ConfigKey";
311        public static final String XML_TAG_PRE_SHARED_KEY = "PreSharedKey";
312        public static final String XML_TAG_WEP_KEYS = "WEPKeys";
313        public static final String XML_TAG_WEP_TX_KEY_INDEX = "WEPTxKeyIndex";
314        public static final String XML_TAG_HIDDEN_SSID = "HiddenSSID";
315        public static final String XML_TAG_REQUIRE_PMF = "RequirePMF";
316        public static final String XML_TAG_ALLOWED_KEY_MGMT = "AllowedKeyMgmt";
317        public static final String XML_TAG_ALLOWED_PROTOCOLS = "AllowedProtocols";
318        public static final String XML_TAG_ALLOWED_AUTH_ALGOS = "AllowedAuthAlgos";
319        public static final String XML_TAG_ALLOWED_GROUP_CIPHERS = "AllowedGroupCiphers";
320        public static final String XML_TAG_ALLOWED_PAIRWISE_CIPHERS = "AllowedPairwiseCiphers";
321        public static final String XML_TAG_SHARED = "Shared";
322        public static final String XML_TAG_STATUS = "Status";
323        public static final String XML_TAG_FQDN = "FQDN";
324        public static final String XML_TAG_PROVIDER_FRIENDLY_NAME = "ProviderFriendlyName";
325        public static final String XML_TAG_LINKED_NETWORKS_LIST = "LinkedNetworksList";
326        public static final String XML_TAG_DEFAULT_GW_MAC_ADDRESS = "DefaultGwMacAddress";
327        public static final String XML_TAG_VALIDATED_INTERNET_ACCESS = "ValidatedInternetAccess";
328        public static final String XML_TAG_NO_INTERNET_ACCESS_EXPECTED = "NoInternetAccessExpected";
329        public static final String XML_TAG_USER_APPROVED = "UserApproved";
330        public static final String XML_TAG_METERED_HINT = "MeteredHint";
331        public static final String XML_TAG_USE_EXTERNAL_SCORES = "UseExternalScores";
332        public static final String XML_TAG_NUM_ASSOCIATION = "NumAssociation";
333        public static final String XML_TAG_CREATOR_UID = "CreatorUid";
334        public static final String XML_TAG_CREATOR_NAME = "CreatorName";
335        public static final String XML_TAG_CREATION_TIME = "CreationTime";
336        public static final String XML_TAG_LAST_UPDATE_UID = "LastUpdateUid";
337        public static final String XML_TAG_LAST_UPDATE_NAME = "LastUpdateName";
338        public static final String XML_TAG_LAST_CONNECT_UID = "LastConnectUid";
339        public static final String XML_TAG_IS_LEGACY_PASSPOINT_CONFIG = "IsLegacyPasspointConfig";
340        public static final String XML_TAG_ROAMING_CONSORTIUM_OIS = "RoamingConsortiumOIs";
341
342        /**
343         * Write WepKeys to the XML stream.
344         * WepKeys array is intialized in WifiConfiguration constructor, but all of the elements
345         * are set to null. User may chose to set any one of the key elements in WifiConfiguration.
346         * XmlUtils serialization doesn't handle this array of nulls well .
347         * So, write empty strings if some of the keys are not initialized and null if all of
348         * the elements are empty.
349         */
350        private static void writeWepKeysToXml(XmlSerializer out, String[] wepKeys)
351                throws XmlPullParserException, IOException {
352            String[] wepKeysToWrite = new String[wepKeys.length];
353            boolean hasWepKey = false;
354            for (int i = 0; i < wepKeys.length; i++) {
355                if (wepKeys[i] == null) {
356                    wepKeysToWrite[i] = new String();
357                } else {
358                    wepKeysToWrite[i] = wepKeys[i];
359                    hasWepKey = true;
360                }
361            }
362            if (hasWepKey) {
363                XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, wepKeysToWrite);
364            } else {
365                XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, null);
366            }
367        }
368
369        /**
370         * Write the Configuration data elements that are common for backup & config store to the
371         * XML stream.
372         *
373         * @param out           XmlSerializer instance pointing to the XML stream.
374         * @param configuration WifiConfiguration object to be serialized.
375         */
376        public static void writeCommonElementsToXml(
377                XmlSerializer out, WifiConfiguration configuration)
378                throws XmlPullParserException, IOException {
379            XmlUtil.writeNextValue(out, XML_TAG_CONFIG_KEY, configuration.configKey());
380            XmlUtil.writeNextValue(out, XML_TAG_SSID, configuration.SSID);
381            XmlUtil.writeNextValue(out, XML_TAG_BSSID, configuration.BSSID);
382            XmlUtil.writeNextValue(out, XML_TAG_PRE_SHARED_KEY, configuration.preSharedKey);
383            writeWepKeysToXml(out, configuration.wepKeys);
384            XmlUtil.writeNextValue(out, XML_TAG_WEP_TX_KEY_INDEX, configuration.wepTxKeyIndex);
385            XmlUtil.writeNextValue(out, XML_TAG_HIDDEN_SSID, configuration.hiddenSSID);
386            XmlUtil.writeNextValue(out, XML_TAG_REQUIRE_PMF, configuration.requirePMF);
387            XmlUtil.writeNextValue(
388                    out, XML_TAG_ALLOWED_KEY_MGMT,
389                    configuration.allowedKeyManagement.toByteArray());
390            XmlUtil.writeNextValue(
391                    out, XML_TAG_ALLOWED_PROTOCOLS,
392                    configuration.allowedProtocols.toByteArray());
393            XmlUtil.writeNextValue(
394                    out, XML_TAG_ALLOWED_AUTH_ALGOS,
395                    configuration.allowedAuthAlgorithms.toByteArray());
396            XmlUtil.writeNextValue(
397                    out, XML_TAG_ALLOWED_GROUP_CIPHERS,
398                    configuration.allowedGroupCiphers.toByteArray());
399            XmlUtil.writeNextValue(
400                    out, XML_TAG_ALLOWED_PAIRWISE_CIPHERS,
401                    configuration.allowedPairwiseCiphers.toByteArray());
402            XmlUtil.writeNextValue(out, XML_TAG_SHARED, configuration.shared);
403        }
404
405        /**
406         * Write the Configuration data elements for backup from the provided Configuration to the
407         * XML stream.
408         * Note: This is a subset of the elements serialized for config store.
409         *
410         * @param out           XmlSerializer instance pointing to the XML stream.
411         * @param configuration WifiConfiguration object to be serialized.
412         */
413        public static void writeToXmlForBackup(XmlSerializer out, WifiConfiguration configuration)
414                throws XmlPullParserException, IOException {
415            writeCommonElementsToXml(out, configuration);
416        }
417
418        /**
419         * Write the Configuration data elements for config store from the provided Configuration
420         * to the XML stream.
421         *
422         * @param out           XmlSerializer instance pointing to the XML stream.
423         * @param configuration WifiConfiguration object to be serialized.
424         */
425        public static void writeToXmlForConfigStore(
426                XmlSerializer out, WifiConfiguration configuration)
427                throws XmlPullParserException, IOException {
428            writeCommonElementsToXml(out, configuration);
429            XmlUtil.writeNextValue(out, XML_TAG_STATUS, configuration.status);
430            XmlUtil.writeNextValue(out, XML_TAG_FQDN, configuration.FQDN);
431            XmlUtil.writeNextValue(
432                    out, XML_TAG_PROVIDER_FRIENDLY_NAME, configuration.providerFriendlyName);
433            XmlUtil.writeNextValue(
434                    out, XML_TAG_LINKED_NETWORKS_LIST, configuration.linkedConfigurations);
435            XmlUtil.writeNextValue(
436                    out, XML_TAG_DEFAULT_GW_MAC_ADDRESS, configuration.defaultGwMacAddress);
437            XmlUtil.writeNextValue(
438                    out, XML_TAG_VALIDATED_INTERNET_ACCESS, configuration.validatedInternetAccess);
439            XmlUtil.writeNextValue(
440                    out, XML_TAG_NO_INTERNET_ACCESS_EXPECTED,
441                    configuration.noInternetAccessExpected);
442            XmlUtil.writeNextValue(out, XML_TAG_USER_APPROVED, configuration.userApproved);
443            XmlUtil.writeNextValue(out, XML_TAG_METERED_HINT, configuration.meteredHint);
444            XmlUtil.writeNextValue(
445                    out, XML_TAG_USE_EXTERNAL_SCORES, configuration.useExternalScores);
446            XmlUtil.writeNextValue(out, XML_TAG_NUM_ASSOCIATION, configuration.numAssociation);
447            XmlUtil.writeNextValue(out, XML_TAG_CREATOR_UID, configuration.creatorUid);
448            XmlUtil.writeNextValue(out, XML_TAG_CREATOR_NAME, configuration.creatorName);
449            XmlUtil.writeNextValue(out, XML_TAG_CREATION_TIME, configuration.creationTime);
450            XmlUtil.writeNextValue(out, XML_TAG_LAST_UPDATE_UID, configuration.lastUpdateUid);
451            XmlUtil.writeNextValue(out, XML_TAG_LAST_UPDATE_NAME, configuration.lastUpdateName);
452            XmlUtil.writeNextValue(out, XML_TAG_LAST_CONNECT_UID, configuration.lastConnectUid);
453            XmlUtil.writeNextValue(
454                    out, XML_TAG_IS_LEGACY_PASSPOINT_CONFIG,
455                    configuration.isLegacyPasspointConfig);
456            XmlUtil.writeNextValue(
457                    out, XML_TAG_ROAMING_CONSORTIUM_OIS, configuration.roamingConsortiumIds);
458        }
459
460        /**
461         * Populate wepKeys array elements only if they were non-empty in the backup data.
462         *
463         * @throws XmlPullParserException if parsing errors occur.
464         */
465        private static void populateWepKeysFromXmlValue(Object value, String[] wepKeys)
466                throws XmlPullParserException, IOException {
467            String[] wepKeysInData = (String[]) value;
468            if (wepKeysInData == null) {
469                return;
470            }
471            if (wepKeysInData.length != wepKeys.length) {
472                throw new XmlPullParserException(
473                        "Invalid Wep Keys length: " + wepKeysInData.length);
474            }
475            for (int i = 0; i < wepKeys.length; i++) {
476                if (wepKeysInData[i].isEmpty()) {
477                    wepKeys[i] = null;
478                } else {
479                    wepKeys[i] = wepKeysInData[i];
480                }
481            }
482        }
483
484        /**
485         * Parses the configuration data elements from the provided XML stream to a
486         * WifiConfiguration object.
487         * Note: This is used for parsing both backup data and config store data. Looping through
488         * the tags make it easy to add or remove elements in the future versions if needed.
489         *
490         * @param in            XmlPullParser instance pointing to the XML stream.
491         * @param outerTagDepth depth of the outer tag in the XML document.
492         * @return Pair<Config key, WifiConfiguration object> if parsing is successful,
493         * null otherwise.
494         */
495        public static Pair<String, WifiConfiguration> parseFromXml(
496                XmlPullParser in, int outerTagDepth)
497                throws XmlPullParserException, IOException {
498            WifiConfiguration configuration = new WifiConfiguration();
499            String configKeyInData = null;
500
501            // Loop through and parse out all the elements from the stream within this section.
502            while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
503                String[] valueName = new String[1];
504                Object value = XmlUtil.readCurrentValue(in, valueName);
505                if (valueName[0] == null) {
506                    throw new XmlPullParserException("Missing value name");
507                }
508                switch (valueName[0]) {
509                    case XML_TAG_CONFIG_KEY:
510                        configKeyInData = (String) value;
511                        break;
512                    case XML_TAG_SSID:
513                        configuration.SSID = (String) value;
514                        break;
515                    case XML_TAG_BSSID:
516                        configuration.BSSID = (String) value;
517                        break;
518                    case XML_TAG_PRE_SHARED_KEY:
519                        configuration.preSharedKey = (String) value;
520                        break;
521                    case XML_TAG_WEP_KEYS:
522                        populateWepKeysFromXmlValue(value, configuration.wepKeys);
523                        break;
524                    case XML_TAG_WEP_TX_KEY_INDEX:
525                        configuration.wepTxKeyIndex = (int) value;
526                        break;
527                    case XML_TAG_HIDDEN_SSID:
528                        configuration.hiddenSSID = (boolean) value;
529                        break;
530                    case XML_TAG_REQUIRE_PMF:
531                        configuration.requirePMF = (boolean) value;
532                        break;
533                    case XML_TAG_ALLOWED_KEY_MGMT:
534                        byte[] allowedKeyMgmt = (byte[]) value;
535                        configuration.allowedKeyManagement = BitSet.valueOf(allowedKeyMgmt);
536                        break;
537                    case XML_TAG_ALLOWED_PROTOCOLS:
538                        byte[] allowedProtocols = (byte[]) value;
539                        configuration.allowedProtocols = BitSet.valueOf(allowedProtocols);
540                        break;
541                    case XML_TAG_ALLOWED_AUTH_ALGOS:
542                        byte[] allowedAuthAlgorithms = (byte[]) value;
543                        configuration.allowedAuthAlgorithms = BitSet.valueOf(allowedAuthAlgorithms);
544                        break;
545                    case XML_TAG_ALLOWED_GROUP_CIPHERS:
546                        byte[] allowedGroupCiphers = (byte[]) value;
547                        configuration.allowedGroupCiphers = BitSet.valueOf(allowedGroupCiphers);
548                        break;
549                    case XML_TAG_ALLOWED_PAIRWISE_CIPHERS:
550                        byte[] allowedPairwiseCiphers = (byte[]) value;
551                        configuration.allowedPairwiseCiphers =
552                                BitSet.valueOf(allowedPairwiseCiphers);
553                        break;
554                    case XML_TAG_SHARED:
555                        configuration.shared = (boolean) value;
556                        break;
557                    case XML_TAG_STATUS:
558                        configuration.status = (int) value;
559                        break;
560                    case XML_TAG_FQDN:
561                        configuration.FQDN = (String) value;
562                        break;
563                    case XML_TAG_PROVIDER_FRIENDLY_NAME:
564                        configuration.providerFriendlyName = (String) value;
565                        break;
566                    case XML_TAG_LINKED_NETWORKS_LIST:
567                        configuration.linkedConfigurations = (HashMap<String, Integer>) value;
568                        break;
569                    case XML_TAG_DEFAULT_GW_MAC_ADDRESS:
570                        configuration.defaultGwMacAddress = (String) value;
571                        break;
572                    case XML_TAG_VALIDATED_INTERNET_ACCESS:
573                        configuration.validatedInternetAccess = (boolean) value;
574                        break;
575                    case XML_TAG_NO_INTERNET_ACCESS_EXPECTED:
576                        configuration.noInternetAccessExpected = (boolean) value;
577                        break;
578                    case XML_TAG_USER_APPROVED:
579                        configuration.userApproved = (int) value;
580                        break;
581                    case XML_TAG_METERED_HINT:
582                        configuration.meteredHint = (boolean) value;
583                        break;
584                    case XML_TAG_USE_EXTERNAL_SCORES:
585                        configuration.useExternalScores = (boolean) value;
586                        break;
587                    case XML_TAG_NUM_ASSOCIATION:
588                        configuration.numAssociation = (int) value;
589                        break;
590                    case XML_TAG_CREATOR_UID:
591                        configuration.creatorUid = (int) value;
592                        break;
593                    case XML_TAG_CREATOR_NAME:
594                        configuration.creatorName = (String) value;
595                        break;
596                    case XML_TAG_CREATION_TIME:
597                        configuration.creationTime = (String) value;
598                        break;
599                    case XML_TAG_LAST_UPDATE_UID:
600                        configuration.lastUpdateUid = (int) value;
601                        break;
602                    case XML_TAG_LAST_UPDATE_NAME:
603                        configuration.lastUpdateName = (String) value;
604                        break;
605                    case XML_TAG_LAST_CONNECT_UID:
606                        configuration.lastConnectUid = (int) value;
607                        break;
608                    case XML_TAG_IS_LEGACY_PASSPOINT_CONFIG:
609                        configuration.isLegacyPasspointConfig = (boolean) value;
610                        break;
611                    case XML_TAG_ROAMING_CONSORTIUM_OIS:
612                        configuration.roamingConsortiumIds = (long[]) value;
613                        break;
614                    default:
615                        throw new XmlPullParserException(
616                                "Unknown value name found: " + valueName[0]);
617                }
618            }
619            return Pair.create(configKeyInData, configuration);
620        }
621    }
622
623    /**
624     * Utility class to serialize and deseriaize {@link IpConfiguration} object to XML & vice versa.
625     * This is used by both {@link com.android.server.wifi.WifiConfigStore} &
626     * {@link com.android.server.wifi.WifiBackupRestore} modules.
627     */
628    public static class IpConfigurationXmlUtil {
629
630        /**
631         * List of XML tags corresponding to IpConfiguration object elements.
632         */
633        public static final String XML_TAG_IP_ASSIGNMENT = "IpAssignment";
634        public static final String XML_TAG_LINK_ADDRESS = "LinkAddress";
635        public static final String XML_TAG_LINK_PREFIX_LENGTH = "LinkPrefixLength";
636        public static final String XML_TAG_GATEWAY_ADDRESS = "GatewayAddress";
637        public static final String XML_TAG_DNS_SERVER_ADDRESSES = "DNSServers";
638        public static final String XML_TAG_PROXY_SETTINGS = "ProxySettings";
639        public static final String XML_TAG_PROXY_HOST = "ProxyHost";
640        public static final String XML_TAG_PROXY_PORT = "ProxyPort";
641        public static final String XML_TAG_PROXY_PAC_FILE = "ProxyPac";
642        public static final String XML_TAG_PROXY_EXCLUSION_LIST = "ProxyExclusionList";
643
644        /**
645         * Write the static IP configuration data elements to XML stream.
646         */
647        private static void writeStaticIpConfigurationToXml(
648                XmlSerializer out, StaticIpConfiguration staticIpConfiguration)
649                throws XmlPullParserException, IOException {
650            if (staticIpConfiguration.ipAddress != null) {
651                XmlUtil.writeNextValue(
652                        out, XML_TAG_LINK_ADDRESS,
653                        staticIpConfiguration.ipAddress.getAddress().getHostAddress());
654                XmlUtil.writeNextValue(
655                        out, XML_TAG_LINK_PREFIX_LENGTH,
656                        staticIpConfiguration.ipAddress.getPrefixLength());
657            } else {
658                XmlUtil.writeNextValue(
659                        out, XML_TAG_LINK_ADDRESS, null);
660                XmlUtil.writeNextValue(
661                        out, XML_TAG_LINK_PREFIX_LENGTH, null);
662            }
663            if (staticIpConfiguration.gateway != null) {
664                XmlUtil.writeNextValue(
665                        out, XML_TAG_GATEWAY_ADDRESS,
666                        staticIpConfiguration.gateway.getHostAddress());
667            } else {
668                XmlUtil.writeNextValue(
669                        out, XML_TAG_GATEWAY_ADDRESS, null);
670
671            }
672            if (staticIpConfiguration.dnsServers != null) {
673                // Create a string array of DNS server addresses
674                String[] dnsServers = new String[staticIpConfiguration.dnsServers.size()];
675                int dnsServerIdx = 0;
676                for (InetAddress inetAddr : staticIpConfiguration.dnsServers) {
677                    dnsServers[dnsServerIdx++] = inetAddr.getHostAddress();
678                }
679                XmlUtil.writeNextValue(
680                        out, XML_TAG_DNS_SERVER_ADDRESSES, dnsServers);
681            } else {
682                XmlUtil.writeNextValue(
683                        out, XML_TAG_DNS_SERVER_ADDRESSES, null);
684            }
685        }
686
687        /**
688         * Write the IP configuration data elements from the provided Configuration to the XML
689         * stream.
690         *
691         * @param out             XmlSerializer instance pointing to the XML stream.
692         * @param ipConfiguration IpConfiguration object to be serialized.
693         */
694        public static void writeToXml(XmlSerializer out, IpConfiguration ipConfiguration)
695                throws XmlPullParserException, IOException {
696            // Write IP assignment settings
697            XmlUtil.writeNextValue(out, XML_TAG_IP_ASSIGNMENT,
698                    ipConfiguration.ipAssignment.toString());
699            switch (ipConfiguration.ipAssignment) {
700                case STATIC:
701                    writeStaticIpConfigurationToXml(
702                            out, ipConfiguration.getStaticIpConfiguration());
703                    break;
704                default:
705                    break;
706            }
707
708            // Write proxy settings
709            XmlUtil.writeNextValue(
710                    out, XML_TAG_PROXY_SETTINGS,
711                    ipConfiguration.proxySettings.toString());
712            switch (ipConfiguration.proxySettings) {
713                case STATIC:
714                    XmlUtil.writeNextValue(
715                            out, XML_TAG_PROXY_HOST,
716                            ipConfiguration.httpProxy.getHost());
717                    XmlUtil.writeNextValue(
718                            out, XML_TAG_PROXY_PORT,
719                            ipConfiguration.httpProxy.getPort());
720                    XmlUtil.writeNextValue(
721                            out, XML_TAG_PROXY_EXCLUSION_LIST,
722                            ipConfiguration.httpProxy.getExclusionListAsString());
723                    break;
724                case PAC:
725                    XmlUtil.writeNextValue(
726                            out, XML_TAG_PROXY_PAC_FILE,
727                            ipConfiguration.httpProxy.getPacFileUrl().toString());
728                    break;
729                default:
730                    break;
731            }
732        }
733
734        /**
735         * Parse out the static IP configuration from the XML stream.
736         */
737        private static StaticIpConfiguration parseStaticIpConfigurationFromXml(XmlPullParser in)
738                throws XmlPullParserException, IOException {
739            StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
740
741            String linkAddressString =
742                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_ADDRESS);
743            Integer linkPrefixLength =
744                    (Integer) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_PREFIX_LENGTH);
745            if (linkAddressString != null && linkPrefixLength != null) {
746                LinkAddress linkAddress = new LinkAddress(
747                        NetworkUtils.numericToInetAddress(linkAddressString),
748                        linkPrefixLength);
749                if (linkAddress.getAddress() instanceof Inet4Address) {
750                    staticIpConfiguration.ipAddress = linkAddress;
751                } else {
752                    Log.w(TAG, "Non-IPv4 address: " + linkAddress);
753                }
754            }
755            String gatewayAddressString =
756                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_GATEWAY_ADDRESS);
757            if (gatewayAddressString != null) {
758                LinkAddress dest = null;
759                InetAddress gateway =
760                        NetworkUtils.numericToInetAddress(gatewayAddressString);
761                RouteInfo route = new RouteInfo(dest, gateway);
762                if (route.isIPv4Default()) {
763                    staticIpConfiguration.gateway = gateway;
764                } else {
765                    Log.w(TAG, "Non-IPv4 default route: " + route);
766                }
767            }
768            String[] dnsServerAddressesString =
769                    (String[]) XmlUtil.readNextValueWithName(in, XML_TAG_DNS_SERVER_ADDRESSES);
770            if (dnsServerAddressesString != null) {
771                for (String dnsServerAddressString : dnsServerAddressesString) {
772                    InetAddress dnsServerAddress =
773                            NetworkUtils.numericToInetAddress(dnsServerAddressString);
774                    staticIpConfiguration.dnsServers.add(dnsServerAddress);
775                }
776            }
777            return staticIpConfiguration;
778        }
779
780        /**
781         * Parses the IP configuration data elements from the provided XML stream to an
782         * IpConfiguration object.
783         *
784         * @param in            XmlPullParser instance pointing to the XML stream.
785         * @param outerTagDepth depth of the outer tag in the XML document.
786         * @return IpConfiguration object if parsing is successful, null otherwise.
787         */
788        public static IpConfiguration parseFromXml(XmlPullParser in, int outerTagDepth)
789                throws XmlPullParserException, IOException {
790            IpConfiguration ipConfiguration = new IpConfiguration();
791
792            // Parse out the IP assignment info first.
793            String ipAssignmentString =
794                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_IP_ASSIGNMENT);
795            IpAssignment ipAssignment = IpAssignment.valueOf(ipAssignmentString);
796            ipConfiguration.setIpAssignment(ipAssignment);
797            switch (ipAssignment) {
798                case STATIC:
799                    ipConfiguration.setStaticIpConfiguration(parseStaticIpConfigurationFromXml(in));
800                    break;
801                case DHCP:
802                case UNASSIGNED:
803                    break;
804                default:
805                    throw new XmlPullParserException("Unknown ip assignment type: " + ipAssignment);
806            }
807
808            // Parse out the proxy settings next.
809            String proxySettingsString =
810                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_SETTINGS);
811            ProxySettings proxySettings = ProxySettings.valueOf(proxySettingsString);
812            ipConfiguration.setProxySettings(proxySettings);
813            switch (proxySettings) {
814                case STATIC:
815                    String proxyHost =
816                            (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_HOST);
817                    int proxyPort =
818                            (int) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PORT);
819                    String proxyExclusionList =
820                            (String) XmlUtil.readNextValueWithName(
821                                    in, XML_TAG_PROXY_EXCLUSION_LIST);
822                    ipConfiguration.setHttpProxy(
823                            new ProxyInfo(proxyHost, proxyPort, proxyExclusionList));
824                    break;
825                case PAC:
826                    String proxyPacFile =
827                            (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PAC_FILE);
828                    ipConfiguration.setHttpProxy(new ProxyInfo(proxyPacFile));
829                    break;
830                case NONE:
831                case UNASSIGNED:
832                    break;
833                default:
834                    throw new XmlPullParserException(
835                            "Unknown proxy settings type: " + proxySettings);
836            }
837            return ipConfiguration;
838        }
839    }
840
841    /**
842     * Utility class to serialize and deseriaize {@link NetworkSelectionStatus} object to XML &
843     * vice versa. This is used by {@link com.android.server.wifi.WifiConfigStore} module.
844     */
845    public static class NetworkSelectionStatusXmlUtil {
846
847        /**
848         * List of XML tags corresponding to NetworkSelectionStatus object elements.
849         */
850        public static final String XML_TAG_SELECTION_STATUS = "SelectionStatus";
851        public static final String XML_TAG_DISABLE_REASON = "DisableReason";
852        public static final String XML_TAG_CONNECT_CHOICE = "ConnectChoice";
853        public static final String XML_TAG_CONNECT_CHOICE_TIMESTAMP = "ConnectChoiceTimeStamp";
854        public static final String XML_TAG_HAS_EVER_CONNECTED = "HasEverConnected";
855
856        /**
857         * Write the NetworkSelectionStatus data elements from the provided status to the XML
858         * stream.
859         *
860         * @param out             XmlSerializer instance pointing to the XML stream.
861         * @param selectionStatus NetworkSelectionStatus object to be serialized.
862         */
863        public static void writeToXml(XmlSerializer out, NetworkSelectionStatus selectionStatus)
864                throws XmlPullParserException, IOException {
865            XmlUtil.writeNextValue(
866                    out, XML_TAG_SELECTION_STATUS, selectionStatus.getNetworkStatusString());
867            XmlUtil.writeNextValue(
868                    out, XML_TAG_DISABLE_REASON, selectionStatus.getNetworkDisableReasonString());
869            XmlUtil.writeNextValue(out, XML_TAG_CONNECT_CHOICE, selectionStatus.getConnectChoice());
870            XmlUtil.writeNextValue(
871                    out, XML_TAG_CONNECT_CHOICE_TIMESTAMP,
872                    selectionStatus.getConnectChoiceTimestamp());
873            XmlUtil.writeNextValue(
874                    out, XML_TAG_HAS_EVER_CONNECTED, selectionStatus.getHasEverConnected());
875        }
876
877        /**
878         * Parses the NetworkSelectionStatus data elements from the provided XML stream to a
879         * NetworkSelectionStatus object.
880         *
881         * @param in            XmlPullParser instance pointing to the XML stream.
882         * @param outerTagDepth depth of the outer tag in the XML document.
883         * @return NetworkSelectionStatus object if parsing is successful, null otherwise.
884         */
885        public static NetworkSelectionStatus parseFromXml(XmlPullParser in, int outerTagDepth)
886                throws XmlPullParserException, IOException {
887            NetworkSelectionStatus selectionStatus = new NetworkSelectionStatus();
888            String statusString = "";
889            String disableReasonString = "";
890
891            // Loop through and parse out all the elements from the stream within this section.
892            while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
893                String[] valueName = new String[1];
894                Object value = XmlUtil.readCurrentValue(in, valueName);
895                if (valueName[0] == null) {
896                    throw new XmlPullParserException("Missing value name");
897                }
898                switch (valueName[0]) {
899                    case XML_TAG_SELECTION_STATUS:
900                        statusString = (String) value;
901                        break;
902                    case XML_TAG_DISABLE_REASON:
903                        disableReasonString = (String) value;
904                        break;
905                    case XML_TAG_CONNECT_CHOICE:
906                        selectionStatus.setConnectChoice((String) value);
907                        break;
908                    case XML_TAG_CONNECT_CHOICE_TIMESTAMP:
909                        selectionStatus.setConnectChoiceTimestamp((long) value);
910                        break;
911                    case XML_TAG_HAS_EVER_CONNECTED:
912                        selectionStatus.setHasEverConnected((boolean) value);
913                        break;
914                    default:
915                        throw new XmlPullParserException(
916                                "Unknown value name found: " + valueName[0]);
917                }
918            }
919            // Now figure out the network selection status codes from |selectionStatusString| &
920            // |disableReasonString|.
921            int status =
922                    Arrays.asList(NetworkSelectionStatus.QUALITY_NETWORK_SELECTION_STATUS)
923                            .indexOf(statusString);
924            int disableReason =
925                    Arrays.asList(NetworkSelectionStatus.QUALITY_NETWORK_SELECTION_DISABLE_REASON)
926                            .indexOf(disableReasonString);
927
928            // If either of the above codes are invalid or if the network was temporarily disabled
929            // (blacklisted), restore the status as enabled. We don't want to persist blacklists
930            // across reboots.
931            if (status == -1 || disableReason == -1 ||
932                    status == NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED) {
933                status = NetworkSelectionStatus.NETWORK_SELECTION_ENABLED;
934                disableReason = NetworkSelectionStatus.NETWORK_SELECTION_ENABLE;
935            }
936            selectionStatus.setNetworkSelectionStatus(status);
937            selectionStatus.setNetworkSelectionDisableReason(disableReason);
938            return selectionStatus;
939        }
940    }
941
942    /**
943     * Utility class to serialize and deseriaize {@link WifiEnterpriseConfig} object to XML &
944     * vice versa. This is used by {@link com.android.server.wifi.WifiConfigStore} module.
945     */
946    public static class WifiEnterpriseConfigXmlUtil {
947
948        /**
949         * List of XML tags corresponding to WifiEnterpriseConfig object elements.
950         */
951        public static final String XML_TAG_IDENTITY = "Identity";
952        public static final String XML_TAG_ANON_IDENTITY = "AnonIdentity";
953        public static final String XML_TAG_PASSWORD = "Password";
954        public static final String XML_TAG_CLIENT_CERT = "ClientCert";
955        public static final String XML_TAG_CA_CERT = "CaCert";
956        public static final String XML_TAG_SUBJECT_MATCH = "SubjectMatch";
957        public static final String XML_TAG_ENGINE = "Engine";
958        public static final String XML_TAG_ENGINE_ID = "EngineId";
959        public static final String XML_TAG_PRIVATE_KEY_ID = "PrivateKeyId";
960        public static final String XML_TAG_ALT_SUBJECT_MATCH = "AltSubjectMatch";
961        public static final String XML_TAG_DOM_SUFFIX_MATCH = "DomSuffixMatch";
962        public static final String XML_TAG_CA_PATH = "CaPath";
963        public static final String XML_TAG_EAP_METHOD = "EapMethod";
964        public static final String XML_TAG_PHASE2_METHOD = "Phase2Method";
965        public static final String XML_TAG_PLMN = "PLMN";
966        public static final String XML_TAG_REALM = "Realm";
967
968        /**
969         * Write the WifiEnterpriseConfig data elements from the provided config to the XML
970         * stream.
971         *
972         * @param out              XmlSerializer instance pointing to the XML stream.
973         * @param enterpriseConfig WifiEnterpriseConfig object to be serialized.
974         */
975        public static void writeToXml(XmlSerializer out, WifiEnterpriseConfig enterpriseConfig)
976                throws XmlPullParserException, IOException {
977            XmlUtil.writeNextValue(out, XML_TAG_IDENTITY,
978                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY));
979            XmlUtil.writeNextValue(out, XML_TAG_ANON_IDENTITY,
980                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY));
981            XmlUtil.writeNextValue(out, XML_TAG_PASSWORD,
982                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY));
983            XmlUtil.writeNextValue(out, XML_TAG_CLIENT_CERT,
984                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY));
985            XmlUtil.writeNextValue(out, XML_TAG_CA_CERT,
986                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY));
987            XmlUtil.writeNextValue(out, XML_TAG_SUBJECT_MATCH,
988                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY));
989            XmlUtil.writeNextValue(out, XML_TAG_ENGINE,
990                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_KEY));
991            XmlUtil.writeNextValue(out, XML_TAG_ENGINE_ID,
992                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY));
993            XmlUtil.writeNextValue(out, XML_TAG_PRIVATE_KEY_ID,
994                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY));
995            XmlUtil.writeNextValue(out, XML_TAG_ALT_SUBJECT_MATCH,
996                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY));
997            XmlUtil.writeNextValue(out, XML_TAG_DOM_SUFFIX_MATCH,
998                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY));
999            XmlUtil.writeNextValue(out, XML_TAG_CA_PATH,
1000                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY));
1001            XmlUtil.writeNextValue(out, XML_TAG_EAP_METHOD, enterpriseConfig.getEapMethod());
1002            XmlUtil.writeNextValue(out, XML_TAG_PHASE2_METHOD, enterpriseConfig.getPhase2Method());
1003            XmlUtil.writeNextValue(out, XML_TAG_PLMN, enterpriseConfig.getPlmn());
1004            XmlUtil.writeNextValue(out, XML_TAG_REALM, enterpriseConfig.getRealm());
1005        }
1006
1007        /**
1008         * Parses the data elements from the provided XML stream to a WifiEnterpriseConfig object.
1009         *
1010         * @param in            XmlPullParser instance pointing to the XML stream.
1011         * @param outerTagDepth depth of the outer tag in the XML document.
1012         * @return WifiEnterpriseConfig object if parsing is successful, null otherwise.
1013         */
1014        public static WifiEnterpriseConfig parseFromXml(XmlPullParser in, int outerTagDepth)
1015                throws XmlPullParserException, IOException {
1016            WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
1017
1018            // Loop through and parse out all the elements from the stream within this section.
1019            while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
1020                String[] valueName = new String[1];
1021                Object value = XmlUtil.readCurrentValue(in, valueName);
1022                if (valueName[0] == null) {
1023                    throw new XmlPullParserException("Missing value name");
1024                }
1025                switch (valueName[0]) {
1026                    case XML_TAG_IDENTITY:
1027                        enterpriseConfig.setFieldValue(
1028                                WifiEnterpriseConfig.IDENTITY_KEY, (String) value);
1029                        break;
1030                    case XML_TAG_ANON_IDENTITY:
1031                        enterpriseConfig.setFieldValue(
1032                                WifiEnterpriseConfig.ANON_IDENTITY_KEY, (String) value);
1033                        break;
1034                    case XML_TAG_PASSWORD:
1035                        enterpriseConfig.setFieldValue(
1036                                WifiEnterpriseConfig.PASSWORD_KEY, (String) value);
1037                        break;
1038                    case XML_TAG_CLIENT_CERT:
1039                        enterpriseConfig.setFieldValue(
1040                                WifiEnterpriseConfig.CLIENT_CERT_KEY, (String) value);
1041                        break;
1042                    case XML_TAG_CA_CERT:
1043                        enterpriseConfig.setFieldValue(
1044                                WifiEnterpriseConfig.CA_CERT_KEY, (String) value);
1045                        break;
1046                    case XML_TAG_SUBJECT_MATCH:
1047                        enterpriseConfig.setFieldValue(
1048                                WifiEnterpriseConfig.SUBJECT_MATCH_KEY, (String) value);
1049                        break;
1050                    case XML_TAG_ENGINE:
1051                        enterpriseConfig.setFieldValue(
1052                                WifiEnterpriseConfig.ENGINE_KEY, (String) value);
1053                        break;
1054                    case XML_TAG_ENGINE_ID:
1055                        enterpriseConfig.setFieldValue(
1056                                WifiEnterpriseConfig.ENGINE_ID_KEY, (String) value);
1057                        break;
1058                    case XML_TAG_PRIVATE_KEY_ID:
1059                        enterpriseConfig.setFieldValue(
1060                                WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, (String) value);
1061                        break;
1062                    case XML_TAG_ALT_SUBJECT_MATCH:
1063                        enterpriseConfig.setFieldValue(
1064                                WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, (String) value);
1065                        break;
1066                    case XML_TAG_DOM_SUFFIX_MATCH:
1067                        enterpriseConfig.setFieldValue(
1068                                WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, (String) value);
1069                        break;
1070                    case XML_TAG_CA_PATH:
1071                        enterpriseConfig.setFieldValue(
1072                                WifiEnterpriseConfig.CA_PATH_KEY, (String) value);
1073                        break;
1074                    case XML_TAG_EAP_METHOD:
1075                        enterpriseConfig.setEapMethod((int) value);
1076                        break;
1077                    case XML_TAG_PHASE2_METHOD:
1078                        enterpriseConfig.setPhase2Method((int) value);
1079                        break;
1080                    case XML_TAG_PLMN:
1081                        enterpriseConfig.setPlmn((String) value);
1082                        break;
1083                    case XML_TAG_REALM:
1084                        enterpriseConfig.setRealm((String) value);
1085                        break;
1086                    default:
1087                        throw new XmlPullParserException(
1088                                "Unknown value name found: " + valueName[0]);
1089                }
1090            }
1091            return enterpriseConfig;
1092        }
1093    }
1094}
1095
1096