Пример #1
0
        void OnUPnPDeviceDisconnected(DeviceConnection connection)
        {
            IEnumerable <UPnPServiceProxyBase> servicesToDispose;

            lock (_networkTracker.SharedControlPointData.SyncObj)
            {
                _connection = null;
                _contentDirectoryService    = null;
                _resourceInformationService = null;
                _serverControllerService    = null;
                servicesToDispose           = _additionalServices;
                _additionalServices.Clear();
            }
            // Dispose all additional services if possible, to allow proper shutdown and cleanup
            foreach (UPnPServiceProxyBase service in servicesToDispose)
            {
                IDisposable disposable = service as IDisposable;
                if (disposable == null)
                {
                    continue;
                }
                try
                {
                    disposable.Dispose();
                }
                catch (Exception e)
                {
                    ServiceRegistration.Get <ILogger>().Warn("UPnPClientControlPoint: Error disposing additional service '{0}'", service, e);
                }
            }
            InvokeBackendServerDeviceDisconnected(connection);
        }
Пример #2
0
 public void Stop()
 {
     _contentDirectoryService    = null;
     _resourceInformationService = null;
     _serverControllerService    = null;
     _networkTracker.Close();
     _controlPoint.Close(); // Close the control point after the network tracker was closed. See docs of Close() method.
 }
Пример #3
0
    public void DetachFromHomeServer()
    {
      ISettingsManager settingsManager = ServiceRegistration.Get<ISettingsManager>();
      ServerConnectionSettings settings = settingsManager.Load<ServerConnectionSettings>();
      ServiceRegistration.Get<ILogger>().Info("ServerConnectionManager: Detaching from home server '{0}'", settings.HomeServerSystemId);

      ServiceRegistration.Get<ILogger>().Debug("ServerConnectionManager: Clearing pending import jobs and suspending importer worker");
      IImporterWorker importerWorker = ServiceRegistration.Get<IImporterWorker>();
      importerWorker.Suspend();
      importerWorker.CancelPendingJobs();

      ServiceRegistration.Get<ILogger>().Debug("ServerConnectionManager: Notifying the MediaPortal server about the detachment");
      UPnPServerControllerServiceProxy sc = ServerControllerServiceProxy;
      ISystemResolver systemResolver = ServiceRegistration.Get<ISystemResolver>();
      if (sc != null)
        try
        {
          sc.DetachClient(systemResolver.LocalSystemId);
          sc.AttachedClientsChanged -= OnAttachedClientsChanged;
          sc.ConnectedClientsChanged -= OnConnectedClientsChanged;
        }
        catch (Exception e)
        {
          ServiceRegistration.Get<ILogger>().Warn("ServerConnectionManager: Error detaching from home server '{0}'", e, HomeServerSystemId);
        }
      UPnPContentDirectoryServiceProxy cd = ContentDirectoryServiceProxy;
      if (cd != null)
        try
        {
          cd.PlaylistsChanged -= OnContentDirectoryPlaylistsChanged;
          cd.MIATypeRegistrationsChanged -= OnContentDirectoryMIATypeRegistrationsChanged;
          cd.RegisteredSharesChangeCounterChanged -= OnRegisteredSharesChangeCounterChanged;
        }
        catch (Exception e)
        {
          ServiceRegistration.Get<ILogger>().Warn("ServerConnectionManager: Error unregistering from state variable change events", e);
        }

      ServiceRegistration.Get<ILogger>().Debug("ServerConnectionManager: Closing server connection");
      UPnPClientControlPoint cp;
      lock (_syncObj)
        cp = _controlPoint;
      if (cp != null)
        cp.Stop(); // Must be outside the lock - sends messages
      lock (_syncObj)
      {
        settings.HomeServerSystemId = null;
        settings.LastHomeServerName = null;
        settings.LastHomeServerSystem = null;
        settingsManager.Save(settings);
        _controlPoint = null;
      }
      UpdateCurrentlyImportingShares(null); // Mark all shares as not being imported
      ServerConnectionMessaging.SendServerConnectionStateChangedMessage(ServerConnectionMessaging.MessageType.HomeServerDetached);

      ServiceRegistration.Get<ILogger>().Debug("ServerConnectionManager: Starting to watch for MediaPortal servers");
      if (_serverWatcher == null)
      {
        lock (_syncObj)
          _serverWatcher = BuildServerWatcher();
        _serverWatcher.Start(); // Outside the lock
      }
    }
