Example #1
0
        /// <summary>
        /// Sends a directed Probe request and parses ProbeMatches responses.
        /// </summary>
        /// <param name="endpointAddress">
        /// A string containing a Dpws devices transport endpoint address.
        /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="targetServiceAddress">
        /// A string containing the target service address to probe for.
        /// For example: urn:uuid:3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="filters">
        /// A DpwsServiceTypes object containing a collection of types a service must support to signal a match.
        /// Null = any type.
        /// </param>
        /// <remarks>
        /// A directed Probe is used to discover services on a network. The DirectedProbe method sends a
        /// HTTP request to the service specified endpointAddress parameter. A service at the endpoint that
        /// implements matching types specified in the filters parameter should respond with a ProbeMatches
        /// message. The ProbeMatches mesgage is returned as the response to the DirectedProbe request.
        /// If a null filter is supplied any Dpws complient service should reply with a ProbeMatches reponse.
        /// This method is used to directly ask for service endpoint information.
        /// </remarks>
        /// <returns>
        /// A collection of ProbeMatches objects.  A ProbeMatch object contains endpoint details used
        /// used to locate the actual service on a network and the types supported by the service.
        /// </returns>
        /// <exception cref="InvalidOperationException">If a fault response is received.</exception>
        public DpwsServiceDescriptions DirectedProbe(string endpointAddress, string targetServiceAddress, DpwsServiceTypes filters)
        {
            // Build the probe request message
            string messageID = null;

            byte[] probeRequest = BuildProbeRequest(targetServiceAddress, filters, out messageID);

            System.Ext.Console.Write("");
            System.Ext.Console.Write("Sending DirectedProbe:");
            System.Ext.Console.Write(new string(new UTF8Encoding().GetChars(probeRequest)));
            System.Ext.Console.Write("");

            // Create an http client and send the probe request. Use a WspHttpClient to get an array response.
            WsHttpClient httpClient = new WsHttpClient();

            byte[] probeResponse = httpClient.SendRequest(probeRequest, endpointAddress, false, false);

            // Build probe matches collection
            DpwsServiceDescriptions  probeMatches  = new DpwsServiceDescriptions();
            DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor();

            if (probeResponse != null)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("ProbeMatches Response From: " + endpointAddress);
                System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(probeResponse)));

                try
                {
                    DpwsServiceDescriptions tempMatches = soapProcessor.ProcessProbeMatch(probeResponse, messageID, null, null);
                    if (tempMatches != null)
                    {
                        int count = tempMatches.Count;
                        for (int i = 0; i < count; i++)
                        {
                            probeMatches.Add(tempMatches[i]);
                        }
                    }
                }
                catch (Exception e)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write(e.Message);
                    System.Ext.Console.Write("");
                }
            }

            if (probeMatches.Count == 0)
            {
                return(null);
            }
            else
            {
                return(probeMatches);
            }
        }
        /// <summary>
        /// Sends a directed Resolve request and parses ResolveMatch response.
        /// </summary>
        /// <param name="endpointAddress">
        /// A string containing a Dpws devices transport endpoint address.
        /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="serviceAddress">
        /// A string containing the address of a service that will handle the resolve request.
        /// For example: urn:uuid:2bcdd1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="targetServiceAddress">
        /// A string containing the address of a service that can process the resolve request.
        /// For example: urn:uuid:3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <remarks>
        /// A Resolve is used to resolve the transport address of a know service. The request contains a service
        /// address aquired from configuration or a previous Resolve or Metadata Get request.
        /// The DirectedResolve method sends a Http request to the specified endpoint address.
        /// If the endpoint contains a device with this address receives the request, it must send a unicast ResolveMatches
        /// response back to the client that made the request.
        /// </remarks>
        /// <returns>
        /// A collection of ResolveMatches objects. A ResolveMatch object contains endpoint details used
        /// used to locate the actual service on a network and the types supported by the service.
        /// </returns>
        public DpwsServiceDescription DirectedResolve(string endpointAddress, string serviceAddress, string targetServiceAddress)
        {
            String    messageID      = "";
            WsMessage resolveRequest = BuildResolveRequest(targetServiceAddress, serviceAddress, ref messageID);

            if (resolveRequest == null)
            {
                return(null);
            }

            System.Ext.Console.Write("");
            System.Ext.Console.Write("Sending Resolve:");
            System.Ext.Console.Write(resolveRequest.Body as byte[]);

            // Create an http client and send the resolve request. Use a WspHttpClient to get an array response.
            WsHttpClient httpClient = new WsHttpClient(m_version);

            WsMessage resolveResponse = httpClient.SendRequest(resolveRequest, new Uri(endpointAddress));

            DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(m_version);
            DpwsServiceDescription   resolveMatch  = soapProcessor.ProcessResolveMatch(resolveResponse, messageID, null, null);

            return(resolveMatch);
        }
