示例#1
0
 public StateData(HTTPMessage req, IPEndPoint d, object Tag, HeaderHandler HeaderCB)
 {
     this.Dest = d;
     this.Request = req;
     this.Tag = Tag;
     this.HeaderCB = HeaderCB;
 }
 /// <summary>
 /// This is used to complete an AsyncRequest in an AsyncFashion.
 /// <para>
 /// You must either assign all the Argument values, or return an exception with "e"
 /// </para>
 /// </summary>
 /// <param name="id">ID</param>
 /// <param name="RetArg">Return Argument</param>
 /// <param name="OutArgs">Out Arguments</param>
 /// <param name="e">Exception</param>
 public void DelayedInvokeResponse(long id, object RetArg, UPnPArgument[] OutArgs, UPnPCustomException e)
 {
     UPnPDevice.InvokerInfoStruct iis = (UPnPDevice.InvokerInfoStruct)DelayedResponseTable[id];
     HTTPMessage resp = new HTTPMessage();
     if (e != null)
     {
         resp.StatusCode = 500;
         resp.StatusData = "Internal";
         resp.StringBuffer = ParentDevice.BuildErrorBody(e);
     }
     else
     {
         resp = ParentDevice.ParseInvokeResponse(iis.MethodName, iis.SOAPAction, this.ServiceURN, RetArg, OutArgs);
     }
     iis.WebSession.Send(resp);
     iis.WebSession.StartReading();
     lock (DelayedResponseTable)
     {
         DelayedResponseTable.Remove(id);
     }
 }
        /// <summary>
        /// Parses a Byte Array at a specific location, and builds a Packet.
        /// </summary>
        /// <param name="buffer">The Array of Bytes</param>
        /// <param name="indx">The Start Index</param>
        /// <param name="count">The number of Bytes to process</param>
        /// <returns></returns>
        public static HTTPMessage ParseByteArray(byte[] buffer, int indx, int count)
        {
            HTTPMessage TheMessage = new HTTPMessage();
            UTF8Encoding UTF8 = new UTF8Encoding();
            String TempData = UTF8.GetString(buffer,indx,count);
            DText parser = new DText();
            String TempString;

            int idx = TempData.IndexOf("\r\n\r\n");
            if (idx < 0) return null;
            TempData = TempData.Substring(0,idx);

            parser.ATTRMARK = "\r\n";
            parser.MULTMARK = ":";
            parser[0] = TempData;
            string CurrentLine = parser[1];

            DText HdrParser = new DText();
            HdrParser.ATTRMARK = " ";
            HdrParser.MULTMARK = "/";
            HdrParser[0] = CurrentLine;

            if (CurrentLine.ToUpper().StartsWith("HTTP/")==true)
            {
                TheMessage.ResponseCode = int.Parse(HdrParser[2]);
                int s1 = CurrentLine.IndexOf(" ");
                s1 = CurrentLine.IndexOf(" ",s1+1);
                TheMessage.ResponseData = HTTPMessage.UnEscapeString(CurrentLine.Substring(s1));
                try
                {
                    TheMessage.Version = HdrParser[1,2];
                }
                catch(Exception)
                {
                    TheMessage.Version = "0.9";
                }
            }
            else
            {
                TheMessage.Directive = HdrParser[1];
                TempString = CurrentLine.Substring(CurrentLine.LastIndexOf(" ") + 1);
                if (TempString.ToUpper().StartsWith("HTTP/")==false)
                {
                    TheMessage.Version = "0.9";
                    TheMessage.DirectiveObj = HTTPMessage.UnEscapeString(TempString);
                }
                else
                {
                    TheMessage.Version = TempString.Substring(TempString.IndexOf("/")+1);
                    int fs = CurrentLine.IndexOf(" ") + 1;
                    TheMessage.DirectiveObj = HTTPMessage.UnEscapeString(CurrentLine.Substring(
                        fs,
                        CurrentLine.Length-fs-TempString.Length-1));
                }
            }
            String Tag="";
            String TagData="";

            for(int line=2;line<=parser.DCOUNT();++line)
            {
                if (Tag!="" && parser[line,1].StartsWith(" "))
                {
                    TagData = parser[line,1].Substring(1);
                }
                else
                {
                    Tag = parser[line,1];
                    TagData = "";
                    for(int i=2;i<=parser.DCOUNT(line);++i)
                    {
                        if (TagData=="")
                        {
                            TagData = parser[line,i];
                        }
                        else
                        {
                            TagData = TagData + parser.MULTMARK + parser[line,i];
                        }
                    }
                }
                TheMessage.AppendTag(Tag,TagData);
            }
            int cl=0;
            if (TheMessage.HasTag("Content-Length"))
            {
                try
                {
                    cl = int.Parse(TheMessage.GetTag("Content-Length"));
                }
                catch(Exception)
                {
                    cl = -1;
                }
            }
            else
            {
                cl = -1;
            }

            byte[] tbuffer;
            if (cl>0)
            {
                tbuffer = new byte[cl];
                if ((idx+4+cl)>count)
                {
                    // NOP
                }
                else
                {
                    Array.Copy(buffer,idx+4,tbuffer,0,cl);
                    TheMessage.DataBuffer = tbuffer;
                }
            }
            if (cl==-1)
            {
                tbuffer = new Byte[count-(idx+4)];
                Array.Copy(buffer,idx+4,tbuffer,0,tbuffer.Length);
                TheMessage.DataBuffer = tbuffer;
            }
            if (cl==0)
            {
                TheMessage.DataBuffer = new byte[0];
            }
            return(TheMessage);
        }
 private void OnPacketTraceChangedSink(IUPnPTestGroup sender, HTTPMessage packet)
 {
     this.BeginInvoke(new UpdatePacketTraceForCurrentTestHandler(UpdatePacketTraceForCurrentTest), new object[] { sender, packet });
 }
