public void Search(string SearchString, IPEndPoint ep)
        {
            HTTPMessage request = new HTTPMessage();

            request.Directive    = "M-SEARCH";
            request.DirectiveObj = "*";
            if (ep.AddressFamily == AddressFamily.InterNetwork)
            {
                request.AddTag("HOST", ep.ToString());                                                 // "239.255.255.250:1900"
            }
            if (ep.AddressFamily == AddressFamily.InterNetworkV6)
            {
                request.AddTag("HOST", string.Format("[{0}]:{1}", ep.Address.ToString(), ep.Port));                                                   // "[FF05::C]:1900" or "[FF02::C]:1900"
            }
            request.AddTag("MAN", "\"ssdp:discover\"");
            request.AddTag("MX", "10");
            request.AddTag("ST", SearchString);
            SearchEx(UTF8Encoding.UTF8.GetBytes(request.StringPacket), ep);
        }
Пример #2
0
 private void PageHandler(OpenSource.UPnP.UPnPDevice sender, OpenSource.UPnP.HTTPMessage msg, OpenSource.UPnP.HTTPSession WebSession, string VirtualDir)
 {
     if (VirtualDir.Equals("/stream", StringComparison.InvariantCultureIgnoreCase) && msg.DirectiveObj.Equals("/swyh.mp3", StringComparison.InvariantCultureIgnoreCase))
     {
         WebSession.OnStreamDone += (s, e) =>
         {
             if (sessionMp3Streams.ContainsKey(s.SessionID))
             {
                 PipeStream value;
                 sessionMp3Streams.TryRemove(s.SessionID, out value);
                 App.CurrentInstance.wasapiProvider.UpdateClientsList();
             }
         };
         PipeStream stream = sessionMp3Streams.GetOrAdd(WebSession.SessionID, new PipeStream());
         App.CurrentInstance.wasapiProvider.UpdateClientsList();
         WebSession.SendStreamObject(stream, "audio/mpeg");
     }
     else if (VirtualDir.Equals("/stream", StringComparison.InvariantCultureIgnoreCase) && msg.DirectiveObj.Equals("/swyh.wav", StringComparison.InvariantCultureIgnoreCase))
     {
         WebSession.OnStreamDone += (s, e) =>
         {
             if (sessionPcmStreams.ContainsKey(s.SessionID))
             {
                 PipeStream value;
                 sessionPcmStreams.TryRemove(s.SessionID, out value);
                 App.CurrentInstance.wasapiProvider.UpdateClientsList();
             }
         };
         PipeStream stream = sessionPcmStreams.GetOrAdd(WebSession.SessionID, new PipeStream());
         App.CurrentInstance.wasapiProvider.UpdateClientsList();
         var audioFormat = AudioSettings.GetAudioFormat();
         WebSession.SendStreamObject(stream, "audio/L16;rate=" + audioFormat.SampleRate + ";channels=" + audioFormat.Channels);
     }
     else if (VirtualDir.Equals("/about", StringComparison.InvariantCultureIgnoreCase))
     {
         OpenSource.UPnP.HTTPMessage response = new OpenSource.UPnP.HTTPMessage();
         response.StatusCode = 200;
         response.StatusData = "OK";
         response.AddTag("Content-Type", "text/html");
         response.BodyBuffer = System.Text.Encoding.UTF8.GetBytes(Properties.Resources.About);
         WebSession.Send(response);
     }
     else
     {
         OpenSource.UPnP.HTTPMessage response = new OpenSource.UPnP.HTTPMessage();
         response.StatusCode = 404;
         response.StatusData = "Not Found";
         response.AddTag("Content-Type", "text/html");
         response.BodyBuffer = System.Text.Encoding.UTF8.GetBytes(Properties.Resources.Error404);
         WebSession.Send(response);
     }
 }
Пример #3
0
        /// <summary>
        /// Searches for a SearchTarget Asynchronously
        /// </summary>
        /// <param name="SearchTarget">The Target</param>
        public void FindDeviceAsync(String SearchTarget, IPEndPoint RemoteEP)
        {
            HTTPMessage request = new HTTPMessage();
            request.Directive = "M-SEARCH";
            request.DirectiveObj = "*";
            request.AddTag("ST", SearchTarget);
            request.AddTag("MX", MX.ToString());
            request.AddTag("MAN", "\"ssdp:discover\"");
            if (RemoteEP.AddressFamily == AddressFamily.InterNetwork) request.AddTag("HOST", RemoteEP.ToString()); // "239.255.255.250:1900"
            if (RemoteEP.AddressFamily == AddressFamily.InterNetworkV6) request.AddTag("HOST", string.Format("[{0}]:{1}", RemoteEP.Address.ToString(), RemoteEP.Port)); // "[FF05::C]:1900"
            byte[] buffer = UTF8Encoding.UTF8.GetBytes(request.StringPacket);

            IPAddress[] LocalAddresses = NetInfo.GetLocalAddresses();

            foreach (IPAddress localaddr in LocalAddresses)
            {
                try
                {
                    UdpClient session = (UdpClient)SSDPSessions[localaddr];
                    if (session == null)
                    {
                        session = new UdpClient(new IPEndPoint(localaddr, 0));
                        session.EnableBroadcast = true;
                        session.BeginReceive(new AsyncCallback(OnReceiveSink), session);
                        SSDPSessions[localaddr] = session;
                    }
                    if (RemoteEP.AddressFamily != session.Client.AddressFamily) continue;
                    if ((RemoteEP.AddressFamily == AddressFamily.InterNetworkV6) && ((IPEndPoint)session.Client.LocalEndPoint).Address.IsIPv6LinkLocal == true && RemoteEP != Utils.UpnpMulticastV6EndPoint2) continue;
                    if ((RemoteEP.AddressFamily == AddressFamily.InterNetworkV6) && ((IPEndPoint)session.Client.LocalEndPoint).Address.IsIPv6LinkLocal == false && RemoteEP != Utils.UpnpMulticastV6EndPoint1) continue;

                    IPEndPoint lep = (IPEndPoint)session.Client.LocalEndPoint;
                    if (session.Client.AddressFamily == AddressFamily.InterNetwork)
                    {
                        session.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, localaddr.GetAddressBytes());
                    }
                    else if (session.Client.AddressFamily == AddressFamily.InterNetworkV6)
                    {
                        session.Client.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.MulticastInterface, BitConverter.GetBytes((int)localaddr.ScopeId));
                    }

                    session.Send(buffer, buffer.Length, RemoteEP);
                    session.Send(buffer, buffer.Length, RemoteEP);
                }
                catch (Exception ex)
                {
                    OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.Error, "CP Failure: " + localaddr.ToString());
                    OpenSource.Utilities.EventLogger.Log(ex);
                }
            }
        }
        internal HTTPMessage _SubscribeEvent(out String SID, String CallbackURL, String Timeout)
        {
            SubscriberInfo sinfo = new SubscriberInfo();
            sinfo.SID = GetNewSID();
            sinfo.CallbackURL = CallbackURL;
            sinfo.SEQ = 1;

            int to = int.Parse(Timeout);

            if (to == 0)
            {
                sinfo.Expires = -1;
            }
            else
            {
                sinfo.Expires = DateTime.Now.AddSeconds(to).Ticks;
            }

            SubscriberTable[sinfo.SID] = sinfo;

            // Send an inital Event
            //SSDP.ParseURL(CallbackURL,out WebIP, out WebPort, out Tag);
            HTTPMessage Packet = new HTTPMessage();
            Packet.Directive = "NOTIFY";

            Packet.AddTag("Content-Type", "text/xml");
            Packet.AddTag("NT", "upnp:event");
            Packet.AddTag("NTS", "upnp:propchange");
            Packet.AddTag("SID", sinfo.SID);
            Packet.AddTag("SEQ", "0");
            Packet.AddTag("CONNECTION", "close");
            Packet.BodyBuffer = BuildEventXML();
            SID = sinfo.SID;
            SubscriptionAddedEvent.Fire(this); // Trigger event saying that a subscription was added
            return (Packet);
        }
        /// <summary>
        /// Unsubscribe to UPnPEvent
        /// </summary>
        /// <param name="cb"></param>
        public void UnSubscribe(UPnPEventHandler cb)
        {
            bool processUnSubscribe = false;

            lock (SubscribeLock)
            {
                --SubscribeCounter;
                if (SubscribeCounter <= 0)
                {
                    SubscribeCounter = 0;
                    processUnSubscribe = true;
                }
                if (cb == null)
                {
                    processUnSubscribe = true;
                    OnUPnPEvent = null;
                }
                else
                {
                    OnUPnPEvent -= cb;
                }
            }

            if (processUnSubscribe == false) return;

            HTTPMessage request = new HTTPMessage();
            String WebIP;
            int WebPort;
            String Tag;

            SSDP.ParseURL(this.__eventurl, out WebIP, out WebPort, out Tag);
            IPEndPoint dest = new IPEndPoint(IPAddress.Parse(WebIP), WebPort);

            request.Directive = "UNSUBSCRIBE";
            request.DirectiveObj = Tag;
            request.AddTag("Host", WebIP + ":" + WebPort.ToString()); // WebIP is already formatted for IPv6
            request.AddTag("SID", CurrentSID);

            HTTPRequest UR = new HTTPRequest();
            SubscribeRequestTable[UR] = UR;
            UR.OnResponse += new HTTPRequest.RequestHandler(HandleUnsubscribeResponse);
            CurrentSID = "";
            UR.PipelineRequest(dest, request, null);
        }
        /// <summary>
        /// Invokes a method on this service with specific callbacks
        /// </summary>
        /// <param name="MethodName">Name of Method</param>
        /// <param name="InVarArr">Array of UPnPArguments</param>
        /// <param name="InvokeCallback">Callback for Success</param>
        /// <param name="ErrorCallback">Callback for Failed</param>
        /// <returns>Unique Handle identifier</returns>
        public void InvokeAsync(String MethodName, UPnPArgument[] InVarArr,
            object Tag,
            UPnPService.UPnPServiceInvokeHandler InvokeCallback,
            UPnPService.UPnPServiceInvokeErrorHandler ErrorCallback)
        {
            HTTPMessage request = new HTTPMessage();
            if (InVarArr == null)
            {
                InVarArr = new UPnPArgument[0];
            }

            UPnPAction action = (UPnPAction)RemoteMethods[MethodName];
            if (action == null)
            {
                throw (new UPnPInvokeException(MethodName, InVarArr, MethodName + " is not currently defined in this object"));
            }
            else
            {
                action.ValidateArgs(InVarArr);
            }

            String WebIP;
            String sName;
            int WebPort;

            SSDP.ParseURL(__controlurl, out WebIP, out WebPort, out sName);
            IPEndPoint dest = new IPEndPoint(IPAddress.Parse(WebIP), WebPort);

            request.Directive = "POST";
            request.DirectiveObj = sName;
            request.AddTag("Host", WebIP + ":" + WebPort);
            request.AddTag("Content-Type", "text/xml; charset=\"utf-8\"");
            request.AddTag("SoapAction", "\"" + ServiceURN + "#" + MethodName + "\"");

            MemoryStream mstream = new MemoryStream(4096);
            XmlTextWriter W = new XmlTextWriter(mstream, System.Text.Encoding.UTF8);
            W.Formatting = Formatting.Indented;
            W.Indentation = 3;

            W.WriteStartDocument();
            String S = "http://schemas.xmlsoap.org/soap/envelope/";

            W.WriteStartElement("s", "Envelope", S);
            W.WriteAttributeString("s", "encodingStyle", S, "http://schemas.xmlsoap.org/soap/encoding/");
            W.WriteStartElement("s", "Body", S);
            W.WriteStartElement("u", MethodName, ServiceURN);
            for (int ID = 0; ID < InVarArr.Length; ++ID)
            {
                if (action.GetArg(InVarArr[ID].Name).Direction == "in")
                {
                    W.WriteElementString(InVarArr[ID].Name, UPnPService.SerializeObjectInstance(InVarArr[ID].DataValue));
                }
            }
            W.WriteEndElement();
            W.WriteEndElement();
            W.WriteEndElement();
            W.WriteEndDocument();
            W.Flush();

            byte[] wbuf = new Byte[mstream.Length - 3];
            mstream.Seek(3, SeekOrigin.Begin);
            mstream.Read(wbuf, 0, wbuf.Length);
            W.Close();

            request.BodyBuffer = wbuf;
            AsyncInvokeInfo state = new AsyncInvokeInfo();
            state.Args = InVarArr;
            state.MethodName = MethodName;
            state.Packet = request;
            state.Tag = Tag;
            state.InvokeCB = InvokeCallback;
            state.ErrorCB = ErrorCallback;

            InvocationPipeline.PipelineRequest(dest, request, state);
        }
