Rewrote the complete blindscanning engine.
This commit is contained in:
parent
1d7c9c3807
commit
03d827df44
@ -168,7 +168,62 @@ namespace skyscraper5.Data.PostgreSql
|
|||||||
return new object[] { pluginToken };
|
return new object[] { pluginToken };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void InsertUiBlindscanSettingHistory(int settingsWindowBlScanTunerSelection,
|
||||||
|
bool settingsWindowUseDifferentTunerForSetFilter, int settingsWindowSetFilterTunerSelection,
|
||||||
|
int settingsWindowDiseqc, bool settingsWindowCollectIqGraphs, bool settingsWindowCollectRfSpectrum,
|
||||||
|
bool settingsWindowCaptureFile, int settingsWindowSatellite, int settingsWindowLnb, int dish,
|
||||||
|
bool settingsWindowScanHorizontalLow, bool settingsWindowScanHorizontalHigh, bool settingsWindowScanVerticalLow,
|
||||||
|
bool settingsWindowScanVerticalHigh)
|
||||||
|
{
|
||||||
|
using (NpgsqlConnection connection = new NpgsqlConnection(connectionStringBuilder.ToString()))
|
||||||
|
{
|
||||||
|
connection.Open();
|
||||||
|
NpgsqlCommand command = connection.CreateCommand();
|
||||||
|
command.CommandText =
|
||||||
|
"INSERT INTO ui_blindscan_setting_history VALUES (DEFAULT,@bstselection,@ustfsfilter,@sftselection,@diseqc,@cigraphs,@crspectrum,@cfilters,@satellite,@lnb,@dish,@hl,@hh,@vl,@vh);";
|
||||||
|
command.Parameters.AddWithValue("@bstselection", NpgsqlDbType.Integer, settingsWindowBlScanTunerSelection);
|
||||||
|
command.Parameters.AddWithValue("@ustfsfilter", NpgsqlDbType.Boolean, settingsWindowUseDifferentTunerForSetFilter);
|
||||||
|
command.Parameters.AddWithValue("@sftselection", NpgsqlDbType.Integer, settingsWindowSetFilterTunerSelection);
|
||||||
|
command.Parameters.AddWithValue("@diseqc", NpgsqlDbType.Integer, settingsWindowDiseqc);
|
||||||
|
command.Parameters.AddWithValue("@cigraphs", NpgsqlDbType.Boolean, settingsWindowCollectIqGraphs);
|
||||||
|
command.Parameters.AddWithValue("@crspectrum", NpgsqlDbType.Boolean, settingsWindowCollectRfSpectrum);
|
||||||
|
command.Parameters.AddWithValue("@cfilters", NpgsqlDbType.Boolean, settingsWindowCaptureFile);
|
||||||
|
command.Parameters.AddWithValue("@satellite", NpgsqlDbType.Integer, settingsWindowSatellite);
|
||||||
|
command.Parameters.AddWithValue("@lnb", NpgsqlDbType.Integer, settingsWindowLnb);
|
||||||
|
command.Parameters.AddWithValue("@dish", NpgsqlDbType.Integer, dish);
|
||||||
|
command.Parameters.AddWithValue("@hl", NpgsqlDbType.Boolean, settingsWindowScanHorizontalLow);
|
||||||
|
command.Parameters.AddWithValue("@hh", NpgsqlDbType.Boolean, settingsWindowScanHorizontalHigh);
|
||||||
|
command.Parameters.AddWithValue("@vl", NpgsqlDbType.Boolean, settingsWindowScanVerticalLow);
|
||||||
|
command.Parameters.AddWithValue("@vh", NpgsqlDbType.Boolean, settingsWindowScanVerticalHigh);
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
connection.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] GetLastUiBlindscanSettings()
|
||||||
|
{
|
||||||
|
using (NpgsqlConnection connection = new NpgsqlConnection(connectionStringBuilder.ToString()))
|
||||||
|
{
|
||||||
|
connection.Open();
|
||||||
|
NpgsqlCommand command = connection.CreateCommand();
|
||||||
|
command.CommandText = "SELECT * FROM ui_blindscan_setting_history WHERE dateadded = (SELECT MAX(dateadded) FROM ui_blindscan_setting_history)";
|
||||||
|
NpgsqlDataReader dataReader = command.ExecuteReader();
|
||||||
|
object[] result = null;
|
||||||
|
if (dataReader.Read())
|
||||||
|
{
|
||||||
|
int fields = dataReader.FieldCount;
|
||||||
|
result = new object[fields];
|
||||||
|
for (int i = 0; i < fields; i++)
|
||||||
|
{
|
||||||
|
result[i] = dataReader.GetValue(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dataReader.Close();
|
||||||
|
command.Dispose();
|
||||||
|
connection.Close();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,8 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using SDL2Demo.Jobs;
|
||||||
|
using skyscraper8.Skyscraper.FrequencyListGenerator;
|
||||||
using static SDL2Demo.Jobs.Blindscan;
|
using static SDL2Demo.Jobs.Blindscan;
|
||||||
|
|
||||||
namespace SDL2Demo.Forms
|
namespace SDL2Demo.Forms
|
||||||
@ -98,6 +100,19 @@ namespace SDL2Demo.Forms
|
|||||||
ImGui.End();
|
ImGui.End();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Add(BlindscanSearchResult searchResult, int polarityIndex, int lnbTypeMinimumFrequency, int i)
|
||||||
|
{
|
||||||
|
if (searchResult.IsSatellite())
|
||||||
|
_blindscanResults.Add(new Blindscan.BlindscanResult(searchResult.SearchResult, lnbTypeMinimumFrequency, i));
|
||||||
|
else
|
||||||
|
_blindscanResults.Add(new BlindscanResult(searchResult.SearchResult2, lnbTypeMinimumFrequency, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_blindscanResults.Clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
93
GUIs/skyscraper8.UI.ImGui/Forms/FoundFrequenciesWindow2.cs
Normal file
93
GUIs/skyscraper8.UI.ImGui/Forms/FoundFrequenciesWindow2.cs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
using SDL2Demo;
|
||||||
|
using skyscraper8.Skyscraper.FrequencyListGenerator;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using ImGuiNET;
|
||||||
|
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
||||||
|
|
||||||
|
namespace SDL2Demo
|
||||||
|
{
|
||||||
|
internal class FoundFrequenciesWindow2 : IRenderable
|
||||||
|
{
|
||||||
|
private readonly List<BlindscanSearchResult> _foundFrequencies;
|
||||||
|
public bool doNotAutoZap;
|
||||||
|
public bool allowZapNow;
|
||||||
|
public bool zapNowRequested;
|
||||||
|
private string tableUuid;
|
||||||
|
public long statusPacketsInTotal;
|
||||||
|
public long statusPacketsInQueue;
|
||||||
|
|
||||||
|
public FoundFrequenciesWindow2(List<BlindscanSearchResult> foundFrequencies)
|
||||||
|
{
|
||||||
|
_foundFrequencies = foundFrequencies;
|
||||||
|
tableUuid = Guid.NewGuid().ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Render()
|
||||||
|
{
|
||||||
|
if (_foundFrequencies.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ImGui.Begin("Blind-Scan Results"))
|
||||||
|
{
|
||||||
|
ImGui.Checkbox("Do not Auto-Zap", ref doNotAutoZap);
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.BeginDisabled(!allowZapNow);
|
||||||
|
if (ImGui.Button("Zap now"))
|
||||||
|
{
|
||||||
|
zapNowRequested = true;
|
||||||
|
}
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
|
if (allowZapNow)
|
||||||
|
{
|
||||||
|
ImGui.Text(String.Format("{0} packets received in total, {1} queued.", statusPacketsInTotal, statusPacketsInQueue));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.BeginTable(tableUuid, 5,
|
||||||
|
ImGuiTableFlags.NoSavedSettings | ImGuiTableFlags.SizingFixedFit))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _foundFrequencies.Count; i++)
|
||||||
|
{
|
||||||
|
BlindscanSearchResult blindscanResult = _foundFrequencies[i];
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
if (blindscanResult.IsSatellite())
|
||||||
|
{
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
ImGui.Text(String.Format("{0} {1} ", blindscanResult.SearchResult.Freq / 1000,
|
||||||
|
blindscanResult.SearchResult.Pol == 0 ? "H" : "V"));
|
||||||
|
|
||||||
|
ImGui.TableSetColumnIndex(1);
|
||||||
|
ImGui.Text((blindscanResult.SearchResult.SR / 1000).ToString());
|
||||||
|
|
||||||
|
ImGui.TableSetColumnIndex(2);
|
||||||
|
ImGui.Text(((MOD_TYPE)blindscanResult.SearchResult.ModType).ToString());
|
||||||
|
|
||||||
|
ImGui.TableSetColumnIndex(3);
|
||||||
|
ImGui.Text((blindscanResult.SearchResult.MIS + 1).ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
ImGui.Text((blindscanResult.SearchResult.Freq / 1000).ToString());
|
||||||
|
|
||||||
|
ImGui.TableSetColumnIndex(1);
|
||||||
|
ImGui.Text((blindscanResult.SearchResult.SR / 10).ToString());
|
||||||
|
|
||||||
|
ImGui.TableSetColumnIndex(2);
|
||||||
|
ImGui.Text(((MOD_TYPE)blindscanResult.SearchResult.ModType).ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TableSetColumnIndex(4);
|
||||||
|
ImGui.Text(blindscanResult.State.ToString());
|
||||||
|
}
|
||||||
|
ImGui.EndTable();
|
||||||
|
}
|
||||||
|
ImGui.End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -21,10 +21,14 @@ using skyscraper5.Mpeg2;
|
|||||||
using skyscraper5.Mpeg2.Descriptors;
|
using skyscraper5.Mpeg2.Descriptors;
|
||||||
using skyscraper5.Mpeg2.Psi.Model;
|
using skyscraper5.Mpeg2.Psi.Model;
|
||||||
using skyscraper5.Scte35;
|
using skyscraper5.Scte35;
|
||||||
|
using skyscraper5.Skyscraper.Equipment;
|
||||||
|
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
||||||
using skyscraper5.Skyscraper.Net;
|
using skyscraper5.Skyscraper.Net;
|
||||||
using skyscraper5.Skyscraper.Scraper;
|
using skyscraper5.Skyscraper.Scraper;
|
||||||
using skyscraper5.src.Skyscraper.FrequencyListGenerator;
|
using skyscraper5.src.Skyscraper.FrequencyListGenerator;
|
||||||
using skyscraper5.Teletext.Wss;
|
using skyscraper5.Teletext.Wss;
|
||||||
|
using skyscraper8.Skyscraper.Drawing;
|
||||||
|
using skyscraper8.Skyscraper.FrequencyListGenerator;
|
||||||
using testdrid.SdlWrapper;
|
using testdrid.SdlWrapper;
|
||||||
|
|
||||||
namespace SDL2Demo.Forms
|
namespace SDL2Demo.Forms
|
||||||
@ -2060,6 +2064,126 @@ namespace SDL2Demo.Forms
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public void OnBlindscanOpenFoundFrquenciesWindow(List<BlindscanSearchResult> foundFrequencies, STD_TYPE tunerMetadataType)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanJobDone(bool success)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanErrorMessage(string blindscanningLowHorizontalAreaFailed)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanBandComplete()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanBeforeBLScan(int minimum, int currentProgress, int maximum)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanAfterBLScan()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanSearchResult1Callback(BlindscanSearchResult searchResult, int polarityIndex,
|
||||||
|
int lnbTypeMinimumFrequency, int lnbTypeMaximumFrequency)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanBeforeSetChannel(BlindscanSearchResult blindscanResult,LnbType lnbType)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnScrapeBandComplete()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanScrapeTransponderComplete(BlindscanSearchResult blindscanResult)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanBeginRfSpectrum()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanRfSpectrumEnqueueSample(SatelliteDeliverySystemDescriptor.PolarizationEnum polarization, int frequency, double rf)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanEndRfSpectrum()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanBeginIqSpectrum(IqChartData result)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanEndIq()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanLockFail(SearchResult satelliteSr, BlindscanResultState resultState)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanFilterSetUp()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanScrapeStopCondition()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanAfterPacketDrain()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanPacketError(int errorCount, int length)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnBlindscanPacketOk(int numPackets, int packetsQueueCount)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsZapNowRequested()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MayAutoZap()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskQueue Tasks { get; set; }
|
||||||
|
|
||||||
private ushort? ResolveCaId(ProgramMapping patValuePmt, SdtCoordinate sdt)
|
private ushort? ResolveCaId(ProgramMapping patValuePmt, SdtCoordinate sdt)
|
||||||
{
|
{
|
||||||
if (patValuePmt != null)
|
if (patValuePmt != null)
|
||||||
@ -2082,8 +2206,6 @@ namespace SDL2Demo.Forms
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
|||||||
using Echo.UserInterface.Backend;
|
using Echo.UserInterface.Backend;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using SDL2;
|
using SDL2;
|
||||||
|
using skyscraper8.Skyscraper.FrequencyListGenerator;
|
||||||
using testdrid.SdlWrapper;
|
using testdrid.SdlWrapper;
|
||||||
|
|
||||||
namespace SDL2Demo.Forms
|
namespace SDL2Demo.Forms
|
||||||
@ -60,12 +61,22 @@ namespace SDL2Demo.Forms
|
|||||||
ImGui.End();
|
ImGui.End();
|
||||||
ImGui.PopStyleVar();
|
ImGui.PopStyleVar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private bool disposed;
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_texture.Dispose();
|
if (disposed)
|
||||||
_surface.Dispose();
|
return;
|
||||||
|
|
||||||
|
tasks.EnqueueTask(() =>
|
||||||
|
{
|
||||||
|
renderables.Remove(this);
|
||||||
|
_texture.Dispose();
|
||||||
|
_surface.Dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
disposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Renderer Renderer { get; set; }
|
internal static Renderer Renderer { get; set; }
|
||||||
@ -75,5 +86,13 @@ namespace SDL2Demo.Forms
|
|||||||
position.X = x;
|
position.X = x;
|
||||||
position.Y = y;
|
position.Y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TaskQueue tasks;
|
||||||
|
private List<IRenderable> renderables;
|
||||||
|
public void SetTaskQueue(TaskQueue tasks, List<IRenderable> jobContextRenderables)
|
||||||
|
{
|
||||||
|
this.tasks = tasks;
|
||||||
|
this.renderables = jobContextRenderables;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -59,6 +59,7 @@ namespace skyscraper8.UI.ImGui.Forms
|
|||||||
_plot.Dispose();
|
_plot.Dispose();
|
||||||
_skBitmap.Dispose();
|
_skBitmap.Dispose();
|
||||||
_skCanvas.Dispose();
|
_skCanvas.Dispose();
|
||||||
|
_texture.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -314,7 +314,7 @@ namespace SDL2Demo.Jobs
|
|||||||
public BlindscanResult(SearchResult searchResult, int satPositionMinFreq, int satPositionMaxFreq)
|
public BlindscanResult(SearchResult searchResult, int satPositionMinFreq, int satPositionMaxFreq)
|
||||||
{
|
{
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
|
|
||||||
if (searchResult.Pol == 0)
|
if (searchResult.Pol == 0)
|
||||||
{
|
{
|
||||||
//Horizontal
|
//Horizontal
|
||||||
|
|||||||
247
GUIs/skyscraper8.UI.ImGui/Jobs/InheritedBlindscanConfigWindow.cs
Normal file
247
GUIs/skyscraper8.UI.ImGui/Jobs/InheritedBlindscanConfigWindow.cs
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
using ImGuiNET;
|
||||||
|
using skyscraper5.Skyscraper;
|
||||||
|
using skyscraper5.Skyscraper.Equipment;
|
||||||
|
using skyscraper5.Skyscraper.Gps;
|
||||||
|
using skyscraper5.Skyscraper.IO;
|
||||||
|
using skyscraper8.Skyscraper.FrequencyListGenerator;
|
||||||
|
using skyscraper8.Skyscraper.Scraper.Storage;
|
||||||
|
using skyscraper8.UI.SDL2.Jobs;
|
||||||
|
|
||||||
|
namespace SDL2Demo.Jobs
|
||||||
|
{
|
||||||
|
internal class InheritedBlindscanConfigWindow : IRenderable
|
||||||
|
{
|
||||||
|
private bool windowOpen;
|
||||||
|
private List<TunerMetadata> tuners;
|
||||||
|
private List<SatellitePosition> satellites;
|
||||||
|
private List<LnbType> lnbs;
|
||||||
|
private List<DishType> dishes;
|
||||||
|
private readonly TaskQueue _taskQueue;
|
||||||
|
|
||||||
|
public int settingsWindowBLScanTunerSelection;
|
||||||
|
public bool settingsWindowUseDifferentTunerForSetFilter;
|
||||||
|
public int settingsWindowSetFilterTunerSelection;
|
||||||
|
public int settingsWindowDiseqc;
|
||||||
|
public bool settingsWindowCollectIqGraphs;
|
||||||
|
public bool settingsWindowCollectRfSpectrum;
|
||||||
|
public bool settingsWindowCaptureFile;
|
||||||
|
public int settingsWindowSatellite;
|
||||||
|
public int settingsWindowLNB;
|
||||||
|
public int settingsWindowDish;
|
||||||
|
|
||||||
|
public bool settingsWindowScanHorizontalLow;
|
||||||
|
public bool settingsWindowScanHorizontalHigh;
|
||||||
|
public bool settingsWindowScanVerticalLow;
|
||||||
|
public bool settingsWindowScanVerticalHigh;
|
||||||
|
|
||||||
|
private DataStorage dataStorage;
|
||||||
|
private ObjectStorage objectStorage;
|
||||||
|
private IGpsReceiver gpsReceiver;
|
||||||
|
private Ini ini;
|
||||||
|
private IStreamReader streamReader;
|
||||||
|
|
||||||
|
private void StoreSettings()
|
||||||
|
{
|
||||||
|
dataStorage.InsertUiBlindscanSettingHistory(settingsWindowBLScanTunerSelection,
|
||||||
|
settingsWindowUseDifferentTunerForSetFilter, settingsWindowSetFilterTunerSelection,
|
||||||
|
settingsWindowDiseqc, settingsWindowCollectIqGraphs,
|
||||||
|
settingsWindowCollectRfSpectrum, settingsWindowCaptureFile, settingsWindowSatellite, settingsWindowLNB,
|
||||||
|
settingsWindowDish, settingsWindowScanHorizontalLow, settingsWindowScanHorizontalHigh,
|
||||||
|
settingsWindowScanVerticalLow, settingsWindowScanVerticalHigh);
|
||||||
|
}
|
||||||
|
public InheritedBlindscanConfigWindow(List<TunerMetadata> tunerMetadatas,
|
||||||
|
List<SatellitePosition> satellitePositions, List<LnbType> lnbTypes, List<DishType> dishTypes,
|
||||||
|
DataStorage dataStorage, ObjectStorage objectStorage, IGpsReceiver gps, Ini ini, IStreamReader streamReader,
|
||||||
|
TaskQueue taskQueue)
|
||||||
|
{
|
||||||
|
tuners = tunerMetadatas;
|
||||||
|
satellites = satellitePositions;
|
||||||
|
lnbs = lnbTypes;
|
||||||
|
dishes = dishTypes;
|
||||||
|
windowOpen = true;
|
||||||
|
settingsWindowDiseqc = 1;
|
||||||
|
this.dataStorage = dataStorage;
|
||||||
|
this.objectStorage = objectStorage;
|
||||||
|
this.gpsReceiver = gps;
|
||||||
|
this.ini = ini;
|
||||||
|
this.streamReader = streamReader;
|
||||||
|
_taskQueue = taskQueue;
|
||||||
|
|
||||||
|
object[] previousSettings = dataStorage.GetLastUiBlindscanSettings();
|
||||||
|
if (previousSettings != null)
|
||||||
|
{
|
||||||
|
settingsWindowBLScanTunerSelection = (int)previousSettings[1];
|
||||||
|
settingsWindowUseDifferentTunerForSetFilter = (bool)previousSettings[2];
|
||||||
|
settingsWindowSetFilterTunerSelection = (int)previousSettings[3];
|
||||||
|
settingsWindowDiseqc = (int)previousSettings[4];
|
||||||
|
settingsWindowCollectIqGraphs = (bool)previousSettings[5];
|
||||||
|
settingsWindowCollectRfSpectrum = (bool)previousSettings[6];
|
||||||
|
settingsWindowCaptureFile = (bool)previousSettings[7];
|
||||||
|
settingsWindowSatellite = (int)previousSettings[8];
|
||||||
|
settingsWindowLNB = (int)previousSettings[9];
|
||||||
|
settingsWindowDish = (int)previousSettings[10];
|
||||||
|
|
||||||
|
settingsWindowScanHorizontalLow = (bool)previousSettings[11];
|
||||||
|
settingsWindowScanHorizontalHigh = (bool)previousSettings[12];
|
||||||
|
settingsWindowScanVerticalLow = (bool)previousSettings[13];
|
||||||
|
settingsWindowScanVerticalHigh = (bool)previousSettings[14];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool IsWindowOpen()
|
||||||
|
{
|
||||||
|
return windowOpen;
|
||||||
|
}
|
||||||
|
public BlindscanJobConfiguration GetConfiguration()
|
||||||
|
{
|
||||||
|
if (!okButtonClicked)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
BlindscanJobConfiguration bjc = new BlindscanJobConfiguration();
|
||||||
|
bjc.DataStorage = dataStorage;
|
||||||
|
bjc.DiseqcIndex = settingsWindowDiseqc;
|
||||||
|
bjc.DoHorizontalLow = settingsWindowScanHorizontalLow;
|
||||||
|
bjc.DoHorizontalHigh = settingsWindowScanHorizontalHigh;
|
||||||
|
bjc.DoVerticalLow = settingsWindowScanVerticalLow;
|
||||||
|
bjc.DoVerticalHigh = settingsWindowScanHorizontalHigh;
|
||||||
|
bjc.DoCollectIqGraphs = settingsWindowCollectIqGraphs;
|
||||||
|
bjc.DoCollectRfSpectrum = settingsWindowCollectRfSpectrum;
|
||||||
|
bjc.DoRecordTs = settingsWindowCaptureFile;
|
||||||
|
bjc.Gps = gpsReceiver;
|
||||||
|
bjc.Ini = ini;
|
||||||
|
bjc.LnbType = lnbs[settingsWindowLNB];
|
||||||
|
bjc.ObjectStorage = objectStorage;
|
||||||
|
bjc.SatellitePosition = satellites[settingsWindowSatellite];
|
||||||
|
|
||||||
|
if (settingsWindowUseDifferentTunerForSetFilter)
|
||||||
|
bjc.StreamReader = new CoopBlindscanStreamReader(streamReader, settingsWindowBLScanTunerSelection, settingsWindowSetFilterTunerSelection);
|
||||||
|
else
|
||||||
|
bjc.StreamReader = streamReader;
|
||||||
|
|
||||||
|
bjc.TunerMetadata = tuners[settingsWindowBLScanTunerSelection];
|
||||||
|
bjc.Ui = new InheritedBlindscanUiJunction();
|
||||||
|
bjc.Ui.Tasks = _taskQueue;
|
||||||
|
return bjc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool okButtonClicked;
|
||||||
|
public void Render()
|
||||||
|
{
|
||||||
|
if (ImGui.Begin("Blindscan", ref windowOpen, ImGuiWindowFlags.AlwaysAutoResize))
|
||||||
|
{
|
||||||
|
ImGui.PushID("tunerA");
|
||||||
|
if (ImGui.BeginCombo("Tuner for BLScanEx and RFScan", tuners[settingsWindowBLScanTunerSelection].Name))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < tuners.Count; i++)
|
||||||
|
{
|
||||||
|
bool isSelected = settingsWindowBLScanTunerSelection == i;
|
||||||
|
if (ImGui.Selectable(tuners[i].Name, isSelected))
|
||||||
|
{
|
||||||
|
settingsWindowBLScanTunerSelection = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui.EndCombo();
|
||||||
|
}
|
||||||
|
ImGui.PopID();
|
||||||
|
|
||||||
|
if (tuners[settingsWindowBLScanTunerSelection].IsSatellite())
|
||||||
|
{
|
||||||
|
ImGui.Checkbox("Use different Tuner for IQScan and SetFilter", ref settingsWindowUseDifferentTunerForSetFilter);
|
||||||
|
|
||||||
|
if (settingsWindowUseDifferentTunerForSetFilter)
|
||||||
|
{
|
||||||
|
ImGui.Text("This assumes that both tuners are connected to the same antenna set-up, using e.g. a splitter.");
|
||||||
|
|
||||||
|
ImGui.PushID("tunerB");
|
||||||
|
if (ImGui.BeginCombo("Tuner for BLScanEx and RFScan", tuners[settingsWindowSetFilterTunerSelection].Name))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < tuners.Count; i++)
|
||||||
|
{
|
||||||
|
bool isSelected = settingsWindowSetFilterTunerSelection == i;
|
||||||
|
if (ImGui.Selectable(tuners[i].Name, isSelected))
|
||||||
|
{
|
||||||
|
settingsWindowSetFilterTunerSelection = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui.EndCombo();
|
||||||
|
}
|
||||||
|
ImGui.PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Text("DiSEqC");
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.RadioButton("A", ref settingsWindowDiseqc, 1);
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.RadioButton("B", ref settingsWindowDiseqc, 2);
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.RadioButton("C", ref settingsWindowDiseqc, 3);
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.RadioButton("D", ref settingsWindowDiseqc, 4);
|
||||||
|
|
||||||
|
|
||||||
|
if (ImGui.BeginCombo("Target Satellite", satellites[settingsWindowSatellite].name))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < satellites.Count; i++)
|
||||||
|
{
|
||||||
|
bool isSelected = settingsWindowSatellite == i;
|
||||||
|
if (ImGui.Selectable(satellites[i].name, isSelected))
|
||||||
|
{
|
||||||
|
settingsWindowSatellite = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui.EndCombo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.BeginCombo("LNB", lnbs[settingsWindowLNB].Name))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < lnbs.Count; i++)
|
||||||
|
{
|
||||||
|
bool isSelected = settingsWindowLNB == i;
|
||||||
|
if (ImGui.Selectable(lnbs[i].Name, isSelected))
|
||||||
|
{
|
||||||
|
settingsWindowLNB = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui.EndCombo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.BeginCombo("Dish", dishes[settingsWindowDish].Name))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < dishes.Count; i++)
|
||||||
|
{
|
||||||
|
bool isSelected = settingsWindowDish == i;
|
||||||
|
if (ImGui.Selectable(dishes[i].Name, isSelected))
|
||||||
|
{
|
||||||
|
settingsWindowDish = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui.EndCombo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lnbs[settingsWindowLNB].LofSw != 0)
|
||||||
|
{
|
||||||
|
ImGui.Checkbox("Scan Horizontal Low Band", ref settingsWindowScanHorizontalLow);
|
||||||
|
ImGui.Checkbox("Scan Horizontal High Band", ref settingsWindowScanHorizontalHigh);
|
||||||
|
ImGui.Checkbox("Scan Vertical Low Band", ref settingsWindowScanVerticalLow);
|
||||||
|
ImGui.Checkbox("Scan Vertical High Band", ref settingsWindowScanVerticalHigh);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.Checkbox("Scan Left circular Band", ref settingsWindowScanHorizontalLow);
|
||||||
|
ImGui.Checkbox("Scan Right circular Band", ref settingsWindowScanVerticalLow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Checkbox("Capture Packets to files", ref settingsWindowCaptureFile);
|
||||||
|
ImGui.Checkbox("Collect IQ Graphs", ref settingsWindowCollectIqGraphs);
|
||||||
|
ImGui.Checkbox("Collect RF Spectrum", ref settingsWindowCollectRfSpectrum);
|
||||||
|
|
||||||
|
if (ImGui.Button("OK"))
|
||||||
|
{
|
||||||
|
windowOpen = false;
|
||||||
|
okButtonClicked = true;
|
||||||
|
StoreSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
43
GUIs/skyscraper8.UI.ImGui/Jobs/InheritedBlindscanJob.cs
Normal file
43
GUIs/skyscraper8.UI.ImGui/Jobs/InheritedBlindscanJob.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using SDL2Demo;
|
||||||
|
using SDL2Demo.Jobs;
|
||||||
|
using skyscraper8.Skyscraper.FrequencyListGenerator;
|
||||||
|
|
||||||
|
namespace skyscraper8.UI.SDL2.Jobs
|
||||||
|
{
|
||||||
|
internal class InheritedBlindscanJob : IJob
|
||||||
|
{
|
||||||
|
private readonly BlindscanJobConfiguration _jobConfiguration;
|
||||||
|
|
||||||
|
public InheritedBlindscanJob(BlindscanJobConfiguration jobConfiguration)
|
||||||
|
{
|
||||||
|
_jobConfiguration = jobConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseBlindscanJob baseBlindscanJob;
|
||||||
|
public void Run()
|
||||||
|
{
|
||||||
|
if (JobContext == null)
|
||||||
|
{
|
||||||
|
throw new NullReferenceException(nameof(JobContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
InheritedBlindscanUiJunction inherited = (InheritedBlindscanUiJunction)_jobConfiguration.Ui;
|
||||||
|
inherited.jobContext = JobContext;
|
||||||
|
|
||||||
|
baseBlindscanJob = new BaseBlindscanJob(_jobConfiguration);
|
||||||
|
baseBlindscanJob.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Cancel()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JobContext JobContext { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
1786
GUIs/skyscraper8.UI.ImGui/Jobs/InheritedBlindscanUiJunction.cs
Normal file
1786
GUIs/skyscraper8.UI.ImGui/Jobs/InheritedBlindscanUiJunction.cs
Normal file
File diff suppressed because it is too large
Load Diff
@ -23,9 +23,11 @@ using skyscraper5.Skyscraper.Scraper.Storage;
|
|||||||
using skyscraper5.Skyscraper.Scraper.Storage.Filesystem;
|
using skyscraper5.Skyscraper.Scraper.Storage.Filesystem;
|
||||||
using skyscraper5.Skyscraper.Scraper.Storage.InMemory;
|
using skyscraper5.Skyscraper.Scraper.Storage.InMemory;
|
||||||
using skyscraper5.src.Skyscraper;
|
using skyscraper5.src.Skyscraper;
|
||||||
|
using skyscraper8.Skyscraper.FrequencyListGenerator;
|
||||||
using skyscraper8.Skyscraper.Plugins;
|
using skyscraper8.Skyscraper.Plugins;
|
||||||
using skyscraper8.Skyscraper.Scraper.Storage;
|
using skyscraper8.Skyscraper.Scraper.Storage;
|
||||||
using skyscraper8.UI.ImGui.Forms;
|
using skyscraper8.UI.ImGui.Forms;
|
||||||
|
using skyscraper8.UI.SDL2.Jobs;
|
||||||
using Color = ScottPlot.Color;
|
using Color = ScottPlot.Color;
|
||||||
using Exception = System.Exception;
|
using Exception = System.Exception;
|
||||||
using Version = System.Version;
|
using Version = System.Version;
|
||||||
@ -201,6 +203,7 @@ namespace SkyscraperUI
|
|||||||
private DataStorage dataStorage;
|
private DataStorage dataStorage;
|
||||||
private ObjectStorage objectStorage;
|
private ObjectStorage objectStorage;
|
||||||
private IGpsReceiver gps;
|
private IGpsReceiver gps;
|
||||||
|
private TaskQueue tasks;
|
||||||
|
|
||||||
|
|
||||||
private List<MessageWindow> messageWindows;
|
private List<MessageWindow> messageWindows;
|
||||||
@ -223,6 +226,7 @@ namespace SkyscraperUI
|
|||||||
private ConfigureGpsWindow configureGpsWindow;
|
private ConfigureGpsWindow configureGpsWindow;
|
||||||
private GpsDisplay gpsDisplayWindow;
|
private GpsDisplay gpsDisplayWindow;
|
||||||
private BlindscanJobDeleter jobDeleter;
|
private BlindscanJobDeleter jobDeleter;
|
||||||
|
private InheritedBlindscanConfigWindow inheritedBlindscanWindow;
|
||||||
|
|
||||||
private ScreenHack[] allScreenHacks;
|
private ScreenHack[] allScreenHacks;
|
||||||
private ScreenHack currentScreenHack;
|
private ScreenHack currentScreenHack;
|
||||||
@ -243,7 +247,11 @@ namespace SkyscraperUI
|
|||||||
|
|
||||||
|
|
||||||
private void BeforeRenderFrame()
|
private void BeforeRenderFrame()
|
||||||
{
|
{
|
||||||
|
if (tasks == null)
|
||||||
|
tasks = new TaskQueue();
|
||||||
|
tasks.ProcessTasks();
|
||||||
|
|
||||||
if (jobContext != null)
|
if (jobContext != null)
|
||||||
{
|
{
|
||||||
if (jobContext.MessageQueue.Count != 0)
|
if (jobContext.MessageQueue.Count != 0)
|
||||||
@ -473,6 +481,8 @@ namespace SkyscraperUI
|
|||||||
blindscanWindow = new Blindscan(tuners, satellitePositions, lnbTypes, dataStorage);
|
blindscanWindow = new Blindscan(tuners, satellitePositions, lnbTypes, dataStorage);
|
||||||
if (ImGui.MenuItem("Perform Cooperative Blindscan", CanPerformBlindscan()))
|
if (ImGui.MenuItem("Perform Cooperative Blindscan", CanPerformBlindscan()))
|
||||||
coopBlindscanWindow = new CoopBlindscan(tuners, satellitePositions, lnbTypes, dataStorage);
|
coopBlindscanWindow = new CoopBlindscan(tuners, satellitePositions, lnbTypes, dataStorage);
|
||||||
|
if (ImGui.MenuItem("Perform inherited Blindscan", CanPerformBlindscan()))
|
||||||
|
inheritedBlindscanWindow = new InheritedBlindscanConfigWindow(tuners, satellitePositions, lnbTypes, dishTypes, dataStorage, objectStorage, gps, ini, streamReader, tasks);
|
||||||
if (ImGui.MenuItem("Cancel current job", CanCancelJob()))
|
if (ImGui.MenuItem("Cancel current job", CanCancelJob()))
|
||||||
jobContext.Job.Cancel();
|
jobContext.Job.Cancel();
|
||||||
if (ImGui.MenuItem("Quit"))
|
if (ImGui.MenuItem("Quit"))
|
||||||
@ -722,15 +732,32 @@ namespace SkyscraperUI
|
|||||||
|
|
||||||
if (coopBlindscanWindow != null)
|
if (coopBlindscanWindow != null)
|
||||||
{
|
{
|
||||||
coopBlindscanWindow.Render();
|
coopBlindscanWindow.Render();
|
||||||
if (!coopBlindscanWindow.WindowOpen)
|
if (!coopBlindscanWindow.WindowOpen)
|
||||||
|
{
|
||||||
|
if (coopBlindscanWindow.Configuration != null)
|
||||||
|
{
|
||||||
|
EnrollJob(coopBlindscanWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
coopBlindscanWindow = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inheritedBlindscanWindow != null)
|
||||||
|
{
|
||||||
|
inheritedBlindscanWindow.Render();
|
||||||
|
if (!inheritedBlindscanWindow.IsWindowOpen())
|
||||||
{
|
{
|
||||||
if (coopBlindscanWindow.Configuration != null)
|
BlindscanJobConfiguration jobConfiguration = inheritedBlindscanWindow.GetConfiguration();
|
||||||
{
|
if (jobConfiguration != null)
|
||||||
EnrollJob(coopBlindscanWindow);
|
{
|
||||||
}
|
InheritedBlindscanJob inheritedBlindscanJob = new InheritedBlindscanJob(jobConfiguration);
|
||||||
coopBlindscanWindow = null;
|
EnrollJob(inheritedBlindscanJob);
|
||||||
|
inheritedBlindscanWindow = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aboutWindow != null)
|
if (aboutWindow != null)
|
||||||
|
|||||||
@ -38,6 +38,7 @@ namespace skyscraper5
|
|||||||
private static void IntegrationTest()
|
private static void IntegrationTest()
|
||||||
{
|
{
|
||||||
RtspClient rtspClient = new RtspClient("172.20.20.121", 554);
|
RtspClient rtspClient = new RtspClient("172.20.20.121", 554);
|
||||||
|
rtspClient.AutoReconnect = true;
|
||||||
RtspOptionsResponse options = rtspClient.GetOptions("/");
|
RtspOptionsResponse options = rtspClient.GetOptions("/");
|
||||||
string url = RtspClient.MakeUrl(DiSEqC_Opcode.DISEQC_OPTION_A | DiSEqC_Opcode.DISEQC_POSITION_A | DiSEqC_Opcode.DISEQC_HORIZONTAL, 11954, true, 27500);
|
string url = RtspClient.MakeUrl(DiSEqC_Opcode.DISEQC_OPTION_A | DiSEqC_Opcode.DISEQC_POSITION_A | DiSEqC_Opcode.DISEQC_HORIZONTAL, 11954, true, 27500);
|
||||||
RtspDescribeResponse describe = rtspClient.GetDescribe(url);
|
RtspDescribeResponse describe = rtspClient.GetDescribe(url);
|
||||||
@ -59,6 +60,31 @@ namespace skyscraper5
|
|||||||
rtspClient.GetTeardown(setup);
|
rtspClient.GetTeardown(setup);
|
||||||
Console.WriteLine("{0} RTCPs",rtcps);
|
Console.WriteLine("{0} RTCPs",rtcps);
|
||||||
Console.WriteLine("{0} RTPs",rtps);
|
Console.WriteLine("{0} RTPs",rtps);
|
||||||
|
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
|
||||||
|
url = RtspClient.MakeUrl(DiSEqC_Opcode.DISEQC_OPTION_A | DiSEqC_Opcode.DISEQC_POSITION_A | DiSEqC_Opcode.DISEQC_VERTICAL, 10758, true, 22000);
|
||||||
|
describe = rtspClient.GetDescribe(url);
|
||||||
|
sessionDescriptionProtocol = describe.GetSessionDescriptionProtocol();
|
||||||
|
|
||||||
|
rtcps = 0;
|
||||||
|
rtps = 0;
|
||||||
|
|
||||||
|
setup = rtspClient.GetSetup(url);
|
||||||
|
setup.OnRtcpPacket += ((data, length) =>
|
||||||
|
rtcps++);
|
||||||
|
setup.OnRtpPacket += (data, length) =>
|
||||||
|
rtps++;
|
||||||
|
|
||||||
|
play = rtspClient.GetPlay(setup);
|
||||||
|
|
||||||
|
Thread.Sleep(5000);
|
||||||
|
|
||||||
|
rtspClient.AutoReconnect = false;
|
||||||
|
rtspClient.GetTeardown(setup);
|
||||||
|
Console.WriteLine("{0} RTCPs", rtcps);
|
||||||
|
Console.WriteLine("{0} RTPs", rtps);
|
||||||
|
rtspClient.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
@ -212,13 +238,7 @@ namespace skyscraper5
|
|||||||
GpsManager.GpsTest();
|
GpsManager.GpsTest();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args[0].ToLowerInvariant().Equals("mk-cable-csv"))
|
|
||||||
{
|
|
||||||
new CableFrequencyListGenerator().Run();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[0].ToLowerInvariant().Equals("what-can-i-receive"))
|
if (args[0].ToLowerInvariant().Equals("what-can-i-receive"))
|
||||||
{
|
{
|
||||||
WhatCanIReceive.StandaloneProgram();
|
WhatCanIReceive.StandaloneProgram();
|
||||||
@ -247,27 +267,7 @@ namespace skyscraper5
|
|||||||
}
|
}
|
||||||
passing.Run();
|
passing.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void StreamReaderTest(IStreamReader streamReader)
|
|
||||||
{
|
|
||||||
List<StreamReaderScanController.StreamReaderTuner> streamReaderTuners = StreamReaderScanController.GetTuners(streamReader);
|
|
||||||
if (streamReaderTuners.Count == 0)
|
|
||||||
{
|
|
||||||
Console.WriteLine("No tuners, lmao.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//FileInfo fi = new FileInfo("blindscan.json");
|
|
||||||
StreamReaderScanController srsc = new StreamReaderScanController(streamReader, streamReaderTuners[0]);
|
|
||||||
//srsc.SetDefaultDvbCParameters();
|
|
||||||
srsc.SetDefaultKuBandParameters();
|
|
||||||
srsc.SetParameter(StreamReaderScanController.StreamReaderParameter.ScanDiseqcType, 2);
|
|
||||||
srsc.SetParameter(StreamReaderScanController.StreamReaderParameter.DiseqcSwitchPosition, 1);
|
|
||||||
srsc.RunBlindscan();
|
|
||||||
srsc.Dispose();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ProcessDirectory(DirectoryInfo di)
|
private static void ProcessDirectory(DirectoryInfo di)
|
||||||
{
|
{
|
||||||
DataStorage dataStorage = new InMemoryScraperStorage();
|
DataStorage dataStorage = new InMemoryScraperStorage();
|
||||||
|
|||||||
@ -1,168 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using skyscraper5.Dvb.Psi.Model;
|
|
||||||
using skyscraper5.Mpeg2.Psi.Model;
|
|
||||||
using skyscraper5.Skyscraper.IO;
|
|
||||||
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
|
||||||
using skyscraper5.Skyscraper.IO.TunerInterface;
|
|
||||||
using skyscraper5.Skyscraper.Plugins;
|
|
||||||
using skyscraper5.Skyscraper.Scraper;
|
|
||||||
using skyscraper5.Skyscraper.Scraper.Storage;
|
|
||||||
using skyscraper5.Skyscraper.Scraper.Storage.InMemory;
|
|
||||||
using skyscraper8.Skyscraper.Scraper.Storage;
|
|
||||||
using Console = System.Console;
|
|
||||||
|
|
||||||
namespace skyscraper5.Skyscraper
|
|
||||||
{
|
|
||||||
internal class CableFrequencyListGenerator
|
|
||||||
{
|
|
||||||
public CableFrequencyListGenerator()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Run()
|
|
||||||
{
|
|
||||||
Ini ini = PluginManager.GetInstance().Ini;
|
|
||||||
TunerFactoryConnectionManager tunerFactoryConnectionManager = TunerFactoryConnectionManager.GetInstance();
|
|
||||||
ITunerFactory tunerFactory = tunerFactoryConnectionManager.AutoGetConfiguredTunerFactory();
|
|
||||||
IStreamReader streamReader = tunerFactory.CreateStreamReader();
|
|
||||||
int usableTuner = -1;
|
|
||||||
if (!streamReader.CheckForDVBExEx((x, y, z) =>
|
|
||||||
{
|
|
||||||
if (usableTuner == -1 && z == STD_TYPE.STD_DVBC)
|
|
||||||
usableTuner = x;
|
|
||||||
}))
|
|
||||||
{
|
|
||||||
Console.WriteLine("Failed to check for tuners.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (usableTuner == -1)
|
|
||||||
{
|
|
||||||
Console.WriteLine("no dvb-c tuner present, quitting.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!streamReader.StartDvbEx(usableTuner))
|
|
||||||
{
|
|
||||||
Console.WriteLine("Failed to start the tuner.");
|
|
||||||
streamReader.StopDVB();
|
|
||||||
if (!streamReader.StartDvbEx(usableTuner))
|
|
||||||
{
|
|
||||||
Console.WriteLine("Giving up...");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IntPtr pSearchResult = Marshal.AllocHGlobal(ushort.MaxValue);
|
|
||||||
int tpNum = 0;
|
|
||||||
SearchResult2 sr2 = default;
|
|
||||||
if (!streamReader.AirScan(48000, 1000000, 3000, 8000, (int)STD_TYPE.STD_DVBC, pSearchResult, ref tpNum, (ref SearchResult2 searchResult) => SearchResult2Callback(searchResult)))
|
|
||||||
{
|
|
||||||
Console.WriteLine("Failed to run AirScan...");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string filename = String.Format("dvb-c_{0}.csv", DateTime.Now.ToUnixTime());
|
|
||||||
FileStream fileStream = File.OpenWrite(filename);
|
|
||||||
StreamWriter streamWriter = new StreamWriter(fileStream);
|
|
||||||
|
|
||||||
foreach (SearchResult2 searchResult2 in searchResults)
|
|
||||||
{
|
|
||||||
double outFreq = searchResult2.Freq;
|
|
||||||
outFreq = Math.Round((double)outFreq / (double)1000.0, 0) * 1000;
|
|
||||||
outFreq /= 1000;
|
|
||||||
|
|
||||||
Console.WriteLine("Tuning to {0} Mhz", outFreq);
|
|
||||||
if (!streamReader.SetChannel2((uint)searchResult2.Freq, (uint)searchResult2.BW))
|
|
||||||
{
|
|
||||||
Console.WriteLine("Failed to tune.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchResult2 recheck = default;
|
|
||||||
if (!streamReader.SignalInfo2(ref recheck))
|
|
||||||
{
|
|
||||||
Console.WriteLine("Failed to get signal info.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!recheck.Lock)
|
|
||||||
{
|
|
||||||
Console.WriteLine("No lock.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
double outSymRate = searchResult2.SR;
|
|
||||||
outSymRate = Math.Round((double)outSymRate / (double)10000.0, 0) * 10000;
|
|
||||||
outSymRate /= 1000;
|
|
||||||
string outModType = ((MOD_TYPE)searchResult2.ModType).ToString();
|
|
||||||
string outLine = String.Format("{0} Mhz;{1} kSym/s;{2}", outFreq, outSymRate, outModType);
|
|
||||||
streamWriter.WriteLine(outLine);
|
|
||||||
|
|
||||||
StreamReaderScraperController scraper = new StreamReaderScraperController(streamReader);
|
|
||||||
scraper.DataStorage = new InMemoryScraperStorage();
|
|
||||||
scraper.Recording = false;
|
|
||||||
Console.Write("Running PSI acquisition...");
|
|
||||||
scraper.Run();
|
|
||||||
Console.WriteLine(".DONE");
|
|
||||||
|
|
||||||
DataStorage data = scraper.DataStorage;
|
|
||||||
IEnumerable<Tuple<int, int, ProgramMapping>> pmtEntries = data.SelectAllPmt().ToList();
|
|
||||||
List<Tuple<int, int, SdtService>> tuples = data.SelectAllSdt().ToList();
|
|
||||||
foreach (var (tsId, networkId, programMapping) in pmtEntries)
|
|
||||||
{
|
|
||||||
SdtService sdt = data.SelectSdtById(networkId, tsId, programMapping.ProgramNumber);
|
|
||||||
if (sdt == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
outLine = String.Format("{0};{1};{2};{3};{4}", programMapping.ProgramNumber,sdt.ServiceProviderName,sdt.ServiceName,GetCaSystemName(programMapping,sdt),sdt.ServiceType);
|
|
||||||
streamWriter.WriteLine(outLine);
|
|
||||||
streamWriter.Flush();
|
|
||||||
}
|
|
||||||
streamWriter.WriteLine("");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!streamReader.StopDVB())
|
|
||||||
{
|
|
||||||
Console.WriteLine("Failed to properly close the tuner!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
streamWriter.Flush();
|
|
||||||
streamWriter.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetCaSystemName(ProgramMapping pmt, SdtService sdt)
|
|
||||||
{
|
|
||||||
if (pmt.CaSystemId.HasValue)
|
|
||||||
{
|
|
||||||
return CaSystemNames.GetHumanReadableName(pmt.CaSystemId.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sdt.CaIdentifiers != null)
|
|
||||||
{
|
|
||||||
if (sdt.CaIdentifiers.Length > 0)
|
|
||||||
{
|
|
||||||
return CaSystemNames.GetHumanReadableName(sdt.CaIdentifiers[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<SearchResult2> searchResults;
|
|
||||||
private void SearchResult2Callback(SearchResult2 searchResult)
|
|
||||||
{
|
|
||||||
if (searchResults == null)
|
|
||||||
searchResults = new List<SearchResult2>();
|
|
||||||
searchResults.Add(searchResult);
|
|
||||||
Console.WriteLine("Heard something at {0}", searchResult.Freq / 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,904 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using skyscraper5.src.Skyscraper.FrequencyListGenerator;
|
||||||
|
using skyscraper8.Skyscraper.Plugins;
|
||||||
|
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
||||||
|
using skyscraper8.Skyscraper.Drawing;
|
||||||
|
using skyscraper5.Dvb.Descriptors;
|
||||||
|
using skyscraper5.src.Mpeg2.PacketFilter;
|
||||||
|
using skyscraper5.Skyscraper.IO;
|
||||||
|
using skyscraper5.Skyscraper.Scraper;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using skyscraper5.Skyscraper.Equipment;
|
||||||
|
|
||||||
|
namespace skyscraper8.Skyscraper.FrequencyListGenerator
|
||||||
|
{
|
||||||
|
public class BaseBlindscanJob
|
||||||
|
{
|
||||||
|
private static PluginLogger logger = PluginLogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
public BaseBlindscanJob(BlindscanJobConfiguration config)
|
||||||
|
{
|
||||||
|
if (config == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(config));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlindscanJobConfiguration config;
|
||||||
|
private DbBlindscanJob jobInDb;
|
||||||
|
private List<BlindscanSearchResult> foundFrequencies;
|
||||||
|
|
||||||
|
public void Run()
|
||||||
|
{
|
||||||
|
if (config == null)
|
||||||
|
throw new NullReferenceException("No config? Dude, what?");
|
||||||
|
if (config.StreamReader == null)
|
||||||
|
throw new NullReferenceException("No StreamReader available");
|
||||||
|
|
||||||
|
|
||||||
|
jobInDb = new DbBlindscanJob(Guid.NewGuid(), config.TunerMetadata.MacAddress, config.TunerMetadata.Type, config.DiseqcIndex, config.Gps, config.SatellitePosition);
|
||||||
|
jobInDb.HorizontalHighState = config.DoHorizontalHigh ? DbBlindscanJobPolarizationStatus.SELECTED_WAITING : DbBlindscanJobPolarizationStatus.NOT_SELECTED;
|
||||||
|
jobInDb.HorizontalLowState = config.DoHorizontalLow ? DbBlindscanJobPolarizationStatus.SELECTED_WAITING : DbBlindscanJobPolarizationStatus.NOT_SELECTED;
|
||||||
|
jobInDb.VerticalLowState = config.DoVerticalLow ? DbBlindscanJobPolarizationStatus.SELECTED_WAITING : DbBlindscanJobPolarizationStatus.NOT_SELECTED;
|
||||||
|
jobInDb.VerticalHighState = config.DoVerticalHigh ? DbBlindscanJobPolarizationStatus.SELECTED_WAITING : DbBlindscanJobPolarizationStatus.NOT_SELECTED;
|
||||||
|
config.DataStorage.InsertBlindscanJob(jobInDb);
|
||||||
|
|
||||||
|
foundFrequencies = new List<BlindscanSearchResult>();
|
||||||
|
config.Ui.OnBlindscanOpenFoundFrquenciesWindow(foundFrequencies, config.TunerMetadata.Type);
|
||||||
|
|
||||||
|
if (!config.StreamReader.StartDvbEx(config.TunerMetadata.Index))
|
||||||
|
{
|
||||||
|
throw new Exception("Failed to start DVB");
|
||||||
|
}
|
||||||
|
if (!RunBlindscan())
|
||||||
|
{
|
||||||
|
config.StreamReader.StopDVB();
|
||||||
|
config.Ui.OnBlindscanJobDone(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Ui.OnBlindscanJobDone(true);
|
||||||
|
logger.Log(PluginLogLevel.Info,"Blindscan Job done!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RunBlindscan()
|
||||||
|
{
|
||||||
|
Caps caps = config.TunerMetadata.Caps;
|
||||||
|
|
||||||
|
if (config.DoCollectRfSpectrum)
|
||||||
|
{
|
||||||
|
RfSpectrumData rfSpectrum = GatherRfSpectrum();
|
||||||
|
if (rfSpectrum != null)
|
||||||
|
{
|
||||||
|
config.ObjectStorage.StoreRfSpectrum(jobInDb.JobGuid, rfSpectrum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (caps.HasFlag(Caps.SR_BLSCAN2))
|
||||||
|
{
|
||||||
|
SearchResult sr1 = default;
|
||||||
|
int tpNum = default;
|
||||||
|
|
||||||
|
int lof1 = config.LnbType.Lof1 * 1000;
|
||||||
|
int lof2 = config.LnbType.Lof2 * 1000;
|
||||||
|
int lofSw = config.LnbType.LofSw * 1000;
|
||||||
|
int diseqc = config.TunerMetadata.DiseqcType;
|
||||||
|
int startFreq = config.LnbType.MinimumFrequency * 1000;
|
||||||
|
int endFreq = config.LnbType.MaximumFrequency * 1000;
|
||||||
|
bool anythingSuceeded = false;
|
||||||
|
nint allocHGlobal = Marshal.AllocHGlobal(ushort.MaxValue);
|
||||||
|
|
||||||
|
if (lofSw != 0)
|
||||||
|
{
|
||||||
|
if (config.DoHorizontalLow)
|
||||||
|
{
|
||||||
|
if (SendDiseqcCommand(false, true))
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Info,"Scanning low horizontal band...");
|
||||||
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
bool hLower = BlScan2Wrap(startFreq, lofSw, 0, lof1, lof2, lofSw, allocHGlobal, ref tpNum, (ref SearchResult sr1) => SearchResult1Callback(sr1, 1));
|
||||||
|
config.Ui.OnBlindscanBandComplete();
|
||||||
|
if (!hLower)
|
||||||
|
{
|
||||||
|
config.Ui.OnBlindscanErrorMessage("Blindscanning low horizontal area failed.");
|
||||||
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
anythingSuceeded = true;
|
||||||
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_SCRAPING;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
SendDiseqcCommand(false, true);
|
||||||
|
RunScrape();
|
||||||
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_DONE;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
foundFrequencies.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
config.Ui.OnBlindscanErrorMessage("DiSEqC Switch to low horizontal area failed.");
|
||||||
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED_DISEQC;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.DoHorizontalHigh)
|
||||||
|
{
|
||||||
|
if (SendDiseqcCommand(true, true))
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Info,"Scanning high horizontal band...");
|
||||||
|
jobInDb.HorizontalHighState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
bool hUpper = BlScan2Wrap(lofSw, endFreq, 0, lof1, lof2, lofSw, allocHGlobal, ref tpNum, (ref SearchResult sr1) => SearchResult1Callback(sr1, 2));
|
||||||
|
config.Ui.OnBlindscanBandComplete();
|
||||||
|
if (!hUpper)
|
||||||
|
{
|
||||||
|
config.Ui.OnBlindscanErrorMessage("Blindscanning high horizontal area failed.");
|
||||||
|
jobInDb.HorizontalHighState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
anythingSuceeded = true;
|
||||||
|
jobInDb.HorizontalHighState = DbBlindscanJobPolarizationStatus.SELECTED_SCRAPING;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
SendDiseqcCommand(true, true);
|
||||||
|
RunScrape();
|
||||||
|
jobInDb.HorizontalHighState = DbBlindscanJobPolarizationStatus.SELECTED_DONE;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
foundFrequencies.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
config.Ui.OnBlindscanErrorMessage("DiSEqC Switch to high horizontal area failed.");
|
||||||
|
jobInDb.HorizontalHighState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED_DISEQC;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.DoVerticalLow)
|
||||||
|
{
|
||||||
|
if (SendDiseqcCommand(false, false))
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Info,"Scanning low vertical band...");
|
||||||
|
jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
bool vLower = BlScan2Wrap(startFreq, lofSw, 1, lof1, lof2, lofSw, allocHGlobal, ref tpNum, (ref SearchResult sr1) => SearchResult1Callback(sr1, 3));
|
||||||
|
config.Ui.OnBlindscanBandComplete();
|
||||||
|
if (!vLower)
|
||||||
|
{
|
||||||
|
config.Ui.OnBlindscanErrorMessage("Blindscanning low vertical area failed.");
|
||||||
|
jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
anythingSuceeded = true;
|
||||||
|
jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_SCRAPING;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
SendDiseqcCommand(false, false);
|
||||||
|
RunScrape();
|
||||||
|
jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_DONE;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
foundFrequencies.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
config.Ui.OnBlindscanErrorMessage("DiSEqC Switch to low vertical area failed.");
|
||||||
|
jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED_DISEQC;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.DoVerticalHigh)
|
||||||
|
{
|
||||||
|
if (SendDiseqcCommand(true, false))
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Info,"Scanning high vertical band...");
|
||||||
|
jobInDb.VerticalHighState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
bool vUpper = BlScan2Wrap(lofSw, endFreq, 1, lof1, lof2, lofSw, allocHGlobal, ref tpNum, (ref SearchResult sr1) => SearchResult1Callback(sr1, 4));
|
||||||
|
config.Ui.OnBlindscanBandComplete();
|
||||||
|
if (!vUpper)
|
||||||
|
{
|
||||||
|
config.Ui.OnBlindscanErrorMessage("Blindscanning high vertical area failed.");
|
||||||
|
jobInDb.VerticalHighState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
anythingSuceeded = true;
|
||||||
|
jobInDb.VerticalHighState = DbBlindscanJobPolarizationStatus.SELECTED_SCRAPING;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
SendDiseqcCommand(true, false);
|
||||||
|
RunScrape();
|
||||||
|
jobInDb.VerticalHighState = DbBlindscanJobPolarizationStatus.SELECTED_DONE;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
foundFrequencies.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
config.Ui.OnBlindscanErrorMessage("DiSEqC Switch to high vertical area failed.");
|
||||||
|
jobInDb.VerticalHighState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED_DISEQC;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (SendDiseqcCommand(false, true))
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Info, string.Format("Scanning left circular band..."));
|
||||||
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
bool lCirc = BlScan2Wrap(startFreq, endFreq, 0, lof1, lof2, lofSw, allocHGlobal, ref tpNum, (ref SearchResult sr1) => SearchResult1Callback(sr1, 1));
|
||||||
|
config.Ui.OnBlindscanBandComplete();
|
||||||
|
if (!lCirc)
|
||||||
|
{
|
||||||
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
config.Ui.OnBlindscanErrorMessage("Blindscanning left circular area failed.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
anythingSuceeded = true;
|
||||||
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_SCRAPING;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
SendDiseqcCommand(false, true);
|
||||||
|
RunScrape();
|
||||||
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_DONE;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
foundFrequencies.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
config.Ui.OnBlindscanErrorMessage("DiSEqC Switch to left circulation failed.");
|
||||||
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED_DISEQC;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
}
|
||||||
|
if (SendDiseqcCommand(false, false))
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Info, string.Format("Scanning right circular band..."));
|
||||||
|
jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
bool rCirc = BlScan2Wrap(startFreq, endFreq, 1, lof1, lof2, lofSw, allocHGlobal, ref tpNum, (ref SearchResult sr1) => SearchResult1Callback(sr1, 3));
|
||||||
|
config.Ui.OnBlindscanBandComplete();
|
||||||
|
if (!rCirc)
|
||||||
|
{
|
||||||
|
config.Ui.OnBlindscanErrorMessage("Blindscanning right circular area failed.");
|
||||||
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
anythingSuceeded = true;
|
||||||
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_SCRAPING;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
SendDiseqcCommand(false, false);
|
||||||
|
RunScrape();
|
||||||
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_DONE;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
foundFrequencies.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
config.Ui.OnBlindscanErrorMessage("DiSEqC Switch to right circulation failed.");
|
||||||
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_DONE;
|
||||||
|
config.DataStorage.UpdateJobState(jobInDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Marshal.FreeHGlobal(allocHGlobal);
|
||||||
|
return anythingSuceeded;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("Don't know how to blindscan with this tuner.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private bool BlScan2Wrap(int freq_start, int freq_stop, int pol, int lof1, int lof2, int lofSw, nint pSearchResult, ref int pTpNum, BlScanCallback lpFunc)
|
||||||
|
{
|
||||||
|
config.Ui.OnBlindscanBeforeBLScan(freq_start, freq_start, freq_stop);
|
||||||
|
|
||||||
|
bool result = config.StreamReader.BLScan2(freq_start, freq_stop, pol, lof1, lof2, lofSw, pSearchResult, ref pTpNum, lpFunc);
|
||||||
|
|
||||||
|
config.Ui.OnBlindscanAfterBLScan();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool SendDiseqcCommand(bool highBand, bool horizontal)
|
||||||
|
{
|
||||||
|
DiSEqC_Opcode myOpcode = DiSEqC_Opcode.DISEQC_HIGH_NIBBLE;
|
||||||
|
if (highBand)
|
||||||
|
myOpcode |= DiSEqC_Opcode.DISEQC_HIGH_BAND;
|
||||||
|
else
|
||||||
|
myOpcode |= DiSEqC_Opcode.DISEQC_LOW_BAND;
|
||||||
|
|
||||||
|
if (horizontal)
|
||||||
|
myOpcode |= DiSEqC_Opcode.DISEQC_HORIZONTAL;
|
||||||
|
else
|
||||||
|
myOpcode |= DiSEqC_Opcode.DISEQC_VERTICAL;
|
||||||
|
|
||||||
|
int parameter = config.DiseqcIndex;
|
||||||
|
switch (parameter)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
myOpcode |= DiSEqC_Opcode.DISEQC_OPTION_A;
|
||||||
|
myOpcode |= DiSEqC_Opcode.DISEQC_POSITION_A;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
myOpcode |= DiSEqC_Opcode.DISEQC_OPTION_A;
|
||||||
|
myOpcode |= DiSEqC_Opcode.DISEQC_POSITION_B;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
myOpcode |= DiSEqC_Opcode.DISEQC_OPTION_B;
|
||||||
|
myOpcode |= DiSEqC_Opcode.DISEQC_POSITION_A;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
myOpcode |= DiSEqC_Opcode.DISEQC_OPTION_B;
|
||||||
|
myOpcode |= DiSEqC_Opcode.DISEQC_POSITION_B;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException("DiSEqC Switch Position");
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Log(PluginLogLevel.Info, string.Format("Send DiSEqC Command {0:X2}", (byte)myOpcode), 8);
|
||||||
|
|
||||||
|
DateTime started = DateTime.Now;
|
||||||
|
bool result = config.StreamReader.SendDiSEqC(2, myOpcode);
|
||||||
|
TimeSpan timeTaken = DateTime.Now - started;
|
||||||
|
logger.Log(PluginLogLevel.Debug, string.Format("DiSEqC Comannd sent in {0:F1} seconds.", timeTaken.TotalSeconds));
|
||||||
|
if (timeTaken.TotalSeconds > 10)
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Warn, string.Format("Something went wrong while performing the DiSEqC operation, trying again..."), 8);
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
return SendDiseqcCommand(highBand, horizontal);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchResult1Callback(SearchResult searchResult, int polarityIndex)
|
||||||
|
{
|
||||||
|
BlindscanSearchResult blindscanSearchResult = new BlindscanSearchResult();
|
||||||
|
blindscanSearchResult.SearchResult = searchResult;
|
||||||
|
blindscanSearchResult.Standard = (STD_TYPE)searchResult.StdType;
|
||||||
|
logger.Log(PluginLogLevel.Info, string.Format("Found frequency: {0}, {1}", searchResult.Freq / 1000, searchResult.Pol == 0 ? "H" : "V"));
|
||||||
|
lock (foundFrequencies)
|
||||||
|
{
|
||||||
|
foundFrequencies.Add(blindscanSearchResult);
|
||||||
|
}
|
||||||
|
config.DataStorage.InsertSearchResult(jobInDb, true, searchResult, polarityIndex, new SearchResult2());
|
||||||
|
config.Ui.OnBlindscanSearchResult1Callback(blindscanSearchResult, polarityIndex, config.LnbType.MinimumFrequency, config.LnbType.MaximumFrequency);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void RunScrape()
|
||||||
|
{
|
||||||
|
int lof1 = config.LnbType.Lof1 * 1000;
|
||||||
|
int lof2 = config.LnbType.Lof2 * 1000;
|
||||||
|
int lofSw = config.LnbType.LofSw * 1000;
|
||||||
|
|
||||||
|
|
||||||
|
foreach (BlindscanSearchResult blindscanResult in foundFrequencies)
|
||||||
|
{
|
||||||
|
DateTime now = DateTime.Now;
|
||||||
|
|
||||||
|
blindscanResult.State = BlindscanResultState.Tuning;
|
||||||
|
config.DataStorage.UpdateTransponderState(jobInDb, blindscanResult.IsSatellite(), blindscanResult.SearchResult, blindscanResult.State, blindscanResult.SearchResult2);
|
||||||
|
config.Ui.OnBlindscanBeforeSetChannel(blindscanResult, config.LnbType);
|
||||||
|
bool channel = config.StreamReader.SetChannel(blindscanResult.SearchResult.Freq, blindscanResult.SearchResult.SR, blindscanResult.SearchResult.Pol, blindscanResult.SearchResult.FEC, lof1, lof2, lofSw);
|
||||||
|
if (!channel)
|
||||||
|
{
|
||||||
|
blindscanResult.State = BlindscanResultState.TuningFailed;
|
||||||
|
config.DataStorage.UpdateTransponderState(jobInDb, blindscanResult.IsSatellite(), blindscanResult.SearchResult, blindscanResult.State, blindscanResult.SearchResult2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
RunSkyscraper(blindscanResult);
|
||||||
|
config.Ui.OnBlindscanScrapeTransponderComplete(blindscanResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Ui.OnScrapeBandComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private RfSpectrumData GatherRfSpectrum()
|
||||||
|
{
|
||||||
|
Caps caps = config.TunerMetadata.Caps;
|
||||||
|
if (caps.HasFlag(Caps.SR_RFSCAN2))
|
||||||
|
{
|
||||||
|
return GatherRfSpectrumCable();
|
||||||
|
}
|
||||||
|
else if (!caps.HasFlag(Caps.SR_RFSCAN))
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Error, "Couldn't figure out whether to use RFScan or RFScan2!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Ui.OnBlindscanBeginRfSpectrum();
|
||||||
|
|
||||||
|
int lof1 = config.LnbType.Lof1 * 1000;
|
||||||
|
int lof2 = config.LnbType.Lof2 * 1000;
|
||||||
|
int lofSw = config.LnbType.LofSw * 1000;
|
||||||
|
int startFreq = config.LnbType.MinimumFrequency * 1000;
|
||||||
|
int endFreq = config.LnbType.MaximumFrequency * 1000;
|
||||||
|
|
||||||
|
RfSpectrumData spectrumData = RfSpectrumData.Create();
|
||||||
|
|
||||||
|
void RunRfScan(RfSpectrumData spectrum, int startFreq, int endFreq, SatelliteDeliverySystemDescriptor.PolarizationEnum polarization, DiSEqC_Opcode diseqcCmd, int lof1, int lof2, int lofSw)
|
||||||
|
{
|
||||||
|
const int STEP = 1000;
|
||||||
|
config.StreamReader.SendDiSEqC(2, diseqcCmd);
|
||||||
|
RfSpectrumDataBlock block = spectrumData.CreateBlock(startFreq, endFreq, STEP, polarization);
|
||||||
|
for (int i = startFreq; i <= endFreq; i += STEP)
|
||||||
|
{
|
||||||
|
double rf = double.NaN;
|
||||||
|
config.StreamReader.RFScan(i, diseqcCmd.HasFlag(DiSEqC_Opcode.DISEQC_HORIZONTAL) ? 0 : 1, lof1, lof2, lofSw, out rf);
|
||||||
|
logger.Log(PluginLogLevel.Debug,"{0} {1}, {2}", i, polarization.ToString().Substring(0, 1), rf);
|
||||||
|
block.Push(i, rf);
|
||||||
|
config.Ui.OnBlindscanRfSpectrumEnqueueSample(polarization, i, rf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (DiSEqC_Opcode opcode in GetIqGraphDiseqcOpcodes())
|
||||||
|
{
|
||||||
|
RunRfScan(spectrumData, startFreq, endFreq,
|
||||||
|
opcode.HasFlag(DiSEqC_Opcode.DISEQC_HORIZONTAL) ? SatelliteDeliverySystemDescriptor.PolarizationEnum.HorizontalLinear : SatelliteDeliverySystemDescriptor.PolarizationEnum.VerticalLinear,
|
||||||
|
opcode, lof1, lof2, lofSw);
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Ui.OnBlindscanEndRfSpectrum();
|
||||||
|
|
||||||
|
return spectrumData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RfSpectrumData GatherRfSpectrumCable()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<DiSEqC_Opcode> GetIqGraphDiseqcOpcodes()
|
||||||
|
{
|
||||||
|
DiSEqC_Opcode baseDiseqc = DiSEqC_Opcode.DISEQC_HIGH_NIBBLE;
|
||||||
|
|
||||||
|
int parameter = config.DiseqcIndex;
|
||||||
|
switch (parameter)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
baseDiseqc |= DiSEqC_Opcode.DISEQC_OPTION_A;
|
||||||
|
baseDiseqc |= DiSEqC_Opcode.DISEQC_POSITION_A;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
baseDiseqc |= DiSEqC_Opcode.DISEQC_OPTION_A;
|
||||||
|
baseDiseqc |= DiSEqC_Opcode.DISEQC_POSITION_B;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
baseDiseqc |= DiSEqC_Opcode.DISEQC_OPTION_B;
|
||||||
|
baseDiseqc |= DiSEqC_Opcode.DISEQC_POSITION_A;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
baseDiseqc |= DiSEqC_Opcode.DISEQC_OPTION_B;
|
||||||
|
baseDiseqc |= DiSEqC_Opcode.DISEQC_POSITION_B;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException("DiSEqC Switch Position");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.DoHorizontalLow || config.DoHorizontalHigh)
|
||||||
|
yield return baseDiseqc | DiSEqC_Opcode.DISEQC_HORIZONTAL | DiSEqC_Opcode.DISEQC_LOW_BAND;
|
||||||
|
if (config.DoVerticalLow || config.DoVerticalHigh)
|
||||||
|
yield return baseDiseqc | DiSEqC_Opcode.DISEQC_VERTICAL | DiSEqC_Opcode.DISEQC_LOW_BAND;
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
private IqChartData GatherIqGraph()
|
||||||
|
{
|
||||||
|
Caps caps = config.TunerMetadata.Caps;
|
||||||
|
if (caps.HasFlag(Caps.SR_IQSCAN2))
|
||||||
|
{
|
||||||
|
return GatherIQGraphCable();
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (!caps.HasFlag(Caps.SR_IQSCAN))
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Error, "Couldn't figure out whether to use IQScan or IQScan2!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
IqChartData result = IqChartData.Create();
|
||||||
|
config.Ui.OnBlindscanBeginIqSpectrum(result);
|
||||||
|
|
||||||
|
|
||||||
|
sbyte[] buffer = new sbyte[400];
|
||||||
|
DateTime started = DateTime.Now;
|
||||||
|
while (!result.IsComplete)
|
||||||
|
{
|
||||||
|
bool iqScan = config.StreamReader.IQScan(0, buffer, (uint)(buffer.Length / 2));
|
||||||
|
if (!iqScan)
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
logger.Log(PluginLogLevel.Error, "IQScan failed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result.PushPacket(buffer);
|
||||||
|
}
|
||||||
|
TimeSpan finished = DateTime.Now - started;
|
||||||
|
logger.Log(PluginLogLevel.Debug, "Finished IQ acquisiton in {0} ({1} samples per call)", finished.ToString(), buffer.Length / 2);
|
||||||
|
|
||||||
|
config.Ui.OnBlindscanEndIq();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
private IqChartData GatherIQGraphCable()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RunSkyscraper(BlindscanSearchResult result)
|
||||||
|
{
|
||||||
|
int misCounter = 1;
|
||||||
|
bool misMode = false;
|
||||||
|
bool cableTvMode = false;
|
||||||
|
Caps caps = config.TunerMetadata.Caps;
|
||||||
|
SearchResult satelliteSr = new SearchResult();
|
||||||
|
SearchResult2 cableSr = new SearchResult2();
|
||||||
|
|
||||||
|
if (caps.HasFlag(Caps.SR_SIGINFO))
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Info, string.Format("Trying to BLScanEx..."), 8);
|
||||||
|
if (!config.StreamReader.BLScanEx(result.SearchResult.Freq, 5000, result.SearchResult.Pol,
|
||||||
|
config.LnbType.Lof1 * 1000, config.LnbType.Lof2 * 1000,
|
||||||
|
config.LnbType.LofSw * 1000, 1000000, (STD_TYPE)result.SearchResult.StdType,
|
||||||
|
ref satelliteSr))
|
||||||
|
{
|
||||||
|
//No blindscan? No problem! Try anyway!
|
||||||
|
satelliteSr = result.SearchResult;
|
||||||
|
satelliteSr.Lock = false;
|
||||||
|
result.State = BlindscanResultState.BlScanFailure;
|
||||||
|
config.DataStorage.UpdateTransponderState(jobInDb, result.IsSatellite(), result.SearchResult, result.State, result.SearchResult2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!satelliteSr.Lock)
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Info, string.Format("Trying to SetChannel..."), 8);
|
||||||
|
bool channel = config.StreamReader.SetChannel(result.SearchResult.Freq, result.SearchResult.SR, result.SearchResult.Freq, result.SearchResult.FEC, config.LnbType.Lof1 * 1000, config.LnbType.Lof2 * 1000, config.LnbType.LofSw * 1000);
|
||||||
|
if (!channel)
|
||||||
|
{
|
||||||
|
result.State = BlindscanResultState.TuningFailed;
|
||||||
|
config.Ui.OnBlindscanLockFail(satelliteSr, result.State);
|
||||||
|
config.DataStorage.UpdateTransponderState(jobInDb, result.IsSatellite(), result.SearchResult, result.State, result.SearchResult2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Info, string.Format("Trying to get SignalInfo..."), 8);
|
||||||
|
bool signalInfo = config.StreamReader.SignalInfo(ref satelliteSr);
|
||||||
|
if (!signalInfo)
|
||||||
|
{
|
||||||
|
result.State = BlindscanResultState.TuningFailed;
|
||||||
|
config.DataStorage.UpdateTransponderState(jobInDb, result.IsSatellite(), result.SearchResult, result.State, result.SearchResult2);
|
||||||
|
config.Ui.OnBlindscanLockFail(satelliteSr, result.State);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!satelliteSr.Lock)
|
||||||
|
{
|
||||||
|
result.State = BlindscanResultState.NoLock;
|
||||||
|
config.DataStorage.UpdateTransponderState(jobInDb, result.IsSatellite(), result.SearchResult, result.State, result.SearchResult2);
|
||||||
|
config.Ui.OnBlindscanLockFail(satelliteSr, result.State);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (caps.HasFlag(Caps.SR_MISSEL))
|
||||||
|
{
|
||||||
|
if (satelliteSr.MIS > 16)
|
||||||
|
satelliteSr.MIS = 1;
|
||||||
|
|
||||||
|
if (satelliteSr.MIS == 0)
|
||||||
|
satelliteSr.MIS = 1;
|
||||||
|
|
||||||
|
if (satelliteSr.MIS != 1)
|
||||||
|
misMode = true;
|
||||||
|
|
||||||
|
misCounter = satelliteSr.MIS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (caps.HasFlag(Caps.SR_SIGINFO2))
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Info, string.Format("Trying to SetChannel2..."), 8);
|
||||||
|
bool channel2 = config.StreamReader.SetChannel2((uint)result.SearchResult2.Freq, (uint)result.SearchResult2.BW);
|
||||||
|
if (!channel2)
|
||||||
|
{
|
||||||
|
result.State = BlindscanResultState.TuningFailed;
|
||||||
|
config.DataStorage.UpdateTransponderState(jobInDb, result.IsSatellite(), result.SearchResult, result.State, result.SearchResult2);
|
||||||
|
config.Ui.OnBlindscanLockFail(result.SearchResult, result.State);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Log(PluginLogLevel.Info, string.Format("Trying to get SignalInfo2..."), 8);
|
||||||
|
bool signalInfo2 = config.StreamReader.SignalInfo2(ref cableSr);
|
||||||
|
if (!signalInfo2)
|
||||||
|
{
|
||||||
|
result.State = BlindscanResultState.TuningFailed;
|
||||||
|
config.DataStorage.UpdateTransponderState(jobInDb, result.IsSatellite(), result.SearchResult, result.State, result.SearchResult2);
|
||||||
|
config.Ui.OnBlindscanLockFail(result.SearchResult, result.State);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cableSr.Lock)
|
||||||
|
{
|
||||||
|
result.State = BlindscanResultState.NoLock;
|
||||||
|
config.DataStorage.UpdateTransponderState(jobInDb, result.IsSatellite(), result.SearchResult, result.State, result.SearchResult2);
|
||||||
|
config.Ui.OnBlindscanLockFail(result.SearchResult, result.State);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("Couldn't figure out what signal info to use.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.DoCollectIqGraphs)
|
||||||
|
{
|
||||||
|
result.State = BlindscanResultState.IqCollecting;
|
||||||
|
IqChartData plot = GatherIqGraph();
|
||||||
|
if (plot != null)
|
||||||
|
{
|
||||||
|
result.State = BlindscanResultState.IqSaving;
|
||||||
|
config.ObjectStorage.StoreIqGraph(jobInDb.JobGuid, result.GetFrequency(), result.GetPolarity(config.LnbType.LofSw), plot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int mis = 0; mis < misCounter; mis++)
|
||||||
|
{
|
||||||
|
if (misMode)
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Info, string.Format("Selecting MIS IS {0}", satelliteSr.IS[mis]), 8);
|
||||||
|
bool misSel = config.StreamReader.MISSel(misMode, satelliteSr.IS[mis], 0xff);
|
||||||
|
if (!misSel)
|
||||||
|
{
|
||||||
|
result.State = BlindscanResultState.MisFailure;
|
||||||
|
config.DataStorage.UpdateTransponderState(jobInDb, result.IsSatellite(), result.SearchResult, result.State, result.SearchResult2);
|
||||||
|
config.Ui.OnBlindscanLockFail(result.SearchResult, result.State);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Start Filter
|
||||||
|
TsRecorder tsRecorder = null;
|
||||||
|
if (config.DoRecordTs)
|
||||||
|
{
|
||||||
|
tsRecorder = new TsRecorder();
|
||||||
|
tsRecorder.Recording = true;
|
||||||
|
string outputDirName = config.Ini.ReadValue("recording", "output_dir", "recording_output");
|
||||||
|
tsRecorder.RecordingOutputDirectory = new DirectoryInfo(outputDirName);
|
||||||
|
tsRecorder.RecordingOutputDirectory.EnsureExists();
|
||||||
|
if (tsRecorder.PrepareRecording())
|
||||||
|
{
|
||||||
|
DateTime now = DateTime.Now;
|
||||||
|
string recordingFilename = string.Format(
|
||||||
|
"skyscraper_{0:D4}{1:D2}{2:D2}_{3:D2}{4:D2}_{8:D4}{9}_{5}_{6}_{7}.ts",
|
||||||
|
now.Year, now.Month, now.Day, now.Hour, now.Minute, result.GetFrequency() / 1000,
|
||||||
|
result.GetPolarity(config.LnbType.LofSw), result.GetSymbolRate() / 1000,
|
||||||
|
(int)(config.SatellitePosition.angle * 10),
|
||||||
|
config.SatellitePosition.cardinalDirection == 0 ? "E" : "W");
|
||||||
|
tsRecorder.SetNextFilename(recordingFilename);
|
||||||
|
tsRecorder.CreateBufferedStream();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nint filterReference = nint.MaxValue;
|
||||||
|
logger.Log(PluginLogLevel.Info, string.Format("Set-Up filter..."), 8);
|
||||||
|
packetsQueue = new Queue<byte[]>();
|
||||||
|
|
||||||
|
bool filter = config.StreamReader.SetFilter(8192, DvbCallback, 0x02, 2, ref filterReference);
|
||||||
|
if (!filter)
|
||||||
|
{
|
||||||
|
result.State = BlindscanResultState.FilterFailure;
|
||||||
|
config.DataStorage.UpdateTransponderState(jobInDb, result.IsSatellite(), result.SearchResult, result.State, result.SearchResult2);
|
||||||
|
config.Ui.OnBlindscanLockFail(result.SearchResult, result.State);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.Log(PluginLogLevel.Debug, string.Format("Filter set-up complete!"), 8);
|
||||||
|
|
||||||
|
//Use the Filter
|
||||||
|
result.State = BlindscanResultState.Scraping;
|
||||||
|
config.DataStorage.UpdateTransponderState(jobInDb, result.IsSatellite(), result.SearchResult, result.State, result.SearchResult2);
|
||||||
|
config.Ui.OnBlindscanFilterSetUp();
|
||||||
|
|
||||||
|
SkipFilter skipper = new SkipFilter(SkipFilter.CRAZYSCAN_BUFFER * 8);
|
||||||
|
skyscraperContext = SkyscraperContextFactory.CreateSkyscraper(config.DataStorage, config.ObjectStorage);
|
||||||
|
skyscraperContext.TcpProxyEnabled = true;
|
||||||
|
skyscraperContext.UiJunction = config.Ui;
|
||||||
|
IPacketFilter[] packetFilters = new IPacketFilter[0];
|
||||||
|
if (tsRecorder != null)
|
||||||
|
packetFilters = new IPacketFilter[] { tsRecorder, skipper };
|
||||||
|
skyscraperContext.InitalizeFilterChain(packetFilters);
|
||||||
|
|
||||||
|
|
||||||
|
byte[] singlePacketBuffer = new byte[188];
|
||||||
|
packetsReceivedInTotal = 0;
|
||||||
|
startedAt = DateTime.Now;
|
||||||
|
|
||||||
|
//The actual scraping happens in this loop
|
||||||
|
while (!StopConditionMet())
|
||||||
|
{
|
||||||
|
if (!HasPackets())
|
||||||
|
{
|
||||||
|
Thread.Sleep(100);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] packetBuffer = null;
|
||||||
|
lock (packetsQueue)
|
||||||
|
{
|
||||||
|
packetBuffer = packetsQueue.Dequeue();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < packetBuffer.Length; i += 188)
|
||||||
|
{
|
||||||
|
Array.Copy(packetBuffer, i, singlePacketBuffer, 0, 188);
|
||||||
|
skyscraperContext.IngestSinglePacket(singlePacketBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config.Ui.OnBlindscanScrapeStopCondition();
|
||||||
|
//Stop Filter
|
||||||
|
logger.Log(PluginLogLevel.Debug, string.Format("Deleting Filter..."), 8);
|
||||||
|
bool stopped = config.StreamReader.DelFilter(filterReference);
|
||||||
|
if (!stopped)
|
||||||
|
{
|
||||||
|
result.State = BlindscanResultState.DelFilterFailed;
|
||||||
|
config.DataStorage.UpdateTransponderState(jobInDb, result.IsSatellite(), result.SearchResult, result.State, result.SearchResult2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.Log(PluginLogLevel.Debug, string.Format("Deleted filter!"), 8);
|
||||||
|
DrainPackets();
|
||||||
|
skyscraperContext.Dispose();
|
||||||
|
|
||||||
|
if (tsRecorder != null)
|
||||||
|
tsRecorder.Dispose();
|
||||||
|
|
||||||
|
result.State = BlindscanResultState.DataSaving;
|
||||||
|
config.DataStorage.UpdateTransponderState(jobInDb, result.IsSatellite(), result.SearchResult, result.State, result.SearchResult2);
|
||||||
|
|
||||||
|
foreach (HumanReadableService humanReadableService in config.Ui.GetServices())
|
||||||
|
{
|
||||||
|
config.DataStorage.InsertTransponderService(jobInDb, result.IsSatellite(), result.SearchResult, result.SearchResult2, humanReadableService);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.State = BlindscanResultState.Done;
|
||||||
|
config.DataStorage.UpdateTransponderState(jobInDb, result.IsSatellite(), result.SearchResult, result.State, result.SearchResult2);
|
||||||
|
config.Ui.OnBlindscanAfterPacketDrain();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Queue<byte[]> packetsQueue;
|
||||||
|
private void DvbCallback(nint data, int length)
|
||||||
|
{
|
||||||
|
if (length % 188 == 0)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[length];
|
||||||
|
Marshal.Copy(data, buffer, 0, length);
|
||||||
|
|
||||||
|
lock (packetsQueue)
|
||||||
|
{
|
||||||
|
packetsQueue.Enqueue(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
packetsReceivedInTotal += (uint)(buffer.Length / 188);
|
||||||
|
config.Ui.OnBlindscanPacketOk(buffer.Length / 188, packetsQueue.Count);
|
||||||
|
}
|
||||||
|
catch (OutOfMemoryException e)
|
||||||
|
{
|
||||||
|
config.Ui.OnBlindscanPacketError(2, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Warn, string.Format("odd packet size!"), 8);
|
||||||
|
config.Ui.OnBlindscanPacketError(1, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ISkyscraperContext skyscraperContext;
|
||||||
|
private ulong packetsReceivedInTotal;
|
||||||
|
private DateTime startedAt;
|
||||||
|
private bool StopConditionMet()
|
||||||
|
{
|
||||||
|
if (startedAt == DateTime.MinValue)
|
||||||
|
startedAt = DateTime.Now;
|
||||||
|
|
||||||
|
if (config.Ui.IsZapNowRequested())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config.Ui.MayAutoZap())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (packetsReceivedInTotal == 0 && (DateTime.Now - startedAt).TotalSeconds > 5)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (skyscraperContext.GetIpCommunicationParties() > 1000)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!skyscraperContext.EnableTimeout)
|
||||||
|
{
|
||||||
|
skyscraperContext.TimeoutSeconds = 10;
|
||||||
|
skyscraperContext.EnableTimeout = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packetsReceivedInTotal > 0 && skyscraperContext.IsAbortConditionMet())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private bool HasPackets()
|
||||||
|
{
|
||||||
|
lock (packetsQueue)
|
||||||
|
{
|
||||||
|
return packetsQueue.Count > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrainPackets()
|
||||||
|
{
|
||||||
|
if (packetsQueue.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
logger.Log(PluginLogLevel.Warn, string.Format("{0} packets left after switching off the filter.", packetsQueue.Count), 8);
|
||||||
|
|
||||||
|
DateTime startedAt = DateTime.Now;
|
||||||
|
byte[] singlePacketBuffer = new byte[188];
|
||||||
|
byte[] packetBuffer = null;
|
||||||
|
DateTime drainTickerPrevious = DateTime.Now, drainTickerNow = DateTime.Now;
|
||||||
|
while (packetsQueue.Count > 0)
|
||||||
|
{
|
||||||
|
packetBuffer = packetsQueue.Dequeue();
|
||||||
|
if (packetBuffer == null)
|
||||||
|
continue;
|
||||||
|
for (int i = 0; i < packetBuffer.Length; i += 188)
|
||||||
|
{
|
||||||
|
Array.Copy(packetBuffer, i, singlePacketBuffer, 0, 188);
|
||||||
|
skyscraperContext.IngestSinglePacket(singlePacketBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
drainTickerPrevious = drainTickerNow;
|
||||||
|
drainTickerNow = DateTime.Now;
|
||||||
|
if (drainTickerNow.Second != drainTickerPrevious.Second)
|
||||||
|
{
|
||||||
|
logger.Log(PluginLogLevel.Warn, string.Format("{0} packets left ({1}).", packetsQueue.Count, drainTickerNow.ToLongTimeString()), 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Log(PluginLogLevel.Warn, string.Format("Packets drained in {0} seconds.", (DateTime.Now - startedAt).TotalSeconds), 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using skyscraper5.Skyscraper;
|
||||||
|
using skyscraper5.Skyscraper.Equipment;
|
||||||
|
using skyscraper5.Skyscraper.Gps;
|
||||||
|
using skyscraper5.Skyscraper.IO;
|
||||||
|
using skyscraper5.Skyscraper.Scraper;
|
||||||
|
using skyscraper8.Skyscraper.Scraper.Storage;
|
||||||
|
|
||||||
|
namespace skyscraper8.Skyscraper.FrequencyListGenerator
|
||||||
|
{
|
||||||
|
public class BlindscanJobConfiguration
|
||||||
|
{
|
||||||
|
public IStreamReader StreamReader { get; set; }
|
||||||
|
public TunerMetadata TunerMetadata { get; set; }
|
||||||
|
public int DiseqcIndex { get; set; }
|
||||||
|
public IGpsReceiver Gps { get; set; }
|
||||||
|
public SatellitePosition SatellitePosition { get; set; }
|
||||||
|
|
||||||
|
public bool DoHorizontalHigh { get; set; }
|
||||||
|
public bool DoHorizontalLow { get; set; }
|
||||||
|
public bool DoVerticalHigh { get; set; }
|
||||||
|
public bool DoVerticalLow { get; set; }
|
||||||
|
|
||||||
|
public DataStorage DataStorage { get; set; }
|
||||||
|
public ObjectStorage ObjectStorage { get; set; }
|
||||||
|
public ISkyscraperUiJunction Ui { get; set; }
|
||||||
|
public bool DoCollectRfSpectrum { get; set; }
|
||||||
|
public LnbType LnbType { get; set; }
|
||||||
|
public bool DoCollectIqGraphs { get; set; }
|
||||||
|
public bool DoRecordTs { get; set; }
|
||||||
|
public Ini Ini { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
||||||
|
using skyscraper5.src.Skyscraper.FrequencyListGenerator;
|
||||||
|
|
||||||
|
namespace skyscraper8.Skyscraper.FrequencyListGenerator
|
||||||
|
{
|
||||||
|
public class BlindscanSearchResult
|
||||||
|
{
|
||||||
|
public SearchResult SearchResult;
|
||||||
|
public STD_TYPE Standard { get; set; }
|
||||||
|
public BlindscanResultState State { get; set; }
|
||||||
|
public SearchResult2 SearchResult2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, the data is in SearchResult.
|
||||||
|
/// If false, the data is in SearchResult2.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsSatellite()
|
||||||
|
{
|
||||||
|
switch (Standard)
|
||||||
|
{
|
||||||
|
case STD_TYPE.STD_DVBS2: return true;
|
||||||
|
case STD_TYPE.STD_DVBS: return true;
|
||||||
|
case STD_TYPE.STD_DVBC: return false;
|
||||||
|
case STD_TYPE.STD_DVBC2: return false;
|
||||||
|
case STD_TYPE.STD_DVBT: return false;
|
||||||
|
case STD_TYPE.STD_DVBT2: return false;
|
||||||
|
default: throw new NotImplementedException(Standard.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long GetFrequency()
|
||||||
|
{
|
||||||
|
if (IsSatellite())
|
||||||
|
return SearchResult.Freq;
|
||||||
|
else
|
||||||
|
return SearchResult2.Freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char GetPolarity(int lnbTypeLofSw)
|
||||||
|
{
|
||||||
|
if (IsSatellite())
|
||||||
|
{
|
||||||
|
if (lnbTypeLofSw == 0 && SearchResult.Pol == 0)
|
||||||
|
return 'L';
|
||||||
|
else if (lnbTypeLofSw == 0 && SearchResult.Pol == 1)
|
||||||
|
return 'R';
|
||||||
|
else if (lnbTypeLofSw != 0 && SearchResult.Pol == 0)
|
||||||
|
return 'H';
|
||||||
|
else if (lnbTypeLofSw != 0 && SearchResult.Pol == 1)
|
||||||
|
return 'V';
|
||||||
|
else
|
||||||
|
throw new NotImplementedException("Couldn't figure out signal polarity.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 'T';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetSymbolRate()
|
||||||
|
{
|
||||||
|
if (IsSatellite())
|
||||||
|
return SearchResult.SR;
|
||||||
|
else
|
||||||
|
return SearchResult2.SR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,306 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using skyscraper5.Skyscraper.IO;
|
||||||
|
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
||||||
|
|
||||||
|
namespace skyscraper8.Skyscraper.FrequencyListGenerator
|
||||||
|
{
|
||||||
|
public class CoopBlindscanStreamReader : IStreamReader
|
||||||
|
{
|
||||||
|
private readonly IStreamReader _proxiedStreamReader;
|
||||||
|
private readonly int _blindScanTuner;
|
||||||
|
private readonly int _setFilterTuner;
|
||||||
|
|
||||||
|
public CoopBlindscanStreamReader(IStreamReader proxiedStreamReader, int blindScanTuner, int setFilterTuner)
|
||||||
|
{
|
||||||
|
_proxiedStreamReader = proxiedStreamReader;
|
||||||
|
_blindScanTuner = blindScanTuner;
|
||||||
|
_setFilterTuner = setFilterTuner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CheckForDVB()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CheckForDVBEx(DvbEnumCallback func)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CheckForDVBExEx(DvbEnumCallbackEx func)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool StartDVB()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool StartDvbEx(int index)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool StopDVB()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetTunerType(ref STD_TYPE type)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SendDiSEqC(uint diseqcType, DiSEqC_Opcode data)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SendDiseqCmd(byte[] buffer, int length)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SendDiseqCmdEx(nint pCmd, int length, nint reply, int replyLength)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetChannel(int freq, int symbrate, int pol, VITERBIRATE_TYPE fec, int lof1, int lof2, int lofsw)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetChannelEx(int freq, int symbrate, int pol, VITERBIRATE_TYPE fec, int lof1, int lof2, int lofsw, MOD_TYPE mod)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetChannelExEx(int freq, int symbrate, int pol, VITERBIRATE_TYPE fec, int lof1, int lof2, int lofsw, MOD_TYPE mod,
|
||||||
|
int inv, int pilot, ROLLOFF_TYPE rolloff)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetFilter(int pid, StdcallDvbCallback func, int callbackType, int size, ref nint lpFilterNum)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetFilterEx(int pid, StdcallDvbCallbackEx lpFunc, int callbackType, int size, ref nint lpFilterNum)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetBitFilter(int pid, nint filterData, nint filterMask, byte filterLength, StdcallDvbCallback lpFunc,
|
||||||
|
ref nint lpFilterNum)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetRemoteControl(int irtype, short devAddr, StdcallDvbCallback func, ref nint lpFilterNum)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DelFilter(nint filterNum)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetSignal(ref int pStrength, ref int pQuality)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetSignalStrength(ref float pStrength, ref float pQuality)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetSignalEx(ref float pSNR, ref float pBER)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetSignalExEx(ref bool pPresent, ref bool pLock, ref int pRFLevel, ref float pSNR, ref float pBER)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Statistic(int[] pStat)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetMAC(byte[] pMac)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Caps GetCaps()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RFScan(int freq, int pol, int lof1, int lof2, int lofsw, out double pRFLevel)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool FFTInit()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool FFTScan(int freq, int pol, int lof1, int lof2, int lofsw, uint range, byte mode, byte nb_acc, nint pTab,
|
||||||
|
nint pBegin, nint pNum)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool BLScan(int freq, int freq_range, int pol, int lof1, int lof2, int lofsw, int minsr,
|
||||||
|
ref SearchResult pSearchResult)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool BLScanEx(int freq, int freq_range, int pol, int lof1, int lof2, int lofsw, int minsr, STD_TYPE std,
|
||||||
|
ref SearchResult pSearchResult)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool BLScan2(int freq_start, int freq_stop, int pol, int lof1, int lof2, int lofsw, nint pSearchResult, ref int pTpNum,
|
||||||
|
BlScanCallback lpFunc)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SignalInfo(ref SearchResult pSearchResult)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IQScan(uint input, sbyte[] pIQ, uint num)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IQScan2(uint point, short[] pIQ, uint num)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IQScan2Range(byte input, ref ushort pMinPoint, ref ushort pMaxPoint)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CIRScanRange(bool bHiRes, ref ushort pMinCnum, ref ushort pMaxCnum, ref int pMinDelayNs, ref int pMaxDelayNs)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CIRScan(bool bHiRes, int[] pPowers, int[] pDelays)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CarRange(ref ushort pMinCnum, ref ushort pMaxCnum)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CarEsNo(ref ushort cnum, ref double pEsNo)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MISSel(bool bEnable, byte misFilter, byte misFilterMask)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool PLSSel(byte plsMode, uint code)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool PLSGet(byte pMode, ref uint pCode)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ModSel(ref S2Mode ps2Modes, uint num)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ModInv(uint WaitMs, ref S2Mode pS2Modes, ref uint pNum)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetChannel2(uint freq, uint bandwidth)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetChannel2Ex(uint freq, uint bandwidth, STD_TYPE std, int stream)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetChannel2ExEx(uint freq, uint bandwidth, uint symbrate, STD_TYPE std, int stream)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SignalInfo2(ref SearchResult2 si2)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RFScan2(uint freq, STD_TYPE std, ref double pRFLevel)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AirScan(int freq_start, int freq_stop, uint step, uint bandwidth, int std, nint pSearchResult, ref int pTpNum,
|
||||||
|
AirScanCallback lpFunc)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetEEPROM(byte[] buffer, int offset, int len)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetEEPROM(byte[] buffer, int offset, int len)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Version GetEngineVersion()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetEngineName()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,203 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using skyscraper5.Docsis;
|
|
||||||
using skyscraper5.Dvb.DataBroadcasting.SkyscraperVfs;
|
|
||||||
using skyscraper5.Dvb.Descriptors;
|
|
||||||
using skyscraper5.Dvb.Psi.Model;
|
|
||||||
using skyscraper5.Mhp.Si.Model;
|
|
||||||
using skyscraper5.Mpeg2.Descriptors;
|
|
||||||
using skyscraper5.Mpeg2.Psi.Model;
|
|
||||||
using skyscraper5.Scte35;
|
|
||||||
using skyscraper5.Skyscraper.Net;
|
|
||||||
using skyscraper5.Skyscraper.Scraper;
|
|
||||||
using skyscraper5.Teletext.Wss;
|
|
||||||
|
|
||||||
namespace skyscraper5.src.Skyscraper.FrequencyListGenerator
|
|
||||||
{
|
|
||||||
internal class FrequencyListGeneratorJunction : ISkyscraperUiJunction
|
|
||||||
{
|
|
||||||
public FrequencyListGeneratorJunction()
|
|
||||||
{
|
|
||||||
sdtServices = new Dictionary<ushort, SdtService>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dictionary<ushort, SdtService> sdtServices;
|
|
||||||
private Dictionary<ushort, ProgramMapping> programMappings;
|
|
||||||
|
|
||||||
public void NotifyEvent(EitEvent eitEvent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifySdtService(SdtService sdtService)
|
|
||||||
{
|
|
||||||
if (!sdtServices.ContainsKey(sdtService.ServiceId))
|
|
||||||
sdtServices.Add(sdtService.ServiceId, sdtService);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyPatProgram(int pmtPid, ushort programId)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyPmtProgram(ProgramMapping result, int pmtPid)
|
|
||||||
{
|
|
||||||
if (!programMappings.ContainsKey(result.ProgramNumber))
|
|
||||||
programMappings.Add(result.ProgramNumber, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyNit(NitTransportStream transportStream)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyMpeTraffic(IpTrafficInfo iti, int ipv4PacketLength)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyAit(AitApplication aitApplication)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DsmCcModuleAdd(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DsmCcModuleProgress(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion,
|
|
||||||
double moduleInfoDownloadProgress)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DsmCcModuleComplete(int elementaryPid, ushort moduleModuleId, byte moduleModuleVersion)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyWss(ushort programNumber, WssDataBlock wssDataBlock)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyStreamTypeDetection(string contestantTag, int pid)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyBat(BatBouquet batBouquet)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyBatTs(ushort batBouquetBouquetId, BatTransportStream child)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DsmCcVfs(VfsFile vfsFile)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyTot(DateTime utcTime, LocalTimeOffsetDescriptor ltod)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyTdt(DateTime utcTime)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyCat(CaDescriptor caDescriptor)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyScte35(ushort programNumber, SpliceInsert spliceInsert)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyScte35(ushort programNumber, TimeSignal spliceInsert)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetMemorySaverMode(bool saveMemory)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyDocsisCarrier(DocsisEnvironment docsisEnvironment)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyDocsisFrequency(uint? frequency, bool isUpstream, object mmm)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetGseMode()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ShowFramegrab(int currentNetworkId, int transportStreamId, ushort mappingProgramNumber,
|
|
||||||
int mappingStreamElementaryPid, byte[] imageData)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyBlockstreamCarrier()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<HumanReadableService> GetServices()
|
|
||||||
{
|
|
||||||
foreach (var (pmtPid, pmt) in programMappings)
|
|
||||||
{
|
|
||||||
ushort serviceId = pmt.ProgramNumber;
|
|
||||||
if (!sdtServices.ContainsKey(serviceId))
|
|
||||||
continue;
|
|
||||||
SdtService service = sdtServices[serviceId];
|
|
||||||
string providerName = service.ServiceProviderName;
|
|
||||||
string serviceName = service.ServiceName;
|
|
||||||
ushort? caId = GetCaId(pmt, service);
|
|
||||||
ServiceDescriptor.ServiceTypeCoding serviceType = service.ServiceType.GetValueOrDefault();
|
|
||||||
yield return new HumanReadableService(serviceId, providerName, serviceName, caId, serviceType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ushort? GetCaId(ProgramMapping pmt, SdtService sdt)
|
|
||||||
{
|
|
||||||
if (pmt.CaSystemId.HasValue)
|
|
||||||
{
|
|
||||||
return pmt.CaSystemId.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (ProgramMappingStream stream in pmt.Streams)
|
|
||||||
{
|
|
||||||
if (stream.CaSystemId.HasValue)
|
|
||||||
return stream.CaSystemId.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sdt.CaIdentifiers != null)
|
|
||||||
{
|
|
||||||
if (sdt.CaIdentifiers.Length > 0)
|
|
||||||
{
|
|
||||||
return sdt.CaIdentifiers[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
38
skyscraper8/Skyscraper/FrequencyListGenerator/TaskQueue.cs
Normal file
38
skyscraper8/Skyscraper/FrequencyListGenerator/TaskQueue.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace skyscraper8.Skyscraper.FrequencyListGenerator
|
||||||
|
{
|
||||||
|
public class TaskQueue
|
||||||
|
{
|
||||||
|
public TaskQueue()
|
||||||
|
{
|
||||||
|
tasks = new Queue<Action>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Queue<Action> tasks;
|
||||||
|
|
||||||
|
public void EnqueueTask(Action a)
|
||||||
|
{
|
||||||
|
lock (this)
|
||||||
|
{
|
||||||
|
tasks.Enqueue(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ProcessTasks()
|
||||||
|
{
|
||||||
|
lock (this)
|
||||||
|
{
|
||||||
|
while (tasks.Count > 0)
|
||||||
|
{
|
||||||
|
Action dequeue = tasks.Dequeue();
|
||||||
|
dequeue.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,469 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.NetworkInformation;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
|
||||||
using skyscraper5.Skyscraper.Scraper;
|
|
||||||
using skyscraper5.Skyscraper.Scraper.Storage.Filesystem;
|
|
||||||
using skyscraper8.Skyscraper.Scraper.Storage;
|
|
||||||
|
|
||||||
namespace skyscraper5.Skyscraper.IO
|
|
||||||
{
|
|
||||||
internal class StreamReaderScanController : IDisposable
|
|
||||||
{
|
|
||||||
private readonly IStreamReader streamReader;
|
|
||||||
|
|
||||||
public static List<StreamReaderTuner> GetTuners(IStreamReader streamReader)
|
|
||||||
{
|
|
||||||
List<StreamReaderTuner> result = new List<StreamReaderTuner>();
|
|
||||||
bool checkForDvbExEx = streamReader.CheckForDVBExEx((index, name, type) =>
|
|
||||||
{
|
|
||||||
result.Add(new StreamReaderTuner(index, name, type));
|
|
||||||
});
|
|
||||||
if (!checkForDvbExEx)
|
|
||||||
{
|
|
||||||
return new List<StreamReaderTuner>();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<StreamReaderTuner> GetTunersByStandard(STD_TYPE stdType)
|
|
||||||
{
|
|
||||||
return GetTuners(streamReader).Where(x => x.Type == stdType).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public StreamReaderTuner GetTunerByStandard(STD_TYPE stdType)
|
|
||||||
{
|
|
||||||
List<StreamReaderTuner> streamReaderTuners = GetTunersByStandard(stdType);
|
|
||||||
if (streamReaderTuners.Count == 0)
|
|
||||||
return null;
|
|
||||||
else
|
|
||||||
return streamReaderTuners[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool busy;
|
|
||||||
private PhysicalAddress physicalAddress;
|
|
||||||
private STD_TYPE stdType;
|
|
||||||
private Caps caps;
|
|
||||||
private StreamReaderTuner tunerMetadata;
|
|
||||||
private static int instances = 0;
|
|
||||||
private bool disposed;
|
|
||||||
|
|
||||||
public StreamReaderScanController(IStreamReader streamReader, StreamReaderTuner tuner)
|
|
||||||
{
|
|
||||||
this.streamReader = streamReader;
|
|
||||||
|
|
||||||
if (instances > 0)
|
|
||||||
{
|
|
||||||
throw new StreamReaderException("Only one StreamReader may be active, dispose the other one first.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tuner != null)
|
|
||||||
{
|
|
||||||
tunerMetadata = tuner;
|
|
||||||
if (!streamReader.StartDvbEx(tuner.Index))
|
|
||||||
{
|
|
||||||
throw new StreamReaderException(string.Format("{0} failed", nameof(streamReader.StartDvbEx)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!streamReader.StartDVB())
|
|
||||||
{
|
|
||||||
throw new StreamReaderException(string.Format("{0} failed", nameof(streamReader.StartDVB)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
caps = streamReader.GetCaps();
|
|
||||||
if (!streamReader.GetTunerType(ref stdType))
|
|
||||||
{
|
|
||||||
throw new StreamReaderException(string.Format("{0} failed", nameof(streamReader.GetTunerType)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (caps.HasFlag(Caps.SR_GETMAC))
|
|
||||||
{
|
|
||||||
byte[] macBuffer = new byte[6];
|
|
||||||
if (streamReader.GetMAC(macBuffer))
|
|
||||||
{
|
|
||||||
physicalAddress = new PhysicalAddress(macBuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string[] strings = Enum.GetNames(typeof(StreamReaderParameter));
|
|
||||||
parameters = new uint[strings.Length];
|
|
||||||
paramsSet = new bool[strings.Length];
|
|
||||||
|
|
||||||
if (stdType == STD_TYPE.STD_DVBC)
|
|
||||||
SetDefaultDvbCParameters();
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool[] paramsSet;
|
|
||||||
private uint[] parameters;
|
|
||||||
public enum StreamReaderParameter : int
|
|
||||||
{
|
|
||||||
ScanStartFreq,
|
|
||||||
ScanEndFreq,
|
|
||||||
ScanStep,
|
|
||||||
ScanBandwidth,
|
|
||||||
ScanStdType,
|
|
||||||
ScanLof1,
|
|
||||||
ScanLofSwitch,
|
|
||||||
ScanLof2,
|
|
||||||
ScanDiseqcType,
|
|
||||||
DiseqcSwitchPosition
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetParameter(StreamReaderParameter key, uint value)
|
|
||||||
{
|
|
||||||
parameters[(int)key] = value;
|
|
||||||
paramsSet[(int)key] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint GetParameter(StreamReaderParameter key)
|
|
||||||
{
|
|
||||||
if (!paramsSet[(int)key])
|
|
||||||
{
|
|
||||||
throw new StreamReaderException(string.Format("{0} was not set.", key.ToString()));
|
|
||||||
}
|
|
||||||
return parameters[(int)key];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetDefaultDvbCParameters()
|
|
||||||
{
|
|
||||||
SetParameter(StreamReaderParameter.ScanStartFreq, 48000);
|
|
||||||
SetParameter(StreamReaderParameter.ScanEndFreq, 1000000);
|
|
||||||
SetParameter(StreamReaderParameter.ScanStep, 3000);
|
|
||||||
SetParameter(StreamReaderParameter.ScanBandwidth, 8000);
|
|
||||||
SetParameter(StreamReaderParameter.ScanStdType, (uint)STD_TYPE.STD_DVBC);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetDefaultKuBandParameters()
|
|
||||||
{
|
|
||||||
SetParameter(StreamReaderParameter.ScanLof1, 9750000);
|
|
||||||
SetParameter(StreamReaderParameter.ScanLofSwitch, 11700000);
|
|
||||||
SetParameter(StreamReaderParameter.ScanLof2, 10600000);
|
|
||||||
SetParameter(StreamReaderParameter.ScanStartFreq, 10700000);
|
|
||||||
SetParameter(StreamReaderParameter.ScanEndFreq, 12750000);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (busy)
|
|
||||||
{
|
|
||||||
throw new StreamReaderException("TunerMetadata is busy.");
|
|
||||||
}
|
|
||||||
|
|
||||||
streamReader.StopDVB();
|
|
||||||
instances--;
|
|
||||||
disposed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class StreamReaderTuner
|
|
||||||
{
|
|
||||||
public int Index { get; }
|
|
||||||
public string Name { get; }
|
|
||||||
public STD_TYPE Type { get; }
|
|
||||||
|
|
||||||
public StreamReaderTuner(int index, string name, STD_TYPE type)
|
|
||||||
{
|
|
||||||
Index = index;
|
|
||||||
Name = name;
|
|
||||||
Type = type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Tune(BlindScanResult blindScanResult)
|
|
||||||
{
|
|
||||||
switch (stdType)
|
|
||||||
{
|
|
||||||
case STD_TYPE.STD_DVBC:
|
|
||||||
Console.WriteLine("Tuning to {0} Mhz", blindScanResult.SearchResult2.Freq / 1000.0);
|
|
||||||
bool channel2 = streamReader.SetChannel2((uint)blindScanResult.SearchResult2.Freq, (uint)blindScanResult.SearchResult2.BW);
|
|
||||||
if (!channel2)
|
|
||||||
{
|
|
||||||
throw new StreamReaderException(string.Format("{0} failed", nameof(streamReader.SetChannel2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchResult2 sr2 = default;
|
|
||||||
bool signalInfo2 = streamReader.SignalInfo2(ref sr2);
|
|
||||||
if (!signalInfo2)
|
|
||||||
{
|
|
||||||
throw new StreamReaderException(string.Format("{0} failed", nameof(streamReader.SetChannel2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return sr2.Lock;
|
|
||||||
case STD_TYPE.STD_DVBS:
|
|
||||||
Console.WriteLine("Tuning to {0} Mhz", blindScanResult.SearchResult1.Freq / 1000.0);
|
|
||||||
SearchResult searchResult1 = blindScanResult.SearchResult1;
|
|
||||||
uint lof1 = GetParameter(StreamReaderParameter.ScanLof1);
|
|
||||||
uint lof2 = GetParameter(StreamReaderParameter.ScanLof2);
|
|
||||||
uint lofSw = GetParameter(StreamReaderParameter.ScanLofSwitch);
|
|
||||||
if (!streamReader.SetChannel(searchResult1.Freq, searchResult1.SR, searchResult1.Pol, searchResult1.FEC, (int)lof1, (int)lof2, (int)lofSw))
|
|
||||||
{
|
|
||||||
throw new StreamReaderException(string.Format("{0} failed", nameof(streamReader.SetChannel)));
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchResult cmp = default;
|
|
||||||
bool signalInfo = streamReader.SignalInfo(ref cmp);
|
|
||||||
if (!signalInfo)
|
|
||||||
{
|
|
||||||
throw new StreamReaderException(string.Format("{0} failed", nameof(streamReader.SignalInfo)));
|
|
||||||
}
|
|
||||||
return cmp.Lock;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SearchResult2Callback(BlindScanResults results, SearchResult2 sr2Ptr)
|
|
||||||
{
|
|
||||||
BlindScanResult bbsr = new BlindScanResult();
|
|
||||||
bbsr.System = stdType;
|
|
||||||
bbsr.SearchResult2 = sr2Ptr;
|
|
||||||
results.Transponders.Add(bbsr);
|
|
||||||
|
|
||||||
Console.WriteLine("{0} Mhz, {1} ksyms, {2}", sr2Ptr.Freq / 1000.0, sr2Ptr.SR / 1000, (MOD_TYPE)sr2Ptr.ModType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SearchResult2Callback(BlindScanResults results, SearchResult sr2Ptr)
|
|
||||||
{
|
|
||||||
BlindScanResult bbsr = new BlindScanResult();
|
|
||||||
bbsr.SearchResult1 = sr2Ptr;
|
|
||||||
bbsr.System = stdType;
|
|
||||||
results.Transponders.Add(bbsr);
|
|
||||||
|
|
||||||
Console.WriteLine("{0} Mhz, {1} ksyms, {2}", sr2Ptr.Freq / 1000.0, sr2Ptr.SR / 1000, (MOD_TYPE)sr2Ptr.ModType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SendDiseqcCommand(int diseqcType, bool highBand, bool horizontal)
|
|
||||||
{
|
|
||||||
DiSEqC_Opcode myOpcode = DiSEqC_Opcode.DISEQC_HIGH_NIBBLE;
|
|
||||||
if (highBand)
|
|
||||||
myOpcode |= DiSEqC_Opcode.DISEQC_HIGH_BAND;
|
|
||||||
else
|
|
||||||
myOpcode |= DiSEqC_Opcode.DISEQC_LOW_BAND;
|
|
||||||
|
|
||||||
if (horizontal)
|
|
||||||
myOpcode |= DiSEqC_Opcode.DISEQC_HORIZONTAL;
|
|
||||||
else
|
|
||||||
myOpcode |= DiSEqC_Opcode.DISEQC_VERTICAL;
|
|
||||||
|
|
||||||
if (diseqcType == 2)
|
|
||||||
{
|
|
||||||
uint parameter = GetParameter(StreamReaderParameter.DiseqcSwitchPosition);
|
|
||||||
switch (parameter)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
myOpcode |= DiSEqC_Opcode.DISEQC_OPTION_A;
|
|
||||||
myOpcode |= DiSEqC_Opcode.DISEQC_POSITION_A;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
myOpcode |= DiSEqC_Opcode.DISEQC_OPTION_A;
|
|
||||||
myOpcode |= DiSEqC_Opcode.DISEQC_POSITION_B;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
myOpcode |= DiSEqC_Opcode.DISEQC_OPTION_B;
|
|
||||||
myOpcode |= DiSEqC_Opcode.DISEQC_POSITION_A;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
myOpcode |= DiSEqC_Opcode.DISEQC_OPTION_B;
|
|
||||||
myOpcode |= DiSEqC_Opcode.DISEQC_POSITION_B;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(StreamReaderParameter.DiseqcSwitchPosition));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sendDiSEqC = streamReader.SendDiSEqC((uint)diseqcType, myOpcode);
|
|
||||||
if (!sendDiSEqC)
|
|
||||||
{
|
|
||||||
throw new StreamReaderException(string.Format("{0} failed", nameof(streamReader.SendDiSEqC)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RunBlindscan()
|
|
||||||
{
|
|
||||||
if (busy)
|
|
||||||
throw new StreamReaderException("TunerMetadata is busy");
|
|
||||||
|
|
||||||
int startFreq = (int)GetParameter(StreamReaderParameter.ScanStartFreq);
|
|
||||||
int endFreq = (int)GetParameter(StreamReaderParameter.ScanEndFreq);
|
|
||||||
|
|
||||||
BlindScanResults result = new BlindScanResults();
|
|
||||||
result.Standard = stdType;
|
|
||||||
switch (stdType)
|
|
||||||
{
|
|
||||||
case STD_TYPE.STD_DVBC:
|
|
||||||
if (caps.HasFlag(Caps.SR_AIRSCAN))
|
|
||||||
{
|
|
||||||
|
|
||||||
uint step = GetParameter(StreamReaderParameter.ScanStep);
|
|
||||||
uint bandwidth = GetParameter(StreamReaderParameter.ScanBandwidth);
|
|
||||||
STD_TYPE stdType = (STD_TYPE)GetParameter(StreamReaderParameter.ScanStdType);
|
|
||||||
SearchResult2 sr2 = default;
|
|
||||||
int tpNum = default;
|
|
||||||
IntPtr pSearchResult = Marshal.AllocHGlobal(ushort.MaxValue);
|
|
||||||
busy = true;
|
|
||||||
bool airScan = streamReader.AirScan(startFreq, endFreq, step, bandwidth, (int)stdType, pSearchResult, ref tpNum, (ref SearchResult2 searchResult) => SearchResult2Callback(result, searchResult));
|
|
||||||
if (airScan)
|
|
||||||
{
|
|
||||||
Scrape(result);
|
|
||||||
}
|
|
||||||
busy = false;
|
|
||||||
Marshal.FreeHGlobal(pSearchResult);
|
|
||||||
if (!airScan)
|
|
||||||
{
|
|
||||||
throw new StreamReaderException(string.Format("{0} failed", nameof(streamReader.GetTunerType)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new NotImplementedException("Don't know how to blindscan with this tuner.");
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case STD_TYPE.STD_DVBS:
|
|
||||||
if (caps.HasFlag(Caps.SR_BLSCAN2))
|
|
||||||
{
|
|
||||||
SearchResult sr1 = default;
|
|
||||||
int tpNum = default;
|
|
||||||
|
|
||||||
int lof1 = (int)GetParameter(StreamReaderParameter.ScanLof1);
|
|
||||||
int lof2 = (int)GetParameter(StreamReaderParameter.ScanLof2);
|
|
||||||
int lofSw = (int)GetParameter(StreamReaderParameter.ScanLofSwitch);
|
|
||||||
int diseqc = (int)GetParameter(StreamReaderParameter.ScanDiseqcType);
|
|
||||||
|
|
||||||
IntPtr allocHGlobal = Marshal.AllocHGlobal(ushort.MaxValue);
|
|
||||||
|
|
||||||
if (lofSw != 0)
|
|
||||||
{
|
|
||||||
busy = true;
|
|
||||||
|
|
||||||
result.Transponders.Clear();
|
|
||||||
SendDiseqcCommand(diseqc, false, true);
|
|
||||||
bool hLower = streamReader.BLScan2(startFreq, lofSw, 0, lof1, lof2, lofSw, allocHGlobal, ref tpNum, (ref SearchResult searchResult) => SearchResult2Callback(result, searchResult));
|
|
||||||
if (hLower)
|
|
||||||
{
|
|
||||||
Scrape(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Transponders.Clear();
|
|
||||||
SendDiseqcCommand(diseqc, true, true);
|
|
||||||
bool hUpper = streamReader.BLScan2(lofSw, endFreq, 0, lof1, lof2, lofSw, allocHGlobal, ref tpNum, (ref SearchResult searchResult) => SearchResult2Callback(result, searchResult));
|
|
||||||
if (hUpper)
|
|
||||||
{
|
|
||||||
Scrape(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Transponders.Clear();
|
|
||||||
SendDiseqcCommand(diseqc, false, false);
|
|
||||||
bool vLower = streamReader.BLScan2(startFreq, lofSw, 1, lof1, lof2, lofSw, allocHGlobal, ref tpNum, (ref SearchResult searchResult) => SearchResult2Callback(result, searchResult));
|
|
||||||
if (vLower)
|
|
||||||
{
|
|
||||||
Scrape(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Transponders.Clear();
|
|
||||||
SendDiseqcCommand(diseqc, true, false);
|
|
||||||
bool vUpper = streamReader.BLScan2(lofSw, endFreq, 1, lof1, lof2, lofSw, allocHGlobal, ref tpNum, (ref SearchResult searchResult) => SearchResult2Callback(result, searchResult));
|
|
||||||
if (vUpper)
|
|
||||||
{
|
|
||||||
Scrape(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
busy = false;
|
|
||||||
if (!hLower && !hUpper && !vLower && !vUpper)
|
|
||||||
throw new StreamReaderException(string.Format("{0} failed", nameof(streamReader.BLScan2)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new NotImplementedException("non switching lnb");
|
|
||||||
}
|
|
||||||
|
|
||||||
Marshal.FreeHGlobal(allocHGlobal);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new NotImplementedException("Don't know how to blindscan with this tuner.");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException(stdType.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private StreamReaderScraperController srsc2;
|
|
||||||
private void Scrape(BlindScanResults blindScanResults)
|
|
||||||
{
|
|
||||||
if (srsc2 == null)
|
|
||||||
{
|
|
||||||
srsc2 = new StreamReaderScraperController(streamReader);
|
|
||||||
srsc2.RecordingOutputDirectory = new DirectoryInfo("recordings");
|
|
||||||
srsc2.Recording = true;
|
|
||||||
srsc2.DataStorage = new FilesystemStorage(new DirectoryInfo("srtest_results"));
|
|
||||||
srsc2.ObjectStorage = (ObjectStorage)srsc2.DataStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (BlindScanResult blindScanResult in blindScanResults.Transponders)
|
|
||||||
{
|
|
||||||
if (Tune(blindScanResult))
|
|
||||||
{
|
|
||||||
srsc2.SetNamingHint(blindScanResult);
|
|
||||||
srsc2.Run();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Console.WriteLine("Lock failed.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
class StreamReaderException : SkyscraperIOException
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// For guidelines regarding the creation of new exception types, see
|
|
||||||
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp
|
|
||||||
// and
|
|
||||||
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp
|
|
||||||
//
|
|
||||||
|
|
||||||
public StreamReaderException()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public StreamReaderException(string message) : base(message)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public StreamReaderException(string message, Exception inner) : base(message, inner)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected StreamReaderException(
|
|
||||||
SerializationInfo info,
|
|
||||||
StreamingContext context) : base(info, context)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class BlindScanResults
|
|
||||||
{
|
|
||||||
public BlindScanResults()
|
|
||||||
{
|
|
||||||
Transponders = new List<BlindScanResult>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BlindScanResult> Transponders { get; private set; }
|
|
||||||
public STD_TYPE Standard { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
class BlindScanResult
|
|
||||||
{
|
|
||||||
public SearchResult2 SearchResult2 { get; set; }
|
|
||||||
public SearchResult SearchResult1 { get; set; }
|
|
||||||
public STD_TYPE System { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,324 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Threading;
|
|
||||||
using skyscraper5.Mpeg2;
|
|
||||||
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
|
||||||
using skyscraper5.Skyscraper.Scraper;
|
|
||||||
using skyscraper5.Skyscraper.Scraper.Storage;
|
|
||||||
using skyscraper8.Skyscraper.Scraper.Storage;
|
|
||||||
|
|
||||||
namespace skyscraper5.Skyscraper.IO
|
|
||||||
{
|
|
||||||
internal class StreamReaderScraperController
|
|
||||||
{
|
|
||||||
private readonly IStreamReader streamReader;
|
|
||||||
|
|
||||||
public StreamReaderScraperController(IStreamReader streamReader)
|
|
||||||
{
|
|
||||||
this.streamReader = streamReader;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private const string RECORDING_FILENAME_MASK = "skyscraper_{0}.ts";
|
|
||||||
|
|
||||||
public DataStorage DataStorage { get; set; }
|
|
||||||
public ObjectStorage ObjectStorage { get; set; }
|
|
||||||
|
|
||||||
public bool Recording { get; set; }
|
|
||||||
|
|
||||||
public DirectoryInfo RecordingOutputDirectory { get; set; }
|
|
||||||
|
|
||||||
private bool PrepareRecording()
|
|
||||||
{
|
|
||||||
if (!Recording)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (RecordingOutputDirectory == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
DirectoryInfo rootDirectory = RecordingOutputDirectory.Root;
|
|
||||||
DriveInfo driveInfo = new DriveInfo(rootDirectory.FullName);
|
|
||||||
long driveFreeSpace = driveInfo.TotalFreeSpace;
|
|
||||||
long driveTotalSize = driveInfo.TotalSize;
|
|
||||||
long tenPercentOfDriveTotal = driveTotalSize / 10;
|
|
||||||
if (driveFreeSpace > tenPercentOfDriveTotal)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
FileInfo[] fileInfos = RecordingOutputDirectory.GetFiles(string.Format(RECORDING_FILENAME_MASK, "*"));
|
|
||||||
Array.Sort(fileInfos, (x, y) => DateTime.Compare(x.CreationTimeUtc, y.CreationTimeUtc));
|
|
||||||
long sizeOfAllKnown = fileInfos.Select(x => x.Length).Sum();
|
|
||||||
long driveFreeSpaceAfterDeleting = driveFreeSpace + sizeOfAllKnown;
|
|
||||||
if (driveFreeSpaceAfterDeleting < tenPercentOfDriveTotal)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (int i = 0; i < fileInfos.Length; i++)
|
|
||||||
{
|
|
||||||
fileInfos[i].Delete();
|
|
||||||
Console.WriteLine("Deleted for rotation: {0}", fileInfos[i].Name);
|
|
||||||
fileInfos[i] = null;
|
|
||||||
driveInfo = new DriveInfo(rootDirectory.FullName);
|
|
||||||
driveFreeSpace = driveInfo.TotalFreeSpace;
|
|
||||||
if (driveFreeSpace > tenPercentOfDriveTotal)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
driveInfo = new DriveInfo(rootDirectory.FullName);
|
|
||||||
driveFreeSpace = driveInfo.TotalFreeSpace;
|
|
||||||
if (driveFreeSpace > tenPercentOfDriveTotal)
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool HasLock(bool cableTv)
|
|
||||||
{
|
|
||||||
if (cableTv)
|
|
||||||
{
|
|
||||||
SearchResult2 sr2 = new SearchResult2();
|
|
||||||
if (!streamReader.SignalInfo2(ref sr2))
|
|
||||||
return false;
|
|
||||||
return sr2.Lock;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SearchResult sr = new SearchResult();
|
|
||||||
if (!streamReader.SignalInfo(ref sr))
|
|
||||||
return false;
|
|
||||||
return sr.Lock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ulong packetsReceivedInTotal;
|
|
||||||
private Queue<byte[]> packetsQueue;
|
|
||||||
private void DvbCallback(IntPtr data, int length)
|
|
||||||
{
|
|
||||||
if (length % 188 == 0)
|
|
||||||
{
|
|
||||||
byte[] buffer = new byte[length];
|
|
||||||
Marshal.Copy(data, buffer, 0, length);
|
|
||||||
lock (packetsQueue)
|
|
||||||
{
|
|
||||||
packetsQueue.Enqueue(buffer);
|
|
||||||
}
|
|
||||||
packetsReceivedInTotal++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine("odd packet size!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool HasPackets()
|
|
||||||
{
|
|
||||||
lock (packetsQueue)
|
|
||||||
{
|
|
||||||
return packetsQueue.Count > 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private DateTime startedAt;
|
|
||||||
private bool StopConditionMet()
|
|
||||||
{
|
|
||||||
if (startedAt == DateTime.MinValue)
|
|
||||||
startedAt = DateTime.Now;
|
|
||||||
|
|
||||||
if (packetsReceivedInTotal == 0 && (DateTime.Now - startedAt).TotalSeconds > 5)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (!skyscraperContext.EnableTimeout)
|
|
||||||
{
|
|
||||||
skyscraperContext.TimeoutSeconds = 10;
|
|
||||||
skyscraperContext.EnableTimeout = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packetsReceivedInTotal > 0 && skyscraperContext.IsAbortConditionMet())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrainPackets()
|
|
||||||
{
|
|
||||||
if (packetsQueue.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
DateTime startedAt = DateTime.Now;
|
|
||||||
byte[] singlePacketBuffer = new byte[188];
|
|
||||||
byte[] packetBuffer = null;
|
|
||||||
while (packetsQueue.Count > 0)
|
|
||||||
{
|
|
||||||
packetBuffer = packetsQueue.Dequeue();
|
|
||||||
if (recordingBufferedStream != null)
|
|
||||||
recordingBufferedStream.Write(packetBuffer, 0, packetBuffer.Length);
|
|
||||||
for (int i = 0; i < packetBuffer.Length; i += 188)
|
|
||||||
{
|
|
||||||
Array.Copy(packetBuffer, i, singlePacketBuffer, 0, 188);
|
|
||||||
skyscraperContext.IngestSinglePacket(singlePacketBuffer);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private BufferedStream recordingBufferedStream;
|
|
||||||
private FileStream recordingFileStream;
|
|
||||||
private SkyscraperContext skyscraperContext;
|
|
||||||
public void Run()
|
|
||||||
{
|
|
||||||
bool cableTvMode = false;
|
|
||||||
Caps caps = streamReader.GetCaps();
|
|
||||||
if (caps.HasFlag(Caps.SR_SIGINFO))
|
|
||||||
{
|
|
||||||
cableTvMode = false;
|
|
||||||
}
|
|
||||||
else if (caps.HasFlag(Caps.SR_SIGINFO2))
|
|
||||||
{
|
|
||||||
cableTvMode = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new NotImplementedException("Couldn't figure out what signal info to use.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!HasLock(cableTvMode))
|
|
||||||
{
|
|
||||||
throw new NotImplementedException("No lock.");
|
|
||||||
}
|
|
||||||
|
|
||||||
int misCounter = 1;
|
|
||||||
int misMode = 0;
|
|
||||||
byte[] s2_is = null;
|
|
||||||
if (!cableTvMode)
|
|
||||||
{
|
|
||||||
SearchResult sr = default;
|
|
||||||
if (!streamReader.SignalInfo(ref sr))
|
|
||||||
{
|
|
||||||
throw new StreamReaderException(string.Format("{0} failed", nameof(streamReader.SignalInfo)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sr.Lock)
|
|
||||||
return;
|
|
||||||
|
|
||||||
misMode = sr.MIS;
|
|
||||||
s2_is = sr.IS;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int mis = 0; mis < misCounter; mis++)
|
|
||||||
{
|
|
||||||
if (misMode != 0)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Selecting MIS IS {0}", s2_is[mis]);
|
|
||||||
bool misSel = streamReader.MISSel(misMode != 0, s2_is[mis], 0xff);
|
|
||||||
if (!misSel)
|
|
||||||
{
|
|
||||||
throw new StreamReaderException(string.Format("{0} failed", nameof(streamReader.MISSel)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Start Filter
|
|
||||||
if (PrepareRecording())
|
|
||||||
{
|
|
||||||
string recordingFileName = GenerateRecordingFilename(mis, misMode);
|
|
||||||
FileInfo recordingFileInfo = new FileInfo(recordingFileName);
|
|
||||||
recordingFileInfo.Directory.EnsureExists();
|
|
||||||
recordingFileStream = recordingFileInfo.OpenWrite();
|
|
||||||
recordingBufferedStream = new BufferedStream(recordingFileStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
IntPtr filterReference = IntPtr.MaxValue;
|
|
||||||
packetsQueue = new Queue<byte[]>();
|
|
||||||
bool filter = streamReader.SetFilter(8192, DvbCallback, 0x02, 2, ref filterReference);
|
|
||||||
if (!filter)
|
|
||||||
{
|
|
||||||
throw new Exception("failed to set filter");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Use the Filter
|
|
||||||
skyscraperContext = new SkyscraperContext(new TsContext(), DataStorage,ObjectStorage);
|
|
||||||
skyscraperContext.TcpProxyEnabled = true;
|
|
||||||
byte[] singlePacketBuffer = new byte[188];
|
|
||||||
while (!StopConditionMet())
|
|
||||||
{
|
|
||||||
if (!HasPackets())
|
|
||||||
{
|
|
||||||
Thread.Sleep(100);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] packetBuffer = null;
|
|
||||||
lock (packetsQueue)
|
|
||||||
{
|
|
||||||
packetBuffer = packetsQueue.Dequeue();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (recordingBufferedStream != null)
|
|
||||||
recordingBufferedStream.Write(packetBuffer, 0, packetBuffer.Length);
|
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < packetBuffer.Length; i += 188)
|
|
||||||
{
|
|
||||||
Array.Copy(packetBuffer, i, singlePacketBuffer, 0, 188);
|
|
||||||
skyscraperContext.IngestSinglePacket(singlePacketBuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Stop Filter
|
|
||||||
bool stopped = streamReader.DelFilter(filterReference);
|
|
||||||
if (!stopped)
|
|
||||||
{
|
|
||||||
throw new Exception("failed to stop filter");
|
|
||||||
}
|
|
||||||
|
|
||||||
DrainPackets();
|
|
||||||
if (recordingBufferedStream != null)
|
|
||||||
{
|
|
||||||
recordingBufferedStream.Flush();
|
|
||||||
recordingBufferedStream.Close();
|
|
||||||
recordingBufferedStream.Dispose();
|
|
||||||
recordingBufferedStream = null;
|
|
||||||
recordingFileStream.Close();
|
|
||||||
recordingFileStream.Dispose();
|
|
||||||
recordingFileStream = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GenerateRecordingFilename(int mis, int misMode)
|
|
||||||
{
|
|
||||||
DateTime dt = DateTime.Now;
|
|
||||||
string dateFmt = string.Format("{0:D4}{1:D2}{2:D2}_{3:D2}{4:D2}", dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute);
|
|
||||||
if (namingHint != null)
|
|
||||||
{
|
|
||||||
switch (namingHint.System)
|
|
||||||
{
|
|
||||||
case STD_TYPE.STD_DVBS:
|
|
||||||
string resultS = null;
|
|
||||||
if (misMode == 0)
|
|
||||||
{
|
|
||||||
resultS = string.Format("{0}_{1}_{2}_{3}.ts", dateFmt, namingHint.SearchResult1.Freq / 1000, namingHint.SearchResult1.Pol == 0 ? "H" : "V", namingHint.SearchResult1.SR / 1000);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
resultS = string.Format("{0}_{1}_{2}_{3}_MIS{4}.ts", dateFmt, namingHint.SearchResult1.Freq / 1000, namingHint.SearchResult1.Pol == 0 ? "H" : "V", namingHint.SearchResult1.SR / 1000, mis);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Path.Combine(RecordingOutputDirectory.FullName, resultS);
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException(namingHint.System.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Path.Combine(RecordingOutputDirectory.FullName, string.Format(RECORDING_FILENAME_MASK, dateFmt));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private BlindScanResult namingHint;
|
|
||||||
public void SetNamingHint(BlindScanResult blindScanResult)
|
|
||||||
{
|
|
||||||
namingHint = blindScanResult;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -25,5 +25,6 @@ namespace skyscraper5.Skyscraper.Scraper
|
|||||||
|
|
||||||
public void InitalizeFilterChain(params IPacketFilter[] args);
|
public void InitalizeFilterChain(params IPacketFilter[] args);
|
||||||
|
|
||||||
}
|
int GetIpCommunicationParties();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,9 +12,13 @@ using skyscraper5.Mhp.Si.Model;
|
|||||||
using skyscraper5.Mpeg2.Descriptors;
|
using skyscraper5.Mpeg2.Descriptors;
|
||||||
using skyscraper5.Mpeg2.Psi.Model;
|
using skyscraper5.Mpeg2.Psi.Model;
|
||||||
using skyscraper5.Scte35;
|
using skyscraper5.Scte35;
|
||||||
|
using skyscraper5.Skyscraper.Equipment;
|
||||||
|
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
||||||
using skyscraper5.Skyscraper.Net;
|
using skyscraper5.Skyscraper.Net;
|
||||||
using skyscraper5.src.Skyscraper.FrequencyListGenerator;
|
using skyscraper5.src.Skyscraper.FrequencyListGenerator;
|
||||||
using skyscraper5.Teletext.Wss;
|
using skyscraper5.Teletext.Wss;
|
||||||
|
using skyscraper8.Skyscraper.Drawing;
|
||||||
|
using skyscraper8.Skyscraper.FrequencyListGenerator;
|
||||||
|
|
||||||
namespace skyscraper5.Skyscraper.Scraper
|
namespace skyscraper5.Skyscraper.Scraper
|
||||||
{
|
{
|
||||||
@ -48,5 +52,143 @@ namespace skyscraper5.Skyscraper.Scraper
|
|||||||
void NotifyBlockstreamCarrier();
|
void NotifyBlockstreamCarrier();
|
||||||
|
|
||||||
IEnumerable<HumanReadableService> GetServices();
|
IEnumerable<HumanReadableService> GetServices();
|
||||||
|
void OnBlindscanOpenFoundFrquenciesWindow(List<BlindscanSearchResult> foundFrequencies, STD_TYPE tunerMetadataType);
|
||||||
|
void OnBlindscanJobDone(bool success);
|
||||||
|
void OnBlindscanErrorMessage(string blindscanningLowHorizontalAreaFailed);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called after the part of a band (e.g. Horizontal High) has completed blindscanning.
|
||||||
|
/// Is supposed to move the puppets in the SDL2 based UI to their home position.
|
||||||
|
/// </summary>
|
||||||
|
void OnBlindscanBandComplete();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called before a BLScan operation begins.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="minimum">The minimum frequency to scan</param>
|
||||||
|
/// <param name="currentProgress">The Frequency on which we're starting.</param>
|
||||||
|
/// <param name="maximum">The maximum frequency to scan</param>
|
||||||
|
void OnBlindscanBeforeBLScan(int minimum, int currentProgress, int maximum);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called before a BLScan operation ends.
|
||||||
|
/// </summary>
|
||||||
|
void OnBlindscanAfterBLScan();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when a transponder is found during a BLScan2.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="searchResult"></param>
|
||||||
|
/// <param name="polarityIndex"></param>
|
||||||
|
/// <param name="lnbTypeMinimumFrequency"></param>
|
||||||
|
/// <param name="lnbTypeMaximumFrequency"></param>
|
||||||
|
void OnBlindscanSearchResult1Callback(BlindscanSearchResult searchResult, int polarityIndex, int lnbTypeMinimumFrequency, int lnbTypeMaximumFrequency);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called before a SetChannel operation is performed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="blindscanResult"></param>
|
||||||
|
void OnBlindscanBeforeSetChannel(BlindscanSearchResult blindscanResult, LnbType lnbType);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called after a band (meaning e.g. Horizontal High) has been scraped.
|
||||||
|
/// In the SDL2 version, this is supposed to move the puppets back to their home position.
|
||||||
|
/// </summary>
|
||||||
|
void OnScrapeBandComplete();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called after a single transponder has been scraped.
|
||||||
|
/// In the SDL2 version, this is supposed to hide the pressure plate representing the transponder.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="blindscanResult"></param>
|
||||||
|
void OnBlindscanScrapeTransponderComplete(BlindscanSearchResult blindscanResult);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when beginning to gather the RF Spectrum.
|
||||||
|
/// In the SDL2 version, this is supposed to create the ScottPlot window.
|
||||||
|
/// </summary>
|
||||||
|
void OnBlindscanBeginRfSpectrum();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when a data point for the RF Spectrum is available.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="polarization"></param>
|
||||||
|
/// <param name="frequency"></param>
|
||||||
|
/// <param name="rf"></param>
|
||||||
|
void OnBlindscanRfSpectrumEnqueueSample(SatelliteDeliverySystemDescriptor.PolarizationEnum polarization, int frequency, double rf);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the gathering of the RF Spectrum has been completed.
|
||||||
|
/// In the SDL2 version, this is supposed to close the ScottPlotWindow.
|
||||||
|
/// </summary>
|
||||||
|
void OnBlindscanEndRfSpectrum();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when beginning to gather an IQ Spectrum.
|
||||||
|
/// In the SDL2 version, this is supposed to create a Surface for Pixel drawing.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="result"></param>
|
||||||
|
void OnBlindscanBeginIqSpectrum(IqChartData result);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the gathering of an IQ Spectrum has been completed.
|
||||||
|
/// In the SDL2 version, this is supposed to remove the Surface for Pixel drawing.
|
||||||
|
/// </summary>
|
||||||
|
void OnBlindscanEndIq();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when a lock couldn't be acquired.
|
||||||
|
/// In the SDL2 version, this is supposed to play the fail.wav sound.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="satelliteSr"></param>
|
||||||
|
/// <param name="resultState"></param>
|
||||||
|
void OnBlindscanLockFail(SearchResult satelliteSr, BlindscanResultState resultState);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called before SetFilter is called.
|
||||||
|
/// In the SDL2 version, this is supposed to:
|
||||||
|
/// 1) Spawn all these nice windows about PAT, CAT, PMT, EIT, etc...
|
||||||
|
/// 2) Play the Success1.wav
|
||||||
|
/// 3) Set the packet counters in foundFrequenciesWindow to 0.
|
||||||
|
/// 4) Enable the Zap now button in the foundFrequenciesWindow.
|
||||||
|
/// </summary>
|
||||||
|
void OnBlindscanFilterSetUp();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called after we're done collecting packets from a transponder.
|
||||||
|
/// In the SDL2 version, this is supposed to:
|
||||||
|
/// 1) Disable the Zap now button in the foundFrequenciesWindow.
|
||||||
|
/// </summary>
|
||||||
|
void OnBlindscanScrapeStopCondition();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called after the packets collected from the transponder have all been processed.
|
||||||
|
/// In the SDL2 version, this is supposed to:
|
||||||
|
/// 1) Hide all the windows about DVB Tables
|
||||||
|
/// </summary>
|
||||||
|
void OnBlindscanAfterPacketDrain();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when StreamReader has invoked a DvbCallback.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="errorCount">1 when the packet size is odd. 2 when out of memory</param>
|
||||||
|
/// <param name="length">The size of the data StreamReader gave to the DvbCallback</param>
|
||||||
|
void OnBlindscanPacketError(int errorCount, int length);
|
||||||
|
|
||||||
|
void OnBlindscanPacketOk(int numPackets, int packetsQueueCount);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks whether the user asks to abort scraping and switch to the next transponder.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Returns true if the button has been pressed.</returns>
|
||||||
|
bool IsZapNowRequested();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks whether the user asks not to zap automatically.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Returns true if the "Do not auto-zap" checkbox is checked in the FoundFrequenciesWIndow</returns>
|
||||||
|
bool MayAutoZap();
|
||||||
|
|
||||||
|
TaskQueue Tasks { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -229,6 +229,14 @@ namespace skyscraper5.Skyscraper.Scraper
|
|||||||
logger.DebugFormat("Built filter chain: {0}", stringBuilder.ToString());
|
logger.DebugFormat("Built filter chain: {0}", stringBuilder.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GetIpCommunicationParties()
|
||||||
|
{
|
||||||
|
if (trafficInfos == null)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return trafficInfos.Count;
|
||||||
|
}
|
||||||
|
|
||||||
public void IngestFromStream(Stream stream)
|
public void IngestFromStream(Stream stream)
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[188];
|
byte[] buffer = new byte[188];
|
||||||
|
|||||||
@ -191,5 +191,7 @@ namespace skyscraper8.Skyscraper.Scraper.Storage
|
|||||||
|
|
||||||
void Ping();
|
void Ping();
|
||||||
IEnumerable<Tuple<int, SatelliteDeliverySystemDescriptor.PolarizationEnum>> GetBlindscanResultFrequencies(Guid selectedGuid);
|
IEnumerable<Tuple<int, SatelliteDeliverySystemDescriptor.PolarizationEnum>> GetBlindscanResultFrequencies(Guid selectedGuid);
|
||||||
|
void InsertUiBlindscanSettingHistory(int settingsWindowBlScanTunerSelection, bool settingsWindowUseDifferentTunerForSetFilter, int settingsWindowSetFilterTunerSelection, int settingsWindowDiseqc, bool settingsWindowCollectIqGraphs, bool settingsWindowCollectRfSpectrum, bool settingsWindowCaptureFile, int settingsWindowSatellite, int settingsWindowLnb, int dish, bool settingsWindowScanHorizontalLow, bool settingsWindowScanHorizontalHigh, bool settingsWindowScanVerticalLow, bool settingsWindowScanVerticalHigh);
|
||||||
|
object[] GetLastUiBlindscanSettings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1121,6 +1121,21 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void InsertUiBlindscanSettingHistory(int settingsWindowBlScanTunerSelection,
|
||||||
|
bool settingsWindowUseDifferentTunerForSetFilter, int settingsWindowSetFilterTunerSelection,
|
||||||
|
int settingsWindowDiseqc, bool settingsWindowCollectIqGraphs, bool settingsWindowCollectRfSpectrum,
|
||||||
|
bool settingsWindowCaptureFile, int settingsWindowSatellite, int settingsWindowLnb, int dish,
|
||||||
|
bool settingsWindowScanHorizontalLow, bool settingsWindowScanHorizontalHigh, bool settingsWindowScanVerticalLow,
|
||||||
|
bool settingsWindowScanVerticalHigh)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] GetLastUiBlindscanSettings()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<Tuple<int, int, ProgramMapping>> SelectAllPmt()
|
public IEnumerable<Tuple<int, int, ProgramMapping>> SelectAllPmt()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|||||||
@ -929,6 +929,21 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void InsertUiBlindscanSettingHistory(int settingsWindowBlScanTunerSelection,
|
||||||
|
bool settingsWindowUseDifferentTunerForSetFilter, int settingsWindowSetFilterTunerSelection,
|
||||||
|
int settingsWindowDiseqc, bool settingsWindowCollectIqGraphs, bool settingsWindowCollectRfSpectrum,
|
||||||
|
bool settingsWindowCaptureFile, int settingsWindowSatellite, int settingsWindowLnb, int dish,
|
||||||
|
bool settingsWindowScanHorizontalLow, bool settingsWindowScanHorizontalHigh, bool settingsWindowScanVerticalLow,
|
||||||
|
bool settingsWindowScanVerticalHigh)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] GetLastUiBlindscanSettings()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<Tuple<int, int, ProgramMapping>> SelectAllPmt()
|
public IEnumerable<Tuple<int, int, ProgramMapping>> SelectAllPmt()
|
||||||
{
|
{
|
||||||
for (int x = 0; x < pmtEntries.Length; x++)
|
for (int x = 0; x < pmtEntries.Length; x++)
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
||||||
|
|
||||||
namespace skyscraper5.Skyscraper
|
namespace skyscraper5.Skyscraper
|
||||||
@ -43,5 +44,19 @@ namespace skyscraper5.Skyscraper
|
|||||||
default: throw new NotImplementedException(String.Format("{0} {1}", nameof(DiseqcType), DiseqcType));
|
default: throw new NotImplementedException(String.Format("{0} {1}", nameof(DiseqcType), DiseqcType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsSatellite()
|
||||||
|
{
|
||||||
|
switch (Type)
|
||||||
|
{
|
||||||
|
case STD_TYPE.STD_DVBS: return true;
|
||||||
|
case STD_TYPE.STD_DVBS2: return true;
|
||||||
|
case STD_TYPE.STD_DVBT: return false;
|
||||||
|
case STD_TYPE.STD_DVBT2: return false;
|
||||||
|
case STD_TYPE.STD_DVBC: return false;
|
||||||
|
case STD_TYPE.STD_DVBC2: return false;
|
||||||
|
default: throw new NotImplementedException(Type.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user