/// <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>
        /// 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;
        }
        public virtual byte[] ProbeMatch(WsWsaHeader header, XmlReader reader)
        {

            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long startTime = timeDebuger.ResetStartTime("");

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

            // If a Host exist write the Host namespace
            WsXmlNamespaces additionalPrefixes = null;
            if (Device.Host != null)
            {
                additionalPrefixes = new WsXmlNamespaces();
                additionalPrefixes.Add(Device.Host.ServiceNamespace);
            }

            WsWsaHeader matchHeader = new WsWsaHeader(
                WsWellKnownUri.WsdNamespaceUri + "/ProbeMatches",                       // Action
                header.MessageID,                                                       // RelatesTo
                WsWellKnownUri.WsaAnonymousUri,                                         // To
                null, null, null);                                                      // ReplyTo, From, Any

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

            // Performance debuging
            timeDebuger.PrintElapsedTime("*****Write Header Took");

            // write body
            xmlWriter.WriteStartElement("wsd", "ProbeMatches", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteStartElement("wsd", "ProbeMatch", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteStartElement("wsa", "EndpointReference", WsWellKnownUri.WsaNamespaceUri_2005_08);
            xmlWriter.WriteStartElement("wsa", "Address", WsWellKnownUri.WsaNamespaceUri_2005_08);
            xmlWriter.WriteString(Device.EndpointAddress);
            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndElement();

            // Write hosted service types
            xmlWriter.WriteStartElement("wsd", "Types", WsWellKnownUri.WsdNamespaceUri);
            WriteDeviceServiceTypes(xmlWriter);
            xmlWriter.WriteEndElement(); // End Types

            xmlWriter.WriteStartElement("wsd", "XAddrs", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteString(Device.TransportAddress);
            xmlWriter.WriteEndElement();

            xmlWriter.WriteStartElement("wsd", "MetadataVersion", WsWellKnownUri.WsdNamespaceUri);
            xmlWriter.WriteString(Device.MetadataVersion.ToString());
            xmlWriter.WriteEndElement();

            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndElement();

            // Create return buffer and close writer

            // Performance debuging
            timeDebuger.PrintElapsedTime("*****Write Body Took");

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

            // Performance debuging
            timeDebuger.PrintTotalTime(startTime, "***ProbeMatch Took");

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

            // Delay probe match as per Ws-Discovery specification
            Thread.Sleep(new Random().Next(Device.ProbeMatchDelay));

            return soapStream.ToArray();

        }
        /// <summary>
        /// Use to subscribe to a devices, hosted service event sources.
        /// </summary>
        /// <param name="subscriptionRequest">
        /// A DpwsSubscriptionRequest object containing the address of the service hosting the desired event,
        /// the address where the event is sent, an optional address where subscription end messages are sent,
        /// A subscription expiration (in duration format) and an optional user defined identifier.
        /// </param>
        /// <returns>
        /// A DpwsEventSubscription containing the the subscription managers address, the time when the subscription
        /// expires (duration) and optional reference parameters and properties. Per spec the
        /// sub mananger may assign a different duration value than that specified in the request.
        /// </returns>
        /// <exception cref="ArgumentNullException">If required subscription parameters are not set.</exception>
        public DpwsEventSubscription Subscribe(DpwsSubscribeRequest subscriptionRequest)
        {
            if ((subscriptionRequest.SubscriptionType              == null) ||
                (subscriptionRequest.SubscriptionType.TypeName     == null) ||
                (subscriptionRequest.SubscriptionType.NamespaceUri == null) ||
                (subscriptionRequest.EndpointAddress               == null) ||
                (subscriptionRequest.NotifyTo                      == null) ||
                (subscriptionRequest.NotifyTo.Address              == null))
            {
                throw new ArgumentNullException();
            }

            // Convert the address string to a Uri
            Uri serviceUri = null;
            try
            {
                serviceUri = subscriptionRequest.EndpointAddress;
                if (serviceUri.Scheme != "http")
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Invalid endpoint address. Must be a Uri. Http Uri schemes only.");
                    System.Ext.Console.Write("");
                    return null;
                }
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write(e.Message);
                System.Ext.Console.Write("");
                return null;
            }

            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long startTime = timeDebuger.ResetStartTime("");
            WsMessage subscribeResponse = null;

            // Build Subscribe Request
            using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsWsaHeader header = new WsWsaHeader(
                    m_version.EventingNamespace + "/Subscribe",     // Action
                    null,                                           // RelatesTo
                    serviceUri.AbsoluteUri,                         // To
                    m_version.AnonymousUri,                         // ReplyTo
                    null, null);                                    // From, Any

                WsXmlNamespaces additionalPrefixes = new WsXmlNamespaces();
                additionalPrefixes.Add(new WsXmlNamespace("myPrefix", subscriptionRequest.SubscriptionType.NamespaceUri));

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

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

                // Performance debuging
                timeDebuger.PrintElapsedTime("*****Write Header Took");

                // write body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Subscribe", null);
                
                // If EndTo is set write it
                if (subscriptionRequest.EndTo != null)
                    WriteEndpointRef(xmlWriter, subscriptionRequest.EndTo, "EndTo");

                // Add the delivery element and NotifyTo endpoint
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Delivery", null);
                xmlWriter.WriteAttributeString("Mode", m_version.EventingNamespace + "/DeliveryModes/Push");

                // Writer the notify to endpoint
                WriteEndpointRef(xmlWriter, subscriptionRequest.NotifyTo, "NotifyTo");

                xmlWriter.WriteEndElement(); // End Delivery

                // Write Expiration time
                if (subscriptionRequest.Expires != null)
                {
                    xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Expires", null);
                    xmlWriter.WriteString(subscriptionRequest.Expires.DurationString);
                    xmlWriter.WriteEndElement(); // End Expires
                }

                // Write Filter element specifying the event to subscribe to.
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Filter", null);
                xmlWriter.WriteAttributeString("Dialect", m_version.WsdpNamespaceUri + "/Action");
                xmlWriter.WriteString(subscriptionRequest.SubscriptionType.NamespaceUri + "/" + subscriptionRequest.SubscriptionType.TypeName);
                xmlWriter.WriteEndElement(); // End Filter

                xmlWriter.WriteEndElement(); // End Subscribe

                smw.WriteSoapMessageEnd(xmlWriter);

                // Performance debuging
                timeDebuger.PrintElapsedTime("*****Write Body Took");

                // Performance debuging
                timeDebuger.PrintTotalTime(startTime, "***Subscribe Message Build Took");

                // Create an Http client and send Subscribe request
                WsHttpClient httpClient = new WsHttpClient(m_version);

                msg.Body = xmlWriter.ToArray();

                subscribeResponse = httpClient.SendRequest(msg, subscriptionRequest.EndpointAddress);

                // If a subscribe response is received process it and return expiration time the subscription manager
                // actually assigned.
                // If a parsing fault is received print exception and go on.
                DpwsEventSubscription response = null;
                if (subscribeResponse == null)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Subscribe response is null.");
                    return null;
                }
                else
                {
                    byte[] responseBytes = subscribeResponse.Body as byte[];

                    // It is ok for the service to return a 202 and a 0 length response
                    // if thi is the case just return null
                    if(responseBytes == null || responseBytes.Length == 0) return null;

                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Response From: " + subscriptionRequest.EndpointAddress.Host);
                    System.Ext.Console.Write(responseBytes);
                    try
                    {
                        response = ProcessSubscribeResponse(responseBytes, messageID);
                    }
                    catch (Exception e)
                    {
                        System.Ext.Console.Write("");
                        System.Ext.Console.Write("Subscription response parsing failed.");
                        System.Ext.Console.Write(e.Message);
                    }
                }
                
                return response;
            }
        }
        /// <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;
                    }
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// Use to unsubscribe from a devices event source.
        /// </summary>
        /// <param name="endpointAddress">
        /// A Uri containing the endpoint address of the service or subscription manager that is currently
        /// maintaining this event subscription on behalf of the device. This address is an http uri
        /// (i.e. http://ip_address:port/serviceID).
        /// </param>
        /// <param name="subscription">An event subscription returned from a previous subscribe call.
        /// The subscription contains among other things a subscription ID used by the subscription manager
        /// to identify a specific event source subscription and the endpoint address of the subscription manager.
        /// </param>
        /// <returns>True if the Unsubscribe request was successful.</returns>
        public bool Unsubscribe(Uri endpointAddress, DpwsEventSubscription subscription)
        {
            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long startTime = timeDebuger.ResetStartTime("");

            // Build Unsubscribe Request
            MemoryStream soapStream = new MemoryStream();
            XmlWriter xmlWriter = XmlWriter.Create(soapStream);

            WsXmlNodeList nodeList = new WsXmlNodeList();
            nodeList.Add(new WsXmlNode(null, "identifier", WsWellKnownUri.WseNamespaceUri, subscription.SubscriptionID));

            WsWsaHeader header = new WsWsaHeader(
                WsWellKnownUri.WseNamespaceUri + "/Unsubscribe",            // Action
                null,                                                       // RelatesTo
                endpointAddress.AbsoluteUri,                                // To
                WsWellKnownUri.WsaAnonymousUri,                             // ReplyTo
                subscription.SubscriptionManager.Address.AbsoluteUri,       // From
                nodeList);                                                  // Identifier

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

            // Performance debuging
            timeDebuger.PrintElapsedTime("*****Write Header Took");

            // write body
            xmlWriter.WriteStartElement("wse", "Unsubscribe", null);
            xmlWriter.WriteString("");
            xmlWriter.WriteEndElement(); // End Unsubscribe

            // Performance debuging
            timeDebuger.PrintElapsedTime("*****Write Body Took");

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

            // Performance debuging
            timeDebuger.PrintTotalTime(startTime, "***Unsubscribe Message Build Took");

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

            // Create an Http client and send Unsubscribe request
            WsHttpClient httpClient = new WsHttpClient();
            byte[] unsubscribeResponse = null;
            try
            {
                unsubscribeResponse = httpClient.SendRequest(soapStream.ToArray(), endpointAddress.ToString(), false, false);
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Unsubscribe failed. " + e.Message);
                return false;
            }

            // If a unsubscribe response is received simple validate that the messageID and action are correct and
            // If a parsing fault is received print exception and go on.
            if (unsubscribeResponse == null)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Unsubscribe response is null.");
                return false;
            }
            else
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Response From: " + endpointAddress.Host);
                System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(unsubscribeResponse)));
                try
                {
                    return ProcessUnsubscribeResponse(unsubscribeResponse, messageID);
                }
                catch (Exception e)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Unsubscribe response parsing failed.");
                    System.Ext.Console.Write(e.Message);
                    return false;
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Use to get the status of an event subscription.
        /// </summary>
        /// <param name="endpointAddress">
        /// A Uri containing the endpoint address of the service or subscription manager that is currently
        /// maintaining this event subscription on behalf of the device. This address is an http uri
        /// (i.e. http://ip_address:port/serviceID).
        /// </param>
        /// <param name="subscriptionID">
        /// A subscription ID returned from a previous subscribe response. The device uses this ID
        /// to identify a specific event source subscription.
        /// </param>
        /// <returns>
        /// A WsDuration object containing the remaining subscription time for this event subscription, null = infinite.
        /// </returns>
        public WsDuration GetStatus(Uri endpointAddress, string subscriptionID)
        {
            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long startTime = timeDebuger.ResetStartTime("");

            // Build Renew request
            MemoryStream soapStream = new MemoryStream();
            XmlWriter xmlWriter = XmlWriter.Create(soapStream);

            WsXmlNodeList nodeList = new WsXmlNodeList();
            nodeList.Add(new WsXmlNode("wse", "Identifier", null, subscriptionID));

            WsWsaHeader header = new WsWsaHeader(
                WsWellKnownUri.WseNamespaceUri + "/GetStatus",  // Action
                null,                                           // RelatesTo
                endpointAddress.AbsoluteUri,                    // To
                null, null, nodeList);                          // ReplyTo, From, Any

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

            // Performance debuging
            timeDebuger.PrintElapsedTime("*****Write Header Took");

            // write body
            xmlWriter.WriteStartElement("soap", "Body", null);
            xmlWriter.WriteStartElement("wse", "GetStatus", null);
            xmlWriter.WriteString("");
            xmlWriter.WriteEndElement(); // End GetStatus

            // Performance debuging
            timeDebuger.PrintElapsedTime("*****Write Body Took");

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

            // Performance debuging
            timeDebuger.PrintTotalTime(startTime, "***Renew Message Build Took");

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

            // Create an Http client and send GetStatus request
            WsHttpClient httpClient = new WsHttpClient();
            byte[] getStatusResponse = null;
            try
            {
                getStatusResponse = httpClient.SendRequest(soapStream.ToArray(), endpointAddress.ToString(), false, false);
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("GetStatus failed. " + e.Message);
                return null;
            }

            // If a GetStatus response is received validate the messageID and action and get the remaining
            // event subscription time. If a fault is received print exception and go on.
            if (getStatusResponse == null)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Renew response is null.");
                return null;
            }
            else
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Response From: " + endpointAddress.Host);
                System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(getStatusResponse)));

                // Note: Since the response is the same for GetStatus ans it is for Renew reuse the
                // Renew response parser.
                try
                {
                    return ProcessRenewResponse(getStatusResponse, messageID);
                }
                catch (Exception e)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Unsubscribe response parsing failed.");
                    System.Ext.Console.Write(e.Message);
                }
            }

            return null;
        }
