MOManager.java revision 05d2f4e6f26834a94b53187e6121379a16749088
1package com.android.server.wifi.hotspot2.omadm; 2 3import android.util.Log; 4 5import com.android.server.wifi.anqp.eap.EAP; 6import com.android.server.wifi.anqp.eap.EAPMethod; 7import com.android.server.wifi.anqp.eap.ExpandedEAPMethod; 8import com.android.server.wifi.anqp.eap.InnerAuthEAP; 9import com.android.server.wifi.anqp.eap.NonEAPInnerAuth; 10import com.android.server.wifi.hotspot2.Utils; 11import com.android.server.wifi.hotspot2.pps.Credential; 12import com.android.server.wifi.hotspot2.pps.HomeSP; 13 14import org.xml.sax.SAXException; 15 16import java.io.BufferedInputStream; 17import java.io.BufferedOutputStream; 18import java.io.File; 19import java.io.FileInputStream; 20import java.io.FileOutputStream; 21import java.io.IOException; 22import java.text.DateFormat; 23import java.text.ParseException; 24import java.text.SimpleDateFormat; 25import java.util.ArrayList; 26import java.util.Arrays; 27import java.util.Collection; 28import java.util.Collections; 29import java.util.Date; 30import java.util.HashMap; 31import java.util.HashSet; 32import java.util.List; 33import java.util.Map; 34import java.util.Set; 35import java.util.TimeZone; 36 37/** 38 * Handles provisioning of PerProviderSubscription data. 39 */ 40public class MOManager { 41 42 public static final String TAG_AAAServerTrustRoot = "AAAServerTrustRoot"; 43 public static final String TAG_AbleToShare = "AbleToShare"; 44 public static final String TAG_CertificateType = "CertificateType"; 45 public static final String TAG_CertSHA256Fingerprint = "CertSHA256Fingerprint"; 46 public static final String TAG_CertURL = "CertURL"; 47 public static final String TAG_CheckAAAServerCertStatus = "CheckAAAServerCertStatus"; 48 public static final String TAG_Country = "Country"; 49 public static final String TAG_CreationDate = "CreationDate"; 50 public static final String TAG_Credential = "Credential"; 51 public static final String TAG_CredentialPriority = "CredentialPriority"; 52 public static final String TAG_DataLimit = "DataLimit"; 53 public static final String TAG_DigitalCertificate = "DigitalCertificate"; 54 public static final String TAG_DLBandwidth = "DLBandwidth"; 55 public static final String TAG_EAPMethod = "EAPMethod"; 56 public static final String TAG_EAPType = "EAPType"; 57 public static final String TAG_ExpirationDate = "ExpirationDate"; 58 public static final String TAG_Extension = "Extension"; 59 public static final String TAG_FQDN = "FQDN"; 60 public static final String TAG_FQDN_Match = "FQDN_Match"; 61 public static final String TAG_FriendlyName = "FriendlyName"; 62 public static final String TAG_HESSID = "HESSID"; 63 public static final String TAG_HomeOI = "HomeOI"; 64 public static final String TAG_HomeOIList = "HomeOIList"; 65 public static final String TAG_HomeOIRequired = "HomeOIRequired"; 66 public static final String TAG_HomeSP = "HomeSP"; 67 public static final String TAG_IconURL = "IconURL"; 68 public static final String TAG_IMSI = "IMSI"; 69 public static final String TAG_InnerEAPType = "InnerEAPType"; 70 public static final String TAG_InnerMethod = "InnerMethod"; 71 public static final String TAG_InnerVendorID = "InnerVendorID"; 72 public static final String TAG_InnerVendorType = "InnerVendorType"; 73 public static final String TAG_IPProtocol = "IPProtocol"; 74 public static final String TAG_MachineManaged = "MachineManaged"; 75 public static final String TAG_MaximumBSSLoadValue = "MaximumBSSLoadValue"; 76 public static final String TAG_MinBackhaulThreshold = "MinBackhaulThreshold"; 77 public static final String TAG_NetworkID = "NetworkID"; 78 public static final String TAG_NetworkType = "NetworkType"; 79 public static final String TAG_Other = "Other"; 80 public static final String TAG_OtherHomePartners = "OtherHomePartners"; 81 public static final String TAG_Password = "Password"; 82 public static final String TAG_PerProviderSubscription = "PerProviderSubscription"; 83 public static final String TAG_Policy = "Policy"; 84 public static final String TAG_PolicyUpdate = "PolicyUpdate"; 85 public static final String TAG_PortNumber = "PortNumber"; 86 public static final String TAG_PreferredRoamingPartnerList = "PreferredRoamingPartnerList"; 87 public static final String TAG_Priority = "Priority"; 88 public static final String TAG_Realm = "Realm"; 89 public static final String TAG_RequiredProtoPortTuple = "RequiredProtoPortTuple"; 90 public static final String TAG_Restriction = "Restriction"; 91 public static final String TAG_RoamingConsortiumOI = "RoamingConsortiumOI"; 92 public static final String TAG_SIM = "SIM"; 93 public static final String TAG_SoftTokenApp = "SoftTokenApp"; 94 public static final String TAG_SPExclusionList = "SPExclusionList"; 95 public static final String TAG_SSID = "SSID"; 96 public static final String TAG_StartDate = "StartDate"; 97 public static final String TAG_SubscriptionParameters = "SubscriptionParameters"; 98 public static final String TAG_SubscriptionUpdate = "SubscriptionUpdate"; 99 public static final String TAG_TimeLimit = "TimeLimit"; 100 public static final String TAG_TrustRoot = "TrustRoot"; 101 public static final String TAG_TypeOfSubscription = "TypeOfSubscription"; 102 public static final String TAG_ULBandwidth = "ULBandwidth"; 103 public static final String TAG_UpdateIdentifier = "UpdateIdentifier"; 104 public static final String TAG_UpdateInterval = "UpdateInterval"; 105 public static final String TAG_UpdateMethod = "UpdateMethod"; 106 public static final String TAG_URI = "URI"; 107 public static final String TAG_UsageLimits = "UsageLimits"; 108 public static final String TAG_UsageTimePeriod = "UsageTimePeriod"; 109 public static final String TAG_Username = "Username"; 110 public static final String TAG_UsernamePassword = "UsernamePassword"; 111 public static final String TAG_VendorId = "VendorId"; 112 public static final String TAG_VendorType = "VendorType"; 113 114 private final File mPpsFile; 115 private final Map<String, HomeSP> mSPs; 116 117 public MOManager(File ppsFile) { 118 mPpsFile = ppsFile; 119 mSPs = new HashMap<>(); 120 } 121 122 public File getPpsFile() { 123 return mPpsFile; 124 } 125 126 public Map<String, HomeSP> getLoadedSPs() { 127 return mSPs; 128 } 129 130 public List<HomeSP> loadAllSPs() throws IOException { 131 132 if (!mPpsFile.exists()) { 133 return Collections.emptyList(); 134 } 135 136 try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(mPpsFile))) { 137 MOTree moTree = MOTree.unmarshal(in); 138 Log.d("HS2J", "MO Tree: " + moTree); 139 mSPs.clear(); 140 if (moTree == null) { 141 return Collections.emptyList(); // Empty file 142 } 143 144 List<HomeSP> sps = buildSPs(moTree); 145 if (sps != null) { 146 for (HomeSP sp : sps) { 147 if (mSPs.put(sp.getFQDN(), sp) != null) { 148 throw new OMAException("Multiple SPs for FQDN '" + sp.getFQDN() + "'"); 149 } else { 150 Log.d("PARSE-LOG", "retrieved " + sp.getFQDN() + " from PPS"); 151 } 152 } 153 return sps; 154 155 } else { 156 throw new OMAException("Failed to build HomeSP"); 157 } 158 } 159 } 160 161 public static HomeSP buildSP(String xml) throws IOException, SAXException { 162 OMAParser omaParser = new OMAParser(); 163 MOTree tree = omaParser.parse(xml, OMAConstants.LOC_PPS + ":1.0"); 164 List<HomeSP> spList = buildSPs(tree); 165 if (spList.size() != 1) { 166 throw new OMAException("Expected exactly one HomeSP, got " + spList.size()); 167 } 168 return spList.iterator().next(); 169 } 170 171 public HomeSP addSP(String xml) throws IOException, SAXException { 172 OMAParser omaParser = new OMAParser(); 173 MOTree tree = omaParser.parse(xml, OMAConstants.LOC_PPS + ":1.0"); 174 List<HomeSP> spList = buildSPs(tree); 175 if (spList.size() != 1) { 176 throw new OMAException("Expected exactly one HomeSP, got " + spList.size()); 177 } 178 HomeSP sp = spList.iterator().next(); 179 String fqdn = sp.getFQDN(); 180 if (mSPs.put(fqdn, sp) != null) { 181 throw new OMAException("SP " + fqdn + " already exists"); 182 } 183 184 BufferedOutputStream out = null; 185 try { 186 out = new BufferedOutputStream(new FileOutputStream(mPpsFile, true)); 187 tree.marshal(out); 188 out.flush(); 189 } finally { 190 if (out != null) { 191 try { 192 out.close(); 193 } catch (IOException ioe) { 194 /**/ 195 } 196 } 197 } 198 199 return sp; 200 } 201 202 public void saveAllSps(Collection<HomeSP> homeSPs) throws IOException { 203 boolean dirty = homeSPs.size() != mSPs.size(); 204 205 if (!dirty) { 206 Map<String, HomeSP> spClone = new HashMap<>(mSPs); 207 for (HomeSP homeSP : homeSPs) { 208 HomeSP existing = spClone.remove(homeSP.getFQDN()); 209 if (!homeSP.deepEquals(existing)) { 210 dirty = true; 211 break; 212 } 213 } 214 215 if (!dirty) { 216 dirty = !spClone.isEmpty(); 217 } 218 } 219 220 Log.d("HS2J", "Save all SPs: dirty: " + dirty + 221 ", update from " + mSPs.size() + " to " + homeSPs); 222 if (homeSPs.size() < mSPs.size()) { 223 return; 224 } 225 226 if (dirty) { 227 mSPs.clear(); 228 229 OMAConstructed ppsNode = new OMAConstructed(null, TAG_PerProviderSubscription, null); 230 int instance = 0; 231 for (HomeSP homeSP : homeSPs) { 232 buildHomeSPTree(homeSP, ppsNode, instance++); 233 mSPs.put(homeSP.getFQDN(), homeSP); 234 } 235 236 MOTree tree = new MOTree(OMAConstants.LOC_PPS + ":1.0", "1.2", ppsNode); 237 try (BufferedOutputStream out = 238 new BufferedOutputStream(new FileOutputStream(mPpsFile, true))) { 239 tree.marshal(out); 240 out.flush(); 241 } 242 } 243 } 244 245 private static void buildHomeSPTree(HomeSP homeSP, OMAConstructed root, int spInstance) 246 throws IOException { 247 OMANode providerSubNode = root.addChild(getInstanceString(spInstance), null, null, null); 248 249 // The HomeSP: 250 OMANode homeSpNode = providerSubNode.addChild(TAG_HomeSP, null, null, null); 251 if (!homeSP.getSSIDs().isEmpty()) { 252 OMAConstructed nwkIDNode = 253 (OMAConstructed) homeSpNode.addChild(TAG_NetworkID, null, null, null); 254 int instance = 0; 255 for (Map.Entry<String, Long> entry : homeSP.getSSIDs().entrySet()) { 256 OMAConstructed inode = 257 (OMAConstructed) nwkIDNode.addChild(getInstanceString(instance++), null, null, null); 258 inode.addChild(TAG_SSID, null, entry.getKey(), null); 259 if (entry.getValue() != null) { 260 inode.addChild(TAG_HESSID, null, String.format("%012x", entry.getValue()), null); 261 } 262 } 263 } 264 265 homeSpNode.addChild(TAG_FriendlyName, null, homeSP.getFriendlyName(), null); 266 267 if (homeSP.getIconURL() != null) { 268 homeSpNode.addChild(TAG_IconURL, null, homeSP.getIconURL(), null); 269 } 270 271 homeSpNode.addChild(TAG_FQDN, null, homeSP.getFQDN(), null); 272 273 if (!homeSP.getMatchAllOIs().isEmpty() || !homeSP.getMatchAnyOIs().isEmpty()) { 274 OMAConstructed homeOIList = 275 (OMAConstructed) homeSpNode.addChild(TAG_HomeOIList, null, null, null); 276 277 int instance = 0; 278 for (Long oi : homeSP.getMatchAllOIs()) { 279 OMAConstructed inode = 280 (OMAConstructed) homeOIList.addChild(getInstanceString(instance++), 281 null, null, null); 282 inode.addChild(TAG_HomeOI, null, String.format("%x", oi), null); 283 inode.addChild(TAG_HomeOIRequired, null, "TRUE", null); 284 } 285 for (Long oi : homeSP.getMatchAnyOIs()) { 286 OMAConstructed inode = 287 (OMAConstructed) homeOIList.addChild(getInstanceString(instance++), 288 null, null, null); 289 inode.addChild(TAG_HomeOI, null, String.format("%x", oi), null); 290 inode.addChild(TAG_HomeOIRequired, null, "FALSE", null); 291 } 292 } 293 294 if (!homeSP.getOtherHomePartners().isEmpty()) { 295 OMAConstructed otherPartners = 296 (OMAConstructed) homeSpNode.addChild(TAG_OtherHomePartners, null, null, null); 297 int instance = 0; 298 for (String fqdn : homeSP.getOtherHomePartners()) { 299 OMAConstructed inode = 300 (OMAConstructed) otherPartners.addChild(getInstanceString(instance++), 301 null, null, null); 302 inode.addChild(TAG_FQDN, null, fqdn, null); 303 } 304 } 305 306 if (!homeSP.getRoamingConsortiums().isEmpty()) { 307 homeSpNode.addChild(TAG_RoamingConsortiumOI, null, getRCList(homeSP.getRoamingConsortiums()), null); 308 } 309 310 // The Credential: 311 OMANode credentialNode = providerSubNode.addChild(TAG_Credential, null, null, null); 312 Credential cred = homeSP.getCredential(); 313 EAPMethod method = cred.getEAPMethod(); 314 315 if (method.getEAPMethodID() == EAP.EAPMethodID.EAP_SIM 316 || method.getEAPMethodID() == EAP.EAPMethodID.EAP_AKA 317 || method.getEAPMethodID() == EAP.EAPMethodID.EAP_AKAPrim) { 318 319 OMANode simNode = credentialNode.addChild(TAG_SIM, null, null, null); 320 simNode.addChild(TAG_IMSI, null, cred.getImsi(), null); 321 simNode.addChild(TAG_EAPType, null, 322 Integer.toString(EAP.mapEAPMethod(method.getEAPMethodID())), null); 323 324 } else if (method.getEAPMethodID() == EAP.EAPMethodID.EAP_TTLS) { 325 326 OMANode unpNode = credentialNode.addChild(TAG_UsernamePassword, null, null, null); 327 unpNode.addChild(TAG_Username, null, cred.getUserName(), null); 328 unpNode.addChild(TAG_Password, null, cred.getPassword(), null); 329 OMANode eapNode = unpNode.addChild(TAG_EAPMethod, null, null, null); 330 eapNode.addChild(TAG_EAPType, null, 331 Integer.toString(EAP.mapEAPMethod(method.getEAPMethodID())), null); 332 eapNode.addChild(TAG_InnerMethod, null, 333 ((NonEAPInnerAuth) method.getAuthParam()).getOMAtype(), null); 334 335 } else if (method.getEAPMethodID() == EAP.EAPMethodID.EAP_TLS) { 336 337 OMANode certNode = credentialNode.addChild(TAG_DigitalCertificate, null, null, null); 338 certNode.addChild(TAG_CertificateType, null, Credential.CertTypeX509, null); 339 certNode.addChild(TAG_CertSHA256Fingerprint, null, 340 Utils.toHex(cred.getFingerPrint()), null); 341 342 } else { 343 throw new OMAException("Invalid credential on " + homeSP.getFQDN()); 344 } 345 346 credentialNode.addChild(TAG_Realm, null, homeSP.getCredential().getRealm(), null); 347 // !!! Note: This node defines CRL checking through OSCP, I suspect we won't be able 348 // to do that so it is commented out: 349 //credentialNode.addChild(TAG_CheckAAAServerCertStatus, null, "TRUE", null); 350 } 351 352 private static String getInstanceString(int instance) { 353 return "i" + instance; 354 } 355 356 private static String getRCList(Collection<Long> rcs) { 357 StringBuilder builder = new StringBuilder(); 358 boolean first = true; 359 for (Long roamingConsortium : rcs) { 360 if (first) { 361 first = false; 362 } 363 else { 364 builder.append(','); 365 } 366 builder.append(String.format("%x", roamingConsortium)); 367 } 368 return builder.toString(); 369 } 370 371 private static final DateFormat DTFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); 372 373 static { 374 DTFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 375 } 376 377 private static List<HomeSP> buildSPs(MOTree moTree) throws OMAException { 378 Log.d("HS2J", "MO root: " + moTree.getRoot().getName()); 379 OMAConstructed spList; 380 if (moTree.getRoot().getName().equals(TAG_PerProviderSubscription)) { 381 // The PPS file is rooted at PPS instead of MgmtTree to conserve space 382 spList = moTree.getRoot(); 383 } 384 else { 385 List<String> spPath = Arrays.asList(TAG_PerProviderSubscription); 386 spList = moTree.getRoot().getListValue(spPath.iterator()); 387 } 388 389 List<HomeSP> homeSPs = new ArrayList<>(); 390 391 if (spList == null) { 392 return homeSPs; 393 } 394 for (OMANode spRoot : spList.getChildren()) { 395 homeSPs.add(buildHomeSP(spRoot)); 396 } 397 398 return homeSPs; 399 } 400 401 private static HomeSP buildHomeSP(OMANode ppsRoot) throws OMAException { 402 OMANode spRoot = ppsRoot.getChild(TAG_HomeSP); 403 404 String fqdn = spRoot.getScalarValue(Arrays.asList(TAG_FQDN).iterator()); 405 String friendlyName = spRoot.getScalarValue(Arrays.asList(TAG_FriendlyName).iterator()); 406 String iconURL = spRoot.getScalarValue(Arrays.asList(TAG_IconURL).iterator()); 407 408 HashSet<Long> roamingConsortiums = new HashSet<>(); 409 String oiString = spRoot.getScalarValue(Arrays.asList(TAG_RoamingConsortiumOI).iterator()); 410 if (oiString != null) { 411 for (String oi : oiString.split(",")) { 412 roamingConsortiums.add(Long.parseLong(oi.trim(), 16)); 413 } 414 } 415 416 Map<String, Long> ssids = new HashMap<>(); 417 418 OMANode ssidListNode = spRoot.getListValue(Arrays.asList(TAG_NetworkID).iterator()); 419 if (ssidListNode != null) { 420 for (OMANode ssidRoot : ssidListNode.getChildren()) { 421 OMANode hessidNode = ssidRoot.getChild(TAG_HESSID); 422 ssids.put(ssidRoot.getChild(TAG_SSID).getValue(), getMac(hessidNode)); 423 } 424 } 425 426 Set<Long> matchAnyOIs = new HashSet<>(); 427 List<Long> matchAllOIs = new ArrayList<>(); 428 OMANode homeOIListNode = spRoot.getListValue(Arrays.asList(TAG_HomeOIList).iterator()); 429 if (homeOIListNode != null) { 430 for (OMANode homeOIRoot : homeOIListNode.getChildren()) { 431 String homeOI = homeOIRoot.getChild(TAG_HomeOI).getValue(); 432 if (Boolean.parseBoolean(homeOIRoot.getChild(TAG_HomeOIRequired).getValue())) { 433 matchAllOIs.add(Long.parseLong(homeOI, 16)); 434 } else { 435 matchAnyOIs.add(Long.parseLong(homeOI, 16)); 436 } 437 } 438 } 439 440 Set<String> otherHomePartners = new HashSet<>(); 441 OMANode otherListNode = 442 spRoot.getListValue(Arrays.asList(TAG_OtherHomePartners).iterator()); 443 if (otherListNode != null) { 444 for (OMANode fqdnNode : otherListNode.getChildren()) { 445 otherHomePartners.add(fqdnNode.getChild(TAG_FQDN).getValue()); 446 } 447 } 448 449 Credential credential = buildCredential(ppsRoot.getChild(TAG_Credential)); 450 451 return new HomeSP(ssids, fqdn, roamingConsortiums, otherHomePartners, 452 matchAnyOIs, matchAllOIs, friendlyName, iconURL, credential); 453 } 454 455 private static Credential buildCredential(OMANode credNode) throws OMAException { 456 long ctime = getTime(credNode.getChild(TAG_CreationDate)); 457 long expTime = getTime(credNode.getChild(TAG_ExpirationDate)); 458 String realm = getString(credNode.getChild(TAG_Realm)); 459 boolean checkAAACert = getBoolean(credNode.getChild(TAG_CheckAAAServerCertStatus)); 460 461 OMANode unNode = credNode.getChild(TAG_UsernamePassword); 462 OMANode certNode = credNode.getChild(TAG_DigitalCertificate); 463 OMANode simNode = credNode.getChild(TAG_SIM); 464 465 int alternatives = 0; 466 alternatives += unNode != null ? 1 : 0; 467 alternatives += certNode != null ? 1 : 0; 468 alternatives += simNode != null ? 1 : 0; 469 if (alternatives != 1) { 470 throw new OMAException("Expected exactly one credential type, got " + alternatives); 471 } 472 473 if (unNode != null) { 474 String userName = getString(unNode.getChild(TAG_Username)); 475 String password = getString(unNode.getChild(TAG_Password)); 476 boolean machineManaged = getBoolean(unNode.getChild(TAG_MachineManaged)); 477 String softTokenApp = getString(unNode.getChild(TAG_SoftTokenApp)); 478 boolean ableToShare = getBoolean(unNode.getChild(TAG_AbleToShare)); 479 480 OMANode eapMethodNode = unNode.getChild(TAG_EAPMethod); 481 int eapID = getInteger(eapMethodNode.getChild(TAG_EAPType)); 482 483 EAP.EAPMethodID eapMethodID = EAP.mapEAPMethod(eapID); 484 if (eapMethodID == null) { 485 throw new OMAException("Unknown EAP method: " + eapID); 486 } 487 488 Long vid = getOptionalInteger(eapMethodNode.getChild(TAG_VendorId)); 489 Long vtype = getOptionalInteger(eapMethodNode.getChild(TAG_VendorType)); 490 Long innerEAPType = getOptionalInteger(eapMethodNode.getChild(TAG_InnerEAPType)); 491 EAP.EAPMethodID innerEAPMethod = null; 492 if (innerEAPType != null) { 493 innerEAPMethod = EAP.mapEAPMethod(innerEAPType.intValue()); 494 if (innerEAPMethod == null) { 495 throw new OMAException("Bad inner EAP method: " + innerEAPType); 496 } 497 } 498 499 Long innerVid = getOptionalInteger(eapMethodNode.getChild(TAG_InnerVendorID)); 500 Long innerVtype = getOptionalInteger(eapMethodNode.getChild(TAG_InnerVendorType)); 501 String innerNonEAPMethod = getString(eapMethodNode.getChild(TAG_InnerMethod)); 502 503 EAPMethod eapMethod; 504 if (innerEAPMethod != null) { 505 eapMethod = new EAPMethod(eapMethodID, new InnerAuthEAP(innerEAPMethod)); 506 } else if (vid != null) { 507 eapMethod = new EAPMethod(eapMethodID, 508 new ExpandedEAPMethod(EAP.AuthInfoID.ExpandedEAPMethod, 509 vid.intValue(), vtype)); 510 } else if (innerVid != null) { 511 eapMethod = 512 new EAPMethod(eapMethodID, new ExpandedEAPMethod(EAP.AuthInfoID 513 .ExpandedInnerEAPMethod, innerVid.intValue(), innerVtype)); 514 } else if (innerNonEAPMethod != null) { 515 eapMethod = new EAPMethod(eapMethodID, new NonEAPInnerAuth(innerNonEAPMethod)); 516 } else { 517 throw new OMAException("Incomplete set of EAP parameters"); 518 } 519 520 return new Credential(ctime, expTime, realm, checkAAACert, eapMethod, userName, 521 password, machineManaged, softTokenApp, ableToShare); 522 } 523 if (certNode != null) { 524 try { 525 String certTypeString = getString(certNode.getChild(TAG_CertificateType)); 526 byte[] fingerPrint = getOctets(certNode.getChild(TAG_CertSHA256Fingerprint)); 527 528 EAPMethod eapMethod = new EAPMethod(EAP.EAPMethodID.EAP_TLS, null); 529 530 return new Credential(ctime, expTime, realm, checkAAACert, eapMethod, 531 Credential.mapCertType(certTypeString), fingerPrint); 532 } 533 catch (NumberFormatException nfe) { 534 throw new OMAException("Bad hex string: " + nfe.toString()); 535 } 536 } 537 if (simNode != null) { 538 539 String imsi = getString(simNode.getChild(TAG_IMSI)); 540 EAPMethod eapMethod = 541 new EAPMethod(EAP.mapEAPMethod(getInteger(simNode.getChild(TAG_EAPType))), 542 null); 543 544 return new Credential(ctime, expTime, realm, checkAAACert, eapMethod, imsi); 545 } 546 throw new OMAException("Missing credential parameters"); 547 } 548 549 private static boolean getBoolean(OMANode boolNode) { 550 return boolNode != null && Boolean.parseBoolean(boolNode.getValue()); 551 } 552 553 private static String getString(OMANode stringNode) { 554 return stringNode != null ? stringNode.getValue() : null; 555 } 556 557 private static int getInteger(OMANode intNode) throws OMAException { 558 if (intNode == null) { 559 throw new OMAException("Missing integer value"); 560 } 561 try { 562 return Integer.parseInt(intNode.getValue()); 563 } catch (NumberFormatException nfe) { 564 throw new OMAException("Invalid integer: " + intNode.getValue()); 565 } 566 } 567 568 private static Long getMac(OMANode macNode) throws OMAException { 569 if (macNode == null) { 570 return null; 571 } 572 try { 573 return Long.parseLong(macNode.getValue(), 16); 574 } catch (NumberFormatException nfe) { 575 throw new OMAException("Invalid MAC: " + macNode.getValue()); 576 } 577 } 578 579 private static Long getOptionalInteger(OMANode intNode) throws OMAException { 580 if (intNode == null) { 581 return null; 582 } 583 try { 584 return Long.parseLong(intNode.getValue()); 585 } catch (NumberFormatException nfe) { 586 throw new OMAException("Invalid integer: " + intNode.getValue()); 587 } 588 } 589 590 private static long getTime(OMANode timeNode) throws OMAException { 591 if (timeNode == null) { 592 return -1; 593 } 594 String timeText = timeNode.getValue(); 595 try { 596 Date date = DTFormat.parse(timeText); 597 return date.getTime(); 598 } catch (ParseException pe) { 599 throw new OMAException("Badly formatted time: " + timeText); 600 } 601 } 602 603 private static byte[] getOctets(OMANode octetNode) throws OMAException { 604 if (octetNode == null) { 605 throw new OMAException("Missing byte value"); 606 } 607 return Utils.hexToBytes(octetNode.getValue()); 608 } 609} 610