org.cybergarage.upnp.Device Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of upnp-stack-jdk13 Show documentation
Show all versions of upnp-stack-jdk13 Show documentation
A pure Java Open Source implementation of the UPnP stack backported for JDK13
The newest version!
/****************************************************************** * * CyberLink for Java * * Copyright (C) Satoshi Konno 2002-2004 * * File: Device.java * * Revision: * * 11/28/02 * - first revision. * 02/26/03 * - URLBase is updated automatically. * - Description of a root device is returned from the XML node tree. * 05/13/03 * - URLBase is updated when the request is received. * - Changed to create socket threads each local interfaces. * (HTTP, SSDPSearch) * 06/17/03 * - Added notify all state variables when a new subscription is received. * 06/18/03 * - Fixed a announce bug when the bind address is null on J2SE v 1.4.1_02 and Redhat 9. * 09/02/03 * - Giordano Sassaroli
to get the default beahvior */ public void setSSDPBindAddress(InetAddress[] inets){ this.getDeviceData().setSSDPBindAddress(inets); } /** * * @return inets The IP that will be used for binding the SSDP service. * null means the default setted by the class UPnP */ public InetAddress[] getSSDPBindAddress(){ return this.getDeviceData().getSSDPBindAddress(); } /** * * @param ip The IPv4 address used for Multicast comunication */ public void setMulticastIPv4Address(String ip){ this.getDeviceData().setMulticastIPv4Address(ip); } /** * * @return The IPv4 address used for Multicast comunication */ public String getMulticastIPv4Address(){ return this.getDeviceData().getMulticastIPv4Address(); } private SSDPSearchSocketList getSSDPSearchSocketList() { return getDeviceData().getSSDPSearchSocketList(); } private void setAdvertiser(Advertiser adv) { getDeviceData().setAdvertiser(adv); } private Advertiser getAdvertiser() { return getDeviceData().getAdvertiser(); } public boolean start() { stop(true); //////////////////////////////////////// // HTTP Server //////////////////////////////////////// int retryCnt = 0; int bindPort = getHTTPPort(); HTTPServerList httpServerList = getHTTPServerList(); while (httpServerList.open(bindPort) == false) { retryCnt++; if (UPnP.SERVER_RETRY_COUNT < retryCnt) return false; setHTTPPort(bindPort + 1); bindPort = getHTTPPort(); } httpServerList.addRequestListener(this); httpServerList.start(); //////////////////////////////////////// // SSDP Seach Socket //////////////////////////////////////// SSDPSearchSocketList ssdpSearchSockList = getSSDPSearchSocketList(); if (ssdpSearchSockList.open() == false) return false; ssdpSearchSockList.addSearchListener(this); ssdpSearchSockList.start(); //////////////////////////////////////// // Announce //////////////////////////////////////// announce(); //////////////////////////////////////// // Advertiser //////////////////////////////////////// Advertiser adv = new Advertiser(this); setAdvertiser(adv); adv.start("Cyber.device.advertiser["+getFriendlyName()+"]"); return true; } private boolean stop(boolean doByeBye) { if (doByeBye == true) byebye(); HTTPServerList httpServerList = getHTTPServerList(); httpServerList.stop(); httpServerList.close(); httpServerList.clear(); SSDPSearchSocketList ssdpSearchSockList = getSSDPSearchSocketList(); ssdpSearchSockList.stop(); ssdpSearchSockList.close(); ssdpSearchSockList.clear(); Advertiser adv = getAdvertiser(); if (adv != null) { adv.stop(); setAdvertiser(null); } return true; } public boolean stop() { return stop(true); } //////////////////////////////////////////////// // Interface Address //////////////////////////////////////////////// public String getInterfaceAddress() { SSDPPacket ssdpPacket = getSSDPPacket(); if (ssdpPacket == null) return ""; return ssdpPacket.getLocalAddress(); } //////////////////////////////////////////////// // Acion/QueryListener //////////////////////////////////////////////// public void setActionListener(ActionListener listener) { ServiceList serviceList = getServiceList(); int nServices = serviceList.size(); for (int n=0; n* - Problem : bad request response sent even with successful subscriptions * - Error : a return statement is missing in the httpRequestRecieved method * 10/21/03 * - Updated a udn field by a original uuid. * 10/22/03 * - Added setActionListener(). * - Added setQueryListener(). * 12/12/03 * - Added a static() to initialize UPnP class. * 12/25/03 * - Added advertiser functions. * 01/05/04 * - Added isExpired(). * 03/23/04 * - Oliver Newell * - Changed to update the UDN only when the field is null. * 04/21/04 * - Added isDeviceType(). * 06/18/04 * - Added setNMPRMode() and isNMPRMode(). * - Changed getDescriptionData() to update only when the NMPR mode is false. * 06/21/04 * - Changed start() to send a bye-bye before the announce. * - Changed annouce(), byebye() and deviceSearchReceived() to send the SSDP * messsage four times when the NMPR and the Wireless mode are true. * 07/02/04 * - Fixed announce() and byebye() to send the upnp::rootdevice message despite embedded devices. * - Fixed getRootNode() to return the root node when the device is embedded. * 07/24/04 * - Thanks for Stefano Lenzi * - Added getParentDevice(). * 10/20/04 * - Brent Hills * - Changed postSearchResponse() to add MYNAME header. * 11/19/04 * - Theo Beisch * - Added getStateVariable(String serviceType, String name). * 03/22/05 * - Changed httpPostRequestRecieved() to return the bad request when the post request isn't the soap action. * 03/23/05 * - Added loadDescription(String) to load the description from memory. * 03/30/05 * - Added getDeviceByDescriptionURI(). * - Added getServiceBySCPDURL(). * 03/31/05 * - Changed httpGetRequestRecieved() to return the description stream using * Device::getDescriptionData() and Service::getSCPDData() at first. * 04/25/05 * - Thanks for Mikael Hakman * Changed announce() and byebye() to close the socket after the posting. * 04/25/05 * - Thanks for Mikael Hakman * Changed deviceSearchResponse() answer with USN:UDN:: when request ST is device type. * 04/25/05 * - Thanks for Mikael Hakman * - Changed getDescriptionData() to add a XML declaration at first line. * 04/25/05 * - Thanks for Mikael Hakman * - Added a new setActionListener() and serQueryListner() to include the sub devices. * 07/24/05 * - Thanks for Stefano Lenzi * - Fixed a bug of getParentDevice() to return the parent device normally. * 02/21/06 * - Changed httpRequestRecieved() not to ignore HEAD requests. * 04/12/06 * - Added setUserData() and getUserData() to set a user original data object. * * 02/01/08 * - added thread name for device advertiser in setLeaseTime (francesco) * - TODO check if restart is compatibile with Advertiser thread suspended on sleep * ******************************************************************/ package org.cybergarage.upnp; import java.io.File; import java.io.InputStream; import java.net.InetAddress; import java.net.URL; import java.util.Calendar; import org.cybergarage.http.HTTPRequest; import org.cybergarage.http.HTTPResponse; import org.cybergarage.http.HTTPServerList; import org.cybergarage.http.HTTPStatus; import org.cybergarage.net.HostInterface; import org.cybergarage.soap.SOAPResponse; import org.cybergarage.upnp.control.ActionListener; import org.cybergarage.upnp.control.ActionRequest; import org.cybergarage.upnp.control.ActionResponse; import org.cybergarage.upnp.control.ControlRequest; import org.cybergarage.upnp.control.ControlResponse; import org.cybergarage.upnp.control.QueryListener; import org.cybergarage.upnp.control.QueryRequest; import org.cybergarage.upnp.device.Advertiser; import org.cybergarage.upnp.device.Description; import org.cybergarage.upnp.device.InvalidDescriptionException; import org.cybergarage.upnp.device.NTS; import org.cybergarage.upnp.device.ST; import org.cybergarage.upnp.device.SearchListener; import org.cybergarage.upnp.device.USN; import org.cybergarage.upnp.event.Subscriber; import org.cybergarage.upnp.event.Subscription; import org.cybergarage.upnp.event.SubscriptionRequest; import org.cybergarage.upnp.event.SubscriptionResponse; import org.cybergarage.upnp.ssdp.SSDPNotifyRequest; import org.cybergarage.upnp.ssdp.SSDPNotifySocket; import org.cybergarage.upnp.ssdp.SSDPPacket; import org.cybergarage.upnp.ssdp.SSDPSearchResponse; import org.cybergarage.upnp.ssdp.SSDPSearchResponseSocket; import org.cybergarage.upnp.ssdp.SSDPSearchSocketList; import org.cybergarage.upnp.xml.DeviceData; import org.cybergarage.util.Debug; import org.cybergarage.util.FileUtil; import org.cybergarage.util.Mutex; import org.cybergarage.util.TimerUtil; import org.cybergarage.xml.Node; import org.cybergarage.xml.Parser; import org.cybergarage.xml.ParserException; import org.cybergarage.xml.XML; public class Device implements org.cybergarage.http.HTTPRequestListener, SearchListener { //////////////////////////////////////////////// // Constants //////////////////////////////////////////////// public final static String ELEM_NAME = "device"; public final static String UPNP_ROOTDEVICE = "upnp:rootdevice"; public final static int DEFAULT_STARTUP_WAIT_TIME = 1000; public final static int DEFAULT_DISCOVERY_WAIT_TIME = 300; public final static int DEFAULT_LEASE_TIME = 30 * 60; public final static int HTTP_DEFAULT_PORT = 4004; public final static String DEFAULT_DESCRIPTION_URI = "/description.xml"; //////////////////////////////////////////////// // Member //////////////////////////////////////////////// private Node rootNode; private Node deviceNode; public Node getRootNode() { if (rootNode != null) return rootNode; if (deviceNode == null) return null; return deviceNode.getRootNode(); } public Node getDeviceNode() { return deviceNode; } public void setRootNode(Node node) { rootNode = node; } public void setDeviceNode(Node node) { deviceNode = node; } //////////////////////////////////////////////// // Initialize //////////////////////////////////////////////// static { UPnP.initialize(); } //////////////////////////////////////////////// // Constructor //////////////////////////////////////////////// public Device(Node root, Node device) { rootNode = root; deviceNode = device; setUUID(UPnP.createUUID()); setWirelessMode(false); } public Device() { this(null, null); } public Device(Node device) { this(null, device); } public Device(File descriptionFile) throws InvalidDescriptionException { this(null, null); loadDescription(descriptionFile); } /** * @since 1.8.0 */ public Device(InputStream input) throws InvalidDescriptionException { this(null, null); loadDescription(input); } public Device(String descriptionFileName) throws InvalidDescriptionException { this(new File(descriptionFileName)); } //////////////////////////////////////////////// // Mutex //////////////////////////////////////////////// private Mutex mutex = new Mutex(); public void lock() { mutex.lock(); } public void unlock() { mutex.unlock(); } //////////////////////////////////////////////// // NMPR //////////////////////////////////////////////// public void setNMPRMode(boolean flag) { Node devNode = getDeviceNode(); if (devNode == null) return; if (flag == true) { devNode.setNode(UPnP.INMPR03, UPnP.INMPR03_VERSION); devNode.removeNode(Device.URLBASE_NAME); } else { devNode.removeNode(UPnP.INMPR03); } } public boolean isNMPRMode() { Node devNode = getDeviceNode(); if (devNode == null) return false; return (devNode.getNode(UPnP.INMPR03) != null) ? true : false; } //////////////////////////////////////////////// // Wireless //////////////////////////////////////////////// private boolean wirelessMode; public void setWirelessMode(boolean flag) { wirelessMode = flag; } public boolean isWirelessMode() { return wirelessMode; } public int getSSDPAnnounceCount() { if (isNMPRMode() == true && isWirelessMode() == true) return UPnP.INMPR03_DISCOVERY_OVER_WIRELESS_COUNT; return 1; } //////////////////////////////////////////////// // Device UUID //////////////////////////////////////////////// private String devUUID; private void setUUID(String uuid) { devUUID = uuid; } private String getUUID() { return devUUID; } private void updateUDN() { setUDN("uuid:" + getUUID()); } //////////////////////////////////////////////// // Root Device //////////////////////////////////////////////// public Device getRootDevice() { Node rootNode = getRootNode(); if (rootNode == null) return null; Node devNode = rootNode.getNode(Device.ELEM_NAME); if (devNode == null) return null; return new Device(rootNode, devNode); } //////////////////////////////////////////////// // Parent Device //////////////////////////////////////////////// // Thanks for Stefano Lenzi (07/24/04) /** * * @return A Device that contain this object.
* Returnnull
if this is a root device. * @author Stefano "Kismet" Lenzi */ public Device getParentDevice() { if(isRootDevice()) return null; Node devNode = getDeviceNode(); Node aux = null; //aux = devNode.getParentNode().getParentNode(); return new Device(aux); } /** * Add a Service to device without checking for duplicate or syntax error * * @param s Add Service s to the Device */ public void addService(Service s) { Node serviceListNode = getDeviceNode().getNode(ServiceList.ELEM_NAME); if (serviceListNode == null) { serviceListNode = new Node(ServiceList.ELEM_NAME); getDeviceNode().addNode(serviceListNode); } serviceListNode.addNode(s.getServiceNode()); } /** * Add a Device to device without checking for duplicate or syntax error. * This method set or reset the root node of the Device and itself
*
* Note: This method should be used to create a dynamic
* Device withtout writing any XML that describe the device
. * * @param d Add Device d to the Device * * @author Stefano "Kismet" Lenzi - [email protected] - 2005 * */ public void addDevice(Device d) { Node deviceListNode = getDeviceNode().getNode(DeviceList.ELEM_NAME); if (deviceListNode == null) { //deviceListNode = new Node(ServiceList.ELEM_NAME); twa wrong ELEM_NAME; deviceListNode = new Node(DeviceList.ELEM_NAME); getDeviceNode().addNode(deviceListNode); } deviceListNode.addNode(d.getDeviceNode()); d.setRootNode(null); if(getRootNode()==null){ Node root = new Node(RootDescription.ROOT_ELEMENT); root.setNameSpace("",RootDescription.ROOT_ELEMENT_NAMESPACE); Node spec = new Node(RootDescription.SPECVERSION_ELEMENT); Node maj =new Node(RootDescription.MAJOR_ELEMENT); maj.setValue("1"); Node min =new Node(RootDescription.MINOR_ELEMENT); min.setValue("0"); spec.addNode(maj); spec.addNode(min); root.addNode(spec); setRootNode(root); } } //////////////////////////////////////////////// // UserData //////////////////////////////////////////////// private DeviceData getDeviceData() { Node node = getDeviceNode(); DeviceData userData = (DeviceData)node.getUserData(); if (userData == null) { userData = new DeviceData(); node.setUserData(userData); userData.setNode(node); } return userData; } //////////////////////////////////////////////// // Description //////////////////////////////////////////////// private void setDescriptionFile(File file) { getDeviceData().setDescriptionFile(file); } public File getDescriptionFile() { return getDeviceData().getDescriptionFile(); } private void setDescriptionURI(String uri) { getDeviceData().setDescriptionURI(uri); } private String getDescriptionURI() { return getDeviceData().getDescriptionURI(); } private boolean isDescriptionURI(String uri) { String descriptionURI = getDescriptionURI(); if (uri == null || descriptionURI == null) return false; return descriptionURI.equals(uri); } public String getDescriptionFilePath() { File descriptionFile = getDescriptionFile(); if (descriptionFile == null) return ""; return descriptionFile.getAbsoluteFile().getParent(); } /** * @since 1.8.0 */ public boolean loadDescription(InputStream input) throws InvalidDescriptionException { try { Parser parser = UPnP.getXMLParser(); rootNode = parser.parse(input); if (rootNode == null) throw new InvalidDescriptionException(Description.NOROOT_EXCEPTION); deviceNode = rootNode.getNode(Device.ELEM_NAME); if (deviceNode == null) throw new InvalidDescriptionException(Description.NOROOTDEVICE_EXCEPTION); } catch (ParserException e) { throw new InvalidDescriptionException(e); } if (initializeLoadedDescription() == false) return false; setDescriptionFile(null); return true; } public boolean loadDescription(String descString) throws InvalidDescriptionException { try { Parser parser = UPnP.getXMLParser(); rootNode = parser.parse(descString); if (rootNode == null) throw new InvalidDescriptionException(Description.NOROOT_EXCEPTION); deviceNode = rootNode.getNode(Device.ELEM_NAME); if (deviceNode == null) throw new InvalidDescriptionException(Description.NOROOTDEVICE_EXCEPTION); } catch (ParserException e) { throw new InvalidDescriptionException(e); } if (initializeLoadedDescription() == false) return false; setDescriptionFile(null); return true; } public boolean loadDescription(File file) throws InvalidDescriptionException { try { Parser parser = UPnP.getXMLParser(); rootNode = parser.parse(file); if (rootNode == null) throw new InvalidDescriptionException(Description.NOROOT_EXCEPTION, file); deviceNode = rootNode.getNode(Device.ELEM_NAME); if (deviceNode == null) throw new InvalidDescriptionException(Description.NOROOTDEVICE_EXCEPTION, file); } catch (ParserException e) { throw new InvalidDescriptionException(e); } if (initializeLoadedDescription() == false) return false; setDescriptionFile(file); return true; } private boolean initializeLoadedDescription() { setDescriptionURI(DEFAULT_DESCRIPTION_URI); setLeaseTime(DEFAULT_LEASE_TIME); setHTTPPort(HTTP_DEFAULT_PORT); // Thanks for Oliver Newell (03/23/04) if (hasUDN() == false) updateUDN(); return true; } //////////////////////////////////////////////// // isDeviceNode //////////////////////////////////////////////// public static boolean isDeviceNode(Node node) { return Device.ELEM_NAME.equals(node.getName()); } //////////////////////////////////////////////// // Root Device //////////////////////////////////////////////// public boolean isRootDevice(){ return getRootNode().getNode("device").getNodeValue(UDN).equals(getUDN()); } //////////////////////////////////////////////// // Root Device //////////////////////////////////////////////// public void setSSDPPacket(SSDPPacket packet) { getDeviceData().setSSDPPacket(packet); } public SSDPPacket getSSDPPacket() { if (isRootDevice() == false) return null; return getDeviceData().getSSDPPacket(); } //////////////////////////////////////////////// // Location //////////////////////////////////////////////// public void setLocation(String value) { getDeviceData().setLocation(value); } public String getLocation() { SSDPPacket packet = getSSDPPacket(); if (packet != null) return packet.getLocation(); return getDeviceData().getLocation(); } //////////////////////////////////////////////// // LeaseTime //////////////////////////////////////////////// public void setLeaseTime(int value) { getDeviceData().setLeaseTime(value); Advertiser adv = getAdvertiser(); if (adv != null) { announce(); adv.restart("Cyber.device.advertiser["+getFriendlyName()+"]"); } } public int getLeaseTime() { SSDPPacket packet = getSSDPPacket(); if (packet != null) return packet.getLeaseTime(); return getDeviceData().getLeaseTime(); } //////////////////////////////////////////////// // TimeStamp //////////////////////////////////////////////// public long getTimeStamp() { SSDPPacket packet = getSSDPPacket(); if (packet != null) return packet.getTimeStamp(); return 0; } public long getElapsedTime() { return (System.currentTimeMillis() - getTimeStamp()) / 1000; } public boolean isExpired() { long elipsedTime = getElapsedTime(); long leaseTime = getLeaseTime() + UPnP.DEFAULT_EXPIRED_DEVICE_EXTRA_TIME; if (leaseTime < elipsedTime) return true; return false; } //////////////////////////////////////////////// // URL Base //////////////////////////////////////////////// private final static String URLBASE_NAME = "URLBase"; private void setURLBase(String value) { if (isRootDevice() == true) { Node node = getRootNode().getNode(URLBASE_NAME); if (node != null) { node.setValue(value); return; } node = new Node(URLBASE_NAME); node.setValue(value); int index = 1; if (getRootNode().hasNodes() == false) index = 1; getRootNode().insertNode(node, index); } } private void updateURLBase(String host) { String urlBase = HostInterface.getHostURL(host, getHTTPPort(), ""); setURLBase(urlBase); } public String getURLBase() { if (isRootDevice() == true) return getRootNode().getNodeValue(URLBASE_NAME); return ""; } //////////////////////////////////////////////// // deviceType //////////////////////////////////////////////// private final static String DEVICE_TYPE = "deviceType"; public void setDeviceType(String value) { getDeviceNode().setNode(DEVICE_TYPE, value); } public String getDeviceType() { return getDeviceNode().getNodeValue(DEVICE_TYPE); } public boolean isDeviceType(String value) { if (value == null) return false; return value.equals(getDeviceType()); } //////////////////////////////////////////////// // friendlyName //////////////////////////////////////////////// private final static String FRIENDLY_NAME = "friendlyName"; public void setFriendlyName(String value) { getDeviceNode().setNode(FRIENDLY_NAME, value); } public String getFriendlyName() { return getDeviceNode().getNodeValue(FRIENDLY_NAME); } //////////////////////////////////////////////// // manufacture //////////////////////////////////////////////// private final static String MANUFACTURE = "manufacturer"; public void setManufacture(String value) { getDeviceNode().setNode(MANUFACTURE, value); } public String getManufacture() { return getDeviceNode().getNodeValue(MANUFACTURE); } //////////////////////////////////////////////// // manufactureURL //////////////////////////////////////////////// private final static String MANUFACTURE_URL = "manufacturerURL"; public void setManufactureURL(String value) { getDeviceNode().setNode(MANUFACTURE_URL, value); } public String getManufactureURL() { return getDeviceNode().getNodeValue(MANUFACTURE_URL); } //////////////////////////////////////////////// // modelDescription //////////////////////////////////////////////// private final static String MODEL_DESCRIPTION = "modelDescription"; public void setModelDescription(String value) { getDeviceNode().setNode(MODEL_DESCRIPTION, value); } public String getModelDescription() { return getDeviceNode().getNodeValue(MODEL_DESCRIPTION); } //////////////////////////////////////////////// // modelName //////////////////////////////////////////////// private final static String MODEL_NAME = "modelName"; public void setModelName(String value) { getDeviceNode().setNode(MODEL_NAME, value); } public String getModelName() { return getDeviceNode().getNodeValue(MODEL_NAME); } //////////////////////////////////////////////// // modelNumber //////////////////////////////////////////////// private final static String MODEL_NUMBER = "modelNumber"; public void setModelNumber(String value) { getDeviceNode().setNode(MODEL_NUMBER, value); } public String getModelNumber() { return getDeviceNode().getNodeValue(MODEL_NUMBER); } //////////////////////////////////////////////// // modelURL //////////////////////////////////////////////// private final static String MODEL_URL = "modelURL"; public void setModelURL(String value) { getDeviceNode().setNode(MODEL_URL, value); } public String getModelURL() { return getDeviceNode().getNodeValue(MODEL_URL); } //////////////////////////////////////////////// // serialNumber //////////////////////////////////////////////// private final static String SERIAL_NUMBER = "serialNumber"; public void setSerialNumber(String value) { getDeviceNode().setNode(SERIAL_NUMBER, value); } public String getSerialNumber() { return getDeviceNode().getNodeValue(SERIAL_NUMBER); } //////////////////////////////////////////////// // UDN //////////////////////////////////////////////// private final static String UDN = "UDN"; public void setUDN(String value) { getDeviceNode().setNode(UDN, value); } public String getUDN() { return getDeviceNode().getNodeValue(UDN); } public boolean hasUDN() { String udn = getUDN(); if (udn == null || udn.length() <= 0) return false; return true; } //////////////////////////////////////////////// // UPC //////////////////////////////////////////////// private final static String UPC = "UPC"; public void setUPC(String value) { getDeviceNode().setNode(UPC, value); } public String getUPC() { return getDeviceNode().getNodeValue(UPC); } //////////////////////////////////////////////// // presentationURL //////////////////////////////////////////////// private final static String presentationURL = "presentationURL"; public void setPresentationURL(String value) { getDeviceNode().setNode(presentationURL, value); } public String getPresentationURL() { return getDeviceNode().getNodeValue(presentationURL); } //////////////////////////////////////////////// // deviceList //////////////////////////////////////////////// public DeviceList getDeviceList() { DeviceList devList = new DeviceList(); Node devListNode = getDeviceNode().getNode(DeviceList.ELEM_NAME); if (devListNode == null) return devList; int nNode = devListNode.getNNodes(); for (int n=0; nnull
© 2015 - 2024 Weber Informatics LLC | Privacy Policy