Exemple #8
0
        /// <summary>
        /// Use to subscribe to a devices, hosted service event sources.
        /// </summary>
        /// <param name="subscriptionRequest">
        /// A DpwsSubscriptionRequest object containing the address of the service hosting the desired event,
        /// the address where the event is sent, an optional address where subscription end messages are sent,
        /// A subscription expiration (in duration format) and an optional user defined identifier.
        /// </param>
        /// <returns>
        /// A DpwsEventSubscription containing the the subscription managers address, the time when the subscription
        /// expires (duration) and optional reference parameters and properties. Per spec the
        /// sub mananger may assign a different duration value than that specified in the request.
        /// </returns>
        /// <exception cref="ArgumentNullException">If required subscription parameters are not set.</exception>
        public DpwsEventSubscription Subscribe(DpwsSubscribeRequest subscriptionRequest)
        {
            if (subscriptionRequest.SubscriptionType == null)
                throw new ArgumentNullException("Subscribe - SubscriptionType must not be null");
            if (subscriptionRequest.SubscriptionType.TypeName == null)
                throw new ArgumentNullException("Subscribe - SubscriptionType.TypeName must not be null");
            if (subscriptionRequest.SubscriptionType.NamespaceUri == null)
                throw new ArgumentNullException("Subscribe - SubscriptionType.NamespaceUri must not be null");
            if (subscriptionRequest.EndpointAddress == null)
                throw new ArgumentNullException("Subscribe - EndpointAddress property must not be null.");
            if (subscriptionRequest.NotifyTo == null)
                throw new ArgumentNullException("Subscribe - NotifyTo must not be null.");
            if (subscriptionRequest.NotifyTo.Address == null)
                throw new ArgumentNullException("Subscribe - NotifyTo.Address must not be null.");

            // Convert the address string to a Uri
            Uri serviceUri = null;
            try
            {
                serviceUri = subscriptionRequest.EndpointAddress;
                if (serviceUri.Scheme != "http")
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Invalid endpoint address. Must be a Uri. Http Uri schemes only.");
                    System.Ext.Console.Write("");
                    return null;
                }
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write(e.Message);
                System.Ext.Console.Write("");
                return null;
            }

            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long startTime = timeDebuger.ResetStartTime("");

            // Build Subscribe Request
            MemoryStream soapStream = new MemoryStream();
            XmlWriter xmlWriter = XmlWriter.Create(soapStream);

            WsWsaHeader header = new WsWsaHeader(
                WsWellKnownUri.WseNamespaceUri + "/Subscribe",  // Action
                null,                                           // RelatesTo
                serviceUri.AbsoluteUri,                         // To
                WsWellKnownUri.WsaAnonymousUri,                 // ReplyTo
                null, null);                                    // From, Any

            WsXmlNamespaces additionalPrefixes = new WsXmlNamespaces();
            additionalPrefixes.Add(new WsXmlNamespace("myPrefix", subscriptionRequest.SubscriptionType.NamespaceUri));

            String messageID = WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter,
                WsSoapMessageWriter.Prefixes.Wsd | WsSoapMessageWriter.Prefixes.Wse,
                additionalPrefixes, header, null);

            // Performance debuging
            timeDebuger.PrintElapsedTime("*****Write Header Took");

            // write body
            xmlWriter.WriteStartElement("wse", "Subscribe", null);
            
            // If EndTo is set write it
            if (subscriptionRequest.EndTo != null)
                WriteEndpointRef(ref xmlWriter, subscriptionRequest.EndTo, "EndTo");

            // Add the delivery element and NotifyTo endpoint
            xmlWriter.WriteStartElement("wse", "Delivery", null);
            xmlWriter.WriteAttributeString("Mode", "http://schemas.xmlsoap.org/ws/2004/08/eventing/DeliveryModes/Push");

            // Writer the notify to endpoint
            WriteEndpointRef(ref xmlWriter, subscriptionRequest.NotifyTo, "NotifyTo");

            xmlWriter.WriteEndElement(); // End Delivery

            // Write Expiration time
            if (subscriptionRequest.Expires != null)
            {
                xmlWriter.WriteStartElement("wse", "Expires", null);
                xmlWriter.WriteString(subscriptionRequest.Expires.DurationString);
                xmlWriter.WriteEndElement(); // End Expires
            }

            // Write Filter element specifying the event to subscribe to.
            xmlWriter.WriteStartElement("wse", "Filter", null);
            xmlWriter.WriteAttributeString("Dialect", "http://schemas.xmlsoap.org/ws/2006/02/devprof/Action");
            xmlWriter.WriteString(subscriptionRequest.SubscriptionType.NamespaceUri + "/" + subscriptionRequest.SubscriptionType.TypeName);
            xmlWriter.WriteEndElement(); // End Filter

            xmlWriter.WriteEndElement(); // End Subscribe

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

            // Performance debuging
            timeDebuger.PrintElapsedTime("*****Write Body Took");

            // Performance debuging
            timeDebuger.PrintTotalTime(startTime, "***Subscribe Message Build Took");

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

            // Create an Http client and send Subscribe request
            WsHttpClient httpClient = new WsHttpClient();
            byte[] subscribeResponse = null;
            try
            {
                subscribeResponse = httpClient.SendRequest(soapStream.ToArray(), subscriptionRequest.EndpointAddress.AbsoluteUri, false, false);
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Subscribe failed. " + e.Message);
                return null;
            }

            // If a subscribe response is received process it and return expiration time the subscription manager
            // actually assigned.
            // If a parsing fault is received print exception and go on.
            DpwsEventSubscription response = null;
            if (subscribeResponse == null)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Subscribe response is null.");
                return null;
            }
            else
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Response From: " + subscriptionRequest.EndpointAddress.Host);
                System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(subscribeResponse)));
                try
                {
                    // It is ok for the service to return a 202 and a 0 length response
                    // if thi is the case just return null
                    if (subscribeResponse.Length == 0)
                        return null;
                    response = ProcessSubscribeResponse(subscribeResponse, messageID);
                }
                catch (Exception e)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Subscription response parsing failed.");
                    System.Ext.Console.Write(e.Message);
                }
            }

            return response;
        }
