// 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 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 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); }
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); } }
/// <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="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); }
public virtual WsMessage ProbeMatch(WsMessage probe, DpwsHostedService matchedService) { XmlReader reader = probe.Reader; WsWsaHeader header = probe.Header; // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); // Build ProbeMatch using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { // If a Host exist write the Host namespace WsXmlNamespaces additionalPrefixes = null; if (Device.Host != null) { additionalPrefixes = new WsXmlNamespaces(); additionalPrefixes.Add(Device.Host.ServiceNamespace); } WsWsaHeader matchHeader = new WsWsaHeader( this.Version.DiscoveryNamespace + "/ProbeMatches", // Action header.MessageID, // RelatesTo this.Version.AnonymousUri, // To null, null, null); // ReplyTo, From, Any WsMessage msg = new WsMessage(matchHeader, null, WsPrefix.Wsd | WsPrefix.Wsdp, additionalPrefixes, new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); WsSoapMessageWriter smw = new WsSoapMessageWriter(this.Version); smw.WriteSoapMessageStart(xmlWriter, msg); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "ProbeMatches", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "ProbeMatch", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "EndpointReference", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null); xmlWriter.WriteString(matchedService == null ? Device.EndpointAddress : matchedService.EndpointAddress); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); // Write hosted service types xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "Types", null); WriteDeviceServiceTypes(xmlWriter); xmlWriter.WriteEndElement(); // End Types xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "XAddrs", null); string transport = Device.TransportAddress; if (matchedService != null) { int idx = transport.LastIndexOf('/'); if (idx != -1) { transport = transport.Substring(0, idx + 1); transport += matchedService.EndpointAddress.Substring(matchedService.EndpointAddress.IndexOf("urn:uuid:") + 9); } } int idx2 = transport.ToLower().IndexOf("localhost"); if (idx2 != -1) { transport = transport.Substring(0, idx2) + WsNetworkServices.GetLocalIPV4Address() + transport.Substring(idx2 + 9 /*localhost*/); } xmlWriter.WriteString(transport); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "MetadataVersion", null); xmlWriter.WriteString(Device.MetadataVersion.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); smw.WriteSoapMessageEnd(xmlWriter); msg.Body = xmlWriter.ToArray(); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***ProbeMatch Took"); // Delay probe match as per Ws-Discovery specification (2.4 Protocol Assignments) Thread.Sleep(new Random().Next(Device.ProbeMatchDelay)); // Return stream buffer return(msg); } }
public virtual WsMessage ResolveMatch(WsMessage message) { XmlReader reader = message.Reader; WsWsaHeader header = message.Header; bool match = false; string epAddr = ""; reader.ReadStartElement("Resolve", this.Version.DiscoveryNamespace); if (reader.IsStartElement("EndpointReference", this.Version.AddressingNamespace) == false) { return(null); } WsWsaEndpointRef epRef = new WsWsaEndpointRef(reader, this.Version.AddressingNamespace); epAddr = epRef.Address.AbsoluteUri; if (Device.EndpointAddress != epAddr) { // If the destination endpoint is ours send a resolve match else return null int servicesCount = Device.HostedServices.Count; DpwsHostedService hostedService; for (int i = 0; i < servicesCount; i++) { hostedService = (DpwsHostedService)Device.HostedServices[i]; // Skip internal services if (hostedService.ServiceTypeName == "Internal") { continue; } if (hostedService.EndpointAddress == epAddr) { match = true; break; } } if (!match) { return(null); } } // Build ResolveMatch using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { // If a Host exist write the Host namespace WsXmlNamespaces additionalPrefixes = null; if (Device.Host != null) { additionalPrefixes = new WsXmlNamespaces(); additionalPrefixes.Add(Device.Host.ServiceNamespace); } WsWsaHeader matchHeader = new WsWsaHeader( this.Version.DiscoveryNamespace + "/ResolveMatches", // Action header.MessageID, // RelatesTo this.Version.AnonymousUri, // To null, null, null); // ReplyTo, From, Any WsMessage msg = new WsMessage(matchHeader, null, WsPrefix.Wsd | WsPrefix.Wsdp, additionalPrefixes, new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); WsSoapMessageWriter smw = new WsSoapMessageWriter(this.Version); smw.WriteSoapMessageStart(xmlWriter, msg); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "ResolveMatches", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "ResolveMatch", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "EndpointReference", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null); xmlWriter.WriteString(epRef.Address.AbsoluteUri); xmlWriter.WriteEndElement(); // End Address xmlWriter.WriteEndElement(); // End EndpointReference // Write hosted service types xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "Types", null); WriteDeviceServiceTypes(xmlWriter); xmlWriter.WriteEndElement(); // End Types string transport = Device.TransportAddress; if (match) { int idx = transport.LastIndexOf('/'); if (idx != -1) { transport = transport.Substring(0, idx + 1); transport += epAddr.Substring(epAddr.IndexOf("urn:uuid:") + 9); } } int idx2 = transport.ToLower().IndexOf("localhost"); if (idx2 != -1) { transport = transport.Substring(0, idx2) + WsNetworkServices.GetLocalIPV4Address() + transport.Substring(idx2 + 9 /*localhost*/); } xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "XAddrs", null); xmlWriter.WriteString(transport); xmlWriter.WriteEndElement(); // End XAddrs xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "MetadataVersion", null); xmlWriter.WriteString(Device.MetadataVersion.ToString()); xmlWriter.WriteEndElement(); // End MetadataVersion xmlWriter.WriteEndElement(); // End ResolveMatch xmlWriter.WriteEndElement(); // End ResolveMatches smw.WriteSoapMessageEnd(xmlWriter); msg.Body = xmlWriter.ToArray(); // Return stream buffer return(msg); } }
/// <summary> /// Use to get the status of an event subscription. /// </summary> /// <param name="endpointAddress"> /// A Uri containing the endpoint address of the service or subscription manager that is currently /// maintaining this event subscription on behalf of the device. This address is an http uri /// (i.e. http://ip_address:port/serviceID). /// </param> /// <param name="subscriptionID"> /// A subscription ID returned from a previous subscribe response. The device uses this ID /// to identify a specific event source subscription. /// </param> /// <returns> /// A WsDuration object containing the remaining subscription time for this event subscription, null = infinite. /// </returns> public WsDuration GetStatus(Uri endpointAddress, string subscriptionID) { // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); // Build Renew request using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { WsXmlNodeList nodeList = new WsXmlNodeList(); nodeList.Add(new WsXmlNode(WsNamespacePrefix.Wse, "Identifier", null, subscriptionID)); WsWsaHeader header = new WsWsaHeader( m_version.EventingNamespace + "/GetStatus", // Action null, // RelatesTo endpointAddress.AbsoluteUri, // To null, null, nodeList); // ReplyTo, From, Any WsMessage msg = new WsMessage(header, null, WsPrefix.Wse, null, null); WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version); String messageID = smw.WriteSoapMessageStart(xmlWriter, msg); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Soap, "Body", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "GetStatus", null); xmlWriter.WriteString(""); xmlWriter.WriteEndElement(); // End GetStatus // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); smw.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Renew Message Build Took"); // Create an Http client and send GetStatus request WsHttpClient httpClient = new WsHttpClient(m_version); msg.Body = xmlWriter.ToString(); WsMessage getStatusResponse = httpClient.SendRequest(msg, endpointAddress); // If a GetStatus response is received validate the messageID and action and get the remaining // event subscription time. If a fault is received print exception and go on. if (getStatusResponse == null) { System.Ext.Console.Write(""); System.Ext.Console.Write("Renew response is null."); return(null); } else { System.Ext.Console.Write(""); System.Ext.Console.Write("Response From: " + endpointAddress.Host); System.Ext.Console.Write(getStatusResponse.Body as byte[]); // Note: Since the response is the same for GetStatus ans it is for Renew reuse the // Renew response parser. try { return(ProcessRenewResponse((byte[])getStatusResponse.Body, messageID)); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Unsubscribe response parsing failed."); System.Ext.Console.Write(e.Message); } } } return(null); }
/// <summary> /// Use to unsubscribe from a devices event source. /// </summary> /// <param name="endpointAddress"> /// A Uri containing the endpoint address of the service or subscription manager that is currently /// maintaining this event subscription on behalf of the device. This address is an http uri /// (i.e. http://ip_address:port/serviceID). /// </param> /// <param name="subscription">An event subscription returned from a previous subscribe call. /// The subscription contains among other things a subscription ID used by the subscription manager /// to identify a specific event source subscription and the endpoint address of the subscription manager. /// </param> /// <returns>True if the Unsubscribe request was successful.</returns> public bool Unsubscribe(Uri endpointAddress, DpwsEventSubscription subscription) { // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); // Build Unsubscribe Request using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { WsXmlNodeList nodeList = new WsXmlNodeList(); nodeList.Add(new WsXmlNode(null, "identifier", WsWellKnownUri.WseNamespaceUri, subscription.SubscriptionID)); WsWsaHeader header = new WsWsaHeader( m_version.EventingNamespace + "/Unsubscribe", // Action null, // RelatesTo endpointAddress.AbsoluteUri, // To m_version.AddressingNamespace, // ReplyTo subscription.SubscriptionManager.Address.AbsoluteUri, // From nodeList); // Identifier WsMessage msg = new WsMessage(header, null, WsPrefix.Wse, null, null); WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version); String messageID = smw.WriteSoapMessageStart(xmlWriter, msg); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Unsubscribe", null); xmlWriter.WriteString(""); xmlWriter.WriteEndElement(); // End Unsubscribe // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); smw.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Unsubscribe Message Build Took"); // Create an Http client and send Unsubscribe request WsHttpClient httpClient = new WsHttpClient(m_version); msg.Body = xmlWriter.ToArray(); WsMessage unsubscribeResponse = httpClient.SendRequest(msg, endpointAddress); // If a unsubscribe response is received simple validate that the messageID and action are correct and // If a parsing fault is received print exception and go on. if (unsubscribeResponse == null) { System.Ext.Console.Write(""); System.Ext.Console.Write("Unsubscribe response is null."); return(false); } else { System.Ext.Console.Write(""); System.Ext.Console.Write("Response From: " + endpointAddress.Host); System.Ext.Console.Write(unsubscribeResponse.Body as byte[]); try { return(ProcessUnsubscribeResponse((byte[])unsubscribeResponse.Body, messageID)); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Unsubscribe response parsing failed."); System.Ext.Console.Write(e.Message); return(false); } } } }
/// <summary> /// Use to subscribe to a devices, hosted service event sources. /// </summary> /// <param name="subscriptionRequest"> /// A DpwsSubscriptionRequest object containing the address of the service hosting the desired event, /// the address where the event is sent, an optional address where subscription end messages are sent, /// A subscription expiration (in duration format) and an optional user defined identifier. /// </param> /// <returns> /// A DpwsEventSubscription containing the the subscription managers address, the time when the subscription /// expires (duration) and optional reference parameters and properties. Per spec the /// sub mananger may assign a different duration value than that specified in the request. /// </returns> /// <exception cref="ArgumentNullException">If required subscription parameters are not set.</exception> public DpwsEventSubscription Subscribe(DpwsSubscribeRequest subscriptionRequest) { if ((subscriptionRequest.SubscriptionType == null) || (subscriptionRequest.SubscriptionType.TypeName == null) || (subscriptionRequest.SubscriptionType.NamespaceUri == null) || (subscriptionRequest.EndpointAddress == null) || (subscriptionRequest.NotifyTo == null) || (subscriptionRequest.NotifyTo.Address == null)) { throw new ArgumentNullException(); } // Convert the address string to a Uri Uri serviceUri = null; try { serviceUri = subscriptionRequest.EndpointAddress; if (serviceUri.Scheme != "http") { System.Ext.Console.Write(""); System.Ext.Console.Write("Invalid endpoint address. Must be a Uri. Http Uri schemes only."); System.Ext.Console.Write(""); return(null); } } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write(e.Message); System.Ext.Console.Write(""); return(null); } // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); WsMessage subscribeResponse = null; // Build Subscribe Request using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { WsWsaHeader header = new WsWsaHeader( m_version.EventingNamespace + "/Subscribe", // Action null, // RelatesTo serviceUri.AbsoluteUri, // To m_version.AnonymousUri, // ReplyTo null, null); // From, Any WsXmlNamespaces additionalPrefixes = new WsXmlNamespaces(); additionalPrefixes.Add(new WsXmlNamespace("myPrefix", subscriptionRequest.SubscriptionType.NamespaceUri)); WsMessage msg = new WsMessage(header, null, WsPrefix.Wsd | WsPrefix.Wse, additionalPrefixes, null); WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version); String messageID = smw.WriteSoapMessageStart(xmlWriter, msg); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Subscribe", null); // If EndTo is set write it if (subscriptionRequest.EndTo != null) { WriteEndpointRef(xmlWriter, subscriptionRequest.EndTo, "EndTo"); } // Add the delivery element and NotifyTo endpoint xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Delivery", null); xmlWriter.WriteAttributeString("Mode", m_version.EventingNamespace + "/DeliveryModes/Push"); // Writer the notify to endpoint WriteEndpointRef(xmlWriter, subscriptionRequest.NotifyTo, "NotifyTo"); xmlWriter.WriteEndElement(); // End Delivery // Write Expiration time if (subscriptionRequest.Expires != null) { xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Expires", null); xmlWriter.WriteString(subscriptionRequest.Expires.DurationString); xmlWriter.WriteEndElement(); // End Expires } // Write Filter element specifying the event to subscribe to. xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Filter", null); xmlWriter.WriteAttributeString("Dialect", m_version.WsdpNamespaceUri + "/Action"); xmlWriter.WriteString(subscriptionRequest.SubscriptionType.NamespaceUri + "/" + subscriptionRequest.SubscriptionType.TypeName); xmlWriter.WriteEndElement(); // End Filter xmlWriter.WriteEndElement(); // End Subscribe smw.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Subscribe Message Build Took"); // Create an Http client and send Subscribe request WsHttpClient httpClient = new WsHttpClient(m_version); msg.Body = xmlWriter.ToArray(); subscribeResponse = httpClient.SendRequest(msg, subscriptionRequest.EndpointAddress); // If a subscribe response is received process it and return expiration time the subscription manager // actually assigned. // If a parsing fault is received print exception and go on. DpwsEventSubscription response = null; if (subscribeResponse == null) { System.Ext.Console.Write(""); System.Ext.Console.Write("Subscribe response is null."); return(null); } else { byte[] responseBytes = subscribeResponse.Body as byte[]; // It is ok for the service to return a 202 and a 0 length response // if thi is the case just return null if (responseBytes == null || responseBytes.Length == 0) { return(null); } System.Ext.Console.Write(""); System.Ext.Console.Write("Response From: " + subscriptionRequest.EndpointAddress.Host); System.Ext.Console.Write(responseBytes); try { response = ProcessSubscribeResponse(responseBytes, messageID); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Subscription response parsing failed."); System.Ext.Console.Write(e.Message); } } return(response); } }
/// <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); }
public WsMessage GetResponse(WsMessage req) { XmlReader reader = req.Reader; WsWsaHeader header = req.Header; // Build ProbeMatch using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { // Write service type namespaces WsXmlNamespaces additionalPrefixes = new WsXmlNamespaces(); if (Device.Host != null) { additionalPrefixes = new WsXmlNamespaces(); additionalPrefixes.Add(Device.Host.ServiceNamespace); } WsServiceEndpoints hostedServices = Device.HostedServices; int count = hostedServices.Count; for (int i = 0; i < count; i++) { DpwsHostedService hostedService = (DpwsHostedService)hostedServices[i]; // Don't return Mex Service namespace if (hostedService.ServiceTypeName == "Internal") { continue; } additionalPrefixes.Add(hostedService.ServiceNamespace); } WsWsaHeader responseHeader = new WsWsaHeader( WsWellKnownUri.WstNamespaceUri + "/GetResponse", // Action header.MessageID, // RelatesTo header.ReplyTo.Address.AbsoluteUri, // To null, null, null); WsMessage resp = new WsMessage(responseHeader, null, WsPrefix.Wsx | WsPrefix.Wsdp, additionalPrefixes, new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version); smw.WriteSoapMessageStart(xmlWriter, resp); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Wsx, "Metadata", null); // Write ThisModel metadata section xmlWriter.WriteStartElement(WsNamespacePrefix.Wsx, "MetadataSection", null); xmlWriter.WriteAttributeString("Dialect", m_version.WsdpNamespaceUri + "/ThisModel"); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ThisModel", null); if (Device.ThisModel.Manufacturer != null && Device.ThisModel.Manufacturer != "") { xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "Manufacturer", null); xmlWriter.WriteString(Device.ThisModel.Manufacturer); xmlWriter.WriteEndElement(); // End Manufacturer } if (Device.ThisModel.ManufacturerUrl != null && Device.ThisModel.ManufacturerUrl != "") { xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ManufacturerUrl", null); xmlWriter.WriteString(Device.ThisModel.ManufacturerUrl); xmlWriter.WriteEndElement(); // End ManufacturerUrl } if (Device.ThisModel.ModelName != null && Device.ThisModel.ModelName != "") { xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ModelName", null); xmlWriter.WriteString(Device.ThisModel.ModelName); xmlWriter.WriteEndElement(); // End ModelName } if (Device.ThisModel.ModelNumber != null && Device.ThisModel.ModelNumber != "") { xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ModelNumber", null); xmlWriter.WriteString(Device.ThisModel.ModelNumber); xmlWriter.WriteEndElement(); // End ModelNumber } if (Device.ThisModel.ModelUrl != null && Device.ThisModel.ModelUrl != "") { xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ModelUrl", null); xmlWriter.WriteString(Device.ThisModel.ModelUrl); xmlWriter.WriteEndElement(); // End ModelUrl } if (Device.ThisModel.PresentationUrl != null && Device.ThisModel.PresentationUrl != "") { xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "PresentationUrl", null); xmlWriter.WriteString(Device.ThisModel.PresentationUrl); xmlWriter.WriteEndElement(); // End PresentationUrl } if (Device.ThisModel.Any != null) { Device.ThisModel.Any.WriteTo(xmlWriter); } xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ModelName", null); xmlWriter.WriteString(Device.ThisModel.ModelName); xmlWriter.WriteEndElement(); // End ModelName xmlWriter.WriteEndElement(); // End ThisModel xmlWriter.WriteEndElement(); // End MetadataSection // Write ThisDevice metadata section xmlWriter.WriteStartElement(WsNamespacePrefix.Wsx, "MetadataSection", null); xmlWriter.WriteAttributeString("Dialect", m_version.WsdpNamespaceUri + "/ThisDevice"); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ThisDevice", null); if (Device.ThisDevice.FriendlyName != null && Device.ThisDevice.FriendlyName != "") { xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "FriendlyName", null); xmlWriter.WriteString(Device.ThisDevice.FriendlyName); xmlWriter.WriteEndElement(); // End FriendlyName } if (Device.ThisDevice.FirmwareVersion != null && Device.ThisDevice.FirmwareVersion != "") { xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "FirmwareVersion", null); xmlWriter.WriteString(Device.ThisDevice.FirmwareVersion); xmlWriter.WriteEndElement(); // End FirmwareVersion } if (Device.ThisDevice.SerialNumber != null && Device.ThisDevice.SerialNumber != "") { xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "SerialNumber", null); xmlWriter.WriteString(Device.ThisDevice.SerialNumber); xmlWriter.WriteEndElement(); // End SerialNumber } if (Device.ThisDevice.Any != null) { Device.ThisDevice.Any.WriteTo(xmlWriter); } xmlWriter.WriteEndElement(); // End ThisDevice xmlWriter.WriteEndElement(); // End MetadataSection // Write next MetadataSection xmlWriter.WriteStartElement(WsNamespacePrefix.Wsx, "MetadataSection", null); xmlWriter.WriteAttributeString("Dialect", m_version.WsdpNamespaceUri + "/Relationship"); // Write Relationship Elements xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "Relationship", null); xmlWriter.WriteAttributeString("Type", m_version.WsdpNamespaceUri + "/host"); // List used to maintain service endpoints that have been processed. Because the DPWS spec allows // for multiple service types at a single endpoint address, we must make sure we only create // a relationship once for all of the types at a service endpoint. ArrayList processedEndpointList = new ArrayList(); // If a Host type exist add it if (Device.Host != null) { xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "Host", null); WsWsaEndpointRef endpointReference; endpointReference = (WsWsaEndpointRef)Device.Host.EndpointRefs[0]; xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "EndpointReference", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null); xmlWriter.WriteString(endpointReference.Address.AbsoluteUri); xmlWriter.WriteEndElement(); // End Address xmlWriter.WriteEndElement(); // End EndpointReference // Build list of all service types that share this endpoint address /* * string serviceTypes = null; * if ((serviceTypes = BuildServiceTypesList(Device.Host, processedEndpointList)) == null) * serviceTypes = Device.Host.ServiceNamespace.Prefix + ":" + Device.Host.ServiceTypeName; * else * serviceTypes = serviceTypes + " " + Device.Host.ServiceNamespace.Prefix + ":" + Device.Host.ServiceTypeName; */ // Write service types xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "Types", null); xmlWriter.WriteString(Device.Host.ServiceNamespace.Prefix + ":" + Device.Host.ServiceTypeName); xmlWriter.WriteEndElement(); // End Types // Write Service ID xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ServiceId", null); xmlWriter.WriteString(Device.Host.ServiceID); xmlWriter.WriteEndElement(); // End ServiceID xmlWriter.WriteEndElement(); // End Hosted // Update processed endpoint list processedEndpointList.Add(Device.Host.EndpointAddress); } // Add hosted services types int serviceCount = hostedServices.Count; DpwsHostedService currentService; for (int i = 0; i < serviceCount; i++) { currentService = (DpwsHostedService)hostedServices[i]; // Don't return Mex Service type if (currentService.ServiceTypeName == "Internal") { continue; } // Build list of all service types that share this endpoint address string serviceTypes = null; if ((serviceTypes = BuildServiceTypesList(currentService, processedEndpointList)) == null) { continue; } // Write hosted start element xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "Hosted", null); // Write n number of endpoint references int epRefCount = currentService.EndpointRefs.Count; for (int j = 0; j < epRefCount; j++) { xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "EndpointReference", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null); xmlWriter.WriteString(currentService.EndpointRefs[j].Address.AbsoluteUri); xmlWriter.WriteEndElement(); // End Address xmlWriter.WriteEndElement(); // End EndpointReference } // Write service types xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "Types", null); xmlWriter.WriteString(currentService.ServiceNamespace.Prefix + ":" + currentService.ServiceTypeName); xmlWriter.WriteEndElement(); // End Types // Write Service ID xmlWriter.WriteStartElement(WsNamespacePrefix.Wsdp, "ServiceId", null); xmlWriter.WriteString(currentService.ServiceID); xmlWriter.WriteEndElement(); // End ServiceID xmlWriter.WriteEndElement(); // End Hosted // Update processed endpoint list processedEndpointList.Add(currentService.EndpointAddress); } xmlWriter.WriteEndElement(); // End Relastionship xmlWriter.WriteEndElement(); // End MetadataSection xmlWriter.WriteEndElement(); // End Metadata smw.WriteSoapMessageEnd(xmlWriter); resp.Body = xmlWriter.ToArray(); return(resp); } }
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); } }