/// <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; } }
/// <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; } }
/// <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)); }
/// <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); }