Example #1
0
 /// <summary>
 /// Stops this UPnP network tracker's activity, i.e. closes the UPnP network listener and clears all
 /// <see cref="KnownRootDevices"/>.
 /// </summary>
 public void Close()
 {
     lock (_cpData.SyncObj)
     {
         if (!_active)
         {
             return;
         }
         _active = false;
         foreach (RootEntry entry in _cpData.SSDPController.RootEntries)
         {
             RootDescriptor rd = GetRootDescriptor(entry);
             if (rd == null)
             {
                 continue;
             }
             InvalidateDescriptor(rd);
         }
         SSDPClientController ssdpController = _cpData.SSDPController;
         ssdpController.Close();
         ssdpController.RootDeviceAdded            -= OnSSDPRootDeviceAdded;
         ssdpController.RootDeviceRemoved          -= OnSSDPRootDeviceRemoved;
         ssdpController.DeviceRebooted             -= OnSSDPDeviceRebooted;
         ssdpController.DeviceConfigurationChanged -= OnSSDPDeviceConfigurationChanged;
         _cpData.SSDPController = null;
         foreach (DescriptionRequestState state in _pendingRequests)
         {
             state.Request.Abort();
         }
         _pendingRequests.Clear();
     }
 }
        private void OnServiceDescriptionReceived(IAsyncResult asyncResult)
        {
            DescriptionRequestState state   = (DescriptionRequestState)asyncResult.AsyncState;
            RootDescriptor          rd      = state.RootDescriptor;
            HttpWebRequest          request = state.Request;

            try
            {
                using (WebResponse response = request.EndGetResponse(asyncResult))
                {
                    using (_cpData.Lock.EnterRead())
                        if (rd.State != RootDescriptorState.AwaitingServiceDescriptions)
                        {
                            return;
                        }
                    try
                    {
                        using (Stream body = CompressionHelper.Decompress(response))
                        {
                            XPathDocument xmlServiceDescription = new XPathDocument(body);
                            state.CurrentServiceDescriptor.ServiceDescription = xmlServiceDescription;
                            state.CurrentServiceDescriptor.State = ServiceDescriptorState.Ready;
                        }
                    }
                    catch (Exception) // Don't log exceptions at this low protocol level
                    {
                        using (_cpData.Lock.EnterWrite())
                        {
                            state.CurrentServiceDescriptor.State = ServiceDescriptorState.Erroneous;
                            rd.State = RootDescriptorState.Erroneous;
                        }
                    }
                    finally
                    {
                        response.Close();
                    }
                }
            }
            catch (WebException e)
            {
                state.CurrentServiceDescriptor.State = ServiceDescriptorState.Erroneous;
                using (_cpData.Lock.EnterWrite())
                    rd.State = RootDescriptorState.Erroneous;
                if (e.Response != null)
                {
                    e.Response.Close();
                }
            }

            // Don't hold the lock while calling ContinueGetServiceDescription - that method is calling event handlers
            try
            {
                ContinueGetServiceDescription(state);
            }
            catch (Exception) // Don't log exceptions at this low protocol level
            {
                using (_cpData.Lock.EnterWrite())
                    rd.State = RootDescriptorState.Erroneous;
            }
        }
Example #3
0
        protected void InitializeRootDescriptor(RootEntry rootEntry)
        {
            RootDescriptor rd = new RootDescriptor(rootEntry)
            {
                State = RootDescriptorState.AwaitingDeviceDescription
            };

            lock (_cpData.SyncObj)
                SetRootDescriptor(rootEntry, rd);
            try
            {
                LinkData                preferredLink = rootEntry.PreferredLink;
                HttpWebRequest          request       = CreateHttpGetRequest(new Uri(preferredLink.DescriptionLocation), preferredLink.Endpoint.EndPointIPAddress);
                DescriptionRequestState state         = new DescriptionRequestState(rd, request);
                lock (_cpData.SyncObj)
                    _pendingRequests.Add(state);
                IAsyncResult result = request.BeginGetResponse(OnDeviceDescriptionReceived, state);
                NetworkHelper.AddTimeout(request, result, PENDING_REQUEST_TIMEOUT * 1000);
            }
            catch (Exception) // Don't log messages at this low protocol level
            {
                lock (_cpData.SyncObj)
                    rd.State = RootDescriptorState.Erroneous;
            }
        }
Example #4
0
 private void HandleDeviceConfigurationChanged(RootDescriptor rootDescriptor)
 {
     // Configuration changes cannot be given to our clients because they need a re-initialization of the
     // device and all service description documents. So configuration changes will be handled by invocing a
     // root device remove/add event combination. The add event will be fired when the initialization of the root descriptor has finished.
     InvokeRootDeviceRemoved(rootDescriptor);
     InitializeRootDescriptor(rootDescriptor.SSDPRootEntry);
 }
 protected DeviceConnection DoConnect(RootDescriptor descriptor, string deviceUuid, DataTypeResolverDlgt dataTypeResolver, bool useHttpKeepAlive = true)
 {
     lock (_cpData.SyncObj)
     {
         DeviceConnection connection = new DeviceConnection(this, descriptor, deviceUuid, _cpData, dataTypeResolver, useHttpKeepAlive);
         _connectedDevices.Add(deviceUuid, connection);
         return(connection);
     }
 }