示例#5
0
        private void SniffPacketSink(HTTPSession sender, HTTPMessage MSG)
        {
            if (this.OnSniffPacket != null)
            {
                if (sender.StateObject == null)
                {
                    OnSniffPacket(this, MSG, null);
                    return;
                }
                StateData sd = (StateData)sender.StateObject;
                object Tag = sd.Tag;

                OnSniffPacket(this, MSG, Tag);
            }
        }
示例#6
0
 private void HeaderSink(HTTPSession sender, HTTPMessage header, Stream TheStream)
 {
     _Source = sender.Source;
     StateData sd = null;
     if (TheStream != null)
     {
         // This is the result of post-headers in a chunked document
         sd = (StateData)sender.StateObject;
         object Tag = sd.Tag;
         if (sd.HeaderCB != null) sd.HeaderCB(this, sender, header, TheStream, Tag);
         sender.StateObject = null;
         KeepAliveTimer.Add(this.GetHashCode(), 10);
     }
     else
     {
         lock (TagQueue)
         {
             sd = (StateData)TagQueue.Dequeue();
         }
         sender.StateObject = sd;
         object Tag = sd.Tag;
         if (sd.HeaderCB != null)
         {
             sd.HeaderCB(this, sender, header, TheStream, Tag);
             if (sender.UserStream != null && !sender.IsChunked)
             {
                 // If I don't set this to null, this holds a strong reference, resulting in
                 // possible memory leaks
                 sender.StateObject = null;
             }
         }
     }
 }
示例#7
0
 private void NonPipelinedSniffPacketSink(HTTPRequest sender, HTTPMessage Response, object Tag)
 {
     if (OnSniffPacket != null)
         OnSniffPacket(this, Response, Tag);
 }
