/// <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>
 /// Called by for each active event sink to send an event message to a listening client.
 /// </summary>
 /// <param name="eventMessage">Byte array containing the event message soap envelope.</param>
 /// <param name="notifyToAddress"></param>
 private void SendEvent(byte[] eventMessage, string notifyToAddress)
 {
     // Parse the http transport address
     if (notifyToAddress.IndexOf("http://") == 0)
     {
         httpClient.SendRequest(eventMessage, notifyToAddress, false, false);
     }
     else
     {
         System.Ext.Console.Write("");
         System.Ext.Console.Write("Unsupported transport address (FireEvent - notifyToAddress: " + notifyToAddress);
         System.Ext.Console.Write("");
         return;
     }
 }
        /// <summary>
        /// Method used to send a soap request over http to a service endpoint.
        /// </summary>
        /// <param name="soapMessage">A byte array contining a soap request message.</param>
        /// <param name="endpointAddress">A string containing the endpoint address of a service that will receive
        /// the request. This must be a transport address in the format http://ip_address:port/service_address.</param>
        /// <param name="isOneway">True = don't wait for response, false means wait for a response.</param>
        /// <param name="isChuncked">If true true the message will be chunk encoded.</param>
        /// <param name="mtomParams">If not null contains parameters required to fix up the http header for mime multipart.</param>
        /// <returns>WsMessage object containing the soap response returned from a service endpoint.</returns>
        private WsMessage SendRequest(byte[] soapMessage, string endpointAddress, bool isOneway, bool isChuncked, WsMtomParams mtomParams)
        {
            if (soapMessage == null)
            {
                throw new ArgumentNullException("DpwsHttpClient.SendRequest - soapMessage must not be null.");
            }
            if (endpointAddress == null)
            {
                throw new ArgumentNullException("DpwsHttpClient.SendRequest - endpointAddress must not be null.");
            }

            // Send the request
            WsMessage response = m_httpClient.SendRequest(soapMessage, endpointAddress, isOneway, isChuncked, mtomParams);

            return(response);
        }
        /// <summary>
        /// Used by the subscription manager to send a subscription end message to a listening client.
        /// </summary>
        /// <param name="eventSink">An event sink object containing the client endpoint information.</param>
        /// <param name="subEndType">A string that specifies the reason fot the subscription end.</param>
        /// <param name="subMangerID">A id used by the client to identify this subcription.</param>
        /// <remarks>If an error occures when sending an event message this method is called to tell
        /// the client this subscription has been expired.
        /// </remarks>
        private void SendSubscriptionEnd(DpwsWseEventSink eventSink, string subEndType, string subMangerID)
        {
            // if we weren't given an EndTo, don't send
            if (eventSink.EndTo == null)
            {
                return;
            }

            // Parse the http transport address
            if (eventSink.EndTo.Address.Scheme == "http")
            {
                WsHttpClient httpClient = new WsHttpClient();
                httpClient.SendRequest(SubscriptionEndResponse(eventSink, subEndType, subMangerID), eventSink.EndTo.Address.AbsoluteUri, true, false);
            }
            else
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Unsupported transport address Subscription EndTo.Address: " + eventSink.EndTo.Address);
                System.Ext.Console.Write("");
                return;
            }
        }
        /// <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 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 get the status of an event subscription.
        /// </summary>
        /// <param name="endpointAddress">
        /// A Uri containing the endpoint address of the service or subscription manager that is currently
        /// maintaining this event subscription on behalf of the device. This address is an http uri
        /// (i.e. http://ip_address:port/serviceID).
        /// </param>
        /// <param name="subscriptionID">
        /// A subscription ID returned from a previous subscribe response. The device uses this ID
        /// to identify a specific event source subscription.
        /// </param>
        /// <returns>
        /// A WsDuration object containing the remaining subscription time for this event subscription, null = infinite.
        /// </returns>
        public WsDuration GetStatus(Uri endpointAddress, string subscriptionID)
        {
            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long        startTime   = timeDebuger.ResetStartTime("");

            // Build Renew request
            using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsXmlNodeList nodeList = new WsXmlNodeList();
                nodeList.Add(new WsXmlNode(WsNamespacePrefix.Wse, "Identifier", null, subscriptionID));

                WsWsaHeader header = new WsWsaHeader(
                    m_version.EventingNamespace + "/GetStatus",  // Action
                    null,                                        // RelatesTo
                    endpointAddress.AbsoluteUri,                 // To
                    null, null, nodeList);                       // ReplyTo, From, Any

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

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

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

                // write body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Body", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "GetStatus", null);
                xmlWriter.WriteString("");
                xmlWriter.WriteEndElement(); // End GetStatus

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

                smw.WriteSoapMessageEnd(xmlWriter);

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

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

                msg.Body = xmlWriter.ToString();

                WsMessage getStatusResponse = httpClient.SendRequest(msg, endpointAddress);

                // If a GetStatus response is received validate the messageID and action and get the remaining
                // event subscription time. If a fault is received print exception and go on.
                if (getStatusResponse == null)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Renew response is null.");
                    return(null);
                }
                else
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Response From: " + endpointAddress.Host);
                    System.Ext.Console.Write(getStatusResponse.Body as byte[]);

                    // Note: Since the response is the same for GetStatus ans it is for Renew reuse the
                    // Renew response parser.
                    try
                    {
                        return(ProcessRenewResponse((byte[])getStatusResponse.Body, messageID));
                    }
                    catch (Exception e)
                    {
                        System.Ext.Console.Write("");
                        System.Ext.Console.Write("Unsubscribe response parsing failed.");
                        System.Ext.Console.Write(e.Message);
                    }
                }
            }

            return(null);
        }
        /// <summary>
        /// Use to unsubscribe from a devices event source.
        /// </summary>
        /// <param name="endpointAddress">
        /// A Uri containing the endpoint address of the service or subscription manager that is currently
        /// maintaining this event subscription on behalf of the device. This address is an http uri
        /// (i.e. http://ip_address:port/serviceID).
        /// </param>
        /// <param name="subscription">An event subscription returned from a previous subscribe call.
        /// The subscription contains among other things a subscription ID used by the subscription manager
        /// to identify a specific event source subscription and the endpoint address of the subscription manager.
        /// </param>
        /// <returns>True if the Unsubscribe request was successful.</returns>
        public bool Unsubscribe(Uri endpointAddress, DpwsEventSubscription subscription)
        {
            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long        startTime   = timeDebuger.ResetStartTime("");

            // Build Unsubscribe Request
            using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsXmlNodeList nodeList = new WsXmlNodeList();
                nodeList.Add(new WsXmlNode(null, "identifier", WsWellKnownUri.WseNamespaceUri, subscription.SubscriptionID));

                WsWsaHeader header = new WsWsaHeader(
                    m_version.EventingNamespace + "/Unsubscribe",            // Action
                    null,                                                    // RelatesTo
                    endpointAddress.AbsoluteUri,                             // To
                    m_version.AddressingNamespace,                           // ReplyTo
                    subscription.SubscriptionManager.Address.AbsoluteUri,    // From
                    nodeList);                                               // Identifier

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

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

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

                // write body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Unsubscribe", null);
                xmlWriter.WriteString("");
                xmlWriter.WriteEndElement(); // End Unsubscribe

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

                smw.WriteSoapMessageEnd(xmlWriter);

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

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

                msg.Body = xmlWriter.ToArray();

                WsMessage unsubscribeResponse = httpClient.SendRequest(msg, endpointAddress);

                // If a unsubscribe response is received simple validate that the messageID and action are correct and
                // If a parsing fault is received print exception and go on.
                if (unsubscribeResponse == null)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Unsubscribe response is null.");
                    return(false);
                }
                else
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Response From: " + endpointAddress.Host);
                    System.Ext.Console.Write(unsubscribeResponse.Body as byte[]);
                    try
                    {
                        return(ProcessUnsubscribeResponse((byte[])unsubscribeResponse.Body, messageID));
                    }
                    catch (Exception e)
                    {
                        System.Ext.Console.Write("");
                        System.Ext.Console.Write("Unsubscribe response parsing failed.");
                        System.Ext.Console.Write(e.Message);
                        return(false);
                    }
                }
            }
        }
        /// <summary>
        /// Use to subscribe to a devices, hosted service event sources.
        /// </summary>
        /// <param name="subscriptionRequest">
        /// A DpwsSubscriptionRequest object containing the address of the service hosting the desired event,
        /// the address where the event is sent, an optional address where subscription end messages are sent,
        /// A subscription expiration (in duration format) and an optional user defined identifier.
        /// </param>
        /// <returns>
        /// A DpwsEventSubscription containing the the subscription managers address, the time when the subscription
        /// expires (duration) and optional reference parameters and properties. Per spec the
        /// sub mananger may assign a different duration value than that specified in the request.
        /// </returns>
        /// <exception cref="ArgumentNullException">If required subscription parameters are not set.</exception>
        public DpwsEventSubscription Subscribe(DpwsSubscribeRequest subscriptionRequest)
        {
            if ((subscriptionRequest.SubscriptionType == null) ||
                (subscriptionRequest.SubscriptionType.TypeName == null) ||
                (subscriptionRequest.SubscriptionType.NamespaceUri == null) ||
                (subscriptionRequest.EndpointAddress == null) ||
                (subscriptionRequest.NotifyTo == null) ||
                (subscriptionRequest.NotifyTo.Address == null))
            {
                throw new ArgumentNullException();
            }

            // Convert the address string to a Uri
            Uri serviceUri = null;

            try
            {
                serviceUri = subscriptionRequest.EndpointAddress;
                if (serviceUri.Scheme != "http")
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Invalid endpoint address. 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("");
            WsMessage   subscribeResponse = null;

            // Build Subscribe Request
            using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsWsaHeader header = new WsWsaHeader(
                    m_version.EventingNamespace + "/Subscribe",     // Action
                    null,                                           // RelatesTo
                    serviceUri.AbsoluteUri,                         // To
                    m_version.AnonymousUri,                         // ReplyTo
                    null, null);                                    // From, Any

                WsXmlNamespaces additionalPrefixes = new WsXmlNamespaces();
                additionalPrefixes.Add(new WsXmlNamespace("myPrefix", subscriptionRequest.SubscriptionType.NamespaceUri));

                WsMessage msg = new WsMessage(header, null, WsPrefix.Wsd | WsPrefix.Wse, additionalPrefixes, null);

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

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

                // write body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Subscribe", null);

                // If EndTo is set write it
                if (subscriptionRequest.EndTo != null)
                {
                    WriteEndpointRef(xmlWriter, subscriptionRequest.EndTo, "EndTo");
                }

                // Add the delivery element and NotifyTo endpoint
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Delivery", null);
                xmlWriter.WriteAttributeString("Mode", m_version.EventingNamespace + "/DeliveryModes/Push");

                // Writer the notify to endpoint
                WriteEndpointRef(xmlWriter, subscriptionRequest.NotifyTo, "NotifyTo");

                xmlWriter.WriteEndElement(); // End Delivery

                // Write Expiration time
                if (subscriptionRequest.Expires != null)
                {
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Expires", null);
                    xmlWriter.WriteString(subscriptionRequest.Expires.DurationString);
                    xmlWriter.WriteEndElement(); // End Expires
                }

                // Write Filter element specifying the event to subscribe to.
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Filter", null);
                xmlWriter.WriteAttributeString("Dialect", m_version.WsdpNamespaceUri + "/Action");
                xmlWriter.WriteString(subscriptionRequest.SubscriptionType.NamespaceUri + "/" + subscriptionRequest.SubscriptionType.TypeName);
                xmlWriter.WriteEndElement(); // End Filter

                xmlWriter.WriteEndElement(); // End Subscribe

                smw.WriteSoapMessageEnd(xmlWriter);

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

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

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

                msg.Body = xmlWriter.ToArray();

                subscribeResponse = httpClient.SendRequest(msg, subscriptionRequest.EndpointAddress);

                // If a subscribe response is received process it and return expiration time the subscription manager
                // actually assigned.
                // If a parsing fault is received print exception and go on.
                DpwsEventSubscription response = null;
                if (subscribeResponse == null)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Subscribe response is null.");
                    return(null);
                }
                else
                {
                    byte[] responseBytes = subscribeResponse.Body as byte[];

                    // It is ok for the service to return a 202 and a 0 length response
                    // if thi is the case just return null
                    if (responseBytes == null || responseBytes.Length == 0)
                    {
                        return(null);
                    }

                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Response From: " + subscriptionRequest.EndpointAddress.Host);
                    System.Ext.Console.Write(responseBytes);
                    try
                    {
                        response = ProcessSubscribeResponse(responseBytes, messageID);
                    }
                    catch (Exception e)
                    {
                        System.Ext.Console.Write("");
                        System.Ext.Console.Write("Subscription response parsing failed.");
                        System.Ext.Console.Write(e.Message);
                    }
                }

                return(response);
            }
        }
        void SimpleServiceClient_HelloEvent(object obj, DpwsServiceDescription helloEventArgs)
        {
            m_receivedHelloEvent = true;
            DpwsMetadata m_mexDetails = null;

            try
            {
                // Print Hello information
                //Log.Comment("");
                //Log.Comment("SimpleService received a hello request.");
                ////Log.Comment("Endpoint address: " + helloEventArgs.Endpoint.Address.AbsoluteUri);
                string types = "";
                int    count = helloEventArgs.ServiceTypes.Count;
                for (int i = 0; i < count; i++)
                {
                    DpwsServiceType type = helloEventArgs.ServiceTypes[i];
                    types += "NamespaceUri: " + type.NamespaceUri + " " + "TypeName: " + type.TypeName + "\n";
                }
                ////Log.Comment("Types: " + types);

                if (helloEventArgs.XAddrs != null)
                {
                    foreach (String xaddr in helloEventArgs.XAddrs)
                    {
                        ////Log.Comment("Xaddrs: " + xaddr);
                    }
                }

                ////Log.Comment("Metadata version: " + helloEventArgs.MetadataVersion);
                ////Log.Comment("");

                // Probe for services. For each valid probe match, print service information.
                DpwsServiceType  searchType  = new DpwsServiceType("SimpleService", "http://schemas.example.org/SimpleService");
                DpwsServiceTypes searchTypes = new DpwsServiceTypes();

                searchTypes.Add(searchType);

                // Accept the first 10 found within the first 10 seconds
                DpwsServiceDescriptions probeMatches = this.DiscoveryClient.Probe(searchTypes, 1, 10000);

                // retry
                if (probeMatches.Count == 0)
                {
                    probeMatches = this.DiscoveryClient.Probe(searchTypes, 1, 10000);
                }

                if (probeMatches != null)
                {
                    // Print the probe match information
                    ////Log.Comment("**********************");
                    ////Log.Comment("ProbeMatches received: " + probeMatches.Count);
                    int probeMatchCount = probeMatches.Count;
                    for (int i = 0; i < probeMatchCount; i++)
                    {
                        DpwsServiceDescription probeMatch = probeMatches[i];
                        ////Log.Comment("");
                        ////Log.Comment("ProbeMatch:");
                        ////Log.Comment("  Endpoint Address = " + probeMatch.Endpoint.Address.AbsoluteUri);
                        ////Log.Comment("  Types:");

                        PrintServiceTypes(probeMatch.ServiceTypes);

                        //////Log.Comment("  Xaddrs:");
                        //foreach (string xaddr in probeMatch.XAddrs)
                        //    //Log.Comment("    TransportAddress = " + xaddr);
                        ////Log.Comment("  Metadata Version = " + probeMatch.MetadataVersion);

                        // Resolve this endpoint
                        DpwsServiceDescription resolveMatch = this.DiscoveryClient.Resolve(probeMatch.Endpoint.Address.AbsoluteUri, 10000);
                        if (resolveMatch != null)
                        {
                            // Print resolve match information
                            ////Log.Comment("");
                            ////Log.Comment("ResolveMatch:");
                            ////Log.Comment("  Endpoint Address = " + resolveMatch.Endpoint.Address.AbsoluteUri);
                            ////Log.Comment("  Types:");

                            PrintServiceTypes(resolveMatch.ServiceTypes);

                            ////Log.Comment("  Xaddrs:");
                            //foreach (string xaddr in resolveMatch.XAddrs)
                            //    //Log.Comment("    TransportAddress = " + xaddr);

                            //Log.Comment("  Metadata Version = " + resolveMatch.MetadataVersion);

                            // For each Xaddr, get metadata
                            foreach (string xaddr in resolveMatch.XAddrs)
                            {
                                // Call Get
                                m_mexDetails = this.MexClient.Get(xaddr);

                                if (m_mexDetails == null)
                                {
                                    ////Log.Comment("Get failed. Address: " + xaddr);
                                }
                                else
                                {
                                    m_getMex = true;

                                    // Display metadata information
                                    ////Log.Comment("  Metadata:");
                                    ////Log.Comment("    ThisModel:");
                                    ////Log.Comment("      Manufacturer: " + m_mexDetails.ThisModel.Manufacturer);
                                    ////Log.Comment("      ManufacturerUrl: " + m_mexDetails.ThisModel.ManufacturerUrl);
                                    ////Log.Comment("      ModelName: " + m_mexDetails.ThisModel.ModelName);
                                    ////Log.Comment("      ModelNumber: " + m_mexDetails.ThisModel.ModelNumber);
                                    ////Log.Comment("      ModelUrl: " + m_mexDetails.ThisModel.ModelUrl);
                                    ////Log.Comment("      PresentationUrl: " + m_mexDetails.ThisModel.PresentationUrl);
                                    ////Log.Comment("    ThisDevice:");
                                    ////Log.Comment("      FirmwareVersion: " + m_mexDetails.ThisDevice.FirmwareVersion);
                                    ////Log.Comment("      FriendlyName: " + m_mexDetails.ThisDevice.FriendlyName);
                                    ////Log.Comment("      SerialNumber: " + m_mexDetails.ThisDevice.SerialNumber);
                                    if (m_mexDetails.Relationship.Host != null)
                                    {
                                        ////Log.Comment("    Host:");
                                        ////Log.Comment("      Service ID: " + m_mexDetails.Relationship.Host.ServiceID);
                                        ////Log.Comment("      Address: " + m_mexDetails.Relationship.Host.EndpointRefs[0].Address.AbsoluteUri);
                                        ////Log.Comment("      Types:");

                                        PrintServiceTypes(m_mexDetails.Relationship.Host.ServiceTypes);
                                    }
                                    if (m_mexDetails.Relationship.HostedServices != null)
                                    {
                                        ////Log.Comment("    HostedServices:");
                                        int hostedServiceCount = m_mexDetails.Relationship.HostedServices.Count;
                                        for (int j = 0; j < hostedServiceCount; j++)
                                        {
                                            DpwsMexService hostedService = m_mexDetails.Relationship.HostedServices[j];

                                            ////Log.Comment("      Service ID: " + hostedService.ServiceID);
                                            ////Log.Comment("      Address: " + hostedService.EndpointRefs[0].Address.AbsoluteUri);
                                            ////Log.Comment("      Types:");

                                            PrintServiceTypes(hostedService.ServiceTypes);
                                        }
                                    }
                                }
                            }

                            if (m_mexDetails != null)
                            {
                                // Look for the SimpleService in the HostedServices collection, create an HTTP
                                // client, call TwoWayRequest on the service endpoint, and display the result.
                                int hostedServiceCount = m_mexDetails.Relationship.HostedServices.Count;
                                for (int j = 0; j < hostedServiceCount; j++)
                                {
                                    DpwsMexService hostedService = m_mexDetails.Relationship.HostedServices[j];

                                    if (hostedService.ServiceTypes["SimpleService"] != null)    // found a SimpleService endpoint
                                    {
                                        string endpointAddress = hostedService.EndpointRefs[0].Address.AbsoluteUri;
                                        ////Log.Comment("");
                                        ////Log.Comment("Calling TwoWayRequest at endpoint: " + endpointAddress);

                                        // Create HttpClient and send request
                                        int x = 150;
                                        int y = 180;

                                        byte[] TwoWayRequest = Build2wayRequest(x, y, endpointAddress);


                                        //Log.Comment(new String(System.Text.Encoding.UTF8.GetChars(TwoWayRequest)));
                                        //DpwsHttpClient httpClient = new DpwsHttpClient();
                                        //DpwsSoapResponse response = httpClient.SendRequest(TwoWayRequest, endpointAddress, false, false);

                                        WsHttpClient httpClient = new WsHttpClient(m_version);
                                        WsMessage    response   = httpClient.SendRequest(new WsMessage(null, TwoWayRequest, WsPrefix.Wsdp), new Uri(endpointAddress));

                                        if (response != null)       // got a response
                                        {
                                            try
                                            {
                                                int sum = Parse2WayResponse(response.Header, response.Reader);
                                                //Log.Comment("");
                                                //Log.Comment("Received sum of " + sum.ToString() + " from " + endpointAddress);
                                                if ((x + y) == sum)
                                                {
                                                    m_twoWay = true;
                                                }
                                            }
                                            finally
                                            {
                                                response.Reader.Close();
                                            }
                                        }
                                    }
                                }
                            }
                            //Log.Comment("");
                        }
                    }
                }
            }
            finally
            {
            }

            if (m_mexDetails != null)
            {
                arHello.Set();
            }
        }
        /// <summary>
        /// Use to get the status of an event subscription.
        /// </summary>
        /// <param name="endpointAddress">
        /// A Uri containing the endpoint address of the service or subscription manager that is currently
        /// maintaining this event subscription on behalf of the device. This address is an http uri
        /// (i.e. http://ip_address:port/serviceID).
        /// </param>
        /// <param name="subscriptionID">
        /// A subscription ID returned from a previous subscribe response. The device uses this ID
        /// to identify a specific event source subscription.
        /// </param>
        /// <returns>
        /// A WsDuration object containing the remaining subscription time for this event subscription, null = infinite.
        /// </returns>
        public WsDuration GetStatus(Uri endpointAddress, string subscriptionID)
        {
            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long        startTime   = timeDebuger.ResetStartTime("");

            // Build Renew request
            MemoryStream soapStream = new MemoryStream();
            XmlWriter    xmlWriter  = XmlWriter.Create(soapStream);

            WsXmlNodeList nodeList = new WsXmlNodeList();

            nodeList.Add(new WsXmlNode("wse", "Identifier", null, subscriptionID));

            WsWsaHeader header = new WsWsaHeader(
                WsWellKnownUri.WseNamespaceUri + "/GetStatus",  // Action
                null,                                           // RelatesTo
                endpointAddress.AbsoluteUri,                    // To
                null, null, nodeList);                          // ReplyTo, From, Any

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

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

            // write body
            xmlWriter.WriteStartElement("soap", "Body", null);
            xmlWriter.WriteStartElement("wse", "GetStatus", null);
            xmlWriter.WriteString("");
            xmlWriter.WriteEndElement(); // End GetStatus

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

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

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

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

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

            byte[] getStatusResponse = null;
            try
            {
                getStatusResponse = httpClient.SendRequest(soapStream.ToArray(), endpointAddress.ToString(), false, false);
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("GetStatus failed. " + e.Message);
                return(null);
            }

            // If a GetStatus response is received validate the messageID and action and get the remaining
            // event subscription time. If a fault is received print exception and go on.
            if (getStatusResponse == null)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Renew response is null.");
                return(null);
            }
            else
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Response From: " + endpointAddress.Host);
                System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(getStatusResponse)));

                // Note: Since the response is the same for GetStatus ans it is for Renew reuse the
                // Renew response parser.
                try
                {
                    return(ProcessRenewResponse(getStatusResponse, messageID));
                }
                catch (Exception e)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Unsubscribe response parsing failed.");
                    System.Ext.Console.Write(e.Message);
                }
            }

            return(null);
        }
        /// <summary>
        /// Use to unsubscribe from a devices event source.
        /// </summary>
        /// <param name="endpointAddress">
        /// A Uri containing the endpoint address of the service or subscription manager that is currently
        /// maintaining this event subscription on behalf of the device. This address is an http uri
        /// (i.e. http://ip_address:port/serviceID).
        /// </param>
        /// <param name="subscription">An event subscription returned from a previous subscribe call.
        /// The subscription contains among other things a subscription ID used by the subscription manager
        /// to identify a specific event source subscription and the endpoint address of the subscription manager.
        /// </param>
        /// <returns>True if the Unsubscribe request was successful.</returns>
        public bool Unsubscribe(Uri endpointAddress, DpwsEventSubscription subscription)
        {
            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long        startTime   = timeDebuger.ResetStartTime("");

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

            WsXmlNodeList nodeList = new WsXmlNodeList();

            nodeList.Add(new WsXmlNode(null, "identifier", WsWellKnownUri.WseNamespaceUri, subscription.SubscriptionID));

            WsWsaHeader header = new WsWsaHeader(
                WsWellKnownUri.WseNamespaceUri + "/Unsubscribe",            // Action
                null,                                                       // RelatesTo
                endpointAddress.AbsoluteUri,                                // To
                WsWellKnownUri.WsaAnonymousUri,                             // ReplyTo
                subscription.SubscriptionManager.Address.AbsoluteUri,       // From
                nodeList);                                                  // Identifier

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

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

            // write body
            xmlWriter.WriteStartElement("wse", "Unsubscribe", null);
            xmlWriter.WriteString("");
            xmlWriter.WriteEndElement(); // End Unsubscribe

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

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

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

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

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

            byte[] unsubscribeResponse = null;
            try
            {
                unsubscribeResponse = httpClient.SendRequest(soapStream.ToArray(), endpointAddress.ToString(), false, false);
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Unsubscribe failed. " + e.Message);
                return(false);
            }

            // If a unsubscribe response is received simple validate that the messageID and action are correct and
            // If a parsing fault is received print exception and go on.
            if (unsubscribeResponse == null)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Unsubscribe response is null.");
                return(false);
            }
            else
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Response From: " + endpointAddress.Host);
                System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(unsubscribeResponse)));
                try
                {
                    return(ProcessUnsubscribeResponse(unsubscribeResponse, messageID));
                }
                catch (Exception e)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Unsubscribe response parsing failed.");
                    System.Ext.Console.Write(e.Message);
                    return(false);
                }
            }
        }
        /// <summary>
        /// Use to subscribe to a devices, hosted service event sources.
        /// </summary>
        /// <param name="subscriptionRequest">
        /// A DpwsSubscriptionRequest object containing the address of the service hosting the desired event,
        /// the address where the event is sent, an optional address where subscription end messages are sent,
        /// A subscription expiration (in duration format) and an optional user defined identifier.
        /// </param>
        /// <returns>
        /// A DpwsEventSubscription containing the the subscription managers address, the time when the subscription
        /// expires (duration) and optional reference parameters and properties. Per spec the
        /// sub mananger may assign a different duration value than that specified in the request.
        /// </returns>
        /// <exception cref="ArgumentNullException">If required subscription parameters are not set.</exception>
        public DpwsEventSubscription Subscribe(DpwsSubscribeRequest subscriptionRequest)
        {
            if (subscriptionRequest.SubscriptionType == null)
            {
                throw new ArgumentNullException("Subscribe - SubscriptionType must not be null");
            }
            if (subscriptionRequest.SubscriptionType.TypeName == null)
            {
                throw new ArgumentNullException("Subscribe - SubscriptionType.TypeName must not be null");
            }
            if (subscriptionRequest.SubscriptionType.NamespaceUri == null)
            {
                throw new ArgumentNullException("Subscribe - SubscriptionType.NamespaceUri must not be null");
            }
            if (subscriptionRequest.EndpointAddress == null)
            {
                throw new ArgumentNullException("Subscribe - EndpointAddress property must not be null.");
            }
            if (subscriptionRequest.NotifyTo == null)
            {
                throw new ArgumentNullException("Subscribe - NotifyTo must not be null.");
            }
            if (subscriptionRequest.NotifyTo.Address == null)
            {
                throw new ArgumentNullException("Subscribe - NotifyTo.Address must not be null.");
            }

            // Convert the address string to a Uri
            Uri serviceUri = null;

            try
            {
                serviceUri = subscriptionRequest.EndpointAddress;
                if (serviceUri.Scheme != "http")
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Invalid endpoint address. 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 Subscribe Request
            MemoryStream soapStream = new MemoryStream();
            XmlWriter    xmlWriter  = XmlWriter.Create(soapStream);

            WsWsaHeader header = new WsWsaHeader(
                WsWellKnownUri.WseNamespaceUri + "/Subscribe",  // Action
                null,                                           // RelatesTo
                serviceUri.AbsoluteUri,                         // To
                WsWellKnownUri.WsaAnonymousUri,                 // ReplyTo
                null, null);                                    // From, Any

            WsXmlNamespaces additionalPrefixes = new WsXmlNamespaces();

            additionalPrefixes.Add(new WsXmlNamespace("myPrefix", subscriptionRequest.SubscriptionType.NamespaceUri));

            String messageID = WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter,
                                                                         WsSoapMessageWriter.Prefixes.Wsd | WsSoapMessageWriter.Prefixes.Wse,
                                                                         additionalPrefixes, header, null);

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

            // write body
            xmlWriter.WriteStartElement("wse", "Subscribe", null);

            // If EndTo is set write it
            if (subscriptionRequest.EndTo != null)
            {
                WriteEndpointRef(ref xmlWriter, subscriptionRequest.EndTo, "EndTo");
            }

            // Add the delivery element and NotifyTo endpoint
            xmlWriter.WriteStartElement("wse", "Delivery", null);
            xmlWriter.WriteAttributeString("Mode", "http://schemas.xmlsoap.org/ws/2004/08/eventing/DeliveryModes/Push");

            // Writer the notify to endpoint
            WriteEndpointRef(ref xmlWriter, subscriptionRequest.NotifyTo, "NotifyTo");

            xmlWriter.WriteEndElement(); // End Delivery

            // Write Expiration time
            if (subscriptionRequest.Expires != null)
            {
                xmlWriter.WriteStartElement("wse", "Expires", null);
                xmlWriter.WriteString(subscriptionRequest.Expires.DurationString);
                xmlWriter.WriteEndElement(); // End Expires
            }

            // Write Filter element specifying the event to subscribe to.
            xmlWriter.WriteStartElement("wse", "Filter", null);
            xmlWriter.WriteAttributeString("Dialect", "http://schemas.xmlsoap.org/ws/2006/02/devprof/Action");
            xmlWriter.WriteString(subscriptionRequest.SubscriptionType.NamespaceUri + "/" + subscriptionRequest.SubscriptionType.TypeName);
            xmlWriter.WriteEndElement(); // End Filter

            xmlWriter.WriteEndElement(); // End Subscribe

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

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

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

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

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

            byte[] subscribeResponse = null;
            try
            {
                subscribeResponse = httpClient.SendRequest(soapStream.ToArray(), subscriptionRequest.EndpointAddress.AbsoluteUri, false, false);
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Subscribe failed. " + e.Message);
                return(null);
            }

            // If a subscribe response is received process it and return expiration time the subscription manager
            // actually assigned.
            // If a parsing fault is received print exception and go on.
            DpwsEventSubscription response = null;

            if (subscribeResponse == null)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Subscribe response is null.");
                return(null);
            }
            else
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Response From: " + subscriptionRequest.EndpointAddress.Host);
                System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(subscribeResponse)));
                try
                {
                    // It is ok for the service to return a 202 and a 0 length response
                    // if thi is the case just return null
                    if (subscribeResponse.Length == 0)
                    {
                        return(null);
                    }
                    response = ProcessSubscribeResponse(subscribeResponse, messageID);
                }
                catch (Exception e)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Subscription response parsing failed.");
                    System.Ext.Console.Write(e.Message);
                }
            }

            return(response);
        }
Exemple #14
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);
            }
        }