Exemple #1
0
        /// <summary>
        /// Aktiviert eine einzelne Quelle für den <i>Zapping Modus</i>.
        /// </summary>
        /// <param name="selectionKey">Die gewünschte Quelle.</param>
        /// <param name="target">Die Netzwerkadresse, an die alle Daten versendet werden sollen.</param>
        /// <returns>Steuereinheit für diesen Aufruf.</returns>
        /// <exception cref="ArgumentNullException">Ein Parameter wurde nicht angegeben.</exception>
        public IAsyncResult <ServerInformation> BeginSetZappingSource(string selectionKey, string target)
        {
            // Validate
            if (string.IsNullOrEmpty(selectionKey))
            {
                throw new ArgumentNullException("selectionKey");
            }
            if (string.IsNullOrEmpty(target))
            {
                throw new ArgumentNullException("target");
            }

            // Create the selection
            var source = new SourceSelection {
                SelectionKey = selectionKey
            };

            // Check for profile match
            if (string.IsNullOrEmpty(m_Profile) || !string.Equals(m_Profile, source.ProfileName, StringComparison.InvariantCultureIgnoreCase))
            {
                CardServerException.Throw(new ProfileMismatchFault(m_Profile, source.ProfileName));
            }

            // Start action
            return((IAsyncResult <ServerInformation>)Start <ServerInformation>(() => { OnSetZappingSource(source, target); }));
        }
        /// <summary>
        /// Aktiviert die Nutzung eines DVB.NET Geräteprofils.
        /// </summary>
        /// <param name="profileName">Der Name des Geräteprofils.</param>
        /// <param name="reset">Gesetzt, wenn das zugehörige Windows Gerät neu initialisiert werden soll.</param>
        /// <param name="disablePCRFromH264">Wird gesetzt um zu verhindern, dass die Systemzeit (PCR) aus
        /// dem H.264 Bildsignal ermittelt wird, da dieser Mechanismus hochgradig unsicher ist.</param>
        /// <param name="disablePCRFromMPEG2">Wird gesetzt um zu verhindern, dass die Systemzeit (PCR) aus
        /// dem MPEG2 Bildsignal ermittelt wird, da dieser Mechanismus hochgradig unsicher ist.</param>
        /// <exception cref="CardServerException">Es existiert kein Geräteprofil mit dem
        /// angegebenen Namen.</exception>
        protected override void OnAttachProfile(string profileName, bool reset, bool disablePCRFromH264, bool disablePCRFromMPEG2)
        {
            // Overwrite flags
            Manager.DisablePCRForSDTV = disablePCRFromMPEG2;
            Manager.DisablePCRForHDTV = disablePCRFromH264;

            // Load the profile
            Profile = ProfileManager.FindProfile(profileName);

            // Validate
            if (Profile == null)
            {
                CardServerException.Throw(new NoProfileFault(profileName));
            }

            // Load special overwrites
            ReadRecordingParameter(RecordingSettings.DecryptWatchDogIntervalName, ref m_DecryptionWatchDogInterval, TimeSpan.MaxValue);
            ReadRecordingParameter(RecordingSettings.PSIWatchDogIntervalName, ref m_RetestWatchDogInterval, m_RetestWatchDogInterval);
            ReadRecordingParameter(RecordingSettings.StreamWatchDogIntervalName, ref m_GroupWatchDogInterval, TimeSpan.MaxValue);

            // Create the thread
            m_Thread = new Thread(WorkerThread)
            {
                Name = "DVB.NET Card Server Worker Thread", Priority = ThreadPriority.AboveNormal
            };
            m_Thread.SetApartmentState(ApartmentState.STA);
            m_Thread.Start(reset);

            // Create the idle thread
            m_IdleThread = new Thread(Idle)
            {
                Name = "DVB.NET Card Server Idle Thread"
            };
            m_IdleThread.Start();
        }
