Esempio n. 1
0
        /// <summary>
        /// Löschte diesen Auftrag.
        /// </summary>
        /// <param name="target">Der Pfad zu einem Zielverzeichnis.</param>
        /// <returns>Gesetzt, wenn der Löschvorgang erfolgreich war. <i>null</i> wird gemeldet,
        /// wenn die Datei nicht existierte.</returns>
        public bool?Delete(DirectoryInfo target)
        {
            // Get the file
            var file = GetFileName(target);

            if (file == null)
            {
                return(null);
            }
            if (!file.Exists)
            {
                return(null);
            }

            // Be safe
            try
            {
                // Process
                file.Delete();
            }
            catch (Exception e)
            {
                // Report error
                VCRServer.Log(e);

                // Failed
                return(false);
            }

            // Did it
            return(true);
        }
Esempio n. 2
0
        /// <summary>
        /// Speichert diesen Auftrag ab.
        /// </summary>
        /// <param name="target">Der Pfad zu einem Zielverzeichnis.</param>
        /// <returns>Gesetzt, wenn der Speichervorgang erfolgreich war. <i>null</i> wird
        /// gemeldet, wenn diesem Auftrag keine Datei zugeordnet ist.</returns>
        public bool?Save(DirectoryInfo target)
        {
            // Get the file
            var file = GetFileName(target);

            if (file == null)
            {
                return(null);
            }

            // Be safe
            try
            {
                // Process
                SerializationTools.Save(this, file);
            }
            catch (Exception e)
            {
                // Report
                VCRServer.Log(e);

                // Done
                return(false);
            }

            // Done
            return(true);
        }
Esempio n. 3
0
        /// <summary>
        /// Erzeugt eine neue Laufzeitumgebung und bindet diese an einen lokalen
        /// TCP/IP Port.
        /// </summary>
        /// <remarks>
        /// Als virtuelles Verzeichnis wird <i>/VCR.NET</i> verwendet. Dieses wird
        /// physikalisch an das Verzeichnis gebunden, dass der aktuellen Anwendung
        /// übergeordnet ist. Es empfiehlt sich, die Anwendung in einem Unterverzeichnis
        /// <i>bin</i> unterzubringen.
        /// </remarks>
        /// <exception cref="InvalidOperationException">Es wurde bereits eine Laufzeitumgebung
        /// angelegt.</exception>
        public void Start()
        {
            // Report
            Tools.ExtendedLogging("Starting Web Server");

            // Already running
            if (m_endPoints.Count > 0)
            {
                return;
            }

            // Create
            m_endPoints.Add(new PrimaryEndPoint(m_server));

            // Check the application directory
            var appDir = new DirectoryInfo(Path.Combine(Tools.ApplicationDirectory.Parent.FullName, ApplicationRoot));

            if (appDir.Exists)
            {
                foreach (var app in appDir.GetDirectories())
                {
                    m_endPoints.Add(new ExtensionEndPoint(app.Name, Path.Combine(ApplicationRoot, app.Name)));
                }
            }

            // Report
            Tools.ExtendedLogging("Listener is up and running");

            // Report
            VCRServer.Log(LoggingLevel.Full, Properties.Resources.WebServerStarted);
        }