Пример #7
0
 private void PageHandler(OpenSource.UPnP.UPnPDevice sender, OpenSource.UPnP.HTTPMessage msg, OpenSource.UPnP.HTTPSession WebSession, string VirtualDir)
 {
     if (VirtualDir.Equals("/stream", StringComparison.InvariantCultureIgnoreCase) && msg.DirectiveObj.Equals("/swyh.mp3", StringComparison.InvariantCultureIgnoreCase))
     {
         WebSession.OnStreamDone += (s, e) =>
         {
             PipeStream value;
             while (!sessionMp3Streams.TryRemove(s.SessionID, out value)) ; ;
             App.CurrentInstance.wasapiProvider.UpdateClientsList();
         };
         PipeStream stream = sessionMp3Streams.GetOrAdd(WebSession.SessionID, new PipeStream());
         App.CurrentInstance.wasapiProvider.UpdateClientsList();
         WebSession.SendStreamObject(stream, "audio/mpeg");
     }
     else if (VirtualDir.Equals("/stream", StringComparison.InvariantCultureIgnoreCase) && msg.DirectiveObj.Equals("/swyh.wav", StringComparison.InvariantCultureIgnoreCase))
     {
         WebSession.OnStreamDone += (s, e) =>
         {
             PipeStream value;
             while (!sessionPcmStreams.TryRemove(s.SessionID, out value)) ; ;
             App.CurrentInstance.wasapiProvider.UpdateClientsList();
         };
         PipeStream stream = sessionPcmStreams.GetOrAdd(WebSession.SessionID, new PipeStream());
         App.CurrentInstance.wasapiProvider.UpdateClientsList();
         var audioFormat = AudioSettings.GetAudioFormat();
         WebSession.SendStreamObject(stream, "audio/L16;rate=" + audioFormat.SampleRate + ";channels=" + audioFormat.Channels);
     }
     else if (VirtualDir.Equals("/about", StringComparison.InvariantCultureIgnoreCase))
     {
         OpenSource.UPnP.HTTPMessage response = new OpenSource.UPnP.HTTPMessage();
         response.StatusCode = 200;
         response.StatusData = "OK";
         response.AddTag("Content-Type", "text/html");
         response.BodyBuffer = System.Text.Encoding.UTF8.GetBytes(Properties.Resources.About);
         WebSession.Send(response);
     }
     else
     {
         OpenSource.UPnP.HTTPMessage response = new OpenSource.UPnP.HTTPMessage();
         response.StatusCode = 404;
         response.StatusData = "Not Found";
         response.AddTag("Content-Type", "text/html");
         response.BodyBuffer = System.Text.Encoding.UTF8.GetBytes(Properties.Resources.Error404);
         WebSession.Send(response);
     }
 }
        private void Validate_MSEARCH_RESPONSETIME()
        {
            AddMessage(0, "Testing Notifications");
            HTTPMessage r = new HTTPMessage();
            r.Directive = "M-SEARCH";
            r.DirectiveObj = "*";
            r.AddTag("MX", "10");
            r.AddTag("ST", "uuid:" + TestDevice.UniqueDeviceName);
            r.AddTag("Host", "239.255.255.250:1900");
            r.AddTag("MAN", "\"ssdp:discover\"");

            byte[] buf = r.RawPacket;
            IPEndPoint dest = new IPEndPoint(IPAddress.Parse("239.255.255.250"), 1900);
            Cache = -1;

            MRE.Reset();
            StartTime = DateTime.Now;
            ASocket.Send(buf, 0, buf.Length, dest);
            StartCountDown(0, 90);
            MRE.WaitOne(15000, false);
            AbortCountDown();

            MRE.Reset();
            StartTime = DateTime.Now;
            ASocket.Send(buf, 0, buf.Length, dest);
            StartCountDown(15, 90);
            MRE.WaitOne(15000, false);
            AbortCountDown();

            MRE.Reset();
            StartTime = DateTime.Now;
            ASocket.Send(buf, 0, buf.Length, dest);
            StartCountDown(30, 90);
            MRE.WaitOne(15000, false);
            AbortCountDown();

            MRE.Reset();
            StartTime = DateTime.Now;
            ASocket.Send(buf, 0, buf.Length, dest);
            StartCountDown(45, 90);
            MRE.WaitOne(15000, false);
            AbortCountDown();

            MRE.Reset();
            StartTime = DateTime.Now;
            ASocket.Send(buf, 0, buf.Length, dest);
            StartCountDown(60, 90);
            MRE.WaitOne(15000, false);
            AbortCountDown();

            MRE.Reset();
            StartTime = DateTime.Now;
            ASocket.Send(buf, 0, buf.Length, dest);
            StartCountDown(75, 90);
            MRE.WaitOne(15000, false);
            AbortCountDown();

            double s = 0;
            try
            {
                s = DPA.StandardDeviation.TotalSeconds;
            }
            catch (DivideByZeroException) {}

            if (s < (double)1.50)
            {
                AddEvent(LogImportance.Medium, "M-SEARCH, MX Value",
                    "WARNING: Device not choosing Random interval based on MX value <<Standard Deviation: " + s.ToString() + ">>");
                Results.Add("M-SEARCH Response time not choosing Random interval based on MX value");
                MX = UPnPTestStates.Warn;
                SetState("MX Value", UPnPTestStates.Warn);
            }
            else
            {
                MX = UPnPTestStates.Pass;
                AddEvent(LogImportance.Remark, "M-SEARCH, MX Value",
                    "Random MX interval: <<Standard Deviation: " + s.ToString() + ">> OK");
                Results.Add("M-SEARCH Response time OK");
                SetState("MX Value", UPnPTestStates.Pass);
            }
        }
Пример #9
0
        private HTTPMessage[] BuildByePacket(IPAddress local)
        {
            HTTPMessage msg;
            ArrayList ByeList = new ArrayList();

            msg = new HTTPMessage();
            msg.Directive = "NOTIFY";
            msg.DirectiveObj = "*";
            msg.AddTag("Host", Utils.GetMulticastAddrBraketPort(local));
            msg.AddTag("NT", "upnp:rootdevice");
            msg.AddTag("NTS", "ssdp:byebye");
            msg.AddTag("USN", "uuid:" + UniqueDeviceName + "::upnp:rootdevice");
            ByeList.Add(msg);

            BuildByePacket2(ByeList, local);
            foreach (UPnPDevice d in this.EmbeddedDevices)
            {
                d.BuildByePacket2(ByeList, local);
            }

            return ((HTTPMessage[])ByeList.ToArray(typeof(HTTPMessage)));
        }
Пример #10
0
        internal HTTPMessage ParseInvokeResponse(string MethodTag, string SOAPACTION, string urn, object RetVal, UPnPArgument[] OutArgs)
        {
            HTTPMessage response = new HTTPMessage();
            MemoryStream mstream = new MemoryStream(4096);
            XmlTextWriter W = new XmlTextWriter(mstream, System.Text.Encoding.UTF8);
            W.Formatting = Formatting.Indented;
            W.Indentation = 3;

            W.WriteStartDocument();
            String S = "http://schemas.xmlsoap.org/soap/envelope/";

            W.WriteStartElement("s", "Envelope", S);
            W.WriteAttributeString("s", "encodingStyle", S, "http://schemas.xmlsoap.org/soap/encoding/");

            W.WriteStartElement("s", "Body", S);

            if (SOAPACTION.EndsWith("#QueryStateVariable\"") == false)
            {
                W.WriteStartElement("u", MethodTag + "Response", urn);
                if (RetVal != null)
                {
                    W.WriteElementString(((UPnPArgument)RetVal).Name, UPnPService.SerializeObjectInstance(((UPnPArgument)RetVal).DataValue));
                }
                foreach (UPnPArgument arg in OutArgs)
                {
                    W.WriteElementString(arg.Name, UPnPService.SerializeObjectInstance(arg.DataValue));
                }
            }
            else
            {
                //QueryStateVariableResponse
                String QSV = "urn:schemas-upnp-org:control-1-0";
                W.WriteStartElement("u", MethodTag + "Response", QSV);
                W.WriteElementString("return", UPnPStringFormatter.EscapeString(UPnPService.SerializeObjectInstance(RetVal)));
            }

            W.WriteEndElement();
            W.WriteEndElement();
            W.WriteEndElement();
            W.WriteEndDocument();
            W.Flush();

            byte[] wbuf = new Byte[mstream.Length - 3];
            mstream.Seek(3, SeekOrigin.Begin);
            mstream.Read(wbuf, 0, wbuf.Length);
            W.Close();

            response.StatusCode = 200;
            response.StatusData = "OK";
            response.AddTag("Content-Type", "text/xml; charset=\"utf-8\"");
            response.AddTag("EXT", "");
            response.AddTag("Server", "Windows NT/5.0, UPnP/1.0");
            response.BodyBuffer = wbuf;
            return (response);
        }
