Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.cybergarage.upnp.Device Maven / Gradle / Ivy
/******************************************************************
*
* 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
* - 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.
* 03/29/08
* - Added isRunning() to know whether the device is running.
*
******************************************************************/
package org.cybergarage.upnp;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URL;
import java.util.Calendar;
import java.util.HashMap;
import org.cybergarage.http.HTTP;
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.device.PresentationListener;
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";
public final static String DEFAULT_PRESENTATION_URI = "/presentation";
// //////////////////////////////////////////////
// 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();
}
// //////////////////////////////////////////////
// getAbsoluteURL
// //////////////////////////////////////////////
public String getAbsoluteURL(String urlString, String baseURLStr,
String locationURLStr) {
//Debug.warning("GAURL \"" + urlString + "\" \"" + baseURLStr + "\" \"" + locationURLStr + '"');
if ((urlString == null) || (urlString.length() <= 0))
return "";
try {
URL url = new URL(urlString);
//Debug.warning("Return 0: " + url);
return url.toString();
} catch (Exception e) {
}
if ((baseURLStr == null) || (baseURLStr.length() <= 0)) {
if ((locationURLStr != null) && (0 < locationURLStr.length())) {
if (!urlString.startsWith("/")) {
String absUrl;
// Relative to location, so back up to last slash
if (!locationURLStr.endsWith("/")) {
absUrl = locationURLStr.substring(0, locationURLStr.lastIndexOf('/') + 1) + urlString;
} else {
absUrl = locationURLStr + urlString;
}
try {
URL url = new URL(absUrl);
//Debug.warning("Return 1: " + url);
return url.toString();
} catch (Exception e) {
}
}
String absUrl = HTTP.getAbsoluteURL(locationURLStr, urlString);
try {
URL url = new URL(absUrl);
//Debug.warning("Return 3: " + url);
return url.toString();
} catch (Exception e) {
}
// Thanks for Steven Yen (2003/09/03)
Device rootDev = getRootDevice();
if (rootDev != null) {
String location = rootDev.getLocation();
String locationHost = HTTP.getHost(location);
int locationPort = HTTP.getPort(location);
baseURLStr = HTTP.getRequestHostURL(locationHost,
locationPort);
}
}
}
if ((baseURLStr != null) && (0 < baseURLStr.length())) {
if (!urlString.startsWith("/")) {
String absUrl;
// Relative to base, so back up to last slash
if (!baseURLStr.endsWith("/")) {
absUrl = baseURLStr.substring(0, baseURLStr.lastIndexOf('/') + 1) + urlString;
} else {
absUrl = baseURLStr + urlString;
}
try {
URL url = new URL(absUrl);
//Debug.warning("Return 4: " + url);
return url.toString();
} catch (Exception e) {
}
}
String absUrl = HTTP.getAbsoluteURL(baseURLStr, urlString);
try {
URL url = new URL(absUrl);
//Debug.warning("Return 6: " + url);
return url.toString();
} catch (Exception e) {
}
}
//Debug.warning("Return 7: " + urlString);
return urlString;
}
public String getAbsoluteURL(String urlString) {
String baseURLStr = null;
String locationURLStr = null;
Device rootDev = getRootDevice();
if (rootDev != null) {
baseURLStr = rootDev.getURLBase();
locationURLStr = rootDev.getLocation();
}
return getAbsoluteURL(urlString, baseURLStr, locationURLStr);
}
// //////////////////////////////////////////////
// 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) {
this.devUUID = uuid;
}
public String getUUID() {
return this.devUUID;
}
private void updateUDN() {
setUDN("uuid:" + getUUID());
}
// //////////////////////////////////////////////
// BootId
// //////////////////////////////////////////////
private int bootId;
private void updateBootId() {
this.bootId = UPnP.createBootId();
}
public int getBootId() {
return this.bootId;
}
// //////////////////////////////////////////////
// configID
// //////////////////////////////////////////////
private final static String CONFIG_ID = "configId";
private void updateConfigId(Device dev) {
int configId = 0;
DeviceList cdevList = dev.getDeviceList();
int cdevCnt = cdevList.size();
for (int n = 0; n < cdevCnt; n++) {
Device cdev = cdevList.getDevice(n);
updateConfigId(cdev);
configId += cdev.getConfigId();
configId &= UPnP.CONFIGID_UPNP_ORG_MAX;
}
ServiceList serviceList = dev.getServiceList();
int serviceCnt = serviceList.size();
for (int n = 0; n < serviceCnt; n++) {
Service service = serviceList.getService(n);
service.updateConfigId();
configId += service.getConfigId();
configId &= UPnP.CONFIGID_UPNP_ORG_MAX;
}
Node devNode = getDeviceNode();
if (devNode == null)
return;
String devDescXml = devNode.toString();
configId += UPnP.caluculateConfigId(devDescXml);
configId &= UPnP.CONFIGID_UPNP_ORG_MAX;
devNode.setAttribute(CONFIG_ID, configId);
}
public void updateConfigId() {
updateConfigId(this);
}
public int getConfigId() {
Node devNode = getDeviceNode();
if (devNode == null)
return 0;
return devNode.getAttributeIntegerValue(CONFIG_ID);
}
// //////////////////////////////////////////////
// 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.
* Return null
if this is a root device.
*/
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
*/
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() {
return getSSDPPacket(false);
}
/**
* I2P for multiple location support
*
* @since 0.9.50
*/
public SSDPPacket getSSDPPacket(boolean preferIPv6) {
if (isRootDevice() == false)
return null;
return getDeviceData().getSSDPPacket(preferIPv6);
}
// //////////////////////////////////////////////
// Location
// //////////////////////////////////////////////
public void setLocation(String value) {
getDeviceData().setLocation(value);
}
public String getLocation() {
return getLocation(false);
}
/**
* I2P for multiple location support
*
* @since 0.9.50
*/
public String getLocation(boolean preferIPv6) {
SSDPPacket packet = getSSDPPacket(preferIPv6);
if (packet != null)
return packet.getLocation();
return getDeviceData().getLocation(preferIPv6);
}
// //////////////////////////////////////////////
// LeaseTime
// //////////////////////////////////////////////
public void setLeaseTime(int value) {
getDeviceData().setLeaseTime(value);
Advertiser adv = getAdvertiser();
if (adv != null) {
announce();
adv.restart();
}
}
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";
private PresentationListener presentationListener;
public void setPresentationURL(String value) {
getDeviceNode().setNode(presentationURL, value);
}
public String getPresentationURL() {
return getDeviceNode().getNodeValue(presentationURL);
}
public boolean removePresentationURL() {
return getDeviceNode().removeNode(presentationURL);
}
private boolean isPresentationRequest(HTTPRequest httpReq) {
if (!httpReq.isGetRequest())
return false;
String urlPath = httpReq.getURI();
if (urlPath == null)
return false;
String presentationURL = getPresentationURL();
if (presentationURL == null)
return false;
return urlPath.startsWith(presentationURL);
}
public void setPresentationListener(PresentationListener listener) {
this.presentationListener = listener;
if (listener != null) {
setPresentationURL(DEFAULT_PRESENTATION_URI);
} else {
removePresentationURL();
}
}
public boolean hasPresentationListener() {
return (this.presentationListener != null) ? true : false;
}
public PresentationListener getPresentationListener() {
return this.presentationListener;
}
// //////////////////////////////////////////////
// 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; n < nNode; n++) {
Node node = devListNode.getNode(n);
if (Device.isDeviceNode(node) == false)
continue;
Device dev = new Device(node);
devList.add(dev);
}
return devList;
}
public boolean isDevice(String name) {
if (name == null)
return false;
if (name.endsWith(getUDN()) == true)
return true;
if (name.equals(getFriendlyName()) == true)
return true;
if (name.endsWith(getDeviceType()) == true)
return true;
return false;
}
public Device getDevice(String name) {
DeviceList devList = getDeviceList();
int devCnt = devList.size();
for (int n = 0; n < devCnt; n++) {
Device dev = devList.getDevice(n);
if (dev.isDevice(name) == true)
return dev;
Device cdev = dev.getDevice(name);
if (cdev != null)
return cdev;
}
return null;
}
public Device getDeviceByDescriptionURI(String uri) {
DeviceList devList = getDeviceList();
int devCnt = devList.size();
for (int n = 0; n < devCnt; n++) {
Device dev = devList.getDevice(n);
if (dev.isDescriptionURI(uri) == true)
return dev;
Device cdev = dev.getDeviceByDescriptionURI(uri);
if (cdev != null)
return cdev;
}
return null;
}
// //////////////////////////////////////////////
// serviceList
// //////////////////////////////////////////////
public ServiceList getServiceList() {
ServiceList serviceList = new ServiceList();
Node serviceListNode = getDeviceNode().getNode(ServiceList.ELEM_NAME);
if (serviceListNode == null)
return serviceList;
int nNode = serviceListNode.getNNodes();
for (int n = 0; n < nNode; n++) {
Node node = serviceListNode.getNode(n);
if (Service.isServiceNode(node) == false)
continue;
Service service = new Service(node);
serviceList.add(service);
}
return serviceList;
}
public Service getService(String name) {
ServiceList serviceList = getServiceList();
int serviceCnt = serviceList.size();
for (int n = 0; n < serviceCnt; n++) {
Service service = serviceList.getService(n);
if (service.isService(name) == true)
return service;
}
DeviceList devList = getDeviceList();
int devCnt = devList.size();
for (int n = 0; n < devCnt; n++) {
Device dev = devList.getDevice(n);
Service service = dev.getService(name);
if (service != null)
return service;
}
return null;
}
public Service getServiceBySCPDURL(String searchUrl) {
ServiceList serviceList = getServiceList();
int serviceCnt = serviceList.size();
for (int n = 0; n < serviceCnt; n++) {
Service service = serviceList.getService(n);
if (service.isSCPDURL(searchUrl) == true)
return service;
}
DeviceList devList = getDeviceList();
int devCnt = devList.size();
for (int n = 0; n < devCnt; n++) {
Device dev = devList.getDevice(n);
Service service = dev.getServiceBySCPDURL(searchUrl);
if (service != null)
return service;
}
return null;
}
public Service getServiceByControlURL(String searchUrl) {
ServiceList serviceList = getServiceList();
int serviceCnt = serviceList.size();
for (int n = 0; n < serviceCnt; n++) {
Service service = serviceList.getService(n);
if (service.isControlURL(searchUrl) == true)
return service;
}
DeviceList devList = getDeviceList();
int devCnt = devList.size();
for (int n = 0; n < devCnt; n++) {
Device dev = devList.getDevice(n);
Service service = dev.getServiceByControlURL(searchUrl);
if (service != null)
return service;
}
return null;
}
public Service getServiceByEventSubURL(String searchUrl) {
ServiceList serviceList = getServiceList();
int serviceCnt = serviceList.size();
for (int n = 0; n < serviceCnt; n++) {
Service service = serviceList.getService(n);
if (service.isEventSubURL(searchUrl) == true)
return service;
}
DeviceList devList = getDeviceList();
int devCnt = devList.size();
for (int n = 0; n < devCnt; n++) {
Device dev = devList.getDevice(n);
Service service = dev.getServiceByEventSubURL(searchUrl);
if (service != null)
return service;
}
return null;
}
public Service getSubscriberService(String uuid) {
ServiceList serviceList = getServiceList();
int serviceCnt = serviceList.size();
for (int n = 0; n < serviceCnt; n++) {
Service service = serviceList.getService(n);
String sid = service.getSID();
if (uuid.equals(sid) == true)
return service;
}
DeviceList devList = getDeviceList();
int devCnt = devList.size();
for (int n = 0; n < devCnt; n++) {
Device dev = devList.getDevice(n);
Service service = dev.getSubscriberService(uuid);
if (service != null)
return service;
}
return null;
}
// //////////////////////////////////////////////
// StateVariable
// //////////////////////////////////////////////
public StateVariable getStateVariable(String serviceType, String name) {
if (serviceType == null && name == null)
return null;
ServiceList serviceList = getServiceList();
int serviceCnt = serviceList.size();
for (int n = 0; n < serviceCnt; n++) {
Service service = serviceList.getService(n);
// Thanks for Theo Beisch (11/09/04)
if (serviceType != null) {
if (service.getServiceType().equals(serviceType) == false)
continue;
}
StateVariable stateVar = service.getStateVariable(name);
if (stateVar != null)
return stateVar;
}
DeviceList devList = getDeviceList();
int devCnt = devList.size();
for (int n = 0; n < devCnt; n++) {
Device dev = devList.getDevice(n);
StateVariable stateVar = dev.getStateVariable(serviceType, name);
if (stateVar != null)
return stateVar;
}
return null;
}
public StateVariable getStateVariable(String name) {
return getStateVariable(null, name);
}
// //////////////////////////////////////////////
// Action
// //////////////////////////////////////////////
public Action getAction(String name) {
ServiceList serviceList = getServiceList();
int serviceCnt = serviceList.size();
for (int n = 0; n < serviceCnt; n++) {
Service service = serviceList.getService(n);
ActionList actionList = service.getActionList();
int actionCnt = actionList.size();
for (int i = 0; i < actionCnt; i++) {
Action action = actionList.getAction(i);
String actionName = action.getName();
if (actionName == null)
continue;
if (actionName.equals(name) == true)
return action;
}
}
DeviceList devList = getDeviceList();
int devCnt = devList.size();
for (int n = 0; n < devCnt; n++) {
Device dev = devList.getDevice(n);
Action action = dev.getAction(name);
if (action != null)
return action;
}
return null;
}
// //////////////////////////////////////////////
// iconList
// //////////////////////////////////////////////
private HashMap iconBytesMap = new HashMap();
public boolean isIconBytesURI(String uri) {
byte iconBytes[] = iconBytesMap.get(uri);
if (iconBytes == null)
return false;
return true;
}
public Icon getIconByURI(String uri) {
IconList iconList = getIconList();
if (iconList.size() <= 0)
return null;
int nIcon = iconList.size();
for (int n = 0; n < nIcon; n++) {
Icon icon = iconList.getIcon(n);
if (icon.isURL(uri))
return icon;
}
return null;
}
public boolean addIcon(Icon icon) {
Node deviceNode = getDeviceNode();
if (deviceNode == null)
return false;
Node iconListNode = deviceNode.getNode(IconList.ELEM_NAME);
if (iconListNode == null) {
iconListNode = new Node(IconList.ELEM_NAME);
deviceNode.addNode(iconListNode);
}
Node iconNode = new Node(Icon.ELEM_NAME);
if (icon.getIconNode() != null) {
iconNode.set(icon.getIconNode());
}
iconListNode.addNode(iconNode);
if (icon.hasURL() && icon.hasBytes()) {
iconBytesMap.put(icon.getURL(), icon.getBytes());
}
return true;
}
public IconList getIconList() {
IconList iconList = new IconList();
Node iconListNode = getDeviceNode().getNode(IconList.ELEM_NAME);
if (iconListNode == null)
return iconList;
int nNode = iconListNode.getNNodes();
for (int n = 0; n < nNode; n++) {
Node node = iconListNode.getNode(n);
if (Icon.isIconNode(node) == false)
continue;
Icon icon = new Icon(node);
if (icon.hasURL()) {
String iconURL = icon.getURL();
byte iconBytes[] = iconBytesMap.get(iconURL);
if (iconBytes != null) {
icon.setBytes(iconBytes);
}
}
iconList.add(icon);
}
return iconList;
}
public Icon getIcon(int n) {
IconList iconList = getIconList();
if (n < 0 && (iconList.size() - 1) < n)
return null;
return iconList.getIcon(n);
}
public Icon getSmallestIcon() {
Icon smallestIcon = null;
IconList iconList = getIconList();
int iconCount = iconList.size();
for (int n = 0; n < iconCount; n++) {
Icon icon = iconList.getIcon(n);
if (null == smallestIcon) {
smallestIcon = icon;
continue;
}
if (icon.getWidth() < smallestIcon.getWidth())
smallestIcon = icon;
}
return smallestIcon;
}
// //////////////////////////////////////////////
// Notify
// //////////////////////////////////////////////
public String getLocationURL(String host) {
return HostInterface.getHostURL(host, getHTTPPort(),
getDescriptionURI());
}
private String getNotifyDeviceNT() {
if (isRootDevice() == false)
return getUDN();
return UPNP_ROOTDEVICE;
}
private String getNotifyDeviceUSN() {
if (isRootDevice() == false)
return getUDN();
return getUDN() + "::" + UPNP_ROOTDEVICE;
}
private String getNotifyDeviceTypeNT() {
return getDeviceType();
}
private String getNotifyDeviceTypeUSN() {
return getUDN() + "::" + getDeviceType();
}
public final static void notifyWait() {
TimerUtil.waitRandom(DEFAULT_DISCOVERY_WAIT_TIME);
}
public void announce(String bindAddr) {
String devLocation = getLocationURL(bindAddr);
SSDPNotifySocket ssdpSock;
// I2P
try {
ssdpSock = new SSDPNotifySocket(bindAddr);
} catch (IOException ioe) {
Debug.warning("Failed announce from " + bindAddr, ioe);
return;
}
SSDPNotifyRequest ssdpReq = new SSDPNotifyRequest();
ssdpReq.setServer(UPnP.getServerName());
ssdpReq.setLeaseTime(getLeaseTime());
ssdpReq.setLocation(devLocation);
ssdpReq.setNTS(NTS.ALIVE);
ssdpReq.setBootId(getBootId());
// uuid:device-UUID(::upnp:rootdevice)*
if (isRootDevice() == true) {
String devNT = getNotifyDeviceNT();
String devUSN = getNotifyDeviceUSN();
ssdpReq.setNT(devNT);
ssdpReq.setUSN(devUSN);
ssdpSock.post(ssdpReq);
String devUDN = getUDN();
ssdpReq.setNT(devUDN);
ssdpReq.setUSN(devUDN);
ssdpSock.post(ssdpReq);
}
// uuid:device-UUID::urn:schemas-upnp-org:device:deviceType:v
String devNT = getNotifyDeviceTypeNT();
String devUSN = getNotifyDeviceTypeUSN();
ssdpReq.setNT(devNT);
ssdpReq.setUSN(devUSN);
ssdpSock.post(ssdpReq);
// Thanks for Mikael Hakman (04/25/05)
ssdpSock.close();
ServiceList serviceList = getServiceList();
int serviceCnt = serviceList.size();
for (int n = 0; n < serviceCnt; n++) {
Service service = serviceList.getService(n);
service.announce(bindAddr);
}
DeviceList childDeviceList = getDeviceList();
int childDeviceCnt = childDeviceList.size();
for (int n = 0; n < childDeviceCnt; n++) {
Device childDevice = childDeviceList.getDevice(n);
childDevice.announce(bindAddr);
}
}
public void announce() {
notifyWait();
InetAddress[] binds = getDeviceData().getHTTPBindAddress();
String[] bindAddresses;
if (binds != null) {
bindAddresses = new String[binds.length];
for (int i = 0; i < binds.length; i++) {
bindAddresses[i] = binds[i].getHostAddress();
}
} else {
int nHostAddrs = HostInterface.getNHostAddresses();
bindAddresses = new String[nHostAddrs];
for (int n = 0; n < nHostAddrs; n++) {
bindAddresses[n] = HostInterface.getHostAddress(n);
}
}
for (int j = 0; j < bindAddresses.length; j++) {
if (bindAddresses[j] == null || bindAddresses[j].length() == 0)
continue;
int ssdpCount = getSSDPAnnounceCount();
for (int i = 0; i < ssdpCount; i++)
announce(bindAddresses[j]);
}
}
public void byebye(String bindAddr) {
SSDPNotifySocket ssdpSock;
// I2P
try {
ssdpSock = new SSDPNotifySocket(bindAddr);
} catch (IOException ioe) {
Debug.warning("Failed byebye from " + bindAddr, ioe);
return;
}
SSDPNotifyRequest ssdpReq = new SSDPNotifyRequest();
ssdpReq.setNTS(NTS.BYEBYE);
// uuid:device-UUID(::upnp:rootdevice)*
if (isRootDevice() == true) {
String devNT = getNotifyDeviceNT();
String devUSN = getNotifyDeviceUSN();
ssdpReq.setNT(devNT);
ssdpReq.setUSN(devUSN);
ssdpSock.post(ssdpReq);
}
// uuid:device-UUID::urn:schemas-upnp-org:device:deviceType:v
String devNT = getNotifyDeviceTypeNT();
String devUSN = getNotifyDeviceTypeUSN();
ssdpReq.setNT(devNT);
ssdpReq.setUSN(devUSN);
ssdpSock.post(ssdpReq);
// Thanks for Mikael Hakman (04/25/05)
ssdpSock.close();
ServiceList serviceList = getServiceList();
int serviceCnt = serviceList.size();
for (int n = 0; n < serviceCnt; n++) {
Service service = serviceList.getService(n);
service.byebye(bindAddr);
}
DeviceList childDeviceList = getDeviceList();
int childDeviceCnt = childDeviceList.size();
for (int n = 0; n < childDeviceCnt; n++) {
Device childDevice = childDeviceList.getDevice(n);
childDevice.byebye(bindAddr);
}
}
public void byebye() {
InetAddress[] binds = getDeviceData().getHTTPBindAddress();
String[] bindAddresses;
if (binds != null) {
bindAddresses = new String[binds.length];
for (int i = 0; i < binds.length; i++) {
bindAddresses[i] = binds[i].getHostAddress();
}
} else {
int nHostAddrs = HostInterface.getNHostAddresses();
bindAddresses = new String[nHostAddrs];
for (int n = 0; n < nHostAddrs; n++) {
bindAddresses[n] = HostInterface.getHostAddress(n);
}
}
for (int j = 0; j < bindAddresses.length; j++) {
if (bindAddresses[j] == null || bindAddresses[j].length() <= 0)
continue;
int ssdpCount = getSSDPAnnounceCount();
for (int i = 0; i < ssdpCount; i++)
byebye(bindAddresses[j]);
}
}
// //////////////////////////////////////////////
// Search
// //////////////////////////////////////////////
private static Calendar cal = Calendar.getInstance();
public boolean postSearchResponse(SSDPPacket ssdpPacket, String st,
String usn) {
String localAddr = ssdpPacket.getLocalAddress();
Device rootDev = getRootDevice();
String rootDevLocation = rootDev.getLocationURL(localAddr);
SSDPSearchResponse ssdpRes = new SSDPSearchResponse();
ssdpRes.setLeaseTime(getLeaseTime());
ssdpRes.setDate(cal);
ssdpRes.setST(st);
ssdpRes.setUSN(usn);
ssdpRes.setLocation(rootDevLocation);
ssdpRes.setBootId(getBootId());
// Thanks for Brent Hills (10/20/04)
ssdpRes.setMYNAME(getFriendlyName());
int mx = ssdpPacket.getMX();
TimerUtil.waitRandom(mx * 1000);
String remoteAddr = ssdpPacket.getRemoteAddress();
int remotePort = ssdpPacket.getRemotePort();
SSDPSearchResponseSocket ssdpResSock = new SSDPSearchResponseSocket();
if (Debug.isOn() == true)
ssdpRes.print();
int ssdpCount = getSSDPAnnounceCount();
for (int i = 0; i < ssdpCount; i++)
ssdpResSock.post(remoteAddr, remotePort, ssdpRes);
return true;
}
public void deviceSearchResponse(SSDPPacket ssdpPacket) {
String ssdpST = ssdpPacket.getST();
if (ssdpST == null)
return;
boolean isRootDevice = isRootDevice();
String devUSN = getUDN();
if (isRootDevice == true)
devUSN += "::" + USN.ROOTDEVICE;
if (ST.isAllDevice(ssdpST) == true) {
String devNT = getNotifyDeviceNT();
int repeatCnt = (isRootDevice == true) ? 3 : 2;
for (int n = 0; n < repeatCnt; n++)
postSearchResponse(ssdpPacket, devNT, devUSN);
} else if (ST.isRootDevice(ssdpST) == true) {
if (isRootDevice == true)
postSearchResponse(ssdpPacket, ST.ROOT_DEVICE, devUSN);
} else if (ST.isUUIDDevice(ssdpST) == true) {
String devUDN = getUDN();
if (ssdpST.equals(devUDN) == true)
postSearchResponse(ssdpPacket, devUDN, devUSN);
} else if (ST.isURNDevice(ssdpST) == true) {
String devType = getDeviceType();
if (ssdpST.equals(devType) == true) {
// Thanks for Mikael Hakman (04/25/05)
devUSN = getUDN() + "::" + devType;
postSearchResponse(ssdpPacket, devType, devUSN);
}
}
ServiceList serviceList = getServiceList();
int serviceCnt = serviceList.size();
for (int n = 0; n < serviceCnt; n++) {
Service service = serviceList.getService(n);
service.serviceSearchResponse(ssdpPacket);
}
DeviceList childDeviceList = getDeviceList();
int childDeviceCnt = childDeviceList.size();
for (int n = 0; n < childDeviceCnt; n++) {
Device childDevice = childDeviceList.getDevice(n);
childDevice.deviceSearchResponse(ssdpPacket);
}
}
public void deviceSearchReceived(SSDPPacket ssdpPacket) {
deviceSearchResponse(ssdpPacket);
}
// //////////////////////////////////////////////
// HTTP Server
// //////////////////////////////////////////////
public void setHTTPPort(int port) {
getDeviceData().setHTTPPort(port);
}
public int getHTTPPort() {
return getDeviceData().getHTTPPort();
}
public void setHTTPBindAddress(InetAddress[] inets) {
this.getDeviceData().setHTTPBindAddress(inets);
}
public InetAddress[] getHTTPBindAddress() {
return this.getDeviceData().getHTTPBindAddress();
}
/**
*
* @return SSDPIPv4MulticastAddress
* @since 1.8
*/
public String getSSDPIPv4MulticastAddress() {
return this.getDeviceData().getMulticastIPv4Address();
}
/**
*
* @param ip
* @since 1.8
*/
public void getSSDPIPv4MulticastAddress(String ip) {
this.getDeviceData().setMulticastIPv4Address(ip);
}
/**
*
* @return SSDPIPv6MulticastAddress
* @since 1.8
*/
public String getSSDPIPv6MulticastAddress() {
return this.getDeviceData().getMulticastIPv6Address();
}
/**
*
* @param ip
* @since 1.8
*/
public void getSSDPIPv6MulticastAddress(String ip) {
this.getDeviceData().setMulticastIPv6Address(ip);
}
public void httpRequestRecieved(HTTPRequest httpReq) {
if (Debug.isOn() == true)
httpReq.print();
if (hasPresentationListener() && isPresentationRequest(httpReq)) {
PresentationListener listener = getPresentationListener();
listener.httpRequestRecieved(httpReq);
return;
}
if (httpReq.isGetRequest() == true || httpReq.isHeadRequest() == true) {
httpGetRequestRecieved(httpReq);
return;
}
if (httpReq.isPostRequest() == true) {
httpPostRequestRecieved(httpReq);
return;
}
if (httpReq.isSubscribeRequest() == true
|| httpReq.isUnsubscribeRequest() == true) {
SubscriptionRequest subReq = new SubscriptionRequest(httpReq);
deviceEventSubscriptionRecieved(subReq);
return;
}
httpReq.returnBadRequest();
}
private synchronized byte[] getDescriptionData(String host) {
if (isNMPRMode() == false)
updateURLBase(host);
Node rootNode = getRootNode();
if (rootNode == null)
return new byte[0];
// Thanks for Mikael Hakman (04/25/05)
String desc = new String();
desc += UPnP.XML_DECLARATION;
desc += "\n";
desc += rootNode.toString();
return desc.getBytes();
}
private void httpGetRequestRecieved(HTTPRequest httpReq) {
String uri = httpReq.getURI();
Debug.message("httpGetRequestRecieved = " + uri);
if (uri == null) {
httpReq.returnBadRequest();
return;
}
Device embDev;
Service embService;
byte fileByte[] = new byte[0];
String contentType = null;
String contentLanguage = null;
if (isDescriptionURI(uri) == true) {
String localAddr = httpReq.getLocalAddress();
if ((localAddr == null) || (localAddr.length() <= 0))
localAddr = HostInterface.getInterface();
contentType = XML.DEFAULT_CONTENT_TYPE;
contentLanguage = XML.DEFAULT_CONTENT_LANGUAGE;
fileByte = getDescriptionData(localAddr);
} else if ((embDev = getDeviceByDescriptionURI(uri)) != null) {
String localAddr = httpReq.getLocalAddress();
contentType = XML.DEFAULT_CONTENT_TYPE;
contentLanguage = XML.DEFAULT_CONTENT_LANGUAGE;
fileByte = embDev.getDescriptionData(localAddr);
} else if ((embService = getServiceBySCPDURL(uri)) != null) {
contentType = XML.DEFAULT_CONTENT_TYPE;
contentLanguage = XML.DEFAULT_CONTENT_LANGUAGE;
fileByte = embService.getSCPDData();
} else if (isIconBytesURI(uri) == true) {
Icon devIcon = getIconByURI(uri);
if (devIcon != null) {
contentType = devIcon.getMimeType();
fileByte = devIcon.getBytes();
}
} else {
httpReq.returnBadRequest();
return;
}
HTTPResponse httpRes = new HTTPResponse();
httpRes.setStatusCode(HTTPStatus.OK);
if (contentType != null) {
httpRes.setContentType(contentType);
}
if (contentLanguage != null) {
// FIXME Check ACCEPT-LANGUAGE header in client request, and set a
// suitable code.
httpRes.setContentLanguage(contentLanguage);
}
httpRes.setContent(fileByte);
httpReq.post(httpRes);
}
private void httpPostRequestRecieved(HTTPRequest httpReq) {
if (httpReq.isSOAPAction() == true) {
// SOAPRequest soapReq = new SOAPRequest(httpReq);
soapActionRecieved(httpReq);
return;
}
httpReq.returnBadRequest();
}
// //////////////////////////////////////////////
// SOAP
// //////////////////////////////////////////////
private void soapBadActionRecieved(HTTPRequest soapReq) {
SOAPResponse soapRes = new SOAPResponse();
soapRes.setStatusCode(HTTPStatus.BAD_REQUEST);
soapReq.post(soapRes);
}
private void soapActionRecieved(HTTPRequest soapReq) {
String uri = soapReq.getURI();
Service ctlService = getServiceByControlURL(uri);
if (ctlService != null) {
ActionRequest crlReq = new ActionRequest(soapReq);
deviceControlRequestRecieved(crlReq, ctlService);
return;
}
soapBadActionRecieved(soapReq);
}
// //////////////////////////////////////////////
// controlAction
// //////////////////////////////////////////////
private void deviceControlRequestRecieved(ControlRequest ctlReq,
Service service) {
if (ctlReq.isQueryControl() == true)
deviceQueryControlRecieved(new QueryRequest(ctlReq), service);
else
deviceActionControlRecieved(new ActionRequest(ctlReq), service);
}
private void invalidActionControlRecieved(ControlRequest ctlReq) {
ControlResponse actRes = new ActionResponse();
actRes.setFaultResponse(UPnPStatus.INVALID_ACTION);
ctlReq.post(actRes);
}
private void invalidArgumentsControlRecieved(ControlRequest ctlReq) {
ControlResponse actRes = new ActionResponse();
actRes.setFaultResponse(UPnPStatus.INVALID_ARGS);
ctlReq.post(actRes);
}
private void deviceActionControlRecieved(ActionRequest ctlReq,
Service service) {
if (Debug.isOn() == true)
ctlReq.print();
String actionName = ctlReq.getActionName();
Action action = service.getAction(actionName);
if (action == null) {
invalidActionControlRecieved(ctlReq);
return;
}
ArgumentList actionArgList = action.getArgumentList();
ArgumentList reqArgList = ctlReq.getArgumentList();
try {
actionArgList.setReqArgs(reqArgList);
} catch (IllegalArgumentException ex) {
invalidArgumentsControlRecieved(ctlReq);
return;
}
if (action.performActionListener(ctlReq) == false)
invalidActionControlRecieved(ctlReq);
}
private void deviceQueryControlRecieved(QueryRequest ctlReq, Service service) {
if (Debug.isOn() == true)
ctlReq.print();
String varName = ctlReq.getVarName();
if (service.hasStateVariable(varName) == false) {
invalidActionControlRecieved(ctlReq);
return;
}
StateVariable stateVar = getStateVariable(varName);
if (stateVar.performQueryListener(ctlReq) == false)
invalidActionControlRecieved(ctlReq);
}
// //////////////////////////////////////////////
// eventSubscribe
// //////////////////////////////////////////////
private void upnpBadSubscriptionRecieved(SubscriptionRequest subReq,
int code) {
SubscriptionResponse subRes = new SubscriptionResponse();
subRes.setErrorResponse(code);
subReq.post(subRes);
}
private void deviceEventSubscriptionRecieved(SubscriptionRequest subReq) {
String uri = subReq.getURI();
Service service = getServiceByEventSubURL(uri);
if (service == null) {
subReq.returnBadRequest();
return;
}
if (subReq.hasCallback() == false && subReq.hasSID() == false) {
upnpBadSubscriptionRecieved(subReq, HTTPStatus.PRECONDITION_FAILED);
return;
}
// UNSUBSCRIBE
if (subReq.isUnsubscribeRequest() == true) {
deviceEventUnsubscriptionRecieved(service, subReq);
return;
}
// SUBSCRIBE (NEW)
if (subReq.hasCallback() == true) {
deviceEventNewSubscriptionRecieved(service, subReq);
return;
}
// SUBSCRIBE (RENEW)
if (subReq.hasSID() == true) {
deviceEventRenewSubscriptionRecieved(service, subReq);
return;
}
upnpBadSubscriptionRecieved(subReq, HTTPStatus.PRECONDITION_FAILED);
}
private void deviceEventNewSubscriptionRecieved(Service service,
SubscriptionRequest subReq) {
String callback = subReq.getCallback();
try {
new URL(callback);
} catch (Exception e) {
upnpBadSubscriptionRecieved(subReq, HTTPStatus.PRECONDITION_FAILED);
return;
}
long timeOut = subReq.getTimeout();
String sid = Subscription.createSID();
Subscriber sub = new Subscriber();
sub.setDeliveryURL(callback);
sub.setTimeOut(timeOut);
sub.setSID(sid);
service.addSubscriber(sub);
SubscriptionResponse subRes = new SubscriptionResponse();
subRes.setStatusCode(HTTPStatus.OK);
subRes.setSID(sid);
subRes.setTimeout(timeOut);
if (Debug.isOn() == true)
subRes.print();
subReq.post(subRes);
if (Debug.isOn() == true)
subRes.print();
service.notifyAllStateVariables();
}
private void deviceEventRenewSubscriptionRecieved(Service service,
SubscriptionRequest subReq) {
String sid = subReq.getSID();
Subscriber sub = service.getSubscriber(sid);
if (sub == null) {
upnpBadSubscriptionRecieved(subReq, HTTPStatus.PRECONDITION_FAILED);
return;
}
long timeOut = subReq.getTimeout();
sub.setTimeOut(timeOut);
sub.renew();
SubscriptionResponse subRes = new SubscriptionResponse();
subRes.setStatusCode(HTTPStatus.OK);
subRes.setSID(sid);
subRes.setTimeout(timeOut);
subReq.post(subRes);
if (Debug.isOn() == true)
subRes.print();
}
private void deviceEventUnsubscriptionRecieved(Service service,
SubscriptionRequest subReq) {
String sid = subReq.getSID();
Subscriber sub = service.getSubscriber(sid);
if (sub == null) {
upnpBadSubscriptionRecieved(subReq, HTTPStatus.PRECONDITION_FAILED);
return;
}
service.removeSubscriber(sub);
SubscriptionResponse subRes = new SubscriptionResponse();
subRes.setStatusCode(HTTPStatus.OK);
subReq.post(subRes);
if (Debug.isOn() == true)
subRes.print();
}
// //////////////////////////////////////////////
// Thread
// //////////////////////////////////////////////
private HTTPServerList getHTTPServerList() {
return getDeviceData().getHTTPServerList();
}
/**
*
* @param port
* The port to use for binding the SSDP service
*/
public void setSSDPPort(int port) {
this.getDeviceData().setSSDPPort(port);
}
/**
*
* @return The port to use for binding the SSDP service
*/
public int getSSDPPort() {
return this.getDeviceData().getSSDPPort();
}
/**
*
* @param inets
* The IP that will be used for binding the SSDP service. Use
* null
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();
}
/**
*
* @param ip
* The IPv address used for Multicast comunication
*/
public void setMulticastIPv6Address(String ip) {
this.getDeviceData().setMulticastIPv6Address(ip);
}
/**
*
* @return The IPv address used for Multicast comunication
*/
public String getMulticastIPv6Address() {
return this.getDeviceData().getMulticastIPv6Address();
}
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();
// //////////////////////////////////////
// BOOTID/CONFIGID.UPNP.ORG
// //////////////////////////////////////
updateBootId();
updateConfigId();
// //////////////////////////////////////
// Announce
// //////////////////////////////////////
announce();
// //////////////////////////////////////
// Advertiser
// //////////////////////////////////////
Advertiser adv = new Advertiser(this);
setAdvertiser(adv);
adv.start();
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);
}
public boolean isRunning() {
return (getAdvertiser() != null) ? true : false;
}
// //////////////////////////////////////////////
// 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 < nServices; n++) {
Service service = serviceList.getService(n);
service.setActionListener(listener);
}
}
public void setQueryListener(QueryListener listener) {
ServiceList serviceList = getServiceList();
int nServices = serviceList.size();
for (int n = 0; n < nServices; n++) {
Service service = serviceList.getService(n);
service.setQueryListener(listener);
}
}
// //////////////////////////////////////////////
// Acion/QueryListener (includeSubDevices)
// //////////////////////////////////////////////
// Thanks for Mikael Hakman (04/25/05)
public void setActionListener(ActionListener listener,
boolean includeSubDevices) {
setActionListener(listener);
if (includeSubDevices == true) {
DeviceList devList = getDeviceList();
int devCnt = devList.size();
for (int n = 0; n < devCnt; n++) {
Device dev = devList.getDevice(n);
dev.setActionListener(listener, true);
}
}
}
// Thanks for Mikael Hakman (04/25/05)
public void setQueryListener(QueryListener listener,
boolean includeSubDevices) {
setQueryListener(listener);
if (includeSubDevices == true) {
DeviceList devList = getDeviceList();
int devCnt = devList.size();
for (int n = 0; n < devCnt; n++) {
Device dev = devList.getDevice(n);
dev.setQueryListener(listener, true);
}
}
}
// //////////////////////////////////////////////
// userData
// //////////////////////////////////////////////
private Object userData = null;
public void setUserData(Object data) {
userData = data;
}
public Object getUserData() {
return userData;
}
// //////////////////////////////////////////////
// output
// //////////////////////////////////////////////
/*
* public void output(PrintWriter ps) { ps.println("deviceType = " +
* getDeviceType()); ps.println("freindlyName = " + getFriendlyName());
* ps.println("presentationURL = " + getPresentationURL());
*
* DeviceList devList = getDeviceList(); ps.println("devList = " +
* devList.size());
*
* ServiceList serviceList = getServiceList(); ps.println("serviceList = " +
* serviceList.size());
*
* IconList iconList = getIconList(); ps.println("iconList = " +
* iconList.size()); }
*
* public void print() { PrintWriter pr = new PrintWriter(System.out);
* output(pr); pr.flush(); }
*/
/*
public static void main(String[] args) {
test("/foo/x", "http://aa:123/");
test("/foo/x", "http://aa:123/bar/");
test("/foo/x", "http://aa:123/bar/baz");
test("foo/x", "http://aa:123/");
test("foo/x", "http://aa:123/bar/");
test("foo/x", "http://aa:123/bar/baz");
}
private static void test(String a, String b) {
Device d = new Device();
String c = d.getAbsoluteURL(a, "", b);
System.out.println(b + ' ' + a + ' ' + c);
c = d.getAbsoluteURL(a, b, "");
System.out.println(b + ' ' + a + ' ' + c);
}
*/
}