Example #6
0
 public static ServerDescriptor GetMPBackendServerDescriptor(RootDescriptor uPnPRootDescriptor)
 {
   DeviceDescriptor rootDescriptor = DeviceDescriptor.CreateRootDeviceDescriptor(uPnPRootDescriptor);
   if (rootDescriptor == null)
     return null;
   DeviceDescriptor serverDeviceDescriptor = rootDescriptor.FindFirstDevice(
       UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE_VERSION);
   return serverDeviceDescriptor == null ? null : new ServerDescriptor(serverDeviceDescriptor);
 }
Example #7
0
        private void OnSSDPDeviceConfigurationChanged(RootEntry rootEntry)
        {
            RootDescriptor rd = GetRootDescriptor(rootEntry);

            if (rd == null)
            {
                return;
            }
            HandleDeviceConfigurationChanged(rd);
        }
 private void OnDeviceRebooted(RootDescriptor rootdescriptor)
 {
     foreach (DeviceConnection connection in _connectedDevices.Values)
     {
         if (connection.RootDescriptor == rootdescriptor)
         {
             connection.OnDeviceRebooted();
         }
     }
 }
Example #9
0
 protected void InvalidateDescriptor(RootDescriptor rd)
 {
     rd.State = RootDescriptorState.Invalid;
     foreach (IDictionary <string, ServiceDescriptor> sdDict in rd.ServiceDescriptors.Values)
     {
         foreach (ServiceDescriptor sd in sdDict.Values)
         {
             sd.State = ServiceDescriptorState.Invalid;
         }
     }
 }
Example #10
0
 /// <summary>
 /// Creates a new <see cref="DeviceConnection"/> to the UPnP device contained in the given
 /// <paramref name="rootDescriptor"/> with the given <paramref name="deviceUuid"/>.
 /// </summary>
 /// <param name="controlPoint">Control point hosting the new device connection instance.</param>
 /// <param name="rootDescriptor">Root descriptor containing the description of the UPnP device to connect.</param>
 /// <param name="deviceUuid">UUID of the UPnP device to connect.</param>
 /// <param name="cpData">Shared control point data structure.</param>
 /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param>
 public DeviceConnection(UPnPControlPoint controlPoint, RootDescriptor rootDescriptor, string deviceUuid,
                         CPData cpData, DataTypeResolverDlgt dataTypeResolver)
 {
     _controlPoint         = controlPoint;
     _cpData               = cpData;
     _rootDescriptor       = rootDescriptor;
     _deviceUUID           = deviceUuid;
     _genaClientController = new GENAClientController(_cpData, this, rootDescriptor.SSDPRootEntry.PreferredLink.Endpoint, rootDescriptor.SSDPRootEntry.UPnPVersion);
     BuildDeviceProxy(rootDescriptor, deviceUuid, dataTypeResolver);
     _genaClientController.Start();
 }
Example #11
0
        /// <summary>
        /// Establishes the actual device connection by building the control point's proxy device tree corresponding to the
        /// device contained in the given <paramref name="rootDescriptor"/> specified by its <paramref name="deviceUUID"/>.
        /// </summary>
        /// <param name="rootDescriptor">Root descriptor which contains the device to build.</param>
        /// <param name="deviceUUID">UUID of the device to connect.</param>
        /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param>
        private void BuildDeviceProxy(RootDescriptor rootDescriptor, string deviceUUID, DataTypeResolverDlgt dataTypeResolver)
        {
            if (rootDescriptor.State != RootDescriptorState.Ready)
            {
                throw new ArgumentException("Root descriptor is not ready - cannot connect");
            }
            DeviceDescriptor rootDeviceDescriptor = DeviceDescriptor.CreateRootDeviceDescriptor(rootDescriptor);
            DeviceDescriptor deviceDescriptor     = rootDeviceDescriptor.FindDevice(deviceUUID);

            _device = CpDevice.ConnectDevice(this, deviceDescriptor, dataTypeResolver);
        }
Example #12
0
        private void OnSSDPRootDeviceRemoved(RootEntry rootEntry)
        {
            RootDescriptor rd = GetRootDescriptor(rootEntry);

            if (rd == null)
            {
                return;
            }
            lock (_cpData.SyncObj)
                InvalidateDescriptor(rd);
            InvokeRootDeviceRemoved(rd);
        }
        private void OnSSDPRootDeviceRemoved(RootEntry rootEntry)
        {
            RootDescriptor rd = GetRootDescriptor(rootEntry);

            if (rd == null)
            {
                return;
            }
            using (_cpData.Lock.EnterWrite())
                InvalidateDescriptor(rd);
            InvokeRootDeviceRemoved(rd);
        }
