private void OnUnsubscribeResponseReceived(IAsyncResult ar)
        {
            ChangeEventSubscriptionState state        = (ChangeEventSubscriptionState)ar.AsyncState;
            EventSubscription            subscription = FindEventSubscriptionByService(state.Service);

            try
            {
                HttpWebResponse response = (HttpWebResponse)state.Request.EndGetResponse(ar);
                response.Close();
            }
            catch (WebException e)
            {
                if (e.Response != null)
                {
                    e.Response.Close();
                }
            }
            lock (_cpData.SyncObj)
            {
                _pendingCalls.Remove(state);
                if (subscription != null)
                { // As we are asynchronous, the subscription might have gone already (maybe as a result of a duplicate unsubscribe event
                  // or as a result of a disposal of this instance)
                    _subscriptions.Remove(subscription.Sid);
                    CheckSubscriptionRenewalTimer(_subscriptions.Values);
                }
            }
        }
        private void OnSubscribeOrRenewSubscriptionResponseReceived(IAsyncResult ar)
        {
            ChangeEventSubscriptionState state = (ChangeEventSubscriptionState)ar.AsyncState;

            lock (_cpData.SyncObj)
                _pendingCalls.Remove(state);
            CpService service = state.Service;

            try
            {
                HttpWebResponse response = (HttpWebResponse)state.Request.EndGetResponse(ar);
                try
                {
                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        service.InvokeEventSubscriptionFailed(new UPnPError((uint)response.StatusCode, response.StatusDescription));
                        return;
                    }
                    string   dateStr    = response.Headers.Get("DATE");
                    string   sid        = response.Headers.Get("SID");
                    string   timeoutStr = response.Headers.Get("TIMEOUT");
                    DateTime date       = DateTime.ParseExact(dateStr, "R", CultureInfo.InvariantCulture).ToLocalTime();
                    int      timeout;
                    if (string.IsNullOrEmpty(timeoutStr) || (!timeoutStr.StartsWith("Second-") ||
                                                             !int.TryParse(timeoutStr.Substring("Second-".Length).Trim(), out timeout)))
                    {
                        service.InvokeEventSubscriptionFailed(new UPnPError((int)HttpStatusCode.BadRequest, "Invalid answer from UPnP device"));
                        return;
                    }
                    DateTime          expiration = date.AddSeconds(timeout);
                    EventSubscription subscription;
                    lock (_cpData.SyncObj)
                    {
                        if (_subscriptions.TryGetValue(sid, out subscription))
                        {
                            subscription.Expiration = expiration;
                        }
                        else
                        {
                            _subscriptions.Add(sid, new EventSubscription(sid, state.ServiceDescriptor, service, expiration));
                        }
                        CheckSubscriptionRenewalTimer(_subscriptions.Values);
                    }
                }
                finally
                {
                    response.Close();
                }
            }
            catch (WebException e)
            {
                HttpWebResponse response = (HttpWebResponse)e.Response;
                service.InvokeEventSubscriptionFailed(new UPnPError(response == null ? 503 : (uint)response.StatusCode, "Cannot complete event subscription"));
                if (response != null)
                {
                    response.Close();
                }
                return;
            }
        }
 internal void UnsubscribeEvents(EventSubscription subscription)
 {
     lock (_cpData.SyncObj)
     {
         HttpWebRequest request             = CreateEventUnsubscribeRequest(subscription);
         ChangeEventSubscriptionState state = new ChangeEventSubscriptionState(subscription.ServiceDescriptor, subscription.Service, request);
         _pendingCalls.Add(state);
         IAsyncResult result = state.Request.BeginGetResponse(OnUnsubscribeResponseReceived, state);
         NetworkHelper.AddTimeout(request, result, EVENT_UNSUBSCRIPTION_CALL_TIMEOUT * 1000);
     }
 }
Пример #4
0
 internal void SubscribeEvents(CpService service, ServiceDescriptor serviceDescriptor)
 {
     using (_cpData.Lock.EnterWrite())
     {
         HttpWebRequest request             = CreateEventSubscribeRequest(serviceDescriptor);
         ChangeEventSubscriptionState state = new ChangeEventSubscriptionState(serviceDescriptor, service, request);
         _pendingCalls.Add(state);
         IAsyncResult result = state.Request.BeginGetResponse(OnSubscribeOrRenewSubscriptionResponseReceived, state);
         NetworkHelper.AddTimeout(request, result, EVENT_SUBSCRIPTION_CALL_TIMEOUT * 1000);
     }
 }
        protected void RenewEventSubscription(EventSubscription subscription)
        {
            if (!subscription.Service.IsConnected)
            {
                throw new IllegalCallException("Service '{0}' is not connected to a UPnP network service", subscription.Service.FullQualifiedName);
            }

            lock (_cpData.SyncObj)
            {
                HttpWebRequest request             = CreateRenewEventSubscribeRequest(subscription);
                ChangeEventSubscriptionState state = new ChangeEventSubscriptionState(subscription.ServiceDescriptor, subscription.Service, request);
                _pendingCalls.Add(state);
                IAsyncResult result = state.Request.BeginGetResponse(OnSubscribeOrRenewSubscriptionResponseReceived, state);
                NetworkHelper.AddTimeout(request, result, EVENT_SUBSCRIPTION_CALL_TIMEOUT * 1000);
            }
        }