示例#8
0
 /// <summary>
 /// Pipelines a request packet
 /// </summary>
 /// <param name="dest">Destination IPEndPoint</param>
 /// <param name="MSG">HTTPMessage Packet</param>
 /// <param name="Tag">State Data</param>
 public void PipelineRequest(IPEndPoint dest, HTTPMessage MSG, object Tag)
 {
     ContinueRequest(dest, "", Tag, MSG);
 }
 private void HandleSendEvent(HTTPRequest R, HTTPMessage M, object Tag)
 {
     R.Dispose();
     SendEventTable.Remove(R);
 }
        private void HandleInvokeRequest(HTTPRequest sender, HTTPMessage response, object Tag)
        {
            AsyncInvokeInfo state = (AsyncInvokeInfo)Tag;

            if (response == null)
            {
                if (state.ErrorCB != null)
                {
                    state.ErrorCB(this, state.MethodName, state.Args, new UPnPInvokeException(state.MethodName, state.Args, "Could not connect to device"), state.Tag);
                }
                else
                {
                    if (OnInvokeError != null)
                    {
                        OnInvokeError(this, state.MethodName, state.Args, new UPnPInvokeException(state.MethodName, state.Args, "Could not connect to device"), state.Tag);
                    }
                }
                return;
            }

            if (response.StatusCode == 100)
            {
                // Ignore
                return;
            }

            UPnPAction action = (UPnPAction)RemoteMethods[state.MethodName];
            if (response.StatusCode != 200)
            {
                if ((OnInvokeError != null) || (state.ErrorCB != null))
                {
                    if ((response.StatusCode == 500) && (response.BodyBuffer.Length > 0))
                    {
                        // Try to parse SOAP Encoded Error
                        UPnPCustomException ce = null;
                        try
                        {
                            ce = ParseErrorBody(response.StringBuffer);
                            OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.Error,
                                "UPnP Action <" + state.MethodName + "> Error [" + ce.ErrorCode.ToString() + "] " + ce.ErrorDescription);
                        }
                        catch
                        {
                            ce = null;
                            OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.Error,
                                "HTTP Fault invoking " + state.MethodName + " : " + response.StatusData);

                        }
                        if (state.ErrorCB != null)
                        {
                            state.ErrorCB(this, action.Name, state.Args, new UPnPInvokeException(state.MethodName, state.Args, response.StatusData, ce), state.Tag);
                        }
                        else
                        {
                            if (OnInvokeError != null)
                            {
                                OnInvokeError(this, action.Name, state.Args, new UPnPInvokeException(state.MethodName, state.Args, response.StatusData, ce), state.Tag);
                            }
                        }
                    }
                    else
                    {
                        if (state.ErrorCB != null)
                        {
                            state.ErrorCB(this, action.Name, state.Args, new UPnPInvokeException(state.MethodName, state.Args, response.StatusData), state.Tag);
                        }
                        else
                        {
                            if (OnInvokeError != null)
                            {
                                OnInvokeError(this, action.Name, state.Args, new UPnPInvokeException(state.MethodName, state.Args, response.StatusData), state.Tag);
                            }
                        }
                    }
                }
                return;
            }

            //Lets Parse the data we got back
            //Now we can parse the XML Body

            StringReader MyString = new StringReader(response.StringBuffer.Trim());
            XmlTextReader XMLDoc = new XmlTextReader(MyString);

            String MethodTag = "";
            UPnPArgument VarArg;
            ArrayList VarList = new ArrayList();

            XMLDoc.Read();
            XMLDoc.MoveToContent();
            if (XMLDoc.LocalName == "Envelope")
            {
                XMLDoc.Read();
                XMLDoc.MoveToContent();

                if (XMLDoc.LocalName == "Body")
                {
                    XMLDoc.Read();
                    XMLDoc.MoveToContent();

                    MethodTag = XMLDoc.LocalName;

                    XMLDoc.Read();
                    XMLDoc.MoveToContent();
                    if (XMLDoc.LocalName != "Body")
                    {
                        while ((XMLDoc.LocalName != MethodTag) && (XMLDoc.EOF == false))
                        {
                            //							VarArg = new UPnPArgument(XMLDoc.Name,UPnPStringFormatter.UnEscapeString(XMLDoc.ReadInnerXml()));
                            VarArg = new UPnPArgument(XMLDoc.Name, XMLDoc.ReadString());

                            VarList.Add(VarArg);

                            if ((!XMLDoc.IsStartElement() && XMLDoc.LocalName != MethodTag) || XMLDoc.IsEmptyElement)
                            {
                                XMLDoc.Read();
                                XMLDoc.MoveToContent();
                            }
                        }
                    }
                }
            }

            //Finished processing the SOAP, lets build the return list
            Object RetVal = null;
            UPnPArgument[] InVarArr = state.Args;
            UPnPArgument ThisArg;
            Object[] temp = new Object[1];
            Type[] TypeParm = new Type[1];
            TypeParm[0] = Type.GetType("System.String");
            int StartIDX = 0;
            if (((UPnPAction)RemoteMethods[state.MethodName]).HasReturnValue == true)
            {
                UPnPArgument RetArg = action.GetArg(((UPnPArgument)VarList[0]).Name);
                Type RetType = RetArg.RelatedStateVar.GetNetType();
                RetVal = CreateObjectInstance(RetType,
                    (string)((UPnPArgument)VarList[0]).DataValue);
                StartIDX = 1;
            }

            for (int ID = StartIDX; ID < VarList.Count; ++ID)
            {
                for (int ix = 0; ix < InVarArr.Length; ++ix)
                {
                    if (InVarArr[ix].Name == ((UPnPArgument)VarList[ID]).Name)
                    {
                        ThisArg = action.GetArg(InVarArr[ix].Name);
                        if ((ThisArg.RelatedStateVar.GetNetType().FullName != "System.String") ||
                            (ThisArg.RelatedStateVar.GetNetType().FullName != "System.Object"))
                        {
                            InVarArr[ix].DataValue = CreateObjectInstance(ThisArg.RelatedStateVar.GetNetType(), (string)((UPnPArgument)VarList[ID]).DataValue);
                        }
                        else
                        {
                            InVarArr[ix].DataValue = ((UPnPArgument)VarList[ID]).DataValue;
                        }
                        InVarArr[ix].DataType = ThisArg.RelatedStateVar.GetNetType().FullName;
                        break;
                    }
                }
            }
            if (state.InvokeCB != null)
            {
                state.InvokeCB(this, state.MethodName, InVarArr, RetVal, state.Tag);
            }
            else
            {
                if (OnInvokeResponse != null)
                {
                    OnInvokeResponse(this, state.MethodName, InVarArr, RetVal, state.Tag);
                }
            }
        }
        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);
        }
        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);
                    }
                }
            }
        }
        /// <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>
        /// 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);
        }
        /// <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);
        }
