// Build ws-discovery bye message
        internal WsMessage BuildByeMessage(string endpointAddress, WsWsaHeader header, XmlReader reader)
        {
            using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsWsaHeader byeHeader = new WsWsaHeader(
                    m_version.DiscoveryNamespace + "/Bye",  // Action
                    null,                                   // RelatesTo
                    endpointAddress,                        // To
                    null, null, null);                      // ReplyTo, From, Any

                WsMessage msg = new WsMessage(byeHeader, null, WsPrefix.Wsd, null,
                                              new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID));

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

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

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

                xmlWriter.WriteEndElement();

                smw.WriteSoapMessageEnd(xmlWriter);

                msg.Body = xmlWriter.ToArray();

                // Return stream buffer
                return(msg);
            }
        }
        private byte[] GetStatusResponse(WsWsaHeader header, long newDuration)
        {
            MemoryStream soapStream = new MemoryStream();
            XmlWriter    xmlWriter  = XmlWriter.Create(soapStream);

            WsWsaHeader responseHeader = new WsWsaHeader(
                WsWellKnownUri.WseNamespaceUri + "/RenewResponse",      // Action
                header.MessageID,                                       // RelatesTo
                header.ReplyTo.Address.AbsoluteUri,                     // To
                null, null, null);                                      // ReplyTo, From, Any

            WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter,
                                                      WsSoapMessageWriter.Prefixes.Wse,                                                              // Prefix
                                                      null,                                                                                          // Additional Prefix
                                                      responseHeader,                                                                                // Header
                                                      new WsSoapMessageWriter.AppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); // AppSequence

            // write body
            xmlWriter.WriteStartElement("wse", "Expires", null);
            xmlWriter.WriteString(new WsDuration(newDuration).DurationString);
            xmlWriter.WriteEndElement(); // End Expires

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

            // Flush and close writer. Return stream buffer
            xmlWriter.Flush();
            xmlWriter.Close();
            return(soapStream.ToArray());
        }
        private WsMessage GetStatusResponse(WsWsaHeader header, long newDuration)
        {
            using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsWsaHeader responseHeader = new WsWsaHeader(
                    WsWellKnownUri.WseNamespaceUri + "/RenewResponse",      // Action
                    header.MessageID,                                       // RelatesTo
                    header.ReplyTo.Address.AbsoluteUri,                     // To
                    null, null, null);                                      // ReplyTo, From, Any

                WsMessage msg = new WsMessage(responseHeader, null, WsPrefix.Wse,
                                              null, new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); // AppSequence

                // write body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Expires", null);
                xmlWriter.WriteString(new WsDuration(newDuration).DurationString);
                xmlWriter.WriteEndElement(); // End Expires

                WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version);
                smw.WriteSoapMessageEnd(xmlWriter);

                msg.Body = xmlWriter.ToArray();

                return(msg);
            }
        }
        /// <summary>
        /// Builds a probe request message based on the filters parameter.
        /// </summary>
        /// <param name="targetServiceAddress">
        /// A string containing the target service address of a known service to resolve.
        /// For example: urn:uuid:3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="serviceAddress">
        /// A string containing the address of a service endpoint used to process the resolve request.
        /// For example: urn:uuid:22d0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="messageID">
        /// A string reference used to store retreive the messageID from resolve message generation. The id is
        /// used to verify probe match responses for ad-hoc operation.
        /// </param>
        /// <returns>A byte array containing the resolve message or null if an error occures.</returns>
        private byte[] BuildResolveRequest(string targetServiceAddress, string serviceAddress, ref String messageID)
        {
            // Build Resolve Request
            MemoryStream soapStream = new MemoryStream();
            XmlWriter    xmlWriter  = XmlWriter.Create(soapStream);

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

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


            // write body
            xmlWriter.WriteStartElement("wsd", "Resolve", null);
            xmlWriter.WriteStartElement("wsa", "EndpointReference", null);
            xmlWriter.WriteStartElement("wsa", "Address", null);
            xmlWriter.WriteString(targetServiceAddress);

            xmlWriter.WriteEndElement(); // End Address
            xmlWriter.WriteEndElement(); // End EndpointReference
            xmlWriter.WriteEndElement(); // End Resolve

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

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

            // return the resolve message
            return(soapStream.ToArray());
        }
        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);
            }
        }
        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());
        }
        /// <summary>
        /// This method build a subscription end message.
        /// </summary>
        /// <param name="eventSink">An event sink containing client endpoint information.</param>
        /// <param name="shutdownMessage">A string containing reason why the subscription is ending.</param>
        /// <param name="subMangerID">An id sent by the client that they use to reference a subscription.</param>
        /// <returns></returns>
        private byte[] SubscriptionEndResponse(DpwsWseEventSink eventSink, string shutdownMessage, string subMangerID)
        {
            MemoryStream soapStream = new MemoryStream();
            XmlWriter    xmlWriter  = XmlWriter.Create(soapStream);

            WsWsaHeader responseHeader = new WsWsaHeader(
                WsWellKnownUri.WseNamespaceUri + "/SubscriptionEnd",    // Action
                null,                                                   // RelatesTo
                eventSink.EndTo.Address.AbsoluteUri,                    // To
                null, null, eventSink.EndTo.RefProperties);             // ReplyTo, From, Any

            WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter,
                                                      WsSoapMessageWriter.Prefixes.Wse, // Prefix
                                                      null,                             // Additional Prefix
                                                      responseHeader,                   // Header
                                                      null);                            // AppSequence

            // write body
            xmlWriter.WriteStartElement("wse", "SubscriptionEnd", null);
            xmlWriter.WriteStartElement("wse", "SubscriptionManager", null);
            xmlWriter.WriteStartElement("wsa", "Address", null);
            xmlWriter.WriteString("http://" + Device.IPV4Address + ":" + Device.Port + "/" + subMangerID);
            xmlWriter.WriteEndElement(); // End Address
            xmlWriter.WriteStartElement("wsa", "ReferenceParameters", null);
            xmlWriter.WriteStartElement("wse", "Identifier", null);
            xmlWriter.WriteString(eventSink.ID);
            xmlWriter.WriteEndElement(); // End Identifier
            xmlWriter.WriteEndElement(); // End ReferenceParameters
            xmlWriter.WriteEndElement(); // End SubscriptionManager
            xmlWriter.WriteStartElement("wse", "Code", null);
            xmlWriter.WriteString("wse:" + shutdownMessage);
            xmlWriter.WriteEndElement(); // End Code
            xmlWriter.WriteEndElement(); // End SubscriptionEnd

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

            // Flush and close writer. Return stream buffer
            xmlWriter.Flush();
            xmlWriter.Close();
            return(soapStream.ToArray());
        }
        /// <summary>
        /// This method build a subscription end message.
        /// </summary>
        /// <param name="eventSink">An event sink containing client endpoint information.</param>
        /// <param name="shutdownMessage">A string containing reason why the subscription is ending.</param>
        /// <param name="subMangerID">An id sent by the client that they use to reference a subscription.</param>
        /// <returns></returns>
        private WsMessage SubscriptionEndResponse(DpwsWseEventSink eventSink, string shutdownMessage, string subMangerID)
        {
            using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsWsaHeader responseHeader = new WsWsaHeader(
                    WsWellKnownUri.WseNamespaceUri + "/SubscriptionEnd",    // Action
                    null,                                                   // RelatesTo
                    eventSink.EndTo.Address.AbsoluteUri,                    // To
                    null, null, eventSink.EndTo.RefProperties);             // ReplyTo, From, Any

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

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

                // write body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "SubscriptionEnd", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "SubscriptionManager", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null);
                xmlWriter.WriteString("http://" + Device.IPV4Address + ":" + Device.Port + "/" + subMangerID);
                xmlWriter.WriteEndElement(); // End Address
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "ReferenceParameters", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Identifier", null);
                xmlWriter.WriteString(eventSink.ID);
                xmlWriter.WriteEndElement(); // End Identifier
                xmlWriter.WriteEndElement(); // End ReferenceParameters
                xmlWriter.WriteEndElement(); // End SubscriptionManager
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Code", null);
                xmlWriter.WriteString(WsNamespacePrefix.Wse + ":" + shutdownMessage);
                xmlWriter.WriteEndElement(); // End Code
                xmlWriter.WriteEndElement(); // End SubscriptionEnd

                smw.WriteSoapMessageEnd(xmlWriter);

                msg.Body = xmlWriter.ToArray();

                // Return stream buffer
                return(msg);
            }
        }
        /// <summary>
        /// Builds a probe request message based on the filters parameter.
        /// </summary>
        /// <param name="targetServiceAddress">
        /// A string containing the target service address of a known service to resolve.
        /// For example: urn:uuid:3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="serviceAddress">
        /// A string containing the address of a service endpoint used to process the resolve request.
        /// For example: urn:uuid:22d0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <param name="messageID">
        /// A string reference used to store retreive the messageID from resolve message generation. The id is
        /// used to verify probe match responses for ad-hoc operation.
        /// </param>
        /// <returns>A byte array containing the resolve message or null if an error occures.</returns>
        private WsMessage BuildResolveRequest(string targetServiceAddress, string serviceAddress, ref String messageID)
        {
            WsMessage msg = null;

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

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

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


                // write body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "Resolve", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "EndpointReference", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null);
                xmlWriter.WriteString(targetServiceAddress);

                xmlWriter.WriteEndElement(); // End Address
                xmlWriter.WriteEndElement(); // End EndpointReference
                xmlWriter.WriteEndElement(); // End Resolve

                smw.WriteSoapMessageEnd(xmlWriter);

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

            return(msg);
        }
        // Build ws-discovery bye message
        internal static byte[] BuildByeMessage(string endpointAddress, WsWsaHeader header, XmlReader reader)
        {
            MemoryStream soapStream = new MemoryStream();
            XmlWriter    xmlWriter  = XmlWriter.Create(soapStream);

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

            WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter,
                                                      WsSoapMessageWriter.Prefixes.Wsd,                                                              // Prefix
                                                      null,                                                                                          // Additional Prefix
                                                      byeHeader,                                                                                     // Header
                                                      new WsSoapMessageWriter.AppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); // AppSequence

            // write body
            xmlWriter.WriteStartElement("wsd", "Bye", 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();
            xmlWriter.WriteStartElement("wsd", "XAddrs", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteString(Device.TransportAddress);
            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndElement();

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

            // Flush and close writer. Return stream buffer
            xmlWriter.Flush();
            xmlWriter.Close();
            return(soapStream.ToArray());
        }
Exemple #11
0
        internal static WsMessage GenerateFaultResponse(WsWsaHeader header, WsFaultType faultType, String details, ProtocolVersion version)
        {
            String code = String.Empty;
            String subcode = String.Empty;
            String reason = String.Empty;
            WsPrefix extraNS = WsPrefix.Wse;

            string faultAddress = null;

            if(header.FaultTo != null)
            {
                faultAddress = header.FaultTo.Address.OriginalString;
            }

            if (faultAddress == null)
            {
                faultAddress = version.AnonymousUri;
            }

            switch (faultType)
            {
                case WsFaultType.ArgumentException:
                    code =  WsNamespacePrefix.Soap + ":Receiver";
                    subcode = "ArgumentException";
                    reason = "One of the arguments provided to a method is not valid.";
                    break;
                case WsFaultType.ArgumentNullException:
                    code = WsNamespacePrefix.Soap + ":Receiver";
                    subcode = "ArgumentNullException";
                    reason = "A null reference was passed to a method that does not accept it as a valid argument.";
                    break;
                case WsFaultType.Exception:
                    code = WsNamespacePrefix.Soap + ":Receiver";
                    subcode = "Exception";
                    reason = "Errors occured during application execution.";
                    break;
                case WsFaultType.InvalidOperationException:
                    code = WsNamespacePrefix.Soap + ":Receiver";
                    subcode = "InvalidOperationException";
                    reason = "A method call is invalid for the object's current state.";
                    break;
                case WsFaultType.XmlException:
                    code = WsNamespacePrefix.Soap + ":Receiver";
                    subcode = "XmlException";
                    reason = "Syntax errors found during parsing.";
                    break;

                case WsFaultType.WsaInvalidMessageInformationHeader:
                    code = WsNamespacePrefix.Soap + ":Sender";
                    subcode = WsNamespacePrefix.Wsa + ":InvalidMessageInformationHeader";
                    reason = "A message information header is not valid and cannot be processed.";
                    break;
                case WsFaultType.WsaMessageInformationHeaderRequired:
                    code = WsNamespacePrefix.Soap + ":Sender";
                    subcode = WsNamespacePrefix.Wsa + ":MessageInformationHeaderRequired";
                    reason = "A required message Information header, To, MessageID, or Action, is not present";
                    break;
                case WsFaultType.WsaDestinationUnreachable:
                    code = WsNamespacePrefix.Soap + ":Sender";
                    subcode = WsNamespacePrefix.Wsa + ":DestinationUnreachable";
                    reason = "No route can be determined to reach the destination role defined by the WS=Addressing To.";
                    break;
                case WsFaultType.WsaActionNotSupported:
                    code = WsNamespacePrefix.Soap + ":Sender";
                    subcode = WsNamespacePrefix.Wsa + ":ActionNotSupported";
                    reason = "The [action] cannot be processed at the receiver.";
                    break;
                case WsFaultType.WsaEndpointUnavailable:
                    code = WsNamespacePrefix.Soap + ":Receiver";
                    subcode = WsNamespacePrefix.Wsa + ":EndpointUnavailable";
                    reason = "The endpoint is unable to process the message at this time.";
                    break;

                case WsFaultType.WseDeliverModeRequestedUnavailable:
                    code = WsNamespacePrefix.Soap + ":Sender";
                    subcode = WsNamespacePrefix.Wse + ":DeliverModeRequestedUnavailable";
                    reason = "The request delivery mode is not supported.";
                    extraNS = WsPrefix.Wse;
                    break;
                case WsFaultType.WseInvalidExpirationTime:
                    code = WsNamespacePrefix.Soap + ":Sender";
                    subcode = WsNamespacePrefix.Wse + ":InvalidExpirationTime";
                    reason = "The expiration time requested is invalid.";
                    extraNS = WsPrefix.Wse;
                    break;
                case WsFaultType.WseUnsupportedExpirationType:
                    code = WsNamespacePrefix.Soap + ":Sender";
                    subcode = WsNamespacePrefix.Wse + ":UnsupportedExpirationType";
                    reason = "Only expiration durations are supported.";
                    extraNS = WsPrefix.Wse;
                    break;
                case WsFaultType.WseFilteringNotSupported:
                    code = WsNamespacePrefix.Soap + ":Sender";
                    subcode = WsNamespacePrefix.Wse + ":FilteringNotSupported";
                    reason = "Filtering is not supported.";
                    extraNS = WsPrefix.Wse;
                    break;
                case WsFaultType.WseFilteringRequestedUnavailable:
                    code = WsNamespacePrefix.Soap + ":Sender";
                    subcode = WsNamespacePrefix.Wse + ":FilteringRequestedUnavailable";
                    reason = "The requested filter dialect is not supported.";
                    extraNS = WsPrefix.Wse;
                    break;
                case WsFaultType.WseEventSourceUnableToProcess:
                    code = WsNamespacePrefix.Soap + ":Receiver";
                    subcode = WsNamespacePrefix.Wse + ":EventSourceUnableToProcess";
                    reason = "No explaination yet.";
                    extraNS = WsPrefix.Wse;
                    break;
                case WsFaultType.WseUnableToRenew:
                    code = WsNamespacePrefix.Soap + ":Receiver";
                    subcode = WsNamespacePrefix.Wse + ":UnableToRenew";
                    reason = "No explaination yet.";
                    extraNS = WsPrefix.Wse;
                    break;
                case WsFaultType.WseInvalidMessage:
                    code = WsNamespacePrefix.Soap + ":Sender";
                    subcode = WsNamespacePrefix.Wse + ":InvalidMessage";
                    reason = "Message is not valid and cannot be processed.";
                    extraNS = WsPrefix.Wse;
                    break;
            }

            // Create the XmlWriter
            using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                // Generate the fault Header
                WsWsaHeader faultHeader = new WsWsaHeader(
                    version.AddressingNamespace + "/fault", // Action
                    header.MessageID,                       // RelatesTo
                    faultAddress,                           // To
                    null, null, null);                      // ReplyTo, From, Any

                faultHeader.IsFaultMessage = true;

                WsMessage msg = new WsMessage(faultHeader, null, extraNS, null, null);

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

                // Generate fault Body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Fault", null);

                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Code", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Value", null);
                xmlWriter.WriteString(code);
                xmlWriter.WriteEndElement(); // End Value
                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Subcode", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Value", null);
                xmlWriter.WriteString(subcode);
                xmlWriter.WriteEndElement(); // End Value
                xmlWriter.WriteEndElement(); // End Subcode
                xmlWriter.WriteEndElement(); // End Code

                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Reason", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Text", null);
                xmlWriter.WriteAttributeString("xml", "lang", "http://www.w3.org/XML/1998/namespace", "en-US");
                xmlWriter.WriteString(reason);
                xmlWriter.WriteEndElement(); // End Text
                xmlWriter.WriteEndElement(); // End Reason

                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap , "Detail", null);
                xmlWriter.WriteString(details);
                xmlWriter.WriteEndElement(); // End Detail

                xmlWriter.WriteEndElement(); // End Fault

                smw.WriteSoapMessageEnd(xmlWriter);

                msg.Body = xmlWriter.ToArray();

                // Flush and close writer. Return stream buffer
                return msg;
            }
        }