Пример #4
0
    /// <summary>
    /// Synchronously synchronizes all local shares and media item aspect types with the MediaPortal server.
    /// </summary>
    protected async Task CompleteServerConnectionAsync()
    {
      UPnPServerControllerServiceProxy sc = ServerControllerServiceProxy;
      ISystemResolver systemResolver = ServiceRegistration.Get<ISystemResolver>();
      if (sc != null)
      {
        try
        {
          // Check if we're attached to the server. If the server lost its state, it might have forgotten us.
          if (!sc.GetAttachedClients().Select(clientMetadata => clientMetadata.SystemId).Contains(systemResolver.LocalSystemId))
            sc.AttachClient(systemResolver.LocalSystemId);
        }
        catch (Exception e)
        {
          ServiceRegistration.Get<ILogger>().Warn("ServerConnectionManager: Error checking attachment state at home server '{0}'", e, HomeServerSystemId);
          return; // This is a real error case, we don't need to try any other service calls
        }

        // Register state variables change events
        sc.AttachedClientsChanged += OnAttachedClientsChanged;
        sc.ConnectedClientsChanged += OnConnectedClientsChanged;
      }
      IImporterWorker importerWorker = ServiceRegistration.Get<IImporterWorker>();
      ICollection<Share> newShares = new List<Share>();
      UPnPContentDirectoryServiceProxy cd = ContentDirectoryServiceProxy;
      if (cd != null)
      {
        // Update shares registration
        try
        {
          ISettingsManager settingsManager = ServiceRegistration.Get<ISettingsManager>();
          ServerConnectionSettings settings = settingsManager.Load<ServerConnectionSettings>();
          ServiceRegistration.Get<ILogger>().Info("ServerConnectionManager: Synchronizing shares with home server");
          IDictionary<Guid, Share> serverShares = new Dictionary<Guid, Share>();
          foreach (Share share in await cd.GetSharesAsync(systemResolver.LocalSystemId, SharesFilter.All))
            serverShares.Add(share.ShareId, share);
          IDictionary<Guid, Share> localShares = ServiceRegistration.Get<ILocalSharesManagement>().Shares;
          // First remove shares - if the client lost its configuration and re-registers an already present share, the server's method will throw an exception
          foreach (Guid serverShareId in serverShares.Keys)
            if (!localShares.ContainsKey(serverShareId))
              await cd.RemoveShareAsync(serverShareId);
          foreach (Share localShare in localShares.Values)
          {
            RelocationMode relocationMode;
            if (!serverShares.ContainsKey(localShare.ShareId))
            {
              await cd.RegisterShareAsync(localShare);
              newShares.Add(localShare);
            }
            else if (settings.CachedSharesUpdates.TryGetValue(localShare.ShareId, out relocationMode))
            {
              await cd.UpdateShareAsync(localShare.ShareId, localShare.BaseResourcePath, localShare.Name, localShare.UseShareWatcher, localShare.MediaCategories,
                  relocationMode);
              switch (relocationMode)
              {
                case RelocationMode.ClearAndReImport:
                  importerWorker.ScheduleImport(localShare.BaseResourcePath, localShare.MediaCategories, true);
                  break;
                case RelocationMode.Relocate:
                  importerWorker.ScheduleRefresh(localShare.BaseResourcePath, localShare.MediaCategories, true);
                  break;
              }
            }
          }
          settings.CachedSharesUpdates.Clear();
          settingsManager.Save(settings);
        }
        catch (Exception e)
        {
          ServiceRegistration.Get<ILogger>().Warn("ServerConnectionManager: Could not synchronize local shares with server", e);
        }

        // Update media item aspect type registration
        try
        {
          IMediaItemAspectTypeRegistration miatr = ServiceRegistration.Get<IMediaItemAspectTypeRegistration>();
          ServiceRegistration.Get<ILogger>().Info("ServerConnectionManager: Checking for unregistered media item aspect types at home server");
          ICollection<Guid> serverMIATypes = await cd.GetAllManagedMediaItemAspectTypesAsync();
          foreach (KeyValuePair<Guid, MediaItemAspectMetadata> localMiaType in miatr.LocallyKnownMediaItemAspectTypes)
            if (!serverMIATypes.Contains(localMiaType.Key))
            {
              ServiceRegistration.Get<ILogger>().Info("ServerConnectionManager: Adding unregistered media item aspect type '{0}' (ID '{1}') at home server",
                  localMiaType.Value.Name, localMiaType.Key);
              await cd.AddMediaItemAspectStorageAsync(localMiaType.Value);
            }
        }
        catch (Exception e)
        {
          ServiceRegistration.Get<ILogger>().Warn("ServerConnectionManager: Could not synchronize local media item aspect types with server", e);
        }

        // Register state variables change events
        cd.PlaylistsChanged += OnContentDirectoryPlaylistsChanged;
        cd.MIATypeRegistrationsChanged += OnContentDirectoryMIATypeRegistrationsChanged;
        cd.RegisteredSharesChangeCounterChanged += OnRegisteredSharesChangeCounterChanged;

        // Activate importer worker
        ServiceRegistration.Get<ILogger>().Debug("ServerConnectionManager: Activating importer worker");
        ImporterCallback ic = new ImporterCallback(cd);
        importerWorker.Activate(ic, ic);
        foreach (Share share in newShares)
          importerWorker.ScheduleImport(share.BaseResourcePath, share.MediaCategories, true);
      }
    }
