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