All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.webstersmalley.tv.sky.MulticastSkyResolverService Maven / Gradle / Ivy

/*
 * Copyright 2013 Webster Smalley
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.webstersmalley.tv.sky;

import com.webstersmalley.tv.comms.CachingComms;
import com.webstersmalley.tv.comms.Comms;
import com.webstersmalley.tv.comms.HttpComms;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.annotation.Resource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.MulticastSocket;
import java.net.URL;

/**
 * Created by: Matthew Smalley
 * Date: 27/04/13
 */
public class MulticastSkyResolverService implements SkyResolverService {

                        /* Example multicast response
NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=115
LOCATION: http://192.168.1.67:49153/description4.xml
OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01
01-NLS: effe5fb0-1dd1-11b2-a3c7-e4eb5cb8119e
NT: urn:schemas-nds-com:device:SkyServe:2
NTS: ssdp:alive
SERVER: Linux/2.6.18.8 UPnP/1.0 SKY DLNADOC/1.50
X-User-Agent: redsonic
USN: uuid:444D5376-3247-536B-7953-0019fb7ee677::urn:schemas-nds-com:device:SkyServe:2


                     */

    private final static String LOCATION_STRING = "LOCATION: ";
    private final static String USN_STRING = "USN: uuid:";

    private Logger logger = LoggerFactory.getLogger(getClass());
    private int maxReceiveLoop = 500;
    private String userAgent;
    private String serviceName;

    public void setUserAgent(String userAgent) {
        this.userAgent = userAgent;
    }

    public void setServiceName(String serviceName) {
        this.serviceName = serviceName;
    }

    @Resource(name = "comms")
    private Comms comms;

    private URL skyUrl;

    @Override
    public URL getSkyURL() {
        if (skyUrl == null) {
            skyUrl = getSkyURLImpl();
        }
        return skyUrl;
    }
    private URL getSkyURLImpl() {
        try {
            logger.info("Joining multicast group");
            MulticastSocket socket = new MulticastSocket(1900);
            InetAddress address = InetAddress.getByName("239.255.255.250");
            socket.joinGroup(address);

            String requestString = "M-SEARCH * HTTP/1.1\r\n" +
                    "HOST: 239.255.255.250:1900\r\n" +
                    "MAN: \"ssdp:discover\"\r\n" +
                    "MX: 10\r\n" +
                    "ST: ssdp:all\r\n" +
                    "USER-AGENT: " + userAgent + "\r\n";
            byte[] requestBytes = requestString.getBytes();

            DatagramPacket requestPacket = new DatagramPacket(requestBytes, requestBytes.length, address, 1900);
            socket.send(requestPacket);


            DatagramPacket packet;
            String hostname = null;
            for (int i = 0; i < maxReceiveLoop; i++) {
                byte[] buf = new byte[512];
                packet = new DatagramPacket(buf, buf.length);
                socket.receive(packet);

                String received = new String(packet.getData(), 0, packet.getLength());
                if (received.contains(serviceName)) {
                    logger.debug("Found service");
                    logger.debug(received);
                    hostname = received.substring(received.indexOf(LOCATION_STRING) + LOCATION_STRING.length());
                    hostname = hostname.substring(0, hostname.indexOf("/description")).trim();
                    logger.debug("Hostname: {}", hostname);


                    String usnString = received.substring(received.indexOf(USN_STRING) + USN_STRING.length());
                    usnString = usnString.substring(0, usnString.indexOf("::urn"));
                    logger.debug("NLS String: {}", usnString);
                    return new URL(hostname + "/" + usnString + "SkyBrowse");
                }
            }
            return null;
        } catch (Exception e) {
            logger.error("Error resolving Sky service", e);
            throw new RuntimeException("Error resolving Sky service", e);
        }
    }

    private URL getURL(String hostname) {
        try {
            URL url = new URL(hostname);
            StringBuffer sb = new StringBuffer();
            sb.append("GET " + url.toString() + "/description3.xml HTTP/1.1\r\n" +
                    "Host: " + url.getHost() + ":" + url.getPort() + "\r\n" +
                    "Connection: keep-alive\r\n" +
                    "Accept: */*\r\n" +
                    "Accept-Encoding: gzip, deflate\r\n" +
                    "Accept-Language: en-us\r\n" +
                    "Pragma: no-cache\r\n" +
                    "User-Agent: SKY_skyplus\r\n\r\n");
            String response = comms.getResourceByRawHttp(url, sb.toString());
            response = response.substring(response.indexOf("




© 2015 - 2024 Weber Informatics LLC | Privacy Policy