Пример #5
0
        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 MP 2 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 MP 2 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 MP 2 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 MP 2 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 MP 2 backend server '{0}'", e, deviceUuid);
                connection.DeviceDisconnected -= OnUPnPDeviceDisconnected;
                _controlPoint.Disconnect(deviceUuid);
                return;
            }
            InvokeBackendServerDeviceConnected(connection);
        }
 void OnUPnPDeviceDisconnected(DeviceConnection connection)
 {
   IEnumerable<UPnPServiceProxyBase> servicesToDispose;
   lock (_networkTracker.SharedControlPointData.SyncObj)
   {
     _connection = null;
     _contentDirectoryService = null;
     _resourceInformationService = null;
     _serverControllerService = null;
     servicesToDispose = _additionalServices;
     _additionalServices.Clear();
   }
   // Dispose all additional services if possible, to allow proper shutdown and cleanup
   foreach (UPnPServiceProxyBase service in servicesToDispose)
   {
     IDisposable disposable = service as IDisposable;
     if (disposable == null)
       continue;
     try
     {
       disposable.Dispose();
     }
     catch (Exception e)
     {
       ServiceRegistration.Get<ILogger>().Warn("UPnPClientControlPoint: Error disposing additional service '{0}'", service, e);
     }
   }
   InvokeBackendServerDeviceDisconnected(connection);
 }
    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 MP 2 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 MP 2 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 MP 2 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 MP 2 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 MP 2 backend server '{0}'", e, deviceUuid);
        connection.DeviceDisconnected -= OnUPnPDeviceDisconnected;
        _controlPoint.Disconnect(deviceUuid);
        return;
      }
      InvokeBackendServerDeviceConnected(connection);
    }
 public void Stop()
 {
   _contentDirectoryService = null;
   _resourceInformationService = null;
   _serverControllerService = null;
   _networkTracker.Close();
   _controlPoint.Close(); // Close the control point after the network tracker was closed. See docs of Close() method.
 }