Example #14
0
        private void OnDeviceDescriptionReceived(IAsyncResult asyncResult)
        {
            DescriptionRequestState state   = (DescriptionRequestState)asyncResult.AsyncState;
            RootDescriptor          rd      = state.RootDescriptor;
            HttpWebRequest          request = state.Request;

            try
            {
                WebResponse response = request.EndGetResponse(asyncResult);
                if (rd.State != RootDescriptorState.AwaitingDeviceDescription)
                {
                    return;
                }
                try
                {
                    using (Stream body = CompressionHelper.Decompress(response))
                    {
                        XPathDocument xmlDeviceDescription = new XPathDocument(body);
                        lock (_cpData.SyncObj)
                        {
                            rd.DeviceDescription = xmlDeviceDescription;
                            DeviceDescriptor rootDeviceDescriptor = DeviceDescriptor.CreateRootDeviceDescriptor(rd);
                            if (rootDeviceDescriptor == null)
                            { // No root device description available
                                rd.State = RootDescriptorState.Erroneous;
                                return;
                            }

                            ExtractServiceDescriptorsRecursive(rootDeviceDescriptor, rd.ServiceDescriptors, state.PendingServiceDescriptions);
                            rd.State = RootDescriptorState.AwaitingServiceDescriptions;
                        }
                    }
                    ContinueGetServiceDescription(state);
                }
                catch (Exception) // Don't log exceptions at this low protocol level
                {
                    rd.State = RootDescriptorState.Erroneous;
                }
                finally
                {
                    response.Close();
                }
            }
            catch (WebException e)
            {
                rd.State = RootDescriptorState.Erroneous;
                if (e.Response != null)
                {
                    e.Response.Close();
                }
            }
        }
Example #15
0
 protected void InvokeDeviceRebooted(RootDescriptor rd)
 {
     try
     {
         DeviceRebootedDlgt dlgt = DeviceRebooted;
         if (dlgt != null)
         {
             dlgt(rd);
         }
     }
     catch (Exception e)
     {
         UPnPConfiguration.LOGGER.Warn("UPnPNetworkTracker: Error invoking DeviceRebooted delegate", e);
     }
 }
        private void ContinueGetServiceDescription(DescriptionRequestState state)
        {
            RootDescriptor rootDescriptor = state.RootDescriptor;

            IEnumerator <ServiceDescriptor> enumer = state.PendingServiceDescriptions.GetEnumerator();

            if (!enumer.MoveNext())
            {
                using (_cpData.Lock.EnterWrite())
                {
                    if (rootDescriptor.State != RootDescriptorState.AwaitingServiceDescriptions)
                    {
                        return;
                    }
                    _pendingRequests.Remove(state);
                    rootDescriptor.State = RootDescriptorState.Ready;
                }
                // This event is needed for two cases: 1) "Normal" first device advertisement, 2) configuration change event (see comment in method HandleDeviceConfigurationChanged)
                InvokeRootDeviceAdded(rootDescriptor);
            }
            else
            {
                using (_cpData.Lock.EnterRead())
                    if (rootDescriptor.State != RootDescriptorState.AwaitingServiceDescriptions)
                    {
                        return;
                    }

                state.CurrentServiceDescriptor = enumer.Current;
                string url = state.CurrentServiceDescriptor.DescriptionURL;
                state.PendingServiceDescriptions.Remove(state.CurrentServiceDescriptor);
                state.CurrentServiceDescriptor.State = ServiceDescriptorState.AwaitingDescription;
                try
                {
                    LinkData       preferredLink = rootDescriptor.SSDPRootEntry.PreferredLink;
                    HttpWebRequest request       = CreateHttpGetRequest(new Uri(new Uri(preferredLink.DescriptionLocation), url),
                                                                        preferredLink.Endpoint.EndPointIPAddress);
                    state.Request = request;
                    IAsyncResult result = request.BeginGetResponse(OnServiceDescriptionReceived, state);
                    NetworkHelper.AddTimeout(request, result, PENDING_REQUEST_TIMEOUT * 1000);
                }
                catch (Exception) // Don't log exceptions at this low protocol level
                {
                    using (_cpData.Lock.EnterWrite())
                        state.CurrentServiceDescriptor.State = ServiceDescriptorState.Erroneous;
                }
            }
        }
Example #17
0
 void OnUPnPRootDeviceAdded(RootDescriptor rootDescriptor)
 {
   ICollection<ServerDescriptor> availableServers;
   lock (_networkTracker.SharedControlPointData.SyncObj)
   {
     ServerDescriptor serverDescriptor = ServerDescriptor.GetMPBackendServerDescriptor(rootDescriptor);
     if (serverDescriptor == null || _availableServers.Contains(serverDescriptor))
       return;
     SystemName preferredLink = serverDescriptor.GetPreferredLink();
     ServiceRegistration.Get<ILogger>().Debug("UPnPServerWatcher: Found MediaPortal 2 BackendServer '{0}' at host '{1}' (IP address: '{2}')",
         serverDescriptor.ServerName, preferredLink.HostName, preferredLink.Address);
     _availableServers.Add(serverDescriptor);
     availableServers = _availableServers;
   }
   InvokeAvailableBackendServersChanged(availableServers, true);
 }
