/****************************************************************** * * CyberUPnP for Java * * Copyright (C) Satoshi Konno 2002-2003 * * File: UPnP.java * * Revision; * * 11/18/02 * - first revision. * 05/13/03 * - Added support for IPv6 and loopback address. * 12/26/03 * - Added support for XML Parser * 06/18/03 * - Added INMPR03 and INMPR03_VERSION. * 04/14/06 * - Added some functios about time-to-live, and the default value is 4. * 05/11/09 * - Changed loadDefaultXMLParser() to load org.cybergarage.xml.parser.XmlPullParser at first. * ******************************************************************/ package org.cybergarage.upnp; import org.cybergarage.net.HostInterface; import org.cybergarage.soap.SOAP; import org.cybergarage.upnp.ssdp.SSDP; import org.cybergarage.util.Debug; import org.cybergarage.xml.Parser; public class UPnP { //////////////////////////////////////////////// // Constants //////////////////////////////////////////////// /** * Name of the system properties used to identifies the default XML Parser.<br> * The value of the properties MUST BE the fully qualified class name of<br> * XML Parser which CyberLink should use. */ public final static String XML_CLASS_PROPERTTY="cyberlink.upnp.xml.parser"; public final static String NAME = "CyberLinkJava"; public final static String VERSION = "3.0"; // I2P was 100 public final static int SERVER_RETRY_COUNT = 4; public final static int DEFAULT_EXPIRED_DEVICE_EXTRA_TIME = 60; public final static String getServerName() { String osName = System.getProperty("os.name"); String osVer = System.getProperty("os.version"); return osName + "/" + osVer + " UPnP/1.0 " + NAME + "/" + VERSION; } public final static String INMPR03 = "INMPR03"; public final static String INMPR03_VERSION = "1.0"; public final static int INMPR03_DISCOVERY_OVER_WIRELESS_COUNT = 4; public final static String XML_DECLARATION = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"; public final static int CONFIGID_UPNP_ORG_MAX = 16777215; //////////////////////////////////////////////// // Enable / Disable //////////////////////////////////////////////// public final static int USE_ONLY_IPV6_ADDR = 1; public final static int USE_LOOPBACK_ADDR = 2; public final static int USE_IPV6_LINK_LOCAL_SCOPE = 3; public final static int USE_IPV6_SUBNET_SCOPE = 4; public final static int USE_IPV6_ADMINISTRATIVE_SCOPE = 5; public final static int USE_IPV6_SITE_LOCAL_SCOPE = 6; public final static int USE_IPV6_GLOBAL_SCOPE = 7; public final static int USE_SSDP_SEARCHRESPONSE_MULTIPLE_INTERFACES = 8; public final static int USE_ONLY_IPV4_ADDR = 9; public final static void setEnable(int value) { switch (value) { case USE_ONLY_IPV6_ADDR: { HostInterface.USE_ONLY_IPV6_ADDR = true; } break; case USE_ONLY_IPV4_ADDR: { HostInterface.USE_ONLY_IPV4_ADDR = true; } break; case USE_LOOPBACK_ADDR: { HostInterface.USE_LOOPBACK_ADDR = true; } break; case USE_IPV6_LINK_LOCAL_SCOPE: { SSDP.setIPv6Address(SSDP.IPV6_LINK_LOCAL_ADDRESS); } break; case USE_IPV6_SUBNET_SCOPE: { SSDP.setIPv6Address(SSDP.IPV6_SUBNET_ADDRESS); } break; case USE_IPV6_ADMINISTRATIVE_SCOPE: { SSDP.setIPv6Address(SSDP.IPV6_ADMINISTRATIVE_ADDRESS); } break; case USE_IPV6_SITE_LOCAL_SCOPE: { SSDP.setIPv6Address(SSDP.IPV6_SITE_LOCAL_ADDRESS); } break; case USE_IPV6_GLOBAL_SCOPE: { SSDP.setIPv6Address(SSDP.IPV6_GLOBAL_ADDRESS); } break; } } public final static void setDisable(int value) { switch (value) { case USE_ONLY_IPV6_ADDR: { HostInterface.USE_ONLY_IPV6_ADDR = false; } break; case USE_ONLY_IPV4_ADDR: { HostInterface.USE_ONLY_IPV4_ADDR = false; } break; case USE_LOOPBACK_ADDR: { HostInterface.USE_LOOPBACK_ADDR = false; } break; } } public final static boolean isEnabled(int value) { switch (value) { case USE_ONLY_IPV6_ADDR: { return HostInterface.USE_ONLY_IPV6_ADDR; } case USE_ONLY_IPV4_ADDR: { return HostInterface.USE_ONLY_IPV4_ADDR; } case USE_LOOPBACK_ADDR: { return HostInterface.USE_LOOPBACK_ADDR; } } return false; } //////////////////////////////////////////////// // UUID //////////////////////////////////////////////// private static final String toUUID(int seed) { String id = Integer.toString((int)(seed & 0xFFFF), 16); int idLen = id.length(); String uuid = ""; for (int n=0; n<(4-idLen); n++) uuid += "0"; uuid += id; return uuid; } public static final String createUUID() { long time1 = System.currentTimeMillis(); long time2 = (long)((double)System.currentTimeMillis() * Math.random()); return toUUID((int)(time1 & 0xFFFF)) + "-" + toUUID((int)((time1 >> 32) | 0xA000) & 0xFFFF) + "-" + toUUID((int)(time2 & 0xFFFF)) + "-" + toUUID((int)((time2 >> 32) | 0xE000) & 0xFFFF); } //////////////////////////////////////////////// // BootId //////////////////////////////////////////////// public static final int createBootId() { return (int)(System.currentTimeMillis() / 1000L); } //////////////////////////////////////////////// // ConfigId //////////////////////////////////////////////// public static final int caluculateConfigId(String configXml) { if (configXml == null) return 0; int configId = 0; int configLen = configXml.length(); for (int n=0; n<configLen; n++) { configId += configXml.codePointAt(n); if (configId < CONFIGID_UPNP_ORG_MAX) continue; configId = configId % CONFIGID_UPNP_ORG_MAX; } return configId; } //////////////////////////////////////////////// // XML Parser //////////////////////////////////////////////// private static Parser xmlParser; public final static void setXMLParser(Parser parser) { xmlParser = parser; SOAP.setXMLParser(parser); } public final static Parser getXMLParser() { if(xmlParser == null){ xmlParser = loadDefaultXMLParser(); if(xmlParser == null) throw new RuntimeException("No XML parser defined. And unable to laod any. \n" + "Try to invoke UPnP.setXMLParser before UPnP.getXMLParser"); SOAP.setXMLParser(xmlParser); } return xmlParser; } /** * This method loads the default XML Parser using the following behavior: * - First if present loads the parsers specified by the system property {@link UPnP#XML_CLASS_PROPERTTY}<br> * - Second by a fall-back technique, it tries to load the XMLParser from one<br> * of the following classes: {@link JaxpParser}, {@link kXML2Parser}, {@link XercesParser} * * @return {@link Parser} which has been loaded successuflly or null otherwise * * @since 1.8.0 */ private static Parser loadDefaultXMLParser() { Parser parser = null; String[] parserClass = new String[]{ System.getProperty(XML_CLASS_PROPERTTY), //"org.cybergarage.xml.parser.XmlPullParser", "org.cybergarage.xml.parser.JaxpParser" //"org.cybergarage.xml.parser.kXML2Parser", //"org.cybergarage.xml.parser.XercesParser" }; for (int i = 0; i < parserClass.length; i++) { if(parserClass[i]==null) continue; try { parser = (Parser) Class.forName(parserClass[i]).getDeclaredConstructor().newInstance(); return parser; } catch (Throwable e) { Debug.warning("Unable to load "+parserClass[i]+" as XMLParser due to "+e); } } return null; } //////////////////////////////////////////////// // TTL //////////////////////////////////////////////// public final static int DEFAULT_TTL = 4; private static int timeToLive = DEFAULT_TTL; public final static void setTimeToLive(int value) { timeToLive = value; } public final static int getTimeToLive() { return timeToLive; } //////////////////////////////////////////////// // Initialize //////////////////////////////////////////////// static { //////////////////////////// // Interface Option //////////////////////////// //setXMLParser(new kXML2Parser()); //////////////////////////// // TimeToLive //////////////////////////// setTimeToLive(DEFAULT_TTL); //////////////////////////// // Debug Option //////////////////////////// //Debug.on(); } public final static void initialize() { // Dummy function to call UPnP.static } }