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 17 package com.android.server.wifi.util; 18 19 import android.net.IpConfiguration; 20 import android.net.IpConfiguration.IpAssignment; 21 import android.net.IpConfiguration.ProxySettings; 22 import android.net.LinkAddress; 23 import android.net.NetworkUtils; 24 import android.net.ProxyInfo; 25 import android.net.RouteInfo; 26 import android.net.StaticIpConfiguration; 27 import android.net.wifi.WifiConfiguration; 28 import android.net.wifi.WifiConfiguration.NetworkSelectionStatus; 29 import android.net.wifi.WifiEnterpriseConfig; 30 import android.util.Log; 31 import android.util.Pair; 32 33 import com.android.internal.util.XmlUtils; 34 35 import org.xmlpull.v1.XmlPullParser; 36 import org.xmlpull.v1.XmlPullParserException; 37 import org.xmlpull.v1.XmlSerializer; 38 39 import java.io.IOException; 40 import java.net.Inet4Address; 41 import java.net.InetAddress; 42 import java.util.Arrays; 43 import java.util.BitSet; 44 import 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 */ 67 public 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 */ gotoStartTag(XmlPullParser in)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 */ gotoEndTag(XmlPullParser in)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 */ gotoDocumentStart(XmlPullParser in, String headerName)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 */ gotoNextSectionOrEnd( XmlPullParser in, String[] headerName, int outerDepth)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 */ gotoNextSectionWithNameOrEnd( XmlPullParser in, String expectedName, int outerDepth)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 */ gotoNextSectionWithName( XmlPullParser in, String expectedName, int outerDepth)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 */ isNextSectionEnd(XmlPullParser in, int sectionDepth)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 */ readCurrentValue(XmlPullParser in, String[] valueName)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 */ readNextValueWithName(XmlPullParser in, String expectedName)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 */ writeDocumentStart(XmlSerializer out, String headerName)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 */ writeDocumentEnd(XmlSerializer out, String headerName)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 */ writeNextSectionStart(XmlSerializer out, String headerName)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 */ writeNextSectionEnd(XmlSerializer out, String headerName)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 */ writeNextValue(XmlSerializer out, String name, Object value)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_METERED_OVERRIDE = "MeteredOverride"; 336 public static final String XML_TAG_USE_EXTERNAL_SCORES = "UseExternalScores"; 337 public static final String XML_TAG_NUM_ASSOCIATION = "NumAssociation"; 338 public static final String XML_TAG_CREATOR_UID = "CreatorUid"; 339 public static final String XML_TAG_CREATOR_NAME = "CreatorName"; 340 public static final String XML_TAG_CREATION_TIME = "CreationTime"; 341 public static final String XML_TAG_LAST_UPDATE_UID = "LastUpdateUid"; 342 public static final String XML_TAG_LAST_UPDATE_NAME = "LastUpdateName"; 343 public static final String XML_TAG_LAST_CONNECT_UID = "LastConnectUid"; 344 public static final String XML_TAG_IS_LEGACY_PASSPOINT_CONFIG = "IsLegacyPasspointConfig"; 345 public static final String XML_TAG_ROAMING_CONSORTIUM_OIS = "RoamingConsortiumOIs"; 346 347 /** 348 * Write WepKeys to the XML stream. 349 * WepKeys array is intialized in WifiConfiguration constructor, but all of the elements 350 * are set to null. User may chose to set any one of the key elements in WifiConfiguration. 351 * XmlUtils serialization doesn't handle this array of nulls well . 352 * So, write empty strings if some of the keys are not initialized and null if all of 353 * the elements are empty. 354 */ writeWepKeysToXml(XmlSerializer out, String[] wepKeys)355 private static void writeWepKeysToXml(XmlSerializer out, String[] wepKeys) 356 throws XmlPullParserException, IOException { 357 String[] wepKeysToWrite = new String[wepKeys.length]; 358 boolean hasWepKey = false; 359 for (int i = 0; i < wepKeys.length; i++) { 360 if (wepKeys[i] == null) { 361 wepKeysToWrite[i] = new String(); 362 } else { 363 wepKeysToWrite[i] = wepKeys[i]; 364 hasWepKey = true; 365 } 366 } 367 if (hasWepKey) { 368 XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, wepKeysToWrite); 369 } else { 370 XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, null); 371 } 372 } 373 374 /** 375 * Write the Configuration data elements that are common for backup & config store to the 376 * XML stream. 377 * 378 * @param out XmlSerializer instance pointing to the XML stream. 379 * @param configuration WifiConfiguration object to be serialized. 380 */ writeCommonElementsToXml( XmlSerializer out, WifiConfiguration configuration)381 public static void writeCommonElementsToXml( 382 XmlSerializer out, WifiConfiguration configuration) 383 throws XmlPullParserException, IOException { 384 XmlUtil.writeNextValue(out, XML_TAG_CONFIG_KEY, configuration.configKey()); 385 XmlUtil.writeNextValue(out, XML_TAG_SSID, configuration.SSID); 386 XmlUtil.writeNextValue(out, XML_TAG_BSSID, configuration.BSSID); 387 XmlUtil.writeNextValue(out, XML_TAG_PRE_SHARED_KEY, configuration.preSharedKey); 388 writeWepKeysToXml(out, configuration.wepKeys); 389 XmlUtil.writeNextValue(out, XML_TAG_WEP_TX_KEY_INDEX, configuration.wepTxKeyIndex); 390 XmlUtil.writeNextValue(out, XML_TAG_HIDDEN_SSID, configuration.hiddenSSID); 391 XmlUtil.writeNextValue(out, XML_TAG_REQUIRE_PMF, configuration.requirePMF); 392 XmlUtil.writeNextValue( 393 out, XML_TAG_ALLOWED_KEY_MGMT, 394 configuration.allowedKeyManagement.toByteArray()); 395 XmlUtil.writeNextValue( 396 out, XML_TAG_ALLOWED_PROTOCOLS, 397 configuration.allowedProtocols.toByteArray()); 398 XmlUtil.writeNextValue( 399 out, XML_TAG_ALLOWED_AUTH_ALGOS, 400 configuration.allowedAuthAlgorithms.toByteArray()); 401 XmlUtil.writeNextValue( 402 out, XML_TAG_ALLOWED_GROUP_CIPHERS, 403 configuration.allowedGroupCiphers.toByteArray()); 404 XmlUtil.writeNextValue( 405 out, XML_TAG_ALLOWED_PAIRWISE_CIPHERS, 406 configuration.allowedPairwiseCiphers.toByteArray()); 407 XmlUtil.writeNextValue(out, XML_TAG_SHARED, configuration.shared); 408 } 409 410 /** 411 * Write the Configuration data elements for backup from the provided Configuration to the 412 * XML stream. 413 * Note: This is a subset of the elements serialized for config store. 414 * 415 * @param out XmlSerializer instance pointing to the XML stream. 416 * @param configuration WifiConfiguration object to be serialized. 417 */ writeToXmlForBackup(XmlSerializer out, WifiConfiguration configuration)418 public static void writeToXmlForBackup(XmlSerializer out, WifiConfiguration configuration) 419 throws XmlPullParserException, IOException { 420 writeCommonElementsToXml(out, configuration); 421 } 422 423 /** 424 * Write the Configuration data elements for config store from the provided Configuration 425 * to the XML stream. 426 * 427 * @param out XmlSerializer instance pointing to the XML stream. 428 * @param configuration WifiConfiguration object to be serialized. 429 */ writeToXmlForConfigStore( XmlSerializer out, WifiConfiguration configuration)430 public static void writeToXmlForConfigStore( 431 XmlSerializer out, WifiConfiguration configuration) 432 throws XmlPullParserException, IOException { 433 writeCommonElementsToXml(out, configuration); 434 XmlUtil.writeNextValue(out, XML_TAG_STATUS, configuration.status); 435 XmlUtil.writeNextValue(out, XML_TAG_FQDN, configuration.FQDN); 436 XmlUtil.writeNextValue( 437 out, XML_TAG_PROVIDER_FRIENDLY_NAME, configuration.providerFriendlyName); 438 XmlUtil.writeNextValue( 439 out, XML_TAG_LINKED_NETWORKS_LIST, configuration.linkedConfigurations); 440 XmlUtil.writeNextValue( 441 out, XML_TAG_DEFAULT_GW_MAC_ADDRESS, configuration.defaultGwMacAddress); 442 XmlUtil.writeNextValue( 443 out, XML_TAG_VALIDATED_INTERNET_ACCESS, configuration.validatedInternetAccess); 444 XmlUtil.writeNextValue( 445 out, XML_TAG_NO_INTERNET_ACCESS_EXPECTED, 446 configuration.noInternetAccessExpected); 447 XmlUtil.writeNextValue(out, XML_TAG_USER_APPROVED, configuration.userApproved); 448 XmlUtil.writeNextValue(out, XML_TAG_METERED_HINT, configuration.meteredHint); 449 XmlUtil.writeNextValue(out, XML_TAG_METERED_OVERRIDE, configuration.meteredOverride); 450 XmlUtil.writeNextValue( 451 out, XML_TAG_USE_EXTERNAL_SCORES, configuration.useExternalScores); 452 XmlUtil.writeNextValue(out, XML_TAG_NUM_ASSOCIATION, configuration.numAssociation); 453 XmlUtil.writeNextValue(out, XML_TAG_CREATOR_UID, configuration.creatorUid); 454 XmlUtil.writeNextValue(out, XML_TAG_CREATOR_NAME, configuration.creatorName); 455 XmlUtil.writeNextValue(out, XML_TAG_CREATION_TIME, configuration.creationTime); 456 XmlUtil.writeNextValue(out, XML_TAG_LAST_UPDATE_UID, configuration.lastUpdateUid); 457 XmlUtil.writeNextValue(out, XML_TAG_LAST_UPDATE_NAME, configuration.lastUpdateName); 458 XmlUtil.writeNextValue(out, XML_TAG_LAST_CONNECT_UID, configuration.lastConnectUid); 459 XmlUtil.writeNextValue( 460 out, XML_TAG_IS_LEGACY_PASSPOINT_CONFIG, 461 configuration.isLegacyPasspointConfig); 462 XmlUtil.writeNextValue( 463 out, XML_TAG_ROAMING_CONSORTIUM_OIS, configuration.roamingConsortiumIds); 464 } 465 466 /** 467 * Populate wepKeys array elements only if they were non-empty in the backup data. 468 * 469 * @throws XmlPullParserException if parsing errors occur. 470 */ populateWepKeysFromXmlValue(Object value, String[] wepKeys)471 private static void populateWepKeysFromXmlValue(Object value, String[] wepKeys) 472 throws XmlPullParserException, IOException { 473 String[] wepKeysInData = (String[]) value; 474 if (wepKeysInData == null) { 475 return; 476 } 477 if (wepKeysInData.length != wepKeys.length) { 478 throw new XmlPullParserException( 479 "Invalid Wep Keys length: " + wepKeysInData.length); 480 } 481 for (int i = 0; i < wepKeys.length; i++) { 482 if (wepKeysInData[i].isEmpty()) { 483 wepKeys[i] = null; 484 } else { 485 wepKeys[i] = wepKeysInData[i]; 486 } 487 } 488 } 489 490 /** 491 * Parses the configuration data elements from the provided XML stream to a 492 * WifiConfiguration object. 493 * Note: This is used for parsing both backup data and config store data. Looping through 494 * the tags make it easy to add or remove elements in the future versions if needed. 495 * 496 * @param in XmlPullParser instance pointing to the XML stream. 497 * @param outerTagDepth depth of the outer tag in the XML document. 498 * @return Pair<Config key, WifiConfiguration object> if parsing is successful, 499 * null otherwise. 500 */ parseFromXml( XmlPullParser in, int outerTagDepth)501 public static Pair<String, WifiConfiguration> parseFromXml( 502 XmlPullParser in, int outerTagDepth) 503 throws XmlPullParserException, IOException { 504 WifiConfiguration configuration = new WifiConfiguration(); 505 String configKeyInData = null; 506 507 // Loop through and parse out all the elements from the stream within this section. 508 while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) { 509 String[] valueName = new String[1]; 510 Object value = XmlUtil.readCurrentValue(in, valueName); 511 if (valueName[0] == null) { 512 throw new XmlPullParserException("Missing value name"); 513 } 514 switch (valueName[0]) { 515 case XML_TAG_CONFIG_KEY: 516 configKeyInData = (String) value; 517 break; 518 case XML_TAG_SSID: 519 configuration.SSID = (String) value; 520 break; 521 case XML_TAG_BSSID: 522 configuration.BSSID = (String) value; 523 break; 524 case XML_TAG_PRE_SHARED_KEY: 525 configuration.preSharedKey = (String) value; 526 break; 527 case XML_TAG_WEP_KEYS: 528 populateWepKeysFromXmlValue(value, configuration.wepKeys); 529 break; 530 case XML_TAG_WEP_TX_KEY_INDEX: 531 configuration.wepTxKeyIndex = (int) value; 532 break; 533 case XML_TAG_HIDDEN_SSID: 534 configuration.hiddenSSID = (boolean) value; 535 break; 536 case XML_TAG_REQUIRE_PMF: 537 configuration.requirePMF = (boolean) value; 538 break; 539 case XML_TAG_ALLOWED_KEY_MGMT: 540 byte[] allowedKeyMgmt = (byte[]) value; 541 configuration.allowedKeyManagement = BitSet.valueOf(allowedKeyMgmt); 542 break; 543 case XML_TAG_ALLOWED_PROTOCOLS: 544 byte[] allowedProtocols = (byte[]) value; 545 configuration.allowedProtocols = BitSet.valueOf(allowedProtocols); 546 break; 547 case XML_TAG_ALLOWED_AUTH_ALGOS: 548 byte[] allowedAuthAlgorithms = (byte[]) value; 549 configuration.allowedAuthAlgorithms = BitSet.valueOf(allowedAuthAlgorithms); 550 break; 551 case XML_TAG_ALLOWED_GROUP_CIPHERS: 552 byte[] allowedGroupCiphers = (byte[]) value; 553 configuration.allowedGroupCiphers = BitSet.valueOf(allowedGroupCiphers); 554 break; 555 case XML_TAG_ALLOWED_PAIRWISE_CIPHERS: 556 byte[] allowedPairwiseCiphers = (byte[]) value; 557 configuration.allowedPairwiseCiphers = 558 BitSet.valueOf(allowedPairwiseCiphers); 559 break; 560 case XML_TAG_SHARED: 561 configuration.shared = (boolean) value; 562 break; 563 case XML_TAG_STATUS: 564 int status = (int) value; 565 // Any network which was CURRENT before reboot needs 566 // to be restored to ENABLED. 567 if (status == WifiConfiguration.Status.CURRENT) { 568 status = WifiConfiguration.Status.ENABLED; 569 } 570 configuration.status = status; 571 break; 572 case XML_TAG_FQDN: 573 configuration.FQDN = (String) value; 574 break; 575 case XML_TAG_PROVIDER_FRIENDLY_NAME: 576 configuration.providerFriendlyName = (String) value; 577 break; 578 case XML_TAG_LINKED_NETWORKS_LIST: 579 configuration.linkedConfigurations = (HashMap<String, Integer>) value; 580 break; 581 case XML_TAG_DEFAULT_GW_MAC_ADDRESS: 582 configuration.defaultGwMacAddress = (String) value; 583 break; 584 case XML_TAG_VALIDATED_INTERNET_ACCESS: 585 configuration.validatedInternetAccess = (boolean) value; 586 break; 587 case XML_TAG_NO_INTERNET_ACCESS_EXPECTED: 588 configuration.noInternetAccessExpected = (boolean) value; 589 break; 590 case XML_TAG_USER_APPROVED: 591 configuration.userApproved = (int) value; 592 break; 593 case XML_TAG_METERED_HINT: 594 configuration.meteredHint = (boolean) value; 595 break; 596 case XML_TAG_METERED_OVERRIDE: 597 configuration.meteredOverride = (int) value; 598 break; 599 case XML_TAG_USE_EXTERNAL_SCORES: 600 configuration.useExternalScores = (boolean) value; 601 break; 602 case XML_TAG_NUM_ASSOCIATION: 603 configuration.numAssociation = (int) value; 604 break; 605 case XML_TAG_CREATOR_UID: 606 configuration.creatorUid = (int) value; 607 break; 608 case XML_TAG_CREATOR_NAME: 609 configuration.creatorName = (String) value; 610 break; 611 case XML_TAG_CREATION_TIME: 612 configuration.creationTime = (String) value; 613 break; 614 case XML_TAG_LAST_UPDATE_UID: 615 configuration.lastUpdateUid = (int) value; 616 break; 617 case XML_TAG_LAST_UPDATE_NAME: 618 configuration.lastUpdateName = (String) value; 619 break; 620 case XML_TAG_LAST_CONNECT_UID: 621 configuration.lastConnectUid = (int) value; 622 break; 623 case XML_TAG_IS_LEGACY_PASSPOINT_CONFIG: 624 configuration.isLegacyPasspointConfig = (boolean) value; 625 break; 626 case XML_TAG_ROAMING_CONSORTIUM_OIS: 627 configuration.roamingConsortiumIds = (long[]) value; 628 break; 629 default: 630 throw new XmlPullParserException( 631 "Unknown value name found: " + valueName[0]); 632 } 633 } 634 return Pair.create(configKeyInData, configuration); 635 } 636 } 637 638 /** 639 * Utility class to serialize and deseriaize {@link IpConfiguration} object to XML & vice versa. 640 * This is used by both {@link com.android.server.wifi.WifiConfigStore} & 641 * {@link com.android.server.wifi.WifiBackupRestore} modules. 642 */ 643 public static class IpConfigurationXmlUtil { 644 645 /** 646 * List of XML tags corresponding to IpConfiguration object elements. 647 */ 648 public static final String XML_TAG_IP_ASSIGNMENT = "IpAssignment"; 649 public static final String XML_TAG_LINK_ADDRESS = "LinkAddress"; 650 public static final String XML_TAG_LINK_PREFIX_LENGTH = "LinkPrefixLength"; 651 public static final String XML_TAG_GATEWAY_ADDRESS = "GatewayAddress"; 652 public static final String XML_TAG_DNS_SERVER_ADDRESSES = "DNSServers"; 653 public static final String XML_TAG_PROXY_SETTINGS = "ProxySettings"; 654 public static final String XML_TAG_PROXY_HOST = "ProxyHost"; 655 public static final String XML_TAG_PROXY_PORT = "ProxyPort"; 656 public static final String XML_TAG_PROXY_PAC_FILE = "ProxyPac"; 657 public static final String XML_TAG_PROXY_EXCLUSION_LIST = "ProxyExclusionList"; 658 659 /** 660 * Write the static IP configuration data elements to XML stream. 661 */ writeStaticIpConfigurationToXml( XmlSerializer out, StaticIpConfiguration staticIpConfiguration)662 private static void writeStaticIpConfigurationToXml( 663 XmlSerializer out, StaticIpConfiguration staticIpConfiguration) 664 throws XmlPullParserException, IOException { 665 if (staticIpConfiguration.ipAddress != null) { 666 XmlUtil.writeNextValue( 667 out, XML_TAG_LINK_ADDRESS, 668 staticIpConfiguration.ipAddress.getAddress().getHostAddress()); 669 XmlUtil.writeNextValue( 670 out, XML_TAG_LINK_PREFIX_LENGTH, 671 staticIpConfiguration.ipAddress.getPrefixLength()); 672 } else { 673 XmlUtil.writeNextValue( 674 out, XML_TAG_LINK_ADDRESS, null); 675 XmlUtil.writeNextValue( 676 out, XML_TAG_LINK_PREFIX_LENGTH, null); 677 } 678 if (staticIpConfiguration.gateway != null) { 679 XmlUtil.writeNextValue( 680 out, XML_TAG_GATEWAY_ADDRESS, 681 staticIpConfiguration.gateway.getHostAddress()); 682 } else { 683 XmlUtil.writeNextValue( 684 out, XML_TAG_GATEWAY_ADDRESS, null); 685 686 } 687 if (staticIpConfiguration.dnsServers != null) { 688 // Create a string array of DNS server addresses 689 String[] dnsServers = new String[staticIpConfiguration.dnsServers.size()]; 690 int dnsServerIdx = 0; 691 for (InetAddress inetAddr : staticIpConfiguration.dnsServers) { 692 dnsServers[dnsServerIdx++] = inetAddr.getHostAddress(); 693 } 694 XmlUtil.writeNextValue( 695 out, XML_TAG_DNS_SERVER_ADDRESSES, dnsServers); 696 } else { 697 XmlUtil.writeNextValue( 698 out, XML_TAG_DNS_SERVER_ADDRESSES, null); 699 } 700 } 701 702 /** 703 * Write the IP configuration data elements from the provided Configuration to the XML 704 * stream. 705 * 706 * @param out XmlSerializer instance pointing to the XML stream. 707 * @param ipConfiguration IpConfiguration object to be serialized. 708 */ writeToXml(XmlSerializer out, IpConfiguration ipConfiguration)709 public static void writeToXml(XmlSerializer out, IpConfiguration ipConfiguration) 710 throws XmlPullParserException, IOException { 711 // Write IP assignment settings 712 XmlUtil.writeNextValue(out, XML_TAG_IP_ASSIGNMENT, 713 ipConfiguration.ipAssignment.toString()); 714 switch (ipConfiguration.ipAssignment) { 715 case STATIC: 716 writeStaticIpConfigurationToXml( 717 out, ipConfiguration.getStaticIpConfiguration()); 718 break; 719 default: 720 break; 721 } 722 723 // Write proxy settings 724 XmlUtil.writeNextValue( 725 out, XML_TAG_PROXY_SETTINGS, 726 ipConfiguration.proxySettings.toString()); 727 switch (ipConfiguration.proxySettings) { 728 case STATIC: 729 XmlUtil.writeNextValue( 730 out, XML_TAG_PROXY_HOST, 731 ipConfiguration.httpProxy.getHost()); 732 XmlUtil.writeNextValue( 733 out, XML_TAG_PROXY_PORT, 734 ipConfiguration.httpProxy.getPort()); 735 XmlUtil.writeNextValue( 736 out, XML_TAG_PROXY_EXCLUSION_LIST, 737 ipConfiguration.httpProxy.getExclusionListAsString()); 738 break; 739 case PAC: 740 XmlUtil.writeNextValue( 741 out, XML_TAG_PROXY_PAC_FILE, 742 ipConfiguration.httpProxy.getPacFileUrl().toString()); 743 break; 744 default: 745 break; 746 } 747 } 748 749 /** 750 * Parse out the static IP configuration from the XML stream. 751 */ parseStaticIpConfigurationFromXml(XmlPullParser in)752 private static StaticIpConfiguration parseStaticIpConfigurationFromXml(XmlPullParser in) 753 throws XmlPullParserException, IOException { 754 StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration(); 755 756 String linkAddressString = 757 (String) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_ADDRESS); 758 Integer linkPrefixLength = 759 (Integer) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_PREFIX_LENGTH); 760 if (linkAddressString != null && linkPrefixLength != null) { 761 LinkAddress linkAddress = new LinkAddress( 762 NetworkUtils.numericToInetAddress(linkAddressString), 763 linkPrefixLength); 764 if (linkAddress.getAddress() instanceof Inet4Address) { 765 staticIpConfiguration.ipAddress = linkAddress; 766 } else { 767 Log.w(TAG, "Non-IPv4 address: " + linkAddress); 768 } 769 } 770 String gatewayAddressString = 771 (String) XmlUtil.readNextValueWithName(in, XML_TAG_GATEWAY_ADDRESS); 772 if (gatewayAddressString != null) { 773 LinkAddress dest = null; 774 InetAddress gateway = 775 NetworkUtils.numericToInetAddress(gatewayAddressString); 776 RouteInfo route = new RouteInfo(dest, gateway); 777 if (route.isIPv4Default()) { 778 staticIpConfiguration.gateway = gateway; 779 } else { 780 Log.w(TAG, "Non-IPv4 default route: " + route); 781 } 782 } 783 String[] dnsServerAddressesString = 784 (String[]) XmlUtil.readNextValueWithName(in, XML_TAG_DNS_SERVER_ADDRESSES); 785 if (dnsServerAddressesString != null) { 786 for (String dnsServerAddressString : dnsServerAddressesString) { 787 InetAddress dnsServerAddress = 788 NetworkUtils.numericToInetAddress(dnsServerAddressString); 789 staticIpConfiguration.dnsServers.add(dnsServerAddress); 790 } 791 } 792 return staticIpConfiguration; 793 } 794 795 /** 796 * Parses the IP configuration data elements from the provided XML stream to an 797 * IpConfiguration object. 798 * 799 * @param in XmlPullParser instance pointing to the XML stream. 800 * @param outerTagDepth depth of the outer tag in the XML document. 801 * @return IpConfiguration object if parsing is successful, null otherwise. 802 */ parseFromXml(XmlPullParser in, int outerTagDepth)803 public static IpConfiguration parseFromXml(XmlPullParser in, int outerTagDepth) 804 throws XmlPullParserException, IOException { 805 IpConfiguration ipConfiguration = new IpConfiguration(); 806 807 // Parse out the IP assignment info first. 808 String ipAssignmentString = 809 (String) XmlUtil.readNextValueWithName(in, XML_TAG_IP_ASSIGNMENT); 810 IpAssignment ipAssignment = IpAssignment.valueOf(ipAssignmentString); 811 ipConfiguration.setIpAssignment(ipAssignment); 812 switch (ipAssignment) { 813 case STATIC: 814 ipConfiguration.setStaticIpConfiguration(parseStaticIpConfigurationFromXml(in)); 815 break; 816 case DHCP: 817 case UNASSIGNED: 818 break; 819 default: 820 throw new XmlPullParserException("Unknown ip assignment type: " + ipAssignment); 821 } 822 823 // Parse out the proxy settings next. 824 String proxySettingsString = 825 (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_SETTINGS); 826 ProxySettings proxySettings = ProxySettings.valueOf(proxySettingsString); 827 ipConfiguration.setProxySettings(proxySettings); 828 switch (proxySettings) { 829 case STATIC: 830 String proxyHost = 831 (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_HOST); 832 int proxyPort = 833 (int) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PORT); 834 String proxyExclusionList = 835 (String) XmlUtil.readNextValueWithName( 836 in, XML_TAG_PROXY_EXCLUSION_LIST); 837 ipConfiguration.setHttpProxy( 838 new ProxyInfo(proxyHost, proxyPort, proxyExclusionList)); 839 break; 840 case PAC: 841 String proxyPacFile = 842 (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PAC_FILE); 843 ipConfiguration.setHttpProxy(new ProxyInfo(proxyPacFile)); 844 break; 845 case NONE: 846 case UNASSIGNED: 847 break; 848 default: 849 throw new XmlPullParserException( 850 "Unknown proxy settings type: " + proxySettings); 851 } 852 return ipConfiguration; 853 } 854 } 855 856 /** 857 * Utility class to serialize and deseriaize {@link NetworkSelectionStatus} object to XML & 858 * vice versa. This is used by {@link com.android.server.wifi.WifiConfigStore} module. 859 */ 860 public static class NetworkSelectionStatusXmlUtil { 861 862 /** 863 * List of XML tags corresponding to NetworkSelectionStatus object elements. 864 */ 865 public static final String XML_TAG_SELECTION_STATUS = "SelectionStatus"; 866 public static final String XML_TAG_DISABLE_REASON = "DisableReason"; 867 public static final String XML_TAG_CONNECT_CHOICE = "ConnectChoice"; 868 public static final String XML_TAG_CONNECT_CHOICE_TIMESTAMP = "ConnectChoiceTimeStamp"; 869 public static final String XML_TAG_HAS_EVER_CONNECTED = "HasEverConnected"; 870 871 /** 872 * Write the NetworkSelectionStatus data elements from the provided status to the XML 873 * stream. 874 * 875 * @param out XmlSerializer instance pointing to the XML stream. 876 * @param selectionStatus NetworkSelectionStatus object to be serialized. 877 */ writeToXml(XmlSerializer out, NetworkSelectionStatus selectionStatus)878 public static void writeToXml(XmlSerializer out, NetworkSelectionStatus selectionStatus) 879 throws XmlPullParserException, IOException { 880 XmlUtil.writeNextValue( 881 out, XML_TAG_SELECTION_STATUS, selectionStatus.getNetworkStatusString()); 882 XmlUtil.writeNextValue( 883 out, XML_TAG_DISABLE_REASON, selectionStatus.getNetworkDisableReasonString()); 884 XmlUtil.writeNextValue(out, XML_TAG_CONNECT_CHOICE, selectionStatus.getConnectChoice()); 885 XmlUtil.writeNextValue( 886 out, XML_TAG_CONNECT_CHOICE_TIMESTAMP, 887 selectionStatus.getConnectChoiceTimestamp()); 888 XmlUtil.writeNextValue( 889 out, XML_TAG_HAS_EVER_CONNECTED, selectionStatus.getHasEverConnected()); 890 } 891 892 /** 893 * Parses the NetworkSelectionStatus data elements from the provided XML stream to a 894 * NetworkSelectionStatus object. 895 * 896 * @param in XmlPullParser instance pointing to the XML stream. 897 * @param outerTagDepth depth of the outer tag in the XML document. 898 * @return NetworkSelectionStatus object if parsing is successful, null otherwise. 899 */ parseFromXml(XmlPullParser in, int outerTagDepth)900 public static NetworkSelectionStatus parseFromXml(XmlPullParser in, int outerTagDepth) 901 throws XmlPullParserException, IOException { 902 NetworkSelectionStatus selectionStatus = new NetworkSelectionStatus(); 903 String statusString = ""; 904 String disableReasonString = ""; 905 906 // Loop through and parse out all the elements from the stream within this section. 907 while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) { 908 String[] valueName = new String[1]; 909 Object value = XmlUtil.readCurrentValue(in, valueName); 910 if (valueName[0] == null) { 911 throw new XmlPullParserException("Missing value name"); 912 } 913 switch (valueName[0]) { 914 case XML_TAG_SELECTION_STATUS: 915 statusString = (String) value; 916 break; 917 case XML_TAG_DISABLE_REASON: 918 disableReasonString = (String) value; 919 break; 920 case XML_TAG_CONNECT_CHOICE: 921 selectionStatus.setConnectChoice((String) value); 922 break; 923 case XML_TAG_CONNECT_CHOICE_TIMESTAMP: 924 selectionStatus.setConnectChoiceTimestamp((long) value); 925 break; 926 case XML_TAG_HAS_EVER_CONNECTED: 927 selectionStatus.setHasEverConnected((boolean) value); 928 break; 929 default: 930 throw new XmlPullParserException( 931 "Unknown value name found: " + valueName[0]); 932 } 933 } 934 // Now figure out the network selection status codes from |selectionStatusString| & 935 // |disableReasonString|. 936 int status = 937 Arrays.asList(NetworkSelectionStatus.QUALITY_NETWORK_SELECTION_STATUS) 938 .indexOf(statusString); 939 int disableReason = 940 Arrays.asList(NetworkSelectionStatus.QUALITY_NETWORK_SELECTION_DISABLE_REASON) 941 .indexOf(disableReasonString); 942 943 // If either of the above codes are invalid or if the network was temporarily disabled 944 // (blacklisted), restore the status as enabled. We don't want to persist blacklists 945 // across reboots. 946 if (status == -1 || disableReason == -1 || 947 status == NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED) { 948 status = NetworkSelectionStatus.NETWORK_SELECTION_ENABLED; 949 disableReason = NetworkSelectionStatus.NETWORK_SELECTION_ENABLE; 950 } 951 selectionStatus.setNetworkSelectionStatus(status); 952 selectionStatus.setNetworkSelectionDisableReason(disableReason); 953 return selectionStatus; 954 } 955 } 956 957 /** 958 * Utility class to serialize and deseriaize {@link WifiEnterpriseConfig} object to XML & 959 * vice versa. This is used by {@link com.android.server.wifi.WifiConfigStore} module. 960 */ 961 public static class WifiEnterpriseConfigXmlUtil { 962 963 /** 964 * List of XML tags corresponding to WifiEnterpriseConfig object elements. 965 */ 966 public static final String XML_TAG_IDENTITY = "Identity"; 967 public static final String XML_TAG_ANON_IDENTITY = "AnonIdentity"; 968 public static final String XML_TAG_PASSWORD = "Password"; 969 public static final String XML_TAG_CLIENT_CERT = "ClientCert"; 970 public static final String XML_TAG_CA_CERT = "CaCert"; 971 public static final String XML_TAG_SUBJECT_MATCH = "SubjectMatch"; 972 public static final String XML_TAG_ENGINE = "Engine"; 973 public static final String XML_TAG_ENGINE_ID = "EngineId"; 974 public static final String XML_TAG_PRIVATE_KEY_ID = "PrivateKeyId"; 975 public static final String XML_TAG_ALT_SUBJECT_MATCH = "AltSubjectMatch"; 976 public static final String XML_TAG_DOM_SUFFIX_MATCH = "DomSuffixMatch"; 977 public static final String XML_TAG_CA_PATH = "CaPath"; 978 public static final String XML_TAG_EAP_METHOD = "EapMethod"; 979 public static final String XML_TAG_PHASE2_METHOD = "Phase2Method"; 980 public static final String XML_TAG_PLMN = "PLMN"; 981 public static final String XML_TAG_REALM = "Realm"; 982 983 /** 984 * Write the WifiEnterpriseConfig data elements from the provided config to the XML 985 * stream. 986 * 987 * @param out XmlSerializer instance pointing to the XML stream. 988 * @param enterpriseConfig WifiEnterpriseConfig object to be serialized. 989 */ writeToXml(XmlSerializer out, WifiEnterpriseConfig enterpriseConfig)990 public static void writeToXml(XmlSerializer out, WifiEnterpriseConfig enterpriseConfig) 991 throws XmlPullParserException, IOException { 992 XmlUtil.writeNextValue(out, XML_TAG_IDENTITY, 993 enterpriseConfig.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY)); 994 XmlUtil.writeNextValue(out, XML_TAG_ANON_IDENTITY, 995 enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY)); 996 XmlUtil.writeNextValue(out, XML_TAG_PASSWORD, 997 enterpriseConfig.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY)); 998 XmlUtil.writeNextValue(out, XML_TAG_CLIENT_CERT, 999 enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY)); 1000 XmlUtil.writeNextValue(out, XML_TAG_CA_CERT, 1001 enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY)); 1002 XmlUtil.writeNextValue(out, XML_TAG_SUBJECT_MATCH, 1003 enterpriseConfig.getFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY)); 1004 XmlUtil.writeNextValue(out, XML_TAG_ENGINE, 1005 enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_KEY)); 1006 XmlUtil.writeNextValue(out, XML_TAG_ENGINE_ID, 1007 enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY)); 1008 XmlUtil.writeNextValue(out, XML_TAG_PRIVATE_KEY_ID, 1009 enterpriseConfig.getFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY)); 1010 XmlUtil.writeNextValue(out, XML_TAG_ALT_SUBJECT_MATCH, 1011 enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY)); 1012 XmlUtil.writeNextValue(out, XML_TAG_DOM_SUFFIX_MATCH, 1013 enterpriseConfig.getFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY)); 1014 XmlUtil.writeNextValue(out, XML_TAG_CA_PATH, 1015 enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY)); 1016 XmlUtil.writeNextValue(out, XML_TAG_EAP_METHOD, enterpriseConfig.getEapMethod()); 1017 XmlUtil.writeNextValue(out, XML_TAG_PHASE2_METHOD, enterpriseConfig.getPhase2Method()); 1018 XmlUtil.writeNextValue(out, XML_TAG_PLMN, enterpriseConfig.getPlmn()); 1019 XmlUtil.writeNextValue(out, XML_TAG_REALM, enterpriseConfig.getRealm()); 1020 } 1021 1022 /** 1023 * Parses the data elements from the provided XML stream to a WifiEnterpriseConfig object. 1024 * 1025 * @param in XmlPullParser instance pointing to the XML stream. 1026 * @param outerTagDepth depth of the outer tag in the XML document. 1027 * @return WifiEnterpriseConfig object if parsing is successful, null otherwise. 1028 */ parseFromXml(XmlPullParser in, int outerTagDepth)1029 public static WifiEnterpriseConfig parseFromXml(XmlPullParser in, int outerTagDepth) 1030 throws XmlPullParserException, IOException { 1031 WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); 1032 1033 // Loop through and parse out all the elements from the stream within this section. 1034 while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) { 1035 String[] valueName = new String[1]; 1036 Object value = XmlUtil.readCurrentValue(in, valueName); 1037 if (valueName[0] == null) { 1038 throw new XmlPullParserException("Missing value name"); 1039 } 1040 switch (valueName[0]) { 1041 case XML_TAG_IDENTITY: 1042 enterpriseConfig.setFieldValue( 1043 WifiEnterpriseConfig.IDENTITY_KEY, (String) value); 1044 break; 1045 case XML_TAG_ANON_IDENTITY: 1046 enterpriseConfig.setFieldValue( 1047 WifiEnterpriseConfig.ANON_IDENTITY_KEY, (String) value); 1048 break; 1049 case XML_TAG_PASSWORD: 1050 enterpriseConfig.setFieldValue( 1051 WifiEnterpriseConfig.PASSWORD_KEY, (String) value); 1052 break; 1053 case XML_TAG_CLIENT_CERT: 1054 enterpriseConfig.setFieldValue( 1055 WifiEnterpriseConfig.CLIENT_CERT_KEY, (String) value); 1056 break; 1057 case XML_TAG_CA_CERT: 1058 enterpriseConfig.setFieldValue( 1059 WifiEnterpriseConfig.CA_CERT_KEY, (String) value); 1060 break; 1061 case XML_TAG_SUBJECT_MATCH: 1062 enterpriseConfig.setFieldValue( 1063 WifiEnterpriseConfig.SUBJECT_MATCH_KEY, (String) value); 1064 break; 1065 case XML_TAG_ENGINE: 1066 enterpriseConfig.setFieldValue( 1067 WifiEnterpriseConfig.ENGINE_KEY, (String) value); 1068 break; 1069 case XML_TAG_ENGINE_ID: 1070 enterpriseConfig.setFieldValue( 1071 WifiEnterpriseConfig.ENGINE_ID_KEY, (String) value); 1072 break; 1073 case XML_TAG_PRIVATE_KEY_ID: 1074 enterpriseConfig.setFieldValue( 1075 WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, (String) value); 1076 break; 1077 case XML_TAG_ALT_SUBJECT_MATCH: 1078 enterpriseConfig.setFieldValue( 1079 WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, (String) value); 1080 break; 1081 case XML_TAG_DOM_SUFFIX_MATCH: 1082 enterpriseConfig.setFieldValue( 1083 WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, (String) value); 1084 break; 1085 case XML_TAG_CA_PATH: 1086 enterpriseConfig.setFieldValue( 1087 WifiEnterpriseConfig.CA_PATH_KEY, (String) value); 1088 break; 1089 case XML_TAG_EAP_METHOD: 1090 enterpriseConfig.setEapMethod((int) value); 1091 break; 1092 case XML_TAG_PHASE2_METHOD: 1093 enterpriseConfig.setPhase2Method((int) value); 1094 break; 1095 case XML_TAG_PLMN: 1096 enterpriseConfig.setPlmn((String) value); 1097 break; 1098 case XML_TAG_REALM: 1099 enterpriseConfig.setRealm((String) value); 1100 break; 1101 default: 1102 throw new XmlPullParserException( 1103 "Unknown value name found: " + valueName[0]); 1104 } 1105 } 1106 return enterpriseConfig; 1107 } 1108 } 1109 } 1110 1111