1420 lines
61 KiB
C#
1420 lines
61 KiB
C#
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Diagnostics.Contracts;
|
|
using System.Drawing;
|
|
using System.Net.NetworkInformation;
|
|
using System.Numerics;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.InteropServices;
|
|
using System.Security.Cryptography;
|
|
using ImGuiNET;
|
|
using Newtonsoft.Json;
|
|
using SDL2Demo.Forms;
|
|
using SDL2Demo.SdlWrapper;
|
|
using skyscraper5.Skyscraper;
|
|
using skyscraper5.Skyscraper.IO;
|
|
using skyscraper5.Skyscraper.Scraper;
|
|
using skyscraper5.Skyscraper.Equipment;
|
|
using skyscraper5.Skyscraper.IO;
|
|
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
|
using skyscraper5.src.Skyscraper.FrequencyListGenerator;
|
|
using skyscraper5.src.Mpeg2.PacketFilter;
|
|
using skyscraper8.Skyscraper.Scraper.Storage;
|
|
|
|
namespace SDL2Demo.Jobs
|
|
{
|
|
internal class Blindscan : IRenderable, IJob
|
|
{
|
|
#region Driver
|
|
|
|
public bool WindowOpen;
|
|
public BlindscanTarget SelectedBlindscanTarget;
|
|
|
|
public class BlindscanTarget
|
|
{
|
|
public BlindscanTarget(string name, int tunerIndex, STD_TYPE tunerStandard, int diseqcType,
|
|
SatellitePosition satPosition, int satIndex, LnbType lnbType, PhysicalAddress tunerMetadataMacAddress)
|
|
{
|
|
this.name = name;
|
|
this.tunerIndex = tunerIndex;
|
|
this.tunerStandard = tunerStandard;
|
|
this.diseqcType = diseqcType;
|
|
this.satPosition = satPosition;
|
|
this.satIndex = satIndex;
|
|
this.buttonUuid = Guid.NewGuid().ToString();
|
|
this.lnbType = lnbType;
|
|
this.macAddress = tunerMetadataMacAddress;
|
|
}
|
|
|
|
public string name;
|
|
public int tunerIndex;
|
|
public STD_TYPE tunerStandard;
|
|
public int diseqcType;
|
|
public SatellitePosition satPosition;
|
|
public int satIndex;
|
|
public string buttonUuid;
|
|
public LnbType lnbType;
|
|
public readonly PhysicalAddress macAddress;
|
|
|
|
public bool IsTorC()
|
|
{
|
|
switch (tunerStandard)
|
|
{
|
|
case STD_TYPE.STD_DVBC: return true;
|
|
case STD_TYPE.STD_DVBC2: return true;
|
|
case STD_TYPE.STD_DVBT: return true;
|
|
case STD_TYPE.STD_DVBT2: return true;
|
|
case STD_TYPE.STD_DVBS: return false;
|
|
case STD_TYPE.STD_DVBS2: return false;
|
|
default: throw new NotImplementedException(tunerStandard.ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
private List<BlindscanTarget> possibleBlindscanTargets;
|
|
private string tableUuid;
|
|
private bool willCaptureFiles;
|
|
private IStreamReader streamReader;
|
|
private bool hasSwitchingLnb;
|
|
private bool willScanHorizontalLow, willScanHorizontalHigh, willScanVerticalLow, willScanVerticalHigh;
|
|
private bool continuationDataExists;
|
|
public bool ContinuationMode;
|
|
private FoundFrequenciesWindow ourFoundFrequenciesWindow;
|
|
private bool continueOldJob;
|
|
private DbBlindscanJob jobInDb;
|
|
private IDbBlindscanJobStorage jobStorage;
|
|
|
|
public Blindscan(List<TunerMetadata> tuners, List<SatellitePosition> satellitePositions, List<LnbType> lnbTypes, DataStorage dataStorage)
|
|
{
|
|
this.jobStorage = dataStorage;
|
|
continuationDataExists = jobStorage.TestForIncompleteJob();
|
|
|
|
possibleBlindscanTargets = new List<BlindscanTarget>();
|
|
foreach (TunerMetadata tunerMetadata in tuners)
|
|
{
|
|
switch (tunerMetadata.Type)
|
|
{
|
|
case STD_TYPE.STD_DVBS:
|
|
int numSatsFromDiseqcType = tunerMetadata.GetNumSatsFromDiseqcType();
|
|
for (int i = 0; i < numSatsFromDiseqcType; i++)
|
|
{
|
|
SatellitePosition satellitePosition = satellitePositions.Find(x => x.Checksum == tunerMetadata.Satellites[i]);
|
|
LnbType lnbType = lnbTypes.Find(x => x.Id == tunerMetadata.Lnbs[i]);
|
|
if (satellitePosition == null)
|
|
continue;
|
|
if (lnbType == null)
|
|
continue;
|
|
if (lnbType.LofSw != 0)
|
|
{
|
|
hasSwitchingLnb = true;
|
|
willScanHorizontalHigh = true;
|
|
willScanHorizontalLow = true;
|
|
willScanVerticalHigh = true;
|
|
willScanVerticalLow = true;
|
|
}
|
|
|
|
possibleBlindscanTargets.Add(new BlindscanTarget(tunerMetadata.Name, tunerMetadata.Index,
|
|
tunerMetadata.Type, tunerMetadata.DiseqcType, satellitePosition, i, lnbType, tunerMetadata.MacAddress));
|
|
}
|
|
|
|
break;
|
|
case STD_TYPE.STD_DVBC:
|
|
possibleBlindscanTargets.Add(new BlindscanTarget(tunerMetadata.Name, tunerMetadata.Index, tunerMetadata.Type, 0, null, 0, null, tunerMetadata.MacAddress));
|
|
break;
|
|
case STD_TYPE.STD_DVBT:
|
|
possibleBlindscanTargets.Add(new BlindscanTarget(tunerMetadata.Name, tunerMetadata.Index, tunerMetadata.Type, 0, null, 0, null, tunerMetadata.MacAddress));
|
|
break;
|
|
default:
|
|
throw new NotImplementedException(tunerMetadata.Type.ToString());
|
|
}
|
|
}
|
|
|
|
WindowOpen = true;
|
|
tableUuid = Guid.NewGuid().ToString();
|
|
}
|
|
|
|
public void Render()
|
|
{
|
|
if (ImGui.Begin("Blindscan", ref WindowOpen, ImGuiWindowFlags.AlwaysAutoResize))
|
|
{
|
|
if (possibleBlindscanTargets.Count == 0)
|
|
{
|
|
ImGui.Text("No possible blindscan targets!");
|
|
ImGui.Text("Did you configure the tuners and satellite positions?");
|
|
ImGui.End();
|
|
return;
|
|
}
|
|
|
|
ImGui.BeginTable(tableUuid, 4,
|
|
ImGuiTableFlags.NoSavedSettings | ImGuiTableFlags.Borders | ImGuiTableFlags.SizingFixedFit);
|
|
foreach (BlindscanTarget possibleBlindscanTarget in possibleBlindscanTargets)
|
|
{
|
|
ImGui.TableNextRow();
|
|
ImGui.TableSetColumnIndex(0);
|
|
ImGui.Text(possibleBlindscanTarget.name);
|
|
|
|
ImGui.TableSetColumnIndex(1);
|
|
if (possibleBlindscanTarget.tunerStandard == STD_TYPE.STD_DVBS)
|
|
{
|
|
ImGui.Text(String.Format("DiSEqC Position {0}", possibleBlindscanTarget.satIndex));
|
|
}
|
|
else if (possibleBlindscanTarget.tunerStandard == STD_TYPE.STD_DVBC)
|
|
{
|
|
ImGui.Text("DVB-C");
|
|
}
|
|
|
|
ImGui.TableSetColumnIndex(2);
|
|
if (possibleBlindscanTarget.tunerStandard == STD_TYPE.STD_DVBS)
|
|
{
|
|
ImGui.Text(String.Format("{0} ({1})", possibleBlindscanTarget.satPosition.name, possibleBlindscanTarget.lnbType.Name));
|
|
}
|
|
else
|
|
{
|
|
ImGui.TextWrapped(possibleBlindscanTarget.tunerIndex.ToString());
|
|
}
|
|
|
|
ImGui.TableSetColumnIndex(3);
|
|
ImGui.PushID(possibleBlindscanTarget.buttonUuid);
|
|
if (ImGui.Button("Run scan"))
|
|
{
|
|
WindowOpen = false;
|
|
SelectedBlindscanTarget = possibleBlindscanTarget;
|
|
ContinuationMode = false;
|
|
}
|
|
|
|
ImGui.PopID();
|
|
}
|
|
|
|
ImGui.EndTable();
|
|
|
|
ImGui.Checkbox("Capture Packets to files", ref willCaptureFiles);
|
|
|
|
if (hasSwitchingLnb)
|
|
{
|
|
ImGui.Checkbox("Scan Low Horizontal Region", ref willScanHorizontalLow);
|
|
ImGui.Checkbox("Scan High Horizontal Region", ref willScanHorizontalHigh);
|
|
ImGui.Checkbox("Scan Low Vertical Region", ref willScanVerticalLow);
|
|
ImGui.Checkbox("Scan High Vertical Region", ref willScanVerticalHigh);
|
|
}
|
|
|
|
if (continuationDataExists)
|
|
{
|
|
if (ImGui.Button("Continue with previous run"))
|
|
{
|
|
WindowOpen = false;
|
|
ContinuationMode = true;
|
|
|
|
}
|
|
}
|
|
|
|
ImGui.End();
|
|
}
|
|
}
|
|
|
|
public void Run()
|
|
{
|
|
if (JobContext == null)
|
|
throw new NullReferenceException("Job Context was not enrolled.");
|
|
if (JobContext.StreamReader == null)
|
|
throw new NullReferenceException("No StreamReader available");
|
|
if (streamReader == null)
|
|
streamReader = JobContext.StreamReader;
|
|
|
|
if (continueOldJob)
|
|
{
|
|
throw new NotImplementedException("continue old blindscan job");
|
|
}
|
|
else
|
|
{
|
|
|
|
jobInDb = new DbBlindscanJob(Guid.NewGuid(), SelectedBlindscanTarget.macAddress, SelectedBlindscanTarget.tunerStandard, SelectedBlindscanTarget.satIndex, JobContext.Gps, SelectedBlindscanTarget.satPosition);
|
|
if (SelectedBlindscanTarget.IsTorC())
|
|
{
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_WAITING;
|
|
jobInDb.HorizontalHighState = DbBlindscanJobPolarizationStatus.NOT_SELECTED_NON_S_HINT;
|
|
jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.NOT_SELECTED_NON_S_HINT;
|
|
jobInDb.VerticalHighState = DbBlindscanJobPolarizationStatus.NOT_SELECTED_NON_S_HINT;
|
|
}
|
|
else
|
|
{
|
|
jobInDb.HorizontalHighState = willScanHorizontalHigh ? DbBlindscanJobPolarizationStatus.SELECTED_WAITING : DbBlindscanJobPolarizationStatus.NOT_SELECTED;
|
|
jobInDb.HorizontalLowState = willScanHorizontalLow ? DbBlindscanJobPolarizationStatus.SELECTED_WAITING : DbBlindscanJobPolarizationStatus.NOT_SELECTED;
|
|
jobInDb.VerticalLowState = willScanVerticalLow ? DbBlindscanJobPolarizationStatus.SELECTED_WAITING : DbBlindscanJobPolarizationStatus.NOT_SELECTED;
|
|
jobInDb.VerticalHighState = willScanVerticalHigh ? DbBlindscanJobPolarizationStatus.SELECTED_WAITING : DbBlindscanJobPolarizationStatus.NOT_SELECTED;
|
|
}
|
|
jobStorage.InsertBlindscanJob(jobInDb);
|
|
}
|
|
|
|
//JobContext.LogWindow.Log("Attempting to start the tuner...", 8);
|
|
if (!streamReader.StartDvbEx(SelectedBlindscanTarget.tunerIndex))
|
|
{
|
|
JobContext.MessageQueue.Enqueue(new MessageWindow("Failed to start tuner."));
|
|
JobContext.ReadyForNextJob = true;
|
|
return;
|
|
}
|
|
|
|
//JobContext.LogWindow.Log("Tuner started", 8);
|
|
|
|
foundFrequencies = new List<BlindscanResult>();
|
|
ourFoundFrequenciesWindow = new FoundFrequenciesWindow(foundFrequencies, SelectedBlindscanTarget.tunerStandard, JobContext);
|
|
JobContext.Renderables.Add(ourFoundFrequenciesWindow);
|
|
if (!RunBlindscan())
|
|
{
|
|
streamReader.StopDVB();
|
|
JobContext.ReadyForNextJob = true;
|
|
return;
|
|
}
|
|
|
|
JobContext.Puppets[0].AutoMoveToHome();
|
|
JobContext.Puppets[1].AutoMoveToHome();
|
|
JobContext.Puppets[2].AutoMoveTo(new Point(0, 720 / 2));
|
|
JobContext.Puppets[3].AutoMoveTo(new Point(1280 / 2, 0));
|
|
|
|
//RunScrape();
|
|
streamReader.StopDVB();
|
|
JobContext.ReadyForNextJob = true;
|
|
Console.WriteLine("Blindscan Job done!");
|
|
return;
|
|
}
|
|
|
|
public void Cancel()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public JobContext JobContext { get; set; }
|
|
|
|
#endregion Driver
|
|
|
|
#region Scanner
|
|
|
|
public class BlindscanResult : IPressurePlate
|
|
{
|
|
internal BlindscanResult()
|
|
{
|
|
|
|
}
|
|
|
|
public BlindscanResult(SearchResult2 dvbcResult, int minFreq, int maxFreq)
|
|
{
|
|
Visible = true;
|
|
State = BlindscanResultState.Found;
|
|
|
|
int w = (dvbcResult.Freq / 1000) - minFreq;
|
|
int hundert = 1280;
|
|
int g = (maxFreq - minFreq);
|
|
|
|
int x = w * hundert / g;
|
|
Position = new Point(x, 600);
|
|
|
|
sr2 = dvbcResult;
|
|
Satellite = false;
|
|
}
|
|
|
|
public BlindscanResult(SearchResult searchResult, int satPositionMinFreq, int satPositionMaxFreq)
|
|
{
|
|
int x = 0, y = 0;
|
|
|
|
if (searchResult.Pol == 0)
|
|
{
|
|
//Horizontal
|
|
int w = (searchResult.Freq / 1000) - satPositionMinFreq;
|
|
int hundert = 1280;
|
|
int g = (satPositionMaxFreq - satPositionMinFreq);
|
|
|
|
x = w * hundert / g;
|
|
y = 720 / 2;
|
|
}
|
|
else
|
|
{
|
|
//Vertical
|
|
int w = (searchResult.Freq / 1000) - satPositionMinFreq;
|
|
int hundert = 720;
|
|
int g = (satPositionMaxFreq - satPositionMinFreq);
|
|
|
|
x = 1280 / 2;
|
|
y = w * hundert / g;
|
|
}
|
|
|
|
Position = new Point(x, y);
|
|
Visible = true;
|
|
sr1 = searchResult;
|
|
Satellite = true;
|
|
}
|
|
|
|
|
|
public bool Visible { get; set; }
|
|
public Point Position { get; private set; }
|
|
|
|
public BlindscanResultState State { get; set; }
|
|
|
|
public SearchResult sr1;
|
|
|
|
public SearchResult2 sr2;
|
|
|
|
public bool Satellite { get; private set; }
|
|
|
|
public long GetFrequency()
|
|
{
|
|
if (Satellite)
|
|
{
|
|
return sr1.Freq;
|
|
}
|
|
else
|
|
{
|
|
return sr2.Freq;
|
|
}
|
|
}
|
|
|
|
public char GetPolarity()
|
|
{
|
|
if (Satellite)
|
|
{
|
|
char polarity;
|
|
switch (sr1.Pol)
|
|
{
|
|
case 0: polarity = 'H'; break;
|
|
case 1: polarity = 'V'; break;
|
|
case 2: polarity = 'L'; break;
|
|
case 3: polarity = 'R'; break;
|
|
default: polarity = 'W'; break; //W for WTF?
|
|
}
|
|
return polarity;
|
|
}
|
|
else
|
|
{
|
|
return 'C';
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool RunBlindscan()
|
|
{
|
|
|
|
|
|
Caps caps = streamReader.GetCaps();
|
|
|
|
switch (SelectedBlindscanTarget.tunerStandard)
|
|
{
|
|
case STD_TYPE.STD_DVBC:
|
|
if (caps.HasFlag(Caps.SR_AIRSCAN))
|
|
{
|
|
int startFreq = 48000;
|
|
int endFreq = 1000000;
|
|
uint step = 3000;
|
|
uint bandwidth = 8000;
|
|
STD_TYPE stdType = STD_TYPE.STD_DVBC;
|
|
SearchResult2 sr2 = default;
|
|
int tpNum = default;
|
|
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
|
|
IntPtr pSearchResult = Marshal.AllocHGlobal(UInt16.MaxValue);
|
|
bool airScan = streamReader.AirScan(startFreq, endFreq, step, bandwidth, (int)stdType,
|
|
pSearchResult, ref tpNum,
|
|
((ref SearchResult2 searchResult) => SearchResult2Callback(searchResult)));
|
|
JobContext.Puppets[0].AutoMoveToHome();
|
|
JobContext.Puppets[1].AutoMoveToHome();
|
|
Marshal.FreeHGlobal(pSearchResult);
|
|
if (!airScan)
|
|
{
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
JobContext.MessageQueue.Enqueue(new MessageWindow("AirScan failed."));
|
|
return false;
|
|
}
|
|
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_SCRAPING;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
RunScrape();
|
|
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_DONE;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
throw new NotImplementedException("Don't know how to blindscan with this tuner.");
|
|
}
|
|
case STD_TYPE.STD_DVBS:
|
|
if (caps.HasFlag(Caps.SR_BLSCAN2))
|
|
{
|
|
SearchResult sr1 = default;
|
|
int tpNum = default;
|
|
|
|
int lof1 = SelectedBlindscanTarget.lnbType.Lof1 * 1000;
|
|
int lof2 = SelectedBlindscanTarget.lnbType.Lof2 * 1000;
|
|
int lofSw = SelectedBlindscanTarget.lnbType.LofSw * 1000;
|
|
int diseqc = SelectedBlindscanTarget.diseqcType;
|
|
int startFreq = SelectedBlindscanTarget.lnbType.MinimumFrequency * 1000;
|
|
int endFreq = SelectedBlindscanTarget.lnbType.MaximumFrequency * 1000;
|
|
bool anythingSuceeded = false;
|
|
IntPtr allocHGlobal = Marshal.AllocHGlobal(UInt16.MaxValue);
|
|
|
|
if (lofSw != 0)
|
|
{
|
|
if (willScanHorizontalLow)
|
|
{
|
|
if (SendDiseqcCommand(diseqc, false, true))
|
|
{
|
|
//JobContext.LogWindow.Log(String.Format("Scanning low horizontal band..."));
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
bool hLower = BlScan2Wrap(startFreq, lofSw, 0, lof1, lof2, lofSw,allocHGlobal, ref tpNum,((ref SearchResult searchResult) => SearchResult1Callback(searchResult,1)));
|
|
JobContext.Puppets[0].AutoMoveToHome();
|
|
JobContext.Puppets[1].AutoMoveToHome();
|
|
if (!hLower)
|
|
{
|
|
//JobContext.MessageQueue.Enqueue(new MessageWindow("Blindscanning low horizontal area failed."));
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
}
|
|
else
|
|
{
|
|
anythingSuceeded = true;
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_SCRAPING;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
RunScrape();
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_DONE;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
foundFrequencies.Clear();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
JobContext.MessageQueue.Enqueue(new MessageWindow("DiSEqC Switch to low horizontal area failed."));
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED_DISEQC;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
}
|
|
}
|
|
|
|
if (willScanHorizontalHigh)
|
|
{
|
|
if (SendDiseqcCommand(diseqc, true, true))
|
|
{
|
|
SendDiseqcCommand(diseqc, true, true);
|
|
//JobContext.LogWindow.Log(String.Format("Scanning high horizontal band..."));
|
|
jobInDb.HorizontalHighState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
bool hUpper = BlScan2Wrap(lofSw, endFreq, 0, lof1, lof2, lofSw,allocHGlobal, ref tpNum,((ref SearchResult searchResult) => SearchResult1Callback(searchResult,2)));
|
|
JobContext.Puppets[0].AutoMoveToHome();
|
|
JobContext.Puppets[1].AutoMoveToHome();
|
|
if (!hUpper)
|
|
{
|
|
JobContext.MessageQueue.Enqueue(new MessageWindow("Blindscanning high horizontal area failed."));
|
|
jobInDb.HorizontalHighState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
}
|
|
else
|
|
{
|
|
anythingSuceeded = true;
|
|
jobInDb.HorizontalHighState = DbBlindscanJobPolarizationStatus.SELECTED_SCRAPING;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
RunScrape();
|
|
jobInDb.HorizontalHighState = DbBlindscanJobPolarizationStatus.SELECTED_DONE;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
foundFrequencies.Clear();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
JobContext.MessageQueue.Enqueue(new MessageWindow("DiSEqC Switch to high horizontal area failed."));
|
|
jobInDb.HorizontalHighState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED_DISEQC;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
}
|
|
}
|
|
|
|
if (willScanVerticalLow)
|
|
{
|
|
if (SendDiseqcCommand(diseqc, false, false))
|
|
{
|
|
//JobContext.LogWindow.Log(String.Format("Scanning low vertical band..."));
|
|
jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
bool vLower = BlScan2Wrap(startFreq, lofSw, 1, lof1, lof2, lofSw,allocHGlobal, ref tpNum,((ref SearchResult searchResult) => SearchResult1Callback(searchResult,3)));
|
|
JobContext.Puppets[0].AutoMoveToHome();
|
|
JobContext.Puppets[1].AutoMoveToHome();
|
|
if (!vLower)
|
|
{
|
|
JobContext.MessageQueue.Enqueue(new MessageWindow("Blindscanning low vertical area failed."));
|
|
jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
}
|
|
else
|
|
{
|
|
anythingSuceeded = true;
|
|
jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_SCRAPING;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
RunScrape();
|
|
jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_DONE;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
foundFrequencies.Clear();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
JobContext.MessageQueue.Enqueue(new MessageWindow("DiSEqC Switch to low vertical area failed."));
|
|
jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED_DISEQC;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
}
|
|
}
|
|
|
|
if (willScanVerticalHigh)
|
|
{
|
|
if (SendDiseqcCommand(diseqc, true, false))
|
|
{
|
|
//JobContext.LogWindow.Log(String.Format("Scanning high vertical band..."));
|
|
jobInDb.VerticalHighState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
bool vUpper = BlScan2Wrap(lofSw, endFreq, 1, lof1, lof2, lofSw, allocHGlobal, ref tpNum, ((ref SearchResult searchResult) => SearchResult1Callback(searchResult,4)));
|
|
JobContext.Puppets[0].AutoMoveToHome();
|
|
JobContext.Puppets[1].AutoMoveToHome();
|
|
if (!vUpper)
|
|
{
|
|
JobContext.MessageQueue.Enqueue(new MessageWindow("Blindscanning high vertical area failed."));
|
|
jobInDb.VerticalHighState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
}
|
|
else
|
|
{
|
|
anythingSuceeded = true;
|
|
jobInDb.VerticalHighState = DbBlindscanJobPolarizationStatus.SELECTED_SCRAPING;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
RunScrape();
|
|
jobInDb.VerticalHighState = DbBlindscanJobPolarizationStatus.SELECTED_DONE;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
foundFrequencies.Clear();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
JobContext.MessageQueue.Enqueue(new MessageWindow("DiSEqC Switch to high vertical area failed."));
|
|
jobInDb.VerticalHighState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED_DISEQC;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (SendDiseqcCommand(diseqc, false, true))
|
|
{
|
|
//JobContext.LogWindow.Log(String.Format("Scanning left circular band..."));
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
bool lCirc = BlScan2Wrap(startFreq, endFreq, 0, lof1, lof2, lofSw, allocHGlobal, ref tpNum, ((ref SearchResult searchResult) => SearchResult1Callback(searchResult,1)));
|
|
JobContext.Puppets[0].AutoMoveToHome();
|
|
JobContext.Puppets[1].AutoMoveToHome();
|
|
if (!lCirc)
|
|
{
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
JobContext.MessageQueue.Enqueue(new MessageWindow("Blindscanning left circular area failed."));
|
|
}
|
|
else
|
|
{
|
|
anythingSuceeded = true;
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_SCRAPING;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
RunScrape();
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_DONE;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
foundFrequencies.Clear();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
JobContext.MessageQueue.Enqueue(new MessageWindow("DiSEqC Switch to left circulation failed."));
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED_DISEQC;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
}
|
|
if (SendDiseqcCommand(diseqc, false, false))
|
|
{
|
|
//JobContext.LogWindow.Log(String.Format("Scanning right circular band..."));
|
|
jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
bool rCirc = BlScan2Wrap(startFreq, endFreq, 1, lof1, lof2, lofSw, allocHGlobal, ref tpNum, ((ref SearchResult searchResult) => SearchResult1Callback(searchResult,3)));
|
|
JobContext.Puppets[0].AutoMoveToHome();
|
|
JobContext.Puppets[1].AutoMoveToHome();
|
|
if (!rCirc)
|
|
{
|
|
JobContext.MessageQueue.Enqueue(new MessageWindow("Blindscanning right circular area failed."));
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
}
|
|
else
|
|
{
|
|
anythingSuceeded = true;
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_SCRAPING;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
RunScrape();
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_DONE;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
foundFrequencies.Clear();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
JobContext.MessageQueue.Enqueue(new MessageWindow("DiSEqC Switch to right circulation failed."));
|
|
jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_DONE;
|
|
jobStorage.UpdateJobState(jobInDb);
|
|
}
|
|
}
|
|
|
|
Marshal.FreeHGlobal(allocHGlobal);
|
|
return anythingSuceeded;
|
|
}
|
|
else
|
|
{
|
|
throw new NotImplementedException("Don't know how to blindscan with this tuner.");
|
|
}
|
|
default:
|
|
throw new NotImplementedException(SelectedBlindscanTarget.tunerStandard.ToString());
|
|
}
|
|
}
|
|
|
|
private BlindscanProgressWindow _blindscanProgressWindow;
|
|
private bool BlScan2Wrap(int freq_start, int freq_stop, int pol, int lof1, int lof2, int lofSw, IntPtr pSearchResult, ref int pTpNum, BlScanCallback lpFunc)
|
|
{
|
|
_blindscanProgressWindow = new BlindscanProgressWindow();
|
|
_blindscanProgressWindow.Start = freq_start;
|
|
_blindscanProgressWindow.Progress = freq_start;
|
|
_blindscanProgressWindow.End = freq_stop;
|
|
lock (JobContext.Renderables)
|
|
{
|
|
JobContext.Renderables.Add(_blindscanProgressWindow);
|
|
}
|
|
|
|
bool result = streamReader.BLScan2(freq_start, freq_stop, pol, lof1, lof2, lofSw, pSearchResult, ref pTpNum, lpFunc);
|
|
|
|
lock (JobContext.Renderables)
|
|
{
|
|
JobContext.Renderables.Remove(_blindscanProgressWindow);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private void SearchResult1Callback(SearchResult searchResult, int polarityIndex)
|
|
{
|
|
BlindscanResult blindscanResult = new BlindscanResult(searchResult, SelectedBlindscanTarget.lnbType.MinimumFrequency, SelectedBlindscanTarget.lnbType.MaximumFrequency);
|
|
JobContext.Puppets[blindscanResult.sr1.Pol].AutoMoveTo(blindscanResult.Position);
|
|
lock (JobContext.PressurePlates)
|
|
{
|
|
JobContext.PressurePlates.Add(blindscanResult);
|
|
}
|
|
|
|
lock (foundFrequencies)
|
|
{
|
|
foundFrequencies.Add(blindscanResult);
|
|
}
|
|
|
|
//JobContext.LogWindow.Log(String.Format("Found frequency: {0}, {1}", searchResult.Freq / 1000,searchResult.Pol == 0 ? "H" : "V"));
|
|
SoundPlayer.PlaySoundFile("lock.wav");
|
|
|
|
_blindscanProgressWindow.Progress = searchResult.Freq;
|
|
|
|
jobStorage.InsertSearchResult(jobInDb, true, searchResult, polarityIndex, new SearchResult2());
|
|
}
|
|
|
|
private void SearchResult2Callback(SearchResult2 searchResult)
|
|
{
|
|
BlindscanResult blindscanResult = new BlindscanResult(searchResult, 48, 1000);
|
|
JobContext.Puppets[0].AutoMoveTo(new Point(blindscanResult.Position.X, blindscanResult.Position.Y));
|
|
lock (JobContext.PressurePlates)
|
|
{
|
|
JobContext.PressurePlates.Add(blindscanResult);
|
|
}
|
|
|
|
lock (foundFrequencies)
|
|
{
|
|
foundFrequencies.Add(blindscanResult);
|
|
}
|
|
|
|
//JobContext.LogWindow.Log(String.Format("Found frequency: {0}", searchResult.Freq / 1000));
|
|
SoundPlayer.PlaySoundFile("lock.wav");
|
|
|
|
jobStorage.InsertSearchResult(jobInDb, false, new SearchResult(), 7, searchResult);
|
|
}
|
|
|
|
private bool 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)
|
|
{
|
|
int parameter = SelectedBlindscanTarget.satIndex + 1;
|
|
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");
|
|
}
|
|
}
|
|
|
|
//JobContext.LogWindow.Log(String.Format("Send DiSEqC Command {0:X2}", (byte)myOpcode), 8);
|
|
|
|
DateTime started = DateTime.Now;
|
|
bool result = streamReader.SendDiSEqC((uint)diseqcType, myOpcode);
|
|
TimeSpan timeTaken = DateTime.Now - started;
|
|
//JobContext.LogWindow.Log(String.Format("DiSEqC Comannd sent in {0:F1} seconds.", timeTaken.TotalSeconds));
|
|
if (timeTaken.TotalSeconds > 10)
|
|
{
|
|
//JobContext.LogWindow.Log(String.Format("Something went wrong while performing the DiSEqC operation, trying again..."), 8);
|
|
Thread.Sleep(1000);
|
|
return SendDiseqcCommand(diseqcType, highBand, horizontal);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private List<BlindscanResult> foundFrequencies;
|
|
|
|
#endregion Scanner
|
|
|
|
#region Scraper
|
|
|
|
public void RunScrape()
|
|
{
|
|
int lof1 = 0;
|
|
int lof2 = 0;
|
|
int lofSw = 0;
|
|
|
|
if (SelectedBlindscanTarget.tunerStandard == STD_TYPE.STD_DVBS)
|
|
{
|
|
lof1 = SelectedBlindscanTarget.lnbType.Lof1 * 1000;
|
|
lof2 = SelectedBlindscanTarget.lnbType.Lof2 * 1000;
|
|
lofSw = SelectedBlindscanTarget.lnbType.LofSw * 1000;
|
|
}
|
|
|
|
foreach (BlindscanResult blindscanResult in foundFrequencies)
|
|
{
|
|
recordingFilename = null;
|
|
DateTime now = DateTime.Now;
|
|
switch (SelectedBlindscanTarget.tunerStandard)
|
|
{
|
|
case STD_TYPE.STD_DVBS:
|
|
JobContext.Puppets[2 + blindscanResult.sr1.Pol].AutoMoveTo(blindscanResult.Position);
|
|
blindscanResult.State = BlindscanResultState.Tuning;
|
|
jobStorage.UpdateTransponderState(jobInDb, blindscanResult.Satellite, blindscanResult.sr1, blindscanResult.State, blindscanResult.sr2);
|
|
bool channel = streamReader.SetChannel(blindscanResult.sr1.Freq, blindscanResult.sr1.SR,
|
|
blindscanResult.sr1.Pol, blindscanResult.sr1.FEC, lof1, lof2, lofSw);
|
|
if (!channel)
|
|
{
|
|
blindscanResult.State = BlindscanResultState.TuningFailed;
|
|
jobStorage.UpdateTransponderState(jobInDb, blindscanResult.Satellite, blindscanResult.sr1, blindscanResult.State, blindscanResult.sr2);
|
|
continue;
|
|
}
|
|
|
|
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, blindscanResult.sr1.Freq / 1000,
|
|
blindscanResult.sr1.Pol == 0 ? "H" : "V", blindscanResult.sr1.SR / 1000,
|
|
(int)(SelectedBlindscanTarget.satPosition.angle * 10),
|
|
SelectedBlindscanTarget.satPosition.cardinalDirection == 0 ? "E" : "W");
|
|
break;
|
|
case STD_TYPE.STD_DVBC:
|
|
JobContext.Puppets[1].AutoMoveTo(blindscanResult.Position);
|
|
blindscanResult.State = BlindscanResultState.Tuning;
|
|
jobStorage.UpdateTransponderState(jobInDb, blindscanResult.Satellite, blindscanResult.sr1, blindscanResult.State, blindscanResult.sr2);
|
|
bool channel2 = streamReader.SetChannel2((uint)blindscanResult.sr2.Freq,
|
|
(uint)blindscanResult.sr2.BW);
|
|
if (!channel2)
|
|
{
|
|
blindscanResult.State = BlindscanResultState.TuningFailed;
|
|
jobStorage.UpdateTransponderState(jobInDb, blindscanResult.Satellite, blindscanResult.sr1, blindscanResult.State, blindscanResult.sr2);
|
|
continue;
|
|
}
|
|
|
|
recordingFilename = String.Format("skyscraper_{0:D4}{1:D2}{2:D2}_{3:D2}{4:D2}_C_{5}_{6}.ts",
|
|
now.Year, now.Month, now.Day, now.Hour, now.Minute, blindscanResult.sr2.Freq / 1000,
|
|
blindscanResult.sr2.SR);
|
|
break;
|
|
default:
|
|
throw new NotImplementedException(SelectedBlindscanTarget.tunerStandard.ToString());
|
|
}
|
|
|
|
RunSkyscraper(blindscanResult);
|
|
blindscanResult.Visible = false;
|
|
}
|
|
|
|
JobContext.Puppets[0].AutoMoveToHome();
|
|
JobContext.Puppets[1].AutoMoveToHome();
|
|
JobContext.Puppets[2].AutoMoveToHome();
|
|
JobContext.Puppets[3].AutoMoveToHome();
|
|
}
|
|
|
|
|
|
private JobDisplay jobDisplay;
|
|
private ISkyscraperContext skyscraperContext;
|
|
private string recordingFilename;
|
|
|
|
|
|
|
|
|
|
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 droppedPackets;
|
|
private ulong packetsReceivedInTotal;
|
|
private Queue<byte[]> packetsQueue;
|
|
private int packetsToDrop;
|
|
|
|
private void DvbCallback(IntPtr data, int length)
|
|
{
|
|
if (length % 188 == 0)
|
|
{
|
|
try
|
|
{
|
|
byte[] buffer = new byte[length];
|
|
Marshal.Copy(data, buffer, 0, length);
|
|
|
|
if (packetsToDrop <= 0)
|
|
{
|
|
lock (packetsQueue)
|
|
{
|
|
packetsQueue.Enqueue(buffer);
|
|
}
|
|
}
|
|
|
|
packetsToDrop -= (buffer.Length / 188);
|
|
packetsReceivedInTotal += (uint)(buffer.Length / 188);
|
|
ourFoundFrequenciesWindow.statusPacketsInTotal = packetsReceivedInTotal;
|
|
ourFoundFrequenciesWindow.statusPacketsInqueue = packetsQueue.Count;
|
|
}
|
|
catch (OutOfMemoryException e)
|
|
{
|
|
droppedPackets++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//JobContext.LogWindow.Log(String.Format("odd packet size!"), 8);
|
|
}
|
|
}
|
|
|
|
private bool HasPackets()
|
|
{
|
|
lock (packetsQueue)
|
|
{
|
|
return packetsQueue.Count > 0;
|
|
}
|
|
}
|
|
|
|
private DateTime startedAt;
|
|
|
|
private sbyte[] iqBuffer;
|
|
private DateTime prevIqTimestamp;
|
|
private IqWindow iqWindow;
|
|
|
|
private bool StopConditionMet()
|
|
{
|
|
if (startedAt == DateTime.MinValue)
|
|
startedAt = DateTime.Now;
|
|
|
|
if (ourFoundFrequenciesWindow.zapNowRequested)
|
|
{
|
|
ourFoundFrequenciesWindow.zapNowRequested = false;
|
|
return true;
|
|
}
|
|
|
|
if (ourFoundFrequenciesWindow.doNotAutoZap)
|
|
return false;
|
|
|
|
if (packetsReceivedInTotal == 0 && (DateTime.Now - startedAt).TotalSeconds > 5)
|
|
return true;
|
|
|
|
if (jobDisplay != null)
|
|
{
|
|
if (jobDisplay.GseCommunicationParties > 1000)
|
|
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;
|
|
|
|
//JobContext.LogWindow.Log(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)
|
|
{
|
|
//JobContext.LogWindow.Log(String.Format("{0} packets left ({1}).", packetsQueue.Count, drainTickerNow.ToLongTimeString()),8);
|
|
}
|
|
}
|
|
|
|
//JobContext.LogWindow.Log(String.Format("Packets drained in {0} seconds.", (DateTime.Now - startedAt).TotalSeconds), 8);
|
|
}
|
|
|
|
private void RunSkyscraper(BlindscanResult result)
|
|
{
|
|
int misCounter = 1;
|
|
bool misMode = false;
|
|
bool cableTvMode = false;
|
|
Caps caps = streamReader.GetCaps();
|
|
SearchResult satelliteSr = new SearchResult();
|
|
SearchResult2 cableSr = new SearchResult2();
|
|
|
|
if (caps.HasFlag(Caps.SR_SIGINFO))
|
|
{
|
|
/*if (caps.HasFlag(Caps.SR_MISSEL))
|
|
if (!streamReader.MISSel(false, 0, 0))
|
|
{
|
|
result.State = BlindscanResultState.MisFailure;
|
|
return;
|
|
}
|
|
*/
|
|
|
|
/*S2Mode m = new S2Mode();
|
|
if (caps.HasFlag(Caps.SR_MODSEL))
|
|
if (!streamReader.ModSel(ref m, 0))
|
|
{
|
|
result.State = BlindscanResultState.ModFailure;
|
|
return;
|
|
}*/
|
|
|
|
/*
|
|
if (caps.HasFlag(Caps.SR_PLSSEL))
|
|
if (!streamReader.PLSSel(0, 0))
|
|
{
|
|
result.State = BlindscanResultState.PlsFailure;
|
|
return;
|
|
}
|
|
*/
|
|
|
|
|
|
//JobContext.LogWindow.Log(String.Format("Trying to BLScanEx..."), 8);
|
|
if (!streamReader.BLScanEx(result.sr1.Freq, 5000, result.sr1.Pol,
|
|
SelectedBlindscanTarget.lnbType.Lof1 * 1000, SelectedBlindscanTarget.lnbType.Lof2 * 1000,
|
|
SelectedBlindscanTarget.lnbType.LofSw * 1000, 1000000, (STD_TYPE)result.sr1.StdType,
|
|
ref satelliteSr))
|
|
{
|
|
//No blindscan? No problem! Try anyway!
|
|
satelliteSr = result.sr1;
|
|
satelliteSr.Lock = false;
|
|
result.State = BlindscanResultState.BlScanFailure;
|
|
jobStorage.UpdateTransponderState(jobInDb, result.Satellite, result.sr1, result.State, result.sr2);
|
|
}
|
|
|
|
if (!satelliteSr.Lock)
|
|
{
|
|
//JobContext.LogWindow.Log(String.Format("Trying to SetChannel..."), 8);
|
|
bool channel = streamReader.SetChannel(result.sr1.Freq, result.sr1.SR, result.sr1.Freq, result.sr1.FEC, SelectedBlindscanTarget.lnbType.Lof1 * 1000, SelectedBlindscanTarget.lnbType.Lof2 * 1000, SelectedBlindscanTarget.lnbType.LofSw * 1000);
|
|
if (!channel)
|
|
{
|
|
result.State = BlindscanResultState.TuningFailed;
|
|
SoundPlayer.PlaySoundFile("fail.wav");
|
|
jobStorage.UpdateTransponderState(jobInDb, result.Satellite, result.sr1, result.State, result.sr2);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
//JobContext.LogWindow.Log(String.Format("Trying to get SignalInfo..."), 8);
|
|
bool signalInfo = streamReader.SignalInfo(ref satelliteSr);
|
|
if (!signalInfo)
|
|
{
|
|
result.State = BlindscanResultState.TuningFailed;
|
|
jobStorage.UpdateTransponderState(jobInDb, result.Satellite, result.sr1, result.State, result.sr2);
|
|
SoundPlayer.PlaySoundFile("fail.wav");
|
|
return;
|
|
}
|
|
|
|
if (!satelliteSr.Lock)
|
|
{
|
|
result.State = BlindscanResultState.NoLock;
|
|
jobStorage.UpdateTransponderState(jobInDb, result.Satellite, result.sr1, result.State, result.sr2);
|
|
SoundPlayer.PlaySoundFile("fail.wav");
|
|
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))
|
|
{
|
|
//JobContext.LogWindow.Log(String.Format("Trying to SetChannel2..."), 8);
|
|
bool channel2 = streamReader.SetChannel2((uint)result.sr2.Freq, (uint)result.sr2.BW);
|
|
if (!channel2)
|
|
{
|
|
result.State = BlindscanResultState.TuningFailed;
|
|
jobStorage.UpdateTransponderState(jobInDb, result.Satellite, result.sr1, result.State, result.sr2);
|
|
SoundPlayer.PlaySoundFile("fail.wav");
|
|
return;
|
|
}
|
|
|
|
//JobContext.LogWindow.Log(String.Format("Trying to get SignalInfo2..."), 8);
|
|
bool signalInfo2 = streamReader.SignalInfo2(ref cableSr);
|
|
if (!signalInfo2)
|
|
{
|
|
result.State = BlindscanResultState.TuningFailed;
|
|
jobStorage.UpdateTransponderState(jobInDb, result.Satellite, result.sr1, result.State, result.sr2);
|
|
SoundPlayer.PlaySoundFile("fail.wav");
|
|
return;
|
|
}
|
|
|
|
if (!cableSr.Lock)
|
|
{
|
|
result.State = BlindscanResultState.NoLock;
|
|
jobStorage.UpdateTransponderState(jobInDb, result.Satellite, result.sr1, result.State, result.sr2);
|
|
SoundPlayer.PlaySoundFile("fail.wav");
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw new NotImplementedException("Couldn't figure out what signal info to use.");
|
|
}
|
|
|
|
for (int mis = 0; mis < misCounter; mis++)
|
|
{
|
|
if (misMode)
|
|
{
|
|
//JobContext.LogWindow.Log(String.Format("Selecting MIS IS {0}", satelliteSr.IS[mis]), 8);
|
|
bool misSel = streamReader.MISSel(misMode, satelliteSr.IS[mis], 0xff);
|
|
if (!misSel)
|
|
{
|
|
result.State = BlindscanResultState.MisFailure;
|
|
jobStorage.UpdateTransponderState(jobInDb, result.Satellite, result.sr1, result.State, result.sr2);
|
|
SoundPlayer.PlaySoundFile("fail.wav");
|
|
return;
|
|
}
|
|
}
|
|
|
|
//Start Filter
|
|
TsRecorder tsRecorder = null;
|
|
if (willCaptureFiles)
|
|
{
|
|
tsRecorder = new TsRecorder();
|
|
tsRecorder.Recording = true;
|
|
string outputDirName = JobContext.Ini.ReadValue("recording", "output_dir", "recording_output");
|
|
tsRecorder.RecordingOutputDirectory = new DirectoryInfo(outputDirName);
|
|
tsRecorder.RecordingOutputDirectory.EnsureExists();
|
|
if (tsRecorder.PrepareRecording())
|
|
{
|
|
tsRecorder.SetNextFilename(recordingFilename);
|
|
tsRecorder.CreateBufferedStream();
|
|
}
|
|
}
|
|
|
|
IntPtr filterReference = IntPtr.MaxValue;
|
|
//JobContext.LogWindow.Log(String.Format("Set-Up filter..."), 8);
|
|
packetsToDrop = 1024;
|
|
packetsQueue = new Queue<byte[]>();
|
|
ourFoundFrequenciesWindow.statusPacketsInqueue = 0;
|
|
ourFoundFrequenciesWindow.statusPacketsInTotal = 0;
|
|
bool filter = streamReader.SetFilter(8192, DvbCallback, 0x02, 2, ref filterReference);
|
|
if (!filter)
|
|
{
|
|
result.State = BlindscanResultState.FilterFailure;
|
|
jobStorage.UpdateTransponderState(jobInDb, result.Satellite, result.sr1, result.State, result.sr2);
|
|
SoundPlayer.PlaySoundFile("fail.wav");
|
|
return;
|
|
}
|
|
//JobContext.LogWindow.Log(String.Format("Filter set-up complete!"), 8);
|
|
|
|
//Use the Filter
|
|
result.State = BlindscanResultState.Scraping;
|
|
jobStorage.UpdateTransponderState(jobInDb, result.Satellite, result.sr1, result.State, result.sr2);
|
|
jobDisplay = new JobDisplay(JobContext);
|
|
lock (JobContext.Renderables)
|
|
{
|
|
JobContext.Renderables.Add(jobDisplay);
|
|
}
|
|
|
|
SoundPlayer.PlaySoundFile("Success1.wav");
|
|
skyscraperContext = SkyscraperContextFactory.CreateSkyscraper(JobContext.DataStorage, JobContext.ObjectStorage);
|
|
skyscraperContext.TcpProxyEnabled = true;
|
|
skyscraperContext.UiJunction = jobDisplay;
|
|
IPacketFilter[] packetFilters = new IPacketFilter[0];
|
|
if (tsRecorder != null)
|
|
packetFilters = new IPacketFilter[] { tsRecorder };
|
|
skyscraperContext.InitalizeFilterChain(tsRecorder);
|
|
|
|
|
|
byte[] singlePacketBuffer = new byte[188];
|
|
|
|
startedAt = DateTime.MinValue;
|
|
packetsReceivedInTotal = 0;
|
|
ourFoundFrequenciesWindow.allowZapNow = true;
|
|
|
|
//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);
|
|
}
|
|
}
|
|
ourFoundFrequenciesWindow.allowZapNow = false;
|
|
//Stop Filter
|
|
//JobContext.LogWindow.Log(String.Format("Deleting Filter..."), 8);
|
|
bool stopped = streamReader.DelFilter(filterReference);
|
|
if (!stopped)
|
|
{
|
|
result.State = BlindscanResultState.DelFilterFailed;
|
|
jobStorage.UpdateTransponderState(jobInDb, result.Satellite, result.sr1, result.State, result.sr2);
|
|
return;
|
|
}
|
|
//JobContext.LogWindow.Log(String.Format("Deleted filter!"), 8);
|
|
DrainPackets();
|
|
skyscraperContext.Dispose();
|
|
|
|
if (tsRecorder != null)
|
|
tsRecorder.Dispose();
|
|
|
|
|
|
lock (JobContext.Renderables)
|
|
{
|
|
JobContext.Renderables.Remove(jobDisplay);
|
|
}
|
|
|
|
result.State = BlindscanResultState.DataSaving;
|
|
jobStorage.UpdateTransponderState(jobInDb, result.Satellite, result.sr1, result.State, result.sr2);
|
|
|
|
foreach (HumanReadableService humanReadableService in jobDisplay.GetServices())
|
|
{
|
|
jobStorage.InsertTransponderService(jobInDb, result.Satellite, result.sr1, result.sr2, humanReadableService);
|
|
}
|
|
|
|
jobDisplay = null;
|
|
result.State = BlindscanResultState.Done;
|
|
jobStorage.UpdateTransponderState(jobInDb, result.Satellite, result.sr1, result.State, result.sr2);
|
|
|
|
|
|
}
|
|
/*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))
|
|
{
|
|
result.State = BlindscanResultState.NoLock;
|
|
return;
|
|
}
|
|
|
|
int misCounter = 1;
|
|
int misMode = 0;
|
|
byte[] s2_is = null;
|
|
if (!cableTvMode)
|
|
{
|
|
SearchResult sr = default;
|
|
if (!streamReader.SignalInfo(ref sr))
|
|
{
|
|
result.State = BlindscanResultState.NoLock;
|
|
return;
|
|
}
|
|
|
|
if (sr.MIS > 16)
|
|
sr.MIS = 0;
|
|
|
|
if (!sr.Lock)
|
|
return;
|
|
|
|
misMode = sr.MIS;
|
|
s2_is = sr.IS;
|
|
}
|
|
|
|
for (int mis = 0; mis < misCounter; mis++)
|
|
{
|
|
if (misMode != 0)
|
|
{
|
|
JobContext.LogWindow.Log(String.Format("Selecting MIS IS {0}", s2_is[mis]),8);
|
|
bool misSel = streamReader.MISSel(misMode != 0, s2_is[mis], 0xff);
|
|
if (!misSel)
|
|
{
|
|
result.State = BlindscanResultState.MisFailure;
|
|
return;
|
|
}
|
|
}
|
|
|
|
//Start Filter
|
|
if (PrepareRecording())
|
|
{
|
|
FileInfo recordingFileInfo = new FileInfo(Path.Combine(RecordingOutputDirectory.FullName,recordingFilename));
|
|
recordingFileInfo.Directory.EnsureExists();
|
|
recordingFileStream = recordingFileInfo.OpenWrite();
|
|
recordingBufferedStream = new BufferedStream(recordingFileStream);
|
|
}
|
|
|
|
IntPtr filterReference = IntPtr.MaxValue;
|
|
JobContext.LogWindow.Log(String.Format("before set filter"), 8);
|
|
packetsQueue = new Queue<byte[]>();
|
|
bool filter = streamReader.SetFilter(8192, DvbCallback, 0x02, 2, ref filterReference);
|
|
if (!filter)
|
|
{
|
|
result.State = BlindscanResultState.FilterFailure;
|
|
return;
|
|
}
|
|
|
|
//Use the Filter
|
|
result.State = BlindscanResultState.Scraping;
|
|
jobDisplay = new JobDisplay(JobContext);
|
|
lock (JobContext.Renderables)
|
|
{
|
|
JobContext.Renderables.Add(jobDisplay);
|
|
}
|
|
|
|
skyscraperContext = SkyscraperContextFactory.CreateSkyscraper(JobContext.ScraperEventLogger, JobContext.ScraperStorage);
|
|
skyscraperContext.TcpProxyEnabled = true;
|
|
skyscraperContext.UiJunction = jobDisplay;
|
|
byte[] singlePacketBuffer = new byte[188];
|
|
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);
|
|
}
|
|
}
|
|
skyscraperContext.Dispose();
|
|
|
|
//Stop Filter
|
|
bool stopped = streamReader.DelFilter(filterReference);
|
|
if (!stopped)
|
|
{
|
|
result.State = BlindscanResultState.DelFilterFailed;
|
|
return;
|
|
}
|
|
|
|
DrainPackets();
|
|
if (recordingBufferedStream != null)
|
|
{
|
|
recordingBufferedStream.Flush();
|
|
recordingBufferedStream.Close();
|
|
recordingBufferedStream.Dispose();
|
|
recordingBufferedStream = null;
|
|
recordingFileStream.Close();
|
|
recordingFileStream.Dispose();
|
|
recordingFileStream = null;
|
|
}
|
|
|
|
lock (JobContext.Renderables)
|
|
{
|
|
JobContext.Renderables.Remove(jobDisplay);
|
|
}
|
|
|
|
jobDisplay = null;
|
|
result.State = BlindscanResultState.Done;*/
|
|
}
|
|
}
|
|
|
|
|
|
#endregion
|
|
} |