Пример #11
0
 private void HeaderHandler(OpenSource.UPnP.UPnPDevice sender, OpenSource.UPnP.HTTPMessage msg, OpenSource.UPnP.HTTPSession WebSession, string VirtualDir)
 {
     msg.AddTag("transferMode.dlna.org", "Streaming");
     msg.AddTag("contentFeatures.dlna.org", "DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000");
 }
        public override void Start(UPnPDevice device)
        {
            if(!Enabled) return;

            UPnPDevice dv = device;
            while(dv.ParentDevice!=null)
            {
                dv = dv.ParentDevice;
            }

            state = UPnPTestStates.Running;
            UPnPService[] _S = device.GetServices("urn:");

            foreach(UPnPService s in _S)
            {
                bool ok = false;
                foreach(UPnPStateVariable v in s.GetStateVariables())
                {
                    if(v.SendEvent)
                    {
                        ok = true;
                        break;
                    }
                }
                if(ok)
                {

                    UPnPDebugObject d = new UPnPDebugObject(s);
                    Uri EventUri = new Uri((string)d.GetField("__eventurl"));

                    IPEndPoint dest = new IPEndPoint(IPAddress.Parse(EventUri.Host),EventUri.Port);
                    HTTPMessage R = new HTTPMessage();
                    R.Directive = "SUBSCRIBE";
                    R.DirectiveObj = HTTPMessage.UnEscapeString(EventUri.PathAndQuery);
                    R.AddTag("Host",dest.ToString());
                    R.AddTag("Callback","<http://" + dv.InterfaceToHost.ToString()+ ":" + NetworkInfo.GetFreePort(10000,50000,dv.InterfaceToHost).ToString() + ">");
                    //R.AddTag("Callback","<http://127.0.0.1:55555>");
                    R.AddTag("NT","upnp:event");
                    R.AddTag("Timeout","Second-15");

                    System.Console.WriteLine(R.GetTag("Callback"));

                    MRE.Reset();
                    SID = "";
                    StartCountDown(30);
                    HTTPRequest rq = new HTTPRequest();
                    rq.OnResponse += new HTTPRequest.RequestHandler(SubscribeSink);

                    AddHTTPMessage(R);

                    rq.PipelineRequest(dest,R,s);
                    MRE.WaitOne(30000,false);
                    AbortCountDown();

                    if (SID=="")
                    {
                        AddEvent(LogImportance.Critical,"Subscribe","SUBSCRIBE: " + s.ServiceURN + " << FAILED >>");
                        AddEvent(LogImportance.Remark,"Subscribe","Aborting tests");

                        result = "Subscription test failed."; // TODO
                        state = UPnPTestStates.Failed;
                        return;
                    }
                    else
                    {
                        AddEvent(LogImportance.Remark,"Subscribe","SUBSCRIBE: " + s.ServiceURN + " << OK >>");

                        // Renew Test
                        R = new HTTPMessage();
                        R.Directive = "SUBSCRIBE";
                        R.DirectiveObj = HTTPMessage.UnEscapeString(EventUri.PathAndQuery);
                        R.AddTag("Host",dest.ToString());
                        R.AddTag("SID",SID);
                        R.AddTag("Timeout","Second-15");
                        StartCountDown(30);
                        SID = "";
                        MRE.Reset();

                        AddHTTPMessage(R);

                        rq = new HTTPRequest();
                        rq.OnResponse += new HTTPRequest.RequestHandler(SubscribeSink);
                        rq.PipelineRequest(dest,R,s);

                        MRE.WaitOne(30000,false);
                        AbortCountDown();

                        if (SID=="")
                        {
                            AddEvent(LogImportance.Critical,"Subscribe","SUBSCRIBE (Renew): " + s.ServiceURN + " << FAILED >>");
                            AddEvent(LogImportance.Remark,"Subscribe","Aborting tests");

                            result = "Subscription test failed."; // TODO
                            state = UPnPTestStates.Failed;
                            return;
                        }
                        else
                        {
                            AddEvent(LogImportance.Remark,"Subscribe","SUBSCRIBE (Renew): " + s.ServiceURN + " << OK >>");

                            // Cancel
                            R = new HTTPMessage();
                            R.Directive = "UNSUBSCRIBE";
                            R.DirectiveObj = HTTPMessage.UnEscapeString(EventUri.PathAndQuery);
                            R.AddTag("Host",dest.ToString());
                            R.AddTag("SID",SID);

                            StartCountDown(30);
                            SID = "";
                            MRE.Reset();
                            rq = new HTTPRequest();
                            rq.OnResponse += new HTTPRequest.RequestHandler(CancelSink);

                            AddHTTPMessage(R);

                            rq.PipelineRequest(dest,R,s);

                            MRE.WaitOne(30000,false);
                            AbortCountDown();

                            if (SID=="")
                            {
                                AddEvent(LogImportance.Critical,"Subscribe","UNSUBSCRIBE: " + s.ServiceURN + " << FAILED >>");
                                AddEvent(LogImportance.Remark,"Subscribe","Aborting tests");

                                result = "Subscription test failed.";
                                state = UPnPTestStates.Failed;
                                return;
                            }
                            else
                            {
                                AddEvent(LogImportance.Remark,"Subscribe","UNSUBSCRIBE: " + s.ServiceURN + " << OK >>");
                            }

                            /* Test for duplicate SID
                             * as well as initial events */

                            EventTable.Clear();
                            NumEvents = 0;
                            foreach(UPnPStateVariable V in s.GetStateVariables())
                            {
                                if(V.SendEvent)
                                {
                                    ++ NumEvents;
                                    EventTable[V.Name] = false;
                                    V.OnModified -= new UPnPStateVariable.ModifiedHandler(StateVarModifiedSink);
                                    V.OnModified += new UPnPStateVariable.ModifiedHandler(StateVarModifiedSink);
                                }
                            }
                            if(EventTable.Count>0)
                            {
                                MRE.Reset();
                                s.OnSubscribe -= new UPnPService.UPnPEventSubscribeHandler(OnSubscribeSink);
                                s.OnSubscribe += new UPnPService.UPnPEventSubscribeHandler(OnSubscribeSink);
                                s.UnSubscribe(null);
                                foreach(UPnPStateVariable V in s.GetStateVariables())
                                {
                                    V.Clear();
                                }
                                s.Subscribe(120,null);
                                MRE.WaitOne(30000,false);
                                if(SID=="")
                                {
                                    // Subscribe Failed
                                    AddEvent(LogImportance.Critical,"Subscribe","SUBSCRIBE(2): " + s.ServiceURN + " << FAILED >>");
                                    AddEvent(LogImportance.Remark,"Subscribe","Aborting tests");

                                    result = "Subscription test failed.";
                                    state = UPnPTestStates.Failed;
                                    return;
                                }
                                else
                                {
                                    if(SID==null)
                                    {
                                        // Duplicate SID
                                        // Subscribe Failed
                                        AddEvent(LogImportance.Critical,"Subscribe","SUBSCRIBE(2): " + s.ServiceURN + " << FAILED, duplicate SID >>");
                                        AddEvent(LogImportance.Remark,"Subscribe","Aborting tests");

                                        result = "Subscription test failed.";
                                        state = UPnPTestStates.Failed;
                                        return;
                                    }
                                    else
                                    {
                                        // Check Hashtable
                                        IDictionaryEnumerator de = EventTable.GetEnumerator();
                                        bool OK = true;
                                        while(de.MoveNext())
                                        {
                                            if((bool)de.Value==false)
                                            {
                                                // No Event Received
                                                OK = false;
                                                AddEvent(LogImportance.Critical,"Subscribe","   StateVariable: " + (string)de.Key + " >> Event NOT received");
                                            }
                                            else
                                            {
                                                // OK
                                                AddEvent(LogImportance.Remark,"Subscribe","   StateVariable: " + (string)de.Key + " >> Event OK");
                                            }
                                        }
                                        if(OK==false)
                                        {
                                            AddEvent(LogImportance.Critical,"Subscribe","SUBSCRIBE(2): " + s.ServiceURN + " << FAILED, Did not receive all events >>");
                                            AddEvent(LogImportance.Remark,"Subscribe","Aborting tests");

                                            result = "Subscription test failed.";
                                            state = UPnPTestStates.Failed;
                                            return;
                                        }
                                    }
                                }
                            }
                        }

                    }
                }
            }

            result = "Subscribe Tests OK";
            state = UPnPTestStates.Pass;
        }
        /// <summary>
        /// Method executes when a control point invokes the ContentDirectory.ImportResource action.
        /// The method first checks to see if the local URI actually maps to an automapped file
        /// and that the remote URI is an HTTP resource.
        /// The method then asks upper software layers to accept or reject the request to
        /// import a resource from a remote URI to a local URI. Upper software layers reject the request by throwing an exception,
        /// preferably a UPnPCustomException. If the request was approved by upper layers,
        /// then we do a bunch of stuff that results in the file getting transferred over HTTP.
        /// </summary>
        /// <param name="SourceURI">the URI where the binary should be obtained</param>
        /// <param name="DestinationURI">the URI (that can map to a local file) where the binary should be stored</param>
        /// <param name="TransferID">Returns ID for the file transfer.</param>
        private void SinkCd_ImportResource(System.Uri SourceURI, System.Uri DestinationURI, out System.UInt32 TransferID)
        {
            string objectID, resourceID;

            // Parse the media and resource IDs from the destination uri.
            this.GetObjectResourceIDS(DestinationURI, out objectID, out resourceID);

            if ((objectID == "") || (resourceID == ""))
            {
                throw new Error_NoSuchResource(DestinationURI.ToString());
            }
            else
            {
                // TODO: Might consider throwing ane xception in the
                // rare case that stupid ass control point says to
                // download to a different media server.
            }

            // ensure that we're doing http
            if (SourceURI.Scheme.ToLower().StartsWith("http") == false)
            {
                throw new Error_NonHttpImport(DestinationURI.ToString());
            }

            // get the resource object associated with the destination uri
            IDvResource res = this.GetResource(objectID, resourceID);

            // request application logic to approve the binary transfer;
            // Application logic should throw an exception to rject the request.
            if (this.OnRequestSaveBinary != null)
            {
                this.OnRequestSaveBinary(this, res);
            }
            else
            {
                throw new Error_InvalidServerConfiguration("ImportResource() cannot be supported until the vendor configures the server correctly.");
            }

            //
            // Grab the file through http-get
            //

            IPAddress addr = null;
            IPHostEntry ihe = null;
            IPEndPoint dest = null;

            // Attempt to get a routeable IP address for the request

            try
            {
                if(SourceURI.HostNameType == UriHostNameType.Dns)
                {
                    ihe = Dns.GetHostByName(SourceURI.Host);
                    addr = new IPAddress(ihe.AddressList[0].Address);
                }
                else
                {
                    addr = IPAddress.Parse(SourceURI.Host);
                }
            }
            catch
            {
                throw new Error_ConnectionProblem("Could parse or resolve the SourceURI IP address represented by" +SourceURI.ToString());
            }

            dest = new IPEndPoint(addr, SourceURI.Port);

            // Open a socket and connect to the remote IP address and port

            System.Net.Sockets.Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                s.Connect(dest);
            }
            catch
            {
                throw new Error_ConnectionProblem("Could not connect to the remote URI " + DestinationURI.ToString());
            }

            // Do a check to make sure we're not dumping to a directory.

            string filename = res.ContentUri.Substring(MediaResource.AUTOMAPFILE.Length);
            if (Directory.Exists(filename))
            {
                throw new Error_ImportError("System error. Resource has been mapped incorrectly. Cannot overwrite a directory with a binary.");
            }

            // Create an HTTP session for this socket.
            // Set things up so that the HTTP-GET will automatically dump
            // the body of the message into a binary file that has
            // been automatically mapped.

            HTTPSession session = new HTTPSession(s, null, null);
            this.SetupSessionForTransfer(session);
            session.OnHeader += new HTTPSession.ReceiveHeaderHandler(this.GetRequest_OnHeaderReceiveSink);
            try
            {
                session.UserStream = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
            }
            catch
            {
                throw new Error_ImportError("System busy. Could not open file from local system for writing.");
            }

            if (session.UserStream == null)
            {
                throw new Error_ImportError("System error. Cannot write to a null stream.");
            }

            SessionData sd = (SessionData) session.StateObject;
            sd.HttpVer1_1 = false;

            // Create the HTTP message that will request the binary.

            HTTPMessage msg = new HTTPMessage();
            msg.Directive = "GET";
            msg.DirectiveObj = HTTPMessage.UnEscapeString(SourceURI.PathAndQuery);
            msg.AddTag("HOST", dest.ToString());
            msg.Version = "1.0";

            // Create an HttpTransfer object that will represent the progress
            // of this file transfer and add it to the media server's current
            // transfers list.

            long expectedLength = 0;
            HttpTransfer transferInfo = new HttpTransfer(true, true, session, res, session.UserStream, expectedLength);
            this.AddTransfer(session, transferInfo);
            TransferID = transferInfo.m_TransferId;

            // Go make the request for the file.
            session.Send(msg);

            this.m_Stats.ImportResource++;
            this.FireStatsChange();
        }
        /// <summary>
        /// This method is called by <see cref="MediaServerDevice.WebServer_OnPacketReceiveSink"/>
        /// and handles the HTTP-GET or HTTP-GET message requests and provides
        /// the appropriate response. In either case, the handler is intended
        /// to handle requests for resource URIs that have been mapped to local
        /// files using the <see cref="MediaResource.AUTOMAPFILE"/> convention.
        /// <para>
        /// If a resource cannot be mapped to a local file, 
        /// then the method will ask upper-layer application logic 
        /// for a stream object to send in response to the request.
        /// This is used primarily in scenarios where the application intentionally
        /// specified a contentUri value for a resource that uses the 
        /// <see cref="MediaResource.AUTOMAPFILE"/> convention but doesn't
        /// actually map to a local file. This gives the upper application layer
        /// to provide transcoded stream objects or some specialized file stream
        /// that is not stored on the local file system.
        /// </para>
        /// <para>
        /// Upper application layers can always opt to leave the stream object
        /// blank, effectively indicating that the HTTP-GET or head request 
        /// cannot be handled because such a file does not exist.
        /// </para>
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="session"></param>
        private void HandleGetOrHeadRequest(HTTPMessage msg, HTTPSession session)
        {
            // Format of DirectiveObj will be
            // "/[res.m_ResourceID]/[item.ID]/[item.Title].[ext]"
            // We want the
            bool is404 = true;
            Exception problem = null;

            string resourceID = null;
            string objectID = null;

            try
            {
                DText DirectiveParser = new DText();
                DirectiveParser.ATTRMARK = "/";

                DirectiveParser[0] = msg.DirectiveObj;
                resourceID = DirectiveParser[2];
                objectID = DirectiveParser[3];
                IDvResource res = this.GetResource(objectID, resourceID);

                if (res == null)
                {
                    throw new Error_GetRequestError(msg.DirectiveObj, null);
                }
                else
                {
                    // attempt to figure otu the local file path and the mime type
                    string f = MediaResource.AUTOMAPFILE;
                    string fileName = res.ContentUri.Substring(f.Length);
                    string type = res.ProtocolInfo.MimeType;

                    if ((type == null) || (type == "") || (type == "*"))
                    {
                        //content-type not known, programmer
                        //that built content-hierarchy didn't provide one

                        throw new Error_GetRequestError(msg.DirectiveObj, res);
                    }
                    else
                    {
                        // must be a get or head request

                        // check if the file actually exists
                        if (Directory.Exists(fileName))
                        {
                            throw new Error_GetRequestError(msg.DirectiveObj, res);
                        }

                        FileNotMapped mapping = new FileNotMapped();
                        mapping.RequestedResource = res;
                        mapping.LocalInterface = session.Source.ToString();
                        mapping.RedirectedStream = null;
                        if (File.Exists(fileName))
                        {
                            // the file exists, so go ahead and send it
                            mapping.RedirectedStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                        }
                        else
                        {
                            try
                            {
                                // the file doesn't exist but the owner of this
                                // server specified some kind of locally mapped file
                                // so perhaps they may want to route a stream object themselves
                                if (this.OnFileNotMapped != null)
                                {
                                    this.OnFileNotMapped (this, mapping);
                                }
                            }
                            catch (Exception ofnm)
                            {
                                mapping.RedirectedStream = null;
                            }
                        }

                        // if the RedirectedStream is blank, then it means
                        // no stream can be sent in response to the request

                        if (mapping.RedirectedStream != null)
                        {
                            lock (session)
                            {
                                // get the intended length, if known
                                long expectedLength = -1;
                                if (mapping.OverrideRedirectedStreamLength)
                                {
                                    expectedLength = mapping.ExpectedStreamLength;
                                }
                                else
                                {
                                    expectedLength = mapping.RedirectedStream.Length;
                                }

                                if (String.Compare(msg.Directive, "HEAD", true) == 0)
                                {
                                    // must be a head request - reply with 200/OK, content type, content length
                                    HTTPMessage head = new HTTPMessage();
                                    head.StatusCode = 200;
                                    head.StatusData = "OK";
                                    head.ContentType = type;
                                    if (expectedLength >= 0)
                                    {
                                        // if we can calculate the length,
                                        // then we provide a content-length and
                                        // also indicate that range requests can be
                                        // handled.

                                        head.OverrideContentLength = true;

                                        string rangeStr = msg.GetTag("RANGE");
                                        if ((rangeStr == null) || (rangeStr == ""))
                                        {
                                            head.AddTag("CONTENT-LENGTH", expectedLength.ToString());
                                            head.AddTag("ACCEPT-RANGES", "bytes");
                                        }
                                        else
                                        {
                                            ArrayList rangeSets = new ArrayList();
                                            head.StatusCode = 206;
                                            AddRangeSets(rangeSets, rangeStr.Trim().ToLower(), expectedLength);
                                            if (rangeSets.Count == 1)
                                            {
                                                head.AddTag("Content-Range", "bytes " + ((HTTPSession.Range)(rangeSets[0])).Position.ToString() + "-" + ((int)(((HTTPSession.Range)(rangeSets[0])).Position+((HTTPSession.Range)(rangeSets[0])).Length-1)).ToString() + "/" + expectedLength.ToString());
                                                head.AddTag("Content-Length", ((HTTPSession.Range)(rangeSets[0])).Length.ToString());
                                            }
                                        }
                                    }
                                    else
                                    {
                                        // can't calculate length => can't do range
                                        head.AddTag("ACCEPT-RANGES", "none");
                                    }
                                    session.Send(head);
                                    is404 = false;
                                }
                                else
                                {
                                    ArrayList rangeSets = new ArrayList();
                                    string rangeStr = msg.GetTag("RANGE");

                                    // Only allow range requests for content where we have the
                                    // entire length and also only for requests that have
                                    // also provided an allowed range.
                                    if ((rangeStr == null) || (rangeStr != ""))
                                    {
                                        if (expectedLength >= 0)
                                        {
                                            // validate the requested ranges; if invalid range
                                            // found, send the entire document...
                                            AddRangeSets(rangeSets, rangeStr.Trim().ToLower(), expectedLength);
                                        }
                                    }

                                    // must be a get request
                                    // create an outgoing transfer that is not visible to UPNP
                                    // GetTransferProgress method, and add the transfer
                                    HttpTransfer transferInfo = new HttpTransfer(false, false, session, res, mapping.RedirectedStream, expectedLength);
                                    this.AddTransfer(session, transferInfo);

                                    if (rangeSets.Count > 0)
                                    {
                                        session.SendStreamObject(mapping.RedirectedStream, (HTTPSession.Range[])rangeSets.ToArray(typeof(HTTPSession.Range)), type);
                                    }
                                    else
                                    {
                                        //start from the beginning
                                        mapping.RedirectedStream.Seek(0, SeekOrigin.Begin);
                                        if (expectedLength >= 0)
                                        {
                                            session.SendStreamObject(mapping.RedirectedStream, expectedLength, type);
                                        }
                                        else
                                        {
                                            session.SendStreamObject(mapping.RedirectedStream, type);
                                        }
                                    }
                                    is404 = false;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception error)
            {
                problem = error;
            }

            if (is404)
            {
                StringBuilder sb = new StringBuilder();

                sb.Append("File not found.");
                sb.AppendFormat("\r\n\tRequested: \"{0}\"", msg.DirectiveObj);

                if (objectID != null)
                {
                    sb.AppendFormat("\r\n\tObjectID=\"{0}\"", objectID);
                }

                if (resourceID != null)
                {
                    sb.AppendFormat("\r\n\tResourceID=\"{0}\"", resourceID);
                }

                Error_GetRequestError getHeadError = problem as Error_GetRequestError;

                if (getHeadError != null)
                {
                    sb.Append("\r\n");

                    IUPnPMedia mobj = this._GetEntry(objectID);

                    if (mobj == null)
                    {
                        sb.AppendFormat("\r\n\tCould not find object with ID=\"{0}\"", objectID);
                    }
                    else
                    {
                        sb.AppendFormat("\r\n\tFound object with ID=\"{0}\"", objectID);
                        sb.Append("\r\n---Metadata---\r\n");
                        sb.Append(mobj.ToDidl());
                    }

                    sb.Append("\r\n");

                    if (getHeadError.Resource == null)
                    {
                        sb.Append("\r\n\tResource is null.");
                    }
                    else
                    {
                        sb.Append("\r\n\tResource is not null.");

                        string uri = getHeadError.Resource.ContentUri;
                        if (uri== null)
                        {
                            sb.Append("\r\n\t\tContentUri of resource is null.");
                        }
                        else if (uri == "")
                        {
                            sb.Append("\r\n\t\tContentUri of resource is empty.");
                        }
                        else
                        {
                            sb.AppendFormat("\r\n\t\tContentUri of resource is \"{0}\"", uri);
                        }
                    }
                }

                if (problem != null)
                {
                    sb.Append("\r\n");

                    Exception e = problem;
                    sb.Append("\r\n!!! Exception information !!!");

                    while (e != null)
                    {
                        sb.AppendFormat("\r\nMessage=\"{0}\".\r\nStackTrace=\"{1}\"", e.Message, e.StackTrace);

                        e = e.InnerException;
                        if (e != null)
                        {
                            sb.Append("\r\n---InnerException---");
                        }
                    }
                }

                // file has not been found so return a valid HTTP 404 error message
                HTTPMessage error = new HTTPMessage();
                error.StatusCode = 404;
                error.StatusData = "File not found";
                error.StringBuffer = sb.ToString();
                session.Send(error);
            }
        }
        private HTTPMessage[] MSEARCH(UPnPDevice device)
        {
            ArrayList PacketList = new ArrayList();
            foreach (UPnPDevice d in device.EmbeddedDevices)
            {
                foreach (HTTPMessage m in MSEARCH(d))
                {
                    PacketList.Add(m);
                }
            }

            HTTPMessage rq;
            rq = new HTTPMessage();
            rq.Directive = "M-SEARCH";
            rq.DirectiveObj = "*";
            rq.AddTag("MX", "5");
            rq.AddTag("ST", "uuid:" + device.UniqueDeviceName);
            rq.AddTag("Host", "239.255.255.250:1900");
            rq.AddTag("MAN", "\"ssdp:discover\"");
            PacketList.Add(rq);

            rq = new HTTPMessage();
            rq.Directive = "M-SEARCH";
            rq.DirectiveObj = "*";
            rq.AddTag("MX", "5");
            rq.AddTag("ST", device.DeviceURN);
            rq.AddTag("Host", "239.255.255.250:1900");
            rq.AddTag("MAN", "\"ssdp:discover\"");
            PacketList.Add(rq);

            foreach (UPnPService s in device.Services)
            {
                rq = new HTTPMessage();
                rq.Directive = "M-SEARCH";
                rq.DirectiveObj = "*";
                rq.AddTag("MX", "5");
                rq.AddTag("ST", s.ServiceURN);
                rq.AddTag("Host", "239.255.255.250:1900");
                rq.AddTag("MAN", "\"ssdp:discover\"");
                PacketList.Add(rq);
            }

            return ((HTTPMessage[])PacketList.ToArray(typeof(HTTPMessage)));
        }
Пример #16
0
        private void BuildByePacket2(ArrayList ByeList, IPAddress local)
        {
            HTTPMessage msg;

            for (int id = 0; id < Services.Length; ++id)
            {
                msg = new HTTPMessage();
                msg.Directive = "NOTIFY";
                msg.DirectiveObj = "*";
                msg.AddTag("Host", Utils.GetMulticastAddrBraketPort(local));
                msg.AddTag("NT", Services[id].ServiceURN);
                msg.AddTag("NTS", "ssdp:byebye");
                msg.AddTag("USN", "uuid:" + UniqueDeviceName + "::" + Services[id].ServiceURN);
                ByeList.Add(msg);
            }
            msg = new HTTPMessage();
            msg.Directive = "NOTIFY";
            msg.DirectiveObj = "*";
            msg.AddTag("Host", Utils.GetMulticastAddrBraketPort(local));
            msg.AddTag("NT", DeviceURN);
            msg.AddTag("NTS", "ssdp:byebye");
            msg.AddTag("USN", "uuid:" + UniqueDeviceName + "::" + DeviceURN);
            ByeList.Add(msg);

            msg = new HTTPMessage();
            msg.Directive = "NOTIFY";
            msg.DirectiveObj = "*";
            msg.AddTag("Host", Utils.GetMulticastAddrBraketPort(local));
            msg.AddTag("NT", "uuid:" + UniqueDeviceName);
            msg.AddTag("NTS", "ssdp:byebye");
            msg.AddTag("USN", "uuid:" + UniqueDeviceName);
            ByeList.Add(msg);
        }
        private void Validate_DISCOVERY()
        {
            //Test all types of M-SEARCH, both valid and invalid
            MSEARCHTable.Clear();
            ASocket.OnReceive -= new AsyncSocket.OnReceiveHandler(ReceiveSink);
            ASocket.OnReceive += new AsyncSocket.OnReceiveHandler(MSEARCHSink);

            HTTPMessage rq = new HTTPMessage();
            byte[] rbuf;
            IPEndPoint d = new IPEndPoint(IPAddress.Parse("239.255.255.250"), 1900);
            rq.Directive = "M-SEARCH";
            rq.DirectiveObj = "*";
            rq.AddTag("MX", "5");
            rq.AddTag("Host", "239.255.255.250:1900");
            rq.AddTag("MAN", "\"ssdp:discover\"");
            rq.AddTag("ST", "ssdp:all");
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(0, 91);
            MRE.WaitOne(8000, false);
            AbortCountDown();

            if (MSEARCHTable.ContainsKey("upnp:rootdevice"))
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<ssdp:all / upnp:rootdevice>> OK");
            }
            else
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.Critical, "Discovery", "MSEARCH <<ssdp:all / upnp:rootdevice>> MISSING");
            }

            foreach (HTTPMessage m in MSEARCH(TestDevice))
            {
                if (MSEARCHTable.ContainsKey(m.GetTag("ST").Trim()))
                {
                    AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<ssdp:all / " + m.GetTag("ST").Trim() + ">> OK");
                }
                else
                {
                    DISCOVERY = UPnPTestStates.Failed;
                    AddEvent(LogImportance.Critical, "Discovery", "MSEARCH <<ssdp:all / " + m.GetTag("ST").Trim() + ">> MISSING");
                }
            }

            // Test MSEARCH upnp:rootdevice, and others
            MSEARCHTable.Clear();
            rq.AddTag("ST", "upnp:rootdevice");
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            foreach (HTTPMessage m in MSEARCH(TestDevice))
            {
                this.sample2 += "\r\n\r\n" + m.StringPacket;
                ASocket.Send(m.RawPacket, 0, m.RawPacket.Length, d);
            }
            MRE.Reset();
            StartCountDown(8, 91);
            MRE.WaitOne(8000, false);
            AbortCountDown();
            ASocket.OnReceive -= new AsyncSocket.OnReceiveHandler(MSEARCHSink);

            if (MSEARCHTable.ContainsKey("upnp:rootdevice"))
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<upnp:rootdevice>> OK");
            }
            else
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.Critical, "Discovery", "MSEARCH <<upnp:rootdevice>> MISSING");
            }

            foreach (HTTPMessage m in MSEARCH(TestDevice))
            {
                if (MSEARCHTable.ContainsKey(m.GetTag("ST").Trim()))
                {
                    AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<" + m.GetTag("ST").Trim() + ">> OK");
                }
                else
                {
                    DISCOVERY = UPnPTestStates.Failed;
                    AddEvent(LogImportance.Critical, "Discovery", "MSEARCH <<" + m.GetTag("ST").Trim() + ">> MISSING");
                }
            }

            // Test Invalid MSEARCHes
            string ST = "";
            MSEARCHTable.Clear();
            ASocket.OnReceive += new AsyncSocket.OnReceiveHandler(BadMSEARCHSink);
            rq = new HTTPMessage();
            rq.Directive = "M-SEARCH";
            rq.DirectiveObj = "*";
            rq.AddTag("MX", "2");
            rq.AddTag("Host", "239.255.255.250:1900");
            rq.AddTag("MAN", "\"ssdp:discover\"");
            rq.AddTag("ST", "uuid:___" + TestDevice.UniqueDeviceName + "___");
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(16, 91);
            MRE.WaitOne(5000, false);
            AbortCountDown();
            if (MSEARCHTable.Count != 0)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "MSEARCH <<NonExistent UDN>> Unexpected Response");
            }
            else
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<NonExistent UDN>> OK");
            }
            MSEARCHTable.Clear();

            ST = TestDevice.DeviceURN;
            int i = ST.LastIndexOf(":");
            if (i == -1)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "Can't parse DeviceURN");
                return;
            }
            ST = ST.Substring(0, i);
            ST = ST + ":" + ((int)(int.Parse(TestDevice.Version) + 5)).ToString();
            rq.AddTag("ST", ST);
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(21, 91);
            MRE.WaitOne(5000, false);
            AbortCountDown();
            if (MSEARCHTable.Count != 0)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "MSEARCH <<Existing Device Type, Bad Version>> Unexpected Response");
            }
            else
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<Existing Device Type, Bad Version>> OK");
            }
            MSEARCHTable.Clear();

            UPnPService _S = FetchAService(TestDevice);
            ST = _S.ServiceURN;
            ST = ST.Substring(0, ST.LastIndexOf(":"));
            ST = ST + ":" + ((int)(int.Parse(_S.Version) + 5)).ToString();
            rq.AddTag("ST", ST);
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(26, 91);
            MRE.WaitOne(5000, false);
            AbortCountDown();
            if (MSEARCHTable.Count != 0)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "MSEARCH <<Existing Service Type, Bad Version>> Unexpected Response");
            }
            else
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<Existing Service Type, Bad Version>> OK");
            }

            // Test MSEARCH No *
            MSEARCHTable.Clear();
            rq = new HTTPMessage();
            rq.Directive = "M-SEARCH";
            rq.DirectiveObj = "";
            rq.AddTag("MX", "2");
            rq.AddTag("Host", "239.255.255.250:1900");
            rq.AddTag("MAN", "\"ssdp:discover\"");
            rq.AddTag("ST", "upnp:rootdevice");
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(31, 91);
            MRE.WaitOne(5000, false);
            AbortCountDown();
            if (MSEARCHTable.Count != 0)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "MSEARCH <<No *>> Unexpected Response");
            }
            else
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<No *>> OK");
            }

            MSEARCHTable.Clear();
            rq.DirectiveObj = "/";
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(36, 91);
            MRE.WaitOne(5000, false);
            AbortCountDown();
            if (MSEARCHTable.Count != 0)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "MSEARCH <<Not *>> Unexpected Response");
            }
            else
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<Not *>> OK");
            }

            MSEARCHTable.Clear();
            rq = new HTTPMessage();
            rq.Directive = "M-SEARCH";
            rq.DirectiveObj = "";
            rq.AddTag("MX", "2");
            rq.AddTag("Host", "239.255.255.250:1900");
            rq.AddTag("MAN", "\"ssdp:discover\"");
            rq.AddTag("ST", "upnp:rootdevice");
            rq.Version = "1.0";
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(41, 91);
            MRE.WaitOne(5000, false);
            AbortCountDown();
            if (MSEARCHTable.Count != 0)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "MSEARCH <<Version = 1.0>> Unexpected Response");
            }
            else
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<Version = 1.0>> OK");
            }

            MSEARCHTable.Clear();
            rq.DirectiveObj = "*";
            rq.Version = "";
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(46, 91);
            MRE.WaitOne(5000, false);
            AbortCountDown();
            if (MSEARCHTable.Count != 0)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "MSEARCH <<No Version>> Unexpected Response");
            }
            else
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<No Version>> OK");
            }

            MSEARCHTable.Clear();
            rq.Version = "1.1";
            rq.RemoveTag("MAN");
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(51, 91);
            MRE.WaitOne(5000, false);
            AbortCountDown();
            if (MSEARCHTable.Count != 0)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "MSEARCH <<No MAN>> Unexpected Response");
            }
            else
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<No MAN>> OK");
            }

            MSEARCHTable.Clear();
            rq.AddTag("MAN", "\"ssdp:discover\"");
            rq.RemoveTag("MX");
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(56, 91);
            MRE.WaitOne(5000, false);
            AbortCountDown();
            if (MSEARCHTable.Count != 0)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "MSEARCH <<No MX>> Unexpected Response");
            }
            else
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<No MX>> OK");
            }

            MSEARCHTable.Clear();
            rq.AddTag("MX", "");
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(61, 91);
            MRE.WaitOne(5000, false);
            AbortCountDown();
            if (MSEARCHTable.Count != 0)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "MSEARCH <<MX Empty>> Unexpected Response");
            }
            else
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<MX Empty>> OK");
            }

            MSEARCHTable.Clear();
            rq.AddTag("MX", "Z");
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(66, 91);
            MRE.WaitOne(5000, false);
            AbortCountDown();
            if (MSEARCHTable.Count != 0)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "MSEARCH <<MX Not Integer>> Unexpected Response");
            }
            else
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<MX Not Integer>> OK");
            }

            MSEARCHTable.Clear();
            rq.AddTag("MX", "-1");
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(71, 91);
            MRE.WaitOne(5000, false);
            AbortCountDown();
            if (MSEARCHTable.Count != 0)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "MSEARCH <<MX Negative>> Unexpected Response");
            }
            else
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<MX Negative>> OK");
            }

            MSEARCHTable.Clear();
            rq.AddTag("MX", "2");
            rq.RemoveTag("ST");
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(76, 91);
            MRE.WaitOne(5000, false);
            AbortCountDown();
            if (MSEARCHTable.Count != 0)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "MSEARCH <<No ST>> Unexpected Response");
            }
            else
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<No ST>> OK");
            }

            MSEARCHTable.Clear();
            rq.AddTag("ST", "");
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(81, 91);
            MRE.WaitOne(5000, false);
            AbortCountDown();
            if (MSEARCHTable.Count != 0)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "MSEARCH <<ST Empty>> Unexpected Response");
            }
            else
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<ST Empty>> OK");
            }

            MSEARCHTable.Clear();
            rq.AddTag("ST", "ABCDEFG");
            rbuf = rq.RawPacket;
            ASocket.Send(rbuf, 0, rbuf.Length, d);
            MRE.Reset();
            StartCountDown(86, 91);
            MRE.WaitOne(5000, false);
            AbortCountDown();
            if (MSEARCHTable.Count != 0)
            {
                DISCOVERY = UPnPTestStates.Failed;
                AddEvent(LogImportance.High, "Discovery", "MSEARCH <<ST Invalid>> Unexpected Response");
            }
            else
            {
                AddEvent(LogImportance.Remark, "Discovery", "MSEARCH <<ST Invalid>> OK");
            }

            SetState("Discovery", DISCOVERY);
            if (DISCOVERY == UPnPTestStates.Pass)
            {
                Results.Add("Discovery mechanism OK");
            }
            else
            {
                Results.Add("Discovery mechanism is not behaving correctly");
            }
        }