Exemple #9
0
        /// <summary>
        /// Use to request metadata from a devices hosted service endpoint.
        /// </summary>
        /// <param name="serviceAddress">
        /// A string containing the transport address of a service endpoint. For Dpws the address represents
        /// a devices transport address.
        /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <returns>
        /// A collection of DpwsMetadata objects containing endpoint details about services hosted by a device.
        /// </returns>
        public DpwsMetadata Get(string serviceAddress)
        {
            // Convert the address string to a Uri
            Uri serviceUri = null;
            try
            {
                serviceUri = new Uri(serviceAddress);
                if (serviceUri.Scheme != "http")
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Invalid serviceAddress. Must be a Uri. Http Uri schemes only.");
                    System.Ext.Console.Write("");
                    return null;
                }
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write(e.Message);
                System.Ext.Console.Write("");
                return null;
            }

            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long startTime = timeDebuger.ResetStartTime("");

            // Build Get Request
            MemoryStream soapStream = new MemoryStream();
            XmlWriter xmlWriter = XmlWriter.Create(soapStream);

            WsWsaHeader header = new WsWsaHeader(
                WsWellKnownUri.WstNamespaceUri + "/Get",            // Action
                null,                                               // RelatesTo
                "urn:uuid:" + serviceUri.AbsolutePath.Substring(1), // To
                WsWellKnownUri.WsaAnonymousUri,                     // ReplyTo
                null, null);                                        // From, Any

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

            // Performance debuging
            timeDebuger.PrintElapsedTime("*****Write Header Took");

            // Performance debuging
            timeDebuger.PrintElapsedTime("*****Write Body Took");

            WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

            // Performance debuging
            timeDebuger.PrintTotalTime(startTime, "***Get Message Build Took");

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

            // Create an Http client and send Get request
            WsHttpClient httpClient = new WsHttpClient();
            byte[] getResponse = null;
            try
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Sending Get to: " + serviceAddress);
                getResponse = httpClient.SendRequest(soapStream.ToArray(), serviceAddress, false, false);
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write("Get failed. " + e.Message);

                return null;
            }

            // If a get response is received process it and return DpwsMetadata object
            DpwsMetadata metadata = null;
            if (getResponse == null)
                return null;
            else
            {
                System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(getResponse)));
                System.Ext.Console.Write("");
                DpwsDiscoClientProcessor soapProcessor = new DpwsDiscoClientProcessor();
                try
                {
                    metadata = soapProcessor.ProcessGetResponse(getResponse, messageID);
                }
                catch (Exception e)
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Get response parser threw an exception. " + e.Message);
                    return null;
                }
            }

            return metadata;
        }
        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;
            }
        }