Example #3
0
        /// <summary>
        /// Sends a directed Resolve request and parses ResolveMatch response.
        /// </summary>
        /// <param name="endpointAddress">
        /// A string containing a Dpws devices transport endpoint address.
        /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="serviceAddress">
        /// A string containing the address of a service that will handle the resolve request.
        /// For example: urn:uuid:2bcdd1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="targetServiceAddress">
        /// A string containing the address of a service that can process the resolve request.
        /// For example: urn:uuid:3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <remarks>
        /// A Resolve is used to resolve the transport address of a know service. The request contains a service
        /// address aquired from configuration or a previous Resolve or Metadata Get request.
        /// The DirectedResolve method sends a Http request to the specified endpoint address.
        /// If the endpoint contains a device with this address receives the request, it must send a unicast ResolveMatches
        /// response back to the client that made the request.
        /// </remarks>
        /// <returns>
        /// A collection of ResolveMatches objects. A ResolveMatch object contains endpoint details used
        /// used to locate the actual service on a network and the types supported by the service.
        /// </returns>
        public DpwsServiceDescription DirectedResolve(string endpointAddress, string serviceAddress, string targetServiceAddress)
        {
            String messageID = "";

            byte[] resolveRequest = BuildResolveRequest(targetServiceAddress, serviceAddress, ref messageID);

            if (resolveRequest == null)
            {
                return(null);
            }

            System.Ext.Console.Write("");
            System.Ext.Console.Write("Sending Resolve:");
            System.Ext.Console.Write(new string(new UTF8Encoding().GetChars(resolveRequest)));

            // Create an http client and send the resolve request. Use a WspHttpClient to get an array response.
            WsHttpClient httpClient = new WsHttpClient();

            byte[] resolveResponse = httpClient.SendRequest(resolveRequest, endpointAddress, false, false);
            DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor();
            DpwsServiceDescription   resolveMatch  = soapProcessor.ProcessResolveMatch(resolveResponse, messageID, null, null);

            return(resolveMatch);
        }
        /// <summary>
        /// Use to send a resolve request to the ws-discovery address and receive a resolve match.
        /// </summary>
        /// <param name="message">A byte array containing a the resolve message.</param>
        /// <param name="messageID">
        /// A string containing the message ID of a resolve request. This ID will be used to validate against
        /// a ResolveMatch received if it don't match, the ResolveMatch is discarded.
        /// </param>
        /// <param name="timeout">
        /// A DateTime value containing the length of time this request will wait for resolve match.
        /// until the timeout value has expired.
        /// </param>
        /// <returns>A resolve match object.</returns>
        private DpwsServiceDescription SendResolveRequest(byte[] message, string messageID, long timeout)
        {
            WsMessageCheck messageCheck = new WsMessageCheck();
            
            DpwsServiceDescription resolveMatch = null;

            System.Ext.Console.Write("");
            System.Ext.Console.Write("Sending Resolve:");
            System.Ext.Console.Write(message);

            // Create a new UdpClient
            using(Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
            {
                IPEndPoint localEP = new IPEndPoint(IPAddress.Parse(WsNetworkServices.GetLocalIPV4Address()), m_discoResponsePort);
                udpClient.Bind(localEP);

                // Very important - Set default multicast interface for the underlying socket
                udpClient.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)WsNetworkServices.GetLocalIPV4AddressValue());
                udpClient.ReceiveTimeout = m_receiveTimeout;

                // Random back off implemented as per soap over udp specification
                // for unreliable multicast message exchange
                Thread th = SendWithBackoff(message, udpClient);

                // Wait for resolve match as long a timeout has not expired
                byte[] resolveResponse = new byte[c_MaxUdpPacketSize];
                EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
                int responseLength;
                DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(m_version);
                
                while (true)
                {
                    // Since MF sockets does not have an IOControl method catch 10054 to get around the problem
                    // with Upd and ICMP.
                    try
                    {
                        // Wait for response
                        responseLength = udpClient.ReceiveFrom(resolveResponse, c_MaxUdpPacketSize, SocketFlags.None, ref remoteEP);
                    }
                    catch (SocketException se)
                    {
                        if ((SocketError)se.ErrorCode == SocketError.ConnectionReset)
                        {
                            Thread.Sleep(100);
                            continue;
                        }

                        if((SocketError)se.ErrorCode == SocketError.TimedOut)
                            break;
                        
                        throw se;
                    }

                    // If we received process resolve match
                    if (responseLength > 0)
                    {
                        System.Ext.Console.Write("ResolveMatches Response From: " + ((IPEndPoint)remoteEP).Address.ToString());
                        System.Ext.Console.Write(resolveResponse);

                        try
                        {
                            WsWsaHeader header = new WsWsaHeader();
                            
                            XmlReader reader = WsSoapMessageParser.ParseSoapMessage(resolveResponse, ref header, m_version);
                            
                            WsMessage msg = new WsMessage(header, null, WsPrefix.Wsdp);

                            msg.Reader = reader;

                            resolveMatch = soapProcessor.ProcessResolveMatch(msg, messageID, (IPEndPoint)remoteEP, messageCheck);
                            if (resolveMatch != null)
                                break;
                        }
                        catch (Exception e)
                        {
                            System.Ext.Console.Write(e.Message);
                        }
                    }
                }
                
                th.Join();
            }

            // Display results
            if (resolveMatch == null)
                System.Ext.Console.Write("Resolve timed out.");

            return resolveMatch;
        }
        /// <summary>
        /// Sends a Probe request and parses ProbeMatches responses.
        /// </summary>
        /// <param name="filters">
        /// A DpwsServiceTypes object containing a collection of types a service must support to signal a match.
        /// Null = any type.
        /// </param>
        /// <param name="maxProbeMatches">
        /// An integer representing the maximum number of matches to reveive within the timout period. Pass 0 to receive
        /// as many matches as possible before the timeout expires.
        /// </param>
        /// <param name="timeout">
        /// An integer specifying a request timeout in milliseconds. Pass -1 to wait ReceiveTimeout.
        /// </param>
        /// <remarks>
        /// A Probe is used to discover services on a network. The Probe method sends a UDP request to the
        /// Dpws multicast address, 239.255.255.250:3702. Any service that implements types specified in the
        /// filters parameter should respond with a ProbeMatches message. The ProbeMatches mesgage is unicast
        /// back to the that client that made the request. If a null filter is supplied any Dpws complient
        /// service should reply with a ProbeMatches reponse. Probe waits DpwsDiceoveryCleint.ReceiveTimout
        /// for probe matches.
        /// </remarks>
        /// <returns>
        /// A collection of ProbeMatches objects.  A ProbeMatch object contains endpoint details used
        /// used to locate the actual service on a network and the types supported by the service.
        /// </returns>
        public DpwsServiceDescriptions Probe(DpwsServiceTypes filters, int maxProbeMatches, int timeout)
        {
            // Build the probe request message
            WsMessageCheck messageCheck = new WsMessageCheck();
            string messageID = null;
            WsMessage probeRequest = BuildProbeRequest(DiscoVersion.DiscoveryWellKnownAddress, filters, out messageID);
            DpwsServiceDescriptions probeMatches = new DpwsServiceDescriptions();

            System.Ext.Console.Write("");
            System.Ext.Console.Write("Sending Probe:");
            System.Ext.Console.Write(probeRequest.Body as byte[]);
            System.Ext.Console.Write("");

            // Create a new UdpClient
            using(Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
            {
                IPEndPoint localEP = new IPEndPoint(IPAddress.Parse(WsNetworkServices.GetLocalIPV4Address()), m_discoResponsePort);
                udpClient.Bind(localEP);

                // Very important - Set default multicast interface for the underlying socket
                udpClient.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)WsNetworkServices.GetLocalIPV4AddressValue());
                udpClient.ReceiveTimeout = timeout;

                // Random back off implemented as per soap over udp specification
                // for unreliable multicast message exchange
                Thread th = SendWithBackoff((byte[])probeRequest.Body, udpClient);

                // Create probe matches collection and set expiration loop timer
                byte[] probeResponse = new byte[c_MaxUdpPacketSize];
                EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
                int responseLength;

                DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(m_version);

                while (true)
                {
                    // Since MF sockets does not have an IOControl method catch 10054 to get around the problem
                    // with Upd and ICMP.
                    try
                    {
                        // Wait for response
                        responseLength = udpClient.ReceiveFrom(probeResponse, c_MaxUdpPacketSize, SocketFlags.None, ref remoteEP);
                    }
                    catch (SocketException se)
                    {
                        if ((SocketError)se.ErrorCode == SocketError.ConnectionReset)
                        {
                            Thread.Sleep(100);
                            continue;
                        }

                        // Timeout
                        if ((SocketError)se.ErrorCode == SocketError.TimedOut)
                            break;

                        throw se;
                    }

                    // If we received process probe match
                    if (responseLength > 0)
                    {
                        System.Ext.Console.Write("");
                        System.Ext.Console.Write("ProbeMatches Response From: " + ((IPEndPoint)remoteEP).Address.ToString());
                        System.Ext.Console.Write(probeResponse);

                        // Process the response
                        try
                        {
                            WsWsaHeader header = new WsWsaHeader();
                            
                            XmlReader reader = WsSoapMessageParser.ParseSoapMessage(probeResponse, ref header, m_version);
                            
                            WsMessage msg = new WsMessage(header, null, WsPrefix.Wsdp);

                            msg.Reader = reader;

                            DpwsServiceDescriptions tempMatches = soapProcessor.ProcessProbeMatch(msg, messageID, (IPEndPoint)remoteEP, messageCheck);
                            if (tempMatches != null)
                            {
                                int count = maxProbeMatches < tempMatches.Count ? maxProbeMatches : tempMatches.Count;

                                for (int i = 0; i < count; i++)
                                {
                                    probeMatches.Add(tempMatches[i]);
                                }
                                maxProbeMatches -= count;
                            }
                        }
                        catch (Exception e)
                        {
                            System.Ext.Console.Write("");
                            System.Ext.Console.Write(e.Message);
                            System.Ext.Console.Write("");
                        }

                        // If maxProbeRequest is set check count
                        if (maxProbeMatches <= 0)
                        {
                            break;
                        }
                        
                    }
                }

                th.Join();
            }

            // Display results
            if (probeMatches.Count == 0)
                System.Ext.Console.Write("Probe timed out.");
            else
                System.Ext.Console.Write("Received " + probeMatches.Count + " probeMatches matches.");

            return probeMatches;
        }
        /// <summary>
        /// Sends a directed Resolve request and parses ResolveMatch response.
        /// </summary>
        /// <param name="endpointAddress">
        /// A string containing a Dpws devices transport endpoint address.
        /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="serviceAddress">
        /// A string containing the address of a service that will handle the resolve request.
        /// For example: urn:uuid:2bcdd1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="targetServiceAddress">
        /// A string containing the address of a service that can process the resolve request.
        /// For example: urn:uuid:3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <remarks>
        /// A Resolve is used to resolve the transport address of a know service. The request contains a service
        /// address aquired from configuration or a previous Resolve or Metadata Get request.
        /// The DirectedResolve method sends a Http request to the specified endpoint address.
        /// If the endpoint contains a device with this address receives the request, it must send a unicast ResolveMatches
        /// response back to the client that made the request.  
        /// </remarks>
        /// <returns>
        /// A collection of ResolveMatches objects. A ResolveMatch object contains endpoint details used
        /// used to locate the actual service on a network and the types supported by the service. 
        /// </returns>
        public DpwsServiceDescription DirectedResolve(string endpointAddress, string serviceAddress, string targetServiceAddress)
        {
            String messageID = "";
            WsMessage resolveRequest = BuildResolveRequest(targetServiceAddress, serviceAddress, ref messageID);

            if (resolveRequest == null)
                return null;

            System.Ext.Console.Write("");
            System.Ext.Console.Write("Sending Resolve:");
            System.Ext.Console.Write(resolveRequest.Body as byte[]);

            // Create an http client and send the resolve request. Use a WspHttpClient to get an array response.
            WsHttpClient httpClient = new WsHttpClient(m_version);

            WsMessage resolveResponse = httpClient.SendRequest(resolveRequest, new Uri(endpointAddress));

            DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(m_version);
            DpwsServiceDescription resolveMatch = soapProcessor.ProcessResolveMatch(resolveResponse, messageID, null, null);
            return resolveMatch;
        }
        /// <summary>
        /// Sends a directed Probe request and parses ProbeMatches responses.
        /// </summary>
        /// <param name="endpointAddress">
        /// A string containing a Dpws devices transport endpoint address.
        /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="targetServiceAddress">
        /// A string containing the target service address to probe for.
        /// For example: urn:uuid:3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="filters">
        /// A DpwsServiceTypes object containing a collection of types a service must support to signal a match.
        /// Null = any type.
        /// </param>
        /// <remarks>
        /// A directed Probe is used to discover services on a network. The DirectedProbe method sends a
        /// HTTP request to the service specified endpointAddress parameter. A service at the endpoint that
        /// implements matching types specified in the filters parameter should respond with a ProbeMatches
        /// message. The ProbeMatches mesgage is returned as the response to the DirectedProbe request.
        /// If a null filter is supplied any Dpws complient service should reply with a ProbeMatches reponse.
        /// This method is used to directly ask for service endpoint information.
        /// </remarks>
        /// <returns>
        /// A collection of ProbeMatches objects.  A ProbeMatch object contains endpoint details used
        /// used to locate the actual service on a network and the types supported by the service.
        /// </returns>
        /// <exception cref="InvalidOperationException">If a fault response is received.</exception>
        public DpwsServiceDescriptions DirectedProbe(string endpointAddress, string targetServiceAddress, DpwsServiceTypes filters)
        {
            // Build the probe request message
            string messageID = null;
            WsMessage probeRequest = BuildProbeRequest(targetServiceAddress, filters, out messageID);

            System.Ext.Console.Write("");
            System.Ext.Console.Write("Sending DirectedProbe:");
            System.Ext.Console.Write(probeRequest.Body as byte[]);
            System.Ext.Console.Write("");

            // Create an http client and send the probe request. Use a WspHttpClient to get an array response.
            WsHttpClient httpClient = new WsHttpClient(m_version);

            WsMessage probeResponse = httpClient.SendRequest(probeRequest, new Uri(endpointAddress));

            // Build probe matches collection
            DpwsServiceDescriptions probeMatches = new DpwsServiceDescriptions();
            DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(m_version);
            if (probeResponse != null)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("ProbeMatches Response From: " + endpointAddress);
                System.Ext.Console.Write(probeResponse.Body as byte[]);

                try
                {
                    DpwsServiceDescriptions tempMatches = soapProcessor.ProcessProbeMatch(probeResponse, messageID, null, null);
                    if (tempMatches != null)
                    {
                        int count = tempMatches.Count;
                        for (int i = 0; i < count; i++)
                        {
                            probeMatches.Add(tempMatches[i]);
                        }
                    }
                }
                catch (Exception e)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write(e.Message);
                    System.Ext.Console.Write("");
                }
            }

            if (probeMatches.Count == 0)
                return null;
            else
                return probeMatches;
        }