Exemple #12
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());
        }
        /// <summary>
        /// Eventing UnSubscribe stub.
        /// </summary>
        /// <param name="header">Header object.</param>
        /// <param name="reader">An XmlReader positioned at the begining of the Unsubscribe request body element.</param>
        /// <param name="serviceEndpoints">A Collection of serviceEndpoints used to determine what services contain the specified event.</param>
        /// <returns>Byte array containing an UnSubscribe response.</returns>
        /// <remarks>This method is used by the stack framework. Do not use this method.</remarks>
        public WsMessage Unsubscribe(WsWsaHeader header, XmlReader reader, WsServiceEndpoints serviceEndpoints)
        {
            // Parse Unsubscribe Request
            ///////////////////////////////
            // there's no info in Unsubscribe that we actually need, just get the identifier from header
            String eventSinkID = header.Any.GetNodeValue("Identifier", WsWellKnownUri.WseNamespaceUri);

            bool eventSourceFound = false;

            if (eventSinkID != null)
            {
                // Parse urn:uuid from the To address
                string endpointAddress = FixToAddress(header.To);

                // Iterate the list of hosted services at the specified endpoint and unsubscribe from each event source
                // that matches the eventSinkID

                DpwsHostedService serv = (DpwsHostedService)Device.HostedServices[endpointAddress];

                if (serv != null)
                {
                    DpwsWseEventSources eventSources = serv.EventSources;

                    // Delete Subscription
                    // Look for matching event in hosted services event sources
                    DpwsWseEventSource eventSource;
                    DpwsWseEventSinks  eventSinks;
                    DpwsWseEventSink   eventSink;
                    int eventSourcesCount = eventSources.Count;
                    int eventSinksCount;
                    for (int i = 0; i < eventSourcesCount; i++)
                    {
                        eventSource     = eventSources[i];
                        eventSinks      = eventSource.EventSinks;
                        eventSinksCount = eventSinks.Count;

                        eventSink = eventSinks[eventSinkID];

                        if (eventSink != null)
                        {
                            eventSourceFound = true;
                            eventSource.EventSinks.Remove(eventSink);
                        }
                    }
                }

                if (eventSourceFound)
                {
                    // Generate Response
                    using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
                    {
                        WsWsaHeader responseHeader = new WsWsaHeader(
                            WsWellKnownUri.WseNamespaceUri + "/UnsubscribeResponse", // Action
                            header.MessageID,                                        // RelatesTo
                            header.ReplyTo.Address.AbsoluteUri,                      // To
                            null, null, null);

                        WsMessage msg = new WsMessage(responseHeader, null, WsPrefix.Wse, null,
                                                      new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID));

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

                        // Return stream buffer
                        msg.Body = xmlWriter.ToArray();

                        return(msg);
                    }
                }
            }

            // Something went wrong
            throw new WsFaultException(header, WsFaultType.WseEventSourceUnableToProcess);
        }
