void OnUPnPDeviceDisconnected(DeviceConnection connection)
        {
            IEnumerable <UPnPServiceProxyBase> servicesToDispose;

            lock (_networkTracker.SharedControlPointData.SyncObj)
            {
                _connection = null;
                _contentDirectoryService    = null;
                _resourceInformationService = null;
                _serverControllerService    = null;
                servicesToDispose           = new List <UPnPServiceProxyBase>(_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);
        }
 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.
 }
 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 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);
    }
 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.
 }
        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);
        }