Example #8
0
        /// <summary>
        /// Use to request metadata from a devices hosted service endpoint.
        /// </summary>
        /// <param name="serviceAddress">
        /// A string containing the transport address of a service endpoint. For Dpws the address represents
        /// a devices transport address.
        /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <returns>
        /// A collection of DpwsMetadata objects containing endpoint details about services hosted by a device.
        /// </returns>
        public DpwsMetadata Get(string serviceAddress)
        {
            // Convert the address string to a Uri
            Uri serviceUri = null;
            try
            {
                serviceUri = new Uri(serviceAddress);
                if (serviceUri.Scheme != "http")
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Invalid serviceAddress. Must be a Uri. Http Uri schemes only.");
                    System.Ext.Console.Write("");
                    return null;
                }
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write(e.Message);
                System.Ext.Console.Write("");
                return null;
            }

            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long startTime = timeDebuger.ResetStartTime("");

            // Build Get Request
            MemoryStream soapStream = new MemoryStream();
            XmlWriter xmlWriter = XmlWriter.Create(soapStream);

            WsWsaHeader header = new WsWsaHeader(
                WsWellKnownUri.WstNamespaceUri + "/Get",            // Action
                null,                                               // RelatesTo
                "urn:uuid:" + serviceUri.AbsolutePath.Substring(1), // To
                WsWellKnownUri.WsaAnonymousUri,                     // ReplyTo
                null, null);                                        // From, Any

            String messageID = WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter,
                WsSoapMessageWriter.Prefixes.None, null, header, null);

            // Performance debuging
            timeDebuger.PrintElapsedTime("*****Write Header Took");

            // Performance debuging
            timeDebuger.PrintElapsedTime("*****Write Body Took");

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

            // Performance debuging
            timeDebuger.PrintTotalTime(startTime, "***Get Message Build Took");

            // Flush and close writer
            xmlWriter.Flush();
            xmlWriter.Close();

            // Create an Http client and send Get request
            WsHttpClient httpClient = new WsHttpClient();
            byte[] getResponse = null;
            try
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Sending Get to: " + serviceAddress);
                getResponse = httpClient.SendRequest(soapStream.ToArray(), serviceAddress, false, false);
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Get failed. " + e.Message);

                return null;
            }

            // If a get response is received process it and return DpwsMetadata object
            DpwsMetadata metadata = null;
            if (getResponse == null)
                return null;
            else
            {
                System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(getResponse)));
                System.Ext.Console.Write("");
                DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor();
                try
                {
                    metadata = soapProcessor.ProcessGetResponse(getResponse, messageID);
                }
                catch (Exception e)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Get response parser threw an exception. " + e.Message);
                    return null;
                }
            }

            return metadata;
        }
