diff --git a/src/zutil/network/upnp/UPnPMediaServer.java b/src/zutil/network/upnp/UPnPMediaServer.java new file mode 100644 index 0000000..dc6af79 --- /dev/null +++ b/src/zutil/network/upnp/UPnPMediaServer.java @@ -0,0 +1,89 @@ +package zutil.network.upnp; + +import java.util.Map; +import java.util.UUID; + +import zutil.network.http.HttpPrintStream; + +/** + * This class is a UPnP AV Media Server that handles all the + * other UPnP services + * + * @author Ziver + */ +public class UPnPMediaServer extends UPnPRootDevice{ + public static final String RELATIVE_URL = "upnp/rootdev"; + + private String url; + private String uuid; + + public UPnPMediaServer(String location){ + url = location; + } + + public void respond(HttpPrintStream out, Map clientInfo, + Map session, Map cookie, + Map request) { + + out.enableBuffering(true); + out.setHeader("Content-Type", "text/xml"); + + out.println(""); + out.println(""); + out.println(" "); + out.println(" 1"); + out.println(" 0"); + out.println(" "); + out.println(" "+url+"");//"+ssdp.getLocation()+" + out.println(" "); + out.println(" urn:schemas-upnp-org:device:MediaServer:1"); + out.println(" ZupNP AV Media Server"); + out.println(" Ziver Koc"); + out.println(" http://ziver.koc.se"); + out.println(""); + out.println(" ZupNP Server"); + out.println(" UPnP AV Media Server"); + out.println(" 0.1"); + out.println(" "+getUUID()+""); + out.println(" "); + out.println(" "); + out.println(" urn:schemas-upnp-org:service:ConnectionManager:1"); + out.println(" urn:upnp-org:serviceId:CMGR_1-0"); + out.println(" CMGR_Control/GetServDesc"); + out.println(" CMGR_Control"); + out.println(" CMGR_Event"); + out.println(" "); + out.println(" "); + out.println(" urn:schemas-upnp-org:service:ContentDirectory:1"); + out.println(" urn:upnp-org:serviceId:CDS_1-0"); + out.println(" SCP/ContentDir"); + out.println(" Action/ContentDir"); + out.println(" Event/ContentDir"); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(""); + out.flush(); + } + + + public long getExpirationTime() { + return 60*30; // 30min + } + public String getLocation() { + return url+"RootDesc"; + } + public String getSearchTarget() { + return "upnp:rootdevice"; + } + public String getUSN() { + return getUUID()+"::upnp:rootdevice"; + } + public String getUUID() { + if(uuid==null){ + uuid = "uuid:"+UUID.nameUUIDFromBytes( this.getClass().toString().getBytes() ); //(url+Math.random()).getBytes() + } + return uuid; + } + +} diff --git a/src/zutil/network/upnp/UPnPRootDevice.java b/src/zutil/network/upnp/UPnPRootDevice.java new file mode 100644 index 0000000..172f186 --- /dev/null +++ b/src/zutil/network/upnp/UPnPRootDevice.java @@ -0,0 +1,13 @@ +package zutil.network.upnp; + +import zutil.network.http.HttpPage; +import zutil.network.ssdp.SSDPServiceInfo; +/** + * This class is a UPnP Server class that will be extended + * by all root devices handles all the other UPnP services + * + * @author Ziver + */ +public abstract class UPnPRootDevice implements HttpPage, SSDPServiceInfo{ + +} diff --git a/src/zutil/network/upnp/UPnPService.java b/src/zutil/network/upnp/UPnPService.java new file mode 100644 index 0000000..70c1236 --- /dev/null +++ b/src/zutil/network/upnp/UPnPService.java @@ -0,0 +1,10 @@ +package zutil.network.upnp; + +/** + * Information about a UPNP Service + * + * @author Ziver + */ +public interface UPnPService { + +} diff --git a/src/zutil/network/upnp/services/BrowseRetObj.java b/src/zutil/network/upnp/services/BrowseRetObj.java new file mode 100644 index 0000000..b782da5 --- /dev/null +++ b/src/zutil/network/upnp/services/BrowseRetObj.java @@ -0,0 +1,14 @@ +package zutil.network.upnp.services; + +import zutil.network.ws.WSReturnValueList; + +public class BrowseRetObj extends WSReturnValueList{ + @WSValueName("Result") + public String Result; + @WSValueName("NumberReturned") + public int NumberReturned; + @WSValueName("TotalMatches") + public int TotalMatches; + @WSValueName("UpdateID") + public int UpdateID; + } \ No newline at end of file diff --git a/src/zutil/network/upnp/services/UPnPContentDirectory.java b/src/zutil/network/upnp/services/UPnPContentDirectory.java new file mode 100644 index 0000000..cb90aaf --- /dev/null +++ b/src/zutil/network/upnp/services/UPnPContentDirectory.java @@ -0,0 +1,590 @@ +package zutil.network.upnp.services; + +import java.io.File; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.dom4j.DocumentException; + +import zutil.FileUtil; +import zutil.network.http.HttpPage; +import zutil.network.http.HttpPrintStream; +import zutil.network.upnp.UPnPService; +import zutil.network.ws.WSInterface; +import zutil.network.ws.WSReturnValueList; + +/** + * Information about a UPNP Service + * + * @author Ziver + */ +public class UPnPContentDirectory implements UPnPService, HttpPage, WSInterface { + public static final int VERSION = 1; + + private static List file_list; + + public UPnPContentDirectory(){} + + public UPnPContentDirectory(File dir){ + file_list = FileUtil.search(dir, new LinkedList(), true, Integer.MAX_VALUE); + } + + /** + * This action returns the searching capabilities + * that are supported by the device. + * + */ + @WSReturnName("SortCaps") + public String GetSearchCapabilities(){ + // "dc:title,res@size" + return ""; + } + + /** + * Returns the CSV list of meta-data tags that can + * be used in sortCriteria + * + */ + @WSReturnName("SortCaps") + public String GetSortCapabilities(){ + return "dc:title"; + } + + /** + * This action returns the current value of state variable + * SystemUpdateID. It can be used by clients that want to + * 'poll' for any changes in the Content Directory + * (as opposed to subscribing to events). + * + */ + @WSReturnName("Id") + public int GetSystemUpdateID(){ + return 0; + } + + /** + * This action allows the caller to incrementally browse + * the native hierarchy of the Content Directory objects + * exposed by the Content Directory Service, including + * information listing the classes of objects available + * in any particular object container. + * @throws DocumentException + * + */ + //@WSNameSpace("urn:schemas-upnp-org:service:ContentDirectory:1") + public BrowseRetObj Browse( + @WSParamName("ObjectID") String ObjectID, + @WSParamName("BrowseFlag") String BrowseFlag, + @WSParamName("Filter") String Filter, + @WSParamName("StartingIndex") int StartingIndex, + @WSParamName("RequestedCount") int RequestedCount, + @WSParamName("SortCriteria") String SortCriteria) throws DocumentException{ + + BrowseRetObj ret = new BrowseRetObj(); + if( BrowseFlag.equals("BrowseMetadata") ){ + + } + else if( BrowseFlag.equals("BrowseDirectChildren") ){ + StringBuffer xml = new StringBuffer(); + xml.append( "" ); + List tmp = FileUtil.search( file_list.get(Integer.parseInt(ObjectID)), new LinkedList(), false ); + for(File file : tmp){ + xml.append(" "); + + xml.append(" "+file.getName()+" "); + if( file.isDirectory() ) + xml.append(" object.container.storageFolder "); + else + xml.append(" object.container "); + xml.append(" "+(int)(file.length()/1000)+" "); + xml.append(" "); + + ret.NumberReturned++; + ret.TotalMatches++; + } + xml.append( "" ); + + ret.Result = xml.toString(); + //Document document = DocumentHelper.parseText( xml.toString() ); + //ret.Result = document.getRootElement(); + } + return ret; + } + public class BrowseRetObj extends WSReturnValueList{ + @WSValueName("Result") + public String Result; + @WSValueName("NumberReturned") + public int NumberReturned; + @WSValueName("TotalMatches") + public int TotalMatches; + @WSValueName("UpdateID") + public int UpdateID; + } + + + @WSDisabled + public void respond(HttpPrintStream out, Map clientInfo, + Map session, Map cookie, + Map request) { + + out.enableBuffering(true); + out.setHeader("Content-Type", "text/xml"); + + out.println(""); + out.println(""); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(" TransferIDs"); + out.println(" yes"); + out.println(" string"); + out.println(" "); + out.println(" "); + out.println(" A_ARG_TYPE_ObjectID"); + out.println(" no"); + out.println(" string"); + out.println(" "); + out.println(" "); + out.println(" A_ARG_TYPE_Result"); + out.println(" no"); + out.println(" string"); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(" A_ARG_TYPE_SearchCriteria"); + out.println(" no"); + out.println(" string"); + out.println(" "); + out.println(" "); + out.println(" A_ARG_TYPE_BrowseFlag"); + out.println(" no"); + out.println(" string"); + out.println(" "); + out.println(" BrowseMetadata"); + out.println(" BrowseDirectChildren"); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(" A_ARG_TYPE_Filter"); + out.println(" no"); + out.println(" string"); + out.println(" "); + out.println(" "); + out.println(" A_ARG_TYPE_SortCriteria"); + out.println(" no"); + out.println(" string"); + out.println(" "); + out.println(" "); + out.println(" A_ARG_TYPE_Index"); + out.println(" no"); + out.println(" ui4"); + out.println(" "); + out.println(" "); + out.println(" A_ARG_TYPE_Count"); + out.println(" no"); + out.println(" ui4"); + out.println(" "); + out.println(" "); + out.println(" A_ARG_TYPE_UpdateID"); + out.println(" no"); + out.println(" ui4"); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(" A_ARG_TYPE_TransferID"); + out.println(" no"); + out.println(" ui4"); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(" A_ARG_TYPE_TransferStatus"); + out.println(" no"); + out.println(" string"); + out.println(" "); + out.println(" COMPLETED"); + out.println(" ERROR"); + out.println(" IN_PROGRESS"); + out.println(" STOPPED"); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(" A_ARG_TYPE_TransferLength"); + out.println(" no"); + out.println(" string"); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(" A_ARG_TYPE_TransferTotal"); + out.println(" no"); + out.println(" string"); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(" A_ARG_TYPE_TagValueList"); + out.println(" no"); + out.println(" string"); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(" A_ARG_TYPE_URI"); + out.println(" no"); + out.println(" uri"); + out.println(" "); + out.println(" "); + out.println(" SearchCapabilities"); + out.println(" no"); + out.println(" string"); + out.println(" "); + out.println(" "); + out.println(" SortCapabilities"); + out.println(" no"); + out.println(" string"); + out.println(" "); + out.println(" "); + out.println(" SystemUpdateID"); + out.println(" yes"); + out.println(" ui4"); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(" ContainerUpdateIDs"); + out.println(" yes"); + out.println(" string"); + out.println(" "); + out.println(" "); + + + out.println(" "); + out.println(" "); + out.println(" GetSearchCapabilities"); + out.println(" "); + out.println(" "); + out.println(" SearchCaps"); + out.println(" out"); + out.println(" SearchCapabilities"); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(" GetSortCapabilities"); + out.println(" "); + out.println(" "); + out.println(" SortCaps"); + out.println(" out"); + out.println(" SortCapabilities"); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(" "); + out.println(" GetSystemUpdateID"); + out.println(" "); + out.println(" "); + out.println(" Id"); + out.println(" out"); + out.println(" SystemUpdateID"); + out.println(" "); + out.println(" "); + out.println(" "); + + out.println(" "); + out.println(" Browse"); + out.println(" "); + out.println(" "); + out.println(" ObjectID"); + out.println(" in"); + out.println(" A_ARG_TYPE_ObjectID"); + out.println(" "); + out.println(" "); + out.println(" BrowseFlag"); + out.println(" in"); + out.println(" A_ARG_TYPE_BrowseFlag"); + out.println(" "); + out.println(" "); + out.println(" Filter"); + out.println(" in"); + out.println(" A_ARG_TYPE_Filter"); + out.println(" "); + out.println(" "); + out.println(" StartingIndex"); + out.println(" in"); + out.println(" A_ARG_TYPE_Index"); + out.println(" "); + out.println(" "); + out.println(" RequestedCount"); + out.println(" in"); + out.println(" A_ARG_TYPE_Count"); + out.println(" "); + out.println(" "); + out.println(" SortCriteria"); + out.println(" in"); + out.println(" A_ARG_TYPE_SortCriteria"); + out.println(" "); + out.println(" "); + out.println(" Result"); + out.println(" out"); + out.println(" A_ARG_TYPE_Result"); + out.println(" "); + out.println(" "); + out.println(" NumberReturned"); + out.println(" out"); + out.println(" A_ARG_TYPE_Count"); + out.println(" "); + out.println(" "); + out.println(" TotalMatches"); + out.println(" out"); + out.println(" A_ARG_TYPE_Count"); + out.println(" "); + out.println(" "); + out.println(" UpdateID"); + out.println(" out"); + out.println(" A_ARG_TYPE_UpdateID"); + out.println(" "); + out.println(" "); + out.println(" "); + + /*out.println(" "); + out.println(" "); + out.println(" Search"); + out.println(" "); + out.println(" "); + out.println(" ContainerID"); + out.println(" in"); + out.println(" A_ARG_TYPE_ObjectID"); + out.println(" "); + out.println(" "); + out.println(" SearchCriteria"); + out.println(" in"); + out.println(" A_ARG_TYPE_SearchCriteria "); + out.println(" "); + out.println(" "); + out.println(" Filter"); + out.println(" in"); + out.println(" A_ARG_TYPE_Filter"); + out.println(" "); + out.println(" "); + out.println(" StartingIndex"); + out.println(" in"); + out.println(" A_ARG_TYPE_Index"); + out.println(" "); + out.println(" "); + out.println(" RequestedCount"); + out.println(" in"); + out.println(" A_ARG_TYPE_Count"); + out.println(" "); + out.println(" "); + out.println(" SortCriteria"); + out.println(" in"); + out.println(" A_ARG_TYPE_SortCriteria"); + out.println(" "); + out.println(" "); + out.println(" Result"); + out.println(" out"); + out.println(" A_ARG_TYPE_Result"); + out.println(" "); + out.println(" "); + out.println(" NumberReturned"); + out.println(" out"); + out.println(" A_ARG_TYPE_Count"); + out.println(" "); + out.println(" "); + out.println(" TotalMatches"); + out.println(" out"); + out.println(" A_ARG_TYPE_Count"); + out.println(" "); + out.println(" "); + out.println(" UpdateID"); + out.println(" out"); + out.println(" A_ARG_TYPE_UpdateID"); + out.println(" "); + out.println(" "); + out.println(" ");*/ + + /*out.println(" "); + out.println(" "); + out.println(" CreateObject"); + out.println(" "); + out.println(" "); + out.println(" ContainerID"); + out.println(" in"); + out.println(" A_ARG_TYPE_ObjectID"); + out.println(" "); + out.println(" "); + out.println(" Elements"); + out.println(" in"); + out.println(" A_ARG_TYPE_Result"); + out.println(" "); + out.println(" "); + out.println(" ObjectID"); + out.println(" out"); + out.println(" A_ARG_TYPE_ObjectID"); + out.println(" "); + out.println(" "); + out.println(" Result"); + out.println(" out"); + out.println(" A_ARG_TYPE_Result"); + out.println(" "); + out.println(" "); + out.println(" ");*/ + + /*out.println(" "); + out.println(" "); + out.println(" DestroyObject"); + out.println(" "); + out.println(" "); + out.println(" ObjectID"); + out.println(" in"); + out.println(" A_ARG_TYPE_ObjectID"); + out.println(" "); + out.println(" "); + out.println(" ");*/ + + /*out.println(" "); + out.println(" "); + out.println(" UpdateObject"); + out.println(" "); + out.println(" "); + out.println(" ObjectID"); + out.println(" in"); + out.println(" A_ARG_TYPE_ObjectID"); + out.println(" "); + out.println(" "); + out.println(" CurrentTagValue"); + out.println(" in"); + out.println(" A_ARG_TYPE_TagValueList "); + out.println(" "); + out.println(" "); + out.println(" NewTagValue"); + out.println(" in"); + out.println(" A_ARG_TYPE_TagValueList "); + out.println(" "); + out.println(" "); + out.println(" ");*/ + + /*out.println(" "); + out.println(" "); + out.println(" ImportResource"); + out.println(" "); + out.println(" "); + out.println(" SourceURI"); + out.println(" in"); + out.println(" A_ARG_TYPE_URI"); + out.println(" "); + out.println(" "); + out.println(" DestinationURI"); + out.println(" in"); + out.println(" A_ARG_TYPE_URI"); + out.println(" "); + out.println(" "); + out.println(" TransferID"); + out.println(" out"); + out.println(" A_ARG_TYPE_TransferID "); + out.println(" "); + out.println(" "); + out.println(" ");*/ + + /*out.println(" "); + out.println(" "); + out.println(" ExportResource"); + out.println(" "); + out.println(" "); + out.println(" SourceURI"); + out.println(" in"); + out.println(" A_ARG_TYPE_URI"); + out.println(" "); + out.println(" "); + out.println(" DestinationURI"); + out.println(" in"); + out.println(" A_ARG_TYPE_URI"); + out.println(" "); + out.println(" "); + out.println(" TransferID"); + out.println(" out"); + out.println(" A_ARG_TYPE_TransferID "); + out.println(" "); + out.println(" "); + out.println(" ");*/ + + /*out.println(" "); + out.println(" "); + out.println(" StopTransferResource"); + out.println(" "); + out.println(" "); + out.println(" TransferID"); + out.println(" in"); + out.println(" A_ARG_TYPE_TransferID "); + out.println(" "); + out.println(" "); + out.println(" ");*/ + + /*out.println(" "); + out.println(" "); + out.println(" GetTransferProgress"); + out.println(" "); + out.println(" "); + out.println(" TransferID"); + out.println(" in"); + out.println(" A_ARG_TYPE_TransferID "); + out.println(" "); + out.println(" "); + out.println(" TransferStatus"); + out.println(" out"); + out.println(" A_ARG_TYPE_TransferStatus "); + out.println(" "); + out.println(" "); + out.println(" TransferLength"); + out.println(" out"); + out.println(" A_ARG_TYPE_TransferLength "); + out.println(" "); + out.println(" "); + out.println(" TransferTotal"); + out.println(" out"); + out.println(" A_ARG_TYPE_TransferTotal"); + out.println(" "); + out.println(" "); + out.println(" ");*/ + + /*out.println(" "); + out.println(" "); + out.println(" DeleteResource"); + out.println(" "); + out.println(" "); + out.println(" ResourceURI"); + out.println(" in"); + out.println(" A_ARG_TYPE_URI"); + out.println(" "); + out.println(" "); + out.println(" ");*/ + + /*out.println(" "); + out.println(" "); + out.println(" CreateReference"); + out.println(" "); + out.println(" "); + out.println(" ContainerID"); + out.println(" in"); + out.println(" A_ARG_TYPE_ObjectID"); + out.println(" "); + out.println(" "); + out.println(" ObjectID"); + out.println(" in"); + out.println(" A_ARG_TYPE_ObjectID"); + out.println(" "); + out.println(" "); + out.println(" NewID"); + out.println(" out"); + out.println(" A_ARG_TYPE_ObjectID"); + out.println(" "); + out.println(" "); + out.println(" ");*/ + + out.println(" "); + out.println(""); + } +}