Exemplo n.º 1
0
        public virtual byte[] ProbeMatch(WsWsaHeader header, XmlReader reader)
        {

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

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

            // If a Host exist write the Host namespace
            WsXmlNamespaces additionalPrefixes = null;
            if (Device.Host != null)
            {
                additionalPrefixes = new WsXmlNamespaces();
                additionalPrefixes.Add(Device.Host.ServiceNamespace);
            }

            WsWsaHeader matchHeader = new WsWsaHeader(
                WsWellKnownUri.WsdNamespaceUri + "/ProbeMatches",                       // Action
                header.MessageID,                                                       // RelatesTo
                WsWellKnownUri.WsaAnonymousUri,                                         // To
                null, null, null);                                                      // ReplyTo, From, Any

            WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter,
                WsSoapMessageWriter.Prefixes.Wsd | WsSoapMessageWriter.Prefixes.Wsdp,   // Prefix
                additionalPrefixes,                                                     // Additional Prefixes
                matchHeader,                                                            // Header
                new WsSoapMessageWriter.AppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); // AppSequence

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

            // write body
            xmlWriter.WriteStartElement("wsd", "ProbeMatches", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteStartElement("wsd", "ProbeMatch", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteStartElement("wsa", "EndpointReference", WsWellKnownUri.WsaNamespaceUri_2005_08);
            xmlWriter.WriteStartElement("wsa", "Address", WsWellKnownUri.WsaNamespaceUri_2005_08);
            xmlWriter.WriteString(Device.EndpointAddress);
            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndElement();

            // Write hosted service types
            xmlWriter.WriteStartElement("wsd", "Types", WsWellKnownUri.WsdNamespaceUri);
            WriteDeviceServiceTypes(xmlWriter);
            xmlWriter.WriteEndElement(); // End Types

            xmlWriter.WriteStartElement("wsd", "XAddrs", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteString(Device.TransportAddress);
            xmlWriter.WriteEndElement();

            xmlWriter.WriteStartElement("wsd", "MetadataVersion", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteString(Device.MetadataVersion.ToString());
            xmlWriter.WriteEndElement();

            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndElement();

            // Create return buffer and close writer

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

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

            // Performance debuging
            timeDebuger.PrintTotalTime(startTime, "***ProbeMatch Took");

            // Flush and close writer. Return stream buffer
            xmlWriter.Flush();
            xmlWriter.Close();

            // Delay probe match as per Ws-Discovery specification
            Thread.Sleep(new Random().Next(Device.ProbeMatchDelay));

            return soapStream.ToArray();

        }
        /// <summary>
        /// Builds a probe request message based on the filters parameter.
        /// </summary>
        /// <param name="serviceAddress">
        /// A string containing the target service address.
        /// 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>
        /// <param name="messageID">
        /// A string used to return the messageID assigned to this message.
        /// </param>
        /// <returns>A byte array containing the probe message or null if an error occures.</returns>
        private WsMessage BuildProbeRequest(string serviceAddress, DpwsServiceTypes filters, out String messageID)
        {
            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long startTime = timeDebuger.ResetStartTime("");
            WsMessage msg = null;

            // Build Probe request
            using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsWsaHeader header = new WsWsaHeader(
                    m_version.DiscoveryNamespace + "/Probe",      // Action
                    null,                                         // RelatesTo
                    serviceAddress,                               // To
                    m_version.AnonymousUri, null, null);          // ReplyTo, From, Any

                header.MustUnderstand = true;

                // If filters are supplied, write filter namespaces if prefixed. Build filter list for use later
                WsXmlNamespaces namespaces = new WsXmlNamespaces();

                // Prefix hack for now:
                int i = 0;
                string prefix;
                string filterList = "";
                bool spaceFlag = false;
                if (filters != null)
                {
                    int count = filters.Count;
                    for (int j = 0; j < count; j++)
                    {
                        DpwsServiceType serviceType = filters[j];
                        prefix = namespaces.LookupPrefix(serviceType.NamespaceUri);
                        if (prefix == null)
                        {
                            prefix = "dp" + (i++);
                            namespaces.Add(new WsXmlNamespace(prefix, serviceType.NamespaceUri));
                        }

                        filterList = filterList + ((spaceFlag == true) ? " " : "") + prefix + ":" + serviceType.TypeName;
                        spaceFlag = true;
                    }
                }

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

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

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

                // write body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "Probe", null);

                // If filter is supplied add filter types tag else write blank string to probe body, force an empty tag
                if (filterList.Length != 0)
                {
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "Types", null);
                    xmlWriter.WriteString(filterList);
                    xmlWriter.WriteEndElement(); // End Filter
                }
                else
                    xmlWriter.WriteString("");

                xmlWriter.WriteEndElement(); // End Probe

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

                smw.WriteSoapMessageEnd(xmlWriter);

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

                // return the probe message
                msg.Body = xmlWriter.ToArray();
            }

            return msg;
        }
Exemplo n.º 3
0
        internal WsMessage BuildHelloMessage(string endpointAddress, WsWsaHeader header, XmlReader reader)
        {
            using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsXmlNamespaces additionalPrefixes = null;
                // If a Host exist write the Host namespace
                if (Device.Host != null)
                {
                    additionalPrefixes = new WsXmlNamespaces();
                    additionalPrefixes.Add(Device.Host.ServiceNamespace);
                }

                WsWsaHeader helloHeader = new WsWsaHeader(
                    m_version.DiscoveryNamespace + "/Hello",    // Action
                    null,                                       // RelatesTo
                    endpointAddress,                            // To
                    null, null, null);                          // ReplyTo, From, Any

                WsMessage msg = new WsMessage(helloHeader, null, WsPrefix.Wsd | WsPrefix.Wsdp, additionalPrefixes, 
                    new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID));

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

                // write body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "Hello", null);

                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "EndpointReference", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null);
                xmlWriter.WriteString(Device.EndpointAddress);
                xmlWriter.WriteEndElement();
                xmlWriter.WriteEndElement();

                // Write hosted service types
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "Types", null);
                WriteDeviceServiceTypes(xmlWriter, false);
                xmlWriter.WriteEndElement(); // End Types

                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "XAddrs", null);
                xmlWriter.WriteString(Device.TransportAddress);
                xmlWriter.WriteEndElement();

                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "MetadataVersion", null);
                xmlWriter.WriteString(Device.MetadataVersion.ToString());
                xmlWriter.WriteEndElement();

                xmlWriter.WriteEndElement();

                // Flush and close writer. Return stream buffer
                smw.WriteSoapMessageEnd(xmlWriter);

                msg.Body = xmlWriter.ToArray();

                return msg;
            }
        }