Пример #18
0
        private HTTPMessage[] BuildNotifyPacket(IPAddress local)
        {
            ArrayList NotifyList = new ArrayList();
            IPEndPoint localep = null;
            HTTPMessage msg;

            try
            {
                localep = ((MiniWebServer)WebServerTable[local.ToString()]).LocalIPEndPoint;
            }
            catch (Exception ex)
            {
                OpenSource.Utilities.EventLogger.Log(ex);
                return (new HTTPMessage[0]);
            }
            String BaseURL;
            if (localep.AddressFamily == AddressFamily.InterNetworkV6)
            {
                string ipaddr = localep.Address.ToString();
                int i = ipaddr.IndexOf("%");
                if (i > 0)
                    ipaddr = ipaddr.Substring(0, i);
                BaseURL = "http://[" + ipaddr + "]:" + localep.Port.ToString() + "/";
            }
            else
            {
                BaseURL = "http://" + localep.Address.ToString() + ":" + localep.Port.ToString() + "/";
            }

            msg = new HTTPMessage();
            msg.Directive = "NOTIFY";
            msg.DirectiveObj = "*";
            msg.AddTag("Host", Utils.GetMulticastAddrBraketPort(local));
            msg.AddTag("NT", "upnp:rootdevice");
            msg.AddTag("NTS", "ssdp:alive");
            msg.AddTag("Location", BaseURL);
            msg.AddTag("USN", "uuid:" + UniqueDeviceName + "::upnp:rootdevice");
            msg.AddTag("Server", "Windows NT/5.0, UPnP/1.0");
            msg.AddTag("Cache-Control", "max-age=" + ExpirationTimeout.ToString());
            NotifyList.Add(msg);

            BuildNotifyPacket2(BaseURL, NotifyList, local);

            foreach (UPnPDevice d in this.EmbeddedDevices)
            {
                d.BuildNotifyPacket2(BaseURL, NotifyList, local);
            }

            return ((HTTPMessage[])NotifyList.ToArray(typeof(HTTPMessage)));
        }
        /// <summary>
        /// Searches for a SearchTarget Asynchronously
        /// </summary>
        /// <param name="SearchTarget">The Target</param>
        public void FindDeviceAsync(String SearchTarget, IPEndPoint RemoteEP)
        {
            HTTPMessage request = new HTTPMessage();

            request.Directive    = "M-SEARCH";
            request.DirectiveObj = "*";
            request.AddTag("ST", SearchTarget);
            request.AddTag("MX", MX.ToString());
            request.AddTag("MAN", "\"ssdp:discover\"");
            if (RemoteEP.AddressFamily == AddressFamily.InterNetwork)
            {
                request.AddTag("HOST", RemoteEP.ToString()); // "239.255.255.250:1900"
            }
            if (RemoteEP.AddressFamily == AddressFamily.InterNetworkV6)
            {
                request.AddTag("HOST", string.Format("[{0}]:{1}", RemoteEP.Address.ToString(), RemoteEP.Port)); // "[FF05::C]:1900"
            }
            byte[] buffer = UTF8Encoding.UTF8.GetBytes(request.StringPacket);

            IPAddress[] LocalAddresses = NetInfo.GetLocalAddresses();

            foreach (IPAddress localaddr in LocalAddresses)
            {
                try
                {
                    UdpClient session = (UdpClient)SSDPSessions[localaddr];
                    if (session == null)
                    {
                        session = new UdpClient(new IPEndPoint(localaddr, 0));
                        session.EnableBroadcast = true;
                        session.BeginReceive(new AsyncCallback(OnReceiveSink), session);
                        SSDPSessions[localaddr] = session;
                    }
                    if (RemoteEP.AddressFamily != session.Client.AddressFamily)
                    {
                        continue;
                    }
                    if ((RemoteEP.AddressFamily == AddressFamily.InterNetworkV6) && ((IPEndPoint)session.Client.LocalEndPoint).Address.IsIPv6LinkLocal == true && RemoteEP != Utils.UpnpMulticastV6EndPoint2)
                    {
                        continue;
                    }
                    if ((RemoteEP.AddressFamily == AddressFamily.InterNetworkV6) && ((IPEndPoint)session.Client.LocalEndPoint).Address.IsIPv6LinkLocal == false && RemoteEP != Utils.UpnpMulticastV6EndPoint1)
                    {
                        continue;
                    }

                    IPEndPoint lep = (IPEndPoint)session.Client.LocalEndPoint;
                    if (session.Client.AddressFamily == AddressFamily.InterNetwork)
                    {
                        session.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, localaddr.GetAddressBytes());
                    }
                    else if (session.Client.AddressFamily == AddressFamily.InterNetworkV6)
                    {
                        session.Client.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.MulticastInterface, BitConverter.GetBytes((int)localaddr.ScopeId));
                    }

                    session.Send(buffer, buffer.Length, RemoteEP);
                    session.Send(buffer, buffer.Length, RemoteEP);
                }
                catch (Exception ex)
                {
                    OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.Error, "CP Failure: " + localaddr.ToString());
                    OpenSource.Utilities.EventLogger.Log(ex);
                }
            }
        }
