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