Exemple #3
0
        /// <summary>
        /// Beendet die Aktualisierung der Programmzeitschrift.
        /// </summary>
        protected override void OnEndEPGCollection()
        {
            // Process
            Start(device =>
            {
                // Check mode
                if (!EPGProgress.HasValue)
                {
                    CardServerException.Throw(new EPGNotActiveFault());
                }

                // Disable all consumers
                device.SelectGroup(null, null);

                // Preserve some memory
                m_EPGPending.Clear();
                m_EPGSources.Clear();
                m_EPGGroups.Clear();

                // Terminate
                EPGProgress = null;

                // Process result - will reset the list
                return(CreateGuideItems());
            });
        }
Exemple #4
0
        /// <summary>
        /// Beendet einen Sendersuchlauf auf dem aktuellen Geräteprofil.
        /// </summary>
        /// <param name="updateProfile">Gesetzt, wenn das Geräteprofil aktualisiert werden soll.</param>
        protected override void OnEndScan(bool?updateProfile)
        {
            // Process
            Start(device =>
            {
                // Check mode
                if (m_ScanProgress < 0)
                {
                    CardServerException.Throw(new SourceUpdateNotActiveFault());
                }
                if (null != m_ScanAbort)
                {
                    CardServerException.Throw(new SourceUpdateNotActiveFault());
                }

                // Install action
                m_ScanAbort = () =>
                {
                    // With cleanup
                    using (TransponderScanner scanner = m_Scanner)
                    {
                        // Mark as done
                        m_ScanProgress = -1;
                        m_Scanner      = null;

                        // Check mode
                        if (updateProfile.HasValue)
                        {
                            // Do NOT merge
                            if (!updateProfile.Value)
                            {
                                scanner.Profile.Locations.Clear();
                            }

                            // Process
                            scanner.UpdateProfile();

                            // Save it
                            scanner.Profile.Save();
                        }
                    }

                    // Report
                    ActionDone(null, null);
                };

                // Done
                return(DelayedOperationTag);
            });
        }
        /// <summary>
        /// Verändert den Netzwerkversand für eine aktive Quelle.
        /// </summary>
        /// <param name="source">Die Auswahl der Quelle.</param>
        /// <param name="uniqueIdentifier">Der eindeutige Name der Quelle.</param>
        /// <param name="target">Die Daten zum Netzwerkversand.</param>
        /// <exception cref="ArgumentNullException">Es wurde keine Quelle angegeben.</exception>
        protected override void OnSetStreamTarget(SourceIdentifier source, Guid uniqueIdentifier, string target)
        {
            // Prepare operation
            Start(() =>
            {
                // Find the source
                var stream = FindSource(new SourceIdenfierWithKey(uniqueIdentifier, source));
                if (stream == null)
                {
                    CardServerException.Throw(new NoSourceFault(source));
                }

                // Process
                stream.Manager.StreamingTarget = target;
            });
        }
