Permalink
Browse files

Extended SUBSCRIBE support

  • Loading branch information...
1 parent 3fbfac7 commit e9ad14a9b762deb86895d452aad87846c0d57033 @Happy-Neko Happy-Neko committed Jun 25, 2012
@@ -39,4 +39,18 @@
static final String XBOX_1 = "<u:IsValidatedResponse xmlns:u=\"urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1\">" + CRLF + "<Result>1</Result>" + CRLF + "</u:IsValidatedResponse>";
static final String XBOX_2 = "<u:IsAuthorizedResponse xmlns:u=\"urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1\">" + CRLF + "<Result>1</Result>" + CRLF + "</u:IsAuthorizedResponse>";
static final String UPNP_INVALID_ACTION = "<s:Fault><faultCode>s:Client</faultCode><faultString>UPnPError</faultString><detail><UPnPError xmlns=\"urn:schemas-upnp-org:control-1-0\"><errorCode>401</errorCode><errorDescription>Invalid Action</errorDescription></UPnPError></detail></s:Fault>";
+ static final String EVENT_FOOTER="</e:propertyset>";
+
+ public static String eventProp(String prop) {
+ return eventProp(prop,"");
+ }
+
+ public static String eventProp(String prop,String val) {
+ return "<e:property><"+prop+">"+val+"</"+prop+"></e:property>";
+ }
+
+ public static String eventHeader(String urn) {
+ return "<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\" xmlns:s=\""+
+ urn+"\">";
+ }
}
@@ -33,14 +33,13 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.net.Socket;
import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.TimeZone;
+import java.util.*;
public class Request extends HTTPResource {
- private static final Logger logger = LoggerFactory.getLogger(Request.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(Request.class);
+
private final static String CRLF = "\r\n";
private final static String HTTP_200_OK = "HTTP/1.1 200 OK";
private final static String HTTP_500 = "HTTP/1.1 500 Internal Server Error";
@@ -183,10 +182,10 @@ public void answer(OutputStream output, StartStopListenerDelegate startStopListe
// Samsung 2012 TVs have a problematic preceding slash that needs to be removed.
if (argument.startsWith("/")) {
- logger.trace("Stripping preceding slash from: " + argument);
+ LOGGER.trace("Stripping preceding slash from: " + argument);
argument = argument.substring(1);
}
-
+
if ((method.equals("GET") || method.equals("HEAD")) && argument.startsWith("console/")) {
output(output, "Content-Type: text/html");
response.append(HTMLConsole.servePage(argument.substring(8)));
@@ -229,7 +228,7 @@ public void answer(OutputStream output, StartStopListenerDelegate startStopListe
inputStream = dlna.getInputStream(Range.create(lowRange, highRange, timeseek, timeRangeEnd), mediaRenderer);
if (inputStream == null) {
// No inputStream indicates that transcoding / remuxing probably crashed.
- logger.error("There is no inputstream to return for " + name);
+ LOGGER.error("There is no inputstream to return for " + name);
} else {
startStopListenerDelegate.start(dlna);
output(output, "Content-Type: " + getRendererMimeType(dlna.mimeType(), mediaRenderer));
@@ -249,8 +248,8 @@ public void answer(OutputStream output, StartStopListenerDelegate startStopListe
if (type < DLNAMediaSubtitle.subExtensions.length) {
String strType = DLNAMediaSubtitle.subExtensions[type - 1];
String subtitleUrl = "http://" + PMS.get().getServer().getHost()
- + ':' + PMS.get().getServer().getPort() + "/get/"
- + id + "/subtitle0000." + strType;
+ + ':' + PMS.get().getServer().getPort() + "/get/"
+ + id + "/subtitle0000." + strType;
output(output, subtitleHttpHeader + ": " + subtitleUrl);
}
}
@@ -290,15 +289,15 @@ public void answer(OutputStream output, StartStopListenerDelegate startStopListe
if (requested != 0) {
// Determine the range (i.e. smaller of known or requested bytes)
long bytes = remaining > -1 ? remaining : inputStream.available();
-
+
if (requested > 0 && bytes > requested) {
bytes = requested + 1;
}
// Calculate the corresponding highRange (this is usually redundant).
highRange = lowRange + bytes - (bytes > 0 ? 1 : 0);
- logger.trace((chunked ? "Using chunked response. " : "") + "Sending " + bytes + " bytes.");
+ LOGGER.trace((chunked ? "Using chunked response. " : "") + "Sending " + bytes + " bytes.");
output(output, "Content-Range: bytes " + lowRange
+ "-" + (highRange > -1 ? highRange : "*")
@@ -355,15 +354,15 @@ public void answer(OutputStream output, StartStopListenerDelegate startStopListe
s = s.replace("[host]", PMS.get().getServer().getHost());
s = s.replace("[port]", "" + PMS.get().getServer().getPort());
if (xbox) {
- logger.debug("DLNA changes for Xbox360");
+ LOGGER.debug("DLNA changes for Xbox 360");
s = s.replace("PS3 Media Server", "PS3 Media Server [" + profileName + "] : Windows Media Connect");
s = s.replace("<modelName>PMS</modelName>", "<modelName>Windows Media Connect</modelName>");
s = s.replace("<serviceList>", "<serviceList>" + CRLF + "<service>" + CRLF
- + "<serviceType>urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1</serviceType>" + CRLF
- + "<serviceId>urn:microsoft.com:serviceId:X_MS_MediaReceiverRegistrar</serviceId>" + CRLF
- + "<SCPDURL>/upnp/mrr/scpd</SCPDURL>" + CRLF
- + "<controlURL>/upnp/mrr/control</controlURL>" + CRLF
- + "</service>" + CRLF);
+ + "<serviceType>urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1</serviceType>" + CRLF
+ + "<serviceId>urn:microsoft.com:serviceId:X_MS_MediaReceiverRegistrar</serviceId>" + CRLF
+ + "<SCPDURL>/upnp/mrr/scpd</SCPDURL>" + CRLF
+ + "<controlURL>/upnp/mrr/control</controlURL>" + CRLF
+ + "</service>" + CRLF);
} else {
@@ -398,6 +397,46 @@ public void answer(OutputStream output, StartStopListenerDelegate startStopListe
response.append(HTTPXMLHelper.SOAP_ENCODING_FOOTER);
response.append(CRLF);
}
+ } else if (method.equals("SUBSCRIBE")) {
+ if(soapaction==null) //ignore this
+ return;
+ String uuid="uuid:"+ UUID.randomUUID().toString();
+ output(output, CONTENT_TYPE_UTF8);
+ output(output,"Content-Length: 0");
+ output(output,"Connection: close");
+ output(output,"SID: "+uuid);
+ output(output,"Server: "+PMS.get().getServerName());
+ output(output,"Timeout: Second-1800");
+ output(output,"");
+ output.flush();
+ //output.close();
+ String cb=soapaction.replace("<", "").replace(">", "");
+ String faddr=cb.replace("http://", "").replace("/", "");
+ String addr=faddr.split(":")[0];
+ int port=Integer.parseInt(faddr.split(":")[1]);
+ Socket sock=new Socket(addr,port);
+ OutputStream out=sock.getOutputStream();
+ output(out,"NOTIFY /"+argument+" HTTP/1.1");
+ output(out,"SID: "+uuid);
+ output(out,"SEQ: "+0);
+ output(out,"NT: upnp:event");
+ output(out,"NTS: upnp:propchange");
+ output(out,"HOST: "+faddr);
+ output(out, CONTENT_TYPE_UTF8);
+ if(argument.contains("connection_manager")) {
+ response.append(HTTPXMLHelper.eventHeader("urn:schemas-upnp-org:service:ConnectionManager:1"));
+ response.append(HTTPXMLHelper.eventProp("SinkProtocolInfo"));
+ response.append(HTTPXMLHelper.eventProp("SourceProtocolInfo"));
+ response.append(HTTPXMLHelper.eventProp("CurrentConnectionIDs"));
+ response.append(HTTPXMLHelper.EVENT_FOOTER);
+ }
+ else if(argument.contains("content_directory")) {
+ response.append(HTTPXMLHelper.eventHeader("urn:schemas-upnp-org:service:ContentDirectory:1"));
+ response.append(HTTPXMLHelper.eventProp("TransferIDs"));
+ response.append(HTTPXMLHelper.eventProp("ContainerUpdateIDs"));
+ response.append(HTTPXMLHelper.eventProp("SystemUpdateID",""+DLNAResource.getSystemUpdateId()));
+ response.append(HTTPXMLHelper.EVENT_FOOTER);
+ }
} else if (method.equals("POST") && argument.endsWith("upnp/control/content_directory")) {
output(output, CONTENT_TYPE_UTF8);
if (soapaction.indexOf("ContentDirectory:1#GetSystemUpdateID") > -1) {
@@ -441,7 +480,7 @@ public void answer(OutputStream output, StartStopListenerDelegate startStopListe
response.append(HTTPXMLHelper.SOAP_ENCODING_FOOTER);
response.append(CRLF);
} else if (soapaction.contains("ContentDirectory:1#Browse") || soapaction.contains("ContentDirectory:1#Search")) {
- //logger.trace(content);
+ //LOGGER.trace(content);
objectID = getEnclosingValue(content, "<ObjectID>", "</ObjectID>");
String containerID = null;
if ((objectID == null || objectID.length() == 0) && xbox) {
@@ -555,7 +594,7 @@ public void answer(OutputStream output, StartStopListenerDelegate startStopListe
totalCount = startingIndex;
}
response.append("<TotalMatches>").append(totalCount).append("</TotalMatches>");
- }
+ }
else if(browseFlag!=null && browseFlag.equals("BrowseDirectChildren"))
response.append("<TotalMatches>").append(((parentFolder != null) ? parentFolder.childrenNumber() : filessize) - minus).append("</TotalMatches>");
else
@@ -578,7 +617,7 @@ else if(browseFlag!=null && browseFlag.equals("BrowseDirectChildren"))
response.append(CRLF);
response.append(HTTPXMLHelper.SOAP_ENCODING_FOOTER);
response.append(CRLF);
- //logger.trace(response.toString());
+ //LOGGER.trace(response.toString());
}
}
@@ -590,7 +629,7 @@ else if(browseFlag!=null && browseFlag.equals("BrowseDirectChildren"))
output(output, "");
if (!method.equals("HEAD")) {
output.write(responseData);
- //logger.trace(response.toString());
+ //LOGGER.trace(response.toString());
}
} else if (inputStream != null) {
if (CLoverride > -2) {
@@ -603,7 +642,7 @@ else if(browseFlag!=null && browseFlag.equals("BrowseDirectChildren"))
}
} else {
int cl = inputStream.available();
- logger.trace("Available Content-Length: " + cl);
+ LOGGER.trace("Available Content-Length: " + cl);
output(output, "Content-Length: " + cl);
}
@@ -619,7 +658,7 @@ else if(browseFlag!=null && browseFlag.equals("BrowseDirectChildren"))
if (lowRange != DLNAMediaInfo.ENDFILE_POS && !method.equals("HEAD")) {
sendB = sendBytes(inputStream); //, ((lowRange > 0 && highRange > 0)?(highRange-lowRange):-1)
}
- logger.trace("Sending stream: " + sendB + " bytes of " + argument);
+ LOGGER.trace("Sending stream: " + sendB + " bytes of " + argument);
PMS.get().getFrame().setStatusLine(null);
} else {
if (lowRange > 0 && highRange > 0) {
@@ -633,7 +672,7 @@ else if(browseFlag!=null && browseFlag.equals("BrowseDirectChildren"))
private void output(OutputStream output, String line) throws IOException {
output.write((line + CRLF).getBytes("UTF-8"));
- logger.trace("Wrote on socket: " + line);
+ LOGGER.trace("Wrote on socket: " + line);
}
private String getFUTUREDATE() {
@@ -652,7 +691,7 @@ private int sendBytes(InputStream fis) throws IOException {
sendBytes += bytes;
}
} catch (IOException e) {
- logger.trace("Sending stream with premature end: " + sendBytes + " bytes of " + argument + ". Reason: " + e.getMessage());
+ LOGGER.trace("Sending stream with premature end: " + sendBytes + " bytes of " + argument + ". Reason: " + e.getMessage());
} finally {
fis.close();
}
Oops, something went wrong.

0 comments on commit e9ad14a

Please sign in to comment.