Beispiel #1
0
 /// <summary>
 /// Creates a http service host.
 /// </summary>
 /// <param name="port">An integer containing the port number this host will listen on.</param>
 /// <param name="serviceEndpoints">A collection of service endpoints this transport service can dispatch to.</param>
 public WsHttpServiceHost(_Bind.Binding binding, WsServiceEndpoints serviceEndpoints)
 {
     m_threadManager    = new WsThreadManager(5, "Http");            
     m_binding          = binding;
     m_serviceEndpoints = serviceEndpoints;
     m_isStarted        = false;
 }
Beispiel #2
0
        /// <summary>
        /// Creates an instance of a DpwsClient class with a specified eventing callback port number.
        /// </summary>
        public DpwsClient(Binding localBinding, ProtocolVersion v)
        {
            m_threadLock               = new object();
            m_eventClient              = new DpwsEventingClient(v);
            m_mexClient                = new DpwsMexClient(v);
            m_eventCallbacks           = new WsServiceOperations();
            m_callbackServiceEndpoints = new WsServiceEndpoints();
            m_blockingCall             = true;
            m_ignoreRequestFromThisIP  = true;
            m_localBinding             = localBinding;
            m_version                  = v;

            m_discoClient = new DpwsDiscoveryClient(this, v);

            // Add the Hello and Bye discovery disco services
            ClientDiscoveryService = new DpwsDiscoClientService(this, v);

            // Start a Udp discovery service host
            WsUdpServiceHost.Instance.AddServiceEndpoint(ClientDiscoveryService);
            WsUdpServiceHost.Instance.IgnoreRequestFromThisIP = m_ignoreRequestFromThisIP;
            WsUdpServiceHost.Instance.MaxThreadCount = 5;
            WsUdpServiceHost.Instance.Start(new ServerBindingContext(v));
        }
        /// <summary>
        /// Creates an instance of a DpwsClient class with a specified eventing callback port number.
        /// </summary>
        public DpwsClient(Binding localBinding, ProtocolVersion v)
        {
            m_threadLock               = new object();
            m_eventClient              = new DpwsEventingClient(v);
            m_mexClient                = new DpwsMexClient(v);
            m_eventCallbacks           = new WsServiceOperations();
            m_callbackServiceEndpoints = new WsServiceEndpoints();
            m_blockingCall             = true;
            m_ignoreRequestFromThisIP  = true;
            m_localBinding             = localBinding;
            m_version                  = v;

            m_discoClient = new DpwsDiscoveryClient(this, v);

            // Add the Hello and Bye discovery disco services
            ClientDiscoveryService = new DpwsDiscoClientService(this, v);

            // Start a Udp discovery service host
            WsUdpServiceHost.Instance.AddServiceEndpoint(ClientDiscoveryService);
            WsUdpServiceHost.Instance.IgnoreRequestFromThisIP = m_ignoreRequestFromThisIP;
            WsUdpServiceHost.Instance.MaxThreadCount = 5;
            WsUdpServiceHost.Instance.Start(new ServerBindingContext(v));

            // Add eventing SubscriptionEnd ServiceOperations. By default Subscription End call back
            // to this client
            ServiceOperations.Add(new WsServiceOperation(WsWellKnownUri.WseNamespaceUri, "SubscriptionEnd"));

            // Add callbacks implemented by this client
            m_callbackServiceEndpoints.Add(this);

            // Start the Http service host
            m_httpServiceHost = new WsHttpServiceHost(m_localBinding, m_callbackServiceEndpoints);
            m_httpServiceHost.MaxThreadCount = m_callbackServiceEndpoints.Count;
            m_httpServiceHost.Start(new ServerBindingContext(v));
            System.Ext.Console.Write("Http service host started...");
        }
        /// <summary>
        /// Event GetStatus stub.
        /// </summary>
        /// <param name="header">Header object.</param>
        /// <param name="reader">An XmlReader positioned at the begining of the GetStatus request body element.</param>
        /// <param name="serviceEndpoints">A Collection of serviceEndpoints used to determine what services contain the specified event.</param>
        /// <returns>Byte array containing an GetStatus response.</returns>
        /// <remarks>This method is used by the stack framework. Do not use this method.</remarks>
        public WsMessage GetStatus(WsWsaHeader header, XmlReader reader, WsServiceEndpoints serviceEndpoints)
        {
            // Parse GetStatus Request
            ///////////////////////////////
            // there's no info in GetStatus that we actually need, just get the identifier from header
            String eventSinkID = header.Any.GetNodeValue("Identifier", WsWellKnownUri.WseNamespaceUri);

            // Iterate the list of hosted services at the specified endpoint and get the status of the first
            // subscription matching the eventSink. Not pretty but eventing and shared service endpoints don't
            // fit together
            if (eventSinkID != null)
            {
                // Parse urn:uuid from the To address
                string endpointAddress = FixToAddress(header.To);

                DpwsHostedService endpoint = (DpwsHostedService)serviceEndpoints[endpointAddress];
                if (endpoint != null)
                {
                    DpwsWseEventSink eventSink;
                    if ((eventSink = GetEventSink(endpoint.EventSources, eventSinkID)) != null)
                    {
                        long timeRemaining = DateTime.Now.Ticks - (eventSink.StartTime + eventSink.Expires);
                        timeRemaining = timeRemaining < 0 ? 0 : timeRemaining;

                        return GetStatusResponse(header, timeRemaining);
                    }
                }
            }

            // Something went wrong
            throw new WsFaultException(header, WsFaultType.WseEventSourceUnableToProcess);
        }
        /// <summary>
        /// Event renew stub.
        /// </summary>
        /// <param name="header">Header object.</param>
        /// <param name="reader">An XmlReader positioned at the begining of the Renew request body element.</param>
        /// <param name="serviceEndpoints">A Collection of serviceEndpoints used to determine what services contain the specified event.</param>
        /// <returns>Byte array containing an Renew response.</returns>
        /// <remarks>This method is used by the stack framework. Do not use this method.</remarks>
        public WsMessage Renew(WsWsaHeader header, XmlReader reader, WsServiceEndpoints serviceEndpoints)
        {
            long newExpiration = 0;
            String eventSinkId = String.Empty;

            // Parse Renew request
            ////////////////////////////
            try
            {
                reader.ReadStartElement("Renew", WsWellKnownUri.WseNamespaceUri);

                if (reader.IsStartElement("Expires", WsWellKnownUri.WseNamespaceUri))
                {
                    newExpiration = new WsDuration(reader.ReadElementString()).DurationInSeconds;

                    if (newExpiration <= 0)
                    {
                        throw new WsFaultException(header, WsFaultType.WseInvalidExpirationTime);
                    }
                }
                else
                {
                    // Never Expires
                    newExpiration = -1;
                }

                eventSinkId = header.Any.GetNodeValue("Identifier", WsWellKnownUri.WseNamespaceUri);

                if (eventSinkId == null)
                {
                    throw new XmlException();
                }
            }
            catch (XmlException e)
            {
                throw new WsFaultException(header, WsFaultType.WseInvalidMessage, e.ToString());
            }

            // Parse urn:uuid from the To address
            string endpointAddress = FixToAddress(header.To);

            // Iterate the list of hosted services at the specified endpoint and renew each subscription
            // with and event source that matches the eventSinkID
            DpwsWseEventSink eventSink;
            bool eventSinkFound = false;

            DpwsHostedService endpoint = (DpwsHostedService)serviceEndpoints[endpointAddress];

            if(endpoint != null)
            {
                if ((eventSink = GetEventSink(endpoint.EventSources, eventSinkId)) != null)
                {
                    eventSinkFound = true;

                    // Update event sink expires time
                    eventSink.Expires = newExpiration;
                }
            }

            // Generate Response
            if (eventSinkFound)
                return GetStatusResponse(header, newExpiration); // It's just like the GetStatus Response
            throw new WsFaultException(header, WsFaultType.WseEventSourceUnableToProcess, "Subscription was not found. ID=" + eventSinkId);
        }
        /// <summary>
        /// Eventing UnSubscribe stub.
        /// </summary>
        /// <param name="header">Header object.</param>
        /// <param name="reader">An XmlReader positioned at the begining of the Unsubscribe request body element.</param>
        /// <param name="serviceEndpoints">A Collection of serviceEndpoints used to determine what services contain the specified event.</param>
        /// <returns>Byte array containing an UnSubscribe response.</returns>
        /// <remarks>This method is used by the stack framework. Do not use this method.</remarks>
        public WsMessage Unsubscribe(WsWsaHeader header, XmlReader reader, WsServiceEndpoints serviceEndpoints)
        {
            // Parse Unsubscribe Request
            ///////////////////////////////
            // there's no info in Unsubscribe that we actually need, just get the identifier from header
            String eventSinkID = header.Any.GetNodeValue("Identifier", WsWellKnownUri.WseNamespaceUri);

            bool eventSourceFound = false;
            if (eventSinkID != null)
            {

                // Parse urn:uuid from the To address
                string endpointAddress = FixToAddress(header.To);

                // Iterate the list of hosted services at the specified endpoint and unsubscribe from each event source
                // that matches the eventSinkID

                DpwsHostedService serv = (DpwsHostedService)Device.HostedServices[endpointAddress];

                if(serv != null)
                {
                    DpwsWseEventSources eventSources = serv.EventSources;
                        
                    // Delete Subscription
                    // Look for matching event in hosted services event sources
                    DpwsWseEventSource eventSource;
                    DpwsWseEventSinks eventSinks;
                    DpwsWseEventSink eventSink;
                    int eventSourcesCount = eventSources.Count;
                    int eventSinksCount;
                    for (int i = 0; i < eventSourcesCount; i++)
                    {
                        eventSource = eventSources[i];
                        eventSinks = eventSource.EventSinks;
                        eventSinksCount = eventSinks.Count;

                        eventSink = eventSinks[eventSinkID];
                        
                        if (eventSink != null)
                        {
                            eventSourceFound = true;
                            eventSource.EventSinks.Remove(eventSink);
                        }
                    }
                }

                if (eventSourceFound)
                {
                    // Generate Response
                    using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
                    {
                        WsWsaHeader responseHeader = new WsWsaHeader(
                            WsWellKnownUri.WseNamespaceUri + "/UnsubscribeResponse",// Action
                            header.MessageID,                                       // RelatesTo
                            header.ReplyTo.Address.AbsoluteUri,                     // To
                            null, null, null);

                        WsMessage msg = new WsMessage( responseHeader, null, WsPrefix.Wse, null, 
                            new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID));

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

                        // Return stream buffer
                        msg.Body = xmlWriter.ToArray();

                        return msg;
                    }
                }
            }

            // Something went wrong
            throw new WsFaultException(header, WsFaultType.WseEventSourceUnableToProcess);
        }
        /// <summary>
        /// Global eventing Subscribe stub.
        /// </summary>
        /// <param name="header">Header object.</param>
        /// <param name="reader">An XmlReader positioned at the begining of the Subscribe request body element.</param>
        /// <param name="serviceEndpoints">A Collection of serviceEndpoints used to determine what services contain the event source specified in the filter.</param>
        /// <returns>Byte array containing a Subscribe response.</returns>
        internal WsMessage Subscribe(WsWsaHeader header, XmlReader reader, WsServiceEndpoints serviceEndpoints)
        {
            WsMessage msg = null;

            // Parse Subscribe Request
            /////////////////////////////
            DpwsWseEventSink eventSink = new DpwsWseEventSink();
            try
            {
                reader.ReadStartElement("Subscribe", WsWellKnownUri.WseNamespaceUri);

                if (reader.IsStartElement("EndTo", WsWellKnownUri.WseNamespaceUri))
                {
                    eventSink.EndTo = new WsWsaEndpointRef(reader, m_version.AddressingNamespace);
                }

                reader.ReadStartElement("Delivery", WsWellKnownUri.WseNamespaceUri);
                if (reader.IsStartElement("NotifyTo", WsWellKnownUri.WseNamespaceUri))
                {
                    eventSink.NotifyTo = new WsWsaEndpointRef(reader, m_version.AddressingNamespace);
                }
                else
                {
                    throw new WsFaultException(header, WsFaultType.WseDeliverModeRequestedUnavailable);
                }

                reader.ReadEndElement();

                if (reader.IsStartElement("Expires", WsWellKnownUri.WseNamespaceUri))
                {
                    long expires = new WsDuration(reader.ReadElementString()).DurationInSeconds;

                    if (expires > 0)
                    {
                        eventSink.Expires = expires;
                    }
                    else
                    {
                        throw new WsFaultException(header, WsFaultType.WseInvalidExpirationTime);
                    }
                }
                else
                {
                    // Never Expires
                    eventSink.Expires = -1;
                }

                if (reader.IsStartElement("Filter", WsWellKnownUri.WseNamespaceUri))
                {
                    if (reader.MoveToAttribute("Dialect") == false || reader.Value != m_version.WsdpNamespaceUri + "/Action")
                    {
                        throw new WsFaultException(header, WsFaultType.WseFilteringRequestedUnavailable);
                    }

                    reader.MoveToElement();

                    String filters = reader.ReadElementString();

                    if (filters != String.Empty)
                    {
                        eventSink.Filters = filters.Split(' ');
                    }
                }

                XmlReaderHelper.SkipAllSiblings(reader);

                reader.ReadEndElement(); // Subscribe
            }
            catch (XmlException e)
            {
                throw new WsFaultException(header, WsFaultType.WseInvalidMessage, e.ToString());
            }

            // Parse urn:uuid from the To address
            string endpointAddress = FixToAddress(header.To);

            // Build a temporary collection of device services that match the specified endpoint address.
            WsServiceEndpoints matchingServices = new WsServiceEndpoints();
            for (int i = 0; i < serviceEndpoints.Count; ++i)
            {
                if (serviceEndpoints[i].EndpointAddress == endpointAddress)
                    matchingServices.Add(serviceEndpoints[i]);
            }

            // For each service with a matching endpoint and event sources add an event sink to the
            // event source collection
            for (int i = 0; i < matchingServices.Count; ++i)
            {
                DpwsWseEventSources eventSources = ((DpwsHostedService)matchingServices[i]).EventSources;

                // Set the EventSinkID
                eventSink.ID = "urn:uuid:" + Guid.NewGuid().ToString();

                // If subscribing to all event sources
                if (eventSink.Filters == null)
                {
                    int count = eventSources.Count;
                    for (int ii = 0; i < count; i++)
                    {
                        DpwsWseEventSource eventSource = eventSources[ii];
                        eventSink.StartTime = DateTime.Now.Ticks;
                        eventSource.EventSinks.Add(eventSink);
                    }
                }
                else
                {
                    // If subscribing to a specific event based on an event filter.
                    DpwsWseEventSource eventSource;
                    string[] filterList = eventSink.Filters;
                    int length = filterList.Length;
                    for (int ii = 0; i < length; i++)
                    {
                        if ((eventSource = eventSources[filterList[ii]]) != null)
                        {
                            eventSink.StartTime = DateTime.Now.Ticks;
                            eventSource.EventSinks.Add(eventSink);
                        }
                        else
                        {
                            throw new Exception("Event source " + filterList[ii] + " was not found.");
                        }
                    }
                }
            }

            // Generate Response
            //////////////////////////
            using(XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsWsaHeader responseHeader = new WsWsaHeader(
                    WsWellKnownUri.WseNamespaceUri + "/SubscribeResponse",  // Action
                    header.MessageID,                                       // RelatesTo
                    header.ReplyTo.Address.AbsoluteUri,                     // To
                    null, null, null);                                      // ReplyTo, From, Any

                msg = new WsMessage(responseHeader, null, WsPrefix.Wse, null, 
                    new WsAppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID));

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

                // write body
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "SubscribeResponse", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "SubscriptionManager", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "Address", null);
                // Create a uri. Use the path (by default will be a uuid) for the sub manager endpoint
                Uri subMgrUri = new Uri(((DpwsHostedService)matchingServices[0]).EndpointAddress);
                xmlWriter.WriteString("http://" + Device.IPV4Address + ":" + Device.Port + "/" + subMgrUri.AbsolutePath);
                xmlWriter.WriteEndElement(); // End Address
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wsa, "ReferenceParameters", null);
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Identifier", null);
                xmlWriter.WriteString(eventSink.ID);
                xmlWriter.WriteEndElement(); // End Identifier
                xmlWriter.WriteEndElement(); // End ReferenceParameters
                xmlWriter.WriteEndElement(); // End SubscriptionManager
                xmlWriter.WriteStartElement(WsNamespacePrefix.Wse, "Expires", null);
                xmlWriter.WriteString(new WsDuration(eventSink.Expires).DurationString);
                xmlWriter.WriteEndElement(); // End Expires
                xmlWriter.WriteEndElement(); // End SubscribeResponse

                smw.WriteSoapMessageEnd(xmlWriter);

                // Return stream buffer
                msg.Body = xmlWriter.ToArray();
            }

            return msg;
        }