Exemple #6
0
        /// <summary>
        /// Aktiviert den Empfang einer Quelle.
        /// </summary>
        /// <param name="sources">Informationen zu den zu aktivierenden Quellen.</param>
        /// <returns>Steuereinheit für diesen Aufruf. Der Ergebniswert enthält alle Quellen, die erfolgreich
        /// aktiviert wurden - eventuell mit reduzierten Detailaspekten.</returns>
        /// <exception cref="ArgumentNullException">Mindestens eine Quelle ist nicht gesetzt.</exception>
        public IAsyncResult <StreamInformation[]> BeginAddSources(ReceiveInformation[] sources)
        {
            // Validate
            if (sources == null)
            {
                throw new ArgumentNullException("sources");
            }

            // Create helper
            var clones = new List <ReceiveInformation>();

            // Process all
            for (int i = 0; i < sources.Length; ++i)
            {
                // Load the one
                var source = sources[i];
                if (null == source)
                {
                    throw new ArgumentNullException(string.Format("sources[{0}]", i));
                }

                // Clone it
                source = source.Clone();

                // More tests
                if (source.SelectionKey == null)
                {
                    throw new ArgumentNullException(string.Format("sources[{0}].SelectionKey", i));
                }
                if (source.Streams == null)
                {
                    throw new ArgumentNullException(string.Format("sources[{0}].Streams", i));
                }

                // Check for profile match
                if (string.IsNullOrEmpty(m_Profile) || !string.Equals(m_Profile, source.Selection.ProfileName, StringComparison.InvariantCultureIgnoreCase))
                {
                    CardServerException.Throw(new ProfileMismatchFault(m_Profile, source.Selection.ProfileName));
                }

                // Merge
                clones.Add(source);
            }

            // Start action
            return((IAsyncResult <StreamInformation[]>)Start <StreamInformation[]>(() => { OnAddSources(clones.ToArray()); }));
        }
        /// <summary>
        /// Stellt den Empfang für eine Quelle ein.
        /// </summary>
        /// <param name="source">Die betroffene Quelle.</param>
        /// <param name="uniqueIdentifier">Der eindeutige Name der Quelle.</param>
        protected override void OnRemoveSource(SourceIdentifier source, Guid uniqueIdentifier)
        {
            // Prepare operation
            Start(() =>
            {
                // Find the source
                var stream = FindSource(new SourceIdenfierWithKey(uniqueIdentifier, source));
                if (stream == null)
                {
                    CardServerException.Throw(new NoSourceFault(source));
                }

                // Stop all activity on the source
                using (stream)
                    Streams.Remove(stream.SourceKey);
            });
        }
Exemple #8
0
        /// <summary>
        /// Setzt das aktuell zugeordnete DVB.NET Geräteprofil.
        /// </summary>
        /// <param name="profileName">Der Name des zu verwendenden Geräteprofils.</param>
        /// <param name="reset">Gesetzt, wenn das zugehörige Windows Gerät neu initialisiert werden soll.</param>
        /// <param name="disablePCRFromH264">Wird gesetzt um zu verhindern, dass die Systemzeit (PCR) aus
        /// dem H.264 Bildsignal ermittelt wird, da dieser Mechanismus hochgradig unsicher ist.</param>
        /// <param name="disablePCRFromMPEG2">Wird gesetzt um zu verhindern, dass die Systemzeit (PCR) aus
        /// dem MPEG2 Bildsignal ermittelt wird, da dieser Mechanismus hochgradig unsicher ist.</param>
        /// <returns>Steuerinstanz zur asynchronen Ausführung.</returns>
        /// <exception cref="ArgumentNullException">Es wurde kein Geräteprofil angegeben.</exception>
        /// <exception cref="CardServerException">Es wurde bereits ein Geräteprofil aktiviert.</exception>
        public IAsyncResult BeginSetProfile(string profileName, bool reset, bool disablePCRFromH264, bool disablePCRFromMPEG2)
        {
            // Validate
            if (string.IsNullOrEmpty(profileName))
            {
                throw new ArgumentNullException("value");
            }

            // We are in use
            if (!string.IsNullOrEmpty(m_Profile))
            {
                CardServerException.Throw(new ProfileAlreadyAttachedFault(m_Profile));
            }

            // Set the closing action
            return(Start <object>(() => { OnAttachProfile(profileName, reset, disablePCRFromH264, disablePCRFromMPEG2); }, r => { m_Profile = profileName; }));
        }
        /// <summary>
        /// Stellt den Empfang für alle Quellen ein.
        /// </summary>
        protected override void OnRemoveAllSources()
        {
            // Dispatch
            Start(() =>
            {
                // Check mode
                if (EPGProgress.HasValue)
                {
                    CardServerException.Throw(new EPGActiveFault());
                }
                if (m_ScanProgress >= 0)
                {
                    CardServerException.Throw(new SourceUpdateActiveFault());
                }

                // Forward
                RemoveAll();
            });
        }