Example #9
0
        /// <summary>
        /// Use to send a resolve request to the ws-discovery address and receive a resolve match.
        /// </summary>
        /// <param name="message">A byte array containing a the resolve message.</param>
        /// <param name="messageID">
        /// A string containing the message ID of a resolve request. This ID will be used to validate against
        /// a ResolveMatch received if it don't match, the ResolveMatch is discarded.
        /// </param>
        /// <param name="timeout">
        /// A DateTime value containing the length of time this request will wait for resolve match.
        /// until the timeout value has expired.
        /// </param>
        /// <returns>A resolve match object.</returns>
        private DpwsServiceDescription SendResolveRequest(byte[] message, string messageID, long timeout)
        {
            WsMessageCheck messageCheck = new WsMessageCheck();

            System.Ext.Console.Write("");
            System.Ext.Console.Write("Sending Resolve:");
            System.Ext.Console.Write(new string(new UTF8Encoding().GetChars(message)));

            // Create a new UdpClient
            Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint localEP = new IPEndPoint(IPAddress.Any, m_discoResponsePort);
            udpClient.Bind(localEP);

            // Very important - Set default multicast interface for the underlying socket
            byte[] ipBytes = IPAddress.Parse(WsNetworkServices.GetLocalIPV4Address()).GetAddressBytes();
            long longIP = (long)((ipBytes[0] + (ipBytes[1] << 0x08) + (ipBytes[2] << 0x10) + (ipBytes[3] << 0x18)) & 0xFFFFFFFF);
            udpClient.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)longIP);

            // Random back off implemented as per soap over udp specification
            // for unreliable multicast message exchange
            SendWithBackoff(message, udpClient);

            // Wait for resolve match as long a timeout has not expired
            DpwsServiceDescription resolveMatch = null;
            byte[] resolveResponse = new byte[c_MaxUdpPacketSize];
            EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
            int responseLength;
            long endTime = (long)(DateTime.Now.Ticks + (timeout * 10000));
            DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor();
            while (DateTime.Now.Ticks < endTime)
            {
                if (udpClient.Available > 0)
                {
                    // Since MF sockets does not have an IOControl method catch 10054 to get around the problem
                    // with Upd and ICMP.
                    try
                    {
                        // Wait for response
                        responseLength = udpClient.ReceiveFrom(resolveResponse, c_MaxUdpPacketSize, SocketFlags.None, ref remoteEP);
                    }
                    catch (SocketException se)
                    {
                        if (se.ErrorCode == 10054)
                            continue;
                        throw se;
                    }

                    // If we received process resolve match
                    if (responseLength > 0)
                    {
                        System.Ext.Console.Write("");
                        System.Ext.Console.Write("ResolveMatches Response From: " + ((IPEndPoint)remoteEP).Address.ToString());
                        System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(resolveResponse)));

                        try
                        {
                            resolveMatch = soapProcessor.ProcessResolveMatch(resolveResponse, messageID, (IPEndPoint)remoteEP, messageCheck);
                            if (resolveMatch != null)
                                break;
                        }
                        catch (Exception e)
                        {
                            System.Ext.Console.Write("");
                            System.Ext.Console.Write(e.Message);
                            System.Ext.Console.Write("");
                        }
                    }
                }

                Thread.Sleep(10);
            }

            udpClient.Close();
            udpClient = null;

            // Display results
            if (resolveMatch == null)
                System.Ext.Console.Write("Resolve timed out.");

            return resolveMatch;
        }
Example #10
0
        /// <summary>
        /// Sends a Probe request and parses ProbeMatches responses.
        /// </summary>
        /// <param name="filters">
        /// A DpwsServiceTypes object containing a collection of types a service must support to signal a match.
        /// Null = any type.
        /// </param>
        /// <param name="maxProbeMatches">
        /// An integer representing the maximum number of matches to reveive within the timout period. Pass 0 to receive
        /// as many matches as possible before the timeout expires.
        /// </param>
        /// <param name="timeout">
        /// An integer specifying a request timeout in milliseconds. Pass -1 to wait ReceiveTimeout.
        /// </param>
        /// <remarks>
        /// A Probe is used to discover services on a network. The Probe method sends a UDP request to the
        /// Dpws multicast address, 239.255.255.250:3702. Any service that implements types specified in the
        /// filters parameter should respond with a ProbeMatches message. The ProbeMatches mesgage is unicast
        /// back to the that client that made the request. If a null filter is supplied any Dpws complient
        /// service should reply with a ProbeMatches reponse. Probe waits DpwsDiceoveryCleint.ReceiveTimout
        /// for probe matches.
        /// </remarks>
        /// <returns>
        /// A collection of ProbeMatches objects.  A ProbeMatch object contains endpoint details used
        /// used to locate the actual service on a network and the types supported by the service.
        /// </returns>
        public DpwsServiceDescriptions Probe(DpwsServiceTypes filters, int maxProbeMatches, int timeout)
        {
            // Build the probe request message
            WsMessageCheck messageCheck = new WsMessageCheck();
            string messageID = null;
            byte[] probeRequest = BuildProbeRequest(DiscoVersion.WellKnownAddress, filters, out messageID);

            System.Ext.Console.Write("");
            System.Ext.Console.Write("Sending Probe:");
            System.Ext.Console.Write(new string(new UTF8Encoding().GetChars(probeRequest)));
            System.Ext.Console.Write("");

            // Create a new UdpClient
            Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint localEP = new IPEndPoint(IPAddress.Any, m_discoResponsePort);
            udpClient.Bind(localEP);

            // Very important - Set default multicast interface for the underlying socket
            byte[] ipBytes = IPAddress.Parse(WsNetworkServices.GetLocalIPV4Address()).GetAddressBytes();
            long longIP = (long)((ipBytes[0] + (ipBytes[1] << 0x08) + (ipBytes[2] << 0x10) + (ipBytes[3] << 0x18)) & 0xFFFFFFFF);
            udpClient.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)longIP);

            // Random back off implemented as per soap over udp specification
            // for unreliable multicast message exchange
            SendWithBackoff(probeRequest, udpClient);

            // Create probe matches collection and set expiration loop timer
            DpwsServiceDescriptions probeMatches = new DpwsServiceDescriptions();
            byte[] probeResponse = new byte[c_MaxUdpPacketSize];
            EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
            int responseLength;

            // Multiply receive time by 10000 to convert milliseconds to 100 nano ticks
            long endTime = (long)(DateTime.Now.Ticks + (timeout < 0 ? m_receiveTimeout * 10000 : timeout * 10000));
            DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor();

            // Build probe matches collection as long as timeout has not expired
            int noReceived = 0;

            while (DateTime.Now.Ticks < endTime)
            {
                if (udpClient.Available > 0)
                {
                    // If maxProbeRequest is set check count
                    if (maxProbeMatches > 0)
                    {
                        if (noReceived > maxProbeMatches)
                            break;
                    }

                    // Since MF sockets does not have an IOControl method catch 10054 to get around the problem
                    // with Upd and ICMP.
                    try
                    {
                        // Wait for response
                        responseLength = udpClient.ReceiveFrom(probeResponse, c_MaxUdpPacketSize, SocketFlags.None, ref remoteEP);
                    }
                    catch (SocketException se)
                    {
                        if (se.ErrorCode == 10054)
                            continue;
                        throw se;
                    }

                    // If we received process probe match
                    if (responseLength > 0)
                    {
                        System.Ext.Console.Write("");
                        System.Ext.Console.Write("ProbeMatches Response From: " + ((IPEndPoint)remoteEP).Address.ToString());
                        System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(probeResponse)));

                        // Process the response
                        try
                        {
                            DpwsServiceDescriptions tempMatches = soapProcessor.ProcessProbeMatch(probeResponse, messageID, (IPEndPoint)remoteEP, messageCheck);
                            if (tempMatches != null)
                            {
                                int count = tempMatches.Count;
                                for (int i = 0; i < count; i++)
                                {
                                    probeMatches.Add(tempMatches[i]);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            System.Ext.Console.Write("");
                            System.Ext.Console.Write(e.Message);
                            System.Ext.Console.Write("");
                        }

                        // Increment the number received counter
                        ++noReceived;
                    }
                }
                else
                {
                    Thread.Sleep(1);
                }
            }

            udpClient.Close();
            udpClient = null;

            // Display results
            if (probeMatches == null)
                System.Ext.Console.Write("Probe timed out.");
            else
                System.Ext.Console.Write("Received " + probeMatches.Count + " probeMatches matches.");

            return probeMatches;
        }