Exemplo n.º 4
0
        public virtual byte[] ResolveMatch(WsWsaHeader header, XmlReader reader)
        {
            reader.ReadStartElement("Resolve", WsWellKnownUri.WsdNamespaceUri);

            if (reader.IsStartElement("EndpointReference", WsWellKnownUri.WsaNamespaceUri_2005_08) == false)
            {
                return null;
            }

            WsWsaEndpointRef epRef = new WsWsaEndpointRef(reader);

            // If the destination endpoint is ours send a resolve match else return null
            if (Device.EndpointAddress != epRef.Address.AbsoluteUri)
                return null;

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

            // If a Host exist write the Host namespace
            WsXmlNamespaces additionalPrefixes = null;
            if (Device.Host != null)
            {
                additionalPrefixes = new WsXmlNamespaces();
                additionalPrefixes.Add(Device.Host.ServiceNamespace);
            }

            WsWsaHeader matchHeader = new WsWsaHeader(
                WsWellKnownUri.WsdNamespaceUri + "/ResolveMatches",                     // Action
                header.MessageID,                                                       // RelatesTo
                WsWellKnownUri.WsaAnonymousUri,                                         // To
                null, null, null);                                                      // ReplyTo, From, Any

            WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter,
                WsSoapMessageWriter.Prefixes.Wsd | WsSoapMessageWriter.Prefixes.Wsdp,   // Prefix
                additionalPrefixes,                                                     // Additional Prefixes
                matchHeader,                                                            // Header
                new WsSoapMessageWriter.AppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); // AppSequence

            // write body
            xmlWriter.WriteStartElement("wsd", "ResolveMatches", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteStartElement("wsd", "ResolveMatch", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteStartElement("wsa", "EndpointReference", WsWellKnownUri.WsaNamespaceUri_2005_08);
            xmlWriter.WriteStartElement("wsa", "Address", WsWellKnownUri.WsaNamespaceUri_2005_08);
            xmlWriter.WriteString(Device.EndpointAddress);
            xmlWriter.WriteEndElement(); // End Address
            xmlWriter.WriteEndElement(); // End EndpointReference

            // Write hosted service types
            xmlWriter.WriteStartElement("wsd", "Types", WsWellKnownUri.WsdNamespaceUri);
            WriteDeviceServiceTypes(xmlWriter);
            xmlWriter.WriteEndElement(); // End Types

            xmlWriter.WriteStartElement("wsd", "XAddrs", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteString(Device.TransportAddress);
            xmlWriter.WriteEndElement(); // End XAddrs

            xmlWriter.WriteStartElement("wsd", "MetadataVersion", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteString(Device.MetadataVersion.ToString());
            xmlWriter.WriteEndElement(); // End MetadataVersion

            xmlWriter.WriteEndElement(); // End ResolveMatch
            xmlWriter.WriteEndElement(); // End ResolveMatches

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

            // Flush and close writer. Return stream buffer
            xmlWriter.Flush();
            xmlWriter.Close();
            return soapStream.ToArray();

        }
Exemplo n.º 5
0
        /// <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;
        }
        /// <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;
            }
        }
        public virtual WsMessage ProbeMatch(WsMessage probe, DpwsHostedService matchedService)
        {
            XmlReader   reader = probe.Reader;
            WsWsaHeader header = probe.Header;

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

            // Build ProbeMatch
            using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                // If a Host exist write the Host namespace
                WsXmlNamespaces additionalPrefixes = null;
                if (Device.Host != null)
                {
                    additionalPrefixes = new WsXmlNamespaces();
                    additionalPrefixes.Add(Device.Host.ServiceNamespace);
                }

                WsWsaHeader matchHeader = new WsWsaHeader(
                    this.Version.DiscoveryNamespace + "/ProbeMatches", // Action
                    header.MessageID,                                  // RelatesTo
                    this.Version.AnonymousUri,                         // To
                    null, null, null);                                 // ReplyTo, From, Any

                WsMessage msg = new WsMessage(matchHeader, null, WsPrefix.Wsd | WsPrefix.Wsdp, additionalPrefixes,
                    new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID));

                WsSoapMessageWriter smw = new WsSoapMessageWriter(this.Version);
                smw.WriteSoapMessageStart(xmlWriter, msg);

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

                // write body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "ProbeMatches", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "ProbeMatch", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "EndpointReference", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null);
                xmlWriter.WriteString(matchedService == null ? Device.EndpointAddress : matchedService.EndpointAddress);
                xmlWriter.WriteEndElement();
                xmlWriter.WriteEndElement();

                // Write hosted service types
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "Types", null);
                WriteDeviceServiceTypes(xmlWriter);
                xmlWriter.WriteEndElement(); // End Types

                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "XAddrs", null);

                string transport = Device.TransportAddress;
                if(matchedService != null)
                {
                    int idx = transport.LastIndexOf('/');
                    if(idx != -1)
                    {
                        transport = transport.Substring(0, idx + 1);
                        transport += matchedService.EndpointAddress.Substring(matchedService.EndpointAddress.IndexOf("urn:uuid:") + 9);
                    }
                }

                int idx2 = transport.ToLower().IndexOf("localhost");

                if(idx2 != -1)
                {
                    transport = transport.Substring(0, idx2) + WsNetworkServices.GetLocalIPV4Address() + transport.Substring(idx2 + 9 /*localhost*/);
                }
                
                xmlWriter.WriteString(transport);
                xmlWriter.WriteEndElement();

                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "MetadataVersion", null);
                xmlWriter.WriteString(Device.MetadataVersion.ToString());
                xmlWriter.WriteEndElement();

                xmlWriter.WriteEndElement();
                xmlWriter.WriteEndElement();

                smw.WriteSoapMessageEnd(xmlWriter);

                msg.Body = xmlWriter.ToArray();

                // Performance debuging
                timeDebuger.PrintTotalTime(startTime, "***ProbeMatch Took");

                // Delay probe match as per Ws-Discovery specification (2.4 Protocol Assignments)
                Thread.Sleep(new Random().Next(Device.ProbeMatchDelay));

                // Return stream buffer
                return msg;
            }
        }
        public virtual WsMessage ResolveMatch(WsMessage message)
        {
            XmlReader   reader = message.Reader;
            WsWsaHeader header = message.Header;
            bool        match  = false;
            string      epAddr = "";

            reader.ReadStartElement("Resolve", this.Version.DiscoveryNamespace);

            
            if(reader.IsStartElement("EndpointReference", this.Version.AddressingNamespace) == false)
            {
                return null;
            }

            WsWsaEndpointRef epRef = new WsWsaEndpointRef(reader, this.Version.AddressingNamespace);

            epAddr = epRef.Address.AbsoluteUri;

            if(Device.EndpointAddress != epAddr)
            {
                // If the destination endpoint is ours send a resolve match else return null
                int servicesCount = Device.HostedServices.Count;
                DpwsHostedService hostedService;
                for (int i = 0; i < servicesCount; i++)
                {
                    hostedService = (DpwsHostedService)Device.HostedServices[i];
                    // Skip internal services
                    if (hostedService.ServiceTypeName == "Internal")
                        continue;
                
                    if (hostedService.EndpointAddress == epAddr)
                    {
                        match = true;
                        break;
                    }
                }

                if (!match)
                    return null;
            }

            // Build ResolveMatch
            using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                // If a Host exist write the Host namespace
                WsXmlNamespaces additionalPrefixes = null;
                if (Device.Host != null)
                {
                    additionalPrefixes = new WsXmlNamespaces();
                    additionalPrefixes.Add(Device.Host.ServiceNamespace);
                }

                WsWsaHeader matchHeader = new WsWsaHeader(
                    this.Version.DiscoveryNamespace + "/ResolveMatches",  // Action
                    header.MessageID,                                     // RelatesTo
                    this.Version.AnonymousUri,                            // To
                    null, null, null);                                    // ReplyTo, From, Any

                WsMessage msg = new WsMessage(matchHeader, null, WsPrefix.Wsd | WsPrefix.Wsdp, additionalPrefixes, 
                    new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID));

                WsSoapMessageWriter smw = new WsSoapMessageWriter(this.Version);
                smw.WriteSoapMessageStart(xmlWriter, msg);

                // write body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "ResolveMatches", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "ResolveMatch", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "EndpointReference", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null);
                xmlWriter.WriteString(epRef.Address.AbsoluteUri);
                xmlWriter.WriteEndElement(); // End Address
                xmlWriter.WriteEndElement(); // End EndpointReference

                // Write hosted service types
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "Types", null);
                WriteDeviceServiceTypes(xmlWriter);
                xmlWriter.WriteEndElement(); // End Types

                string transport = Device.TransportAddress;
                if(match)
                {
                    int idx = transport.LastIndexOf('/');
                    if(idx != -1)
                    {
                        transport = transport.Substring(0, idx + 1);
                        transport += epAddr.Substring(epAddr.IndexOf("urn:uuid:") + 9);
                    }
                }

                int idx2 = transport.ToLower().IndexOf("localhost");

                if(idx2 != -1)
                {
                    transport = transport.Substring(0, idx2) + WsNetworkServices.GetLocalIPV4Address() + transport.Substring(idx2 + 9 /*localhost*/);
                }

                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "XAddrs", null);
                xmlWriter.WriteString(transport);
                xmlWriter.WriteEndElement(); // End XAddrs

                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "MetadataVersion", null);
                xmlWriter.WriteString(Device.MetadataVersion.ToString());
                xmlWriter.WriteEndElement(); // End MetadataVersion

                xmlWriter.WriteEndElement(); // End ResolveMatch
                xmlWriter.WriteEndElement(); // End ResolveMatches

                smw.WriteSoapMessageEnd(xmlWriter);

                msg.Body = xmlWriter.ToArray();

                // Return stream buffer
                return msg;
            }
        }