Exemple #10
0
        /// <summary>
        /// Meldet, dass die aktuelle Aufgabe abgeschlossen wurde.
        /// </summary>
        /// <param name="e">Die zugehörige Ausnahme oder <i>null</i>, wenn bei der Ausführung
        /// kein Fehler aufgetreten ist.</param>
        /// <param name="result">Das Ergebnis der ausgeführten Aktion</param>
        protected void ActionDone(Exception e, object result)
        {
            // Remember
            m_Result = result;

            // Remember
            if (e == null)
            {
                m_LastError = null;
            }
            else if (e is CardServerException)
            {
                m_LastError = (CardServerException)e;
            }
            else
            {
                m_LastError = new CardServerException(new CardServerFault(e.Message));
            }

            // Finish
            if (m_Pending != null)
            {
                try
                {
                    // Process if there was no error
                    if (m_LastError == null)
                    {
                        m_Pending(m_Result);
                    }
                }
                finally
                {
                    // Forget
                    m_Pending = null;
                }
            }

            // Signal
            m_Done.Set();
        }
Exemple #11
0
        /// <summary>
        /// Wählt eine bestimmte Quellgruppe (Transponder) an.
        /// </summary>
        /// <param name="selectionKey">Die Beschreibung einer Quelle, deren Gruppe aktiviert werden soll.</param>
        /// <returns>Steuereinheit für diesen Aufruf.</returns>
        /// <exception cref="ArgumentNullException">Es wurde keine Quellgruppe angegeben.</exception>
        /// <exception cref="CardServerException">Es wird bereits eine Anfrage ausgeführt.</exception>
        public IAsyncResult BeginSelect(string selectionKey)
        {
            // Validate
            if (selectionKey == null)
            {
                throw new ArgumentNullException("selectionKey");
            }

            // Reconstruct
            var selection = new SourceSelection {
                SelectionKey = selectionKey
            };

            // Check for profile match
            if (string.IsNullOrEmpty(m_Profile) || !string.Equals(m_Profile, selection.ProfileName, StringComparison.InvariantCultureIgnoreCase))
            {
                CardServerException.Throw(new ProfileMismatchFault(m_Profile, selection.ProfileName));
            }

            // Start action
            return(Start <object>(() => { OnSelect(selection); }));
        }
        /// <summary>
        /// Wählt eine Quellgruppe an.
        /// </summary>
        /// <param name="device">Die zu verwendende Hardware.</param>
        /// <param name="selection">Die gewünschte Quellgruppe.</param>
        private void SelectGroup(Hardware device, SourceSelection selection)
        {
            // Check mode
            if (EPGProgress.HasValue)
            {
                CardServerException.Throw(new EPGActiveFault());
            }
            if (m_ScanProgress >= 0)
            {
                CardServerException.Throw(new SourceUpdateActiveFault());
            }

            // Stop all current recordings
            RemoveAll();

            // Forward
            device.SelectGroup(selection.Location, selection.Group);

            // Time to reset counters
            m_LastGroupInfoTime = DateTime.UtcNow;
            GroupRestart        = 0;
        }
        /// <summary>
        /// Führt eine Erweiterungsoperation aus.
        /// </summary>
        /// <param name="actionType">Die Klasse, von der aus die Erweiterungsmethode abgerufen werden kann.</param>
        /// <param name="parameters">Optionale Parameter zur Ausführung.</param>
        protected override void OnCustomAction <TInput, TOutput>(string actionType, TInput parameters)
        {
            // Process
            Start(device =>
            {
                // Resolve the type
                var type = Type.GetType(actionType, false);
                if (type == null)
                {
                    CardServerException.Throw(new NoSuchActionFault(actionType));
                }

                // Create the instance of the type
                var customAction = Activator.CreateInstance(type, new object[] { this }) as CustomAction <TInput, TOutput>;
                if (customAction == null)
                {
                    CardServerException.Throw(new NoSuchActionFault(actionType));
                }

                // Process
                return(customAction.Execute(device, parameters));
            });
        }