Example #18
0
        private void OnSSDPDeviceRebooted(RootEntry rootEntry, bool configurationChanged)
        {
            RootDescriptor rd = GetRootDescriptor(rootEntry);

            if (rd == null)
            {
                return;
            }
            if (configurationChanged)
            {
                HandleDeviceConfigurationChanged(rd);
            }
            else
            {
                InvokeDeviceRebooted(rd);
            }
        }
 protected IResourceInformationService TryGetResourceInformationService(RootDescriptor rootDescriptor)
 {
   DeviceConnection connection;
   lock (_networkTracker.SharedControlPointData.SyncObj)
   {
     object service;
     if (rootDescriptor.SSDPRootEntry.ClientProperties.TryGetValue(KEY_RESOURCE_INFORMATION_SERVICE, out service))
       return service as IResourceInformationService;
   }
   DeviceDescriptor rootDevice = DeviceDescriptor.CreateRootDeviceDescriptor(rootDescriptor);
   DeviceDescriptor frontendServerDevice = rootDevice.FindFirstDevice(
       UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE_VERSION) ??
           rootDevice.FindFirstDevice(UPnPTypesAndIds.FRONTEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.FRONTEND_SERVER_DEVICE_TYPE_VERSION);
   if (frontendServerDevice == null)
     return null;
   string deviceUuid = frontendServerDevice.DeviceUUID;
   try
   {
     connection = _controlPoint.Connect(rootDescriptor, deviceUuid, UPnPExtendedDataTypes.ResolveDataType);
   }
   catch (Exception e)
   {
     ServiceRegistration.Get<ILogger>().Warn("Error connecting to UPnP MP2 device '{0}'", e, deviceUuid);
     return null;
   }
   try
   {
     CpService rasStub = connection.Device.FindServiceByServiceId(UPnPTypesAndIds.RESOURCE_INFORMATION_SERVICE_ID);
     if (rasStub == null)
       throw new InvalidDataException("ResourceAccess service not found in device '{0}'", deviceUuid);
     IResourceInformationService ris = new UPnPResourceInformationServiceProxy(rasStub);
     lock (_networkTracker.SharedControlPointData.SyncObj)
       rootDescriptor.SSDPRootEntry.ClientProperties[KEY_RESOURCE_INFORMATION_SERVICE] = ris;
     return ris;
   }
   catch (Exception e)
   {
     ServiceRegistration.Get<ILogger>().Warn("Error connecting to services of UPnP MP2 device '{0}'", e, deviceUuid);
     _controlPoint.Disconnect(deviceUuid);
     return null;
   }
 }
Example #20
0
 /// <summary>
 /// Connects to the device of the given <paramref name="deviceUuid"/> specified in the <paramref name="rootDescriptor"/>.
 /// </summary>
 /// <param name="rootDescriptor">UPnP root descriptor to connect.</param>
 /// <param name="deviceUuid">UUID of the device in the root descriptor which is the node to connect.</param>
 /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param>
 /// <param name="useHttpKeepAlive"><c>True</c> to set the HTTP keep-alive header in action requests sent over the connection, otherwise <c>false</c>.</param>
 /// <exception cref="ArgumentException">
 /// <list type="bullet">
 /// <item>If the device with the specified <paramref name="deviceUuid"/> isn't present
 /// in the given <paramref name="rootDescriptor"/></item>
 /// <item>If the given <paramref name="rootDescriptor"/> has is in an erroneous state
 /// (<c><see cref="RootDescriptor.State"/> == <see cref="RootDescriptorState.Erroneous"/></c>)</item>
 /// <item>If the given <paramref name="rootDescriptor"/> contains erroneous data, e.g. erroneous device or
 /// service descriptions</item>
 /// </list>
 /// </exception>
 public DeviceConnection Connect(RootDescriptor rootDescriptor, string deviceUuid, DataTypeResolverDlgt dataTypeResolver, bool useHttpKeepAlive = true)
 {
   return DoConnect(rootDescriptor, deviceUuid, dataTypeResolver, useHttpKeepAlive);
 }
Example #21
0
 protected DeviceConnection DoConnect(RootDescriptor descriptor, string deviceUuid, DataTypeResolverDlgt dataTypeResolver, bool useHttpKeepAlive = true)
 {
   lock (_cpData.SyncObj)
   {
     DeviceConnection connection = new DeviceConnection(this, descriptor, deviceUuid, _cpData, dataTypeResolver, useHttpKeepAlive);
     _connectedDevices.Add(deviceUuid, connection);
     return connection;
   }
 }
Example #22
0
 private void OnDeviceRebooted(RootDescriptor rootdescriptor)
 {
   foreach (DeviceConnection connection in _connectedDevices.Values)
     if (connection.RootDescriptor == rootdescriptor)
       connection.OnDeviceRebooted();
 }