Example #11
0
        /// <summary>
        /// Sends a directed Resolve request and parses ResolveMatch response.
        /// </summary>
        /// <param name="endpointAddress">
        /// A string containing a Dpws devices transport endpoint address.
        /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="serviceAddress">
        /// A string containing the address of a service that will handle the resolve request.
        /// For example: urn:uuid:2bcdd1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="targetServiceAddress">
        /// A string containing the address of a service that can process the resolve request.
        /// For example: urn:uuid:3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <remarks>
        /// A Resolve is used to resolve the transport address of a know service. The request contains a service
        /// address aquired from configuration or a previous Resolve or Metadata Get request.
        /// The DirectedResolve method sends a Http request to the specified endpoint address.
        /// If the endpoint contains a device with this address receives the request, it must send a unicast ResolveMatches
        /// response back to the client that made the request.  
        /// </remarks>
        /// <returns>
        /// A collection of ResolveMatches objects. A ResolveMatch object contains endpoint details used
        /// used to locate the actual service on a network and the types supported by the service. 
        /// </returns>
        public DpwsServiceDescription DirectedResolve(string endpointAddress, string serviceAddress, string targetServiceAddress)
        {
            String messageID = "";
            byte[] resolveRequest = BuildResolveRequest(targetServiceAddress, serviceAddress, ref messageID);

            if (resolveRequest == null)
                return null;

            System.Ext.Console.Write("");
            System.Ext.Console.Write("Sending Resolve:");
            System.Ext.Console.Write(new string(new UTF8Encoding().GetChars(resolveRequest)));

            // Create an http client and send the resolve request. Use a WspHttpClient to get an array response.
            WsHttpClient httpClient = new WsHttpClient();
            byte[] resolveResponse = httpClient.SendRequest(resolveRequest, endpointAddress, false, false);
            DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor();
            DpwsServiceDescription resolveMatch = soapProcessor.ProcessResolveMatch(resolveResponse, messageID, null, null);
            return resolveMatch;
        }
Example #12
0
        /// <summary>
        /// Use to request metadata from a devices hosted service endpoint.
        /// </summary>
        /// <param name="serviceAddress">
        /// A string containing the transport address of a service endpoint. For Dpws the address represents
        /// a devices transport address.
        /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <returns>
        /// A collection of DpwsMetadata objects containing endpoint details about services hosted by a device.
        /// </returns>
        public DpwsMetadata Get(string serviceAddress)
        {
            // Convert the address string to a Uri
            Uri serviceUri = null;

            try
            {
                serviceUri = new Uri(serviceAddress);
                if (serviceUri.Scheme != "http")
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Invalid serviceAddress. Must be a Uri. Http Uri schemes only.");
                    System.Ext.Console.Write("");
                    return(null);
                }
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write(e.Message);
                System.Ext.Console.Write("");
                return(null);
            }

            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long        startTime   = timeDebuger.ResetStartTime("");

            // Build Get Request
            MemoryStream soapStream = new MemoryStream();
            XmlWriter    xmlWriter  = XmlWriter.Create(soapStream);

            WsWsaHeader header = new WsWsaHeader(
                WsWellKnownUri.WstNamespaceUri + "/Get",            // Action
                null,                                               // RelatesTo
                "urn:uuid:" + serviceUri.AbsolutePath.Substring(1), // To
                WsWellKnownUri.WsaAnonymousUri,                     // ReplyTo
                null, null);                                        // From, Any

            String messageID = WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter,
                                                                         WsSoapMessageWriter.Prefixes.None, null, header, null);

            // Performance debuging
            timeDebuger.PrintElapsedTime("*****Write Header Took");

            // Performance debuging
            timeDebuger.PrintElapsedTime("*****Write Body Took");

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

            // Performance debuging
            timeDebuger.PrintTotalTime(startTime, "***Get Message Build Took");

            // Flush and close writer
            xmlWriter.Flush();
            xmlWriter.Close();

            // Create an Http client and send Get request
            WsHttpClient httpClient = new WsHttpClient();

            byte[] getResponse = null;
            try
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Sending Get to: " + serviceAddress);
                getResponse = httpClient.SendRequest(soapStream.ToArray(), serviceAddress, false, false);
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Get failed. " + e.Message);

                return(null);
            }

            // If a get response is received process it and return DpwsMetadata object
            DpwsMetadata metadata = null;

            if (getResponse == null)
            {
                return(null);
            }
            else
            {
                System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(getResponse)));
                System.Ext.Console.Write("");
                DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor();
                try
                {
                    metadata = soapProcessor.ProcessGetResponse(getResponse, messageID);
                }
                catch (Exception e)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Get response parser threw an exception. " + e.Message);
                    return(null);
                }
            }

            return(metadata);
        }
        /// <summary>
        /// Use to request metadata from a devices hosted service endpoint.
        /// </summary>
        /// <param name="serviceAddress">
        /// A string containing the transport address of a service endpoint. For Dpws the address represents
        /// a devices transport address.
        /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <returns>
        /// A collection of DpwsMetadata objects containing endpoint details about services hosted by a device.
        /// </returns>
        public DpwsMetadata Get(string serviceAddress)
        {
            // Convert the address string to a Uri
            Uri serviceUri = null;

            try
            {
                serviceUri = new Uri(serviceAddress);
                if (serviceUri.Scheme != "http")
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Invalid serviceAddress. Must be a Uri. Http Uri schemes only.");
                    System.Ext.Console.Write("");
                    return(null);
                }
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write(e.Message);
                System.Ext.Console.Write("");
                return(null);
            }

            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long        startTime   = timeDebuger.ResetStartTime("");

            // Build Get Request
            using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsWsaHeader header = new WsWsaHeader(
                    WsWellKnownUri.WstNamespaceUri + "/Get",            // Action
                    null,                                               // RelatesTo
                    "urn:uuid:" + serviceUri.AbsolutePath.Substring(1), // To
                    m_version.AnonymousUri,                             // ReplyTo
                    null, null);                                        // From, Any

                WsMessage msg = new WsMessage(header, null, WsPrefix.None, null, null);

                WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version);
                String messageID        = smw.WriteSoapMessageStart(xmlWriter, msg);

                // Performance debuging
                timeDebuger.PrintElapsedTime("*****Write Header Took");

                // Performance debuging
                timeDebuger.PrintElapsedTime("*****Write Body Took");

                smw.WriteSoapMessageEnd(xmlWriter);

                // Performance debuging
                timeDebuger.PrintTotalTime(startTime, "***Get Message Build Took");

                // Create an Http client and send Get request
                WsHttpClient httpClient = new WsHttpClient(m_version);

                System.Ext.Console.Write("");
                System.Ext.Console.Write("Sending Get to: " + serviceAddress);

                msg.Body = xmlWriter.ToArray();

                WsMessage getResponse = httpClient.SendRequest(msg, new Uri(serviceAddress));

                // If a get response is received process it and return DpwsMetadata object
                DpwsMetadata metadata = null;
                if (getResponse == null || getResponse.Body == null)
                {
                    return(null);
                }
                else
                {
                    DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(m_version);
                    try
                    {
                        System.Ext.Console.Write(getResponse.Body as byte[]);
                        System.Ext.Console.Write("");

                        metadata = soapProcessor.ProcessGetResponse((byte[])getResponse.Body, messageID);
                    }
                    catch (Exception e)
                    {
                        System.Ext.Console.Write("");
                        System.Ext.Console.Write("Get response parser threw an exception. " + e.Message);
                        return(null);
                    }
                }

                return(metadata);
            }
        }