Пример #20
0
        private void BuildNotifyPacket2(string BaseURL, ArrayList NotifyList, IPAddress local)
        {
            HTTPMessage msg;

            for (int id = 0; id < Services.Length; ++id)
            {
                msg = new HTTPMessage();
                msg.Directive = "NOTIFY";
                msg.DirectiveObj = "*";
                msg.AddTag("Host", Utils.GetMulticastAddrBraketPort(local));
                msg.AddTag("NT", Services[id].ServiceURN);
                msg.AddTag("NTS", "ssdp:alive");
                msg.AddTag("Location", BaseURL);
                msg.AddTag("USN", "uuid:" + UniqueDeviceName + "::" + Services[id].ServiceURN);
                msg.AddTag("Server", "Windows NT/5.0, UPnP/1.0");
                msg.AddTag("Cache-Control", "max-age=" + ExpirationTimeout.ToString());
                NotifyList.Add(msg);
            }
            msg = new HTTPMessage();
            msg.Directive = "NOTIFY";
            msg.DirectiveObj = "*";
            msg.AddTag("Host", Utils.GetMulticastAddrBraketPort(local));
            msg.AddTag("NT", DeviceURN);
            msg.AddTag("NTS", "ssdp:alive");
            msg.AddTag("Location", BaseURL);
            msg.AddTag("USN", "uuid:" + UniqueDeviceName + "::" + DeviceURN);
            msg.AddTag("Server", "Windows NT/5.0, UPnP/1.0");
            msg.AddTag("Cache-Control", "max-age=" + ExpirationTimeout.ToString());
            NotifyList.Add(msg);

            msg = new HTTPMessage();
            msg.Directive = "NOTIFY";
            msg.DirectiveObj = "*";
            msg.AddTag("Host", Utils.GetMulticastAddrBraketPort(local));
            msg.AddTag("NT", "uuid:" + UniqueDeviceName);
            msg.AddTag("NTS", "ssdp:alive");
            msg.AddTag("Location", BaseURL);
            msg.AddTag("USN", "uuid:" + UniqueDeviceName);
            msg.AddTag("Server", "Windows NT/5.0, UPnP/1.0");
            msg.AddTag("Cache-Control", "max-age=" + ExpirationTimeout.ToString());
            NotifyList.Add(msg);
        }