Exemple #14
0
        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);
            }
        }
        /// <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 is ProtocolVersion11?  m_version.AnonymousUri : null), 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);
        }
        internal static WsMessage GenerateFaultResponse(WsWsaHeader header, WsFaultType faultType, String details, ProtocolVersion version)
        {
            String   code    = String.Empty;
            String   subcode = String.Empty;
            String   reason  = String.Empty;
            WsPrefix extraNS = WsPrefix.Wse;

            string faultAddress = null;

            if (header.FaultTo != null)
            {
                faultAddress = header.FaultTo.Address.OriginalString;
            }

            if (faultAddress == null)
            {
                faultAddress = version.AnonymousUri;
            }

            switch (faultType)
            {
            case WsFaultType.ArgumentException:
                code    = WsNamespacePrefix.Soap + ":Receiver";
                subcode = "ArgumentException";
                reason  = "One of the arguments provided to a method is not valid.";
                break;

            case WsFaultType.ArgumentNullException:
                code    = WsNamespacePrefix.Soap + ":Receiver";
                subcode = "ArgumentNullException";
                reason  = "A null reference was passed to a method that does not accept it as a valid argument.";
                break;

            case WsFaultType.Exception:
                code    = WsNamespacePrefix.Soap + ":Receiver";
                subcode = "Exception";
                reason  = "Errors occured during application execution.";
                break;

            case WsFaultType.InvalidOperationException:
                code    = WsNamespacePrefix.Soap + ":Receiver";
                subcode = "InvalidOperationException";
                reason  = "A method call is invalid for the object's current state.";
                break;

            case WsFaultType.XmlException:
                code    = WsNamespacePrefix.Soap + ":Receiver";
                subcode = "XmlException";
                reason  = "Syntax errors found during parsing.";
                break;

            case WsFaultType.WsaInvalidMessageInformationHeader:
                code    = WsNamespacePrefix.Soap + ":Sender";
                subcode = WsNamespacePrefix.Wsa + ":InvalidMessageInformationHeader";
                reason  = "A message information header is not valid and cannot be processed.";
                break;

            case WsFaultType.WsaMessageInformationHeaderRequired:
                code    = WsNamespacePrefix.Soap + ":Sender";
                subcode = WsNamespacePrefix.Wsa + ":MessageInformationHeaderRequired";
                reason  = "A required message Information header, To, MessageID, or Action, is not present";
                break;

            case WsFaultType.WsaDestinationUnreachable:
                code    = WsNamespacePrefix.Soap + ":Sender";
                subcode = WsNamespacePrefix.Wsa + ":DestinationUnreachable";
                reason  = "No route can be determined to reach the destination role defined by the WS=Addressing To.";
                break;

            case WsFaultType.WsaActionNotSupported:
                code    = WsNamespacePrefix.Soap + ":Sender";
                subcode = WsNamespacePrefix.Wsa + ":ActionNotSupported";
                reason  = "The [action] cannot be processed at the receiver.";
                break;

            case WsFaultType.WsaEndpointUnavailable:
                code    = WsNamespacePrefix.Soap + ":Receiver";
                subcode = WsNamespacePrefix.Wsa + ":EndpointUnavailable";
                reason  = "The endpoint is unable to process the message at this time.";
                break;

            case WsFaultType.WseDeliverModeRequestedUnavailable:
                code    = WsNamespacePrefix.Soap + ":Sender";
                subcode = WsNamespacePrefix.Wse + ":DeliverModeRequestedUnavailable";
                reason  = "The request delivery mode is not supported.";
                extraNS = WsPrefix.Wse;
                break;

            case WsFaultType.WseInvalidExpirationTime:
                code    = WsNamespacePrefix.Soap + ":Sender";
                subcode = WsNamespacePrefix.Wse + ":InvalidExpirationTime";
                reason  = "The expiration time requested is invalid.";
                extraNS = WsPrefix.Wse;
                break;

            case WsFaultType.WseUnsupportedExpirationType:
                code    = WsNamespacePrefix.Soap + ":Sender";
                subcode = WsNamespacePrefix.Wse + ":UnsupportedExpirationType";
                reason  = "Only expiration durations are supported.";
                extraNS = WsPrefix.Wse;
                break;

            case WsFaultType.WseFilteringNotSupported:
                code    = WsNamespacePrefix.Soap + ":Sender";
                subcode = WsNamespacePrefix.Wse + ":FilteringNotSupported";
                reason  = "Filtering is not supported.";
                extraNS = WsPrefix.Wse;
                break;

            case WsFaultType.WseFilteringRequestedUnavailable:
                code    = WsNamespacePrefix.Soap + ":Sender";
                subcode = WsNamespacePrefix.Wse + ":FilteringRequestedUnavailable";
                reason  = "The requested filter dialect is not supported.";
                extraNS = WsPrefix.Wse;
                break;

            case WsFaultType.WseEventSourceUnableToProcess:
                code    = WsNamespacePrefix.Soap + ":Receiver";
                subcode = WsNamespacePrefix.Wse + ":EventSourceUnableToProcess";
                reason  = "No explaination yet.";
                extraNS = WsPrefix.Wse;
                break;

            case WsFaultType.WseUnableToRenew:
                code    = WsNamespacePrefix.Soap + ":Receiver";
                subcode = WsNamespacePrefix.Wse + ":UnableToRenew";
                reason  = "No explaination yet.";
                extraNS = WsPrefix.Wse;
                break;

            case WsFaultType.WseInvalidMessage:
                code    = WsNamespacePrefix.Soap + ":Sender";
                subcode = WsNamespacePrefix.Wse + ":InvalidMessage";
                reason  = "Message is not valid and cannot be processed.";
                extraNS = WsPrefix.Wse;
                break;
            }

            // Create the XmlWriter
            using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                // Generate the fault Header
                WsWsaHeader faultHeader = new WsWsaHeader(
                    version.AddressingNamespace + "/fault", // Action
                    header.MessageID,                       // RelatesTo
                    faultAddress,                           // To
                    null, null, null);                      // ReplyTo, From, Any

                WsMessage msg = new WsMessage(faultHeader, null, extraNS, null, null);

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

                // Generate fault Body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Fault", null);

                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Code", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Value", null);
                xmlWriter.WriteString(code);
                xmlWriter.WriteEndElement(); // End Value
                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Subcode", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Value", null);
                xmlWriter.WriteString(subcode);
                xmlWriter.WriteEndElement(); // End Value
                xmlWriter.WriteEndElement(); // End Subcode
                xmlWriter.WriteEndElement(); // End Code

                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Reason", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Text", null);
                xmlWriter.WriteAttributeString("xml", "lang", "http://www.w3.org/XML/1998/namespace", "en-US");
                xmlWriter.WriteString(reason);
                xmlWriter.WriteEndElement(); // End Text
                xmlWriter.WriteEndElement(); // End Reason

                xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Detail", null);
                xmlWriter.WriteString(details);
                xmlWriter.WriteEndElement(); // End Detail

                xmlWriter.WriteEndElement(); // End Fault

                smw.WriteSoapMessageEnd(xmlWriter);

                msg.Body = xmlWriter.ToArray();

                // Flush and close writer. Return stream buffer
                return(msg);
            }
        }
        /// <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 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);
        }
