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