Пример #21
0
        private void ContinueRequest(IPEndPoint dest, string PQ, object Tag, HTTPMessage MSG)
        {
            HTTPMessage r = null;

            if (MSG == null)
            {
                r              = new HTTPMessage();
                r.Directive    = "GET";
                r.DirectiveObj = PQ;
                if (dest.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                {
                    r.AddTag("Host", dest.ToString());
                }
                if (dest.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                {
                    r.AddTag("Host", "[" + RemoveIPv6Scope(dest.ToString()) + "]");
                }
            }
            else
            {
                r = MSG;
            }

            lock (TagQueue)
            {
                this.IdleTimeout = false;
                KeepAliveTimer.Remove(this.GetHashCode());

                LastMessage = r;
                if ((PIPELINE == false && _PIPELINE == false) || (_PIPELINE == false))
                {
                    HTTPRequest TR = new HTTPRequest();
                    TR.ProxySetting = ProxySetting;
                    TR._PIPELINE    = true;
                    if (this.OnSniff != null)
                    {
                        TR.OnSniff += new HTTPRequest.SniffHandler(NonPipelinedSniffSink);
                    }
                    if (this.OnSniffPacket != null)
                    {
                        TR.OnSniffPacket += new HTTPRequest.RequestHandler(NonPipelinedSniffPacketSink);
                    }
                    TR.OnResponse += new HTTPRequest.RequestHandler(NonPipelinedResponseSink);
                    this.NotPipelinedTable[TR] = TR;
                    TR.PipelineRequest(dest, r, Tag);
                    return;
                }

                bool NeedSend = (TagQueue.Count == 0);
                TagQueue.Enqueue(new StateData(r, dest, Tag, null));

                IPAddress localif = IPAddress.Any;
                if (dest.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                {
                    localif = IPAddress.IPv6Any;
                }

                if (s == null)
                {
                    ReceivedFirstResponse = false;
                    if (ProxySetting != null)
                    {
                        s = new HTTPSession(new IPEndPoint(localif, 0),
                                            ProxySetting,
                                            new HTTPSession.SessionHandler(CreateSink),
                                            new HTTPSession.SessionHandler(CreateFailedSink),
                                            null);
                    }
                    else
                    {
                        s = new HTTPSession(new IPEndPoint(localif, 0),
                                            dest,
                                            new HTTPSession.SessionHandler(CreateSink),
                                            new HTTPSession.SessionHandler(CreateFailedSink),
                                            null);
                    }
                }
                else
                {
                    if (s.IsConnected && this.ReceivedFirstResponse)
                    {
                        try
                        {
                            if (ProxySetting == null)
                            {
                                s.Send(r);
                            }
                            else
                            {
                                HTTPMessage pr = (HTTPMessage)r.Clone();
                                pr.DirectiveObj = "http://" + dest.ToString() + pr.DirectiveObj;
                                pr.Version      = "1.0";
                                s.Send(pr);
                            }
                        }
                        catch (Exception ex)
                        {
                            OpenSource.Utilities.EventLogger.Log(ex);
                        }
                    }
                }
            }
        }
Пример #22
0
        private HTTPMessage Get(String GetWhat, IPEndPoint local)
        {
            HTTPMessage msg = new HTTPMessage();

            if (GetWhat == "/")
            {
                msg.StatusCode = 200;
                msg.StatusData = "OK";
                msg.AddTag("Content-Type", "text/xml");
                msg.BodyBuffer = GetRootDeviceXML(local);
                return (msg);
            }
            else
            {
                GetWhat = GetWhat.Substring(1);
            }
            /*
            if ((GetWhat == "icon.png") && (_icon != null))
            {
                lock (_icon)
                {
                    MemoryStream mstm = new MemoryStream();
                    _icon.Save(mstm, System.Drawing.Imaging.ImageFormat.Png);
                    msg.StatusCode = 200;
                    msg.StatusData = "OK";
                    msg.ContentType = "image/png";
                    msg.BodyBuffer = mstm.ToArray();
                    mstm.Close();
                }
                return (msg);
            }

            if ((GetWhat == "favicon.ico") && (_favicon != null))
            {
                lock (_favicon)
                {
                    MemoryStream mstm = new MemoryStream();
                    _favicon.Save(mstm);
                    msg.StatusCode = 200;
                    msg.StatusData = "OK";
                    msg.ContentType = "image/x-icon";
                    msg.BodyBuffer = mstm.ToArray();
                    mstm.Close();
                }
                return (msg);
            }
            */

            bool SCPDok = false;
            for (int id = 0; id < Services.Length; ++id)
            {
                if (GetWhat == Services[id].SCPDFile)
                {
                    SCPDok = true;
                    msg.StatusCode = 200;
                    msg.StatusData = "OK";
                    msg.AddTag("Content-Type", "text/xml");
                    msg.BodyBuffer = Services[id].GetSCPDXml();
                    break;
                }
            }
            if (SCPDok == true)
            {
                return (msg);
            }

            try
            {
                FileStream fs = new FileStream(RootPath + GetWhat, FileMode.Open, FileAccess.Read, FileShare.Read);
                byte[] buffer = new byte[(int)fs.Length];
                fs.Read(buffer, 0, (int)fs.Length);
                fs.Close();
                msg.StatusCode = 200;
                msg.StatusData = "OK";
                String ct = "application/octet-stream";
                if ((GetWhat.EndsWith(".html")) || (GetWhat.EndsWith(".htm")) == true)
                {
                    ct = "text/html";
                }
                else
                {
                    if (GetWhat.EndsWith(".xml") == true)
                    {
                        ct = "text/xml";
                    }
                }
                msg.AddTag("Content-Type", ct);
                msg.BodyBuffer = buffer;
                return (msg);
            }
            catch (Exception ex)
            {
                OpenSource.Utilities.EventLogger.Log(ex);
                throw (new UPnPCustomException(404, "File Not Found"));
            }
        }
Пример #23
0
        /// <summary>
        /// Subscribe to UPnPEvents
        /// </summary>
        /// <param name="Timeout">Subscription Cycle</param>
        public void Subscribe(int Timeout, UPnPEventSubscribeHandler CB)
        {
            bool processSubscribe = false;
            lock (SubscribeLock)
            {
                if (SubscribeCounter == 0) processSubscribe = true;
                ++SubscribeCounter;
                //OnUPnPEvent += UPnPEventCallback;
            }

            if (processSubscribe == false)
            {
                // Already subscribed... Just trigger Events
                foreach (UPnPStateVariable V in this.GetStateVariables()) V.InitialEvent();
                if (CB != null) CB(this, true);
                return;
            }

            foreach (UPnPStateVariable V in this.GetStateVariables())
            {
                if (V.SendEvent) V.CurrentValue = null;
            }

            CurrentTimeout = Timeout;

            HTTPMessage request = new HTTPMessage();
            String WebIP;
            int WebPort;
            String Tag;
            String NT;
            if (Timeout == 0)
            {
                NT = "Second-infinite";
            }
            else
            {
                NT = "Second-" + Timeout.ToString();
            }

            SSDP.ParseURL(this.__eventurl, out WebIP, out WebPort, out Tag);
            IPEndPoint dest = new IPEndPoint(IPAddress.Parse(WebIP), WebPort);
            IPAddress addr = IPAddress.Parse(WebIP);

            request.Directive = "SUBSCRIBE";
            request.DirectiveObj = Tag;
            if (addr.AddressFamily == AddressFamily.InterNetwork)
            {
                request.AddTag("Host", WebIP + ":" + WebPort.ToString());
            }
            else if (addr.AddressFamily == AddressFamily.InterNetworkV6)
            {
                request.AddTag("Host", "[" + RemoveIPv6Scope(addr.ToString()) + "]:" + WebPort.ToString());
            }
            request.AddTag("Callback", "<" + this.EventCallbackURL + ">");
            request.AddTag("NT", "upnp:event");
            request.AddTag("Timeout", NT);

            HTTPRequest SR = new HTTPRequest();
            SubscribeRequestTable[SR] = SR;
            SR.OnResponse += new HTTPRequest.RequestHandler(HandleSubscribeResponse);
            SR.PipelineRequest(dest, request, CB);
        }
Пример #24
0
        private void HandleSearch(String ST, IPEndPoint src, IPEndPoint local)
        {
            if (WebServerTable == null)
                return;
            //if (local == null) local = new IPEndPoint(IPAddress.Loopback, 1234); // DEBUG **********************

            string x = src.Address.ToString();
            ArrayList ResponseList = new ArrayList();
            HTTPMessage msg;
            string Location = null;
            if (local.AddressFamily == AddressFamily.InterNetwork)
            {
                Location = "http://" + local.Address.ToString() + ":" + ((MiniWebServer)WebServerTable[local.Address.ToString()]).LocalIPEndPoint.Port.ToString() + "/";
            }
            if (local.AddressFamily == AddressFamily.InterNetworkV6)
            {
                string xx = local.Address.ToString();
                xx = xx.Substring(0, xx.IndexOf("%"));
                Location = "http://[" + xx + "]:" + ((MiniWebServer)WebServerTable[local.Address.ToString()]).LocalIPEndPoint.Port.ToString() + "/";
            }

            if ((ST == "upnp:rootdevice") || (ST == "ssdp:all"))
            {
                msg = new HTTPMessage();
                msg.StatusCode = 200;
                msg.StatusData = "OK";
                msg.AddTag("ST", "upnp:rootdevice");
                msg.AddTag("USN", "uuid:" + UniqueDeviceName + "::upnp:rootdevice");
                msg.AddTag("Location", Location);
                msg.AddTag("Server", "Windows NT/5.0, UPnP/1.0");
                msg.AddTag("EXT", "");
                msg.AddTag("Cache-Control", "max-age=" + ExpirationTimeout.ToString());
                ResponseList.Add(msg);
            }

            ContainsSearchTarget(ST, Location, ResponseList);

            foreach (HTTPMessage SR in ResponseList)
            {
                try
                {
                    SR.LocalEndPoint = local;
                    SR.RemoteEndPoint = src;
                    SSDPServer.UnicastData(SR);
                }
                catch (SocketException ex)
                {
                    OpenSource.Utilities.EventLogger.Log(ex);
                }
            }
        }
Пример #25
0
        internal void SendEvents(UPnPStateVariable V)
        {
            //IDictionaryEnumerator en = SubscriberTable.GetEnumerator();
            SubscriberInfo sinfo;
            HTTPMessage Packet;
            Uri[] EventURLS;
            ICollection en = SubscriberTable.Keys;
            String[] KEYS = new String[en.Count];
            HTTPRequest R;
            en.CopyTo(KEYS, 0);

            for (int keyid = 0; keyid < KEYS.Length; ++keyid)
            {
                object _tobj = SubscriberTable[KEYS[keyid]];
                if (_tobj != null)
                {
                    sinfo = (SubscriberInfo)_tobj;
                    if ((sinfo.Expires > DateTime.Now.Ticks) || (sinfo.Expires == -1))
                    {
                        EventURLS = ParseEventURL(sinfo.CallbackURL);
                        for (int x = 0; x < EventURLS.Length; ++x)
                        {
                            try
                            {
                                IPAddress dest = IPAddress.Parse(EventURLS[x].Host);

                                Packet = new HTTPMessage();
                                Packet.Directive = "NOTIFY";
                                Packet.AddTag("Content-Type", "text/xml");
                                Packet.AddTag("NT", "upnp:event");
                                Packet.AddTag("NTS", "upnp:propchange");
                                Packet.BodyBuffer = BuildEventXML(new UPnPStateVariable[1] { V });
                                Packet.DirectiveObj = HTTPMessage.UnEscapeString(EventURLS[x].PathAndQuery);
                                if (dest.AddressFamily == AddressFamily.InterNetwork) Packet.AddTag("Host", EventURLS[x].Host + ":" + EventURLS[x].Port.ToString());
                                if (dest.AddressFamily == AddressFamily.InterNetworkV6) Packet.AddTag("Host", "[" + RemoveIPv6Scope(EventURLS[x].Host) + "]:" + EventURLS[x].Port.ToString());
                                Packet.AddTag("SID", sinfo.SID);
                                Packet.AddTag("SEQ", sinfo.SEQ.ToString());
                                Packet.AddTag("CONNECTION", "close");
                                ++sinfo.SEQ;
                                SubscriberTable[KEYS[keyid]] = sinfo;

                                //OpenSource.Utilities.EventLogger.Log(this,System.Diagnostics.EventLogEntryType.SuccessAudit,Packet.StringBuffer);

                                R = new HTTPRequest();
                                SendEventTable[R] = R;
                                R.OnResponse += new HTTPRequest.RequestHandler(HandleSendEvent);
                                R.PipelineRequest(new IPEndPoint(IPAddress.Parse(EventURLS[x].Host), EventURLS[x].Port), Packet, null);
                            }
                            catch (Exception)
                            {
                            }
                        }
                    }
                    else
                    {
                        SubscriberTable.Remove(sinfo.SID);
                    }
                }
            }
        }
Пример #26
0
        private void HandleWebRequest(HTTPMessage msg, HTTPSession WebSession)
        {
            DText parser = new DText();
            HTTPMessage Response = new HTTPMessage();
            HTTPMessage Response2 = null;
            String Method = msg.Directive;
            String MethodData = msg.DirectiveObj;

            if (WebSession.InternalStateObject != null)
            {
                HTTPMessage _msg = (HTTPMessage)msg.Clone();
                object[] state = (object[])WebSession.InternalStateObject;
                _msg.DirectiveObj = (string)state[1];
                VirtualDirectoryHandler t = (VirtualDirectoryHandler)state[2];
                WebSession.InternalStateObject = null;
                t(this, _msg, WebSession, (string)state[0]);
                return;

            }

            if ((Method != "GET") && (Method != "HEAD") && (Method != "POST") &&
                (Method != "SUBSCRIBE") && (Method != "UNSUBSCRIBE") &&
                (Method != "NOTIFY"))
            {
                Response.StatusCode = 405;
                Response.StatusData = Method + " not supported";
                WebSession.Send(Response);
                return; // Other methods are unknown to us
            }

            // Process Headers
            if (Method == "GET" || Method == "HEAD")
            {
                try
                {
                    Response = Get(MethodData, WebSession.Source);
                }
                catch (UPnPCustomException ce)
                {
                    OpenSource.Utilities.EventLogger.Log(ce);
                    Response.StatusCode = ce.ErrorCode;
                    Response.StatusData = ce.ErrorDescription;
                    WebSession.Send(Response);
                    return;
                }
                catch (Exception e)
                {
                    OpenSource.Utilities.EventLogger.Log(e);
                    Response.StatusCode = 500;
                    Response.StatusData = "Internal";
                    Response.StringBuffer = e.ToString();
                }
                if (Method == "HEAD")
                {
                    Response.BodyBuffer = null;
                }
                WebSession.Send(Response);
            }

            if (Method == "POST")
            {
                //InvokerInfo[Thread.CurrentThread.GetHashCode()] = WebSession;
                try
                {
                    Response = Post(MethodData, msg.StringBuffer, msg.GetTag("SOAPACTION"), WebSession);
                }
                catch (DelayedResponseException ex)
                {
                    OpenSource.Utilities.EventLogger.Log(ex);
                    InvokerInfo.Remove(Thread.CurrentThread.GetHashCode());
                    WebSession.StopReading();
                    return;
                }
                catch (UPnPCustomException ce)
                {
                    OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.Error, "UPnP Error [" + ce.ErrorCode.ToString() + "] " + ce.ErrorDescription);
                    Response.StatusCode = 500;
                    Response.StatusData = "Internal";
                    Response.StringBuffer = BuildErrorBody(ce);
                    WebSession.Send(Response);
                    InvokerInfo.Remove(Thread.CurrentThread.GetHashCode());
                    return;
                }
                catch (UPnPInvokeException ie)
                {
                    Response.StatusCode = 500;
                    Response.StatusData = "Internal";
                    if (ie.UPNP != null)
                    {
                        OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.Error, "UPnP Error [" + ie.UPNP.ErrorCode.ToString() + "] " + ie.UPNP.ErrorDescription);
                        Response.StringBuffer = BuildErrorBody(ie.UPNP);
                    }
                    else
                    {
                        OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.Error, "UPnP Invocation Error [" + ie.MethodName + "] " + ie.Message);
                        Response.StringBuffer = BuildErrorBody(new UPnPCustomException(500, ie.Message));
                    }
                    WebSession.Send(Response);
                    InvokerInfo.Remove(Thread.CurrentThread.GetHashCode());
                    return;
                }
                catch (UPnPTypeMismatchException tme)
                {
                    OpenSource.Utilities.EventLogger.Log(tme);
                    Response.StatusCode = 500;
                    Response.StatusData = "Internal";
                    Response.StringBuffer = BuildErrorBody(new UPnPCustomException(402, tme.Message));
                    WebSession.Send(Response);
                    InvokerInfo.Remove(Thread.CurrentThread.GetHashCode());
                    return;
                }
                catch (UPnPStateVariable.OutOfRangeException oor)
                {
                    OpenSource.Utilities.EventLogger.Log(oor);
                    Response.StatusCode = 500;
                    Response.StatusData = "Internal";
                    Response.StringBuffer = BuildErrorBody(new UPnPCustomException(402, oor.Message));
                    WebSession.Send(Response);
                    InvokerInfo.Remove(Thread.CurrentThread.GetHashCode());
                    return;
                }
                catch (System.Reflection.TargetInvocationException tie)
                {
                    Exception inner = tie.InnerException;
                    OpenSource.Utilities.EventLogger.Log(tie);
                    while (inner.InnerException != null && (typeof(UPnPCustomException).IsInstanceOfType(inner) == false))
                    {
                        inner = inner.InnerException;
                    }
                    if (typeof(UPnPCustomException).IsInstanceOfType(inner))
                    {
                        UPnPCustomException ce = (UPnPCustomException)inner;
                        OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.Error, "UPnP Error [" + ce.ErrorCode.ToString() + "] " + ce.ErrorDescription);
                        Response.StatusCode = 500;
                        Response.StatusData = "Internal";
                        Response.StringBuffer = BuildErrorBody(ce);
                        WebSession.Send(Response);
                        InvokerInfo.Remove(Thread.CurrentThread.GetHashCode());
                        return;
                    }
                    else
                    {
                        Response.StatusCode = 500;
                        Response.StatusData = "Internal";
                        Response.StringBuffer = BuildErrorBody(new UPnPCustomException(500, inner.ToString()));
                        WebSession.Send(Response);
                        OpenSource.Utilities.EventLogger.Log(inner);
                        return;
                    }
                }
                catch (Exception e)
                {
                    Response.StatusCode = 500;
                    Response.StatusData = "Internal";
                    Response.StringBuffer = BuildErrorBody(new UPnPCustomException(500, e.ToString()));
                    WebSession.Send(Response);
                    OpenSource.Utilities.EventLogger.Log(e);
                    return;
                }

                WebSession.Send(Response);
                InvokerInfo.Remove(Thread.CurrentThread.GetHashCode());
                return;
            }

            if (Method == "SUBSCRIBE")
            {
                String SID = msg.GetTag("SID");
                String NT = msg.GetTag("NT");
                String Timeout = msg.GetTag("Timeout");
                String CallbackURL = msg.GetTag("Callback");
                if (Timeout == "")
                {
                    Timeout = "7200"; // Default  = 2 Hours
                }
                else
                {
                    Timeout = Timeout.Substring(Timeout.IndexOf("-") + 1).Trim().ToUpper();
                    if (Timeout == "INFINITE")
                    {
                        Timeout = "0";
                    }
                }
                if (SID != "")
                {
                    // Renew
                    RenewEvents(MethodData.Substring(1), SID, Timeout);
                }
                else
                {
                    // Subscribe
                    try
                    {
                        Response2 = SubscribeEvents(ref SID, MethodData.Substring(1), CallbackURL, Timeout);
                    }
                    catch (Exception s_exception)
                    {
                        OpenSource.Utilities.EventLogger.Log(s_exception);
                        HTTPMessage err = new HTTPMessage();
                        err.StatusCode = 500;
                        err.StatusData = s_exception.Message;
                        WebSession.Send(err);
                        return;
                    }
                }
                if (Timeout == "0")
                {
                    Timeout = "Second-infinite";
                }
                else
                {
                    Timeout = "Second-" + Timeout;
                }
                Response.StatusCode = 200;
                Response.StatusData = "OK";
                Response.AddTag("Server", "Windows NT/5.0, UPnP/1.0");
                Response.AddTag("SID", SID);
                Response.AddTag("Timeout", Timeout);
                WebSession.Send(Response);
                if (Response2 != null)
                {
                    Uri[] cbURL = ParseEventURL(CallbackURL);
                    for (int x = 0; x < cbURL.Length; ++x)
                    {
                        Response2.DirectiveObj = HTTPMessage.UnEscapeString(cbURL[x].PathAndQuery);
                        Response2.AddTag("Host", cbURL[x].Host + ":" + cbURL[x].Port.ToString());

                        IPEndPoint d = new IPEndPoint(IPAddress.Parse(cbURL[x].Host), cbURL[x].Port);
                        HTTPRequest R = new HTTPRequest();
                        R.OnResponse += new HTTPRequest.RequestHandler(HandleInitialEvent);
                        this.InitialEventTable[R] = R;
                        R.PipelineRequest(d, Response2, null);
                    }
                }
            }

            if (Method == "UNSUBSCRIBE")
            {
                CancelEvent(MethodData.Substring(1), msg.GetTag("SID"));
                Response.StatusCode = 200;
                Response.StatusData = "OK";
                WebSession.Send(Response);
            }
        }