Exemple #19
0
        internal static WsMessage GenerateFaultResponse(WsWsaHeader header, WsFaultType faultType, String details)
        {
            String code    = String.Empty;
            String subcode = String.Empty;
            String reason  = String.Empty;

            switch (faultType)
            {
            case WsFaultType.ArgumentException:
                code    = "soap:Receiver";
                subcode = "Ws:ArgumentException";
                reason  = "One of the arguments provided to a method is not valid.";
                break;

            case WsFaultType.ArgumentNullException:
                code    = "soap:Receiver";
                subcode = "Ws:ArgumentNullException";
                reason  = "A null reference was passed to a method that does not accept it as a valid argument.";
                break;

            case WsFaultType.Exception:
                code    = "soap:Receiver";
                subcode = "Ws:Exception";
                reason  = "Errors occured during application execution.";
                break;

            case WsFaultType.InvalidOperationException:
                code    = "soap:Receiver";
                subcode = "Ws:InvalidOperationException";
                reason  = "A method call is invalid for the object's current state.";
                break;

            case WsFaultType.XmlException:
                code    = "soap:Receiver";
                subcode = "Ws:XmlException";
                reason  = "Syntax errors found during parsing.";
                break;

            case WsFaultType.WsaInvalidMessageInformationHeader:
                code    = "soap:Sender";
                subcode = "wsa:InvalidMessageInformationHeader";
                reason  = "A message information header is not valid and cannot be processed.";
                break;

            case WsFaultType.WsaMessageInformationHeaderRequired:
                code    = "soap:Sender";
                subcode = "wsa:MessageInformationHeaderRequired";
                reason  = "A required message Information header, To, MessageID, or Action, is not present";
                break;

            case WsFaultType.WsaDestinationUnreachable:
                code    = "soap:Sender";
                subcode = "wsa:DestinationUnreachable";
                reason  = "No route can be determined to reach the destination role defined by the WS=Addressing To.";
                break;

            case WsFaultType.WsaActionNotSupported:
                code    = "soap:Sender";
                subcode = "wsa:ActionNotSupported";
                reason  = "The [action] cannot be processed at the receiver.";
                break;

            case WsFaultType.WsaEndpointUnavailable:
                code    = "soap:Receiver";
                subcode = "wsa:EndpointUnavailable";
                reason  = "The endpoint is unable to process the message at this time.";
                break;

            case WsFaultType.WseDeliverModeRequestedUnavailable:
                code    = "soap:Sender";
                subcode = "wse:DeliverModeRequestedUnavailable";
                reason  = "The request delivery mode is not supported.";
                break;

            case WsFaultType.WseInvalidExpirationTime:
                code    = "soap:Sender";
                subcode = "wse:InvalidExpirationTime";
                reason  = "The expiration time requested is invalid.";
                break;

            case WsFaultType.WseUnsupportedExpirationType:
                code    = "soap:Sender";
                subcode = "wse:UnsupportedExpirationType";
                reason  = "Only expiration durations are supported.";
                break;

            case WsFaultType.WseFilteringNotSupported:
                code    = "soap:Sender";
                subcode = "wse:FilteringNotSupported";
                reason  = "Filtering is not supported.";
                break;

            case WsFaultType.WseFilteringRequestedUnavailable:
                code    = "soap:Sender";
                subcode = "wse:FilteringRequestedUnavailable";
                reason  = "The requested filter dialect is not supported.";
                break;

            case WsFaultType.WseEventSourceUnableToProcess:
                code    = "soap:Receiver";
                subcode = "wse:EventSourceUnableToProcess";
                reason  = "No explaination yet.";
                break;

            case WsFaultType.WseUnableToRenew:
                code    = "soap:Receiver";
                subcode = "wse:UnableToRenew";
                reason  = "No explaination yet.";
                break;

            case WsFaultType.WseInvalidMessage:
                code    = "soap:Sender";
                subcode = "wse:InvalidMessage";
                reason  = "Message is not valid and cannot be processed.";
                break;
            }

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

            // Generate the fault Header
            WsWsaHeader faultHeader = new WsWsaHeader(
                WsWellKnownUri.WsaNamespaceUri_2005_08 + "/fault", // Action
                header.MessageID,                                  // RelatesTo
                "urn:schemas-xmlsoap-org:ws:2005:08:fault",        // To
                null, null, null);                                 // ReplyTo, From, Any

            WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter, WsSoapMessageWriter.Prefixes.Wsdp, null, faultHeader, null);

            // Generate fault Body
            xmlWriter.WriteStartElement("wsa", "Fault", null);

            xmlWriter.WriteStartElement("wsa", "Code", null);
            xmlWriter.WriteStartElement("wsa", "Value", null);
            xmlWriter.WriteString(code);
            xmlWriter.WriteEndElement(); // End Value
            xmlWriter.WriteStartElement("wsa", "Subcode", null);
            xmlWriter.WriteStartElement("wsa", "Value", null);
            xmlWriter.WriteString(subcode);
            xmlWriter.WriteEndElement(); // End Value
            xmlWriter.WriteEndElement(); // End Subcode
            xmlWriter.WriteEndElement(); // End Code

            xmlWriter.WriteStartElement("wsa", "Reason", null);
            xmlWriter.WriteStartElement("wsa", "Text", null);
            xmlWriter.WriteAttributeString("xml", "lang", null, "en");
            xmlWriter.WriteString(reason);
            xmlWriter.WriteEndElement(); // End Text
            xmlWriter.WriteEndElement(); // End Reason

            xmlWriter.WriteStartElement("wsdp", "Detail", null);
            xmlWriter.WriteString(details);
            xmlWriter.WriteEndElement(); // End Detail

            xmlWriter.WriteEndElement(); // End Fault

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

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

            WsMessage response = new WsMessage(soapStream.ToArray());

            return(response);
        }
        /// <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 #22
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>
        /// 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);
            }
        }