Пример #6
0
 internal void UnsubscribeEvents(EventSubscription subscription)
 {
   lock (_cpData.SyncObj)
   {
     HttpWebRequest request = CreateEventUnsubscribeRequest(subscription);
     ChangeEventSubscriptionState state = new ChangeEventSubscriptionState(subscription.ServiceDescriptor, subscription.Service, request);
     _pendingCalls.Add(state);
     IAsyncResult result = state.Request.BeginGetResponse(OnUnsubscribeResponseReceived, state);
     NetworkHelper.AddTimeout(request, result, EVENT_UNSUBSCRIPTION_CALL_TIMEOUT * 1000);
   }
 }
Пример #7
0
    protected void RenewEventSubscription(EventSubscription subscription)
    {
      if (!subscription.Service.IsConnected)
        throw new IllegalCallException("Service '{0}' is not connected to a UPnP network service", subscription.Service.FullQualifiedName);

      lock (_cpData.SyncObj)
      {
        HttpWebRequest request = CreateRenewEventSubscribeRequest(subscription);
        ChangeEventSubscriptionState state = new ChangeEventSubscriptionState(subscription.ServiceDescriptor, subscription.Service, request);
        _pendingCalls.Add(state);
        IAsyncResult result = state.Request.BeginGetResponse(OnSubscribeOrRenewSubscriptionResponseReceived, state);
        NetworkHelper.AddTimeout(request, result, EVENT_SUBSCRIPTION_CALL_TIMEOUT * 1000);
      }
    }
        private void OnSubscribeOrRenewSubscriptionResponseReceived(IAsyncResult ar)
        {
            ChangeEventSubscriptionState state = (ChangeEventSubscriptionState)ar.AsyncState;

            lock (_cpData.SyncObj)
                _pendingCalls.Remove(state);
            CpService service = state.Service;

            try
            {
                HttpWebResponse response = (HttpWebResponse)state.Request.EndGetResponse(ar);
                try
                {
                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        service.InvokeEventSubscriptionFailed(new UPnPError((uint)response.StatusCode, response.StatusDescription));
                        return;
                    }
                    string dateStr    = response.Headers.Get("DATE");
                    string sid        = response.Headers.Get("SID");
                    string timeoutStr = response.Headers.Get("TIMEOUT");
                    int    timeout;
                    if (string.IsNullOrEmpty(timeoutStr) || (!timeoutStr.StartsWith("Second-") ||
                                                             !int.TryParse(timeoutStr.Substring("Second-".Length).Trim(), out timeout)))
                    {
                        service.InvokeEventSubscriptionFailed(new UPnPError((int)HttpStatusCode.BadRequest, "Invalid answer from UPnP device"));
                        return;
                    }

                    // The date header is not always available, and it is not always accurate either.
                    DateTime date = DateTime.Now;
                    try
                    {
                        date = DateTime.ParseExact(dateStr, "R", CultureInfo.InvariantCulture).ToLocalTime();
                    }
                    catch { }

                    DateTime expiration = date.AddSeconds(timeout);
                    if (expiration < DateTime.Now)
                    {
                        // If the timeout is in the past already, assume it is invalid and estimate
                        // the timeout timestamp. This workaround is necessary for devices that do
                        // not have their date set correctly (so the DATE header is unusable).
                        expiration = DateTime.Now.AddSeconds(timeout);
                    }

                    EventSubscription subscription;
                    lock (_cpData.SyncObj)
                    {
                        if (_subscriptions.TryGetValue(sid, out subscription))
                        {
                            subscription.Expiration = expiration;
                        }
                        else
                        {
                            _subscriptions.Add(sid, new EventSubscription(sid, state.ServiceDescriptor, service, expiration));
                        }
                        CheckSubscriptionRenewalTimer(_subscriptions.Values);
                    }
                }
                finally
                {
                    response.Close();
                }
            }
            catch (WebException e)
            {
                HttpWebResponse response = (HttpWebResponse)e.Response;
                service.InvokeEventSubscriptionFailed(new UPnPError(response == null ? 503 : (uint)response.StatusCode, "Cannot complete event subscription"));
                if (response != null)
                {
                    response.Close();
                }
            }
        }