Example #23
0
 private void OnRootDeviceRemoved(RootDescriptor rootdescriptor)
 {
   DoDisconnect(rootdescriptor.SSDPRootEntry.RootDeviceUUID, false);
 }
 void OnUPnPRootDeviceRemoved(RootDescriptor rootDescriptor)
 {
   ClientDescriptor clientDescriptor;
   lock (_networkTracker.SharedControlPointData.SyncObj)
   {
     clientDescriptor = ClientDescriptor.GetMPFrontendServerDescriptor(rootDescriptor);
     if (clientDescriptor == null || !_availableClients.Contains(clientDescriptor))
       return;
     ServiceRegistration.Get<ILogger>().Debug("UPnPServerControlPoint: MP2 client '{0}' (system ID '{1}') at host '{2}' was removed from the network",
         clientDescriptor.ClientName, clientDescriptor.MPFrontendServerUUID, clientDescriptor.System.HostName);
     _availableClients.Remove(clientDescriptor);
   }
   InvokeClientUnavailable(clientDescriptor);
   // The client connection has its own event handler for disconnects - it will trigger method OnClientDisconnected
   // as result of disconnection, this will remove the client connection from the _clientConnections collection
 }
Example #25
0
    private void OnUpnpRootDeviceRemoved(RootDescriptor rootDescriptor)
    {
      if (rootDescriptor == null)
      {
        return;
      }

      _knownUpnpDevices.Remove(rootDescriptor.SSDPRootEntry.RootDeviceUUID);
      DeviceDescriptor deviceDescriptor = DeviceDescriptor.CreateRootDeviceDescriptor(rootDescriptor);
      IEnumerator<DeviceEntry> childDeviceEn = rootDescriptor.SSDPRootEntry.Devices.Values.GetEnumerator();
      bool isFirst = true;
      while (childDeviceEn.MoveNext())
      {
        foreach (string serviceUrn in childDeviceEn.Current.Services)
        {
          if (serviceUrn.Equals("urn:schemas-opencable-com:service:Tuner:1"))
          {
            if (isFirst)
            {
              isFirst = false;
              Log.Log.Info("UPnP device {0} removed", deviceDescriptor.FriendlyName);
            }

            IEnumerator<DeviceDescriptor> childDeviceDescriptorEn = deviceDescriptor.ChildDevices.GetEnumerator();
            while (childDeviceDescriptorEn.MoveNext())
            {
              if (childDeviceDescriptorEn.Current.DeviceUUID == childDeviceEn.Current.UUID)
              {
                break;
              }
            }
            Log.Log.Info("  remove {0} {1}", childDeviceDescriptorEn.Current.FriendlyName, childDeviceDescriptorEn.Current.DeviceUDN);
            _deviceEventListener.OnDeviceRemoved(childDeviceDescriptorEn.Current.DeviceUDN);
            break;
          }
        }
      }
    }
Example #26
0
 private void networkTracker_RootDeviceRemoved(RootDescriptor rootdescriptor)
 {
   ExecuteInUIThread(UpdateTreeView);
 }
 private void OnRootDeviceRemoved(RootDescriptor rootdescriptor)
 {
     DoDisconnect(rootdescriptor.SSDPRootEntry.RootDeviceUUID, false);
 }
 /// <summary>
 /// Creates a new <see cref="DeviceConnection"/> to the UPnP device contained in the given
 /// <paramref name="rootDescriptor"/> with the given <paramref name="deviceUuid"/>.
 /// </summary>
 /// <param name="controlPoint">Control point hosting the new device connection instance.</param>
 /// <param name="rootDescriptor">Root descriptor containing the description of the UPnP device to connect.</param>
 /// <param name="deviceUuid">UUID of the UPnP device to connect.</param>
 /// <param name="cpData">Shared control point data structure.</param>
 /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param>
 /// <param name="useHttpKeepAlive"><c>True</c> to set the HTTP keep-alive header in action requests sent over the connection, otherwise <c>false</c>.</param>
 public DeviceConnection(UPnPControlPoint controlPoint, RootDescriptor rootDescriptor, string deviceUuid,
     CPData cpData, DataTypeResolverDlgt dataTypeResolver, bool useHttpKeepAlive = true)
 {
   _controlPoint = controlPoint;
   _cpData = cpData;
   _rootDescriptor = rootDescriptor;
   _deviceUUID = deviceUuid;
   _useHttpKeepAlive = useHttpKeepAlive;
   _genaClientController = new GENAClientController(_cpData, this, rootDescriptor.SSDPRootEntry.PreferredLink.Endpoint, rootDescriptor.SSDPRootEntry.UPnPVersion);
   BuildDeviceProxy(rootDescriptor, deviceUuid, dataTypeResolver);
   _genaClientController.Start();
 }
 void OnUPnPRootDeviceAdded(RootDescriptor rootDescriptor)
 {
   TryConnect(rootDescriptor);
 }
 protected void SetRootDescriptor(RootEntry rootEntry, RootDescriptor rootDescriptor)
 {
   rootEntry.ClientProperties[KEY_ROOT_DESCRIPTOR] = rootDescriptor;
 }
 /// <summary>
 /// Connects to the device of the given <paramref name="deviceUuid"/> specified in the <paramref name="rootDescriptor"/>.
 /// </summary>
 /// <param name="rootDescriptor">UPnP root descriptor to connect.</param>
 /// <param name="deviceUuid">UUID of the device in the root descriptor which is the node to connect.</param>
 /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param>
 /// <param name="useHttpKeepAlive"><c>True</c> to set the HTTP keep-alive header in action requests sent over the connection, otherwise <c>false</c>.</param>
 /// <exception cref="ArgumentException">
 /// <list type="bullet">
 /// <item>If the device with the specified <paramref name="deviceUuid"/> isn't present
 /// in the given <paramref name="rootDescriptor"/></item>
 /// <item>If the given <paramref name="rootDescriptor"/> has is in an erroneous state
 /// (<c><see cref="RootDescriptor.State"/> == <see cref="RootDescriptorState.Erroneous"/></c>)</item>
 /// <item>If the given <paramref name="rootDescriptor"/> contains erroneous data, e.g. erroneous device or
 /// service descriptions</item>
 /// </list>
 /// </exception>
 public DeviceConnection Connect(RootDescriptor rootDescriptor, string deviceUuid, DataTypeResolverDlgt dataTypeResolver, bool useHttpKeepAlive = true)
 {
     return(DoConnect(rootDescriptor, deviceUuid, dataTypeResolver, useHttpKeepAlive));
 }
 public DescriptionRequestState(RootDescriptor rootDescriptor, HttpWebRequest httpWebRequest)
 {
   _rootDescriptor = rootDescriptor;
   _httpWebRequest = httpWebRequest;
 }
