XmlUtil.java revision 030c5debfefddf0512cd53fec48b269c08d9972e
12b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius/*
22b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * Copyright (C) 2016 The Android Open Source Project
32b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *
42b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * Licensed under the Apache License, Version 2.0 (the "License");
52b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * you may not use this file except in compliance with the License.
62b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * You may obtain a copy of the License at
72b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *
82b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *      http://www.apache.org/licenses/LICENSE-2.0
92b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *
102b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * Unless required by applicable law or agreed to in writing, software
112b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * distributed under the License is distributed on an "AS IS" BASIS,
122b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * See the License for the specific language governing permissions and
142b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * limitations under the License.
152b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius */
162b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
172b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piuspackage com.android.server.wifi.util;
182b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
19e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.IpConfiguration;
20e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.IpConfiguration.IpAssignment;
21e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.IpConfiguration.ProxySettings;
22e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.LinkAddress;
23e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.NetworkUtils;
24e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.ProxyInfo;
25e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.RouteInfo;
26e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.StaticIpConfiguration;
27e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.net.wifi.WifiConfiguration;
28e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport android.util.Log;
292fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Piusimport android.util.Pair;
30e33a4bb414892435c016486585c26022cafdab68Roshan Pius
312b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport com.android.internal.util.XmlUtils;
322b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
332b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport org.xmlpull.v1.XmlPullParser;
342b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport org.xmlpull.v1.XmlPullParserException;
352b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport org.xmlpull.v1.XmlSerializer;
362b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
372b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piusimport java.io.IOException;
38e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport java.net.Inet4Address;
39e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport java.net.InetAddress;
40e33a4bb414892435c016486585c26022cafdab68Roshan Piusimport java.util.BitSet;
41030c5debfefddf0512cd53fec48b269c08d9972eRoshan Piusimport java.util.HashMap;
422b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
432b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius/**
442b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * Utils for manipulating XML data. This is essentially a wrapper over XmlUtils provided by core.
452b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * The utility provides methods to write/parse section headers and write/parse values.
462b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * This utility is designed for formatting the XML into the following format:
472b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * <Document Header>
482b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *  <Section 1 Header>
492b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   <Value 1>
502b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   <Value 2>
512b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   ...
522b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   <Sub Section 1 Header>
532b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *    <Value 1>
542b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *    <Value 2>
552b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *    ...
562b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *   </Sub Section 1 Header>
572b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius *  </Section 1 Header>
582b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius * </Document Header>
592b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius */
602b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Piuspublic class XmlUtil {
612b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    private static final String TAG = "WifiXmlUtil";
622b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
632b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
64e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Ensure that the XML stream is at a start tag or the end of document.
65e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
66052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
672b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
68e33a4bb414892435c016486585c26022cafdab68Roshan Pius    private static void gotoStartTag(XmlPullParser in)
692b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
70e33a4bb414892435c016486585c26022cafdab68Roshan Pius        int type = in.getEventType();
71e33a4bb414892435c016486585c26022cafdab68Roshan Pius        while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) {
72e33a4bb414892435c016486585c26022cafdab68Roshan Pius            type = in.next();
73e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
74e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
75e33a4bb414892435c016486585c26022cafdab68Roshan Pius
76e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
77e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Ensure that the XML stream is at an end tag or the end of document.
78e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
79052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
80e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
81e33a4bb414892435c016486585c26022cafdab68Roshan Pius    private static void gotoEndTag(XmlPullParser in)
82e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws XmlPullParserException, IOException {
83e33a4bb414892435c016486585c26022cafdab68Roshan Pius        int type = in.getEventType();
84e33a4bb414892435c016486585c26022cafdab68Roshan Pius        while (type != XmlPullParser.END_TAG && type != XmlPullParser.END_DOCUMENT) {
85e33a4bb414892435c016486585c26022cafdab68Roshan Pius            type = in.next();
86e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
872b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
882b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
892b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
902b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Start processing the XML stream at the document header.
912b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
922b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param in         XmlPullParser instance pointing to the XML stream.
932b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName expected name for the start tag.
94052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
952b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
962b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void gotoDocumentStart(XmlPullParser in, String headerName)
972b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
982b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        XmlUtils.beginDocument(in, headerName);
992b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
1002b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
1012b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
102e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Move the XML stream to the next section header. The provided outerDepth is used to find
103e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * sub sections within that depth.
1042b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
1052b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param in         XmlPullParser instance pointing to the XML stream.
1062b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName expected name for the start tag.
1072b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param outerDepth Find section within this depth.
1082b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @return {@code true} if a start tag with the provided name is found, {@code false} otherwise
109052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
1102b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
1112b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static boolean gotoNextSection(XmlPullParser in, String headerName, int outerDepth)
1122b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
1132b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        while (XmlUtils.nextElementWithin(in, outerDepth)) {
1142b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            if (in.getName().equals(headerName)) {
1152b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius                return true;
1162b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            }
1172b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        }
1182b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        return false;
1192b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
1202b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
1212b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
122e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Checks if the stream is at the end of a section of values. This moves the stream to next tag
123e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * and checks if it finds an end tag at the specified depth.
124e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
125e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param in           XmlPullParser instance pointing to the XML stream.
126e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param sectionDepth depth of the start tag of this section. Used to match the end tag.
127e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @return {@code true} if a end tag at the provided depth is found, {@code false} otherwise
128052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
129e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
130e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static boolean isNextSectionEnd(XmlPullParser in, int sectionDepth)
131e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws XmlPullParserException, IOException {
132052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius        return (in.nextTag() == XmlPullParser.END_TAG && in.getDepth() == sectionDepth);
133e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
134e33a4bb414892435c016486585c26022cafdab68Roshan Pius
135e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
136e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Read the current value in the XML stream using core XmlUtils and stores the retrieved
137e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * value name in the string provided. This method reads the value contained in current start
138e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * tag.
139e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Note: Because there could be genuine null values being read from the XML, this method raises
140e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * an exception to indicate errors.
141e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *
142e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param in        XmlPullParser instance pointing to the XML stream.
143e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @param valueName An array of one string, used to return the name attribute
144e33a4bb414892435c016486585c26022cafdab68Roshan Pius     *                  of the value's tag.
145e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * @return value retrieved from the XML stream.
146052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if parsing errors occur.
147e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
148e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static Object readCurrentValue(XmlPullParser in, String[] valueName)
149e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws XmlPullParserException, IOException {
150e33a4bb414892435c016486585c26022cafdab68Roshan Pius        Object value = XmlUtils.readValueXml(in, valueName);
151e33a4bb414892435c016486585c26022cafdab68Roshan Pius        // XmlUtils.readValue does not always move the stream to the end of the tag. So, move
152e33a4bb414892435c016486585c26022cafdab68Roshan Pius        // it to the end tag before returning from here.
153e33a4bb414892435c016486585c26022cafdab68Roshan Pius        gotoEndTag(in);
154e33a4bb414892435c016486585c26022cafdab68Roshan Pius        return value;
155e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
156e33a4bb414892435c016486585c26022cafdab68Roshan Pius
157e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
1582b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Read the next value in the XML stream using core XmlUtils and ensure that it matches the
159e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * provided name. This method moves the stream to the next start tag and reads the value
160e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * contained in it.
1612b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Note: Because there could be genuine null values being read from the XML, this method raises
1622b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * an exception to indicate errors.
1632b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
1642b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param in XmlPullParser instance pointing to the XML stream.
1652b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @return value retrieved from the XML stream.
166052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     * @throws XmlPullParserException if the value read does not match |expectedName|,
167052b948a8b8a009486e35cb56dbd7bb9516e8626Roshan Pius     *                                or if parsing errors occur.
1682b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
169e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static Object readNextValueWithName(XmlPullParser in, String expectedName)
1702b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
171e33a4bb414892435c016486585c26022cafdab68Roshan Pius        String[] valueName = new String[1];
172e33a4bb414892435c016486585c26022cafdab68Roshan Pius        XmlUtils.nextElement(in);
173e33a4bb414892435c016486585c26022cafdab68Roshan Pius        Object value = readCurrentValue(in, valueName);
174e33a4bb414892435c016486585c26022cafdab68Roshan Pius        if (valueName[0].equals(expectedName)) {
1752b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            return value;
1762b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        }
1772b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        throw new XmlPullParserException(
178e33a4bb414892435c016486585c26022cafdab68Roshan Pius                "Value not found. Expected: " + expectedName + ", but got: " + valueName[0]);
1792b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
1802b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
1812b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
1822b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write the XML document start with the provided document header name.
1832b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
1842b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
1852b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the start tag.
1862b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
1872b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeDocumentStart(XmlSerializer out, String headerName)
188e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
1892b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.startDocument(null, true);
1902b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.startTag(null, headerName);
1912b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
1922b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
1932b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
1942b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write the XML document end with the provided document header name.
1952b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
1962b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
1972b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the end tag.
1982b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
1992b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeDocumentEnd(XmlSerializer out, String headerName)
200e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
2012b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.endTag(null, headerName);
2022b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.endDocument();
2032b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2042b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2052b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2062b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write a section start header tag with the provided section name.
2072b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2082b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
2092b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the start tag.
2102b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2112b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeNextSectionStart(XmlSerializer out, String headerName)
212e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
2132b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.startTag(null, headerName);
2142b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2152b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2162b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2172b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write a section end header tag with the provided section name.
2182b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2192b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out        XmlSerializer instance pointing to the XML stream.
2202b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param headerName name for the end tag.
2212b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2222b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeNextSectionEnd(XmlSerializer out, String headerName)
223e33a4bb414892435c016486585c26022cafdab68Roshan Pius            throws IOException {
2242b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        out.endTag(null, headerName);
2252b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
2262b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
2272b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    /**
2282b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * Write the value with the provided name in the XML stream using core XmlUtils.
2292b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     *
2302b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param out   XmlSerializer instance pointing to the XML stream.
2312b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param name  name of the value.
2322b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     * @param value value to be written.
2332b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius     */
2342b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    public static void writeNextValue(XmlSerializer out, String name, Object value)
2352b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius            throws XmlPullParserException, IOException {
2362b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius        XmlUtils.writeValueXml(value, name, out);
2372b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius    }
238e33a4bb414892435c016486585c26022cafdab68Roshan Pius
239e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
240e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Utility class to serialize and deseriaize WifConfiguration object to XML & vice versa.
241e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * This is used by both #com.android.server.wifi.WifiConfigStore &
242e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * #com.android.server.wifi.WifiBackupRestore modules.
243e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * The |writeConfigurationToXml| has 2 versions, one for backup and one for config store.
244e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * There is only 1 version of |parseXmlToConfiguration| for both backup & config store.
245e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * The parse method is written so that any element added/deleted in future revisions can
246e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * be easily handled.
247e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
248e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static class WifiConfigurationXmlUtil {
249e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
250e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * List of XML tags corresponding to WifiConfiguration object elements.
251e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
252e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_SSID = "SSID";
253e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_BSSID = "BSSID";
254e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_CONFIG_KEY = "ConfigKey";
255e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PRE_SHARED_KEY = "PreSharedKey";
256e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_WEP_KEYS = "WEPKeys";
257e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_WEP_TX_KEY_INDEX = "WEPTxKeyIndex";
258e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_HIDDEN_SSID = "HiddenSSID";
259e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_ALLOWED_KEY_MGMT = "AllowedKeyMgmt";
260e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_ALLOWED_PROTOCOLS = "AllowedProtocols";
261e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_ALLOWED_AUTH_ALGOS = "AllowedAuthAlgos";
262e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_SHARED = "Shared";
263030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_FQDN = "FQDN";
264030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_PROVIDER_FRIENDLY_NAME = "ProviderFriendlyName";
265030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_LINKED_NETWORKS_LIST = "LinkedNetworksList";
266030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_DEFAULT_GW_MAC_ADDRESS = "DefaultGwMacAddress";
267030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_VALIDATED_INTERNET_ACCESS = "ValidatedInternetAccess";
268030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_NO_INTERNET_ACCESS_EXPECTED = "NoInternetAccessExpected";
269030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_USER_APPROVED = "UserApproved";
270030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_METERED_HINT = "MeteredHint";
271030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_USE_EXTERNAL_SCORES = "UseExternalScores";
272030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_NUM_ASSOCIATION = "NumAssociation";
273e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_CREATOR_UID = "CreatorUid";
2742fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius        public static final String XML_TAG_CREATOR_NAME = "CreatorName";
275030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_CREATION_TIME = "CreationTime";
276030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_LAST_UPDATE_UID = "LastUpdateUid";
277030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_LAST_UPDATE_NAME = "LastUpdateName";
278030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius        public static final String XML_TAG_LAST_CONNECT_UID = "LastConnectUid";
279e33a4bb414892435c016486585c26022cafdab68Roshan Pius
280e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
281e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write WepKeys to the XML stream.
282e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * WepKeys array is intialized in WifiConfiguration constructor, but all of the elements
28306a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * are set to null. User may chose to set any one of the key elements in WifiConfiguration.
28406a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * XmlUtils serialization doesn't handle this array of nulls well .
28506a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * So, write empty strings if some of the keys are not initialized and null if all of
28606a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * the elements are empty.
287e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
288e33a4bb414892435c016486585c26022cafdab68Roshan Pius        private static void writeWepKeysToXml(XmlSerializer out, String[] wepKeys)
289e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
29006a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            String[] wepKeysToWrite = new String[wepKeys.length];
29106a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            boolean hasWepKey = false;
29206a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            for (int i = 0; i < wepKeys.length; i++) {
29306a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                if (wepKeys[i] == null) {
29406a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    wepKeysToWrite[i] = new String();
29506a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                } else {
29606a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    wepKeysToWrite[i] = wepKeys[i];
29706a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    hasWepKey = true;
29806a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                }
29906a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            }
30006a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            if (hasWepKey) {
30106a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, wepKeysToWrite);
302e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
303e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, null);
304e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
305e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
306e33a4bb414892435c016486585c26022cafdab68Roshan Pius
307e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
308e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the Configuration data elements that are common for backup & config store to the
309e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * XML stream.
310e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
311e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param out           XmlSerializer instance pointing to the XML stream.
312e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param configuration WifiConfiguration object to be serialized.
313e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
314e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static void writeCommonWifiConfigurationElementsToXml(XmlSerializer out,
315e33a4bb414892435c016486585c26022cafdab68Roshan Pius                WifiConfiguration configuration)
316e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
317e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CONFIG_KEY, configuration.configKey());
318e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_SSID, configuration.SSID);
319e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_BSSID, configuration.BSSID);
320e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_PRE_SHARED_KEY, configuration.preSharedKey);
321e33a4bb414892435c016486585c26022cafdab68Roshan Pius            writeWepKeysToXml(out, configuration.wepKeys);
322e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_WEP_TX_KEY_INDEX, configuration.wepTxKeyIndex);
323e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_HIDDEN_SSID, configuration.hiddenSSID);
324e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
325e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_ALLOWED_KEY_MGMT,
326e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    configuration.allowedKeyManagement.toByteArray());
327e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
328e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_ALLOWED_PROTOCOLS,
329e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    configuration.allowedProtocols.toByteArray());
330e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
331e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_ALLOWED_AUTH_ALGOS,
332e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    configuration.allowedAuthAlgorithms.toByteArray());
333e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_SHARED, configuration.shared);
334e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
335e33a4bb414892435c016486585c26022cafdab68Roshan Pius
336e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
337e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the Configuration data elements for backup from the provided Configuration to the
338e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * XML stream.
339e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Note: This is a subset of the elements serialized for config store.
340e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
341e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param out           XmlSerializer instance pointing to the XML stream.
342e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param configuration WifiConfiguration object to be serialized.
343e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
344e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static void writeWifiConfigurationToXmlForBackup(XmlSerializer out,
345e33a4bb414892435c016486585c26022cafdab68Roshan Pius                WifiConfiguration configuration)
346e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
347e33a4bb414892435c016486585c26022cafdab68Roshan Pius            writeCommonWifiConfigurationElementsToXml(out, configuration);
348e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
349e33a4bb414892435c016486585c26022cafdab68Roshan Pius
350e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
351e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the Configuration data elements for config store from the provided Configuration
352e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * to the XML stream.
353e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
354e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static void writeWifiConfigurationToXmlForConfigStore(XmlSerializer out,
355e33a4bb414892435c016486585c26022cafdab68Roshan Pius                WifiConfiguration configuration)
356e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
357e33a4bb414892435c016486585c26022cafdab68Roshan Pius            writeCommonWifiConfigurationElementsToXml(out, configuration);
358e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // TODO: Will need to add more elements which needs to be persisted.
359030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_FQDN, configuration.FQDN);
360030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
361030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_PROVIDER_FRIENDLY_NAME, configuration.providerFriendlyName);
362030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
363030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_LINKED_NETWORKS_LIST, configuration.linkedConfigurations);
364030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
365030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_DEFAULT_GW_MAC_ADDRESS, configuration.defaultGwMacAddress);
366030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
367030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_VALIDATED_INTERNET_ACCESS, configuration.validatedInternetAccess);
368030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
369030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_NO_INTERNET_ACCESS_EXPECTED,
370030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    configuration.noInternetAccessExpected);
371030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_USER_APPROVED, configuration.userApproved);
372030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_METERED_HINT, configuration.meteredHint);
373030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(
374030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    out, XML_TAG_USE_EXTERNAL_SCORES, configuration.useExternalScores);
375030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_NUM_ASSOCIATION, configuration.numAssociation);
3762fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CREATOR_UID, configuration.creatorUid);
3772fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CREATOR_NAME, configuration.creatorName);
378030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_CREATION_TIME, configuration.creationTime);
379030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_LAST_UPDATE_UID, configuration.lastUpdateUid);
380030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_LAST_UPDATE_NAME, configuration.lastUpdateName);
381030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius            XmlUtil.writeNextValue(out, XML_TAG_LAST_CONNECT_UID, configuration.lastConnectUid);
382e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
383e33a4bb414892435c016486585c26022cafdab68Roshan Pius
384e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
38506a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * Populate wepKeys array elements only if they were non-empty in the backup data.
3862fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius         *
38706a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius         * @throws XmlPullParserException if parsing errors occur.
388e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
389e33a4bb414892435c016486585c26022cafdab68Roshan Pius        private static void populateWepKeysFromXmlValue(Object value, String[] wepKeys)
390e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
391e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String[] wepKeysInData = (String[]) value;
39206a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            if (wepKeysInData == null) {
39306a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                return;
39406a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            }
39506a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            if (wepKeysInData.length != wepKeys.length) {
39606a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                throw new XmlPullParserException(
39706a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                        "Invalid Wep Keys length: " + wepKeysInData.length);
39806a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            }
39906a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius            for (int i = 0; i < wepKeys.length; i++) {
40006a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                if (wepKeysInData[i].isEmpty()) {
40106a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                    wepKeys[i] = null;
40206a2281303248446bacc87a00ab66ea1fdf0392dRoshan Pius                } else {
403e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    wepKeys[i] = wepKeysInData[i];
404e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
405e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
406e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
407e33a4bb414892435c016486585c26022cafdab68Roshan Pius
408e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
409e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Parses the configuration data elements from the provided XML stream to a Configuration.
410e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Note: This is used for parsing both backup data and config store data. Looping through
411e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * the tags make it easy to add or remove elements in the future versions if needed.
412e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
413e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param in            XmlPullParser instance pointing to the XML stream.
414e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param outerTagDepth depth of the outer tag in the XML document.
4152fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius         * @return Pair<Config key, WifiConfiguration object> if parsing is successful,
4162fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius         * null otherwise.
417e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
4182fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius        public static Pair<String, WifiConfiguration> parseWifiConfigurationFromXml(
4192fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius                XmlPullParser in, int outerTagDepth)
420e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
421e33a4bb414892435c016486585c26022cafdab68Roshan Pius            WifiConfiguration configuration = new WifiConfiguration();
422e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String configKeyInData = null;
423e33a4bb414892435c016486585c26022cafdab68Roshan Pius
424e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Loop through and parse out all the elements from the stream within this section.
425e33a4bb414892435c016486585c26022cafdab68Roshan Pius            while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
426e33a4bb414892435c016486585c26022cafdab68Roshan Pius                String[] valueName = new String[1];
427e33a4bb414892435c016486585c26022cafdab68Roshan Pius                Object value = XmlUtil.readCurrentValue(in, valueName);
428e33a4bb414892435c016486585c26022cafdab68Roshan Pius                if (valueName[0] == null) {
429e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    Log.e(TAG, "Missing value name");
430e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    return null;
431e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
432e33a4bb414892435c016486585c26022cafdab68Roshan Pius                switch (valueName[0]) {
433e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_CONFIG_KEY:
434e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configKeyInData = (String) value;
435e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
436e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_SSID:
437e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.SSID = (String) value;
438e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
439e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_BSSID:
440e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.BSSID = (String) value;
441e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
442e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_PRE_SHARED_KEY:
443e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.preSharedKey = (String) value;
444e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
445e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_WEP_KEYS:
446e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        populateWepKeysFromXmlValue(value, configuration.wepKeys);
447e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
448e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_WEP_TX_KEY_INDEX:
449e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.wepTxKeyIndex = (int) value;
450e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
451e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_HIDDEN_SSID:
452e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.hiddenSSID = (boolean) value;
453e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
454e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_ALLOWED_KEY_MGMT:
455e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        byte[] allowedKeyMgmt = (byte[]) value;
456e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.allowedKeyManagement = BitSet.valueOf(allowedKeyMgmt);
457e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
458e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_ALLOWED_PROTOCOLS:
459e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        byte[] allowedProtocols = (byte[]) value;
460e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.allowedProtocols = BitSet.valueOf(allowedProtocols);
461e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
462e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_ALLOWED_AUTH_ALGOS:
463e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        byte[] allowedAuthAlgorithms = (byte[]) value;
464e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.allowedAuthAlgorithms = BitSet.valueOf(allowedAuthAlgorithms);
465e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
466e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_SHARED:
467e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.shared = (boolean) value;
468e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
469030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_FQDN:
470030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.FQDN = (String) value;
471030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
472030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_PROVIDER_FRIENDLY_NAME:
473030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.providerFriendlyName = (String) value;
474030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
475030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_LINKED_NETWORKS_LIST:
476030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.linkedConfigurations = (HashMap<String, Integer>) value;
477030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
478030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_DEFAULT_GW_MAC_ADDRESS:
479030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.defaultGwMacAddress = (String) value;
480030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
481030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_VALIDATED_INTERNET_ACCESS:
482030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.validatedInternetAccess = (boolean) value;
483030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
484030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_NO_INTERNET_ACCESS_EXPECTED:
485030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.noInternetAccessExpected = (boolean) value;
486030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
487030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_USER_APPROVED:
488030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.userApproved = (int) value;
489030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
490030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_METERED_HINT:
491030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.meteredHint = (boolean) value;
492030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
493030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_USE_EXTERNAL_SCORES:
494030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.useExternalScores = (boolean) value;
495030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
496030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_NUM_ASSOCIATION:
497030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.numAssociation = (int) value;
498030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
499e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    case XML_TAG_CREATOR_UID:
500e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        configuration.creatorUid = (int) value;
501e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        break;
5022fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius                    case XML_TAG_CREATOR_NAME:
5032fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius                        configuration.creatorName = (String) value;
5042fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius                        break;
505030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_CREATION_TIME:
506030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.creationTime = (String) value;
507030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
508030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_LAST_UPDATE_UID:
509030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.lastUpdateUid = (int) value;
510030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
511030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_LAST_UPDATE_NAME:
512030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.lastUpdateName = (String) value;
513030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
514030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                    case XML_TAG_LAST_CONNECT_UID:
515030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        configuration.lastConnectUid = (int) value;
516030c5debfefddf0512cd53fec48b269c08d9972eRoshan Pius                        break;
517e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    default:
518e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        Log.e(TAG, "Unknown value name found: " + valueName[0]);
519e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        return null;
520e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
521e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
5222fafcc56fda54b1adf8b6743beaac59dbb84dfecRoshan Pius            return Pair.create(configKeyInData, configuration);
523e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
524e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
525e33a4bb414892435c016486585c26022cafdab68Roshan Pius
526e33a4bb414892435c016486585c26022cafdab68Roshan Pius    /**
527e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * Utility class to serialize and deseriaize IpConfiguration object to XML & vice versa.
528e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * This is used by both #com.android.server.wifi.WifiConfigStore &
529e33a4bb414892435c016486585c26022cafdab68Roshan Pius     * #com.android.server.wifi.WifiBackupRestore modules.
530e33a4bb414892435c016486585c26022cafdab68Roshan Pius     */
531e33a4bb414892435c016486585c26022cafdab68Roshan Pius    public static class IpConfigurationXmlUtil {
532e33a4bb414892435c016486585c26022cafdab68Roshan Pius
533e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
534e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * List of XML tags corresponding to IpConfiguration object elements.
535e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
536e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_IP_ASSIGNMENT = "IpAssignment";
537e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_LINK_ADDRESS = "LinkAddress";
538e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_LINK_PREFIX_LENGTH = "LinkPrefixLength";
539e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_GATEWAY_ADDRESS = "GatewayAddress";
540e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_DNS_SERVER_ADDRESSES = "DNSServers";
541e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_SETTINGS = "ProxySettings";
542e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_HOST = "ProxyHost";
543e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_PORT = "ProxyPort";
544e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_PAC_FILE = "ProxyPac";
545e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static final String XML_TAG_PROXY_EXCLUSION_LIST = "ProxyExclusionList";
546e33a4bb414892435c016486585c26022cafdab68Roshan Pius
547e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
548e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the static IP configuration data elements to XML stream.
549e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
550e33a4bb414892435c016486585c26022cafdab68Roshan Pius        private static void writeStaticIpConfigurationToXml(XmlSerializer out,
551e33a4bb414892435c016486585c26022cafdab68Roshan Pius                StaticIpConfiguration staticIpConfiguration)
552e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
553e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (staticIpConfiguration.ipAddress != null) {
554e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
555e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_ADDRESS,
556e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        staticIpConfiguration.ipAddress.getAddress().getHostAddress());
557e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
558e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_PREFIX_LENGTH,
559e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        staticIpConfiguration.ipAddress.getPrefixLength());
560e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
561e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
562e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_ADDRESS, null);
563e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
564e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_LINK_PREFIX_LENGTH, null);
565e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
566e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (staticIpConfiguration.gateway != null) {
567e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
568e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_GATEWAY_ADDRESS,
569e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        staticIpConfiguration.gateway.getHostAddress());
570e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
571e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
572e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_GATEWAY_ADDRESS, null);
573e33a4bb414892435c016486585c26022cafdab68Roshan Pius
574e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
575e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (staticIpConfiguration.dnsServers != null) {
576e33a4bb414892435c016486585c26022cafdab68Roshan Pius                // Create a string array of DNS server addresses
577e33a4bb414892435c016486585c26022cafdab68Roshan Pius                String[] dnsServers = new String[staticIpConfiguration.dnsServers.size()];
578e33a4bb414892435c016486585c26022cafdab68Roshan Pius                int dnsServerIdx = 0;
579e33a4bb414892435c016486585c26022cafdab68Roshan Pius                for (InetAddress inetAddr : staticIpConfiguration.dnsServers) {
580e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    dnsServers[dnsServerIdx++] = inetAddr.getHostAddress();
581e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
582e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
583e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_DNS_SERVER_ADDRESSES, dnsServers);
584e33a4bb414892435c016486585c26022cafdab68Roshan Pius            } else {
585e33a4bb414892435c016486585c26022cafdab68Roshan Pius                XmlUtil.writeNextValue(
586e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        out, XML_TAG_DNS_SERVER_ADDRESSES, null);
587e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
588e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
589e33a4bb414892435c016486585c26022cafdab68Roshan Pius
590e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
591e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Write the IP configuration data elements from the provided Configuration to the XML
592e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * stream.
593e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
594e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static void writeIpConfigurationToXml(XmlSerializer out,
595e33a4bb414892435c016486585c26022cafdab68Roshan Pius                IpConfiguration ipConfiguration)
596e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
597e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Write IP assignment settings
598e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(out, XML_TAG_IP_ASSIGNMENT,
599e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.ipAssignment.toString());
600e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (ipConfiguration.ipAssignment) {
601e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
602e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    writeStaticIpConfigurationToXml(
603e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, ipConfiguration.getStaticIpConfiguration());
604e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
605e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
606e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
607e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
608e33a4bb414892435c016486585c26022cafdab68Roshan Pius
609e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Write proxy settings
610e33a4bb414892435c016486585c26022cafdab68Roshan Pius            XmlUtil.writeNextValue(
611e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    out, XML_TAG_PROXY_SETTINGS,
612e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.proxySettings.toString());
613e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (ipConfiguration.proxySettings) {
614e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
615e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
616e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_HOST,
617e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getHost());
618e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
619e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_PORT,
620e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getPort());
621e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
622e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_EXCLUSION_LIST,
623e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getExclusionListAsString());
624e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
625e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case PAC:
626e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    XmlUtil.writeNextValue(
627e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            out, XML_TAG_PROXY_PAC_FILE,
628e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            ipConfiguration.httpProxy.getPacFileUrl().toString());
629e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
630e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
631e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
632e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
633e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
634e33a4bb414892435c016486585c26022cafdab68Roshan Pius
635e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
636e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Parse out the static IP configuration from the XML stream.
637e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
638e33a4bb414892435c016486585c26022cafdab68Roshan Pius        private static StaticIpConfiguration parseStaticIpConfigurationFromXml(XmlPullParser in)
639e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
640e33a4bb414892435c016486585c26022cafdab68Roshan Pius            StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
641e33a4bb414892435c016486585c26022cafdab68Roshan Pius
642e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String linkAddressString =
643e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_ADDRESS);
644e33a4bb414892435c016486585c26022cafdab68Roshan Pius            Integer linkPrefixLength =
645e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (Integer) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_PREFIX_LENGTH);
646e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (linkAddressString != null && linkPrefixLength != null) {
647e33a4bb414892435c016486585c26022cafdab68Roshan Pius                LinkAddress linkAddress = new LinkAddress(
648e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        NetworkUtils.numericToInetAddress(linkAddressString),
649e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        linkPrefixLength);
650e33a4bb414892435c016486585c26022cafdab68Roshan Pius                if (linkAddress.getAddress() instanceof Inet4Address) {
651e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    staticIpConfiguration.ipAddress = linkAddress;
652e33a4bb414892435c016486585c26022cafdab68Roshan Pius                } else {
653e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    Log.w(TAG, "Non-IPv4 address: " + linkAddress);
654e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
655e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
656e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String gatewayAddressString =
657e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_GATEWAY_ADDRESS);
658e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (gatewayAddressString != null) {
659e33a4bb414892435c016486585c26022cafdab68Roshan Pius                LinkAddress dest = null;
660e33a4bb414892435c016486585c26022cafdab68Roshan Pius                InetAddress gateway =
661e33a4bb414892435c016486585c26022cafdab68Roshan Pius                        NetworkUtils.numericToInetAddress(gatewayAddressString);
662e33a4bb414892435c016486585c26022cafdab68Roshan Pius                RouteInfo route = new RouteInfo(dest, gateway);
663e33a4bb414892435c016486585c26022cafdab68Roshan Pius                if (route.isIPv4Default()) {
664e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    staticIpConfiguration.gateway = gateway;
665e33a4bb414892435c016486585c26022cafdab68Roshan Pius                } else {
666e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    Log.w(TAG, "Non-IPv4 default route: " + route);
667e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
668e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
669e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String[] dnsServerAddressesString =
670e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String[]) XmlUtil.readNextValueWithName(in, XML_TAG_DNS_SERVER_ADDRESSES);
671e33a4bb414892435c016486585c26022cafdab68Roshan Pius            if (dnsServerAddressesString != null) {
672e33a4bb414892435c016486585c26022cafdab68Roshan Pius                for (String dnsServerAddressString : dnsServerAddressesString) {
673e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    InetAddress dnsServerAddress =
674e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            NetworkUtils.numericToInetAddress(dnsServerAddressString);
675e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    staticIpConfiguration.dnsServers.add(dnsServerAddress);
676e33a4bb414892435c016486585c26022cafdab68Roshan Pius                }
677e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
678e33a4bb414892435c016486585c26022cafdab68Roshan Pius            return staticIpConfiguration;
679e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
680e33a4bb414892435c016486585c26022cafdab68Roshan Pius
681e33a4bb414892435c016486585c26022cafdab68Roshan Pius        /**
682e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * Parses the IP configuration data elements from the provided XML stream to a
683e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * IpConfiguration.
684e33a4bb414892435c016486585c26022cafdab68Roshan Pius         *
685e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param in            XmlPullParser instance pointing to the XML stream.
686e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @param outerTagDepth depth of the outer tag in the XML document.
687e33a4bb414892435c016486585c26022cafdab68Roshan Pius         * @return IpConfiguration object if parsing is successful, null otherwise.
688e33a4bb414892435c016486585c26022cafdab68Roshan Pius         */
689e33a4bb414892435c016486585c26022cafdab68Roshan Pius        public static IpConfiguration parseIpConfigurationFromXml(XmlPullParser in,
690e33a4bb414892435c016486585c26022cafdab68Roshan Pius                int outerTagDepth)
691e33a4bb414892435c016486585c26022cafdab68Roshan Pius                throws XmlPullParserException, IOException {
692e33a4bb414892435c016486585c26022cafdab68Roshan Pius            IpConfiguration ipConfiguration = new IpConfiguration();
693e33a4bb414892435c016486585c26022cafdab68Roshan Pius
694e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Parse out the IP assignment info first.
695e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String ipAssignmentString =
696e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_IP_ASSIGNMENT);
697e33a4bb414892435c016486585c26022cafdab68Roshan Pius            IpAssignment ipAssignment = IpAssignment.valueOf(ipAssignmentString);
698e33a4bb414892435c016486585c26022cafdab68Roshan Pius            ipConfiguration.setIpAssignment(ipAssignment);
699e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (ipAssignment) {
700e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
701e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.setStaticIpConfiguration(parseStaticIpConfigurationFromXml(in));
702e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
703e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case DHCP:
704e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case UNASSIGNED:
705e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
706e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
707e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    Log.wtf(TAG, "Unknown ip assignment type: " + ipAssignment);
708e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    return null;
709e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
710e33a4bb414892435c016486585c26022cafdab68Roshan Pius
711e33a4bb414892435c016486585c26022cafdab68Roshan Pius            // Parse out the proxy settings next.
712e33a4bb414892435c016486585c26022cafdab68Roshan Pius            String proxySettingsString =
713e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_SETTINGS);
714e33a4bb414892435c016486585c26022cafdab68Roshan Pius            ProxySettings proxySettings = ProxySettings.valueOf(proxySettingsString);
715e33a4bb414892435c016486585c26022cafdab68Roshan Pius            ipConfiguration.setProxySettings(proxySettings);
716e33a4bb414892435c016486585c26022cafdab68Roshan Pius            switch (proxySettings) {
717e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case STATIC:
718e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    String proxyHost =
719e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_HOST);
720e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    int proxyPort =
721e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (int) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PORT);
722e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    String proxyExclusionList =
723e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (String) XmlUtil.readNextValueWithName(
724e33a4bb414892435c016486585c26022cafdab68Roshan Pius                                    in, XML_TAG_PROXY_EXCLUSION_LIST);
725e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.setHttpProxy(
726e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            new ProxyInfo(proxyHost, proxyPort, proxyExclusionList));
727e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
728e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case PAC:
729e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    String proxyPacFile =
730e33a4bb414892435c016486585c26022cafdab68Roshan Pius                            (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PAC_FILE);
731e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    ipConfiguration.setHttpProxy(new ProxyInfo(proxyPacFile));
732e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
733e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case NONE:
734e33a4bb414892435c016486585c26022cafdab68Roshan Pius                case UNASSIGNED:
735e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    break;
736e33a4bb414892435c016486585c26022cafdab68Roshan Pius                default:
737e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    Log.wtf(TAG, "Unknown proxy settings type: " + proxySettings);
738e33a4bb414892435c016486585c26022cafdab68Roshan Pius                    return null;
739e33a4bb414892435c016486585c26022cafdab68Roshan Pius            }
740e33a4bb414892435c016486585c26022cafdab68Roshan Pius            return ipConfiguration;
741e33a4bb414892435c016486585c26022cafdab68Roshan Pius        }
742e33a4bb414892435c016486585c26022cafdab68Roshan Pius    }
7432b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius}
7442b7e486db94455a4a4c0124b5ba5e57c837ef10eRoshan Pius
745