Exemple #11
0
        /// <summary>
        /// Use to request metadata from a devices hosted service endpoint.
        /// </summary>
        /// <param name="serviceAddress">
        /// A string containing the transport address of a service endpoint. For Dpws the address represents
        /// a devices transport address.
        /// For example: http://192.168.0.1:8084/3cb0d1ba-cc3a-46ce-b416-212ac2419b20
        /// </param>
        /// <returns>
        /// A collection of DpwsMetadata objects containing endpoint details about services hosted by a device.
        /// </returns>
        public DpwsMetadata Get(string serviceAddress)
        {
            // Convert the address string to a Uri
            Uri serviceUri = null;
            try
            {
                serviceUri = new Uri(serviceAddress);
                if (serviceUri.Scheme != "http")
                {
                    System.Ext.Console.Write("");
                    System.Ext.Console.Write("Invalid serviceAddress. Must be a Uri. Http Uri schemes only.");
                    System.Ext.Console.Write("");
                    return null;
                }
            }
            catch (Exception e)
            {
                System.Ext.Console.Write("");
                System.Ext.Console.Write(e.Message);
                System.Ext.Console.Write("");
                return null;
            }

            // Performance debugging
            DebugTiming timeDebuger = new DebugTiming();
            long startTime = timeDebuger.ResetStartTime("");

            // Build Get Request
            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;
            }
        }
Exemple #12
0
        /// <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();
        }