Example #14
0
        /// <summary>
        /// Use to send a resolve request to the ws-discovery address and receive a resolve match.
        /// </summary>
        /// <param name="message">A byte array containing a the resolve message.</param>
        /// <param name="messageID">
        /// A string containing the message ID of a resolve request. This ID will be used to validate against
        /// a ResolveMatch received if it don't match, the ResolveMatch is discarded.
        /// </param>
        /// <param name="timeout">
        /// A DateTime value containing the length of time this request will wait for resolve match.
        /// until the timeout value has expired.
        /// </param>
        /// <returns>A resolve match object.</returns>
        private DpwsServiceDescription SendResolveRequest(byte[] message, string messageID, long timeout)
        {
            WsMessageCheck messageCheck = new WsMessageCheck();

            System.Ext.Console.Write("");
            System.Ext.Console.Write("Sending Resolve:");
            System.Ext.Console.Write(new string(new UTF8Encoding().GetChars(message)));

            // Create a new UdpClient
            Socket     udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint localEP   = new IPEndPoint(IPAddress.Any, m_discoResponsePort);

            udpClient.Bind(localEP);

            // Very important - Set default multicast interface for the underlying socket
            byte[] ipBytes = IPAddress.Parse(WsNetworkServices.GetLocalIPV4Address()).GetAddressBytes();
            long   longIP  = (long)((ipBytes[0] + (ipBytes[1] << 0x08) + (ipBytes[2] << 0x10) + (ipBytes[3] << 0x18)) & 0xFFFFFFFF);

            udpClient.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)longIP);

            // Random back off implemented as per soap over udp specification
            // for unreliable multicast message exchange
            SendWithBackoff(message, udpClient);

            // Wait for resolve match as long a timeout has not expired
            DpwsServiceDescription resolveMatch = null;

            byte[]   resolveResponse = new byte[c_MaxUdpPacketSize];
            EndPoint remoteEP        = new IPEndPoint(IPAddress.Any, 0);
            int      responseLength;
            long     endTime = (long)(DateTime.Now.Ticks + (timeout * 10000));
            DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor();

            while (DateTime.Now.Ticks < endTime)
            {
                if (udpClient.Available > 0)
                {
                    // Since MF sockets does not have an IOControl method catch 10054 to get around the problem
                    // with Upd and ICMP.
                    try
                    {
                        // Wait for response
                        responseLength = udpClient.ReceiveFrom(resolveResponse, c_MaxUdpPacketSize, SocketFlags.None, ref remoteEP);
                    }
                    catch (SocketException se)
                    {
                        if (se.ErrorCode == 10054)
                        {
                            continue;
                        }
                        throw se;
                    }

                    // If we received process resolve match
                    if (responseLength > 0)
                    {
                        System.Ext.Console.Write("");
                        System.Ext.Console.Write("ResolveMatches Response From: " + ((IPEndPoint)remoteEP).Address.ToString());
                        System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(resolveResponse)));

                        try
                        {
                            resolveMatch = soapProcessor.ProcessResolveMatch(resolveResponse, messageID, (IPEndPoint)remoteEP, messageCheck);
                            if (resolveMatch != null)
                            {
                                break;
                            }
                        }
                        catch (Exception e)
                        {
                            System.Ext.Console.Write("");
                            System.Ext.Console.Write(e.Message);
                            System.Ext.Console.Write("");
                        }
                    }
                }

                Thread.Sleep(10);
            }

            udpClient.Close();
            udpClient = null;

            // Display results
            if (resolveMatch == null)
            {
                System.Ext.Console.Write("Resolve timed out.");
            }

            return(resolveMatch);
        }