Exemple #24
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 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 this method to raise an event.
        /// </summary>
        /// <param name="hostedService">The hosted service that contains the event source.</param>
        /// <param name="eventSource">The event source that define the event.</param>
        /// <param name="eventMessage">The event message buffer.</param>
        /// <remarks>
        /// A device developer is responsible for building the event message buffer sent
        /// to clients that have an active event subscription with an event source. The subscription manager
        /// uses the hosted service parameter to access various properties of the service. The event source
        /// parameter is used to access the event sinks collection of the event source. Note: This method
        /// requires special provisions in order to properly build event message headers for each event sink.
        /// In order to send an event to a listening client the soap.header.To property must be changed for
        /// each listening client. In the future custom attribute support will solve this problem. For now
        /// however a search and replace mechanism is used to modifiy the header.To property. When a device
        /// developer builds the event message buffer they must use the search string WSDNOTIFYTOADDRESS for
        /// the To header property.
        /// </remarks>
        public void FireEvent(DpwsHostedService hostedService, DpwsWseEventSource eventSource, WsWsaHeader eventHeader, String eventMessageBody)
        {
            // Find the specified event source
            if (eventSource == null)
            {
                throw new ArgumentNullException("FireEvent could not locate specified hosted service");
            }
            DpwsWseEventSinks eventSinks = eventSource.EventSinks;

            // if there are event sources display message
            int count = eventSinks.Count;

            if (count > 0)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Firing " + eventSource.Name);
                System.Ext.Console.Write("");
            }

            // Loop through event sinks and send the event message
            for (int i = 0; i < count; i++)
            {
                DpwsWseEventSink eventSink = eventSinks[i];

                // Try to send event. If attempt fails delete the subscription/eventSink
                try
                {
                    MemoryStream soapStream = new MemoryStream();
                    XmlWriter    xmlWriter  = XmlWriter.Create(soapStream);

                    WsWsaHeader header = new WsWsaHeader(eventHeader.Action, eventHeader.RelatesTo, eventSink.NotifyTo.Address.AbsoluteUri,
                                                         null, null, eventSink.NotifyTo.RefParameters);

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

                    if (eventMessageBody != null)
                    {
                        xmlWriter.WriteRaw(eventMessageBody);
                    }

                    WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

                    xmlWriter.Flush();
                    xmlWriter.Close();

                    SendEvent(soapStream.ToArray(), eventSink.NotifyTo.Address.AbsoluteUri);
                }
                catch (Exception e)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("FireEvent failed. Deleting EventSink! NotifyToAddress = " + eventSink.NotifyTo.Address + " Exception: " + e.Message);
                    System.Ext.Console.Write("");

                    // Send oneway subscription end message
                    try
                    {
                        SendSubscriptionEnd(eventSink, "DeliveryFailure", hostedService.ServiceID);
                    }
                    catch { }

                    // Remove event sink from event source list
                    eventSinks.Remove(eventSink);
                }
            }
        }
        /// <summary>
        /// Processes a message 
        /// </summary>
        /// <param name="msg">The message being processed.</param>
        /// <param name="ctx">The context associated with the message.</param>
        /// <returns>The handling status for this operation.</returns>
        protected override ChainResult OnProcessOutputMessage( ref WsMessage msg, BindingContext ctx )
        {
            byte[] data = null;

            // if the body is a byte[] then it is already serialized (UDP stuff)
            if (msg == null || (msg.Body != null && msg.Body is byte[])) return ChainResult.Continue;

            // Build response message
            using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsSoapMessageWriter smw = new WsSoapMessageWriter(ctx.Version);

                // Write start message up to body element content
                smw.WriteSoapMessageStart(xmlWriter, msg, ctx.Version.IncludeSoapHeaders);

                if (msg.Body != null && msg.Serializer != null)
                {
                    DataContractSerializer ser = (DataContractSerializer)msg.Serializer;
                    // Serialize the body element
                    ser.WriteObject(xmlWriter, msg.Body);

                    if(ser.BodyParts != null && ser.BodyParts.Count > 0)
                    {
                        msg.BodyParts = ser.BodyParts;
                    }
                }

                // Write end message
                smw.WriteSoapMessageEnd(xmlWriter);

                data = xmlWriter.ToArray();
            }

            WsMtomBodyParts bodyParts = msg.BodyParts;

            if (bodyParts != null)
            {
                DataContractSerializer reqDcs = (DataContractSerializer)msg.Serializer;

                bodyParts.Start = "<soap@soap>";
                bodyParts.AddStart(reqDcs.CreateNewBodyPart(data, bodyParts.Start));
                if (reqDcs.BodyParts.Count > 0)
                {
                    bodyParts.Add(reqDcs.BodyParts[0]);
                }

                WsMtomParams mtomParams = new WsMtomParams();
                if (bodyParts.Boundary == null)
                    bodyParts.Boundary = Guid.NewGuid().ToString() + '-' + Guid.NewGuid().ToString().Substring(0, 33);
                mtomParams.start = bodyParts.Start;
                mtomParams.boundary = bodyParts.Boundary;
                msg.MtomPropeties = mtomParams;
                WsMtom mtom = new WsMtom();
                data = mtom.CreateMessage(bodyParts);
            }

            msg.Body = data;

            return ChainResult.Continue;
        }
        /// <summary>
        /// Eventing UnSubscribe stub.
        /// </summary>
        /// <param name="header">Header object.</param>
        /// <param name="reader">An XmlReader positioned at the begining of the Unsubscribe request body element.</param>
        /// <param name="serviceEndpoints">A Collection of serviceEndpoints used to determine what services contain the specified event.</param>
        /// <returns>Byte array containing an UnSubscribe response.</returns>
        /// <remarks>This method is used by the stack framework. Do not use this method.</remarks>
        public byte[] Unsubscribe(WsWsaHeader header, XmlReader reader, WsServiceEndpoints serviceEndpoints)
        {
            // Parse Unsubscribe Request
            ///////////////////////////////
            // there's no info in Unsubscribe that we actually need, just get the identifier from header
            String eventSinkID = header.Any.GetNodeValue("Identifier", WsWellKnownUri.WseNamespaceUri);

            bool eventSourceFound = false;

            if (eventSinkID != null)
            {
                // Parse urn:uuid from the To address
                string endpointAddress = FixToAddress(header.To);

                // Iterate the list of hosted services at the specified endpoint and unsubscribe from each event source
                // that matches the eventSinkID
                for (int i = 0; i < Device.HostedServices.Count; ++i)
                {
                    if (serviceEndpoints[i].EndpointAddress == endpointAddress)
                    {
                        // Delete Subscription
                        DpwsWseEventSources eventSources = ((DpwsHostedService)Device.HostedServices[i]).EventSources;

                        // Look for matching event in hosted services event sources
                        DpwsWseEventSource eventSource;
                        DpwsWseEventSinks  eventSinks;
                        DpwsWseEventSink   eventSink;
                        int eventSourcesCount = eventSources.Count;
                        int eventSinksCount;
                        for (int ii = 0; ii < eventSourcesCount; ii++)
                        {
                            eventSource     = eventSources[ii];
                            eventSinks      = eventSource.EventSinks;
                            eventSinksCount = eventSinks.Count;
                            for (int j = 0; j < eventSinksCount; j++)
                            {
                                eventSink = eventSinks[j];
                                if (eventSink.ID == eventSinkID)
                                {
                                    eventSourceFound = true;
                                    eventSource.EventSinks.Remove(eventSink);
                                }
                            }
                        }
                    }
                }

                if (eventSourceFound)
                {
                    // Generate Response

                    MemoryStream soapStream = new MemoryStream();
                    XmlWriter    xmlWriter  = XmlWriter.Create(soapStream);

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

                    WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter,
                                                              WsSoapMessageWriter.Prefixes.Wse,                                                              // Prefix
                                                              null,                                                                                          // Additional Prefix
                                                              responseHeader,                                                                                // Header
                                                              new WsSoapMessageWriter.AppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); // AppSequence

                    WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

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

            // Something went wrong
            throw new WsFaultException(header, WsFaultType.WseEventSourceUnableToProcess);
        }
Exemple #29
0
        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);
            }
        }
        /// <summary>
        /// Global eventing Subscribe stub.
        /// </summary>
        /// <param name="header">Header object.</param>
        /// <param name="reader">An XmlReader positioned at the begining of the Subscribe request body element.</param>
        /// <param name="serviceEndpoints">A Collection of serviceEndpoints used to determine what services contain the event source specified in the filter.</param>
        /// <returns>Byte array containing a Subscribe response.</returns>
        internal WsMessage Subscribe(WsWsaHeader header, XmlReader reader, WsServiceEndpoints serviceEndpoints)
        {
            WsMessage msg = null;

            // Parse Subscribe Request
            /////////////////////////////
            DpwsWseEventSink eventSink = new DpwsWseEventSink();

            try
            {
                reader.ReadStartElement("Subscribe", WsWellKnownUri.WseNamespaceUri);

                if (reader.IsStartElement("EndTo", WsWellKnownUri.WseNamespaceUri))
                {
                    eventSink.EndTo = new WsWsaEndpointRef(reader, m_version.AddressingNamespace);
                }

                reader.ReadStartElement("Delivery", WsWellKnownUri.WseNamespaceUri);
                if (reader.IsStartElement("NotifyTo", WsWellKnownUri.WseNamespaceUri))
                {
                    eventSink.NotifyTo = new WsWsaEndpointRef(reader, m_version.AddressingNamespace);
                }
                else
                {
                    throw new WsFaultException(header, WsFaultType.WseDeliverModeRequestedUnavailable);
                }

                reader.ReadEndElement();

                if (reader.IsStartElement("Expires", WsWellKnownUri.WseNamespaceUri))
                {
                    long expires = new WsDuration(reader.ReadElementString()).DurationInSeconds;

                    if (expires > 0)
                    {
                        eventSink.Expires = expires;
                    }
                    else
                    {
                        throw new WsFaultException(header, WsFaultType.WseInvalidExpirationTime);
                    }
                }
                else
                {
                    // Never Expires
                    eventSink.Expires = -1;
                }

                if (reader.IsStartElement("Filter", WsWellKnownUri.WseNamespaceUri))
                {
                    if (reader.MoveToAttribute("Dialect") == false || reader.Value != m_version.WsdpNamespaceUri + "/Action")
                    {
                        throw new WsFaultException(header, WsFaultType.WseFilteringRequestedUnavailable);
                    }

                    reader.MoveToElement();

                    String filters = reader.ReadElementString();

                    if (filters != String.Empty)
                    {
                        eventSink.Filters = filters.Split(' ');
                    }
                }

                XmlReaderHelper.SkipAllSiblings(reader);

                reader.ReadEndElement(); // Subscribe
            }
            catch (XmlException e)
            {
                throw new WsFaultException(header, WsFaultType.WseInvalidMessage, e.ToString());
            }

            // Parse urn:uuid from the To address
            string endpointAddress = FixToAddress(header.To);

            // Build a temporary collection of device services that match the specified endpoint address.
            WsServiceEndpoints matchingServices = new WsServiceEndpoints();

            for (int i = 0; i < serviceEndpoints.Count; ++i)
            {
                if (serviceEndpoints[i].EndpointAddress == endpointAddress)
                {
                    matchingServices.Add(serviceEndpoints[i]);
                }
            }

            // For each service with a matching endpoint and event sources add an event sink to the
            // event source collection
            for (int i = 0; i < matchingServices.Count; ++i)
            {
                DpwsWseEventSources eventSources = ((DpwsHostedService)matchingServices[i]).EventSources;

                // Set the EventSinkID
                eventSink.ID = "urn:uuid:" + Guid.NewGuid().ToString();

                // If subscribing to all event sources
                if (eventSink.Filters == null)
                {
                    int count = eventSources.Count;
                    for (int ii = 0; i < count; i++)
                    {
                        DpwsWseEventSource eventSource = eventSources[ii];
                        eventSink.StartTime = DateTime.Now.Ticks;
                        eventSource.EventSinks.Add(eventSink);
                    }
                }
                else
                {
                    // If subscribing to a specific event based on an event filter.
                    DpwsWseEventSource eventSource;
                    string[]           filterList = eventSink.Filters;
                    int length = filterList.Length;
                    for (int ii = 0; i < length; i++)
                    {
                        if ((eventSource = eventSources[filterList[ii]]) != null)
                        {
                            eventSink.StartTime = DateTime.Now.Ticks;
                            eventSource.EventSinks.Add(eventSink);
                        }
                        else
                        {
                            throw new Exception("Event source " + filterList[ii] + " was not found.");
                        }
                    }
                }
            }

            // Generate Response
            //////////////////////////
            using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsWsaHeader responseHeader = new WsWsaHeader(
                    WsWellKnownUri.WseNamespaceUri + "/SubscribeResponse",  // Action
                    header.MessageID,                                       // RelatesTo
                    header.ReplyTo.Address.AbsoluteUri,                     // To
                    null, null, null);                                      // ReplyTo, From, Any

                msg = new WsMessage(responseHeader, null, WsPrefix.Wse, null,
                                    new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID));

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

                // write body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "SubscribeResponse", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "SubscriptionManager", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null);
                // Create a uri. Use the path (by default will be a uuid) for the sub manager endpoint
                Uri subMgrUri = new Uri(((DpwsHostedService)matchingServices[0]).EndpointAddress);
                xmlWriter.WriteString("http://" + Device.IPV4Address + ":" + Device.Port + "/" + subMgrUri.AbsolutePath);
                xmlWriter.WriteEndElement(); // End Address
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "ReferenceParameters", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Identifier", null);
                xmlWriter.WriteString(eventSink.ID);
                xmlWriter.WriteEndElement(); // End Identifier
                xmlWriter.WriteEndElement(); // End ReferenceParameters
                xmlWriter.WriteEndElement(); // End SubscriptionManager
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Expires", null);
                xmlWriter.WriteString(new WsDuration(eventSink.Expires).DurationString);
                xmlWriter.WriteEndElement(); // End Expires
                xmlWriter.WriteEndElement(); // End SubscribeResponse

                smw.WriteSoapMessageEnd(xmlWriter);

                // Return stream buffer
                msg.Body = xmlWriter.ToArray();
            }

            return(msg);
        }