Esempio n. 4
0
        /// <summary>
        /// Aktualisiert die Programmzeitschrift mit neuen Daten.
        /// </summary>
        /// <param name="entries">Die neuen Daten.</param>
        internal void UpdateGuide(ProgramGuideEntries entries)
        {
            // Report
            Tools.ExtendedLogging("Program Guide of {0} will be updated", ProfileName);

            // Did collection
            LastUpdateTime = DateTime.UtcNow;

            // Try to load resulting file
            try
            {
                // Create brand new
                var newData = m_Events.Clone();

                // Merge new
                newData.Merge(entries);

                // Cleanup
                newData.DiscardOld();

                // Save
                SerializationTools.Save(newData, ProgramGuideFile, Encoding.UTF8);

                // Use it
                m_Events = newData;

                // Report
                Tools.ExtendedLogging("Now using new Program Guide");
            }
            catch (Exception e)
            {
                // Report
                VCRServer.Log(LoggingLevel.Errors, Properties.Resources.EPGMergeFailed, e);
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Erzeugt eine neue Verwaltungsinstanz.
        /// </summary>
        /// <param name="jobs">Die zugehörige Auftragsverwaltung.</param>
        /// <param name="profileName">Der Name des verwalteten DVB.NET Geräteprofils.</param>
        public ProgramGuideManager(JobManager jobs, string profileName)
        {
            // Remember
            ProfileName = profileName;
            JobManager  = jobs;

            // Calculate file
            ProgramGuideFile = new FileInfo(Path.Combine(JobManager.CollectorDirectory.FullName, $"EPGData for {ProfileName}.xml"));

            // See if profile has it's own program guide
            if (!HasProgramGuide)
            {
                return;
            }

            // Report
            Tools.ExtendedLogging("Looking for Program Guide of {0}", ProfileName);

            // No such file - start empty
            if (!ProgramGuideFile.Exists)
            {
                return;
            }

            // Process
            var events = SerializationTools.Load <ProgramGuideEntries>(ProgramGuideFile);

            if (events != null)
            {
                // Use it
                m_Events = events;

                // Report
                Tools.ExtendedLogging("Found valid Program Guide and using it");

                // Done
                return;
            }

            // Report
            VCRServer.Log(LoggingLevel.Errors, Properties.Resources.EPGFileCorrupted, ProgramGuideFile.FullName);

            // Save delete
            try
            {
                // Process
                ProgramGuideFile.Delete();
            }
            catch
            {
                // Discard any error
                VCRServer.Log(LoggingLevel.Errors, Properties.Resources.EPGDeleteDenied, ProgramGuideFile.FullName);
            }
        }
        /// <summary>
        /// Beendet die Anwendung endgültig.
        /// </summary>
        public void Dispose()
        {
            // Forward
            var listener = Interlocked.Exchange(ref m_listener, null);

            if (listener != null)
            {
                if (listener.IsListening)
                {
                    try
                    {
                        // Process
                        listener.Stop();
                    }
                    catch (Exception)
                    {
                        // Report to event log
                        VCRServer.Log(LoggingLevel.Errors, EventLogEntryType.Warning, Properties.Resources.WebServerStopFailedChannel);
                    }
                }
            }

            // Wait for all outstanding requests to terminate
            while (Thread.VolatileRead(ref m_Threads) > 0)
            {
                Thread.Sleep(100);
            }

            // See if worker is up
            var runtime = Interlocked.Exchange(ref m_runtime, null);

            if (runtime != null)
            {
                try
                {
                    // Save call - may be already dead
                    runtime.Stop();

                    // Terminate the domain
                    AppDomain.Unload(runtime.AppDomain);
                }
                catch (Exception)
                {
                    // Report to event log
                    VCRServer.Log(LoggingLevel.Errors, EventLogEntryType.Warning, Properties.Resources.WebServerStopFailed);
                }
            }
        }
        /// <summary>
        /// Erstellt eine neue Aktualisierung.
        /// </summary>
        /// <param name="state">Das zugehörige Geräteprofil.</param>
        /// <param name="recording">Daten der primären Aufzeichnung.</param>
        private ProgramGuideProxy(ProfileState state, VCRRecordingInfo recording)
            : base(state, recording)
        {
            // Reset fields
            if (VCRConfiguration.Current.EnableFreeSat)
            {
                m_extensions = EPGExtensions.FreeSatUK;
            }
            else
            {
                m_extensions = EPGExtensions.None;
            }

            // All sources we know about
            var allSources = new Dictionary <string, SourceSelection>(StringComparer.InvariantCultureIgnoreCase);

            // Load all sources of this profile
            foreach (var source in VCRProfiles.GetSources(ProfileName))
            {
                // Remember by direct name
                allSources[source.DisplayName] = source;

                // allSources by unique name
                allSources[source.QualifiedName] = source;
            }

            // Fill in all
            foreach (var legacyName in VCRConfiguration.Current.ProgramGuideSources)
            {
                // Skip if empty
                if (string.IsNullOrEmpty(legacyName))
                {
                    continue;
                }

                // Locate
                SourceSelection realSource;
                if (allSources.TryGetValue(legacyName, out realSource))
                {
                    m_selected.Add(realSource.Source);
                }
                else
                {
                    VCRServer.Log(LoggingLevel.Full, Properties.Resources.BadEPGStation, legacyName);
                }
            }
        }
        /// <summary>
        /// Beendet die Nutzung dieser Instantz.
        /// </summary>
        /// <param name="explicitDisposing">Wird ignoriert.</param>
        protected override void Dispose(bool explicitDisposing)
        {
            // Self
            try
            {
                // Forward
                AbortWaiter();
            }
            catch (Exception e)
            {
                // Report
                VCRServer.Log(e);
            }

            // Forward
            base.Dispose(explicitDisposing);
        }
        /// <summary>
        /// Beendet den Suchlauf endgültig.
        /// </summary>
        protected override void OnStop()
        {
            // Remember the time of the last scan
            ProfileState.LastSourceUpdateTime = DateTime.UtcNow;

            // Log
            VCRServer.Log(LoggingLevel.Full, Properties.Resources.PSIReplace);

            // Finish
            ServerImplementation.EndRequest(Server.BeginEndScan(m_mergeSources));

            // Report
            Tools.ExtendedLogging("Card Server has updated Profile {0} - VCR.NET will reload all Profiles now", ProfileName);

            // Time to refresh our lists
            VCRProfiles.Reset();
        }
        /// <summary>
        /// Beendet einen asynchronen Aufruf. Im Fall einer Ausnahme wird diese nur protokolliert
        /// und der Aufruf als abgeschlossen angenommen.
        /// </summary>
        /// <typeparam name="TAsync">Die Art des Aufrufs.</typeparam>
        /// <param name="request">Der aktive Aufruf.</param>
        /// <param name="traceFormat">Meldung bei Abschluss des Aufrufs. Ist dieser Parameter <i>null</i>, so
        /// wartet die Methode auf den Abschluss des asynchronen Aufrufs.</param>
        /// <param name="traceArgs">Parameter zum Aufbau der Meldung.</param>
        /// <returns>Gesetzt, wenn der Aufruf abgeschlossen wurde oder bereits war. Ansonsten
        /// ist der Aufruf weiterhin aktiv.</returns>
        protected bool WaitForEnd <TAsync>(ref TAsync request, string traceFormat = null, params object[] traceArgs) where TAsync : class, IAsyncResult
        {
            // No request at all
            var pending = request;

            if (pending == null)
            {
                return(true);
            }

            // Request still busy - calling this method with only a single parameter will do a synchronous call
            if (traceFormat != null)
            {
                if (!pending.IsCompleted)
                {
                    return(false);
                }
            }

            // Synchronize
            try
            {
                // Fetch result
                ServerImplementation.EndRequest(pending);

                // Report
                if (!string.IsNullOrEmpty(traceFormat))
                {
                    Tools.ExtendedLogging(traceFormat, traceArgs);
                }
            }
            catch (Exception e)
            {
                // Report only!
                VCRServer.Log(LoggingLevel.Errors, "Failed Operation for '{0}': {1}", ProfileName, e.Message);
            }
            finally
            {
                // Forget
                request = null;
            }

            // Stopped it
            return(true);
        }
Esempio n. 11
0
        /// <summary>
        /// Beendet die aktuelle ASP.NET Laufzeitumgebung.
        /// <seealso cref="ServerRuntime.Stop"/>
        /// </summary>
        public void Stop()
        {
            // Terminate all end-points we started
            foreach (var endPoint in Interlocked.Exchange(ref m_endPoints, new List <IDisposable>()))
            {
                try
                {
                    // Try shutdown
                    endPoint.Dispose();
                }
                catch (Exception)
                {
                    // Ignore any error
                }
            }

            // Report
            VCRServer.Log(LoggingLevel.Full, Properties.Resources.WebServerStopped);
        }
Esempio n. 12
0
 /// <summary>
 /// Löst auf einem separaten <see cref="Thread"/> <see cref="OnPowerUp"/> aus.
 /// </summary>
 public static void OnResume()
 {
     // Start wakeup thread
     new Thread(forbid =>
     {
         // With reset
         using ((IDisposable)forbid)
             try
             {
                 // Trigger events
                 var sink = OnPowerUp;
                 if (sink != null)
                 {
                     sink();
                 }
             }
             catch (Exception e)
             {
                 // Report
                 VCRServer.Log(e);
             }
     }).Start(StartForbidHibernation());
 }
        /// <summary>
        /// Erstellt eine neue Planung.
        /// </summary>
        /// <param name="site">Die zugehörige Arbeitsumgebung.</param>
        private RecordingPlanner(IRecordingPlannerSite site)
        {
            // Remember
            m_site = site;

            // Process all profiles
            foreach (var profileName in site.ProfileNames)
            {
                // Look up the profile
                var profile = ProfileManager.FindProfile(profileName);
                if (profile == null)
                {
                    continue;
                }

                // Create the resource for it
                var profileResource = ProfileScheduleResource.Create(profileName);

                // Remember
                m_resources.Add(profileName, profileResource);

                // See if this is a leaf profile
                if (!string.IsNullOrEmpty(profile.UseSourcesFrom))
                {
                    continue;
                }

                // See if we should process guide updates
                var guideTask = site.CreateProgramGuideTask(profileResource, profile);
                if (guideTask != null)
                {
                    m_tasks.Add(guideTask);
                }

                // See if we should update the source list
                var scanTask = site.CreateSourceScanTask(profileResource, profile);
                if (scanTask != null)
                {
                    m_tasks.Add(scanTask);
                }
            }

            // Make sure we report all errors
            try
            {
                // Create the manager
                m_manager = ResourceManager.Create(site.ScheduleRulesPath, ProfileManager.ProfileNameComparer);
            }
            catch (Exception e)
            {
                // Report
                VCRServer.LogError(Properties.Resources.BadRuleFile, e.Message);

                // Use standard rules
                m_manager = ResourceManager.Create(ProfileManager.ProfileNameComparer);
            }

            // Safe configure it
            try
            {
                // All all resources
                foreach (var resource in m_resources.Values)
                {
                    m_manager.Add(resource);
                }
            }
            catch (Exception e)
            {
                // Cleanup
                Dispose();

                // Report
                VCRServer.Log(e);
            }
        }
        /// <summary>
        /// Startet die eigentlich Aufzeichnung in einer abgesicherten Umgebung.
        /// </summary>
        private void Run()
        {
            // Be fully safe
            try
            {
                // Create raw environment
                var coreEnvironment =
                    new Dictionary <string, string>
                {
                    { "%wakeupprofile%", ProfileState.WakeUpRequired ? "1" : "0" },
                    { "%dvbnetprofile%", ProfileName },
                };

                // Be fully safe
                try
                {
                    // Log it
                    VCRServer.Log(LoggingLevel.Schedules, Properties.Resources.RecordingStarted, TypeName);

                    // Report
                    Tools.ExtendedLogging("Started Recording Control Thread for {0}", ProfileName);

                    // Fire all extensions
                    Tools.RunSynchronousExtensions("BeforeProfileAccess", coreEnvironment);

                    // Use it
                    using (Server = CreateCardServerProxy())
                    {
                        // Check mode
                        var mustWakeUp = ProfileState.WakeUpRequired;
                        if (mustWakeUp)
                        {
                            // Log
                            VCRServer.Log(LoggingLevel.Full, Properties.Resources.RestartMessage);

                            // Report
                            Tools.ExtendedLogging("Will restart Hardware for {0} if Restart Device is configured in Profile", ProfileName);
                        }

                        // Start synchronously
                        ServerImplementation.EndRequest(
                            Server.BeginSetProfile
                            (
                                ProfileName,
                                mustWakeUp,
                                VCRConfiguration.Current.DisablePCRFromH264Generation,
                                VCRConfiguration.Current.DisablePCRFromMPEG2Generation
                            ));

                        // Report
                        Tools.ExtendedLogging("Card Server is up and running");

                        // Remember time
                        Representative.PhysicalStart = DateTime.UtcNow;

                        // Create fresh environment and fire extensions - with no files so far
                        FireRecordingStartedExtensions(ExtensionEnvironment = Representative.GetReplacementPatterns());

                        // Time to allow derived class to start up
                        OnStart();

                        // Process idle loop - done every second if not interrupted earlier
                        for (IAsyncResult <ServerInformation> stateRequest = null; ; m_wakeUp.WaitOne(m_running ? 1000 : 100))
                        {
                            // First check for state request
                            if (stateRequest != null)
                            {
                                // No yet done
                                if (!stateRequest.IsCompleted)
                                {
                                    continue;
                                }

                                // Process the state
                                OnNewStateAvailable(m_state = stateRequest.Result);

                                // No longer waiting for the next state
                                stateRequest = null;
                            }

                            // See if we are busy in the derived class
                            if (HasPendingServerRequest)
                            {
                                continue;
                            }

                            // Process actions - no asynchronous operations allowed in current version
                            ProcessActions();

                            // Make sure that scheduler knows we accepted the request
                            ConfirmPendingRequest();

                            // If we are still idle fire a new state request
                            if (!HasPendingServerRequest)
                            {
                                if (m_running)
                                {
                                    stateRequest = Server.BeginGetState();
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }

                        // Time to let derived class shut down properly
                        OnStop();

                        // Run final state update before protocol entry is created
                        if (m_state != null)
                        {
                            OnNewStateAvailable(m_state);
                        }

                        // Update recording data for the very last time
                        var info = CreateFullInformation(true);
                        if (info != null)
                        {
                            Representative = info.Recording;
                        }

                        // Set real send
                        Representative.EndsAt = DateTime.UtcNow;

                        // Set end state
                        ExtensionEnvironment["%Aborted%"] = m_aborted ? "1" : "0";

                        // Process extensions
                        FireRecordingFinishedExtensions(ExtensionEnvironment);

                        // No need for further wakeups
                        ProfileState.WakeUpRequired = false;
                    }
                }
                catch (Exception e)
                {
                    // Report
                    VCRServer.Log(e);

                    // Try to make sure that job is not restarted
                    try
                    {
                        // Update
                        SetRestartThreshold(null);
                    }
                    catch (Exception ex)
                    {
                        // Report
                        VCRServer.Log(ex);
                    }
                }
                finally
                {
                    // Detach from server - is already disposed and shut down
                    Server = null;

                    // Fire all extensions
                    Tools.RunSynchronousExtensions("AfterProfileAccess", coreEnvironment);

                    // Detach from profile
                    ProfileState.EndRequest(this);

                    // Write recording
                    ProfileState.Server.JobManager.CreateLogEntry(Representative);

                    // May go to sleep after job is finished
                    ProfileState.Server.ReportRecordingDone(Representative.DisableHibernation, IsRealRecording);

                    // Check for next job on all profiles
                    ProfileState.Collection.BeginNewPlan();

                    // Report
                    Tools.ExtendedLogging("Recording finished for {0}", ProfileName);

                    // Log it
                    VCRServer.Log(LoggingLevel.Schedules, Properties.Resources.RecordingFinished, TypeName);
                }
            }
            catch (Exception e)
            {
                // Report
                VCRServer.Log(e);
            }
            finally
            {
                // Make sure that even in case of error we do a full notification
                ConfirmPendingRequest(true);

                // Always fire event
                RequestFinished.Set();
            }
        }
        /// <summary>
        /// Bearbeitet einen einzelnen HTTP Aufruf.
        /// </summary>
        /// <param name="result">Der aktuelle Aufruf.</param>
        private void StartContext(IAsyncResult result)
        {
            // No longer active
            var listener = m_listener;

            if (listener == null)
            {
                return;
            }
            if (!listener.IsListening)
            {
                return;
            }

            // Correct counter
            Interlocked.Increment(ref m_Threads);

            // Check current state
            var endContext = true;

            // With cleanup
            try
            {
                // Context to process
                HttpListenerContext context;

                // Safe load
                try
                {
                    // Read the context
                    context = listener.EndGetContext(result);

                    // Got a full request
                    endContext = false;

                    // Special
                    if (context == null)
                    {
                        VCRServer.Log(LoggingLevel.Full, "Lost Context - Web Server may be in Error");
                    }
                }
                catch (Exception e)
                {
                    // This can be quite normal on XP so better only do a light report
                    Tools.ExtendedLogging("EndGetContext Exception: {0}", e.Message);

                    // Reset
                    context = null;
                }

                // Needs cleanup
                try
                {
                    // Start next
                    if (listener.IsListening)
                    {
                        listener.BeginGetContext(StartContext, null);
                    }

                    // Process
                    if (context != null)
                    {
                        RunTime.ProcessRequest(new ContextAccessor(context));
                    }
                }
                catch (Exception)
                {
                    // Be safe
                    try
                    {
                        // Release respose
                        if (context != null)
                        {
                            context.Response.Close();
                        }
                    }
                    catch
                    {
                        // Ignore any error during cleanup
                    }
                }
            }
            catch (ThreadAbortException e)
            {
                // Report
                VCRServer.Log(e);
            }
            catch (HttpListenerException e)
            {
                // Report
                if (!endContext)
                {
                    VCRServer.Log(e);
                }
            }
            catch (Exception e)
            {
                // Report
                VCRServer.Log(e);
            }
            finally
            {
                // Correct counter
                Interlocked.Decrement(ref m_Threads);
            }
        }
Esempio n. 16
0
        /// <summary>
        /// Steuert die Übergänge zwischen den Zuständen.
        /// </summary>
        private static void ControlThread()
        {
            // Process
            for (; ;)
            {
                // Collected change
                var operations = new List <Operation>();

                // Wait for next operation
                lock (m_operations)
                {
                    // Load
                    while (m_operations.Count < 1)
                    {
                        Monitor.Wait(m_operations);
                    }

                    // Detach - true is for forbid and false is for allow
                    while (m_operations.Count > 0)
                    {
                        operations.Add(m_operations.Dequeue());
                    }
                }

                // See if there is something to do
                var delta = operations.Sum(operation => operation.IsForbid ? +1 : -1);
                if (delta == 0)
                {
                    // Report
                    Tools.ExtendedLogging("PowerManagement Delta is 0");
                }
                else
                {
                    // To report transitions
                    var sink = OnChanged;

                    // Must forbid now
                    var oldCount = m_HibCount;
                    if (oldCount == 0)
                    {
                        if (SetThreadExecutionState(ExecutionState.SystemRequired | ExecutionState.Continuous) == ExecutionState.Error)
                        {
                            VCRServer.Log(LoggingLevel.Errors, Properties.Resources.HibernationNotBlocked);
                        }
                        else if (sink != null)
                        {
                            sink(true);
                        }
                    }

                    // Adjust
                    m_HibCount += delta;

                    // Must allow now
                    var newCount = m_HibCount;
                    if (newCount == 0)
                    {
                        if (SetThreadExecutionState(ExecutionState.Continuous) == ExecutionState.Error)
                        {
                            VCRServer.Log(LoggingLevel.Errors, Properties.Resources.HibernationNotUnblocked);
                        }
                        else if (sink != null)
                        {
                            sink(false);
                        }
                    }

                    // Report
                    Tools.ExtendedLogging("PowerManagement: {0} => {1}", oldCount, newCount);
                }

                // Wakeup all requestors to make call appear synchronously
                operations.ForEach(operation =>
                {
                    // Wakeup
                    lock (operation)
                        Monitor.PulseAll(operation);
                });
            }
        }