/// <summary> /// Parses a Udp transport message and builds a header object and envelope document then calls processRequest /// on a service endpoint contained. /// </summary> /// <param name="soapRequest">A byte array containing a raw soap request message. If null no check is performed.</param> /// <param name="messageCheck">A WsMessageCheck objct used to test for duplicate request.</param> /// <param name="remoteEP">The remote endpoint address of the requestor.</param> /// <returns>A byte array containing a soap response message returned from a service endpoint.</returns> public WsMessage ProcessRequestMessage(WsMessage message) { // Parse and validate the soap message WsWsaHeader header = message.Header; // Check Udp service endpoints collection for a target service. int count = m_serviceEndpoints.Count; // DO NOT USE the subscript operator for endpoint addresses (WsServiceEndpoints[EnpointAddress]) // for local host testing there are multiple endpoints with the same address but different operations for (int i = 0; i < count; i++) { IWsServiceEndpoint serviceEndpoint = m_serviceEndpoints[i]; if (serviceEndpoint.EndpointAddress == header.To) { if (serviceEndpoint.ServiceOperations[header.Action] != null) { // Don't block discovery processes. serviceEndpoint.BlockingCall = false; try { return(serviceEndpoint.ProcessRequest(message)); } catch (WsFaultException e) { return(WsFault.GenerateFaultResponse(e, m_request.Version)); } catch { // If a valid Action is not found, fault return(WsFault.GenerateFaultResponse(header, WsFaultType.WsaDestinationUnreachable, "To: " + header.To + " Action: " + header.Action, m_request.Version)); } } } } // Return null if service endpoint was not found System.Ext.Console.Write("Udp service endpoint was not found."); System.Ext.Console.Write(" Endpoint Address: " + header.To); System.Ext.Console.Write(" Action: " + header.Action); return(null); }
/// <summary> /// Parses a GetResponse message. /// </summary> /// <param name="soapResponse">A byte array containing a response message.</param> /// <param name="messageID">The message ID sent in the original request.</param> /// <returns> /// A DpwsMetadata object containing a details about a service endpoint. /// </returns> internal DpwsMetadata ProcessGetResponse(byte[] soapResponse, string messageID) { // Parse and build header WsWsaHeader header = new WsWsaHeader(); XmlReader reader; try { reader = WsSoapMessageParser.ParseSoapMessage(soapResponse, ref header, m_version); } catch { return(null); } try { // Make sure this is a get response if (header.Action != WsWellKnownUri.WstNamespaceUri + "/GetResponse") { return(null); } // Make sure the messageID matches the request ID if (header.RelatesTo != messageID) { return(null); } #if DEBUG int depth = reader.Depth; #endif DpwsMetadata metaData = new DpwsMetadata(reader, m_version); #if DEBUG Microsoft.SPOT.Debug.Assert(XmlReaderHelper.HasReadCompleteNode(depth, reader)); #endif return(metaData); } finally { reader.Close(); } }
// TwoWayAttachmentRequest: receive an MTOM binary attachment and send a binary attachement in response public WsMessage TwoWayAttachmentRequest(WsMessage request) { WsWsaHeader header = request.Header; XmlReader reader = request.Reader; // Make sure we have MTOM body parts if (request.BodyParts == null) { throw new WsFaultException(header, WsFaultType.XmlException, "MTOM message has no body parts."); } // Find paramaters reader.ReadStartElement("TwoWayAttachmentRequest", AttNamespace); reader.ReadStartElement("Param", AttNamespace); // Look for Include parameter if (reader.IsStartElement("Include", WsWellKnownUri.XopNamespaceUri) == false) { throw new WsFaultException(header, WsFaultType.XmlException, "Body/TwoWayAttachmentRequest/Param/Include is missing."); } // Look for attachment body part reader.MoveToFirstAttribute(); string cid = "<" + reader.Value.Substring(4) + ">"; ////Log.Comment(""); ////Log.Comment("TwoWayAttachment received. href = " + reader.Value); WsMtomBodyPart bodyPart; if ((bodyPart = request.BodyParts[cid]) == null) { throw new WsFaultException(header, WsFaultType.XmlException, "Required body part \"" + reader.Value + "\" in missing."); } // Print information about the attachment ////Log.Comment("Attachment size = " + bodyPart.Content.Length); ////Log.Comment("Content-ID = " + bodyPart.ContentID); ////Log.Comment("Content-Type = " + bodyPart.ContentType); ////Log.Comment("Content-Transfer-Encoding = " + bodyPart.ContentTransferEncoding); ////Log.Comment(""); // Return response return(TwoWayAttachmentResp(header)); }
/// <summary> /// Create an instance of a SubscriptionEndEvent arguments object. /// </summary> internal SubscriptionEndEventArgs(WsWsaHeader header, XmlReader reader) { // Retrieve the Identifier this.Identifier = header.Any.GetNodeValue("Identifier", WsWellKnownUri.WseNamespaceUri); reader.ReadStartElement("SubscriptionEnd", WsWellKnownUri.WseNamespaceUri); if (reader.IsStartElement("SubscriptionManager", WsWellKnownUri.WseNamespaceUri)) { this.SubscriptionManager = new WsWsaEndpointRef(reader); } this.SubscriptionID = this.SubscriptionManager.RefParameters.GetNodeValue("Identifier", WsWellKnownUri.WseNamespaceUri); if (this.SubscriptionID == null || this.Identifier == null) // both need to be there { throw new XmlException(); } }
public virtual SetDataResponse SetData(SetData req) { // Create request header String action; action = "http://tempuri.org/IDataAccessService/SetData"; WsWsaHeader header; header = new WsWsaHeader(action, null, EndpointAddress, m_version.AnonymousUri, null, null); WsMessage request = new WsMessage(header, req, WsPrefix.None); // Create request serializer SetDataDataContractSerializer reqDcs; reqDcs = new SetDataDataContractSerializer("SetData", "http://tempuri.org/"); request.Serializer = reqDcs; request.Method = "SetData"; // Indicate that this message will use Mtom encoding request.BodyParts = new WsMtomBodyParts(); // Send service request m_requestChannel.Open(); WsMessage response = m_requestChannel.Request(request); m_requestChannel.Close(); // Process response SetDataResponseDataContractSerializer respDcs; respDcs = new SetDataResponseDataContractSerializer("SetDataResponse", "http://tempuri.org/"); respDcs.BodyParts = response.BodyParts; SetDataResponse resp; resp = ((SetDataResponse)(respDcs.ReadObject(response.Reader))); response.Reader.Dispose(); response.Reader = null; return(resp); }
/// <summary> /// This method build a subscription end message. /// </summary> /// <param name="eventSink">An event sink containing client endpoint information.</param> /// <param name="shutdownMessage">A string containing reason why the subscription is ending.</param> /// <param name="subMangerID">An id sent by the client that they use to reference a subscription.</param> /// <returns></returns> private byte[] SubscriptionEndResponse(DpwsWseEventSink eventSink, string shutdownMessage, string subMangerID) { MemoryStream soapStream = new MemoryStream(); XmlWriter xmlWriter = XmlWriter.Create(soapStream); WsWsaHeader responseHeader = new WsWsaHeader( WsWellKnownUri.WseNamespaceUri + "/SubscriptionEnd", // Action null, // RelatesTo eventSink.EndTo.Address.AbsoluteUri, // To null, null, eventSink.EndTo.RefProperties); // ReplyTo, From, Any WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter, WsSoapMessageWriter.Prefixes.Wse, // Prefix null, // Additional Prefix responseHeader, // Header null); // AppSequence // write body xmlWriter.WriteStartElement("wse", "SubscriptionEnd", null); xmlWriter.WriteStartElement("wse", "SubscriptionManager", null); xmlWriter.WriteStartElement("wsa", "Address", null); xmlWriter.WriteString("http://" + Device.IPV4Address + ":" + Device.Port + "/" + subMangerID); xmlWriter.WriteEndElement(); // End Address xmlWriter.WriteStartElement("wsa", "ReferenceParameters", null); xmlWriter.WriteStartElement("wse", "Identifier", null); xmlWriter.WriteString(eventSink.ID); xmlWriter.WriteEndElement(); // End Identifier xmlWriter.WriteEndElement(); // End ReferenceParameters xmlWriter.WriteEndElement(); // End SubscriptionManager xmlWriter.WriteStartElement("wse", "Code", null); xmlWriter.WriteString("wse:" + shutdownMessage); xmlWriter.WriteEndElement(); // End Code xmlWriter.WriteEndElement(); // End SubscriptionEnd WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter); // Flush and close writer. Return stream buffer xmlWriter.Flush(); xmlWriter.Close(); return(soapStream.ToArray()); }
public virtual TwoWayAttachmentResponse TwoWayAttachment(TwoWayAttachmentRequest req) { // Create request header String action; action = "http://schemas.example.org/AttachmentService/TwoWayAttachment"; WsWsaHeader header; header = new WsWsaHeader(action, null, EndpointAddress, m_version.AnonymousUri, null, null); WsMessage request = new WsMessage(header, req, WsPrefix.None); // Create request serializer TwoWayAttachmentRequestDataContractSerializer reqDcs; reqDcs = new TwoWayAttachmentRequestDataContractSerializer("TwoWayAttachmentRequest", "http://schemas.example.org/AttachmentService"); request.Serializer = reqDcs; request.Method = "TwoWayAttachment"; // Indicate that this message will use Mtom encoding request.BodyParts = new WsMtomBodyParts(); // Send service request m_requestChannel.Open(); WsMessage response = m_requestChannel.Request(request); m_requestChannel.Close(); // Process response TwoWayAttachmentResponseDataContractSerializer respDcs; respDcs = new TwoWayAttachmentResponseDataContractSerializer("TwoWayAttachmentResponse", "http://schemas.example.org/AttachmentService"); respDcs.BodyParts = response.BodyParts; TwoWayAttachmentResponse resp; resp = ((TwoWayAttachmentResponse)(respDcs.ReadObject(response.Reader))); response.Reader.Dispose(); response.Reader = null; return(resp); }
/// <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> /// Bye stub calls the client Bye handler /// </summary> /// <param name="header">A WsWsaHeader object containing the details soap header information.</param> /// <param name="envelope">A WsXmlDocument object containing the the entire soap message.</param> /// <returns>A byte array containig a soap response mesage.</returns> public WsMessage Bye(WsWsaHeader header, XmlReader reader) { try { if (reader.IsStartElement("Bye", m_version.DiscoveryNamespace)) { m_client.RaiseByeEvent(new DpwsServiceDescription(reader, DpwsServiceDescription.ServiceDescriptionType.Bye, m_version)); } else { throw new XmlException(); } } catch (Exception e) { System.Ext.Console.Write("Bye request processing failed."); System.Ext.Console.Write(e.Message); System.Ext.Console.Write(e.StackTrace); } return(null); }
/// <summary> /// Hello stub calls the client hello handler /// </summary> /// <param name="header">A WsWsaHeader object containing the details soap header information.</param> /// <param name="envelope">A WsXmlDocument object containing the the entire soap message.</param> /// <returns>A byte array containig a soap response mesage.</returns> public byte[] Hello(WsWsaHeader header, XmlReader reader) { try { if (reader.IsStartElement("Hello", WsWellKnownUri.WsdNamespaceUri)) { m_client.RaiseHelloEvent(new DpwsServiceDescription(reader, DpwsServiceDescription.ServiceDescriptionType.Hello)); } else { throw new XmlException(); } } catch (Exception e) { System.Ext.Console.Write("Hello request processing failed."); System.Ext.Console.Write(e.Message); System.Ext.Console.Write(e.StackTrace); } return(null); }
public byte[] OneWay(WsWsaHeader header, XmlReader reader) { try { // Find beginning of request reader.ReadStartElement("OneWay", SimpleServiceNamespaceUri); // Find the integer value int number = Convert.ToInt32(reader.ReadElementString("Param", SimpleServiceNamespaceUri)); Log.Comment(""); Log.Comment("Integer = " + number.ToString()); Log.Comment(""); return(new byte[0]); // Empty response } catch (Exception e) { // Something went wrong throw new WsFaultException(header, WsFaultType.XmlException, e.ToString()); } }
// Implements the IWsServiceEndpoint.ProcessRequest method. // Gets a service callback method based on the action property sent in a soap header and calls // invoke on the callback method. private byte[] ProcessRequest(WsWsaHeader header, XmlReader reader) { WsServiceOperation callback; // Look for a client event sink callback action if ((callback = m_eventCallbacks[header.Action]) != null) { m_messageType = WsMessageType.Soap; System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(callback.MethodName); if (methodInfo == null) { System.Ext.Console.Write(""); System.Ext.Console.Write("Client event callback method for action " + header.Action + " was not found"); System.Ext.Console.Write(""); } return((byte[])methodInfo.Invoke(this, new object[] { header, reader })); } // If a valid Action is not found, fault throw new WsFaultException(header, WsFaultType.WsaDestinationUnreachable, "To: " + header.To + " Action: " + header.Action); }
/// <summary> /// HttpServer Socket Listener /// </summary> public void Listen() { // Create listener and start listening while (m_isStarted) { try { _Bind.RequestContext context = m_replyChannel.ReceiveRequest(); // The context returned by m_httpListener.GetContext(); can be null in case the service was stopped. if (context != null) { WsHttpMessageProcessor processor = new WsHttpMessageProcessor(m_serviceEndpoints, context); if (m_threadManager.ThreadsAvailable == false) { WsWsaHeader header = new WsWsaHeader(); context.Reply(WsFault.GenerateFaultResponse(header, WsFaultType.WsaEndpointUnavailable, "Service Unavailable (busy)", context.Version)); System.Ext.Console.Write("Http max thread count exceeded. Request ignored."); } else { // Try to get a processing thread and process the request m_threadManager.StartNewThread(processor); } } } catch { if (!m_isStarted) { break; } } } }
/// <summary> /// A wrapper method that implements the ProcessRequest interface used to control blocking of request. /// The BlockingCall property is used by the stack to control single instance execution. Hello and Bye /// are not blocked. Event messages from a device are blocked. This means it is up to a client developer /// to insure long thread safety. /// </summary> /// <param name="header">A WsWsaHeader containing the header proerties of a request.</param> /// <param name="envelope">A WsXmlDocument containing the entire envelope of the message in a node tree.</param> /// <returns>A byte array containing a soap response to the request.</returns> byte[] IWsServiceEndpoint.ProcessRequest(WsWsaHeader header, XmlReader reader) { //We always block lock (m_threadLock) { Microsoft.SPOT.Debug.Assert(header.Action.IndexOf(WsWellKnownUri.WsdNamespaceUri) == 0); String action = header.Action.Substring(WsWellKnownUri.WsdNamespaceUri.Length + 1); switch (action) { case "Hello": return(Hello(header, reader)); case "Bye": return(Bye(header, reader)); } System.Ext.Console.Write("Client discovery callback method for action " + header.Action + " was not found"); return(null); } }
/// <summary> /// Create an instance of a SubscriptionEndEvent arguments object. /// </summary> internal SubscriptionEndEventArgs(WsMessage msg, ProtocolVersion version) { // Retrieve the Identifier WsWsaHeader header = msg.Header; XmlReader reader = msg.Reader; this.Identifier = header.Any.GetNodeValue("Identifier", version.EventingNamespace); reader.ReadStartElement("SubscriptionEnd", version.EventingNamespace); if (reader.IsStartElement("SubscriptionManager", version.EventingNamespace)) { this.SubscriptionManager = new WsWsaEndpointRef(reader, version.AddressingNamespace); } this.SubscriptionID = this.SubscriptionManager.RefParameters.GetNodeValue("Identifier", version.EventingNamespace); if (this.SubscriptionID == null || this.Identifier == null) // both need to be there { throw new XmlException(); } }
public virtual void IntegerEvent(IntegerEventRequest eventReq) { // Create temp event source object, set the event action and create the event header DpwsWseEventSource eventSource; eventSource = EventSources["IntegerEvent"]; String action; action = "http://schemas.example.org/EventingService/IntegerEvent"; WsWsaHeader header; header = new WsWsaHeader(action, null, null, null, null, null); WsMessage msg = new WsMessage(header, eventReq, WsPrefix.Wse); // Create event serializer and write the event object IntegerEventRequestDataContractSerializer eventDcs; eventDcs = new IntegerEventRequestDataContractSerializer("IntegerEventRequest", "http://schemas.example.org/EventingService"); msg.Serializer = eventDcs; // Fire event Dpws.Device.Device.SubscriptionManager.FireEvent(this, eventSource, msg); }
private XmlReader ProcessResponse(byte[] response, String messageID, String action) { WsWsaHeader header = new WsWsaHeader(); XmlReader reader = WsSoapMessageParser.ParseSoapMessage(response, ref header, m_version); if (header.Action == m_version.AddressingNamespace + "/fault") { WsFault.ParseFaultResponseAndThrow(reader); } else if (header.Action != m_version.EventingNamespace + "/" + action) { throw new XmlException(); } // Make sure this response matches the request if (header.RelatesTo != messageID) { throw new XmlException(); } return(reader); }
/// <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); }
public virtual HelloWCFResponse HelloWCF(HelloWCF req) { // Create request header String action; action = "http://localhost/ServiceHelloWCF/IServiceHelloWCF/HelloWCF"; WsWsaHeader header; header = new WsWsaHeader(action, null, EndpointAddress, m_version.AnonymousUri, null, null); WsMessage request = new WsMessage(header, req, WsPrefix.None); // Create request serializer HelloWCFDataContractSerializer reqDcs; reqDcs = new HelloWCFDataContractSerializer("HelloWCF", "http://localhost/ServiceHelloWCF"); request.Serializer = reqDcs; request.Method = "HelloWCF"; // Send service request m_requestChannel.Open(); WsMessage response = m_requestChannel.Request(request); m_requestChannel.Close(); // Process response HelloWCFResponseDataContractSerializer respDcs; respDcs = new HelloWCFResponseDataContractSerializer("HelloWCFResponse", "http://localhost/ServiceHelloWCF"); HelloWCFResponse resp; resp = ((HelloWCFResponse)(respDcs.ReadObject(response.Reader))); response.Reader.Dispose(); response.Reader = null; return(resp); }
public virtual keepAliveResponse keepAlive(keepAlive req) { // Create request header String action; action = "http://tempuri.org/IService1/keepAlive"; WsWsaHeader header; header = new WsWsaHeader(action, null, EndpointAddress, m_version.AnonymousUri, null, null); WsMessage request = new WsMessage(header, req, WsPrefix.None); // Create request serializer keepAliveDataContractSerializer reqDcs; reqDcs = new keepAliveDataContractSerializer("keepAlive", "http://tempuri.org/"); request.Serializer = reqDcs; request.Method = "keepAlive"; // Send service request m_requestChannel.Open(); WsMessage response = m_requestChannel.Request(request); m_requestChannel.Close(); // Process response keepAliveResponseDataContractSerializer respDcs; respDcs = new keepAliveResponseDataContractSerializer("keepAliveResponse", "http://tempuri.org/"); keepAliveResponse resp; resp = ((keepAliveResponse)(respDcs.ReadObject(response.Reader))); response.Reader.Dispose(); response.Reader = null; return(resp); }
public byte[] MyTwoWayOperation(WsWsaHeader header, XmlReader reader) { try { reader.ReadStartElement("MyTwoWayRequest", this.ServiceNamespace.NamespaceURI); // Extract parameter A from SOAP message body string strA = reader.ReadElementString("A", this.ServiceNamespace.NamespaceURI); int a = Convert.ToInt32(strA); // Extract parameter B from SOAP message body string strB = reader.ReadElementString("B", this.ServiceNamespace.NamespaceURI); int b = Convert.ToInt32(strB); if (b == 0) { throw new WsFaultException(header, WsFaultType.ArgumentException, "Division by zero. Argument B must not be zero."); } Debug.Print("MyTwoWayOperation with A=" + a + " / B=" + b + " executed."); int quotient = a / b; Debug.Print("Operation returns " + quotient + "."); return(BuildMyTwoWayResponse(header, quotient)); } catch (XmlException ex) { throw new WsFaultException(header, WsFaultType.XmlException, ex.Message); } catch (WsFaultException) { throw; // rethrow fault exception as it is } catch (Exception ex) // all other exception types { throw new WsFaultException(header, WsFaultType.Exception, ex.Message); } }
public virtual void OneWay(OneWayRequest req) { // Create request header String action; action = "http://schemas.example.org/SimpleService/OneWay"; WsWsaHeader header; header = new WsWsaHeader(action, null, EndpointAddress, m_version.AnonymousUri, null, null); WsMessage request = new WsMessage(header, req, WsPrefix.None); // Create request serializer OneWayRequestDataContractSerializer reqDcs; reqDcs = new OneWayRequestDataContractSerializer("OneWayRequest", "http://schemas.example.org/SimpleService"); request.Serializer = reqDcs; request.Method = "OneWay"; // Send service request m_requestChannel.Open(); m_requestChannel.RequestOneWay(request); m_requestChannel.Close(); }
// Build ws-discovery bye message internal static byte[] BuildByeMessage(string endpointAddress, WsWsaHeader header, XmlReader reader) { MemoryStream soapStream = new MemoryStream(); XmlWriter xmlWriter = XmlWriter.Create(soapStream); WsWsaHeader byeHeader = new WsWsaHeader( WsWellKnownUri.WsdNamespaceUri + "/Bye", // Action null, // RelatesTo endpointAddress, // To null, null, null); // ReplyTo, From, Any WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter, WsSoapMessageWriter.Prefixes.Wsd, // Prefix null, // Additional Prefix byeHeader, // Header new WsSoapMessageWriter.AppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); // AppSequence // write body xmlWriter.WriteStartElement("wsd", "Bye", WsWellKnownUri.WsdNamespaceUri); xmlWriter.WriteStartElement("wsa", "EndpointReference", WsWellKnownUri.WsaNamespaceUri_2005_08); xmlWriter.WriteStartElement("wsa", "Address", WsWellKnownUri.WsaNamespaceUri_2005_08); xmlWriter.WriteString(Device.EndpointAddress); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("wsd", "XAddrs", WsWellKnownUri.WsdNamespaceUri); xmlWriter.WriteString(Device.TransportAddress); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter); // Flush and close writer. Return stream buffer xmlWriter.Flush(); xmlWriter.Close(); return(soapStream.ToArray()); }
public virtual TypeCheckResponse TypeCheck(TypeCheckRequest req) { // Create request header String action; action = "http://schemas.example.org/SimpleService/TypeCheck"; WsWsaHeader header; header = new WsWsaHeader(action, null, EndpointAddress, m_version.AnonymousUri, null, null); WsMessage request = new WsMessage(header, req, WsPrefix.None); // Create request serializer TypeCheckRequestDataContractSerializer reqDcs; reqDcs = new TypeCheckRequestDataContractSerializer("TypeCheckRequest", "http://schemas.example.org/SimpleService"); request.Serializer = reqDcs; request.Method = "TypeCheck"; // Send service request m_requestChannel.Open(); WsMessage response = m_requestChannel.Request(request); m_requestChannel.Close(); // Process response TypeCheckResponseDataContractSerializer respDcs; respDcs = new TypeCheckResponseDataContractSerializer("TypeCheckResponse", "http://schemas.example.org/SimpleService"); TypeCheckResponse resp; resp = ((TypeCheckResponse)(respDcs.ReadObject(response.Reader))); response.Reader.Dispose(); response.Reader = null; return(resp); }
public String WriteSoapMessageStart(XmlWriter writer, WsPrefix prefixes, WsXmlNamespaces additionalPrefixes, WsWsaHeader header, WsAppSequence appSequence, bool fSendHeader) { String messageId = "urn:uuid:" + Guid.NewGuid(); String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<s:Envelope xmlns:s=\"" + WsWellKnownUri.SoapNamespaceUri + "\" " + "xmlns:a=\"" + m_version.AddressingNamespace + "\" "; if ((prefixes & WsPrefix.Wsdp) != WsPrefix.None) { xml += "xmlns:p=\"" + m_version.WsdpNamespaceUri + "\" "; } if ((prefixes & WsPrefix.Wse) != WsPrefix.None) { xml += "xmlns:e=\"" + WsWellKnownUri.WseNamespaceUri + "\" "; } if ((prefixes & WsPrefix.Wsx) != WsPrefix.None) { xml += "xmlns:x=\"" + WsWellKnownUri.WsxNamespaceUri + "\" "; } if ((prefixes & WsPrefix.Wsd) != WsPrefix.None || appSequence != null) { xml += "xmlns:d=\"" + m_version.DiscoveryNamespace + "\" "; } if (additionalPrefixes != null) { int count = additionalPrefixes.Count; WsXmlNamespace current; for (int i = 0; i < count; i++) { current = additionalPrefixes[i]; xml += "xmlns:" + current.Prefix + "=\"" + current.NamespaceURI + "\" "; } } xml += ">"; if (fSendHeader) { xml += "<s:Header>" + "<a:Action" + (header.MustUnderstand ? " s:mustUnderstand=\"1\">" : ">") + header.Action + "</a:Action>" + "<a:MessageID>" + messageId + "</a:MessageID>" + "<a:To" + (header.MustUnderstand ? " s:mustUnderstand=\"1\">" : ">") + header.To + "</a:To>"; if (header.RelatesTo != null) { xml += "<a:RelatesTo>" + header.RelatesTo + "</a:RelatesTo>"; } if (header.From != null) { xml += "<a:From><a:Address>" + header.From.Address.AbsoluteUri + "</a:Address></a:From>"; } if (header.ReplyTo != null) { xml += "<a:ReplyTo><a:Address>" + header.ReplyTo.Address.AbsoluteUri + "</a:Address></a:ReplyTo>"; } if (appSequence != null) { xml += "<d:AppSequence InstanceId=\"" + appSequence.InstanceId + "\" "; if (appSequence.SequenceId != null) { xml += "SequenceId=\"" + appSequence.SequenceId + "\" "; } xml += "MessageNumber=\"" + appSequence.MessageNumber + "\"/>"; } writer.WriteRaw(xml); if (header.Any != null) { header.Any.WriteTo(writer); } writer.WriteRaw("</s:Header>"); } else { writer.WriteRaw(xml); } writer.WriteRaw("<s:Body>"); return(messageId); }
/// <summary> /// Use to send a resolve request to the ws-discovery address and receive a resolve match. /// </summary> /// <param name="message">A byte array containing a the resolve message.</param> /// <param name="messageID"> /// A string containing the message ID of a resolve request. This ID will be used to validate against /// a ResolveMatch received if it don't match, the ResolveMatch is discarded. /// </param> /// <param name="timeout"> /// A DateTime value containing the length of time this request will wait for resolve match. /// until the timeout value has expired. /// </param> /// <returns>A resolve match object.</returns> private DpwsServiceDescription SendResolveRequest(byte[] message, string messageID, long timeout) { WsMessageCheck messageCheck = new WsMessageCheck(); DpwsServiceDescription resolveMatch = null; System.Ext.Console.Write(""); System.Ext.Console.Write("Sending Resolve:"); System.Ext.Console.Write(message); // Create a new UdpClient using (Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { uint ipLocal = WsNetworkServices.GetLocalIPV4AddressValue(); IPAddress localIP = IPAddress.Parse(WsNetworkServices.GetLocalIPV4Address()); IPEndPoint localEP = new IPEndPoint(localIP, 0); // Very important - Set default multicast interface for the underlying socket udpClient.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)ipLocal); udpClient.ReceiveTimeout = (int)timeout; udpClient.Bind(localEP); // Random back off implemented as per soap over udp specification // for unreliable multicast message exchange Thread th = SendWithBackoff(message, udpClient); // Wait for resolve match as long a timeout has not expired byte[] resolveResponse = new byte[c_MaxUdpPacketSize]; EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0); int responseLength; DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(m_version); while (true) { // Since MF sockets does not have an IOControl method catch 10054 to get around the problem // with Upd and ICMP. try { // Wait for response responseLength = udpClient.ReceiveFrom(resolveResponse, c_MaxUdpPacketSize, SocketFlags.None, ref remoteEP); } catch (SocketException se) { if ((SocketError)se.ErrorCode == SocketError.ConnectionReset) { Thread.Sleep(100); continue; } if ((SocketError)se.ErrorCode == SocketError.TimedOut) { break; } throw se; } // If we received process resolve match if (responseLength > 0) { System.Ext.Console.Write("ResolveMatches Response From: " + ((IPEndPoint)remoteEP).Address.ToString()); System.Ext.Console.Write(resolveResponse); try { WsWsaHeader header = new WsWsaHeader(); XmlReader reader = WsSoapMessageParser.ParseSoapMessage(resolveResponse, ref header, m_version); WsMessage msg = new WsMessage(header, null, WsPrefix.Wsdp); msg.Reader = reader; resolveMatch = soapProcessor.ProcessResolveMatch(msg, messageID, (IPEndPoint)remoteEP, messageCheck); if (resolveMatch != null) { break; } } catch (Exception e) { System.Ext.Console.Write(e.Message); } } } th.Join(); } // Display results if (resolveMatch == null) { System.Ext.Console.Write("Resolve timed out."); } return(resolveMatch); }
/// <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); }
/// <summary> /// Sends a Probe request and parses ProbeMatches responses. /// </summary> /// <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="maxProbeMatches"> /// An integer representing the maximum number of matches to reveive within the timout period. Pass 0 to receive /// as many matches as possible before the timeout expires. /// </param> /// <param name="timeout"> /// An integer specifying a request timeout in milliseconds. Pass -1 to wait ReceiveTimeout. /// </param> /// <remarks> /// A Probe is used to discover services on a network. The Probe method sends a UDP request to the /// Dpws multicast address, 239.255.255.250:3702. Any service that implements types specified in the /// filters parameter should respond with a ProbeMatches message. The ProbeMatches mesgage is unicast /// back to the that client that made the request. If a null filter is supplied any Dpws complient /// service should reply with a ProbeMatches reponse. Probe waits DpwsDiceoveryCleint.ReceiveTimout /// for probe matches. /// </remarks> /// <returns> /// A collection of ProbeMatches objects. A ProbeMatch object contains endpoint details used /// used to locate the actual service on a network and the types supported by the service. /// </returns> public DpwsServiceDescriptions Probe(DpwsServiceTypes filters, int maxProbeMatches, int timeout) { // Build the probe request message WsMessageCheck messageCheck = new WsMessageCheck(); string messageID = null; WsMessage probeRequest = BuildProbeRequest(DiscoVersion.DiscoveryWellKnownAddress, filters, out messageID); DpwsServiceDescriptions probeMatches = new DpwsServiceDescriptions(); System.Ext.Console.Write(""); System.Ext.Console.Write("Sending Probe:"); System.Ext.Console.Write(probeRequest.Body as byte[]); System.Ext.Console.Write(""); // Create a new UdpClient using (Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { // Very important - Set default multicast interface for the underlying socket uint ipLocal = WsNetworkServices.GetLocalIPV4AddressValue(); IPAddress localIP = IPAddress.Parse(WsNetworkServices.GetLocalIPV4Address()); IPEndPoint localEP = new IPEndPoint(localIP, 0); udpClient.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)ipLocal); udpClient.ReceiveTimeout = timeout; udpClient.Bind(localEP); // Random back off implemented as per soap over udp specification // for unreliable multicast message exchange Thread th = SendWithBackoff((byte[])probeRequest.Body, udpClient); // Create probe matches collection and set expiration loop timer byte[] probeResponse = new byte[c_MaxUdpPacketSize]; EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0); int responseLength; DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor(m_version); while (true) { // Since MF sockets does not have an IOControl method catch 10054 to get around the problem // with Upd and ICMP. try { // Wait for response responseLength = udpClient.ReceiveFrom(probeResponse, c_MaxUdpPacketSize, SocketFlags.None, ref remoteEP); } catch (SocketException se) { if ((SocketError)se.ErrorCode == SocketError.ConnectionReset) { Thread.Sleep(100); continue; } // Timeout if ((SocketError)se.ErrorCode == SocketError.TimedOut) { break; } throw se; } // If we received process probe match if (responseLength > 0) { System.Ext.Console.Write(""); System.Ext.Console.Write("ProbeMatches Response From: " + ((IPEndPoint)remoteEP).Address.ToString()); System.Ext.Console.Write(probeResponse); // Process the response try { WsWsaHeader header = new WsWsaHeader(); XmlReader reader = WsSoapMessageParser.ParseSoapMessage(probeResponse, ref header, m_version); WsMessage msg = new WsMessage(header, null, WsPrefix.Wsdp); msg.Reader = reader; DpwsServiceDescriptions tempMatches = soapProcessor.ProcessProbeMatch(msg, messageID, (IPEndPoint)remoteEP, messageCheck); if (tempMatches != null) { int count = maxProbeMatches < tempMatches.Count ? maxProbeMatches : tempMatches.Count; for (int i = 0; i < count; i++) { probeMatches.Add(tempMatches[i]); } maxProbeMatches -= count; } } catch (Exception e) { System.Ext.Console.Write(""); System.Ext.Console.Write(e.Message); System.Ext.Console.Write(""); } // If maxProbeRequest is set check count if (maxProbeMatches <= 0) { break; } } } th.Join(); } // Display results if (probeMatches.Count == 0) { System.Ext.Console.Write("Probe timed out."); } else { System.Ext.Console.Write("Received " + probeMatches.Count + " probeMatches matches."); } return(probeMatches); }
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); } }