Beispiel #8
0
 /// <summary>
 /// HttpProcess()
 ///     Summary:
 ///         Main Http processor class.
 /// </summary>
 /// <param name="serviceEndpoints">A collection of service endpoints.</param>
 /// <param name="s">
 /// Socket s
 /// </param>
 public WsHttpMessageProcessor(WsServiceEndpoints serviceEndpoints)
 {
     m_serviceEndpoints = serviceEndpoints;
 }
 static Device()
 {
     m_MetadataVersion   = 1;
     m_AppSequence       = 1;
     m_MessageID         = 0;
     m_hostedServices    = new WsServiceEndpoints();
     m_appMaxDelay       = 500;
 }
Beispiel #10
0
        /// <summary>
        /// Stop tranport services and releases the managed resources used by this class.
        /// </summary>
        /// <param name="disposing">True to release managed resources</param>
        internal void Dispose(bool disposing)
        {
            if (disposing)
            {
                // Stop the transport services
                m_httpServiceHost.Stop();
                m_udpSeviceHost.Stop();

                m_threadLock = null;
                m_discoClient = null;
                m_endpointAddress = null;
                m_eventClient = null;
                m_mexClient = null;
                m_eventCallbacks = null;
                m_transportAddress = null;
                m_bodyParts = null;
                m_discoServiceEndpoints = null;
                m_callbackServiceEndpoints = null;
                m_udpSeviceHost = null;
                m_httpServiceHost = null;
            }
        }
        //private const int ReadPayload = 0x800;

        /// <summary>
        /// HttpProcess()
        ///     Summary:
        ///         Main Http processor class.
        /// </summary>
        /// <param name="serviceEndpoints">A collection of service endpoints.</param>
        /// <param name="s">
        /// Socket s
        /// </param>
        public WsHttpMessageProcessor(WsServiceEndpoints serviceEndpoints, _Bind.RequestContext context)
        {
            m_context = context;
            m_serviceEndpoints = serviceEndpoints;
        }
        /// <summary>
        /// Eventing UnSubscribe stub.
        /// </summary>
        /// <param name="header">Header object.</param>
        /// <param name="reader">An XmlReader positioned at the begining of the Unsubscribe request body element.</param>
        /// <param name="serviceEndpoints">A Collection of serviceEndpoints used to determine what services contain the specified event.</param>
        /// <returns>Byte array containing an UnSubscribe response.</returns>
        /// <remarks>This method is used by the stack framework. Do not use this method.</remarks>
        public byte[] Unsubscribe(WsWsaHeader header, XmlReader reader, WsServiceEndpoints serviceEndpoints)
        {
            // Parse Unsubscribe Request
            ///////////////////////////////
            // there's no info in Unsubscribe that we actually need, just get the identifier from header
            String eventSinkID = header.Any.GetNodeValue("Identifier", WsWellKnownUri.WseNamespaceUri);

            bool eventSourceFound = false;
            if (eventSinkID != null)
            {

                // Parse urn:uuid from the To address
                string endpointAddress = FixToAddress(header.To);

                // Iterate the list of hosted services at the specified endpoint and unsubscribe from each event source
                // that matches the eventSinkID
                for (int i = 0; i < Device.HostedServices.Count; ++i)
                {
                    if (serviceEndpoints[i].EndpointAddress == endpointAddress)
                    {

                        // Delete Subscription
                        DpwsWseEventSources eventSources = ((DpwsHostedService)Device.HostedServices[i]).EventSources;

                        // Look for matching event in hosted services event sources
                        DpwsWseEventSource eventSource;
                        DpwsWseEventSinks eventSinks;
                        DpwsWseEventSink eventSink;
                        int eventSourcesCount = eventSources.Count;
                        int eventSinksCount;
                        for (int ii = 0; ii < eventSourcesCount; ii++)
                        {
                            eventSource = eventSources[ii];
                            eventSinks = eventSource.EventSinks;
                            eventSinksCount = eventSinks.Count;
                            for (int j = 0; j < eventSinksCount; j++)
                            {
                                eventSink = eventSinks[j];
                                if (eventSink.ID == eventSinkID)
                                {
                                    eventSourceFound = true;
                                    eventSource.EventSinks.Remove(eventSink);

                                }
                            }
                        }
                    }
                }

                if (eventSourceFound)
                {
                    // Generate Response

                    MemoryStream soapStream = new MemoryStream();
                    XmlWriter xmlWriter = XmlWriter.Create(soapStream);

                    WsWsaHeader responseHeader = new WsWsaHeader(
                        WsWellKnownUri.WseNamespaceUri + "/UnsubscribeResponse",// Action
                        header.MessageID,                                       // RelatesTo
                        header.ReplyTo.Address.AbsoluteUri,                     // To
                        null, null, null);

                    WsSoapMessageWriter.WriteSoapMessageStart(xmlWriter,
                        WsSoapMessageWriter.Prefixes.Wse,                       // Prefix
                        null,                                                   // Additional Prefix
                        responseHeader,                                         // Header
                        new WsSoapMessageWriter.AppSequence(Device.AppSequence, Device.SequenceID, Device.MessageID)); // AppSequence

                    WsSoapMessageWriter.WriteSoapMessageEnd(xmlWriter);

                    // Flush and close writer. Return stream buffer
                    xmlWriter.Flush();
                    xmlWriter.Close();
                    return soapStream.ToArray();
                }
            }

            // Something went wrong
            throw new WsFaultException(header, WsFaultType.WseEventSourceUnableToProcess);
        }