Example #15
0
        /// <summary>
        /// Sends a Probe request and parses ProbeMatches responses.
        /// </summary>
        /// <param name="filters">
        /// A DpwsServiceTypes object containing a collection of types a service must support to signal a match.
        /// Null = any type.
        /// </param>
        /// <param name="maxProbeMatches">
        /// An integer representing the maximum number of matches to reveive within the timout period. Pass 0 to receive
        /// as many matches as possible before the timeout expires.
        /// </param>
        /// <param name="timeout">
        /// An integer specifying a request timeout in milliseconds. Pass -1 to wait ReceiveTimeout.
        /// </param>
        /// <remarks>
        /// A Probe is used to discover services on a network. The Probe method sends a UDP request to the
        /// Dpws multicast address, 239.255.255.250:3702. Any service that implements types specified in the
        /// filters parameter should respond with a ProbeMatches message. The ProbeMatches mesgage is unicast
        /// back to the that client that made the request. If a null filter is supplied any Dpws complient
        /// service should reply with a ProbeMatches reponse. Probe waits DpwsDiceoveryCleint.ReceiveTimout
        /// for probe matches.
        /// </remarks>
        /// <returns>
        /// A collection of ProbeMatches objects.  A ProbeMatch object contains endpoint details used
        /// used to locate the actual service on a network and the types supported by the service.
        /// </returns>
        public DpwsServiceDescriptions Probe(DpwsServiceTypes filters, int maxProbeMatches, int timeout)
        {
            // Build the probe request message
            WsMessageCheck messageCheck = new WsMessageCheck();
            string         messageID    = null;

            byte[] probeRequest = BuildProbeRequest(DiscoVersion.WellKnownAddress, filters, out messageID);

            System.Ext.Console.Write("");
            System.Ext.Console.Write("Sending Probe:");
            System.Ext.Console.Write(new string(new UTF8Encoding().GetChars(probeRequest)));
            System.Ext.Console.Write("");

            // Create a new UdpClient
            Socket     udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint localEP   = new IPEndPoint(IPAddress.Any, m_discoResponsePort);

            udpClient.Bind(localEP);

            // Very important - Set default multicast interface for the underlying socket
            byte[] ipBytes = IPAddress.Parse(WsNetworkServices.GetLocalIPV4Address()).GetAddressBytes();
            long   longIP  = (long)((ipBytes[0] + (ipBytes[1] << 0x08) + (ipBytes[2] << 0x10) + (ipBytes[3] << 0x18)) & 0xFFFFFFFF);

            udpClient.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)longIP);

            // Random back off implemented as per soap over udp specification
            // for unreliable multicast message exchange
            SendWithBackoff(probeRequest, udpClient);

            // Create probe matches collection and set expiration loop timer
            DpwsServiceDescriptions probeMatches = new DpwsServiceDescriptions();

            byte[]   probeResponse = new byte[c_MaxUdpPacketSize];
            EndPoint remoteEP      = new IPEndPoint(IPAddress.Any, 0);
            int      responseLength;

            // Multiply receive time by 10000 to convert milliseconds to 100 nano ticks
            long endTime = (long)(DateTime.Now.Ticks + (timeout < 0 ? m_receiveTimeout * 10000 : timeout * 10000));
            DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor();

            // Build probe matches collection as long as timeout has not expired
            int noReceived = 0;

            while (DateTime.Now.Ticks < endTime)
            {
                if (udpClient.Available > 0)
                {
                    // If maxProbeRequest is set check count
                    if (maxProbeMatches > 0)
                    {
                        if (noReceived > maxProbeMatches)
                        {
                            break;
                        }
                    }

                    // Since MF sockets does not have an IOControl method catch 10054 to get around the problem
                    // with Upd and ICMP.
                    try
                    {
                        // Wait for response
                        responseLength = udpClient.ReceiveFrom(probeResponse, c_MaxUdpPacketSize, SocketFlags.None, ref remoteEP);
                    }
                    catch (SocketException se)
                    {
                        if (se.ErrorCode == 10054)
                        {
                            continue;
                        }
                        throw se;
                    }

                    // If we received process probe match
                    if (responseLength > 0)
                    {
                        System.Ext.Console.Write("");
                        System.Ext.Console.Write("ProbeMatches Response From: " + ((IPEndPoint)remoteEP).Address.ToString());
                        System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(probeResponse)));

                        // Process the response
                        try
                        {
                            DpwsServiceDescriptions tempMatches = soapProcessor.ProcessProbeMatch(probeResponse, messageID, (IPEndPoint)remoteEP, messageCheck);
                            if (tempMatches != null)
                            {
                                int count = tempMatches.Count;
                                for (int i = 0; i < count; i++)
                                {
                                    probeMatches.Add(tempMatches[i]);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            System.Ext.Console.Write("");
                            System.Ext.Console.Write(e.Message);
                            System.Ext.Console.Write("");
                        }

                        // Increment the number received counter
                        ++noReceived;
                    }
                }
                else
                {
                    Thread.Sleep(1);
                }
            }

            udpClient.Close();
            udpClient = null;

            // Display results
            if (probeMatches == null)
            {
                System.Ext.Console.Write("Probe timed out.");
            }
            else
            {
                System.Ext.Console.Write("Received " + probeMatches.Count + " probeMatches matches.");
            }

            return(probeMatches);
        }
Example #16
0
        /// <summary>
        /// Sends a Probe request and parses ProbeMatches responses.
        /// </summary>
        /// <param name="filters">
        /// A DpwsServiceTypes object containing a collection of types a service must support to signal a match.
        /// Null = any type.
        /// </param>
        /// <param name="maxProbeMatches">
        /// An integer representing the maximum number of matches to reveive within the timout period. Pass 0 to receive
        /// as many matches as possible before the timeout expires.
        /// </param>
        /// <param name="timeout">
        /// An integer specifying a request timeout in milliseconds. Pass -1 to wait ReceiveTimeout.
        /// </param>
        /// <remarks>
        /// A Probe is used to discover services on a network. The Probe method sends a UDP request to the
        /// Dpws multicast address, 239.255.255.250:3702. Any service that implements types specified in the
        /// filters parameter should respond with a ProbeMatches message. The ProbeMatches mesgage is unicast
        /// back to the that client that made the request. If a null filter is supplied any Dpws complient
        /// service should reply with a ProbeMatches reponse. Probe waits DpwsDiceoveryCleint.ReceiveTimout
        /// for probe matches.
        /// </remarks>
        /// <returns>
        /// A collection of ProbeMatches objects.  A ProbeMatch object contains endpoint details used
        /// used to locate the actual service on a network and the types supported by the service.
        /// </returns>
        public DpwsServiceDescriptions Probe(DpwsServiceTypes filters, int maxProbeMatches, int timeout)
        {
            // Build the probe request message
            WsMessageCheck          messageCheck = new WsMessageCheck();
            string                  messageID    = null;
            WsMessage               probeRequest = BuildProbeRequest(DiscoVersion.DiscoveryWellKnownAddress, filters, out messageID);
            DpwsServiceDescriptions probeMatches = new DpwsServiceDescriptions();

            System.Ext.Console.Write("");
            System.Ext.Console.Write("Sending Probe:");
            System.Ext.Console.Write(probeRequest.Body as byte[]);
            System.Ext.Console.Write("");

            // Create a new UdpClient
            using (Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
            {
                // Very important - Set default multicast interface for the underlying socket

                uint       ipLocal = WsNetworkServices.GetLocalIPV4AddressValue();
                IPAddress  localIP = IPAddress.Parse(WsNetworkServices.GetLocalIPV4Address());
                IPEndPoint localEP = new IPEndPoint(localIP, 0);

                udpClient.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)ipLocal);
                udpClient.ReceiveTimeout = timeout;

                udpClient.Bind(localEP);

                // Random back off implemented as per soap over udp specification
                // for unreliable multicast message exchange
                Thread th = SendWithBackoff((byte[])probeRequest.Body, udpClient);

                // Create probe matches collection and set expiration loop timer
                byte[]   probeResponse = new byte[c_MaxUdpPacketSize];
                EndPoint remoteEP      = new IPEndPoint(IPAddress.Any, 0);
                int      responseLength;

                DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(m_version);

                while (true)
                {
                    // Since MF sockets does not have an IOControl method catch 10054 to get around the problem
                    // with Upd and ICMP.
                    try
                    {
                        // Wait for response
                        responseLength = udpClient.ReceiveFrom(probeResponse, c_MaxUdpPacketSize, SocketFlags.None, ref remoteEP);
                    }
                    catch (SocketException se)
                    {
                        if ((SocketError)se.ErrorCode == SocketError.ConnectionReset)
                        {
                            Thread.Sleep(100);
                            continue;
                        }

                        // Timeout
                        if ((SocketError)se.ErrorCode == SocketError.TimedOut)
                        {
                            break;
                        }

                        throw se;
                    }

                    // If we received process probe match
                    if (responseLength > 0)
                    {
                        System.Ext.Console.Write("");
                        System.Ext.Console.Write("ProbeMatches Response From: " + ((IPEndPoint)remoteEP).Address.ToString());
                        System.Ext.Console.Write(probeResponse);

                        // Process the response
                        try
                        {
                            WsWsaHeader header = new WsWsaHeader();

                            XmlReader reader = WsSoapMessageParser.ParseSoapMessage(probeResponse, ref header, m_version);

                            WsMessage msg = new WsMessage(header, null, WsPrefix.Wsdp);

                            msg.Reader = reader;

                            DpwsServiceDescriptions tempMatches = soapProcessor.ProcessProbeMatch(msg, messageID, (IPEndPoint)remoteEP, messageCheck);
                            if (tempMatches != null)
                            {
                                int count = maxProbeMatches < tempMatches.Count ? maxProbeMatches : tempMatches.Count;

                                for (int i = 0; i < count; i++)
                                {
                                    probeMatches.Add(tempMatches[i]);
                                }
                                maxProbeMatches -= count;
                            }
                        }
                        catch (Exception e)
                        {
                            System.Ext.Console.Write("");
                            System.Ext.Console.Write(e.Message);
                            System.Ext.Console.Write("");
                        }

                        // If maxProbeRequest is set check count
                        if (maxProbeMatches <= 0)
                        {
                            break;
                        }
                    }
                }

                th.Join();
            }

            // Display results
            if (probeMatches.Count == 0)
            {
                System.Ext.Console.Write("Probe timed out.");
            }
            else
            {
                System.Ext.Console.Write("Received " + probeMatches.Count + " probeMatches matches.");
            }

            return(probeMatches);
        }