示例#16
0
        private void OnReceiveSink2(byte[] buffer, IPEndPoint remote, IPEndPoint local)
        {
            HTTPMessage msg;

            try
            {
                msg = HTTPMessage.ParseByteArray(buffer, 0, buffer.Length);
            }
            catch (Exception ex)
            {
                OpenSource.Utilities.EventLogger.Log(ex);
                msg = new HTTPMessage();
                msg.Directive = "---";
                msg.DirectiveObj = "---";
                msg.BodyBuffer = buffer;
            }
            msg.LocalEndPoint = local;
            msg.RemoteEndPoint = remote;

            DText parser = new DText();

            String Location = msg.GetTag("Location");
            int MaxAge = 0;
            String ma = msg.GetTag("Cache-Control").Trim();
            if (ma != "")
            {
                parser.ATTRMARK = ",";
                parser.MULTMARK = "=";
                parser[0] = ma;
                for (int i = 1; i <= parser.DCOUNT(); ++i)
                {
                    if (parser[i, 1].Trim().ToUpper() == "MAX-AGE")
                    {
                        MaxAge = int.Parse(parser[i, 2].Trim());
                        break;
                    }
                }
            }
            ma = msg.GetTag("USN");
            String USN = ma.Substring(ma.IndexOf(":") + 1);
            String ST = msg.GetTag("ST");
            if (USN.IndexOf("::") != -1) USN = USN.Substring(0, USN.IndexOf("::"));
            OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.SuccessAudit, msg.RemoteEndPoint.ToString());
            if (OnSearch != null) OnSearch(msg.RemoteEndPoint, msg.LocalEndPoint, new Uri(Location), USN, ST, MaxAge);
        }