Пример #27
0
        private void Renew()
        {
            HTTPMessage request = new HTTPMessage();
            String WebIP;
            int WebPort;
            String Tag;
            String NT;

            NT = "Second-" + CurrentTimeout.ToString();

            SSDP.ParseURL(this.__eventurl, out WebIP, out WebPort, out Tag);
            IPEndPoint dest = new IPEndPoint(IPAddress.Parse(WebIP), WebPort);

            request.Directive = "SUBSCRIBE";
            request.DirectiveObj = Tag;
            request.AddTag("Host", WebIP + ":" + WebPort.ToString());
            request.AddTag("SID", CurrentSID);
            request.AddTag("Timeout", NT);

            HTTPRequest R = new HTTPRequest();
            R.OnResponse += new HTTPRequest.RequestHandler(RenewSink);
            this.SendEventTable[R] = R;
            R.PipelineRequest(dest, request, null);
        }
Пример #28
0
        /*
        private static void ParseIconXML(UPnPDevice d, int startLine, String XML)
        {
            StringReader MyString = new StringReader(XML);
            XmlTextReader XMLDoc = new XmlTextReader(MyString);
            String iurl = null;

            try
            {
                XMLDoc.Read();
                XMLDoc.MoveToContent();

                if (XMLDoc.LocalName == "icon")
                {
                    XMLDoc.Read();
                    XMLDoc.MoveToContent();
                    while (XMLDoc.LocalName != "icon")
                    {
                        if (XMLDoc.LocalName == "url")
                        {
                            iurl = XMLDoc.ReadString();
                        }
                        else
                        {
                            XMLDoc.Skip();
                        }
                        XMLDoc.Read();
                        XMLDoc.MoveToContent();
                    }
                }

                if (iurl != null && d.BaseURL != null)
                {
                    if (iurl.ToUpper().StartsWith("HTTP://") == false)
                    {
                        if (iurl.StartsWith("/") == true)
                        {
                            iurl = "http://" + d.BaseURL.Host + ":" + d.BaseURL.Port.ToString() + iurl;
                        }
                        else
                        {
                            iurl = HTTPMessage.UnEscapeString(d.BaseURL.AbsoluteUri + iurl);
                        }
                    }
                    d.FetchIcon(new Uri(iurl));
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Invalid icon XML near line " + (startLine + XMLDoc.LineNumber).ToString() + ", Position " + XMLDoc.LinePosition.ToString(), ex);
            }
        }

        internal void FetchIcon(Uri IconUri)
        {
            HttpRequestor httprequestor = new HttpRequestor();
            httprequestor.OnRequestCompleted += new HttpRequestor.RequestCompletedHandler(HandleIcon);
            httprequestor.LaunchRequest(IconUri.ToString(), null, null, null, null);
            InitialEventTable[httprequestor] = httprequestor;
        }
        */
        /*
        void HandleIcon(HttpRequestor sender, bool success, object tag, string url, byte[] data)
        {
            InitialEventTable.Remove(sender);
            if (success)
            {
                System.Drawing.Image i = System.Drawing.Image.FromStream(new MemoryStream(data));
                if (i != null) _icon = i;
            }
        }
        */
        /// <summary>
        /// Adds response packets for matches in a search request
        /// </summary>
        /// <param name="ST">SearchTarget</param>
        /// <param name="Location">Location</param>
        /// <param name="ResponseList">ArrayList</param>
        public void ContainsSearchTarget(String ST, string Location, ArrayList ResponseList)
        {
            HTTPMessage msg;

            if (ST == "ssdp:all")
            {
                msg = new HTTPMessage();
                msg.StatusCode = 200;
                msg.StatusData = "OK";
                msg.AddTag("ST", "uuid:" + UniqueDeviceName);
                msg.AddTag("USN", "uuid:" + UniqueDeviceName);
                msg.AddTag("Location", Location);
                msg.AddTag("Server", "Windows NT/5.0, UPnP/1.0");
                msg.AddTag("EXT", "");
                msg.AddTag("Cache-Control", "max-age=" + ExpirationTimeout.ToString());
                ResponseList.Add(msg);

                msg = new HTTPMessage();
                msg.StatusCode = 200;
                msg.StatusData = "OK";
                msg.AddTag("ST", DeviceURN);
                msg.AddTag("USN", "uuid:" + UniqueDeviceName + "::" + DeviceURN);
                msg.AddTag("Location", Location);
                msg.AddTag("Server", "Windows NT/5.0, UPnP/1.0");
                msg.AddTag("EXT", "");
                msg.AddTag("Cache-Control", "max-age=" + ExpirationTimeout.ToString());
                ResponseList.Add(msg);
            }

            if (("uuid:" + UniqueDeviceName) == ST)
            {
                msg = new HTTPMessage();
                msg.StatusCode = 200;
                msg.StatusData = "OK";
                msg.AddTag("ST", ST);
                msg.AddTag("USN", "uuid:" + UniqueDeviceName);
                msg.AddTag("Location", Location);
                msg.AddTag("Server", "Windows NT/5.0, UPnP/1.0");
                msg.AddTag("EXT", "");
                msg.AddTag("Cache-Control", "max-age=" + ExpirationTimeout.ToString());
                ResponseList.Add(msg);
            }

            if (DeviceURN == ST)
            {
                msg = new HTTPMessage();
                msg.StatusCode = 200;
                msg.StatusData = "OK";
                msg.AddTag("ST", DeviceURN);
                msg.AddTag("USN", "uuid:" + UniqueDeviceName + "::" + DeviceURN);
                msg.AddTag("Location", Location);
                msg.AddTag("Server", "Windows NT/5.0, UPnP/1.0");
                msg.AddTag("EXT", "");
                msg.AddTag("Cache-Control", "max-age=" + ExpirationTimeout.ToString());
                ResponseList.Add(msg);
            }

            foreach (UPnPService s in Services)
            {
                if (ST == "ssdp:all")
                {
                    msg = new HTTPMessage();
                    msg.StatusCode = 200;
                    msg.StatusData = "OK";
                    msg.AddTag("ST", s.ServiceURN);
                    msg.AddTag("USN", "uuid:" + UniqueDeviceName + "::" + s.ServiceURN);
                    msg.AddTag("Location", Location);
                    msg.AddTag("Server", "Windows NT/5.0, UPnP/1.0");
                    msg.AddTag("EXT", "");
                    msg.AddTag("Cache-Control", "max-age=" + ExpirationTimeout.ToString());
                    ResponseList.Add(msg);
                }
                if (s.ServiceURN == ST)
                {
                    msg = new HTTPMessage();
                    msg.StatusCode = 200;
                    msg.StatusData = "OK";
                    msg.AddTag("ST", s.ServiceURN);
                    msg.AddTag("USN", "uuid:" + UniqueDeviceName + "::" + s.ServiceURN);
                    msg.AddTag("Location", Location);
                    msg.AddTag("Server", "Windows NT/5.0, UPnP/1.0");
                    msg.AddTag("EXT", "");
                    msg.AddTag("Cache-Control", "max-age=" + ExpirationTimeout.ToString());
                    ResponseList.Add(msg);
                }
            }

            foreach (UPnPDevice d in this.EmbeddedDevices)
            {
                d.ContainsSearchTarget(ST, Location, ResponseList);
            }
        }