Example #33
0
    private void OnUpnpRootDeviceAdded(RootDescriptor rootDescriptor)
    {
      if (rootDescriptor == null || rootDescriptor.State != RootDescriptorState.Ready || _knownUpnpDevices.Contains(rootDescriptor.SSDPRootEntry.RootDeviceUUID))
      {
        return;
      }

      _knownUpnpDevices.Add(rootDescriptor.SSDPRootEntry.RootDeviceUUID);
      DeviceDescriptor deviceDescriptor = DeviceDescriptor.CreateRootDeviceDescriptor(rootDescriptor);
      IEnumerator<DeviceEntry> childDeviceEn = rootDescriptor.SSDPRootEntry.Devices.Values.GetEnumerator();
      bool isFirst = true;
      while (childDeviceEn.MoveNext())
      {
        foreach (string serviceUrn in childDeviceEn.Current.Services)
        {
          // Supported device?
          if (serviceUrn.Equals("urn:schemas-opencable-com:service:Tuner:1"))
          {
            if (isFirst)
            {
              isFirst = false;
              Log.Log.Info("Detected new OCUR/DRI device {0}", deviceDescriptor.FriendlyName);
            }

            // Find the corresponding DeviceDescriptor.
            IEnumerator<DeviceDescriptor> childDeviceDescriptorEn = deviceDescriptor.ChildDevices.GetEnumerator();
            while (childDeviceDescriptorEn.MoveNext())
            {
              if (childDeviceDescriptorEn.Current.DeviceUUID == childDeviceEn.Current.UUID)
              {
                break;
              }
            }
            Log.Log.Info("  add {0} {1}", childDeviceDescriptorEn.Current.FriendlyName, childDeviceDescriptorEn.Current.DeviceUDN);
            _deviceEventListener.OnDeviceAdded(new TunerDri(childDeviceDescriptorEn.Current, _upnpControlPoint));
            break;
          }
        }
      }
    }
 /// <summary>
 /// Connects to the device of the given <paramref name="deviceUuid"/> specified in the <paramref name="rootDescriptor"/>.
 /// </summary>
 /// <param name="rootDescriptor">UPnP root descriptor to connect.</param>
 /// <param name="deviceUuid">UUID of the device in the root descriptor which is the node to connect.</param>
 /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param>
 /// <exception cref="ArgumentException">
 /// <list type="bullet">
 /// <item>If the device with the specified <paramref name="deviceUuid"/> isn't present
 /// in the given <paramref name="rootDescriptor"/></item>
 /// <item>If the given <paramref name="rootDescriptor"/> has is in an erroneous state
 /// (<c><see cref="RootDescriptor.State"/> == <see cref="RootDescriptorState.Erroneous"/></c>)</item>
 /// <item>If the given <paramref name="rootDescriptor"/> contains erroneous data, e.g. erroneous device or
 /// service descriptions</item>
 /// </list>
 /// </exception>
 public DeviceConnection Connect(RootDescriptor rootDescriptor, string deviceUuid, DataTypeResolverDlgt dataTypeResolver)
 {
     return(DoConnect(rootDescriptor, deviceUuid, dataTypeResolver));
 }
 /// <summary>
 /// Establishes the actual device connection by building the control point's proxy device tree corresponding to the
 /// device contained in the given <paramref name="rootDescriptor"/> specified by its <paramref name="deviceUUID"/>.
 /// </summary>
 /// <param name="rootDescriptor">Root descriptor which contains the device to build.</param>
 /// <param name="deviceUUID">UUID of the device to connect.</param>
 /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param>
 private void BuildDeviceProxy(RootDescriptor rootDescriptor, string deviceUUID, DataTypeResolverDlgt dataTypeResolver)
 {
   if (rootDescriptor.State != RootDescriptorState.Ready)
     throw new ArgumentException("Root descriptor is not ready - cannot connect");
   DeviceDescriptor rootDeviceDescriptor = DeviceDescriptor.CreateRootDeviceDescriptor(rootDescriptor);
   DeviceDescriptor deviceDescriptor = rootDeviceDescriptor.FindDevice(deviceUUID);
   _device = CpDevice.ConnectDevice(this, deviceDescriptor, dataTypeResolver);
 }
 protected void InvalidateDescriptor(RootDescriptor rd)
 {
   rd.State = RootDescriptorState.Invalid;
   foreach (IDictionary<string, ServiceDescriptor> sdDict in rd.ServiceDescriptors.Values)
     foreach (ServiceDescriptor sd in sdDict.Values)
       sd.State = ServiceDescriptorState.Invalid;
 }
    protected void TryConnect(RootDescriptor rootDescriptor)
    {
      DeviceConnection connection;
      string deviceUuid;
      lock (_networkTracker.SharedControlPointData.SyncObj)
      {
        if (_connection != null)
          return;
        DeviceDescriptor rootDeviceDescriptor = DeviceDescriptor.CreateRootDeviceDescriptor(rootDescriptor);
        DeviceDescriptor backendServerDescriptor = rootDeviceDescriptor.FindFirstDevice(
            UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE_VERSION);
        if (backendServerDescriptor == null)
          return;
        deviceUuid = backendServerDescriptor.DeviceUUID;
        string friendlyName = backendServerDescriptor.FriendlyName;
        SystemName system = new SystemName(new Uri(rootDescriptor.SSDPRootEntry.PreferredLink.DescriptionLocation).Host);
        if (deviceUuid == _homeServerSystemId)
          ServiceRegistration.Get<ILogger>().Debug("UPnPClientControlPoint: Found MP2 home server '{0}' (system ID '{1}') at host '{2}' (IP address: '{3}')",
              friendlyName, deviceUuid, system.HostName, system.Address);
        else
        {
          ServiceRegistration.Get<ILogger>().Debug("UPnPClientControlPoint: Found foreign MP2 server '{0}' (system ID '{1}') at host '{2}' (IP address: '{3}')",
              friendlyName, deviceUuid, system.HostName, system.Address);
          return;
        }
        try
        {
          connection = _connection = _controlPoint.Connect(rootDescriptor, deviceUuid, UPnPExtendedDataTypes.ResolveDataType);
        }
        catch (Exception e)
        {
          ServiceRegistration.Get<ILogger>().Warn("UPnPClientControlPoint: Error connecting to UPnP MP2 backend server '{0}'", e, deviceUuid);
          return;
        }
      }
      connection.DeviceDisconnected += OnUPnPDeviceDisconnected;
      try
      {
        CpService cdsStub = connection.Device.FindServiceByServiceId(UPnPTypesAndIds.CONTENT_DIRECTORY_SERVICE_ID);
        if (cdsStub == null)
          throw new InvalidDataException("ContentDirectory service not found in device '{0}' of type '{1}:{2}'",
              deviceUuid, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE_VERSION);
        CpService risStub = connection.Device.FindServiceByServiceId(UPnPTypesAndIds.RESOURCE_INFORMATION_SERVICE_ID);
        if (risStub == null)
          throw new InvalidDataException("ResourceAccess service not found in device '{0}' of type '{1}:{2}'",
              deviceUuid, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE_VERSION);
        CpService scsStub = connection.Device.FindServiceByServiceId(UPnPTypesAndIds.SERVER_CONTROLLER_SERVICE_ID);
        if (scsStub == null)
          throw new InvalidDataException("ServerController service not found in device '{0}' of type '{1}:{2}'",
              deviceUuid, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE_VERSION);
        CpService updmStub = connection.Device.FindServiceByServiceId(UPnPTypesAndIds.USER_PROFILE_DATA_MANAGEMENT_SERVICE_ID);
        if (updmStub == null)
          throw new InvalidDataException("UserProfileDataManagement service not found in device '{0}' of type '{1}:{2}'",
              deviceUuid, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE, UPnPTypesAndIds.BACKEND_SERVER_DEVICE_TYPE_VERSION);
        lock (_networkTracker.SharedControlPointData.SyncObj)
        {
          _contentDirectoryService = new UPnPContentDirectoryServiceProxy(cdsStub);
          _resourceInformationService = new UPnPResourceInformationServiceProxy(risStub);
          _serverControllerService = new UPnPServerControllerServiceProxy(scsStub);
          _userProfileDataManagementService = new UPnPUserProfileDataManagementServiceProxy(updmStub);
        }

        ICollection<UPnPServiceProxyBase> additionalServices = new List<UPnPServiceProxyBase>();
        foreach (AdditionalServiceRegisterDlgt additionalServiceRegistration in _additionalServiceRegistrations)
        {
          try
          {
            additionalServices.Add(additionalServiceRegistration(connection));
          }
          catch (Exception e)
          {
            ServiceRegistration.Get<ILogger>().Warn("UPnPClientControlPoint: Error registering user service for UPnP MP2 backend server '{0}'", e, deviceUuid);
          }
        }
        lock (_networkTracker.SharedControlPointData.SyncObj)
          _additionalServices = additionalServices;
      }
      catch (Exception e)
      {
        ServiceRegistration.Get<ILogger>().Warn("UPnPClientControlPoint: Error connecting to services of UPnP MP2 backend server '{0}'", e, deviceUuid);
        connection.DeviceDisconnected -= OnUPnPDeviceDisconnected;
        _controlPoint.Disconnect(deviceUuid);
        return;
      }
      InvokeBackendServerDeviceConnected(connection);
    }
 private void HandleDeviceConfigurationChanged(RootDescriptor rootDescriptor)
 {
   // Configuration changes cannot be given to our clients because they need a re-initialization of the
   // device and all service description documents. So configuration changes will be handled by invocing a
   // root device remove/add event combination. The add event will be fired when the initialization of the root descriptor has finished.
   InvokeRootDeviceRemoved(rootDescriptor);
   InitializeRootDescriptor(rootDescriptor.SSDPRootEntry);
 }
 protected void InvokeDeviceRebooted(RootDescriptor rd)
 {
   try
   {
     DeviceRebootedDlgt dlgt = DeviceRebooted;
     if (dlgt != null)
       dlgt(rd);
   }
   catch (Exception e)
   {
     UPnPConfiguration.LOGGER.Warn("UPnPNetworkTracker: Error invoking DeviceRebooted delegate", e);
   }
 }
 protected void InitializeRootDescriptor(RootEntry rootEntry)
 {
   RootDescriptor rd = new RootDescriptor(rootEntry)
     {
         State = RootDescriptorState.AwaitingDeviceDescription
     };
   lock (_cpData.SyncObj)
     SetRootDescriptor(rootEntry, rd);
   try
   {
     LinkData preferredLink = rootEntry.PreferredLink;
     HttpWebRequest request = CreateHttpGetRequest(new Uri(preferredLink.DescriptionLocation), preferredLink.Endpoint.EndPointIPAddress);
     DescriptionRequestState state = new DescriptionRequestState(rd, request);
     lock (_cpData.SyncObj)
       _pendingRequests.Add(state);
     IAsyncResult result = request.BeginGetResponse(OnDeviceDescriptionReceived, state);
     NetworkHelper.AddTimeout(request, result, PENDING_REQUEST_TIMEOUT * 1000);
   }
   catch (Exception) // Don't log messages at this low protocol level
   {
     lock (_cpData.SyncObj)
       rd.State = RootDescriptorState.Erroneous;
   }
 }
 void OnUPnPRootDeviceAdded(RootDescriptor rootDescriptor)
 {
   ClientDescriptor clientDescriptor;
   lock (_networkTracker.SharedControlPointData.SyncObj)
   {
     clientDescriptor = ClientDescriptor.GetMPFrontendServerDescriptor(rootDescriptor);
     if (clientDescriptor == null || _availableClients.Contains(clientDescriptor))
       return;
     ServiceRegistration.Get<ILogger>().Debug("UPnPServerControlPoint: Found MP2 client '{0}' (system ID '{1}') at host '{2}' ({3})",
         clientDescriptor.ClientName, clientDescriptor.MPFrontendServerUUID, clientDescriptor.System.HostName,
         _attachedClientSystemIds.Contains(clientDescriptor.MPFrontendServerUUID) ? "attached" : "not attached");
     _availableClients.Add(clientDescriptor);
   }
   InvokeClientAvailable(clientDescriptor);
   CheckConnect(clientDescriptor);
 }
