/// <summary>
        /// A wrapper method that implements the ProcessRequest interface used to control blocking of request.
        /// The BlockingCall property is used by the stack to control single instance execution. Hello and Bye
        /// are not blocked. Event messages from a device are blocked. This means it is up to a client developer
        /// to insure long thread safety.
        /// </summary>
        /// <param name="header">A WsWsaHeader containing the header proerties of a request.</param>
        /// <param name="envelope">A WsXmlDocument containing the entire envelope of the message in a node tree.</param>
        /// <returns>A byte array containing a soap response to the request.</returns>
        WsMessage IWsServiceEndpoint.ProcessRequest(WsMessage request)
        {
            //We always block
            WsWsaHeader header = request.Header;

            if (header.MessageID != null &&
                m_messageCheck.IsDuplicate(header.MessageID, header.From != null ? header.From.Address.AbsoluteUri : ""))
            {
                return(null);
            }

            if (header.Action.IndexOf(m_version.DiscoveryNamespace) == 0)
            {
                String action = header.Action.Substring(m_version.DiscoveryNamespace.Length + 1);

                switch (action)
                {
                case "Hello":
                    return(Hello(request.Header, request.Reader));

                case "Bye":
                    return(Bye(request.Header, request.Reader));
                }
            }

            System.Ext.Console.Write("Client discovery callback method for action " + header.Action + " was not found");
            return(null);
        }
        private DpwsServiceDescriptions ProcessMatch(DpwsServiceDescription.ServiceDescriptionType type, WsMessage response, string messageID, IPEndPoint remoteEP, WsMessageCheck messageCheck)
        {
            Microsoft.SPOT.Debug.Assert(type == DpwsServiceDescription.ServiceDescriptionType.ProbeMatch ||
                                        type == DpwsServiceDescription.ServiceDescriptionType.ResolveMatch);

            // Parse and build header
            WsWsaHeader header = response.Header;
            XmlReader   reader = response.Reader;

            if (header == null || reader == null)
            {
                return(null);
            }

            try
            {
                // Make sure this is a probe matches response
                String headerAction = (type == DpwsServiceDescription.ServiceDescriptionType.ProbeMatch) ?
                                      m_version.DiscoveryNamespace + "/ProbeMatches" :
                                      m_version.DiscoveryNamespace + "/ResolveMatches";

                if (header.Action != headerAction)
                {
                    return(null);
                }

                // Make sure this is not a duplicate probe response
                if (messageCheck != null)
                {
                    if (messageCheck.IsDuplicate(header.MessageID, remoteEP.ToString()) == true)
                    {
                        System.Ext.Console.Write("ProbeMatches / ResolveMatches - Duplicate response - " + header.Action + " received");
                        return(null);
                    }
                }

                // Make sure the messageID matches the request ID
                if (header.RelatesTo != messageID)
                {
                    return(null);
                }

                // Process the probe matches
#if DEBUG
                int depth = reader.Depth;
#endif
                DpwsServiceDescriptions matches = new DpwsServiceDescriptions(reader, type, m_version, remoteEP);
#if DEBUG
                Microsoft.SPOT.Debug.Assert(XmlReaderHelper.HasReadCompleteNode(depth, reader));
#endif

                return(matches);
            }
            finally
            {
                reader.Close();
            }
        }
Beispiel #3
0
        /// <summary>
        /// Listens for Udp request on 239.255.255.250:3702
        /// </summary>
        /// <remarks>On initialization it sends a Discovery Hello message and listens on the Ws-Discovery
        /// endpoint for a request. When a request arrives it starts a UdpProcess thread that processes the message.
        /// The number of UdpProcessing threads are limited by the Device.MaxUdpRequestThreads property.
        /// </remarks>
        private void Listen()
        {
            // Create a duplicate message tester.
            WsMessageCheck messageCheck = new WsMessageCheck(40);

            while (!m_requestStop)
            {
                try
                {
                    // If threads ara availble receive next message. If we are waiting on threads let the socket
                    // buffer request until we get a thread. This will work until the reveice buffer is depleted
                    // at which time request will be dropped
                    if (m_threadManager.ThreadsAvailable == true)
                    {
                        RequestContext req = m_replyChannel.ReceiveRequest();

                        if (req != null)
                        {
                            WsWsaHeader header = req.Message.Header;

                            if (header.MessageID != null &&
                                messageCheck.IsDuplicate(header.MessageID, header.From != null ? header.From.Address.AbsoluteUri : ""))
                            {
                                continue;
                            }

                            // Try to get a processing thread and process the request
                            m_threadManager.StartNewThread(new WsUdpMessageProcessor(m_serviceEndpoints, req));
                        }
                        else
                        {
                            System.Ext.Console.Write("UDP Receive returned 0 bytes");
                        }
                    }
                    else
                    {
                        System.Ext.Console.Write("Udp service host waiting for a thread...");

                        m_threadManager.ThreadEvent.WaitOne();
                    }
                }
                catch (SocketException se)
                {
                    // Since the MF Socket does not have IOControl that would be used to turn off ICMP notifications
                    // for UDP, catch 10054 and try to continue
                    if ((SocketError)se.ErrorCode == SocketError.ConnectionReset)
                    {
                        Thread.Sleep(100);
                    }
                }
                catch (Exception e)
                {
                    System.Ext.Console.Write(e.Message + " " + e.InnerException);
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Parses a Udp transport message and builds a header object and envelope document then calls processRequest
        /// on a service endpoint contained.
        /// </summary>
        /// <param name="soapRequest">A byte array containing a raw soap request message.  If null no check is performed.</param>
        /// <param name="messageCheck">A WsMessageCheck objct used to test for duplicate request.</param>
        /// <param name="remoteEP">The remote endpoint address of the requestor.</param>
        /// <returns>A byte array containing a soap response message returned from a service endpoint.</returns>
        public byte[] ProcessRequestMessage()
        {
            Debug.Assert(m_messageCheck != null && m_remoteEP != null);

            // Parse and validate the soap message
            WsWsaHeader header;
            XmlReader   reader;

            try
            {
                reader = WsSoapMessageParser.ParseSoapMessage(m_soapMessage, out header);
            }
            catch
            {
                return(null);
            }

            try
            {
                if (m_messageCheck.IsDuplicate(header.MessageID, m_remoteEP.ToString()) == true)
                {
                    System.Ext.Console.Write("Duplicate \"" + header.Action + "\" request received");
                    System.Ext.Console.Write("Request Ignored.");
                    return(null);
                }

                // Check Udp service endpoints collection for a target service.
                IWsServiceEndpoint serviceEndpoint = m_serviceEndpoints[header.To];
                if (serviceEndpoint != null && serviceEndpoint.ServiceOperations[header.Action] != null)
                {
                    // Don't block discovery processes.
                    serviceEndpoint.BlockingCall = false;
                    try
                    {
                        return(serviceEndpoint.ProcessRequest(header, reader));
                    }
                    catch
                    {
                        return(null);
                    }
                }

                // Return null if service endpoint was not found
                System.Ext.Console.Write("Udp service endpoint was not found.");
                System.Ext.Console.Write("  Endpoint Address: " + header.To);
                System.Ext.Console.Write("  Action: " + header.Action);
                return(null);
            }
            finally
            {
                reader.Close();
            }
        }