Exemple #14
0
        /// <summary>
        /// Meldet das Ergebnis der letzten Befehlsausführung. Diese Methode
        /// kann nur ein einziges Mal aufgerufen werden.
        /// </summary>
        /// <returns>Das Ergebnis der letzten Befehlsausführung.</returns>
        private T GetResult <T>()
        {
            // Still running
            if (IsBusy)
            {
                CardServerException.Throw(new ServerBusyFault());
            }

            // Result
            var e = m_LastError;

            // Clear
            m_LastError = null;

            // Report error
            if (e != null)
            {
                throw e;
            }

            // Report result
            return((T)m_Result);
        }
Exemple #15
0
        /// <summary>
        /// Beginnt einen Sendersuchlauf auf dem aktuellen Geräteprofil.
        /// </summary>
        protected override void OnStartScan()
        {
            // Process
            Start(device =>
            {
                // Check mode
                if (EPGProgress.HasValue)
                {
                    CardServerException.Throw(new EPGActiveFault());
                }
                if (m_ScanProgress >= 0)
                {
                    CardServerException.Throw(new SourceUpdateActiveFault());
                }
                if (!string.IsNullOrEmpty(Profile.UseSourcesFrom))
                {
                    CardServerException.Throw(new NoSourceListFault(Profile.Name));
                }

                // Stop all
                RemoveAll();

                // Create scanner
                m_Scanner = new TransponderScanner(Profile);

                // Configure
                m_Scanner.OnDoneLocation += (l, s) => OnUpdateScan();
                m_Scanner.OnDoneGroup    += (l, g, s) => OnUpdateScan();

                // Mark as started
                m_ScanProgress = 0;
                m_ScanSources  = 0;

                // Start it
                m_Scanner.Scan();
            });
        }
Exemple #16
0
        /// <summary>
        /// Beginnt mit der Ausführung einer Aufgabe.
        /// </summary>
        /// <typeparam name="TResult">Die Art des Rückgabewertes.</typeparam>
        /// <param name="action">Die auszuführende Aktion.</param>
        /// <param name="finalizer"></param>
        /// <returns>Steuereinheit für diesen Aufruf.</returns>
        private IAsyncResult Start <TResult>(Action action, Action <object> finalizer)
        {
            // We are Processing
            if (IsBusy)
            {
                CardServerException.Throw(new ServerBusyFault());
            }

            // Set the closing action
            m_Pending = finalizer;

            // Reset error
            m_LastError = null;
            m_Result    = null;

            // Reset synchronizer
            m_Done.Reset();

            // Be safe
            try
            {
                // Initiate the operation
                action();

                // Report control element
                return(_AsyncControl.Create <TResult>(this));
            }
            catch (Exception e)
            {
                // Synchronous error
                ActionDone(e, null);

                // Forward
                throw e;
            }
        }
        /// <summary>
        /// Aktiviert den Empfang einer Quelle.
        /// </summary>
        /// <param name="sources">Informationen zu den zu aktivierenden Quellen.</param>
        protected override void OnAddSources(ReceiveInformation[] sources)
        {
            // Prepare operation
            Start(device =>
            {
                // Check mode
                if (EPGProgress.HasValue)
                {
                    CardServerException.Throw(new EPGActiveFault());
                }
                if (m_ScanProgress >= 0)
                {
                    CardServerException.Throw(new SourceUpdateActiveFault());
                }

                // Force reload of group information to be current
                device.ResetInformationReaders();

                // Create optimizer
                var optimizer = new StreamSelectionOptimizer();

                // Source backmap
                var infos = new Dictionary <SourceIdenfierWithKey, ReceiveInformation>();

                // Pre-Test
                foreach (var info in sources)
                {
                    // It's not allowed to activate a source twice
                    var key = new SourceIdenfierWithKey(info.UniqueIdentifier, info.Selection.Source);
                    if (FindSource(key) != null)
                    {
                        CardServerException.Throw(new SourceInUseFault(info.Selection.Source));
                    }

                    // Remember
                    infos.Add(key, info);

                    // Prepare to optimize
                    optimizer.Add(info.Selection, info.Streams);
                }

                // See how many we are allowed to start
                var allowed = optimizer.Optimize();

                // Streams to activate
                var newStreams = new List <ActiveStream>();
                try
                {
                    // Process all
                    for (int i = 0; i < allowed; ++i)
                    {
                        // Attach to the source
                        var current = sources[i];
                        var source  = current.Selection;
                        var key     = new SourceIdenfierWithKey(current.UniqueIdentifier, source.Source);

                        // Create the stream manager
                        var manager = source.Open(optimizer.GetStreams(i));

                        // Attach file size mapper
                        manager.FileBufferSizeChooser = infos[key].GetFileBufferSize;

                        // Create
                        var stream = new ActiveStream(key.UniqueIdentifier, manager, current.Streams, current.RecordingPath);

                        // Remember
                        newStreams.Add(stream);

                        // See if we have to connect an optimizer for restarts
                        if (device.HasConsumerRestriction)
                        {
                            stream.EnableOptimizer(source);
                        }

                        // Try to start
                        stream.Refresh(m_RetestWatchDogInterval);
                    }

                    // Loaded all
                    newStreams.ForEach(stream => Streams.Add(stream.SourceKey, stream));

                    // Generate response
                    try
                    {
                        // Create all
                        return(newStreams.Select(stream => stream.CreateInformation()).ToArray());
                    }
                    finally
                    {
                        // No need to clean up
                        newStreams.Clear();
                    }
                }
                finally
                {
                    // Cleanup
                    newStreams.ForEach(stream => stream.Dispose());
                }
            });
        }
