/// <summary>
        /// Wählt eine Quellgruppe aus.
        /// </summary>
        /// <param name="group">Díe Daten der Quellgruppe.</param>
        /// <param name="location">Die Wahl des Ursprungs, über den die Quellgruppe empfangen werden kann.</param>
        public void Tune(SourceGroup group, GroupLocation location)
        {
            // May repeat some times
            for (int retryCount = 3; retryCount-- > 0; Thread.Sleep(250))
            {
                // All supported in order of importance
                if (!Tune(group as SatelliteGroup, location as SatelliteLocation).HasValue)
                {
                    if (!Tune(group as CableGroup).HasValue)
                    {
                        if (!Tune(group as TerrestrialGroup).HasValue)
                        {
                            throw new DVBException("Unsupported channel type " + group.GetType().FullName);
                        }
                    }
                }

                // Done if locked
                if (SignalStatus.Locked)
                {
                    break;
                }

                // Enforce reset
                m_lastMessage = null;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Wählt eine Quellgruppe aus.
        /// </summary>
        /// <param name="group">Díe Daten der Quellgruppe.</param>
        /// <param name="location">Die Wahl des Ursprungs, über den die Quellgruppe empfangen werden kann.</param>
        /// <returns>Gesetzt, wenn es sich um eine DVB-S Quellgruppe handelt.</returns>
        public void SetChannel(SourceGroup group, GroupLocation location)
        {
            // Stop all filters
            StopFilters();

            // May repeat some times
            for (int nRetry = 3; nRetry-- > 0;)
            {
                // Supported types in order of importance
                if (!SendChannel(group as SatelliteGroup, location as SatelliteLocation))
                {
                    if (!SendChannel(group as CableGroup))
                    {
                        if (!SendChannel(group as TerrestrialGroup))
                        {
                            throw new DVBException("Unsupported Channel Type " + group.GetType().FullName);
                        }
                    }
                }

                // Wait for the signal
                for (int n = 10; n-- > 0; Thread.Sleep(50))
                {
                    if (SignalStatus.Locked)
                    {
                        return;
                    }
                }

                // Force to resend DiSEqC command
                m_lastMessage = null;
            }
        }
Beispiel #3
0
        /// <summary>
        /// Initialize the frontend.
        /// </summary>
        /// <remarks>
        /// When the C++ method invocation reports a hardware error the call is repeated
        /// up to three times with a <see cref="Thread.Sleep(int)"/>(500) between the calls.
        /// If the error holds a <see cref="DVBException"/> is thrown.
        /// <see cref="StopFilters"/>
        /// </remarks>
        /// <exception cref="DVBException">
        /// Thrown when the C++ method invocation reports some <see cref="DVBError"/>.
        /// </exception>
        public void Initialize()
        {
            // Time to stop all filters
            StopFilters();

            // Execute
            DVBError eCode = CDVBFrontend_Init(m_Class.ClassPointer);

            // Retry
            for (int nRetry = 3; (DVBError.Hardware == eCode) && (nRetry-- > 0);)
            {
                // Delay
                Thread.Sleep(500);

                // Try again
                eCode = CDVBFrontend_Init(m_Class.ClassPointer);
            }

            // Validate
            if (DVBError.None != eCode)
            {
                throw new DVBException("Can not initialize Frontend", eCode);
            }

            // Reset
            m_lastMessage = null;
        }
        /// <summary>
        /// Führt die DiSEqC Steuerung aus.
        /// </summary>
        /// <param name="token">Die Informationen zur aktuellen Wahl der Quellgruppe.</param>
        /// <returns>Das Ergebnis der Operation.</returns>
        private PipelineResult ApplyDiSEqC(DataGraph.TuneToken token)
        {
            // See if we are fully active
            var message = (token == null) ? null : token.DiSEqCMessage;

            if (message == null)
            {
                // Shutdown connection
                Close();

                // Reset
                m_LastDiSEqC = null;

                // Next
                return(PipelineResult.Continue);
            }

            // Attach to tuner
            var tuner = token.Pipeline.Graph.TunerFilter;

            if (tuner == null)
            {
                return(PipelineResult.Continue);
            }

            // Verify that grpah is created
            if (token.Pipeline.Graph.TransportStreamAnalyser == null)
            {
                return(PipelineResult.Continue);
            }

            // Already did it
            if (message.Equals(m_LastDiSEqC))
            {
                return(PipelineResult.Continue);
            }

            // Open the device
            Open(tuner);
            try
            {
                // Process
                var data  = (byte[])message.Request.Clone();
                var error = bdaapiSetDiSEqCMsg(Device, data, (byte)data.Length, (byte)message.Repeat, message.Burst, Polarisation.NotSet);
                if (error == APIErrorCodes.Success)
                {
                    m_LastDiSEqC = message.Clone();
                }
                else
                {
                    throw new DVBException(error.ToString());
                }
            }
            catch (Exception e)
            {
                // Report
                EventLog.WriteEntry("DVB.NET", string.Format("TechnoTrend BDA API DiSEqC: {0}", e), EventLogEntryType.Error);

                // Force recalibrate on next call
                m_LastDiSEqC = null;
            }

            // Next one, please
            return(PipelineResult.Continue);
        }
        /// <summary>
        /// Übernimmt die Ansteuerung einer Antenne.
        /// </summary>
        /// <param name="tune">Der aktuelle Änderungswunsch.</param>
        /// <returns>Beschreibt, wie weiter fortzufahren ist.</returns>
        private PipelineResult ApplyDiSEqC(DataGraph.TuneToken tune)
        {
            // Not active
            var diseqc = (tune == null) ? null : tune.DiSEqCMessage;

            if (diseqc == null)
            {
                // Reset request - or first call at all
                m_LastDiSEqC = null;

                // Next
                return(PipelineResult.Continue);
            }

            // Attach to tuner
            var tuner = tune.Pipeline.Graph.TunerFilter;

            if (tuner == null)
            {
                return(PipelineResult.Continue);
            }

            // Verify that grpah is created
            if (tune.Pipeline.Graph.TransportStreamAnalyser == null)
            {
                return(PipelineResult.Continue);
            }

            // Request the message to send
            if (diseqc.Equals(m_LastDiSEqC))
            {
                return(PipelineResult.Continue);
            }

            // Attach to the one input pin of the tuner
            using (var input = tuner.GetSinglePin(PinDirection.Input))
                using (var propertySet = KsPropertySet.Create <NovaDiSEqCMessage>(input.Interface))
                    if (propertySet != null)
                    {
                        // Create the identifier of the property to use
                        var nodeReference = KsPNode.Create(BdaTunerExtensionProperties, BDATunerExtensions.DiSEqC, BDANodes.Tuner);

                        // Check for support of the property
                        if (!propertySet.DoesSupport(nodeReference, PropertySetSupportedTypes.Set))
                        {
                            return(PipelineResult.Continue);
                        }

                        // Create structures
                        var message = new NovaDiSEqCMessage();

                        // Create a copy
                        var command = (byte[])diseqc.Request.Clone();

                        // As long as necessary
                        for (int nCount = diseqc.Repeat; nCount-- > 0; Thread.Sleep(120))
                        {
                            try
                            {
                                // Prepare the message
                                message.Request  = new byte[151];
                                message.Response = new byte[9];

                                // Fill the message
                                command.CopyTo(message.Request, 0);

                                // Set the lengths
                                message.RequestLength  = (uint)command.Length;
                                message.ResponseLength = 0;

                                // Configure
                                message.ToneBurstModulation  = (ToneBurstModulationModes)diseqc.Burst;
                                message.ResponseMode         = DiSEqCReceiveModes.NoReply;
                                message.DiSEqCVersion        = DiSEqCVersions.Version1;
                                message.AmplitudeAttenuation = 3;
                                message.LastMessage          = true;

                                // Send the message
                                propertySet.Set(nodeReference, message);

                                // Set repeat flag
                                if (command.Length > 0)
                                {
                                    command[0] |= 1;
                                }
                            }
                            catch
                            {
                                // Reset
                                m_LastDiSEqC = null;

                                // Forward
                                throw;
                            }
                        }

                        // Remember
                        m_LastDiSEqC = diseqc.Clone();
                    }

            // Done
            return(PipelineResult.Continue);
        }
        /// <summary>
        /// Wählt eine Quellgruppe aus.
        /// </summary>
        /// <param name="group">Díe Daten der Quellgruppe.</param>
        /// <param name="location">Die Wahl des Ursprungs, über den die Quellgruppe empfangen werden kann.</param>
        /// <returns>Gesetzt, wenn es sich um eine DVB-S Quellgruppe handelt.</returns>
        private Channel_S?Tune(SatelliteGroup group, SatelliteLocation location)
        {
            // Not us
            if (location == null)
            {
                return(null);
            }
            if (group == null)
            {
                return(null);
            }

            // Validate
            if (FrontendType != FrontendType.Satellite)
            {
                throw new DVBException("Expected " + FrontendType.ToString() + " Channel");
            }

            // Create channel
            var data =
                new Channel_S
            {
                Mode       = group.UsesS2Modulation ? DVBSMode.DVB_S2 : DVBSMode.DVB_S,
                Inversion  = SpectrumInversion.Auto,
                SymbolRate = group.SymbolRate,
                Frequency  = group.Frequency,
            };


            // Attach to the DiSEqC setting
            var selector = StandardDiSEqC.FromSourceGroup(group, location);

            // See if the message is different from the last one
            if (!selector.Equals(m_lastMessage))
            {
                // Remember
                m_lastMessage = selector.Clone();

                // As long as necessary
                for (int nCount = selector.Repeat; nCount-- > 0; Thread.Sleep(120))
                {
                    // Send it
                    DVBException.ThrowOnError(_SendDiSEqCMsg(m_Class.ClassPointer, selector.Request, (byte)selector.Request.Length, selector.Burst), "Could not send DiSEqC message");

                    // Set repeat flag
                    if (selector.Request.Length > 0)
                    {
                        selector.Request[0] |= 1;
                    }
                }
            }

            // Calculated items
            data.b22kHz = (group.Frequency >= location.SwitchFrequency) ? 1 : 0;
            data.LOF    = (0 == data.b22kHz) ? location.Frequency1 : location.Frequency2;

            // Power modes
            switch (group.Polarization)
            {
            case Polarizations.Horizontal: data.LNBPower = PowerMode.Horizontal; break;

            case Polarizations.Vertical: data.LNBPower = PowerMode.Vertical; break;

            case Polarizations.NotDefined: data.LNBPower = PowerMode.Off; break;

            default: throw new ArgumentException(group.Polarization.ToString(), "Polarization");
            }

            // Process
            return(data.SetChannel(this, false));
        }
Beispiel #7
0
        /// <summary>
        /// Wählt eine Quellgruppe aus.
        /// </summary>
        /// <param name="group">Díe Daten der Quellgruppe.</param>
        /// <param name="location">Die Wahl des Ursprungs, über den die Quellgruppe empfangen werden kann.</param>
        /// <returns>Gesetzt, wenn es sich um eine DVB-S Quellgruppe handelt.</returns>
        private bool SendChannel(SatelliteGroup group, SatelliteLocation location)
        {
            // Not us
            if (location == null)
            {
                return(false);
            }
            if (group == null)
            {
                return(false);
            }

            // Validate
            if (FrontendType != FrontendType.Satellite)
            {
                throw new DVBException("Expected " + FrontendType.ToString() + " Channel");
            }

            // Create channel
            var channel =
                new Channel_S
            {
                Inversion  = SpectrumInversion.Auto,
                SymbolRate = group.SymbolRate,
                Frequency  = group.Frequency,
            };

            // Attach to the DiSEqC setting
            var selector = StandardDiSEqC.FromSourceGroup(group, location);

            // See if the message is different from the last one
            if (!selector.Equals(m_lastMessage))
            {
                // Remember
                m_lastMessage = selector.Clone();

                // As long as necessary
                for (int nCount = selector.Repeat; nCount-- > 0; Thread.Sleep(120))
                {
                    // Send it
                    DVBException.ThrowOnError(CDVBFrontend_SendDiSEqCMsg(m_Class.ClassPointer, selector.Request, (byte)selector.Request.Length, selector.Burst), "Could not send DiSEqC Message");

                    // Set repeat flag
                    if (selector.Request.Length > 0)
                    {
                        selector.Request[0] |= 1;
                    }
                }
            }

            // Calculated items
            channel.b22kHz = (group.Frequency >= location.SwitchFrequency) ? 1 : 0;
            channel.LOF    = (0 == channel.b22kHz) ? location.Frequency1 : location.Frequency2;

            // Power modes
            switch (group.Polarization)
            {
            case Polarizations.Horizontal: channel.LNBPower = PowerMode.Horizontal; break;

            case Polarizations.Vertical: channel.LNBPower = PowerMode.Vertical; break;

            case Polarizations.NotDefined: channel.LNBPower = PowerMode.Off; break;

            default: throw new ArgumentException(group.Polarization.ToString(), "Polarization");
            }

            // Process
            CheckChannel(CDVBFrontend_SetChannel(m_Class.ClassPointer, channel, false));

            // Check up for synchronisation
            Channel_S val1, val2;

            // Get channel twice
            CheckChannel(CDVBFrontend_GetChannel(m_Class.ClassPointer, out val1));
            CheckChannel(CDVBFrontend_GetChannel(m_Class.ClassPointer, out val2));

            // Did it
            return(true);
        }
        /// <summary>
        /// Führt die DiSEqC Steuerung aus.
        /// </summary>
        /// <param name="token">Die aktuellen Informationen zum Wechsel der Quellgruppe.</param>
        /// <returns>Meldet, wie die weitere Abarbeitung zu erfolgen hat.</returns>
        private PipelineResult ApplyDiSEqC(DataGraph.TuneToken token)
        {
            // Not active
            var diseqc = (token == null) ? null : token.DiSEqCMessage;

            if (diseqc == null)
            {
                // Reset request - or first call at all
                m_LastDiSEqC = null;

                // Next
                return(PipelineResult.Continue);
            }

            // Attach to tuner
            var tuner = token.Pipeline.Graph.TunerFilter;

            if (tuner == null)
            {
                return(PipelineResult.Continue);
            }

            // Verify that grpah is created
            if (token.Pipeline.Graph.TransportStreamAnalyser == null)
            {
                return(PipelineResult.Continue);
            }

            // Request the message to send
            if (diseqc.Equals(m_LastDiSEqC))
            {
                return(PipelineResult.Continue);
            }

            // Attach to the one input pin of the tuner
            using (var input = tuner.GetSinglePin(PinDirection.Input))
                using (var propertySet = KsPropertySet.Create <DiSEqCMessage>(input.Interface))
                    if (propertySet != null)
                    {
                        // Create the identifier of the property to use
                        var nodeReference = KsPNode.Create(TunerExtensionPropertiesS2, TunerExtensionProperties.DiSEqC, 0);

                        // Check for support of the property
                        if (!propertySet.DoesSupport(nodeReference, PropertySetSupportedTypes.Set))
                        {
                            return(PipelineResult.Continue);
                        }

                        // Create structures
                        var message = new DiSEqCMessage();

                        // Create a copy
                        var command = (byte[])diseqc.Request.Clone();

                        // As long as necessary
                        try
                        {
                            // Prepare the message
                            message.Request = new byte[151];

                            // Fill the message
                            command.CopyTo(message.Request, 0);

                            // Configure
                            message.RequestLength = (byte)command.Length;
                            message.LastMessage   = true;
                            message.Power         = 0;

                            // Send the message
                            propertySet.Set(nodeReference, message);
                        }
                        catch
                        {
                            // Reset
                            m_LastDiSEqC = null;

                            // Forward
                            throw;
                        }

                        // Remember
                        m_LastDiSEqC = diseqc.Clone();
                    }

            // Next
            return(PipelineResult.Continue);
        }