Example #42
0
 protected void SetRootDescriptor(RootEntry rootEntry, RootDescriptor rootDescriptor)
 {
     rootEntry.ClientProperties[KEY_ROOT_DESCRIPTOR] = rootDescriptor;
 }
 /// <summary>
 /// Connects to the device of the given <paramref name="deviceUuid"/> specified in the <paramref name="rootDescriptor"/>.
 /// </summary>
 /// <param name="rootDescriptor">UPnP root descriptor to connect.</param>
 /// <param name="deviceUuid">UUID of the device in the root descriptor which is the node to connect.</param>
 /// <param name="dataTypeResolver">Delegate method to resolve extended datatypes.</param>
 /// <exception cref="ArgumentException">
 /// <list type="bullet">
 /// <item>If the device with the specified <paramref name="deviceUuid"/> isn't present
 /// in the given <paramref name="rootDescriptor"/></item>
 /// <item>If the given <paramref name="rootDescriptor"/> has is in an erroneous state
 /// (<c><see cref="RootDescriptor.State"/> == <see cref="RootDescriptorState.Erroneous"/></c>)</item>
 /// <item>If the given <paramref name="rootDescriptor"/> contains erroneous data, e.g. erroneous device or
 /// service descriptions</item>
 /// </list>
 /// </exception>
 public DeviceConnection Connect(RootDescriptor rootDescriptor, string deviceUuid, DataTypeResolverDlgt dataTypeResolver)
 {
   return DoConnect(rootDescriptor, deviceUuid, dataTypeResolver);
 }
Example #44
0
 public DescriptionRequestState(RootDescriptor rootDescriptor, HttpWebRequest httpWebRequest)
 {
     _rootDescriptor = rootDescriptor;
     _httpWebRequest = httpWebRequest;
 }