Exemple #18
0
        /// <summary>
        /// Beginnt mit der Sammlung der Daten für die elektronische Programmzeitschrift
        /// (EPG).
        /// </summary>
        /// <param name="device">Das zu verwendende DVB.NET Gerät.</param>
        /// <param name="sources">Die zu berücksichtigenden Quellen.</param>
        /// <param name="extensions">Spezielle Zusatzfunktionalitäten der Sammlung.</param>
        private void StartEPGCollection(Hardware device, SourceIdentifier[] sources, EPGExtensions extensions)
        {
            // Check mode
            if (EPGProgress.HasValue)
            {
                CardServerException.Throw(new EPGActiveFault());
            }
            if (m_ScanProgress >= 0)
            {
                CardServerException.Throw(new SourceUpdateActiveFault());
            }

            // Reset lists
            m_EPGSources.Clear();
            m_EPGGroups.Clear();

            // Load all identifiers to scan
            if (null != sources)
            {
                foreach (SourceIdentifier source in sources)
                {
                    AddEPGSource(source);
                }
            }

            // Add specials
            if (0 != (extensions & EPGExtensions.PREMIEREDirect))
            {
                if (AddEPGGroup(DirectCIT.TriggerSource).Length < 1)
                {
                    extensions &= ~EPGExtensions.PREMIEREDirect;
                }
            }
            if (0 != (extensions & EPGExtensions.PREMIERESport))
            {
                if (AddEPGGroup(SportCIT.TriggerSource).Length < 1)
                {
                    extensions &= ~EPGExtensions.PREMIERESport;
                }
            }
            if (0 != (extensions & EPGExtensions.FreeSatUK))
            {
                if (AddEPGGroup(EIT.FreeSatEPGTriggerSource).Length < 1)
                {
                    extensions &= ~EPGExtensions.FreeSatUK;
                }
            }

            // Stop all
            RemoveAll();

            // Prepare
            m_EPGPending       = new List <GroupKey>(m_EPGGroups.Keys);
            m_EPGLastItemCheck = DateTime.MaxValue;
            m_EPGLastTune      = DateTime.MinValue;
            m_EPGLastItemCount = -1;
            m_EPGItems.Clear();
            m_EPGItemCount = 0;

            // Mark as active
            m_EPGExtensions = extensions;
            EPGProgress     = 0;

            // Enforce start
            CollectProgramGuide(device);
        }