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