Example #17
0
        /// <summary>
        /// Use to send a resolve request to the ws-discovery address and receive a resolve match.
        /// </summary>
        /// <param name="message">A byte array containing a the resolve message.</param>
        /// <param name="messageID">
        /// A string containing the message ID of a resolve request. This ID will be used to validate against
        /// a ResolveMatch received if it don't match, the ResolveMatch is discarded.
        /// </param>
        /// <param name="timeout">
        /// A DateTime value containing the length of time this request will wait for resolve match.
        /// until the timeout value has expired.
        /// </param>
        /// <returns>A resolve match object.</returns>
        private DpwsServiceDescription SendResolveRequest(byte[] message, string messageID, long timeout)
        {
            WsMessageCheck messageCheck = new WsMessageCheck();

            DpwsServiceDescription resolveMatch = null;

            System.Ext.Console.Write("");
            System.Ext.Console.Write("Sending Resolve:");
            System.Ext.Console.Write(message);

            // Create a new UdpClient
            using (Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
            {
                uint       ipLocal = WsNetworkServices.GetLocalIPV4AddressValue();
                IPAddress  localIP = IPAddress.Parse(WsNetworkServices.GetLocalIPV4Address());
                IPEndPoint localEP = new IPEndPoint(localIP, 0);

                // Very important - Set default multicast interface for the underlying socket
                udpClient.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)ipLocal);
                udpClient.ReceiveTimeout = (int)timeout;

                udpClient.Bind(localEP);

                // Random back off implemented as per soap over udp specification
                // for unreliable multicast message exchange
                Thread th = SendWithBackoff(message, udpClient);

                // Wait for resolve match as long a timeout has not expired
                byte[]   resolveResponse = new byte[c_MaxUdpPacketSize];
                EndPoint remoteEP        = new IPEndPoint(IPAddress.Any, 0);
                int      responseLength;
                DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(m_version);

                while (true)
                {
                    // Since MF sockets does not have an IOControl method catch 10054 to get around the problem
                    // with Upd and ICMP.
                    try
                    {
                        // Wait for response
                        responseLength = udpClient.ReceiveFrom(resolveResponse, c_MaxUdpPacketSize, SocketFlags.None, ref remoteEP);
                    }
                    catch (SocketException se)
                    {
                        if ((SocketError)se.ErrorCode == SocketError.ConnectionReset)
                        {
                            Thread.Sleep(100);
                            continue;
                        }

                        if ((SocketError)se.ErrorCode == SocketError.TimedOut)
                        {
                            break;
                        }

                        throw se;
                    }

                    // If we received process resolve match
                    if (responseLength > 0)
                    {
                        System.Ext.Console.Write("ResolveMatches Response From: " + ((IPEndPoint)remoteEP).Address.ToString());
                        System.Ext.Console.Write(resolveResponse);

                        try
                        {
                            WsWsaHeader header = new WsWsaHeader();

                            XmlReader reader = WsSoapMessageParser.ParseSoapMessage(resolveResponse, ref header, m_version);

                            WsMessage msg = new WsMessage(header, null, WsPrefix.Wsdp);

                            msg.Reader = reader;

                            resolveMatch = soapProcessor.ProcessResolveMatch(msg, messageID, (IPEndPoint)remoteEP, messageCheck);
                            if (resolveMatch != null)
                            {
                                break;
                            }
                        }
                        catch (Exception e)
                        {
                            System.Ext.Console.Write(e.Message);
                        }
                    }
                }

                th.Join();
            }

            // Display results
            if (resolveMatch == null)
            {
                System.Ext.Console.Write("Resolve timed out.");
            }

            return(resolveMatch);
        }
Example #18
0
        /// <summary>
        /// Use to request metadata from a devices hosted service endpoint.
        /// </summary>
        /// <param name="serviceAddress">
        /// A string containing the transport address of a service endpoint. For Dpws the address represents
        /// a devices transport address.
        /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <returns>
        /// A collection of DpwsMetadata objects containing endpoint details about services hosted by a device.
        /// </returns>
        public DpwsMetadata Get(string serviceAddress)
        {
            // Convert the address string to a Uri
            Uri serviceUri = null;
            try
            {
                serviceUri = new Uri(serviceAddress);
                if (serviceUri.Scheme != "http")
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Invalid serviceAddress. Must be a Uri. Http Uri schemes only.");
                    System.Ext.Console.Write("");
                    return null;
                }
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write(e.Message);
                System.Ext.Console.Write("");
                return null;
            }

            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long startTime = timeDebuger.ResetStartTime("");

            // Build Get Request
            using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsWsaHeader header = new WsWsaHeader(
                    WsWellKnownUri.WstNamespaceUri + "/Get",            // Action
                    null,                                               // RelatesTo
                    "urn:uuid:" + serviceUri.AbsolutePath.Substring(1), // To
                    //TODO: should be ROLE???
                    m_version.AnonymousRoleUri,                              // ReplyTo
                    null, null);                                        // From, Any

                WsMessage msg = new WsMessage(header, null, WsPrefix.None, null, null);

                WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version);
                String messageID = smw.WriteSoapMessageStart(xmlWriter, msg);

                // Performance debuging
                timeDebuger.PrintElapsedTime("*****Write Header Took");

                // Performance debuging
                timeDebuger.PrintElapsedTime("*****Write Body Took");

                smw.WriteSoapMessageEnd(xmlWriter);

                // Performance debuging
                timeDebuger.PrintTotalTime(startTime, "***Get Message Build Took");

                // Create an Http client and send Get request
                WsHttpClient httpClient = new WsHttpClient(m_version);

                System.Ext.Console.Write("");
                System.Ext.Console.Write("Sending Get to: " + serviceAddress);

                msg.Body = xmlWriter.ToArray();

                WsMessage getResponse = httpClient.SendRequest(msg, new Uri(serviceAddress));

                // If a get response is received process it and return DpwsMetadata object
                DpwsMetadata metadata = null;
                if (getResponse == null || getResponse.Body == null)
                {
                    return null;
                }
                else
                {
                    DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(m_version);
                    try
                    {
                        System.Ext.Console.Write(getResponse.Body as byte[]);
                        System.Ext.Console.Write("");

                        metadata = soapProcessor.ProcessGetResponse((byte[])getResponse.Body, messageID);
                    }
                    catch (Exception e)
                    {
                        System.Ext.Console.Write("");
                        System.Ext.Console.Write("Get response parser threw an exception. " + e.Message);
                        return null;
                    }
                }

                return metadata;
            }
        }