示例#17
0
		private void SniffPacketSink(HTTPMessage Packet)
		{
			if (OnSniffPacket!=null) OnSniffPacket(Packet);
		}
        private void HandleSubscribeResponse(HTTPRequest sender, HTTPMessage response, object Tag)
        {
            UPnPEventSubscribeHandler CB = (UPnPEventSubscribeHandler)Tag;
            SubscribeRequestTable.Remove(sender);
            sender.Dispose();
            if (response != null)
            {
                if (response.StatusCode != 200)
                {
                    if (CB != null)
                    {
                        CB(this, false);
                    }
                    else
                    {
                        if (OnSubscribe != null) OnSubscribe(this, false);
                    }
                }
                else
                {
                    CurrentSID = response.GetTag("SID");
                    if (CB != null)
                    {
                        CB(this, true);
                    }
                    else
                    {
                        if (OnSubscribe != null) OnSubscribe(this, true);
                    }

                    if (CurrentTimeout != 0)
                    {
                        EventLogger.Log(this, System.Diagnostics.EventLogEntryType.SuccessAudit, "SUBSCRIBE [" + this.CurrentSID + "] Duration: " + CurrentTimeout.ToString() + " <" + DateTime.Now.ToLongTimeString() + ">");
                        SubscribeCycle.Add(this.GetHashCode(), CurrentTimeout / 2);
                    }
                }
            }
            else
            {
                if (CB != null)
                {
                    CB(this, false);
                }
                else
                {
                    if (OnSubscribe != null) OnSubscribe(this, false);
                }
            }
        }
示例#19
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);
                        }
                    }
                }
            }
        }
 private void HandleUnsubscribeResponse(HTTPRequest sender, HTTPMessage response, object Tag)
 {
     SubscribeRequestTable.Remove(sender);
     sender.Dispose();
     SubscribeCycle.Remove(this.GetHashCode());
 }
示例#21
0
 private void NonPipelinedResponseSink(HTTPRequest sender, HTTPMessage Response, object Tag)
 {
     //			OpenSource.Utilities.EventLogger.Log(sender.s,System.Diagnostics.EventLogEntryType.Information,"TryingToDispose");
     _Source = sender.Source;
     this.NotPipelinedTable.Remove(sender);
     sender.Dispose();
     if (this.OnResponse != null)
         OnResponse(this, Response, Tag);
 }
        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);
        }
示例#23
0
        private void ReceiveSink(HTTPSession sender, HTTPMessage msg)
        {
            StateData sd = (StateData)sender.StateObject;
            object Tag = sd.Tag;

            if (msg.Version == "1.0" || msg.Version == "0.9")
            {
                sender.Close();
            }
            else
            {
                if (msg.GetTag("Connection").ToUpper() == "CLOSE")
                {
                    sender.Close();
                }
            }


            if (OnResponse != null) OnResponse(this, msg, Tag);
            // If I don't set this to null, this holds a strong reference, resulting in
            // possible memory leaks
            sender.StateObject = null;
            lock (TagQueue)
            {
                if (TagQueue.Count == 0)
                {
                    this.IdleTimeout = true;
                    KeepAliveTimer.Add(this.GetHashCode(), 10);
                }
            }
        }
        private void RenewSink(HTTPRequest sender, HTTPMessage M, object Tag)
        {
            if (M != null)
            {
                if (M.StatusCode != 200)
                {
                    // Renew Failed
                    EventLogger.Log(this, System.Diagnostics.EventLogEntryType.SuccessAudit, "Renewal [" + this.CurrentSID + "] Error:" + M.StatusCode.ToString() + " <" + DateTime.Now.ToLongTimeString() + ">");

                    SubscribeCycle.Remove(this.GetHashCode());
                    this.SubscribeCounter = 0;
                    PeriodicRenewFailedEvent.Fire(this);
                }
                else
                {
                    EventLogger.Log(this, System.Diagnostics.EventLogEntryType.SuccessAudit, "Renewal [" + this.CurrentSID + "] OK <" + DateTime.Now.ToLongTimeString() + ">");
                    SubscribeCycle.Add(this.GetHashCode(), CurrentTimeout / 2);
                }
            }
            else
            {
                // Renew Failed
                EventLogger.Log(this, System.Diagnostics.EventLogEntryType.SuccessAudit, "Renewal [" + this.CurrentSID + "] DeviceError <" + DateTime.Now.ToLongTimeString() + ">");

                SubscribeCycle.Remove(this.GetHashCode());
                this.SubscribeCounter = 0;
                PeriodicRenewFailedEvent.Fire(this);
            }
            this.SendEventTable.Remove(sender);
            sender.Dispose();
        }
 private void SniffPacketSink(HTTPRequest sender, HTTPMessage MSG, object Tag)
 {
     OnSniffPacketEvent.Fire(this, MSG);
 }
