/// <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); }
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)); WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version); smw.WriteSoapMessageStart(xmlWriter, msg); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Expires", null); xmlWriter.WriteString(new WsDuration(newDuration).DurationString); xmlWriter.WriteEndElement(); // End Expires 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> /// 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; }
/// <summary> /// Builds a probe request message based on the filters parameter. /// </summary> /// <param name="serviceAddress"> /// A string containing the target service address. /// For example: urn:uuid:3cb0d1ba-cc3a-46ce-b416-212ac2419b20 /// </param> /// <param name="filters"> /// A DpwsServiceTypes object containing a collection of types a service must support to signal a match. /// Null = any type. /// </param> /// <param name="messageID"> /// A string used to return the messageID assigned to this message. /// </param> /// <returns>A byte array containing the probe message or null if an error occures.</returns> private WsMessage BuildProbeRequest(string serviceAddress, DpwsServiceTypes filters, out String messageID) { // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); WsMessage msg = null; // Build Probe request using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { WsWsaHeader header = new WsWsaHeader( m_version.DiscoveryNamespace + "/Probe", // Action null, // RelatesTo serviceAddress, // To m_version.AnonymousUri, null, null); // ReplyTo, From, Any header.MustUnderstand = true; // If filters are supplied, write filter namespaces if prefixed. Build filter list for use later WsXmlNamespaces namespaces = new WsXmlNamespaces(); // Prefix hack for now: int i = 0; string prefix; string filterList = ""; bool spaceFlag = false; if (filters != null) { int count = filters.Count; for (int j = 0; j < count; j++) { DpwsServiceType serviceType = filters[j]; prefix = namespaces.LookupPrefix(serviceType.NamespaceUri); if (prefix == null) { prefix = "dp" + (i++); namespaces.Add(new WsXmlNamespace(prefix, serviceType.NamespaceUri)); } filterList = filterList + ((spaceFlag == true) ? " " : "") + prefix + ":" + serviceType.TypeName; spaceFlag = true; } } msg = new WsMessage(header, null, WsPrefix.Wsd, namespaces, null); WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version); messageID = smw.WriteSoapMessageStart(xmlWriter, msg); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "Probe", null); // If filter is supplied add filter types tag else write blank string to probe body, force an empty tag if (filterList.Length != 0) { xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "Types", null); xmlWriter.WriteString(filterList); xmlWriter.WriteEndElement(); // End Filter } else xmlWriter.WriteString(""); xmlWriter.WriteEndElement(); // End Probe // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); smw.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Probe Message Build Took"); // return the probe message msg.Body = xmlWriter.ToArray(); } return msg; }
/// <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; } }
// 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; } }
/// <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 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 subscribe to a devices, hosted service event sources. /// </summary> /// <param name="subscriptionRequest"> /// A DpwsSubscriptionRequest object containing the address of the service hosting the desired event, /// the address where the event is sent, an optional address where subscription end messages are sent, /// A subscription expiration (in duration format) and an optional user defined identifier. /// </param> /// <returns> /// A DpwsEventSubscription containing the the subscription managers address, the time when the subscription /// expires (duration) and optional reference parameters and properties. Per spec the /// sub mananger may assign a different duration value than that specified in the request. /// </returns> /// <exception cref="ArgumentNullException">If required subscription parameters are not set.</exception> public DpwsEventSubscription Subscribe(DpwsSubscribeRequest subscriptionRequest) { if ((subscriptionRequest.SubscriptionType == null) || (subscriptionRequest.SubscriptionType.TypeName == null) || (subscriptionRequest.SubscriptionType.NamespaceUri == null) || (subscriptionRequest.EndpointAddress == null) || (subscriptionRequest.NotifyTo == null) || (subscriptionRequest.NotifyTo.Address == null)) { throw new ArgumentNullException(); } // Convert the address string to a Uri Uri serviceUri = null; try { serviceUri = subscriptionRequest.EndpointAddress; if (serviceUri.Scheme != "http") { System.Ext.Console.Write(""); System.Ext.Console.Write("Invalid endpoint address. Must be a Uri. Http Uri schemes only."); System.Ext.Console.Write(""); return null; } } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write(e.Message); System.Ext.Console.Write(""); return null; } // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); WsMessage subscribeResponse = null; // Build Subscribe Request using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { WsWsaHeader header = new WsWsaHeader( m_version.EventingNamespace + "/Subscribe", // Action null, // RelatesTo serviceUri.AbsoluteUri, // To m_version.AnonymousUri, // ReplyTo null, null); // From, Any WsXmlNamespaces additionalPrefixes = new WsXmlNamespaces(); additionalPrefixes.Add(new WsXmlNamespace("myPrefix", subscriptionRequest.SubscriptionType.NamespaceUri)); WsMessage msg = new WsMessage(header, null, WsPrefix.Wsd | WsPrefix.Wse, additionalPrefixes, null); WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version); String messageID = smw.WriteSoapMessageStart(xmlWriter, msg); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Subscribe", null); // If EndTo is set write it if (subscriptionRequest.EndTo != null) WriteEndpointRef(xmlWriter, subscriptionRequest.EndTo, "EndTo"); // Add the delivery element and NotifyTo endpoint xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Delivery", null); xmlWriter.WriteAttributeString("Mode", m_version.EventingNamespace + "/DeliveryModes/Push"); // Writer the notify to endpoint WriteEndpointRef(xmlWriter, subscriptionRequest.NotifyTo, "NotifyTo"); xmlWriter.WriteEndElement(); // End Delivery // Write Expiration time if (subscriptionRequest.Expires != null) { xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Expires", null); xmlWriter.WriteString(subscriptionRequest.Expires.DurationString); xmlWriter.WriteEndElement(); // End Expires } // Write Filter element specifying the event to subscribe to. xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Filter", null); xmlWriter.WriteAttributeString("Dialect", m_version.WsdpNamespaceUri + "/Action"); xmlWriter.WriteString(subscriptionRequest.SubscriptionType.NamespaceUri + "/" + subscriptionRequest.SubscriptionType.TypeName); xmlWriter.WriteEndElement(); // End Filter xmlWriter.WriteEndElement(); // End Subscribe smw.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Subscribe Message Build Took"); // Create an Http client and send Subscribe request WsHttpClient httpClient = new WsHttpClient(m_version); msg.Body = xmlWriter.ToArray(); subscribeResponse = httpClient.SendRequest(msg, subscriptionRequest.EndpointAddress); // If a subscribe response is received process it and return expiration time the subscription manager // actually assigned. // If a parsing fault is received print exception and go on. DpwsEventSubscription response = null; if (subscribeResponse == null) { System.Ext.Console.Write(""); System.Ext.Console.Write("Subscribe response is null."); return null; } else { byte[] responseBytes = subscribeResponse.Body as byte[]; // It is ok for the service to return a 202 and a 0 length response // if thi is the case just return null if(responseBytes == null || responseBytes.Length == 0) return null; System.Ext.Console.Write(""); System.Ext.Console.Write("Response From: " + subscriptionRequest.EndpointAddress.Host); System.Ext.Console.Write(responseBytes); try { response = ProcessSubscribeResponse(responseBytes, messageID); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Subscription response parsing failed."); System.Ext.Console.Write(e.Message); } } return response; } }
public virtual WsMessage ProbeMatch(WsMessage probe, DpwsHostedService matchedService) { XmlReader reader = probe.Reader; WsWsaHeader header = probe.Header; // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); // Build ProbeMatch using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { // If a Host exist write the Host namespace WsXmlNamespaces additionalPrefixes = null; if (Device.Host != null) { additionalPrefixes = new WsXmlNamespaces(); additionalPrefixes.Add(Device.Host.ServiceNamespace); } WsWsaHeader matchHeader = new WsWsaHeader( this.Version.DiscoveryNamespace + "/ProbeMatches", // Action header.MessageID, // RelatesTo this.Version.AnonymousUri, // To null, null, null); // ReplyTo, From, Any WsMessage msg = new WsMessage(matchHeader, null, WsPrefix.Wsd | WsPrefix.Wsdp, additionalPrefixes, new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); WsSoapMessageWriter smw = new WsSoapMessageWriter(this.Version); smw.WriteSoapMessageStart(xmlWriter, msg); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "ProbeMatches", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "ProbeMatch", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "EndpointReference", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null); xmlWriter.WriteString(matchedService == null ? Device.EndpointAddress : matchedService.EndpointAddress); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); // Write hosted service types xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "Types", null); WriteDeviceServiceTypes(xmlWriter); xmlWriter.WriteEndElement(); // End Types xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "XAddrs", null); string transport = Device.TransportAddress; if(matchedService != null) { int idx = transport.LastIndexOf('/'); if(idx != -1) { transport = transport.Substring(0, idx + 1); transport += matchedService.EndpointAddress.Substring(matchedService.EndpointAddress.IndexOf("urn:uuid:") + 9); } } int idx2 = transport.ToLower().IndexOf("localhost"); if(idx2 != -1) { transport = transport.Substring(0, idx2) + WsNetworkServices.GetLocalIPV4Address() + transport.Substring(idx2 + 9 /*localhost*/); } xmlWriter.WriteString(transport); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "MetadataVersion", null); xmlWriter.WriteString(Device.MetadataVersion.ToString()); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); smw.WriteSoapMessageEnd(xmlWriter); msg.Body = xmlWriter.ToArray(); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***ProbeMatch Took"); // Delay probe match as per Ws-Discovery specification (2.4 Protocol Assignments) Thread.Sleep(new Random().Next(Device.ProbeMatchDelay)); // Return stream buffer return msg; } }
public virtual WsMessage ResolveMatch(WsMessage message) { XmlReader reader = message.Reader; WsWsaHeader header = message.Header; bool match = false; string epAddr = ""; reader.ReadStartElement("Resolve", this.Version.DiscoveryNamespace); if(reader.IsStartElement("EndpointReference", this.Version.AddressingNamespace) == false) { return null; } WsWsaEndpointRef epRef = new WsWsaEndpointRef(reader, this.Version.AddressingNamespace); epAddr = epRef.Address.AbsoluteUri; if(Device.EndpointAddress != epAddr) { // If the destination endpoint is ours send a resolve match else return null int servicesCount = Device.HostedServices.Count; DpwsHostedService hostedService; for (int i = 0; i < servicesCount; i++) { hostedService = (DpwsHostedService)Device.HostedServices[i]; // Skip internal services if (hostedService.ServiceTypeName == "Internal") continue; if (hostedService.EndpointAddress == epAddr) { match = true; break; } } if (!match) return null; } // Build ResolveMatch using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { // If a Host exist write the Host namespace WsXmlNamespaces additionalPrefixes = null; if (Device.Host != null) { additionalPrefixes = new WsXmlNamespaces(); additionalPrefixes.Add(Device.Host.ServiceNamespace); } WsWsaHeader matchHeader = new WsWsaHeader( this.Version.DiscoveryNamespace + "/ResolveMatches", // Action header.MessageID, // RelatesTo this.Version.AnonymousUri, // To null, null, null); // ReplyTo, From, Any WsMessage msg = new WsMessage(matchHeader, null, WsPrefix.Wsd | WsPrefix.Wsdp, additionalPrefixes, new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); WsSoapMessageWriter smw = new WsSoapMessageWriter(this.Version); smw.WriteSoapMessageStart(xmlWriter, msg); // write body xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "ResolveMatches", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "ResolveMatch", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "EndpointReference", null); xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null); xmlWriter.WriteString(epRef.Address.AbsoluteUri); xmlWriter.WriteEndElement(); // End Address xmlWriter.WriteEndElement(); // End EndpointReference // Write hosted service types xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "Types", null); WriteDeviceServiceTypes(xmlWriter); xmlWriter.WriteEndElement(); // End Types string transport = Device.TransportAddress; if(match) { int idx = transport.LastIndexOf('/'); if(idx != -1) { transport = transport.Substring(0, idx + 1); transport += epAddr.Substring(epAddr.IndexOf("urn:uuid:") + 9); } } int idx2 = transport.ToLower().IndexOf("localhost"); if(idx2 != -1) { transport = transport.Substring(0, idx2) + WsNetworkServices.GetLocalIPV4Address() + transport.Substring(idx2 + 9 /*localhost*/); } xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "XAddrs", null); xmlWriter.WriteString(transport); xmlWriter.WriteEndElement(); // End XAddrs xmlWriter.WriteStartElement(WsNamespacePrefix.Wsd, "MetadataVersion", null); xmlWriter.WriteString(Device.MetadataVersion.ToString()); xmlWriter.WriteEndElement(); // End MetadataVersion xmlWriter.WriteEndElement(); // End ResolveMatch xmlWriter.WriteEndElement(); // End ResolveMatches smw.WriteSoapMessageEnd(xmlWriter); msg.Body = xmlWriter.ToArray(); // Return stream buffer return msg; } }
/// <summary> /// Use to request metadata from a devices hosted service endpoint. /// </summary> /// <param name="serviceAddress"> /// A string containing the transport address of a service endpoint. For Dpws the address represents /// a devices transport address. /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20 /// </param> /// <returns> /// A collection of DpwsMetadata objects containing endpoint details about services hosted by a device. /// </returns> public DpwsMetadata Get(string serviceAddress) { // Convert the address string to a Uri Uri serviceUri = null; try { serviceUri = new Uri(serviceAddress); if (serviceUri.Scheme != "http") { System.Ext.Console.Write(""); System.Ext.Console.Write("Invalid serviceAddress. Must be a Uri. Http Uri schemes only."); System.Ext.Console.Write(""); return null; } } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write(e.Message); System.Ext.Console.Write(""); return null; } // Performance debugging DebugTiming timeDebuger = new DebugTiming(); long startTime = timeDebuger.ResetStartTime(""); // Build Get Request using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create()) { WsWsaHeader header = new WsWsaHeader( WsWellKnownUri.WstNamespaceUri + "/Get", // Action null, // RelatesTo "urn:uuid:" + serviceUri.AbsolutePath.Substring(1), // To //TODO: should be ROLE??? m_version.AnonymousRoleUri, // ReplyTo null, null); // From, Any WsMessage msg = new WsMessage(header, null, WsPrefix.None, null, null); WsSoapMessageWriter smw = new WsSoapMessageWriter(m_version); String messageID = smw.WriteSoapMessageStart(xmlWriter, msg); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Header Took"); // Performance debuging timeDebuger.PrintElapsedTime("*****Write Body Took"); smw.WriteSoapMessageEnd(xmlWriter); // Performance debuging timeDebuger.PrintTotalTime(startTime, "***Get Message Build Took"); // Create an Http client and send Get request WsHttpClient httpClient = new WsHttpClient(m_version); System.Ext.Console.Write(""); System.Ext.Console.Write("Sending Get to: " + serviceAddress); msg.Body = xmlWriter.ToArray(); WsMessage getResponse = httpClient.SendRequest(msg, new Uri(serviceAddress)); // If a get response is received process it and return DpwsMetadata object DpwsMetadata metadata = null; if (getResponse == null || getResponse.Body == null) { return null; } else { DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(m_version); try { System.Ext.Console.Write(getResponse.Body as byte[]); System.Ext.Console.Write(""); metadata = soapProcessor.ProcessGetResponse((byte[])getResponse.Body, messageID); } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write("Get response parser threw an exception. " + e.Message); return null; } } return metadata; } }
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; } }