Exemplo n.º 9
0
        public WsMessage GetResponse(WsMessage req)
        {
            XmlReader   reader = req.Reader;
            WsWsaHeader header = req.Header;

            // Build ProbeMatch
            using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                // Write service type namespaces
                WsXmlNamespaces additionalPrefixes = new WsXmlNamespaces();
                if (Device.Host != null)
                {
                    additionalPrefixes = new WsXmlNamespaces();
                    additionalPrefixes.Add(Device.Host.ServiceNamespace);
                }

                WsServiceEndpoints hostedServices = Device.HostedServices;
                int count = hostedServices.Count;
                for (int i = 0; i < count; i++)
                {
                    DpwsHostedService hostedService = (DpwsHostedService)hostedServices[i];

                    // Don't return Mex Service namespace
                    if (hostedService.ServiceTypeName == "Internal")
                        continue;

                    additionalPrefixes.Add(hostedService.ServiceNamespace);
                }

                WsWsaHeader responseHeader = new WsWsaHeader(
                    WsWellKnownUri.WstNamespaceUri + "/GetResponse",                        // Action
                    header.MessageID,                                                       // RelatesTo
                    header.ReplyTo.Address.AbsoluteUri,                                     // To
                    null, null, null);

                WsMessage resp = new WsMessage(responseHeader, null, WsPrefix.Wsx | WsPrefix.Wsdp, additionalPrefixes,
                    new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID));

                WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version);
                smw.WriteSoapMessageStart(xmlWriter, resp);

                // write body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsx, "Metadata", null);

                // Write ThisModel metadata section
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsx, "MetadataSection", null);
                xmlWriter.WriteAttributeString("Dialect", m_version.WsdpNamespaceUri + "/ThisModel");

                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ThisModel", null);
                if (Device.ThisModel.Manufacturer != null && Device.ThisModel.Manufacturer != "")
                {
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "Manufacturer", null);
                    xmlWriter.WriteString(Device.ThisModel.Manufacturer);
                    xmlWriter.WriteEndElement(); // End Manufacturer
                }

                if (Device.ThisModel.ManufacturerUrl != null && Device.ThisModel.ManufacturerUrl != "")
                {
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ManufacturerUrl", null);
                    xmlWriter.WriteString(Device.ThisModel.ManufacturerUrl);
                    xmlWriter.WriteEndElement(); // End ManufacturerUrl
                }

                if (Device.ThisModel.ModelName != null && Device.ThisModel.ModelName != "")
                {
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ModelName", null);
                    xmlWriter.WriteString(Device.ThisModel.ModelName);
                    xmlWriter.WriteEndElement(); // End ModelName
                }

                if (Device.ThisModel.ModelNumber != null && Device.ThisModel.ModelNumber != "")
                {
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ModelNumber", null);
                    xmlWriter.WriteString(Device.ThisModel.ModelNumber);
                    xmlWriter.WriteEndElement(); // End ModelNumber
                }

                if (Device.ThisModel.ModelUrl != null && Device.ThisModel.ModelUrl != "")
                {
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ModelUrl", null);
                    xmlWriter.WriteString(Device.ThisModel.ModelUrl);
                    xmlWriter.WriteEndElement(); // End ModelUrl
                }

                if (Device.ThisModel.PresentationUrl != null && Device.ThisModel.PresentationUrl != "")
                {
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "PresentationUrl", null);
                    xmlWriter.WriteString(Device.ThisModel.PresentationUrl);
                    xmlWriter.WriteEndElement(); // End PresentationUrl
                }

                if (Device.ThisModel.Any != null)
                {
                    Device.ThisModel.Any.WriteTo(xmlWriter);
                }

                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ModelName", null);
                xmlWriter.WriteString(Device.ThisModel.ModelName);
                xmlWriter.WriteEndElement(); // End ModelName

                xmlWriter.WriteEndElement(); // End ThisModel
                xmlWriter.WriteEndElement(); // End MetadataSection

                // Write ThisDevice metadata section
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsx, "MetadataSection", null);
                xmlWriter.WriteAttributeString("Dialect", m_version.WsdpNamespaceUri + "/ThisDevice");

                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ThisDevice", null);
                if (Device.ThisDevice.FriendlyName != null && Device.ThisDevice.FriendlyName != "")
                {
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "FriendlyName", null);
                    xmlWriter.WriteString(Device.ThisDevice.FriendlyName);
                    xmlWriter.WriteEndElement(); // End FriendlyName
                }

                if (Device.ThisDevice.FirmwareVersion != null && Device.ThisDevice.FirmwareVersion != "")
                {
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "FirmwareVersion", null);
                    xmlWriter.WriteString(Device.ThisDevice.FirmwareVersion);
                    xmlWriter.WriteEndElement(); // End FirmwareVersion
                }

                if (Device.ThisDevice.SerialNumber != null && Device.ThisDevice.SerialNumber != "")
                {
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "SerialNumber", null);
                    xmlWriter.WriteString(Device.ThisDevice.SerialNumber);
                    xmlWriter.WriteEndElement(); // End SerialNumber
                }

                if (Device.ThisDevice.Any != null)
                {
                    Device.ThisDevice.Any.WriteTo(xmlWriter);
                }

                xmlWriter.WriteEndElement(); // End ThisDevice
                xmlWriter.WriteEndElement(); // End MetadataSection

                // Write next MetadataSection
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsx, "MetadataSection", null);
                xmlWriter.WriteAttributeString("Dialect", m_version.WsdpNamespaceUri + "/Relationship");

                // Write Relationship Elements
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "Relationship", null);
                xmlWriter.WriteAttributeString("Type", m_version.WsdpNamespaceUri + "/host");

                // List used to maintain service endpoints that have been processed. Because the DPWS spec allows
                // for multiple service types at a single endpoint address, we must make sure we only create
                // a relationship once for all of the types at a service endpoint.
                ArrayList processedEndpointList = new ArrayList();

                // If a Host type exist add it
                if (Device.Host != null)
                {
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "Host", null);
                    WsWsaEndpointRef endpointReference;
                    endpointReference = (WsWsaEndpointRef)Device.Host.EndpointRefs[0];
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "EndpointReference", null);
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null);
                    xmlWriter.WriteString(endpointReference.Address.AbsoluteUri);
                    xmlWriter.WriteEndElement(); // End Address
                    xmlWriter.WriteEndElement(); // End EndpointReference

                    // Build list of all service types that share this endpoint address
                    /*
                    string serviceTypes = null;
                    if ((serviceTypes = BuildServiceTypesList(Device.Host, processedEndpointList)) == null)
                        serviceTypes = Device.Host.ServiceNamespace.Prefix + ":" + Device.Host.ServiceTypeName;
                    else
                        serviceTypes = serviceTypes + " " + Device.Host.ServiceNamespace.Prefix + ":" + Device.Host.ServiceTypeName;
                    */
                    
                    // Write service types
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "Types", null);
                    xmlWriter.WriteString(Device.Host.ServiceNamespace.Prefix + ":" + Device.Host.ServiceTypeName);
                    xmlWriter.WriteEndElement(); // End Types

                    // Write Service ID
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ServiceId", null);
                    xmlWriter.WriteString(Device.Host.ServiceID);
                    xmlWriter.WriteEndElement(); // End ServiceID

                    xmlWriter.WriteEndElement(); // End Hosted

                    // Update processed endpoint list
                    processedEndpointList.Add(Device.Host.EndpointAddress);
                }

                // Add hosted services types
                int serviceCount = hostedServices.Count;
                DpwsHostedService currentService;
                for (int i = 0; i < serviceCount; i++)
                {
                    currentService = (DpwsHostedService)hostedServices[i];

                    // Don't return Mex Service type
                    if (currentService.ServiceTypeName == "Internal")
                        continue;

                    // Build list of all service types that share this endpoint address
                    string serviceTypes = null;
                    if ((serviceTypes = BuildServiceTypesList(currentService, processedEndpointList)) == null)
                        continue;

                    // Write hosted start element
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "Hosted", null);
                    
                    // Write n number of endpoint references
                    int epRefCount = currentService.EndpointRefs.Count;
                    for (int j = 0; j < epRefCount; j++)
                    {
                        xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "EndpointReference", null);
                        xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null);
                        xmlWriter.WriteString(currentService.EndpointRefs[j].Address.AbsoluteUri);
                        xmlWriter.WriteEndElement(); // End Address
                        xmlWriter.WriteEndElement(); // End EndpointReference
                    }

                    // Write service types
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "Types", null);
                    xmlWriter.WriteString(currentService.ServiceNamespace.Prefix + ":" + currentService.ServiceTypeName);
                    xmlWriter.WriteEndElement(); // End Types

                    // Write Service ID
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ServiceId", null);
                    xmlWriter.WriteString(currentService.ServiceID);
                    xmlWriter.WriteEndElement(); // End ServiceID

                    xmlWriter.WriteEndElement(); // End Hosted

                    // Update processed endpoint list
                    processedEndpointList.Add(currentService.EndpointAddress);
                }

                xmlWriter.WriteEndElement(); // End Relastionship
                xmlWriter.WriteEndElement(); // End MetadataSection

                xmlWriter.WriteEndElement(); // End Metadata

                smw.WriteSoapMessageEnd(xmlWriter);

                resp.Body = xmlWriter.ToArray();

                return resp;
            }
        }