Пример #29
0
        private void ContinueRequest(IPEndPoint dest, string PQ, object Tag, HTTPMessage MSG)
        {
            HTTPMessage r = null;
            if (MSG == null)
            {
                r = new HTTPMessage();
                r.Directive = "GET";
                r.DirectiveObj = PQ;
                if (dest.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) r.AddTag("Host", dest.ToString());
                if (dest.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) r.AddTag("Host", "[" + RemoveIPv6Scope(dest.ToString()) + "]");
            }
            else
            {
                r = MSG;
            }

            lock (TagQueue)
            {
                this.IdleTimeout = false;
                KeepAliveTimer.Remove(this.GetHashCode());

                LastMessage = r;
                if ((PIPELINE == false && _PIPELINE == false) || (_PIPELINE == false))
                {
                    HTTPRequest TR = new HTTPRequest();
                    TR.ProxySetting = ProxySetting;
                    TR._PIPELINE = true;
                    if (this.OnSniff != null) TR.OnSniff += new HTTPRequest.SniffHandler(NonPipelinedSniffSink);
                    if (this.OnSniffPacket != null) TR.OnSniffPacket += new HTTPRequest.RequestHandler(NonPipelinedSniffPacketSink);
                    TR.OnResponse += new HTTPRequest.RequestHandler(NonPipelinedResponseSink);
                    this.NotPipelinedTable[TR] = TR;
                    TR.PipelineRequest(dest, r, Tag);
                    return;
                }

                bool NeedSend = (TagQueue.Count == 0);
                TagQueue.Enqueue(new StateData(r, dest, Tag, null));

                IPAddress localif = IPAddress.Any;
                if (dest.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) localif = IPAddress.IPv6Any;

                if (s == null)
                {
                    ReceivedFirstResponse = false;
                    if (ProxySetting != null)
                    {
                        s = new HTTPSession(new IPEndPoint(localif, 0),
                            ProxySetting,
                            new HTTPSession.SessionHandler(CreateSink),
                            new HTTPSession.SessionHandler(CreateFailedSink),
                            null);
                    }
                    else
                    {
                        s = new HTTPSession(new IPEndPoint(localif, 0),
                            dest,
                            new HTTPSession.SessionHandler(CreateSink),
                            new HTTPSession.SessionHandler(CreateFailedSink),
                            null);
                    }
                }
                else
                {
                    if (s.IsConnected && this.ReceivedFirstResponse)
                    {
                        try
                        {
                            if (ProxySetting == null)
                            {
                                s.Send(r);
                            }
                            else
                            {
                                HTTPMessage pr = (HTTPMessage)r.Clone();
                                pr.DirectiveObj = "http://" + dest.ToString() + pr.DirectiveObj;
                                pr.Version = "1.0";
                                s.Send(pr);
                            }
                        }
                        catch (Exception ex)
                        {
                            OpenSource.Utilities.EventLogger.Log(ex);
                        }
                    }
                }
            }
        }
 public void Search(string SearchString, IPEndPoint ep)
 {
     HTTPMessage request = new HTTPMessage();
     request.Directive = "M-SEARCH";
     request.DirectiveObj = "*";
     if (ep.AddressFamily == AddressFamily.InterNetwork) request.AddTag("HOST", ep.ToString()); // "239.255.255.250:1900"
     if (ep.AddressFamily == AddressFamily.InterNetworkV6) request.AddTag("HOST", string.Format("[{0}]:{1}", ep.Address.ToString(), ep.Port)); // "[FF05::C]:1900" or "[FF02::C]:1900"
     request.AddTag("MAN", "\"ssdp:discover\"");
     request.AddTag("MX", "10");
     request.AddTag("ST", SearchString);
     SearchEx(System.Text.UTF8Encoding.UTF8.GetBytes(request.StringPacket), ep);
 }