示例#26
0
 private void HandleNotify(IPEndPoint source, IPEndPoint local, Uri LocationURL, bool IsAlive, String USN, String ST, int MaxAge, HTTPMessage Packet)
 {
     if (IsAlive && LocationURL != null) OpenSource.Utilities.EventLogger.Log(this, System.Diagnostics.EventLogEntryType.SuccessAudit, LocationURL.ToString());
     if (OnNotify != null) OnNotify(source, local, LocationURL, IsAlive, USN, ST, MaxAge, Packet);
 }
示例#27
0
        private void UpdatePacketTraceForCurrentTest(IUPnPTestGroup sender, HTTPMessage msg)
        {
            if (sender != displaytestinfo) return;

            ListViewItem lv;
            if (msg.StatusCode == -1)
            {
                lv = new ListViewItem(new string[] { msg.RawPacket.Length.ToString() + " (" + msg.BodyBuffer.Length + ")", msg.Directive + " " + msg.DirectiveObj }, 5);
            }
            else
            {
                lv = new ListViewItem(new string[] { msg.RawPacket.Length.ToString() + " (" + msg.BodyBuffer.Length + ")", "(" + msg.StatusCode.ToString() + ") " + msg.StatusData }, 5);
            }
            lv.Tag = msg;
            packetListView.Items.Add(lv);
        }
示例#28
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);
                }
            }
        }
示例#29
0
文件: UPnP.cs 项目: Qu3uk/HomeGenie
 internal void SSDPNotifySink(
     IPEndPoint source,
     IPEndPoint local,
     Uri LocationURL,
     bool IsAlive,
     string USN,
     string SearchTarget,
     int MaxAge,
     HTTPMessage Packet
 )
 {
     UPnPDevice device = null;
     if (SearchTarget == searchFilter)
     {
         if (!IsAlive)
         {
             lock (this.deviceTableLock)
             {
                 device = this.UnprotectedRemoveMe(USN);
             }
             if (device != null)
             {
                 //device.Removed();
             }
             if (device != null)
             {
                 this.OnRemovedDeviceEvent.Fire(this, device);
             }
         }
         else
         {
             lock (this.deviceTableLock)
             {
                 if (!this.deviceTable.ContainsKey(USN))
                 {
                     DeviceInfo info = new DeviceInfo();
                     info.Device = null;
                     info.UDN = USN;
                     info.NotifyTime = DateTime.Now;
                     info.BaseURL = LocationURL;
                     info.MaxAge = MaxAge;
                     info.LocalEP = local;
                     info.SourceEP = source;
                     this.deviceTable[USN] = info;
                     this.deviceFactory.CreateDevice(info.BaseURL, info.MaxAge, IPAddress.Any, info.UDN);
                 }
                 else
                 {
                     DeviceInfo info2 = (DeviceInfo)this.deviceTable[USN];
                     if (info2.Device != null)
                     {
                         if (info2.BaseURL.Equals(LocationURL))
                         {
                             this.deviceUpdateClock.Remove(info2);
                             info2.PendingBaseURL = null;
                             info2.PendingMaxAge = 0;
                             info2.PendingLocalEP = null;
                             info2.PendingSourceEP = null;
                             info2.NotifyTime = DateTime.Now;
                             this.deviceTable[USN] = info2;
                             this.deviceLifeTimeClock.Add(info2.UDN, MaxAge);
                         }
                         else if (info2.NotifyTime.AddSeconds(10.0).Ticks < DateTime.Now.Ticks)
                         {
                             info2.PendingBaseURL = LocationURL;
                             info2.PendingMaxAge = MaxAge;
                             info2.PendingLocalEP = local;
                             info2.PendingSourceEP = source;
                             this.deviceTable[USN] = info2;
                             this.deviceUpdateClock.Add(info2.UDN, 3);
                         }
                     }
                 }
             }
         }
     }
 }
示例#30
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);
     }
 }