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