Exemple #31
0
        public byte[] GetResponse(WsWsaHeader header, XmlReader reader)
        {
            // Build ProbeMatch
            MemoryStream soapStream = new MemoryStream();
            XmlWriter    xmlWriter  = XmlWriter.Create(soapStream);

            // 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);

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

            // write body
            xmlWriter.WriteStartElement("wsx", "Metadata", WsWellKnownUri.WsxNamespaceUri);

            // Write ThisModel metadata section
            xmlWriter.WriteStartElement("wsx", "MetadataSection", WsWellKnownUri.WsxNamespaceUri);
            xmlWriter.WriteAttributeString("Dialect", "http://schemas.xmlsoap.org/ws/2006/02/devprof/ThisModel");

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

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

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

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

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

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

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

            xmlWriter.WriteStartElement("wsdp", "ModelName", WsWellKnownUri.WsdpNamespaceUri);
            xmlWriter.WriteString(Device.ThisModel.ModelName);
            xmlWriter.WriteEndElement(); // End ModelName

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

            // Write ThisDevice metadata section
            xmlWriter.WriteStartElement("wsx", "MetadataSection", WsWellKnownUri.WsxNamespaceUri);
            xmlWriter.WriteAttributeString("Dialect", "http://schemas.xmlsoap.org/ws/2006/02/devprof/ThisDevice");

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

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

            if (Device.ThisDevice.SerialNumber != null && Device.ThisDevice.SerialNumber != "")
            {
                xmlWriter.WriteStartElement("wsdp", "SerialNumber", WsWellKnownUri.WsdpNamespaceUri);
                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("wsx", "MetadataSection", WsWellKnownUri.WsxNamespaceUri);
            xmlWriter.WriteAttributeString("Dialect", "http://schemas.xmlsoap.org/ws/2006/02/devprof/Relationship");

            // Write Relationship Elements
            xmlWriter.WriteStartElement("wsdp", "Relationship", WsWellKnownUri.WsdpNamespaceUri);
            xmlWriter.WriteAttributeString("Type", "http://schemas.xmlsoap.org/ws/2006/02/devprof/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("wsdp", "Host", WsWellKnownUri.WsdpNamespaceUri);
                WsWsaEndpointRef endpointReference;
                endpointReference = (WsWsaEndpointRef)Device.Host.EndpointRefs[0];
                xmlWriter.WriteStartElement("wsa", "EndpointReference", WsWellKnownUri.WsaNamespaceUri_2005_08);
                xmlWriter.WriteStartElement("wsa", "Address", WsWellKnownUri.WsaNamespaceUri_2005_08);
                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("wsdp", "Types", WsWellKnownUri.WsdpNamespaceUri);
                xmlWriter.WriteString(Device.Host.ServiceNamespace.Prefix + ":" + Device.Host.ServiceTypeName);
                xmlWriter.WriteEndElement(); // End Types

                // Write Service ID
                xmlWriter.WriteStartElement("wsdp", "ServiceId", WsWellKnownUri.WsdpNamespaceUri);
                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("wsdp", "Hosted", WsWellKnownUri.WsdpNamespaceUri);

                // Write n number of endpoint references
                int epRefCount = currentService.EndpointRefs.Count;
                for (int j = 0; j < epRefCount; j++)
                {
                    xmlWriter.WriteStartElement("wsa", "EndpointReference", WsWellKnownUri.WsaNamespaceUri_2005_08);
                    xmlWriter.WriteStartElement("wsa", "Address", WsWellKnownUri.WsaNamespaceUri_2005_08);
                    xmlWriter.WriteString(currentService.EndpointRefs[j].Address.AbsoluteUri);
                    xmlWriter.WriteEndElement(); // End Address
                    xmlWriter.WriteEndElement(); // End EndpointReference
                }

                // Write service types
                xmlWriter.WriteStartElement("wsdp", "Types", WsWellKnownUri.WsdpNamespaceUri);
                xmlWriter.WriteString(currentService.ServiceNamespace.Prefix + ":" + currentService.ServiceTypeName);
                xmlWriter.WriteEndElement(); // End Types

                // Write Service ID
                xmlWriter.WriteStartElement("wsdp", "ServiceId", WsWellKnownUri.WsdpNamespaceUri);
                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

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

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

            return(soapStream.ToArray());
        }
Exemple #32
0
        /// <summary>
        /// Processes a message
        /// </summary>
        /// <param name="msg">The message being processed.</param>
        /// <param name="ctx">The context associated with the message.</param>
        /// <returns>The handling status for this operation.</returns>
        protected override ChainResult OnProcessOutputMessage(ref WsMessage msg, BindingContext ctx)
        {
            byte[] data = null;

            // if the body is a byte[] then it is already serialized (UDP stuff)
            if (msg == null || (msg.Body != null && msg.Body is byte[]))
            {
                return(ChainResult.Continue);
            }

            // Build response message
            using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsSoapMessageWriter smw = new WsSoapMessageWriter(ctx.Version);

                // Write start message up to body element content
                smw.WriteSoapMessageStart(xmlWriter, msg, ctx.Version.IncludeSoapHeaders);

                if (msg.Body != null && msg.Serializer != null)
                {
                    DataContractSerializer ser = (DataContractSerializer)msg.Serializer;
                    // Serialize the body element
                    ser.WriteObject(xmlWriter, msg.Body);

                    if (ser.BodyParts != null && ser.BodyParts.Count > 0)
                    {
                        msg.BodyParts = ser.BodyParts;
                    }
                }

                // Write end message
                smw.WriteSoapMessageEnd(xmlWriter);

                data = xmlWriter.ToArray();
            }

            WsMtomBodyParts bodyParts = msg.BodyParts;

            if (bodyParts != null)
            {
                DataContractSerializer reqDcs = (DataContractSerializer)msg.Serializer;

                bodyParts.Start = "<soap@soap>";
                bodyParts.AddStart(reqDcs.CreateNewBodyPart(data, bodyParts.Start));
                if (reqDcs.BodyParts.Count > 0)
                {
                    bodyParts.Add(reqDcs.BodyParts[0]);
                }

                WsMtomParams mtomParams = new WsMtomParams();
                if (bodyParts.Boundary == null)
                {
                    bodyParts.Boundary = Guid.NewGuid().ToString() + '-' + Guid.NewGuid().ToString().Substring(0, 33);
                }
                mtomParams.start    = bodyParts.Start;
                mtomParams.boundary = bodyParts.Boundary;
                msg.MtomPropeties   = mtomParams;
                WsMtom mtom = new WsMtom();
                data = mtom.CreateMessage(bodyParts);
            }

            msg.Body = data;

            return(ChainResult.Continue);
        }