Exemplo n.º 10
0
        internal static byte[] BuildHelloMessage(string endpointAddress, WsWsaHeader header, XmlReader reader)
        {
            MemoryStream soapStream = new MemoryStream();
            XmlWriter xmlWriter = XmlWriter.Create(soapStream);

            WsXmlNamespaces additionalPrefixes = null;
            // If a Host exist write the Host namespace
            if (Device.Host != null)
            {
                additionalPrefixes = new WsXmlNamespaces();
                additionalPrefixes.Add(Device.Host.ServiceNamespace);
            }

            WsWsaHeader helloHeader = new WsWsaHeader(
                WsWellKnownUri.WsdNamespaceUri + "/Hello",                              // Action
                null,                                                                   // RelatesTo
                endpointAddress,                                                        // To
                null, null, null);                                                      // ReplyTo, From, Any

            WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter,
                WsSoapMessageWriter.Prefixes.Wsd | WsSoapMessageWriter.Prefixes.Wsdp,   // Prefix
                additionalPrefixes,                                                     // Additional Prefixes
                helloHeader,                                                            // Header
                new WsSoapMessageWriter.AppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); // AppSequence

            // write body
            xmlWriter.WriteStartElement("wsd", "Hello", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteStartElement("wsa", "EndpointReference", WsWellKnownUri.WsaNamespaceUri_2005_08);
            xmlWriter.WriteStartElement("wsa", "Address", WsWellKnownUri.WsaNamespaceUri_2005_08);
            xmlWriter.WriteString(Device.EndpointAddress);
            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndElement();

            // Write hosted service types
            xmlWriter.WriteStartElement("wsd", "Types", WsWellKnownUri.WsdNamespaceUri);
            WriteDeviceServiceTypes(xmlWriter, false);
            xmlWriter.WriteEndElement(); // End Types

            xmlWriter.WriteStartElement("wsd", "XAddrs", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteString(Device.TransportAddress);
            xmlWriter.WriteEndElement();
            xmlWriter.WriteStartElement("wsd", "MetadataVersion", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteString(Device.MetadataVersion.ToString());
            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndElement();

            // Flush and close writer. Return stream buffer
            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

            xmlWriter.Flush();
            xmlWriter.Close();
            return soapStream.ToArray();
        }
Exemplo n.º 11
0
        /// <summary>
        /// Builds a probe request message based on the filters parameter.
        /// </summary>
        /// <param name="serviceAddress">
        /// A string containing the target service address.
        /// 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>
        /// <param name="messageID">
        /// A string used to return the messageID assigned to this message.
        /// </param>
        /// <returns>A byte array containing the probe message or null if an error occures.</returns>
        private byte[] BuildProbeRequest(string serviceAddress, DpwsServiceTypes filters, out String messageID)
        {
            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long startTime = timeDebuger.ResetStartTime("");

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

            WsWsaHeader header = new WsWsaHeader(
                WsWellKnownUri.WsdNamespaceUri + "/Probe",      // Action
                null,                                           // RelatesTo
                serviceAddress,                                 // To
                null, null, null);                              // ReplyTo, From, Any

            // If filters are supplied, write filter namespaces if prefixed. Build filter list for use later,
            // include wsdp:device.
            WsXmlNamespaces namespaces = new WsXmlNamespaces();

            // Prefix hack for now:
            int i = 0;
            string prefix;
            string filterList = "";
            bool spaceFlag = false;
            if (filters != null)
            {
                int count = filters.Count;
                for (int j = 0; j < count; j++)
                {
                    DpwsServiceType serviceType = filters[j];
                    prefix = namespaces.LookupPrefix(serviceType.NamespaceUri);
                    if (prefix == null)
                    {
                        prefix = "MyPrefix" + (i++);
                        namespaces.Add(new WsXmlNamespace(prefix, serviceType.NamespaceUri));
                    }

                    filterList = filterList + ((spaceFlag == true) ? " " : "") + prefix + ":" + serviceType.TypeName;
                    spaceFlag = true;
                }
            }

            messageID = WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter,
                WsSoapMessageWriter.Prefixes.Wsd, namespaces, header, null);

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

            // write body
            xmlWriter.WriteStartElement("wsd", "Probe", null);

            // If filter is supplied add filter types tag else write blank string to probe body, force an empty tag
            if (filterList.Length != 0)
            {
                xmlWriter.WriteStartElement("wsd", "Types", null);
                xmlWriter.WriteString(filterList);
                xmlWriter.WriteEndElement(); // End Filter
            }
            else
                xmlWriter.WriteString("");

            xmlWriter.WriteEndElement(); // End Probe

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

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

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

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

            // return the probe message
            return soapStream.ToArray();
        }