From 8de4b56c6fd8cd38554d98e674157545a19beda0 Mon Sep 17 00:00:00 2001 From: Fey Date: Mon, 30 Mar 2026 15:20:30 +0200 Subject: [PATCH 1/4] Added a command-line option to tune SAT>IP servers without actually processing the stream. --- skyscraper8/GS/GSE-BFBS/BfbsGseReader.cs | 5 + skyscraper8/Program.cs | 10 + skyscraper8/Properties/launchSettings.json | 1 + skyscraper8/QuickAndDirtySatIpClient.cs | 89 ++- skyscraper8/SatIp/RtspClient.cs | 703 +++++++++--------- .../SatIp/RtspResponses/RtspSetupResponse.cs | 40 +- 6 files changed, 458 insertions(+), 390 deletions(-) diff --git a/skyscraper8/GS/GSE-BFBS/BfbsGseReader.cs b/skyscraper8/GS/GSE-BFBS/BfbsGseReader.cs index d97a751..6c6cb7f 100644 --- a/skyscraper8/GS/GSE-BFBS/BfbsGseReader.cs +++ b/skyscraper8/GS/GSE-BFBS/BfbsGseReader.cs @@ -120,6 +120,11 @@ namespace skyscraper8.GS.GSE_BFBS if (!startIndicator && endIndicator) gseLength -= 4; + if (span.GetAvailableBytes() < gseLength) + { + //broken gse packet, invalid length + return; + } gsePacket.GseDataBytes = span.ReadBytes(gseLength); if (!startIndicator && endIndicator) diff --git a/skyscraper8/Program.cs b/skyscraper8/Program.cs index 5facd7b..9ea9c0a 100644 --- a/skyscraper8/Program.cs +++ b/skyscraper8/Program.cs @@ -288,8 +288,17 @@ namespace skyscraper5 QuickAndDirtySatIpClient qadsipc = new QuickAndDirtySatIpClient(args); qadsipc.Run(); return; + } + + if (args[0].ToLowerInvariant().Equals("satip-playout")) + { + QuickAndDirtySatIpClient qadsipc = new QuickAndDirtySatIpClient(args); + qadsipc.SetPlayoutMode(args); + qadsipc.Run(); + return; } + if (args[0].ToLowerInvariant().Equals("shannon")) { if (args.Length != 2) @@ -392,6 +401,7 @@ namespace skyscraper5 Console.WriteLine(" or: .\\skyscraper8.exe \"C:\\path\\to\\file.ts\\"); Console.WriteLine(" or: .\\skyscraper8.exe \"C:\\path\\to\\my\\folder\\with\\ts\\files\\\" (for batch extraction)"); Console.WriteLine(" or: .\\skyscraper8.exe satip IP_ADDRESS DISEQC POLARITY FREQUENCY SYSTEM SYMBOL_RATE (see README file)"); + Console.WriteLine(" or: .\\skyscraper8.exe satip-playout IP_ADDRESS DISEQC POLARITY FREQUENCY SYSTEM SYMBOL_RATE DESTINATION_PORT"); Console.WriteLine(" or: .\\skyscraper8.exe pcap-on - to write a configuration file that allows PCAP writing during scraping."); Console.WriteLine(" or: .\\skyscraper8.exe pcap-off - to write a configuration file that turns off PCAP writing during scraping."); Console.WriteLine(" or: .\\skyscraper8.exe subts-on - to write a configuration file that allows extraction of nested TS."); diff --git a/skyscraper8/Properties/launchSettings.json b/skyscraper8/Properties/launchSettings.json index 6513d14..e263e51 100644 --- a/skyscraper8/Properties/launchSettings.json +++ b/skyscraper8/Properties/launchSettings.json @@ -2,6 +2,7 @@ "profiles": { "skyscraper8": { "commandName": "Project", + "commandLineArgs": "satip-playout auto 1 V 12597 S2 45000 6970", "remoteDebugEnabled": false }, "Container (Dockerfile)": { diff --git a/skyscraper8/QuickAndDirtySatIpClient.cs b/skyscraper8/QuickAndDirtySatIpClient.cs index 96d549d..046a7ac 100644 --- a/skyscraper8/QuickAndDirtySatIpClient.cs +++ b/skyscraper8/QuickAndDirtySatIpClient.cs @@ -74,6 +74,17 @@ namespace skyscraper8 symbolRate = Int32.Parse(args[6]); } + public void SetPlayoutMode(string[] args) + { + if (args.Length == 7) + { + logger.Fatal("What's the target port?"); + return; + } + destinationPort = int.Parse(args[7]); + playoutMode = true; + } + private IPAddress AutodetectIPAddress() { SsdpDevice firstSatIpServer = SsdpClient.GetFirstSatIpServer(1000, null); @@ -105,7 +116,7 @@ namespace skyscraper8 SessionDescriptionProtocol sessionDescriptionProtocol = describe.GetSessionDescriptionProtocol(); packetQueue = new Queue(); - RtspSetupResponse setup = rtspClient.GetSetup(url); + RtspSetupResponse setup = rtspClient.GetSetup(url, destinationPort); if (setup.RtspStatusCode == 404) { logger.Fatal("Your SAT>IP server doesn't have a tuner available that can talk to the requested frequency."); @@ -118,37 +129,59 @@ namespace skyscraper8 dataStorage = new InMemoryScraperStorage(); if (objectStorage == null) objectStorage = new FilesystemStorage(new DirectoryInfo(".")); - context = new SkyscraperContext(new TsContext(), dataStorage, objectStorage); - context.EnableTimeout = true; - context.TimeoutSeconds = 60; - context.InitalizeFilterChain(); + if (!playoutMode) + { + context = new SkyscraperContext(new TsContext(), dataStorage, objectStorage); + context.EnableTimeout = true; + context.TimeoutSeconds = 60; + context.InitalizeFilterChain(); + } RtspPlayResponse play = rtspClient.GetPlay(setup); DateTime lastTimestamp = DateTime.Now; + bool initMessagePrinted = false; while (true) { - if (packetQueue.Count >= 1) - { - byte[] buffer; - lock (packetQueue) - { - buffer = packetQueue.Dequeue(); - } - context.IngestSinglePacket(buffer); + if (playoutMode) + { + Thread.Sleep(1000); + Keepalive(url); + if (!initMessagePrinted) + { + logger.InfoFormat("Began SAT>IP playout to port {0}", destinationPort); + initMessagePrinted = true; + } } else - { - Thread.Sleep(1); - } - - if (context.IsAbortConditionMet()) - break; - - if (DateTime.Now.Second != lastTimestamp.Second) - { - Keepalive(url); - lastTimestamp = DateTime.Now; + { + if (packetQueue.Count >= 1) + { + byte[] buffer; + lock (packetQueue) + { + buffer = packetQueue.Dequeue(); + } + context.IngestSinglePacket(buffer); + if (!initMessagePrinted) + { + logger.InfoFormat("Began SAT>IP stream."); + initMessagePrinted = true; + } + } + else + { + Thread.Sleep(1); + } + + if (context.IsAbortConditionMet()) + break; + + if (DateTime.Now.Second != lastTimestamp.Second) + { + Keepalive(url); + lastTimestamp = DateTime.Now; + } } } @@ -199,8 +232,12 @@ namespace skyscraper8 fs.Write(buffer, 0, buffer.Length); } - private int rtcps; - private void Setup_OnRtcpPacket(byte[] data, int length) + private int rtcps; + private IPAddress destinationIp; + private int destinationPort; + private bool playoutMode; + + private void Setup_OnRtcpPacket(byte[] data, int length) { //rtcps++; } diff --git a/skyscraper8/SatIp/RtspClient.cs b/skyscraper8/SatIp/RtspClient.cs index cb14525..56335ba 100644 --- a/skyscraper8/SatIp/RtspClient.cs +++ b/skyscraper8/SatIp/RtspClient.cs @@ -1,347 +1,356 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Net.Sockets; -using System.Text; -using System.Threading.Tasks; -using skyscraper5.Skyscraper; -using skyscraper5.Skyscraper.IO.CrazycatStreamReader; -using skyscraper8.SatIp.RtspRequests; -using skyscraper8.SatIp.RtspResponses; - -namespace skyscraper8.SatIp -{ - internal class RtspClient : Validatable, IDisposable - { - private uint cseqCounter; - private const string USER_AGENT = "sophiaNetRtspClient/1.0"; - - public RtspClient(string ip, int port) - { - IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(ip), port); - ConstructStep2(ipEndPoint); - } - - public RtspClient(IPAddress ip, int port) - { - IPEndPoint ipEndPoint = new IPEndPoint(ip, port); - ConstructStep2(ipEndPoint); - } - - private void ConstructStep2(IPEndPoint ipEndPoint) - { - this.TcpClient = new TcpClient(); - this.TcpClient.Connect(ipEndPoint); - this.RootPath = string.Format("rtsp://{0}:{1}", ipEndPoint.Address.ToString(), ipEndPoint.Port.ToString()); - this.NetworkStream = TcpClient.GetStream(); - this.BufferedStream = new BufferedStream(this.NetworkStream); - this.StreamReader = new StreamReader(this.BufferedStream); - this.StreamWriter = new StreamWriter(this.BufferedStream); - this.cseqCounter = 2; - this.ListenIp = GetListenIp(this.TcpClient.Client.LocalEndPoint); - RtspOptionsResponse rtspOptionsResponse = GetOptions("/"); - this.Valid = rtspOptionsResponse.Valid; - } - - public bool AutoReconnect { get; set; } - public IPAddress ListenIp { get; set; } - - private IPAddress GetListenIp(EndPoint clientLocalEndPoint) - { - IPEndPoint ipEndPoint = clientLocalEndPoint as IPEndPoint; - if (ipEndPoint == null) - { - throw new NotImplementedException(clientLocalEndPoint.GetType().Name); - } - - if (ipEndPoint.Address.AddressFamily == AddressFamily.InterNetwork) - { - return ipEndPoint.Address; - } - - if (ipEndPoint.Address.IsIPv4MappedToIPv6) - { - return ipEndPoint.Address.MapToIPv4(); - } - - throw new NotImplementedException(String.Format("Don't know whether I can listen on IP {0}", ipEndPoint.ToString())); - } - - public string RootPath { get; set; } - - private TcpClient TcpClient { get; set; } - private NetworkStream NetworkStream { get; set; } - private BufferedStream BufferedStream { get; set; } - private StreamReader StreamReader { get; set; } - private StreamWriter StreamWriter { get; set; } - - public RtspOptionsResponse GetOptions(string url) - { - RtspOptionsRequest request = new RtspOptionsRequest(); - request.RequestPath = url; - request.CSeq = cseqCounter++; - request.UserAgent = USER_AGENT; - RtspResponseHeader header = GetResponse(request.ListHeaders(RootPath)); - RtspOptionsResponse result = new RtspOptionsResponse(header); - return result; - } - - public RtspDescribeResponse GetDescribe(string url) - { - RtspDescribeRequest request = new RtspDescribeRequest(); - request.RequestPath = url; - request.CSeq = cseqCounter++; - request.UserAgent = USER_AGENT; - request.Accept = "application/sdp"; - RtspResponseHeader header = GetResponse(request.ListHeaders(RootPath)); - RtspDescribeResponse result = new RtspDescribeResponse(header); - return result; - } - - public RtspSetupResponse GetSetup(string url) - { - RtspSetupRequest request = new RtspSetupRequest(); - request.RequestPath = url; - request.CSeq = cseqCounter++; - request.UserAgent = USER_AGENT; - - Socket rtpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - rtpSocket.Bind(new IPEndPoint(ListenIp, 0)); - int rtpPort = GetPortFromEndPoint(rtpSocket.LocalEndPoint); - - Socket rtcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - rtcpSocket.Bind(new IPEndPoint(ListenIp, 0)); - int rtcpPort = GetPortFromEndPoint(rtcpSocket.LocalEndPoint); - - request.SetRtpAvpUnicast(rtpPort, rtcpPort); - - RtspResponseHeader response = GetResponse(request.ListHeaders(RootPath)); - RtspSetupResponse setupResponse = new RtspSetupResponse(response); - switch (response.statusCode) - { - case 200: - setupResponse.RtpSocket = rtpSocket; - setupResponse.RtcpSocket = rtcpSocket; - setupResponse.SetupListeners(); - setupResponse.Valid = true; - break; - case 404: - setupResponse.Valid = true; - break; - default: - throw new NotImplementedException(setupResponse.RtspStatusCode.ToString()); - } - return setupResponse; - } - - public RtspPlayResponse GetPlay(RtspSetupResponse setupData) - { - RtspPlayRequest request = new RtspPlayRequest(); - request.RequestPath = string.Format("/stream={0}", setupData.StreamId); - request.Session = setupData.Session; - request.UserAgent = USER_AGENT; - - RtspPlayResponse response = new RtspPlayResponse(GetResponse(request.ListHeaders(RootPath))); - return response; - } - - public RtspTeardownResponse GetTeardown(RtspSetupResponse setupData) - { - RtspTeardownRequest request = new RtspTeardownRequest(); - request.RequestPath = string.Format("/stream={0}", setupData.StreamId); - request.Session = setupData.Session; - request.UserAgent = USER_AGENT; - - RtspTeardownResponse response = new RtspTeardownResponse(GetResponse(request.ListHeaders(RootPath))); - if (response.RtspStatusCode == 200) - { - setupData.InvokeCancellationTokens(); - if (AutoReconnect) - { - Reconnect(); - } - } - return response; - } - - private int GetPortFromEndPoint(EndPoint endpoint) - { - IPEndPoint ipEndPoint = endpoint as IPEndPoint; - if (ipEndPoint == null) - throw new NotImplementedException(endpoint.GetType().Name); - return ipEndPoint.Port; - } - - private RtspResponseHeader GetResponse(string request) - { - StreamWriter.Write(request); - StreamWriter.Flush(); - - RtspResponseHeader result = new RtspResponseHeader(); - - string response = StreamReader.ReadLine(); - if (!response.StartsWith("RTSP/")) - throw new RtspException("Invalid RTSP response."); - - response = response.Substring(5); - - string versionString = response.Substring(0, 3); - result.rtspVersion = Version.Parse(versionString); - response = response.Substring(4); - - string statusCodeString = response.Substring(0,3); - result.statusCode = ushort.Parse(statusCodeString); - - response = response.Substring(4); - result.statusLine = response; - - long contentLength = 0; - - result.kv = new Dictionary(); - while (true) - { - string lineIn = StreamReader.ReadLine(); - if (string.IsNullOrEmpty(lineIn)) - break; - - int indexOf = lineIn.IndexOf(": "); - string key = lineIn.Substring(0, indexOf); - string value = lineIn.Substring(indexOf + 2); - result.kv.Add(key, value); - - if (key.Equals("Content-Length")) - { - contentLength = long.Parse(value); - } - } - - if (contentLength > 0) - { - StreamReader.DiscardBufferedData(); - byte[] buffer = new byte[contentLength]; - int sucessfullyRead = BufferedStream.Read(buffer, 0, (int)contentLength); - if (sucessfullyRead != contentLength) - { - throw new IOException("incomplete read"); - } - - result.payload = buffer; - } - - return result; - } - - public void Reconnect() - { - EndPoint clientRemoteEndPoint = this.TcpClient.Client.RemoteEndPoint; - IPEndPoint ipEndPoint = clientRemoteEndPoint as IPEndPoint; - if (ipEndPoint == null) - { - throw new NotImplementedException(clientRemoteEndPoint.GetType().ToString()); - } - - this.TcpClient.Close(); - this.TcpClient = new TcpClient(); - this.TcpClient.Connect(ipEndPoint); - this.RootPath = string.Format("rtsp://{0}:{1}", ipEndPoint.Address, ipEndPoint.Port); - this.NetworkStream = TcpClient.GetStream(); - this.BufferedStream = new BufferedStream(this.NetworkStream); - this.StreamReader = new StreamReader(this.BufferedStream); - this.StreamWriter = new StreamWriter(this.BufferedStream); - this.cseqCounter = 2; - this.ListenIp = GetListenIp(this.TcpClient.Client.LocalEndPoint); - } - - /// - /// Generates a SAT>IP Tuning string. - /// - /// The DiSEqC Command to send. - /// The frequency to tune to in MHz. - /// Set this to true if tuning to DVB-S2/S2X, or false for DVB-S - /// The transponder's symbol rate in Ksyms. - /// Set this to true to force a STiD135 to BBFrame mode. Set this to false if you do not want this, or if the tuner isn't a STiD135. false is always safe here. - /// A SAT>IP Tuning String - /// Thrown when an invalid DiSEqC Command is supplied. - public static string MakeUrl(DiSEqC_Opcode diseqcChannel, int freq, bool isS2, int symbolrate, byte? mis = null, bool forceBbframeMode = false) - { - bool diseqcOk = false; - byte diseqc = 1; - if (diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_OPTION_A) && diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_POSITION_A)) - { - diseqc = 1; - diseqcOk = true; - } - if (diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_OPTION_A) && diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_POSITION_B)) - { - diseqc = 2; - diseqcOk = true; - } - if (diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_OPTION_B) && diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_POSITION_A)) - { - diseqc = 3; - diseqcOk = true; - } - if (diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_OPTION_B) && diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_POSITION_B)) - { - diseqc = 4; - diseqcOk = true; - } - if (!diseqcOk) - { - throw new ArgumentOutOfRangeException(nameof(diseqcChannel)); - } - - char pol; - if (diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_HORIZONTAL)) - { - pol = 'h'; - } - else - { - pol = 'v'; - } - - StringBuilder sb = new StringBuilder(); - sb.AppendFormat("/?src={0}", diseqc); - sb.AppendFormat("&freq={0}", freq); - sb.AppendFormat("&pol={0}", pol); - sb.AppendFormat("&msys={0}", isS2 ? "dvbs2" : "dvbs"); - sb.AppendFormat("&sr={0}", symbolrate); - sb.AppendFormat("&pids=all"); - - //Thanks to the Digital Devices Customer Support for giving me this advice. - if (forceBbframeMode) - { - sb.Append("&x_isi=0x80000000"); - } - else if (mis.HasValue) - { - sb.AppendFormat("&x_isi={0}", mis.Value); - } - - return sb.ToString(); - } - - private bool disposed; - public void Dispose() - { - if (disposed) - throw new ObjectDisposedException(nameof(RtspClient)); - - ListenIp = null; - RootPath = null; - if (TcpClient.Connected) - { - TcpClient.Close(); - } - - TcpClient.Dispose(); - NetworkStream = null; - BufferedStream = null; - StreamReader = null; - StreamWriter = null; - disposed = true; - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using skyscraper5.Skyscraper; +using skyscraper5.Skyscraper.IO.CrazycatStreamReader; +using skyscraper8.SatIp.RtspRequests; +using skyscraper8.SatIp.RtspResponses; + +namespace skyscraper8.SatIp +{ + internal class RtspClient : Validatable, IDisposable + { + private uint cseqCounter; + private const string USER_AGENT = "sophiaNetRtspClient/1.0"; + + public RtspClient(string ip, int port) + { + IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(ip), port); + ConstructStep2(ipEndPoint); + } + + public RtspClient(IPAddress ip, int port) + { + IPEndPoint ipEndPoint = new IPEndPoint(ip, port); + ConstructStep2(ipEndPoint); + } + + private void ConstructStep2(IPEndPoint ipEndPoint) + { + this.TcpClient = new TcpClient(); + this.TcpClient.Connect(ipEndPoint); + this.RootPath = string.Format("rtsp://{0}:{1}", ipEndPoint.Address.ToString(), ipEndPoint.Port.ToString()); + this.NetworkStream = TcpClient.GetStream(); + this.BufferedStream = new BufferedStream(this.NetworkStream); + this.StreamReader = new StreamReader(this.BufferedStream); + this.StreamWriter = new StreamWriter(this.BufferedStream); + this.cseqCounter = 2; + this.ListenIp = GetListenIp(this.TcpClient.Client.LocalEndPoint); + RtspOptionsResponse rtspOptionsResponse = GetOptions("/"); + this.Valid = rtspOptionsResponse.Valid; + } + + public bool AutoReconnect { get; set; } + public IPAddress ListenIp { get; set; } + + private IPAddress GetListenIp(EndPoint clientLocalEndPoint) + { + IPEndPoint ipEndPoint = clientLocalEndPoint as IPEndPoint; + if (ipEndPoint == null) + { + throw new NotImplementedException(clientLocalEndPoint.GetType().Name); + } + + if (ipEndPoint.Address.AddressFamily == AddressFamily.InterNetwork) + { + return ipEndPoint.Address; + } + + if (ipEndPoint.Address.IsIPv4MappedToIPv6) + { + return ipEndPoint.Address.MapToIPv4(); + } + + throw new NotImplementedException(String.Format("Don't know whether I can listen on IP {0}", ipEndPoint.ToString())); + } + + public string RootPath { get; set; } + + private TcpClient TcpClient { get; set; } + private NetworkStream NetworkStream { get; set; } + private BufferedStream BufferedStream { get; set; } + private StreamReader StreamReader { get; set; } + private StreamWriter StreamWriter { get; set; } + + public RtspOptionsResponse GetOptions(string url) + { + RtspOptionsRequest request = new RtspOptionsRequest(); + request.RequestPath = url; + request.CSeq = cseqCounter++; + request.UserAgent = USER_AGENT; + RtspResponseHeader header = GetResponse(request.ListHeaders(RootPath)); + RtspOptionsResponse result = new RtspOptionsResponse(header); + return result; + } + + public RtspDescribeResponse GetDescribe(string url) + { + RtspDescribeRequest request = new RtspDescribeRequest(); + request.RequestPath = url; + request.CSeq = cseqCounter++; + request.UserAgent = USER_AGENT; + request.Accept = "application/sdp"; + RtspResponseHeader header = GetResponse(request.ListHeaders(RootPath)); + RtspDescribeResponse result = new RtspDescribeResponse(header); + return result; + } + + public RtspSetupResponse GetSetup(string url, int destinationPort = 0) + { + RtspSetupRequest request = new RtspSetupRequest(); + request.RequestPath = url; + request.CSeq = cseqCounter++; + request.UserAgent = USER_AGENT; + + int rtpPort = 0; + Socket rtpSocket = null; + if (destinationPort == 0) + { + rtpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + rtpSocket.Bind(new IPEndPoint(ListenIp, 0)); + rtpPort = GetPortFromEndPoint(rtpSocket.LocalEndPoint); + } + else + { + rtpPort = destinationPort; + } + + Socket rtcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + rtcpSocket.Bind(new IPEndPoint(ListenIp, 0)); + int rtcpPort = GetPortFromEndPoint(rtcpSocket.LocalEndPoint); + + request.SetRtpAvpUnicast(rtpPort, rtcpPort); + + RtspResponseHeader response = GetResponse(request.ListHeaders(RootPath)); + RtspSetupResponse setupResponse = new RtspSetupResponse(response); + switch (response.statusCode) + { + case 200: + setupResponse.RtpSocket = rtpSocket; + setupResponse.RtcpSocket = rtcpSocket; + setupResponse.SetupListeners(); + setupResponse.Valid = true; + break; + case 404: + setupResponse.Valid = true; + break; + default: + throw new NotImplementedException(setupResponse.RtspStatusCode.ToString()); + } + return setupResponse; + } + + public RtspPlayResponse GetPlay(RtspSetupResponse setupData) + { + RtspPlayRequest request = new RtspPlayRequest(); + request.RequestPath = string.Format("/stream={0}", setupData.StreamId); + request.Session = setupData.Session; + request.UserAgent = USER_AGENT; + + RtspPlayResponse response = new RtspPlayResponse(GetResponse(request.ListHeaders(RootPath))); + return response; + } + + public RtspTeardownResponse GetTeardown(RtspSetupResponse setupData) + { + RtspTeardownRequest request = new RtspTeardownRequest(); + request.RequestPath = string.Format("/stream={0}", setupData.StreamId); + request.Session = setupData.Session; + request.UserAgent = USER_AGENT; + + RtspTeardownResponse response = new RtspTeardownResponse(GetResponse(request.ListHeaders(RootPath))); + if (response.RtspStatusCode == 200) + { + setupData.InvokeCancellationTokens(); + if (AutoReconnect) + { + Reconnect(); + } + } + return response; + } + + private int GetPortFromEndPoint(EndPoint endpoint) + { + IPEndPoint ipEndPoint = endpoint as IPEndPoint; + if (ipEndPoint == null) + throw new NotImplementedException(endpoint.GetType().Name); + return ipEndPoint.Port; + } + + private RtspResponseHeader GetResponse(string request) + { + StreamWriter.Write(request); + StreamWriter.Flush(); + + RtspResponseHeader result = new RtspResponseHeader(); + + string response = StreamReader.ReadLine(); + if (!response.StartsWith("RTSP/")) + throw new RtspException("Invalid RTSP response."); + + response = response.Substring(5); + + string versionString = response.Substring(0, 3); + result.rtspVersion = Version.Parse(versionString); + response = response.Substring(4); + + string statusCodeString = response.Substring(0,3); + result.statusCode = ushort.Parse(statusCodeString); + + response = response.Substring(4); + result.statusLine = response; + + long contentLength = 0; + + result.kv = new Dictionary(); + while (true) + { + string lineIn = StreamReader.ReadLine(); + if (string.IsNullOrEmpty(lineIn)) + break; + + int indexOf = lineIn.IndexOf(": "); + string key = lineIn.Substring(0, indexOf); + string value = lineIn.Substring(indexOf + 2); + result.kv.Add(key, value); + + if (key.Equals("Content-Length")) + { + contentLength = long.Parse(value); + } + } + + if (contentLength > 0) + { + StreamReader.DiscardBufferedData(); + byte[] buffer = new byte[contentLength]; + int sucessfullyRead = BufferedStream.Read(buffer, 0, (int)contentLength); + if (sucessfullyRead != contentLength) + { + throw new IOException("incomplete read"); + } + + result.payload = buffer; + } + + return result; + } + + public void Reconnect() + { + EndPoint clientRemoteEndPoint = this.TcpClient.Client.RemoteEndPoint; + IPEndPoint ipEndPoint = clientRemoteEndPoint as IPEndPoint; + if (ipEndPoint == null) + { + throw new NotImplementedException(clientRemoteEndPoint.GetType().ToString()); + } + + this.TcpClient.Close(); + this.TcpClient = new TcpClient(); + this.TcpClient.Connect(ipEndPoint); + this.RootPath = string.Format("rtsp://{0}:{1}", ipEndPoint.Address, ipEndPoint.Port); + this.NetworkStream = TcpClient.GetStream(); + this.BufferedStream = new BufferedStream(this.NetworkStream); + this.StreamReader = new StreamReader(this.BufferedStream); + this.StreamWriter = new StreamWriter(this.BufferedStream); + this.cseqCounter = 2; + this.ListenIp = GetListenIp(this.TcpClient.Client.LocalEndPoint); + } + + /// + /// Generates a SAT>IP Tuning string. + /// + /// The DiSEqC Command to send. + /// The frequency to tune to in MHz. + /// Set this to true if tuning to DVB-S2/S2X, or false for DVB-S + /// The transponder's symbol rate in Ksyms. + /// Set this to true to force a STiD135 to BBFrame mode. Set this to false if you do not want this, or if the tuner isn't a STiD135. false is always safe here. + /// A SAT>IP Tuning String + /// Thrown when an invalid DiSEqC Command is supplied. + public static string MakeUrl(DiSEqC_Opcode diseqcChannel, int freq, bool isS2, int symbolrate, byte? mis = null, bool forceBbframeMode = false) + { + bool diseqcOk = false; + byte diseqc = 1; + if (diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_OPTION_A) && diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_POSITION_A)) + { + diseqc = 1; + diseqcOk = true; + } + if (diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_OPTION_A) && diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_POSITION_B)) + { + diseqc = 2; + diseqcOk = true; + } + if (diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_OPTION_B) && diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_POSITION_A)) + { + diseqc = 3; + diseqcOk = true; + } + if (diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_OPTION_B) && diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_POSITION_B)) + { + diseqc = 4; + diseqcOk = true; + } + if (!diseqcOk) + { + throw new ArgumentOutOfRangeException(nameof(diseqcChannel)); + } + + char pol; + if (diseqcChannel.HasFlag(DiSEqC_Opcode.DISEQC_HORIZONTAL)) + { + pol = 'h'; + } + else + { + pol = 'v'; + } + + StringBuilder sb = new StringBuilder(); + sb.AppendFormat("/?src={0}", diseqc); + sb.AppendFormat("&freq={0}", freq); + sb.AppendFormat("&pol={0}", pol); + sb.AppendFormat("&msys={0}", isS2 ? "dvbs2" : "dvbs"); + sb.AppendFormat("&sr={0}", symbolrate); + sb.AppendFormat("&pids=all"); + + //Thanks to the Digital Devices Customer Support for giving me this advice. + if (forceBbframeMode) + { + sb.Append("&x_isi=0x80000000"); + } + else if (mis.HasValue) + { + sb.AppendFormat("&x_isi={0}", mis.Value); + } + + return sb.ToString(); + } + + private bool disposed; + public void Dispose() + { + if (disposed) + throw new ObjectDisposedException(nameof(RtspClient)); + + ListenIp = null; + RootPath = null; + if (TcpClient.Connected) + { + TcpClient.Close(); + } + + TcpClient.Dispose(); + NetworkStream = null; + BufferedStream = null; + StreamReader = null; + StreamWriter = null; + disposed = true; + } + } +} diff --git a/skyscraper8/SatIp/RtspResponses/RtspSetupResponse.cs b/skyscraper8/SatIp/RtspResponses/RtspSetupResponse.cs index ebe5553..c364c12 100644 --- a/skyscraper8/SatIp/RtspResponses/RtspSetupResponse.cs +++ b/skyscraper8/SatIp/RtspResponses/RtspSetupResponse.cs @@ -53,23 +53,29 @@ namespace skyscraper8.SatIp.RtspResponses if (listenersStarted) throw new RtspException("Listener already started."); - rtpCancellation = new CancellationTokenSource(); + if (RtpSocket != null) + { + rtpCancellation = new CancellationTokenSource(); + } rtcpCancellation = new CancellationTokenSource(); - Task.Run(async () => - { - byte[] buffer = new byte[2048]; - - while (!rtpCancellation.IsCancellationRequested) - { - Array.Clear(buffer); - int result = await RtpSocket.ReceiveAsync(buffer, rtpCancellation.Token); - OnRtpPacket?.Invoke(buffer, result); - } - - exitedThread++; - } - ); + if (RtpSocket != null) + { + Task.Run(async () => + { + byte[] buffer = new byte[2048]; + + while (!rtpCancellation.IsCancellationRequested) + { + Array.Clear(buffer); + int result = await RtpSocket.ReceiveAsync(buffer, rtpCancellation.Token); + OnRtpPacket?.Invoke(buffer, result); + } + + exitedThread++; + } + ); + } Task.Run(async () => { @@ -92,8 +98,8 @@ namespace skyscraper8.SatIp.RtspResponses internal void InvokeCancellationTokens() { - rtpCancellation.Cancel(); - rtcpCancellation.Cancel(); + rtpCancellation?.Cancel(); + rtcpCancellation?.Cancel(); } public event OnRtpPacket OnRtpPacket; From 03f194bd34aef4f47852fe39204a8fa88a784685 Mon Sep 17 00:00:00 2001 From: Fey Date: Mon, 6 Apr 2026 16:42:27 +0200 Subject: [PATCH 2/4] Added options for SAT>IP Multicast Playout and building a date-ordered TS list to CSV. --- skyscraper8/Program.cs | 1912 +++++++++-------- skyscraper8/Properties/launchSettings.json | 2 +- skyscraper8/QuickAndDirtySatIpClient.cs | 532 ++--- skyscraper8/SatIp/RtspClient.cs | 11 +- .../SatIp/RtspRequests/RtspSetupRequest.cs | 120 +- .../RemoteStreamReaderTunerFactory.cs | 2 +- skyscraper8/Skyscraper/TsRotationToCsv.cs | 112 + 7 files changed, 1419 insertions(+), 1272 deletions(-) create mode 100644 skyscraper8/Skyscraper/TsRotationToCsv.cs diff --git a/skyscraper8/Program.cs b/skyscraper8/Program.cs index 9ea9c0a..2fed178 100644 --- a/skyscraper8/Program.cs +++ b/skyscraper8/Program.cs @@ -1,958 +1,966 @@ -using log4net; -using skyscraper5.Abertis; -using skyscraper5.Hdmv; -using skyscraper5.Mpeg2; -using skyscraper5.Scorcher; -using skyscraper5.Skyscraper; -using skyscraper5.Skyscraper.Gps; -using skyscraper5.Skyscraper.IO; -using skyscraper5.Skyscraper.IO.CrazycatStreamReader; -using skyscraper5.Skyscraper.IO.TunerInterface; -using skyscraper5.Skyscraper.Plugins; -using skyscraper5.Skyscraper.RecordingImporter; -using skyscraper5.Skyscraper.Scraper; -using skyscraper5.Skyscraper.Scraper.Storage.Filesystem; -using skyscraper5.Skyscraper.Scraper.Storage.InMemory; -using skyscraper5.Skyscraper.Webserver; -using skyscraper5.src.Aac; -using skyscraper5.src.Mpeg2.PacketFilter; -using skyscraper5.T2MI; -using skyscraper8.Skyscraper.IO; -using skyscraper8.Skyscraper.Scraper.Storage; -using System.Diagnostics; -using System.Net; -using System.Net.NetworkInformation; -using System.Net.Sockets; -using System.Runtime.InteropServices; -using skyscraper5.Dvb.DataBroadcasting; -using skyscraper8; -using skyscraper8.GSE; -using skyscraper8.Skyscraper.Math; -using skyscraper8.Skyscraper; -using skyscraper8.Skyscraper.Security.AccessControl; - -[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config")] -namespace skyscraper5 -{ - class Program - { - private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); - - private static void IntegrationTest() - { - //SoftcamTestProgram softcamTestProgram = new SoftcamTestProgram(); - //softcamTestProgram.Run(); - - /*List ssdpDevices = SsdpClient.GetSsdpDevices(1000).ToList(); - foreach (SsdpDevice ssdpDevice in ssdpDevices) - { - Console.WriteLine("SSDP device: {0}", ssdpDevice.Server); - }*/ - - //"urn:ses-com:device:SatIPServer:1" - /*PluginManager pluginManager = PluginManager.GetInstance(); - StorageConnectionManager storageConnectionManager = StorageConnectionManager.GetInstance(); - ObjectStorageFactory objectStorageFactory = storageConnectionManager.GetDefaultObjectStorageFactory(); - ObjectStorage objectStorage = objectStorageFactory.CreateObjectStorage();*/ - - /*url = RtspClient.MakeUrl(DiSEqC_Opcode.DISEQC_OPTION_A | DiSEqC_Opcode.DISEQC_POSITION_A | DiSEqC_Opcode.DISEQC_HORIZONTAL, 11141, true, 23500); - 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) - { - IntegrationTest(); - - logger.InfoFormat(String.Format("Hello! This is skyscraper8, public release #{0}, code version {1}", VersionInfo.GetPublicReleaseNumber(), VersionInfo.GetCurrentAssemblyDisplayVersion())); - - logger.DebugFormat("Found {0}-bit Operating system.", Environment.Is64BitOperatingSystem ? 64 : 32); - logger.DebugFormat("I'm a {0}-bit Process.", Environment.Is64BitProcess ? 64 : 32); - - PluginManager.GetInstance(); - SoftcamKeyset.GetInstance().AutoInitalize(); - - if (args.Length != 0) - { - if (args[0].ToLowerInvariant().EndsWith(".ts")) - { - FileInfo fi = new FileInfo(args[0]); - if (fi.Exists) - HandleSingleFile(fi); - else - Console.WriteLine("{0} missing.", fi.FullName); - return; - } - - if (args[0].ToLowerInvariant().EndsWith(".m3u8")) - { - M3U8Stream m3U8Stream = new M3U8Stream(args[0]); - SkyscraperContext skyscraperContext = new SkyscraperContext(new TsContext()); - skyscraperContext.InitalizeFilterChain(); - skyscraperContext.IngestFromStream(m3U8Stream); - return; - } - - if (args[0].ToLowerInvariant().Equals("bumutest")) - { - FileInfo fi = new FileInfo(args[1]); - FileStream fstream = fi.OpenRead(); - - TsContext mpeg2 = new TsContext(); - SkyscraperContext skyscraper = new SkyscraperContext(mpeg2, new InMemoryScraperStorage(), new NullObjectStorage()); - skyscraper.InitalizeFilterChain(); - - MultiprotocolEncapsulationDecoder mpeDecoder = new MultiprotocolEncapsulationDecoder(skyscraper); - PsiDecoder psiDecoder = new PsiDecoder(0x1019, mpeDecoder); - mpeg2.RegisterPacketProcessor(0x1019, psiDecoder); - - skyscraper.IngestFromStream(fstream); - } - if (args[0].Equals("aactest")) - { - new AacTestProgram().Run(); - return; - } - if (args[0].ToLowerInvariant().Equals("cscan")) - { - HandleCrazyScanToTestingSystem(args[1]); - return; - } - if (args[0].ToLowerInvariant().Equals("cscan-live")) - { - HandleCrazyScanToLiveSystem(args[1]); - return; - } - if (args[0].ToLowerInvariant().Equals("cscan-live-notimeout")) - { - HandleCrazyScanToLiveSystem(args[1], false); - return; - } - - if (args[0].ToLowerInvariant().Equals("udpin")) - { - HandleUdpTesting(); - return; - } - if (args[0].ToLowerInvariant().Equals("udp-agent")) - { - HandleUdpLive(); - return; - } - - if (args[0].Equals("abertest")) - { - FileInfo fi = new FileInfo(args[1]); - if (!fi.Exists) - { - Console.WriteLine("{0} not found", fi.FullName); - return; - } - AbertisDemoProgram abertisDemo = new AbertisDemoProgram(fi); - abertisDemo.Run(); - return; - } - - if (args[0].ToLowerInvariant().Equals("t2mitest")) - { - new TestApp(args[1]).Run(); - return; - } - - if (args[0].ToLowerInvariant().Equals("ioctltest")) - { - IoctlTest(); - return; - } - - if (args[0].ToLowerInvariant().Equals("m2tstots")) - { - FileInfo infile = new FileInfo(args[1]); - FileInfo outfile = new FileInfo(args[2]); - new M2TsToTs(infile,outfile).Run(); - return; - } - - if (Directory.Exists(args[0])) - { - DirectoryInfo doThisDir = new DirectoryInfo(args[0]); - ProcessDirectory(doThisDir); - return; - } - - if (args[0].ToLowerInvariant().Equals("proxytest")) - { - TcpTsProxy tcpTsProxy = new TcpTsProxy(); - Thread.Sleep(5000); - tcpTsProxy.Dispose(); - return; - } - - if (args[0].ToLowerInvariant().Equals("importtest")) - { - DirectoryInfo doThisDir = new DirectoryInfo(args[1]); - InMemoryScraperStorage imss = new InMemoryScraperStorage(); - FilesystemStorage fs = new FilesystemStorage(new DirectoryInfo(".")); - TsFileCollectionImporter importer = new TsFileCollectionImporter(imss, fs, doThisDir); - importer.Run(); - return; - } - - - //fsimport "D:\Skyscraper" "E:\\" - if (args[0].ToLowerInvariant().Equals("fsimport")) - { - DirectoryInfo srcDir = new DirectoryInfo(args[1]); - DirectoryInfo tgtDir = new DirectoryInfo(args[2]); - FilesystemStorage fss = new FilesystemStorage(tgtDir); - TsFileCollectionImporter importer = new TsFileCollectionImporter(fss, fss, srcDir); - importer.Run(); - return; - } - - if (args[0].ToLowerInvariant().Equals("webservertest")) - { - SkyscraperWebserver webserverTest = SkyscraperWebserver.GetInstance(); - webserverTest.Start(); - while (webserverTest.IsListening) - { - Thread.Sleep(1000); - } - - return; - } - - if (args[0].ToLowerInvariant().Equals("gpstest")) - { - GpsManager.GpsTest(); - return; - } - - if (args[0].ToLowerInvariant().Equals("what-can-i-receive")) - { - WhatCanIReceive.StandaloneProgram(); - return; - } - - if (args[0].ToLowerInvariant().Equals("make-dummy-ts")) - { - DummyTsGenerator dummyTsGenerator = new DummyTsGenerator(); - dummyTsGenerator.Run(); - return; - } - - if (args[0].ToLowerInvariant().Equals("file-live")) - { - Program.HandleFileToLiveSystem(args[1]); - return; - } - - if (args[0].ToLowerInvariant().Equals("hlsproxy")) - { - DirectoryInfo di = new DirectoryInfo(args[1]); - HlsProxy hlsproxy = new HlsProxy(di); - hlsproxy.Run(); - return; - } - - if (args[0].ToLowerInvariant().Equals("hlsproxy-destructive")) - { - DirectoryInfo di = new DirectoryInfo(args[1]); - HlsProxy hlsproxy = new HlsProxy(di); - hlsproxy.DestructiveMode = true; - hlsproxy.Run(); - return; - } - - if (args[0].ToLowerInvariant().Equals("satip")) - { - QuickAndDirtySatIpClient qadsipc = new QuickAndDirtySatIpClient(args); - qadsipc.Run(); - return; +using log4net; +using skyscraper5.Abertis; +using skyscraper5.Hdmv; +using skyscraper5.Mpeg2; +using skyscraper5.Scorcher; +using skyscraper5.Skyscraper; +using skyscraper5.Skyscraper.Gps; +using skyscraper5.Skyscraper.IO; +using skyscraper5.Skyscraper.IO.CrazycatStreamReader; +using skyscraper5.Skyscraper.IO.TunerInterface; +using skyscraper5.Skyscraper.Plugins; +using skyscraper5.Skyscraper.RecordingImporter; +using skyscraper5.Skyscraper.Scraper; +using skyscraper5.Skyscraper.Scraper.Storage.Filesystem; +using skyscraper5.Skyscraper.Scraper.Storage.InMemory; +using skyscraper5.Skyscraper.Webserver; +using skyscraper5.src.Aac; +using skyscraper5.src.Mpeg2.PacketFilter; +using skyscraper5.T2MI; +using skyscraper8.Skyscraper.IO; +using skyscraper8.Skyscraper.Scraper.Storage; +using System.Diagnostics; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Runtime.InteropServices; +using skyscraper5.Dvb.DataBroadcasting; +using skyscraper8; +using skyscraper8.GSE; +using skyscraper8.Skyscraper.Math; +using skyscraper8.Skyscraper; +using skyscraper8.Skyscraper.Security.AccessControl; + +[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config")] +namespace skyscraper5 +{ + class Program + { + private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); + + private static void IntegrationTest() + { + //SoftcamTestProgram softcamTestProgram = new SoftcamTestProgram(); + //softcamTestProgram.Run(); + + /*List ssdpDevices = SsdpClient.GetSsdpDevices(1000).ToList(); + foreach (SsdpDevice ssdpDevice in ssdpDevices) + { + Console.WriteLine("SSDP device: {0}", ssdpDevice.Server); + }*/ + + //"urn:ses-com:device:SatIPServer:1" + /*PluginManager pluginManager = PluginManager.GetInstance(); + StorageConnectionManager storageConnectionManager = StorageConnectionManager.GetInstance(); + ObjectStorageFactory objectStorageFactory = storageConnectionManager.GetDefaultObjectStorageFactory(); + ObjectStorage objectStorage = objectStorageFactory.CreateObjectStorage();*/ + + /*url = RtspClient.MakeUrl(DiSEqC_Opcode.DISEQC_OPTION_A | DiSEqC_Opcode.DISEQC_POSITION_A | DiSEqC_Opcode.DISEQC_HORIZONTAL, 11141, true, 23500); + 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) + { + IntegrationTest(); + + logger.InfoFormat(String.Format("Hello! This is skyscraper8, public release #{0}, code version {1}", VersionInfo.GetPublicReleaseNumber(), VersionInfo.GetCurrentAssemblyDisplayVersion())); + + logger.DebugFormat("Found {0}-bit Operating system.", Environment.Is64BitOperatingSystem ? 64 : 32); + logger.DebugFormat("I'm a {0}-bit Process.", Environment.Is64BitProcess ? 64 : 32); + + PluginManager.GetInstance(); + //SoftcamKeyset.GetInstance().AutoInitalize(); + + if (args.Length != 0) + { + if (args[0].ToLowerInvariant().EndsWith(".ts")) + { + FileInfo fi = new FileInfo(args[0]); + if (fi.Exists) + HandleSingleFile(fi); + else + Console.WriteLine("{0} missing.", fi.FullName); + return; } - if (args[0].ToLowerInvariant().Equals("satip-playout")) + if (args[0].ToLowerInvariant().EndsWith(".m3u8")) + { + M3U8Stream m3U8Stream = new M3U8Stream(args[0]); + SkyscraperContext skyscraperContext = new SkyscraperContext(new TsContext()); + skyscraperContext.InitalizeFilterChain(); + skyscraperContext.IngestFromStream(m3U8Stream); + return; + } + + if (args[0].ToLowerInvariant().Equals("bumutest")) + { + FileInfo fi = new FileInfo(args[1]); + FileStream fstream = fi.OpenRead(); + + TsContext mpeg2 = new TsContext(); + SkyscraperContext skyscraper = new SkyscraperContext(mpeg2, new InMemoryScraperStorage(), new NullObjectStorage()); + skyscraper.InitalizeFilterChain(); + + MultiprotocolEncapsulationDecoder mpeDecoder = new MultiprotocolEncapsulationDecoder(skyscraper); + PsiDecoder psiDecoder = new PsiDecoder(0x1019, mpeDecoder); + mpeg2.RegisterPacketProcessor(0x1019, psiDecoder); + + skyscraper.IngestFromStream(fstream); + } + if (args[0].Equals("aactest")) + { + new AacTestProgram().Run(); + return; + } + if (args[0].ToLowerInvariant().Equals("cscan")) + { + HandleCrazyScanToTestingSystem(args[1]); + return; + } + if (args[0].ToLowerInvariant().Equals("cscan-live")) + { + HandleCrazyScanToLiveSystem(args[1]); + return; + } + if (args[0].ToLowerInvariant().Equals("cscan-live-notimeout")) + { + HandleCrazyScanToLiveSystem(args[1], false); + return; + } + + if (args[0].ToLowerInvariant().Equals("udpin")) + { + HandleUdpTesting(); + return; + } + if (args[0].ToLowerInvariant().Equals("udp-agent")) + { + HandleUdpLive(); + return; + } + + if (args[0].Equals("abertest")) + { + FileInfo fi = new FileInfo(args[1]); + if (!fi.Exists) + { + Console.WriteLine("{0} not found", fi.FullName); + return; + } + AbertisDemoProgram abertisDemo = new AbertisDemoProgram(fi); + abertisDemo.Run(); + return; + } + + if (args[0].ToLowerInvariant().Equals("t2mitest")) + { + new TestApp(args[1]).Run(); + return; + } + + if (args[0].ToLowerInvariant().Equals("ioctltest")) + { + IoctlTest(); + return; + } + + if (args[0].ToLowerInvariant().Equals("m2tstots")) + { + FileInfo infile = new FileInfo(args[1]); + FileInfo outfile = new FileInfo(args[2]); + new M2TsToTs(infile,outfile).Run(); + return; + } + + if (Directory.Exists(args[0])) + { + DirectoryInfo doThisDir = new DirectoryInfo(args[0]); + ProcessDirectory(doThisDir); + return; + } + + if (args[0].ToLowerInvariant().Equals("proxytest")) + { + TcpTsProxy tcpTsProxy = new TcpTsProxy(); + Thread.Sleep(5000); + tcpTsProxy.Dispose(); + return; + } + + if (args[0].ToLowerInvariant().Equals("importtest")) + { + DirectoryInfo doThisDir = new DirectoryInfo(args[1]); + InMemoryScraperStorage imss = new InMemoryScraperStorage(); + FilesystemStorage fs = new FilesystemStorage(new DirectoryInfo(".")); + TsFileCollectionImporter importer = new TsFileCollectionImporter(imss, fs, doThisDir); + importer.Run(); + return; + } + + + //fsimport "D:\Skyscraper" "E:\\" + if (args[0].ToLowerInvariant().Equals("fsimport")) + { + DirectoryInfo srcDir = new DirectoryInfo(args[1]); + DirectoryInfo tgtDir = new DirectoryInfo(args[2]); + FilesystemStorage fss = new FilesystemStorage(tgtDir); + TsFileCollectionImporter importer = new TsFileCollectionImporter(fss, fss, srcDir); + importer.Run(); + return; + } + + if (args[0].ToLowerInvariant().Equals("webservertest")) + { + SkyscraperWebserver webserverTest = SkyscraperWebserver.GetInstance(); + webserverTest.Start(); + while (webserverTest.IsListening) + { + Thread.Sleep(1000); + } + + return; + } + + if (args[0].ToLowerInvariant().Equals("gpstest")) + { + GpsManager.GpsTest(); + return; + } + + if (args[0].ToLowerInvariant().Equals("what-can-i-receive")) + { + WhatCanIReceive.StandaloneProgram(); + return; + } + + if (args[0].ToLowerInvariant().Equals("make-dummy-ts")) + { + DummyTsGenerator dummyTsGenerator = new DummyTsGenerator(); + dummyTsGenerator.Run(); + return; + } + + if (args[0].ToLowerInvariant().Equals("file-live")) + { + Program.HandleFileToLiveSystem(args[1]); + return; + } + + if (args[0].ToLowerInvariant().Equals("hlsproxy")) + { + DirectoryInfo di = new DirectoryInfo(args[1]); + HlsProxy hlsproxy = new HlsProxy(di); + hlsproxy.Run(); + return; + } + + if (args[0].ToLowerInvariant().Equals("hlsproxy-destructive")) + { + DirectoryInfo di = new DirectoryInfo(args[1]); + HlsProxy hlsproxy = new HlsProxy(di); + hlsproxy.DestructiveMode = true; + hlsproxy.Run(); + return; + } + + if (args[0].ToLowerInvariant().Equals("satip")) + { + QuickAndDirtySatIpClient qadsipc = new QuickAndDirtySatIpClient(args); + qadsipc.Run(); + return; + } + + if (args[0].ToLowerInvariant().Equals("satip-playout")) { QuickAndDirtySatIpClient qadsipc = new QuickAndDirtySatIpClient(args); qadsipc.SetPlayoutMode(args); qadsipc.Run(); - return; - } - - - if (args[0].ToLowerInvariant().Equals("shannon")) - { - if (args.Length != 2) - { - Console.WriteLine("Specify ONE file, please."); - return; - } - FileInfo fi = new FileInfo(args[1]); - if (!fi.Exists) - { - Console.WriteLine("{0} doesn't exist.", fi.FullName); - return; - } - FileStream fileStream = fi.OpenRead(); - EntropyCalculatorStream entropyCalculatorStream = new EntropyCalculatorStream(); - fileStream.CopyTo(entropyCalculatorStream); - fileStream.Close(); - fileStream.Dispose(); - Console.WriteLine("Entropy value: {0} ({1}%)", entropyCalculatorStream.Entropy, entropyCalculatorStream.Percentage); - return; - } - - if (args[0].ToLowerInvariant().Equals("pcap-on")) - { - TogglePcapConfiguration(1); - return; - } - if (args[0].ToLowerInvariant().Equals("pcap-off")) - { - TogglePcapConfiguration(2); - return; - } - - if (args[0].ToLowerInvariant().Equals("subts-on")) - { - ToggleSubTsDumpConfiguration(true); - return; - } - - if (args[0].ToLowerInvariant().Equals("subts-off")) - { - ToggleSubTsDumpConfiguration(false); - return; - } - - if (args[0].ToLowerInvariant().Equals("pts2bbf")) - { - if (args[1].ToLowerInvariant().Equals("bbfudpdecap")) - { - FileInfo fi = new FileInfo(args[2]); - Pts2Bbf.Run(fi, true); - return; - } - else - { - FileInfo fi = new FileInfo(args[1]); - Pts2Bbf.Run(fi, false); - return; - } - } - - if (args[0].ToLowerInvariant().Equals("pts2bbf2")) - { - FileInfo fi = new FileInfo(args[1]); - Pts2Bbf2 pts2Bbf2 = new Pts2Bbf2(fi); - pts2Bbf2.Run(); - return; - } - - if (args[0].ToLowerInvariant().Equals("stid135test")) - { - FileInfo fi = new FileInfo(args[1]); - Stid135Test.Run(fi); - return; - } - - if (args[0].ToLowerInvariant().Equals("make-catalogue")) - { - DirectoryInfo di = new DirectoryInfo(args[1]); - logger.InfoFormat("Input directory: {0}", di.FullName); - FileInfo fi = new FileInfo(args[2]); - logger.InfoFormat("Output File: {0}", fi.FullName); - CatalogueGenerator catalogueGenerator = new CatalogueGenerator(di, fi); - catalogueGenerator.Run(); - catalogueGenerator.Dispose(); - return; - } - } - - /*Passing passing = new Passing(); - if (!passing.Boot()) - { - Environment.Exit(1); - return; - } - passing.Run();*/ - Console.WriteLine("You're not supposed to run me directly. Run me from the commandline using the following:"); - Console.WriteLine("for example: .\\skyscraper8.exe cscan tcp://127.0.0.1:6969"); - Console.WriteLine(" or: .\\skyscraper8.exe udpin - listens on port 9003 on all local interface for udp packets."); - Console.WriteLine(" or: .\\skyscraper8.exe \"C:\\path\\to\\file.ts\\"); - Console.WriteLine(" or: .\\skyscraper8.exe \"C:\\path\\to\\my\\folder\\with\\ts\\files\\\" (for batch extraction)"); - Console.WriteLine(" or: .\\skyscraper8.exe satip IP_ADDRESS DISEQC POLARITY FREQUENCY SYSTEM SYMBOL_RATE (see README file)"); - Console.WriteLine(" or: .\\skyscraper8.exe satip-playout IP_ADDRESS DISEQC POLARITY FREQUENCY SYSTEM SYMBOL_RATE DESTINATION_PORT"); - Console.WriteLine(" or: .\\skyscraper8.exe pcap-on - to write a configuration file that allows PCAP writing during scraping."); - Console.WriteLine(" or: .\\skyscraper8.exe pcap-off - to write a configuration file that turns off PCAP writing during scraping."); - Console.WriteLine(" or: .\\skyscraper8.exe subts-on - to write a configuration file that allows extraction of nested TS."); - Console.WriteLine(" or: .\\skyscraper8.exe subts-off - to write a configuration file that turns off extraction of nested TS."); - Console.WriteLine(); - Console.WriteLine("default behaviour is pcap writing and nested TS writing on."); - Console.WriteLine(); - Console.WriteLine("Bonus features:"); - Console.WriteLine(".\\skyscraper8.exe hlsproxy \"C:\\path\\to\\hls\\files\\\" - to pipe a HLS stream from a local directory into VLC."); - Console.WriteLine(".\\skyscraper8.exe hlsproxy-destructive \"C:\\path\\to\\hls\\files\\\" - to pipe a HLS stream from a local directory into VLC and delete HLS segments afterwards. (be careful!)"); - Console.WriteLine(".\\skyscraper8.exe shannon \"C:\\some\\file.bmp\" - calculates the Shannon entropy value for any given file."); - Console.WriteLine(".\\skyscraper8.exe make-catalogue \"C:\\path\\to\\ts\\collection\\\" \"C:\\outputted_index.csv\" - generates a catalogue with core information about your TS files."); - Console.WriteLine(".\\skyscraper8.exe pts2bbf2 \"C:\\path\\to\\file.ts\\\" - extracts every single BBFrame from a GS to into a small file for each. (be careful, might generate many small files!)"); - } - - private static void ToggleSubTsDumpConfiguration(bool enabled) - { - PluginManager pluginManager = PluginManager.GetInstance(); - if (!pluginManager.Ini.ContainsKey("subts")) - pluginManager.Ini.Add("subts", new IniSection()); - - pluginManager.Ini["subts"]["dump"] = enabled ? "1" : "0"; - pluginManager.SaveConfiguration(); - - Console.WriteLine("Wrote skyscraper5.ini."); - } - - private static void TogglePcapConfiguration(int value) - { - PluginManager pluginManager = PluginManager.GetInstance(); - if (!pluginManager.Ini.ContainsKey("ip_handler")) - pluginManager.Ini.Add("ip_handler", new IniSection()); - - pluginManager.Ini["ip_handler"]["type"] = value.ToString(); - pluginManager.SaveConfiguration(); - - Console.WriteLine("Wrote skyscraper5.ini."); - } - private static void ProcessDirectory(DirectoryInfo di) - { - DataStorage dataStorage = new InMemoryScraperStorage(); - FilesystemStorage filesystemStorage = new FilesystemStorage(new DirectoryInfo(".")); - ProcessDirectory(di, dataStorage, filesystemStorage); - } - - private static void ProcessDirectory(DirectoryInfo di, DataStorage dataStorage, ObjectStorage objectStorage) - { - DirectoryInfo[] directoryInfos = di.GetDirectories(); - foreach (DirectoryInfo subdir in directoryInfos) - { - ProcessDirectory(subdir, dataStorage, objectStorage); - } - FileInfo[] fileInfos = di.GetFiles("*.ts"); - foreach (FileInfo fileInfo in fileInfos) - { - Console.WriteLine(new string('_', Console.WindowWidth - 1)); - Console.WriteLine("Processing: {0}", fileInfo.Name); - SkyscraperContext skyscraper = new SkyscraperContext(new TsContext(), dataStorage, objectStorage); - skyscraper.InitalizeFilterChain(); - //StreamTypeAutodetectionTest streamTypeAutodetectionTest = new StreamTypeAutodetectionTest(); - FileStream fileStream = fileInfo.OpenRead(); - - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - skyscraper.IngestFromStream(fileStream); - //streamTypeAutodetectionTest.IngestFromStream(fileStream); - stopwatch.Stop(); - - Console.WriteLine("Time to process: " + stopwatch.Elapsed.TotalSeconds); - - Console.WriteLine("File was: {0}", fileInfo.Name); - PrintPidStatistics(skyscraper); - } - } - - private static void PrintPidStatistics(SkyscraperContext skyscraper) - { - Console.WriteLine("Unattached PIDs:"); - ulong[] pidStatistics = skyscraper.DvbContext.GetPidStatistics(); - if (pidStatistics == null) - return; - for (int i = 0; i < pidStatistics.Length; i++) - { - if (pidStatistics[i] != 0) - { - if (!skyscraper.DvbContext.IsPidProcessorPresent(i)) - { - Console.WriteLine("{0:X4}", i); - } - } - } - } - - private static void HandleUdpTesting() - { - DataStorage data = new InMemoryScraperStorage(); - ObjectStorage objects = new FilesystemStorage(new DirectoryInfo(".")); - HandleUdpInput(data,objects); - } - - private static void HandleUdpLive() - { - StorageConnectionManager connectionManager = StorageConnectionManager.GetInstance(); - DataStorageFactory dataFactory = connectionManager.GetDefaultDataStorageFactory(); - ObjectStorageFactory objectFactory = connectionManager.GetDefaultObjectStorageFactory(); - DataStorage dataStorage = dataFactory.CreateDataStorage(); - ObjectStorage objectStorage; - if (objectFactory.IsEquivalent(dataFactory)) - objectStorage = (ObjectStorage)dataStorage; - else - objectStorage = objectFactory.CreateObjectStorage(); - HandleUdpInput(dataStorage,objectStorage); - } - - private static void HandleUdpInput(DataStorage dataStorage,ObjectStorage objectStorage) - { - NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); - foreach (NetworkInterface networkInterface in networkInterfaces) - { - IPInterfaceProperties interfaceProperties = networkInterface.GetIPProperties(); - foreach (UnicastIPAddressInformation unicastAddress in interfaceProperties.UnicastAddresses) - { - Console.WriteLine("Listening on: {0}", unicastAddress.Address.ToString()); - } - } - - //tsp -v --control-port 9001 -I dvb --delivery-system DVB-S2 --frequency 11421000000 --symbol-rate 22000000 --polarity horizontal -O ip 127.0.0.1:9001 - //SkyscraperWebserver.GetInstance().Start(); - //scraperStorage = new FilesystemScraperStorage(new DirectoryInfo("C:\\scraped_data")); - - SkyscraperContext skyscraper = null; - - UdpClient udpServer = new UdpClient(new IPEndPoint(IPAddress.Any, 9003)); - IPEndPoint remote = null; - IPEndPoint oldRemote = null; - int numPackets; - byte[] singlePacket = new byte[188]; - while (true) - { - byte[] buffer = udpServer.Receive(ref remote); - if (!remote.Equals(oldRemote)) - { - oldRemote = remote; - skyscraper = new SkyscraperContext(new TsContext(), dataStorage,objectStorage); - skyscraper.InitalizeFilterChain(); - skyscraper.EnableTimeout = true; - logger.InfoFormat("Got zapped by {0}", remote); - } - - numPackets = buffer.Length / 188; - for (int i = 0; i < numPackets; i++) - { - Array.Copy(buffer, i * 188, singlePacket, 0, 188); - skyscraper.IngestSinglePacket(singlePacket); - } - } - } - - private static void HandleCrazyScanToTestingSystem(string url) - { - - DataStorage dataStorage = new InMemoryScraperStorage(); - ObjectStorage objectStorage = new FilesystemStorage(new DirectoryInfo(".")); - HandleCrazyScan(url, dataStorage, objectStorage, true); - } - - private static void HandleFileToLiveSystem(string filename) - { - StorageConnectionManager connectionManager = StorageConnectionManager.GetInstance(); - DataStorageFactory dataStorageFactory = connectionManager.GetDefaultDataStorageFactory(); - ObjectStorageFactory objectStorageFactory = connectionManager.GetDefaultObjectStorageFactory(); - DataStorage dataStorage = dataStorageFactory.CreateDataStorage(); - ObjectStorage objectStorage; - if (objectStorageFactory.IsEquivalent(dataStorageFactory)) - objectStorage = (ObjectStorage)dataStorage; - else - objectStorage = objectStorageFactory.CreateObjectStorage(); - - FileInfo fi = new FileInfo(filename); - if (!fi.Exists) - { - logger.FatalFormat("{0} not found.", fi.FullName); - return; - } - - SkyscraperContext skyscraper = new SkyscraperContext(new TsContext(), dataStorage,objectStorage); - skyscraper.InitalizeFilterChain(); - skyscraper.EnableTimeout = false; - skyscraper.TcpProxyEnabled = false; - FileStream fileStream = fi.OpenRead(); - skyscraper.IngestFromStream(fileStream); - fileStream.Close(); - fileStream.Dispose(); - skyscraper.Dispose(); - } - - private static void HandleCrazyScanToLiveSystem(string url, bool withTimeout = true) - { - StorageConnectionManager connectionManager = StorageConnectionManager.GetInstance(); - DataStorageFactory dataStorageFactory = connectionManager.GetDefaultDataStorageFactory(); - ObjectStorageFactory objectStorageFactory = connectionManager.GetDefaultObjectStorageFactory(); - DataStorage dataStorage = dataStorageFactory.CreateDataStorage(); - ObjectStorage objectStorage; - if (objectStorageFactory.IsEquivalent(dataStorageFactory)) - objectStorage = (ObjectStorage)dataStorage; - else - objectStorage = objectStorageFactory.CreateObjectStorage(); - - objectStorage.Ping(); - HandleCrazyScan(url, dataStorage,objectStorage, withTimeout); - } - - private static void HandleCrazyScan(string url, DataStorage dataStorage, ObjectStorage objectStorage, bool timeout) - { - if (!url.StartsWith("tcp://")) - { - logger.Fatal("Use TCP, please."); - return; - } - - if (url.EndsWith("/")) - { - logger.Fatal("Don't use that trailing slash, please."); - return; - } - - url = url.Substring(6); - string[] strings = url.Split(':'); - string hostname = strings[0]; - int port = Int32.Parse(strings[1]); - - TcpClient tcpClient = new TcpClient(hostname, port); - - SkyscraperContext skyscraper = new SkyscraperContext(new TsContext(), dataStorage,objectStorage); - skyscraper.InitalizeFilterChain(new SkipFilter(1024)); - //skyscraper.EnableTimeout = timeout; - //skyscraper.TimeoutSeconds = 10; - skyscraper.TcpProxyEnabled = true; - skyscraper.IngestFromStream(new BufferedStream(tcpClient.GetStream(), 96256 * 2)); - } - - private static void HandleSingleFile(FileInfo fi) - { - //Environment.CurrentDirectory = fi.Directory.FullName; - TsContext tsContext = new TsContext(); - DataStorage dataStorage = new InMemoryScraperStorage(); - ObjectStorage objectStorage = new FilesystemStorage(new DirectoryInfo(".")); - SkyscraperContext skyscraper = new SkyscraperContext(tsContext, dataStorage,objectStorage); - skyscraper.InitalizeFilterChain(); - FileStream fileStream = fi.OpenRead(); - skyscraper.IngestFromStream(fileStream); - skyscraper.Dispose(); - fileStream.Close(); - - Console.WriteLine(""); - Console.WriteLine("Current Network ID: {0}", skyscraper.CurrentNetworkId); - Console.WriteLine("Current Transport Stream ID: {0}", skyscraper.CurrentTransportStreamId); - if (tsContext.PcrMonitor != null) - { - Console.WriteLine("Processing Performance: {0}", tsContext.PcrMonitor.Performance); - } - else - { - Console.WriteLine("No PCR detected."); - } - Console.WriteLine("DNS Records found: {0}", dataStorage.DnsCountA()); - Console.WriteLine(""); - - Console.WriteLine(new string('-', Console.WindowWidth)); - Console.WriteLine(""); - Console.ReadKey(true); - } - - private static void IoctlTest() - { - /* - int dvbSatSearchLnb = LibDvbV5.DvbSatSearchLnb("EXTENDED"); - LibDvbV5SatLnb lnb = new LibDvbV5SatLnb(dvbSatSearchLnb); - - LibDvbV5Device device = new LibDvbV5Device(); - device.SetLog(8, null); - device.Find(); - - LibDvbV5DeviceList findDeviceByDeliverySystem = device.FindDeviceByDeliverySystem(LibDvbV5FrontendDeliverySystem.SYS_DVBC_ANNEX_A); - if (findDeviceByDeliverySystem == null) - return; - - LibDvbV5DeviceList demuxerName = device.GetSisterDevice(findDeviceByDeliverySystem, DvbDeviceType.Demux); - LibDvbV5DeviceList dvrName = device.GetSisterDevice(findDeviceByDeliverySystem, DvbDeviceType.Dvr); - - LibDvb5FrontendParameters frontend = findDeviceByDeliverySystem.ToFrontendParameters(); - frontend.SetDeliverySystem(LibDvbV5FrontendDeliverySystem.SYS_DVBC_ANNEX_A); - frontend.StoreParameter(17, (uint)LibDvbV5FrontendDeliverySystem.SYS_DVBC_ANNEX_A); - frontend.StoreParameter(3, 610000000); //freq - frontend.StoreParameter(8, 6900000); //symbol rate - frontend.SetParameters(); - Thread.Sleep(400); - frontend.GetStatistics(); - Thread.Sleep(400); - uint retrieveStats = frontend.RetrieveStats(512); - if ((retrieveStats & 0x10) != 0) - { - Console.WriteLine("got lock!"); - LibDvbV5OpenDescriptor dvrFd = device.DeviceOpen(dvrName); - if (dvrFd == null) - throw new IOException("open failed"); - dvrFd.SetBufferSize(1024 * 1024); - - LibDvbV5OpenDescriptor demuxFd = device.DeviceOpen(demuxerName); - if (demuxFd == null) - throw new IOException("open failed"); - - demuxFd.DemuxSetPesFilter(0x2000, DemuxerPesType.DMX_PES_OTHER); - - FileStream fileStream = File.OpenWrite(String.Format("{0}.ts", DateTime.Now.Ticks)); - byte[] packBuffer = new byte[188]; - int readLen = 0; - for (int i = 0; i < 9001; i++) - { - readLen = dvrFd.Read(packBuffer, 188); - if (readLen > 0) - { - fileStream.Write(packBuffer, 0, 188); - } - } - - fileStream.Flush(true); - fileStream.Close(); - demuxFd.Dispose(); - dvrFd.Dispose(); - } - else - { - Console.WriteLine("no lock :("); - } - frontend.Dispose(); - device.Dispose(); - Thread.Sleep(1000); - return;*/ - /*FileInfo fi = new FileInfo("/dev/video0"); - SafeUnixHandle safeUnixHandle = UnsafeLibCNativeMethodsWrappers.OpenDevice(fi); - UnsafeLibCNativeMethodsWrappers.GetCapability(safeUnixHandle); - UnsafeLibCNativeMethodsWrappers.Close(safeUnixHandle);*/ - - //LocalStreamReader streamReader = LocalStreamReader.GetInstance(); - IStreamReader streamReader = new NullStreamReader(); - - bool checkForDvb = streamReader.CheckForDVB(); - if (checkForDvb) - { - streamReader.CheckForDVBEx((x, y) => { Console.WriteLine("{0}, {1}", x, y); }); - if (streamReader.StartDvbEx(0)) - { - - STD_TYPE ttype = default; - bool result = streamReader.GetTunerType(ref ttype); - if (!result) - Console.WriteLine("oh no"); - - Caps caps = streamReader.GetCaps(); - - BlScanCallback scanCallback = - (ref SearchResult searchResult) => - { - Console.WriteLine("{0}/{1}/{2}",searchResult.Freq,searchResult.Pol,searchResult.SR); - }; - - /*UnsafeStreamReaderMethods.AirScanCallback airScanCallback = - (ref UnsafeStreamReaderMethods.SearchResult2 searchResult2) => - { - Console.WriteLine(searchResult2.Freq); - };*/ - AirScanCallback altTest = (ref SearchResult2 searchResult) => - { - Console.WriteLine(searchResult.Freq); - }; - - //int tpNum = 0; - //result = UnsafeStreamReaderMethods.BLScanEx(10744000, 8000, 1, 9750000, 10600000, 11700000, 1, UnsafeStreamReaderMethods.STD_TYPE.STD_DVBS2, ref sr1); - //result = UnsafeStreamReaderMethods.BLScan(10744000, 8000, 0, 9750000, 10600000, 11700000, 1000, ref sr1); - /*result = UnsafeStreamReaderMethods.SetChannelExEx(10744000, 22000000, 0, - UnsafeStreamReaderMethods.VITERBIRATE_TYPE.VR_5_6, 9750000, 10600000, 11700000, - UnsafeStreamReaderMethods.MOD_TYPE.MOD_QPSK, 0, 0, - UnsafeStreamReaderMethods.ROLLOFF_TYPE.ROLLOFF_AUTO);*/ - /* - result = UnsafeStreamReaderMethods.SendDiSEqC(2, - UnsafeStreamReaderMethods.DiSEqC_Opcode.DISEQC_HIGH_NIBBLE | - UnsafeStreamReaderMethods.DiSEqC_Opcode.DISEQC_LOW_BAND | - UnsafeStreamReaderMethods.DiSEqC_Opcode.DISEQC_HORIZONTAL | - UnsafeStreamReaderMethods.DiSEqC_Opcode.DISEQC_POSITION_B | - UnsafeStreamReaderMethods.DiSEqC_Opcode.DISEQC_OPTION_A); - result = UnsafeStreamReaderMethods.SetChannel(10775000, 29900000, 0, - UnsafeStreamReaderMethods.VITERBIRATE_TYPE.VR_3_5, 9750000, 10600000, 11700000); - - - for (int i = 0; i < 100; i++) - { - Thread.Sleep(1000); - } - */ - - - SearchResult2 sr1 = default; - SearchResult2 sr2 = default; - int tpNum = default; - IntPtr allocHGlobal = Marshal.AllocHGlobal(1024); - result = streamReader.AirScan(100000, 800000, 3000, 8000, (int)STD_TYPE.STD_DVBC, allocHGlobal, ref tpNum, altTest); - SearchResult2 ptrToStructure = (SearchResult2)Marshal.PtrToStructure(allocHGlobal, typeof(SearchResult2)); - Marshal.FreeHGlobal(allocHGlobal); - Console.WriteLine(tpNum); - - /* - byte[] buffer = new byte[1024]; - - int offset = 0; - FileStream fileStream = File.OpenWrite("tbs5580.bin"); - result = true; - while (result) - { - result = UnsafeStreamReaderMethods.GetEEPROM(buffer, offset, 8); - if (result) - { - fileStream.Write(buffer, 0, 8); - offset += 8; - } - } - - fileStream.Flush(true); - fileStream.Close(); - */ - - /* - * - double snr = default; - for (uint i = 100; i < 200; i++) - { - result = UnsafeStreamReaderMethods.RFScan2(i * 1000, UnsafeStreamReaderMethods.STD_TYPE.STD_DVBC, ref snr); - if (result) - Console.WriteLine("{0} -> {1}", i, snr); - } - - */ - /* - UnsafeStreamReaderMethods.SearchResult sr1 = default; - UnsafeStreamReaderMethods.SearchResult sr2 = default; - int tpNum = default; - result = UnsafeStreamReaderMethods.SetChannel(10744000, 22000000, 0, 0, 9750000, 10600000, 11700000); - ulong numPackets = 0; - IntPtr filterPtr = default; - byte[] buffer = new byte[188]; - FileStream fs = File.OpenWrite("test.ts"); - result = UnsafeStreamReaderMethods.SetFilter(8192, ((data, length) => - { - //Console.WriteLine("Packet {0}", numPackets++); - Marshal.Copy(data, buffer, 0, length); - fs.Write(buffer, 0, 188); - }), 0x02, 1, ref filterPtr); - - sbyte[] iq = new sbyte[200]; - for (int i = 0; i < 150; i++) - { - Thread.Sleep(100); - UnsafeStreamReaderMethods.IQScan(0, iq, 100); - Console.WriteLine("{0},{1} - {2},{3} - {4},{5} - {6},{7}", iq[0], iq[1], iq[2], iq[3], iq[4], iq[5], iq[6], iq[7]); - } - result = UnsafeStreamReaderMethods.DelFilter(filterPtr); - fs.Flush(true); - fs.Close(); - */ - //result = UnsafeStreamReaderMethods.BLScan(11068, 8000, 1, 975000, 10600000, 11700000, 1, ref sr); - - /* - for (int i = 10700; i < 12750; i += 3) - { - result = UnsafeStreamReaderMethods.BLScan(i, 0, 1, 975000, 10600000, 11700000, 1, ref sr1); - if (sr1.SR != 0) - { - Console.Write("\r\n{0}/{1}/{2}", i, sr1.Pol, sr1.SR); - } - else - { - Console.Write("."); - } - result = UnsafeStreamReaderMethods.BLScan(i, 0, 0, 975000, 10600000, 11700000, 1, ref sr1); - if (sr1.SR != 0) - { - Console.Write("\r\n{0}/{1}/{2}", i, sr1.Pol, sr1.SR); - } - else - { - Console.Write("."); - } - }*/ - - //result = UnsafeStreamReaderMethods.BLScan2(10700, 12750, 0, 975000, 10600000, 11700000, ref sr1, ref tpNum, scanCallback); - - /* - byte[] macBuffer = new byte[6]; - result = UnsafeStreamReaderMethods.GetMAC(macBuffer); - */ - /* - double m = default; - for (int i = 10700; i < 12750; i += 1) - { - result = UnsafeStreamReaderMethods.RFScan(i, 0, 975000, 10600000, 11700000, out m); - Console.WriteLine("{2} {0} -> {1}", i, m, result); - } - */ - - - /* - result = UnsafeStreamReaderMethods.SetChannel(10744000, 22000000, 0, 0, 9750000, 10600000, 11700000); - - if (File.Exists("test.ts")) - File.Delete("test.ts"); - - FileStream fileStream = File.OpenWrite("test.ts"); - IntPtr filterPtr = IntPtr.Zero; - byte[] packet = new byte[188]; - UnsafeStreamReaderMethods.StdcallDvbCallback callback = (bytes, k) => - { - Marshal.Copy(bytes, packet, 0, k); - fileStream.Write(packet, 0, 188); - }; - result = UnsafeStreamReaderMethods.SetFilter(8192, callback, 0x02, 1, ref filterPtr); - - if (!result) - throw new NotImplementedException("no filter"); - - IntPtr rcPtr = IntPtr.Zero; - result = UnsafeStreamReaderMethods.SetRemoteControl(0, -1, (bytes, k) => - { - Console.WriteLine(k); - }, - ref rcPtr); - - result = UnsafeStreamReaderMethods.DelFilter(rcPtr); - result = UnsafeStreamReaderMethods.DelFilter(filterPtr); - */ - - /* - if (!UnsafeStreamReaderMethods.StopDVB()) - Console.WriteLine("wtf"); - */ - /* - fileStream.Flush(true); - fileStream.Close(); - */ - } - } - - } - } -} + return; + } + + + if (args[0].ToLowerInvariant().Equals("shannon")) + { + if (args.Length != 2) + { + Console.WriteLine("Specify ONE file, please."); + return; + } + FileInfo fi = new FileInfo(args[1]); + if (!fi.Exists) + { + Console.WriteLine("{0} doesn't exist.", fi.FullName); + return; + } + FileStream fileStream = fi.OpenRead(); + EntropyCalculatorStream entropyCalculatorStream = new EntropyCalculatorStream(); + fileStream.CopyTo(entropyCalculatorStream); + fileStream.Close(); + fileStream.Dispose(); + Console.WriteLine("Entropy value: {0} ({1}%)", entropyCalculatorStream.Entropy, entropyCalculatorStream.Percentage); + return; + } + + if (args[0].ToLowerInvariant().Equals("pcap-on")) + { + TogglePcapConfiguration(1); + return; + } + if (args[0].ToLowerInvariant().Equals("pcap-off")) + { + TogglePcapConfiguration(2); + return; + } + + if (args[0].ToLowerInvariant().Equals("subts-on")) + { + ToggleSubTsDumpConfiguration(true); + return; + } + + if (args[0].ToLowerInvariant().Equals("subts-off")) + { + ToggleSubTsDumpConfiguration(false); + return; + } + + if (args[0].ToLowerInvariant().Equals("pts2bbf")) + { + if (args[1].ToLowerInvariant().Equals("bbfudpdecap")) + { + FileInfo fi = new FileInfo(args[2]); + Pts2Bbf.Run(fi, true); + return; + } + else + { + FileInfo fi = new FileInfo(args[1]); + Pts2Bbf.Run(fi, false); + return; + } + } + + if (args[0].ToLowerInvariant().Equals("pts2bbf2")) + { + FileInfo fi = new FileInfo(args[1]); + Pts2Bbf2 pts2Bbf2 = new Pts2Bbf2(fi); + pts2Bbf2.Run(); + return; + } + + if (args[0].ToLowerInvariant().Equals("stid135test")) + { + FileInfo fi = new FileInfo(args[1]); + Stid135Test.Run(fi); + return; + } + + if (args[0].ToLowerInvariant().Equals("make-catalogue")) + { + DirectoryInfo di = new DirectoryInfo(args[1]); + logger.InfoFormat("Input directory: {0}", di.FullName); + FileInfo fi = new FileInfo(args[2]); + logger.InfoFormat("Output File: {0}", fi.FullName); + CatalogueGenerator catalogueGenerator = new CatalogueGenerator(di, fi); + catalogueGenerator.Run(); + catalogueGenerator.Dispose(); + return; + } + if (args[0].ToLowerInvariant().Equals("rotation-catalogue")) + { + TsRotationToCsv rotator = new TsRotationToCsv(); + rotator.SourceDir = new DirectoryInfo(args[1]); + rotator.DestinationCsv = new FileInfo(args[2]); + rotator.Run(); + return; + } + } + + /*Passing passing = new Passing(); + if (!passing.Boot()) + { + Environment.Exit(1); + return; + } + passing.Run();*/ + Console.WriteLine("You're not supposed to run me directly. Run me from the commandline using the following:"); + Console.WriteLine("for example: .\\skyscraper8.exe cscan tcp://127.0.0.1:6969"); + Console.WriteLine(" or: .\\skyscraper8.exe udpin - listens on port 9003 on all local interface for udp packets."); + Console.WriteLine(" or: .\\skyscraper8.exe \"C:\\path\\to\\file.ts\\"); + Console.WriteLine(" or: .\\skyscraper8.exe \"C:\\path\\to\\my\\folder\\with\\ts\\files\\\" (for batch extraction)"); + Console.WriteLine(" or: .\\skyscraper8.exe satip IP_ADDRESS DISEQC POLARITY FREQUENCY SYSTEM SYMBOL_RATE (see README file)"); + Console.WriteLine(" or: .\\skyscraper8.exe satip-playout IP_ADDRESS DISEQC POLARITY FREQUENCY SYSTEM SYMBOL_RATE DESTINATION_PORT"); + Console.WriteLine(" or: .\\skyscraper8.exe pcap-on - to write a configuration file that allows PCAP writing during scraping."); + Console.WriteLine(" or: .\\skyscraper8.exe pcap-off - to write a configuration file that turns off PCAP writing during scraping."); + Console.WriteLine(" or: .\\skyscraper8.exe subts-on - to write a configuration file that allows extraction of nested TS."); + Console.WriteLine(" or: .\\skyscraper8.exe subts-off - to write a configuration file that turns off extraction of nested TS."); + Console.WriteLine(); + Console.WriteLine("default behaviour is pcap writing and nested TS writing on."); + Console.WriteLine(); + Console.WriteLine("Bonus features:"); + Console.WriteLine(".\\skyscraper8.exe hlsproxy \"C:\\path\\to\\hls\\files\\\" - to pipe a HLS stream from a local directory into VLC."); + Console.WriteLine(".\\skyscraper8.exe hlsproxy-destructive \"C:\\path\\to\\hls\\files\\\" - to pipe a HLS stream from a local directory into VLC and delete HLS segments afterwards. (be careful!)"); + Console.WriteLine(".\\skyscraper8.exe shannon \"C:\\some\\file.bmp\" - calculates the Shannon entropy value for any given file."); + Console.WriteLine(".\\skyscraper8.exe make-catalogue \"C:\\path\\to\\ts\\collection\\\" \"C:\\outputted_index.csv\" - generates a catalogue with core information about your TS files."); + Console.WriteLine(".\\skyscraper8.exe pts2bbf2 \"C:\\path\\to\\file.ts\\\" - extracts every single BBFrame from a GS to into a small file for each. (be careful, might generate many small files!)"); + } + + private static void ToggleSubTsDumpConfiguration(bool enabled) + { + PluginManager pluginManager = PluginManager.GetInstance(); + if (!pluginManager.Ini.ContainsKey("subts")) + pluginManager.Ini.Add("subts", new IniSection()); + + pluginManager.Ini["subts"]["dump"] = enabled ? "1" : "0"; + pluginManager.SaveConfiguration(); + + Console.WriteLine("Wrote skyscraper5.ini."); + } + + private static void TogglePcapConfiguration(int value) + { + PluginManager pluginManager = PluginManager.GetInstance(); + if (!pluginManager.Ini.ContainsKey("ip_handler")) + pluginManager.Ini.Add("ip_handler", new IniSection()); + + pluginManager.Ini["ip_handler"]["type"] = value.ToString(); + pluginManager.SaveConfiguration(); + + Console.WriteLine("Wrote skyscraper5.ini."); + } + private static void ProcessDirectory(DirectoryInfo di) + { + DataStorage dataStorage = new InMemoryScraperStorage(); + FilesystemStorage filesystemStorage = new FilesystemStorage(new DirectoryInfo(".")); + ProcessDirectory(di, dataStorage, filesystemStorage); + } + + private static void ProcessDirectory(DirectoryInfo di, DataStorage dataStorage, ObjectStorage objectStorage) + { + DirectoryInfo[] directoryInfos = di.GetDirectories(); + foreach (DirectoryInfo subdir in directoryInfos) + { + ProcessDirectory(subdir, dataStorage, objectStorage); + } + FileInfo[] fileInfos = di.GetFiles("*.ts"); + foreach (FileInfo fileInfo in fileInfos) + { + Console.WriteLine(new string('_', Console.WindowWidth - 1)); + Console.WriteLine("Processing: {0}", fileInfo.Name); + SkyscraperContext skyscraper = new SkyscraperContext(new TsContext(), dataStorage, objectStorage); + skyscraper.InitalizeFilterChain(); + //StreamTypeAutodetectionTest streamTypeAutodetectionTest = new StreamTypeAutodetectionTest(); + FileStream fileStream = fileInfo.OpenRead(); + + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + skyscraper.IngestFromStream(fileStream); + //streamTypeAutodetectionTest.IngestFromStream(fileStream); + stopwatch.Stop(); + + Console.WriteLine("Time to process: " + stopwatch.Elapsed.TotalSeconds); + + Console.WriteLine("File was: {0}", fileInfo.Name); + PrintPidStatistics(skyscraper); + } + } + + private static void PrintPidStatistics(SkyscraperContext skyscraper) + { + Console.WriteLine("Unattached PIDs:"); + ulong[] pidStatistics = skyscraper.DvbContext.GetPidStatistics(); + if (pidStatistics == null) + return; + for (int i = 0; i < pidStatistics.Length; i++) + { + if (pidStatistics[i] != 0) + { + if (!skyscraper.DvbContext.IsPidProcessorPresent(i)) + { + Console.WriteLine("{0:X4}", i); + } + } + } + } + + private static void HandleUdpTesting() + { + DataStorage data = new InMemoryScraperStorage(); + ObjectStorage objects = new FilesystemStorage(new DirectoryInfo(".")); + HandleUdpInput(data,objects); + } + + private static void HandleUdpLive() + { + StorageConnectionManager connectionManager = StorageConnectionManager.GetInstance(); + DataStorageFactory dataFactory = connectionManager.GetDefaultDataStorageFactory(); + ObjectStorageFactory objectFactory = connectionManager.GetDefaultObjectStorageFactory(); + DataStorage dataStorage = dataFactory.CreateDataStorage(); + ObjectStorage objectStorage; + if (objectFactory.IsEquivalent(dataFactory)) + objectStorage = (ObjectStorage)dataStorage; + else + objectStorage = objectFactory.CreateObjectStorage(); + HandleUdpInput(dataStorage,objectStorage); + } + + private static void HandleUdpInput(DataStorage dataStorage,ObjectStorage objectStorage) + { + NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); + foreach (NetworkInterface networkInterface in networkInterfaces) + { + IPInterfaceProperties interfaceProperties = networkInterface.GetIPProperties(); + foreach (UnicastIPAddressInformation unicastAddress in interfaceProperties.UnicastAddresses) + { + Console.WriteLine("Listening on: {0}", unicastAddress.Address.ToString()); + } + } + + //tsp -v --control-port 9001 -I dvb --delivery-system DVB-S2 --frequency 11421000000 --symbol-rate 22000000 --polarity horizontal -O ip 127.0.0.1:9001 + //SkyscraperWebserver.GetInstance().Start(); + //scraperStorage = new FilesystemScraperStorage(new DirectoryInfo("C:\\scraped_data")); + + SkyscraperContext skyscraper = null; + + UdpClient udpServer = new UdpClient(new IPEndPoint(IPAddress.Any, 9003)); + IPEndPoint remote = null; + IPEndPoint oldRemote = null; + int numPackets; + byte[] singlePacket = new byte[188]; + while (true) + { + byte[] buffer = udpServer.Receive(ref remote); + if (!remote.Equals(oldRemote)) + { + oldRemote = remote; + skyscraper = new SkyscraperContext(new TsContext(), dataStorage,objectStorage); + skyscraper.InitalizeFilterChain(); + skyscraper.EnableTimeout = true; + logger.InfoFormat("Got zapped by {0}", remote); + } + + numPackets = buffer.Length / 188; + for (int i = 0; i < numPackets; i++) + { + Array.Copy(buffer, i * 188, singlePacket, 0, 188); + skyscraper.IngestSinglePacket(singlePacket); + } + } + } + + private static void HandleCrazyScanToTestingSystem(string url) + { + + DataStorage dataStorage = new InMemoryScraperStorage(); + ObjectStorage objectStorage = new FilesystemStorage(new DirectoryInfo(".")); + HandleCrazyScan(url, dataStorage, objectStorage, true); + } + + private static void HandleFileToLiveSystem(string filename) + { + StorageConnectionManager connectionManager = StorageConnectionManager.GetInstance(); + DataStorageFactory dataStorageFactory = connectionManager.GetDefaultDataStorageFactory(); + ObjectStorageFactory objectStorageFactory = connectionManager.GetDefaultObjectStorageFactory(); + DataStorage dataStorage = dataStorageFactory.CreateDataStorage(); + ObjectStorage objectStorage; + if (objectStorageFactory.IsEquivalent(dataStorageFactory)) + objectStorage = (ObjectStorage)dataStorage; + else + objectStorage = objectStorageFactory.CreateObjectStorage(); + + FileInfo fi = new FileInfo(filename); + if (!fi.Exists) + { + logger.FatalFormat("{0} not found.", fi.FullName); + return; + } + + SkyscraperContext skyscraper = new SkyscraperContext(new TsContext(), dataStorage,objectStorage); + skyscraper.InitalizeFilterChain(); + skyscraper.EnableTimeout = false; + skyscraper.TcpProxyEnabled = false; + FileStream fileStream = fi.OpenRead(); + skyscraper.IngestFromStream(fileStream); + fileStream.Close(); + fileStream.Dispose(); + skyscraper.Dispose(); + } + + private static void HandleCrazyScanToLiveSystem(string url, bool withTimeout = true) + { + StorageConnectionManager connectionManager = StorageConnectionManager.GetInstance(); + DataStorageFactory dataStorageFactory = connectionManager.GetDefaultDataStorageFactory(); + ObjectStorageFactory objectStorageFactory = connectionManager.GetDefaultObjectStorageFactory(); + DataStorage dataStorage = dataStorageFactory.CreateDataStorage(); + ObjectStorage objectStorage; + if (objectStorageFactory.IsEquivalent(dataStorageFactory)) + objectStorage = (ObjectStorage)dataStorage; + else + objectStorage = objectStorageFactory.CreateObjectStorage(); + + objectStorage.Ping(); + HandleCrazyScan(url, dataStorage,objectStorage, withTimeout); + } + + private static void HandleCrazyScan(string url, DataStorage dataStorage, ObjectStorage objectStorage, bool timeout) + { + if (!url.StartsWith("tcp://")) + { + logger.Fatal("Use TCP, please."); + return; + } + + if (url.EndsWith("/")) + { + logger.Fatal("Don't use that trailing slash, please."); + return; + } + + url = url.Substring(6); + string[] strings = url.Split(':'); + string hostname = strings[0]; + int port = Int32.Parse(strings[1]); + + TcpClient tcpClient = new TcpClient(hostname, port); + + SkyscraperContext skyscraper = new SkyscraperContext(new TsContext(), dataStorage,objectStorage); + skyscraper.InitalizeFilterChain(new SkipFilter(1024)); + //skyscraper.EnableTimeout = timeout; + //skyscraper.TimeoutSeconds = 10; + skyscraper.TcpProxyEnabled = true; + skyscraper.IngestFromStream(new BufferedStream(tcpClient.GetStream(), 96256 * 2)); + } + + private static void HandleSingleFile(FileInfo fi) + { + //Environment.CurrentDirectory = fi.Directory.FullName; + TsContext tsContext = new TsContext(); + DataStorage dataStorage = new InMemoryScraperStorage(); + ObjectStorage objectStorage = new FilesystemStorage(new DirectoryInfo(".")); + SkyscraperContext skyscraper = new SkyscraperContext(tsContext, dataStorage,objectStorage); + skyscraper.InitalizeFilterChain(); + FileStream fileStream = fi.OpenRead(); + skyscraper.IngestFromStream(fileStream); + skyscraper.Dispose(); + fileStream.Close(); + + Console.WriteLine(""); + Console.WriteLine("Current Network ID: {0}", skyscraper.CurrentNetworkId); + Console.WriteLine("Current Transport Stream ID: {0}", skyscraper.CurrentTransportStreamId); + if (tsContext.PcrMonitor != null) + { + Console.WriteLine("Processing Performance: {0}", tsContext.PcrMonitor.Performance); + } + else + { + Console.WriteLine("No PCR detected."); + } + Console.WriteLine("DNS Records found: {0}", dataStorage.DnsCountA()); + Console.WriteLine(""); + + Console.WriteLine(new string('-', Console.WindowWidth)); + Console.WriteLine(""); + Console.ReadKey(true); + } + + private static void IoctlTest() + { + /* + int dvbSatSearchLnb = LibDvbV5.DvbSatSearchLnb("EXTENDED"); + LibDvbV5SatLnb lnb = new LibDvbV5SatLnb(dvbSatSearchLnb); + + LibDvbV5Device device = new LibDvbV5Device(); + device.SetLog(8, null); + device.Find(); + + LibDvbV5DeviceList findDeviceByDeliverySystem = device.FindDeviceByDeliverySystem(LibDvbV5FrontendDeliverySystem.SYS_DVBC_ANNEX_A); + if (findDeviceByDeliverySystem == null) + return; + + LibDvbV5DeviceList demuxerName = device.GetSisterDevice(findDeviceByDeliverySystem, DvbDeviceType.Demux); + LibDvbV5DeviceList dvrName = device.GetSisterDevice(findDeviceByDeliverySystem, DvbDeviceType.Dvr); + + LibDvb5FrontendParameters frontend = findDeviceByDeliverySystem.ToFrontendParameters(); + frontend.SetDeliverySystem(LibDvbV5FrontendDeliverySystem.SYS_DVBC_ANNEX_A); + frontend.StoreParameter(17, (uint)LibDvbV5FrontendDeliverySystem.SYS_DVBC_ANNEX_A); + frontend.StoreParameter(3, 610000000); //freq + frontend.StoreParameter(8, 6900000); //symbol rate + frontend.SetParameters(); + Thread.Sleep(400); + frontend.GetStatistics(); + Thread.Sleep(400); + uint retrieveStats = frontend.RetrieveStats(512); + if ((retrieveStats & 0x10) != 0) + { + Console.WriteLine("got lock!"); + LibDvbV5OpenDescriptor dvrFd = device.DeviceOpen(dvrName); + if (dvrFd == null) + throw new IOException("open failed"); + dvrFd.SetBufferSize(1024 * 1024); + + LibDvbV5OpenDescriptor demuxFd = device.DeviceOpen(demuxerName); + if (demuxFd == null) + throw new IOException("open failed"); + + demuxFd.DemuxSetPesFilter(0x2000, DemuxerPesType.DMX_PES_OTHER); + + FileStream fileStream = File.OpenWrite(String.Format("{0}.ts", DateTime.Now.Ticks)); + byte[] packBuffer = new byte[188]; + int readLen = 0; + for (int i = 0; i < 9001; i++) + { + readLen = dvrFd.Read(packBuffer, 188); + if (readLen > 0) + { + fileStream.Write(packBuffer, 0, 188); + } + } + + fileStream.Flush(true); + fileStream.Close(); + demuxFd.Dispose(); + dvrFd.Dispose(); + } + else + { + Console.WriteLine("no lock :("); + } + frontend.Dispose(); + device.Dispose(); + Thread.Sleep(1000); + return;*/ + /*FileInfo fi = new FileInfo("/dev/video0"); + SafeUnixHandle safeUnixHandle = UnsafeLibCNativeMethodsWrappers.OpenDevice(fi); + UnsafeLibCNativeMethodsWrappers.GetCapability(safeUnixHandle); + UnsafeLibCNativeMethodsWrappers.Close(safeUnixHandle);*/ + + //LocalStreamReader streamReader = LocalStreamReader.GetInstance(); + IStreamReader streamReader = new NullStreamReader(); + + bool checkForDvb = streamReader.CheckForDVB(); + if (checkForDvb) + { + streamReader.CheckForDVBEx((x, y) => { Console.WriteLine("{0}, {1}", x, y); }); + if (streamReader.StartDvbEx(0)) + { + + STD_TYPE ttype = default; + bool result = streamReader.GetTunerType(ref ttype); + if (!result) + Console.WriteLine("oh no"); + + Caps caps = streamReader.GetCaps(); + + BlScanCallback scanCallback = + (ref SearchResult searchResult) => + { + Console.WriteLine("{0}/{1}/{2}",searchResult.Freq,searchResult.Pol,searchResult.SR); + }; + + /*UnsafeStreamReaderMethods.AirScanCallback airScanCallback = + (ref UnsafeStreamReaderMethods.SearchResult2 searchResult2) => + { + Console.WriteLine(searchResult2.Freq); + };*/ + AirScanCallback altTest = (ref SearchResult2 searchResult) => + { + Console.WriteLine(searchResult.Freq); + }; + + //int tpNum = 0; + //result = UnsafeStreamReaderMethods.BLScanEx(10744000, 8000, 1, 9750000, 10600000, 11700000, 1, UnsafeStreamReaderMethods.STD_TYPE.STD_DVBS2, ref sr1); + //result = UnsafeStreamReaderMethods.BLScan(10744000, 8000, 0, 9750000, 10600000, 11700000, 1000, ref sr1); + /*result = UnsafeStreamReaderMethods.SetChannelExEx(10744000, 22000000, 0, + UnsafeStreamReaderMethods.VITERBIRATE_TYPE.VR_5_6, 9750000, 10600000, 11700000, + UnsafeStreamReaderMethods.MOD_TYPE.MOD_QPSK, 0, 0, + UnsafeStreamReaderMethods.ROLLOFF_TYPE.ROLLOFF_AUTO);*/ + /* + result = UnsafeStreamReaderMethods.SendDiSEqC(2, + UnsafeStreamReaderMethods.DiSEqC_Opcode.DISEQC_HIGH_NIBBLE | + UnsafeStreamReaderMethods.DiSEqC_Opcode.DISEQC_LOW_BAND | + UnsafeStreamReaderMethods.DiSEqC_Opcode.DISEQC_HORIZONTAL | + UnsafeStreamReaderMethods.DiSEqC_Opcode.DISEQC_POSITION_B | + UnsafeStreamReaderMethods.DiSEqC_Opcode.DISEQC_OPTION_A); + result = UnsafeStreamReaderMethods.SetChannel(10775000, 29900000, 0, + UnsafeStreamReaderMethods.VITERBIRATE_TYPE.VR_3_5, 9750000, 10600000, 11700000); + + + for (int i = 0; i < 100; i++) + { + Thread.Sleep(1000); + } + */ + + + SearchResult2 sr1 = default; + SearchResult2 sr2 = default; + int tpNum = default; + IntPtr allocHGlobal = Marshal.AllocHGlobal(1024); + result = streamReader.AirScan(100000, 800000, 3000, 8000, (int)STD_TYPE.STD_DVBC, allocHGlobal, ref tpNum, altTest); + SearchResult2 ptrToStructure = (SearchResult2)Marshal.PtrToStructure(allocHGlobal, typeof(SearchResult2)); + Marshal.FreeHGlobal(allocHGlobal); + Console.WriteLine(tpNum); + + /* + byte[] buffer = new byte[1024]; + + int offset = 0; + FileStream fileStream = File.OpenWrite("tbs5580.bin"); + result = true; + while (result) + { + result = UnsafeStreamReaderMethods.GetEEPROM(buffer, offset, 8); + if (result) + { + fileStream.Write(buffer, 0, 8); + offset += 8; + } + } + + fileStream.Flush(true); + fileStream.Close(); + */ + + /* + * + double snr = default; + for (uint i = 100; i < 200; i++) + { + result = UnsafeStreamReaderMethods.RFScan2(i * 1000, UnsafeStreamReaderMethods.STD_TYPE.STD_DVBC, ref snr); + if (result) + Console.WriteLine("{0} -> {1}", i, snr); + } + + */ + /* + UnsafeStreamReaderMethods.SearchResult sr1 = default; + UnsafeStreamReaderMethods.SearchResult sr2 = default; + int tpNum = default; + result = UnsafeStreamReaderMethods.SetChannel(10744000, 22000000, 0, 0, 9750000, 10600000, 11700000); + ulong numPackets = 0; + IntPtr filterPtr = default; + byte[] buffer = new byte[188]; + FileStream fs = File.OpenWrite("test.ts"); + result = UnsafeStreamReaderMethods.SetFilter(8192, ((data, length) => + { + //Console.WriteLine("Packet {0}", numPackets++); + Marshal.Copy(data, buffer, 0, length); + fs.Write(buffer, 0, 188); + }), 0x02, 1, ref filterPtr); + + sbyte[] iq = new sbyte[200]; + for (int i = 0; i < 150; i++) + { + Thread.Sleep(100); + UnsafeStreamReaderMethods.IQScan(0, iq, 100); + Console.WriteLine("{0},{1} - {2},{3} - {4},{5} - {6},{7}", iq[0], iq[1], iq[2], iq[3], iq[4], iq[5], iq[6], iq[7]); + } + result = UnsafeStreamReaderMethods.DelFilter(filterPtr); + fs.Flush(true); + fs.Close(); + */ + //result = UnsafeStreamReaderMethods.BLScan(11068, 8000, 1, 975000, 10600000, 11700000, 1, ref sr); + + /* + for (int i = 10700; i < 12750; i += 3) + { + result = UnsafeStreamReaderMethods.BLScan(i, 0, 1, 975000, 10600000, 11700000, 1, ref sr1); + if (sr1.SR != 0) + { + Console.Write("\r\n{0}/{1}/{2}", i, sr1.Pol, sr1.SR); + } + else + { + Console.Write("."); + } + result = UnsafeStreamReaderMethods.BLScan(i, 0, 0, 975000, 10600000, 11700000, 1, ref sr1); + if (sr1.SR != 0) + { + Console.Write("\r\n{0}/{1}/{2}", i, sr1.Pol, sr1.SR); + } + else + { + Console.Write("."); + } + }*/ + + //result = UnsafeStreamReaderMethods.BLScan2(10700, 12750, 0, 975000, 10600000, 11700000, ref sr1, ref tpNum, scanCallback); + + /* + byte[] macBuffer = new byte[6]; + result = UnsafeStreamReaderMethods.GetMAC(macBuffer); + */ + /* + double m = default; + for (int i = 10700; i < 12750; i += 1) + { + result = UnsafeStreamReaderMethods.RFScan(i, 0, 975000, 10600000, 11700000, out m); + Console.WriteLine("{2} {0} -> {1}", i, m, result); + } + */ + + + /* + result = UnsafeStreamReaderMethods.SetChannel(10744000, 22000000, 0, 0, 9750000, 10600000, 11700000); + + if (File.Exists("test.ts")) + File.Delete("test.ts"); + + FileStream fileStream = File.OpenWrite("test.ts"); + IntPtr filterPtr = IntPtr.Zero; + byte[] packet = new byte[188]; + UnsafeStreamReaderMethods.StdcallDvbCallback callback = (bytes, k) => + { + Marshal.Copy(bytes, packet, 0, k); + fileStream.Write(packet, 0, 188); + }; + result = UnsafeStreamReaderMethods.SetFilter(8192, callback, 0x02, 1, ref filterPtr); + + if (!result) + throw new NotImplementedException("no filter"); + + IntPtr rcPtr = IntPtr.Zero; + result = UnsafeStreamReaderMethods.SetRemoteControl(0, -1, (bytes, k) => + { + Console.WriteLine(k); + }, + ref rcPtr); + + result = UnsafeStreamReaderMethods.DelFilter(rcPtr); + result = UnsafeStreamReaderMethods.DelFilter(filterPtr); + */ + + /* + if (!UnsafeStreamReaderMethods.StopDVB()) + Console.WriteLine("wtf"); + */ + /* + fileStream.Flush(true); + fileStream.Close(); + */ + } + } + + } + } +} diff --git a/skyscraper8/Properties/launchSettings.json b/skyscraper8/Properties/launchSettings.json index e263e51..087bf5d 100644 --- a/skyscraper8/Properties/launchSettings.json +++ b/skyscraper8/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "skyscraper8": { "commandName": "Project", - "commandLineArgs": "satip-playout auto 1 V 12597 S2 45000 6970", + "commandLineArgs": "rotation-catalogue F:\\\\ F:\\\\rotate-us.csv", "remoteDebugEnabled": false }, "Container (Dockerfile)": { diff --git a/skyscraper8/QuickAndDirtySatIpClient.cs b/skyscraper8/QuickAndDirtySatIpClient.cs index 046a7ac..045c641 100644 --- a/skyscraper8/QuickAndDirtySatIpClient.cs +++ b/skyscraper8/QuickAndDirtySatIpClient.cs @@ -1,79 +1,79 @@ -using log4net; -using skyscraper5.Skyscraper.IO.CrazycatStreamReader; -using skyscraper8.SatIp; -using skyscraper8.SatIp.RtspResponses; -using skyscraper8.SimpleServiceDiscoveryProtocol; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading.Tasks; -using skyscraper5.Mpeg2; -using skyscraper5.Skyscraper.Scraper; -using skyscraper5.Skyscraper.Scraper.Storage.Filesystem; -using skyscraper5.Skyscraper.Scraper.Storage.InMemory; -using skyscraper8.Skyscraper.Scraper.Storage; - -namespace skyscraper8 -{ - internal class QuickAndDirtySatIpClient - { - private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); - private const bool ENABLE_TS_WRITER = true; - - public QuickAndDirtySatIpClient(string[] args) - { - if (args.Length == 1) - { - logger.Fatal("Hey, what's your SAT>IP Server's IP Address? You can also say \"autodetect\" here."); - return; - } - if (args[1].ToLowerInvariant().Contains("auto")) - { - ipAddress = AutodetectIPAddress(); - } - else - { - ipAddress = IPAddress.Parse(args[1]); - } - - if (args.Length == 2) - { - logger.Fatal("You didn't specify a DiSEqc setting. (Number between 1-4)"); - return; - } - diseqcNumber = Int32.Parse(args[2]); - - if (args.Length == 3) - { - logger.Fatal("You didn't specify a polarity. Use H or V."); - return; - } - polarity = args[3].ToUpperInvariant()[0]; - - if (args.Length == 4) - { - logger.Fatal("Please specify a frequency."); - return; - } - frequency = Int32.Parse(args[4]); - - if (args.Length == 5) - { - logger.Fatal("What DVB Standard do we have here? S or S2?"); - return; - } - isS2 = ParseDvbStandard(args[5]); - - if (args.Length == 6) - { - logger.Fatal("What's the symbol rate?"); - return; - } - symbolRate = Int32.Parse(args[6]); - } - +using log4net; +using skyscraper5.Skyscraper.IO.CrazycatStreamReader; +using skyscraper8.SatIp; +using skyscraper8.SatIp.RtspResponses; +using skyscraper8.SimpleServiceDiscoveryProtocol; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using skyscraper5.Mpeg2; +using skyscraper5.Skyscraper.Scraper; +using skyscraper5.Skyscraper.Scraper.Storage.Filesystem; +using skyscraper5.Skyscraper.Scraper.Storage.InMemory; +using skyscraper8.Skyscraper.Scraper.Storage; + +namespace skyscraper8 +{ + internal class QuickAndDirtySatIpClient + { + private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); + private const bool ENABLE_TS_WRITER = true; + + public QuickAndDirtySatIpClient(string[] args) + { + if (args.Length == 1) + { + logger.Fatal("Hey, what's your SAT>IP Server's IP Address? You can also say \"autodetect\" here."); + return; + } + if (args[1].ToLowerInvariant().Contains("auto")) + { + ipAddress = AutodetectIPAddress(); + } + else + { + ipAddress = IPAddress.Parse(args[1]); + } + + if (args.Length == 2) + { + logger.Fatal("You didn't specify a DiSEqc setting. (Number between 1-4)"); + return; + } + diseqcNumber = Int32.Parse(args[2]); + + if (args.Length == 3) + { + logger.Fatal("You didn't specify a polarity. Use H or V."); + return; + } + polarity = args[3].ToUpperInvariant()[0]; + + if (args.Length == 4) + { + logger.Fatal("Please specify a frequency."); + return; + } + frequency = Int32.Parse(args[4]); + + if (args.Length == 5) + { + logger.Fatal("What DVB Standard do we have here? S or S2?"); + return; + } + isS2 = ParseDvbStandard(args[5]); + + if (args.Length == 6) + { + logger.Fatal("What's the symbol rate?"); + return; + } + symbolRate = Int32.Parse(args[6]); + } + public void SetPlayoutMode(string[] args) { if (args.Length == 7) @@ -83,66 +83,79 @@ namespace skyscraper8 } destinationPort = int.Parse(args[7]); playoutMode = true; - } - - private IPAddress AutodetectIPAddress() - { - SsdpDevice firstSatIpServer = SsdpClient.GetFirstSatIpServer(1000, null); - if (firstSatIpServer == null) - { - logger.WarnFormat("Didn't find any SAT>IP servers."); - return null; - } - IPAddress ipAddress = firstSatIpServer.GetIpAddress(); - logger.InfoFormat("Found SAT>IP Server at {0}", ipAddress); - return ipAddress; - } - - private int symbolRate; - private bool isS2; - private int frequency; - private char polarity; - private int diseqcNumber; - private IPAddress ipAddress; - private RtspClient rtspClient; - public void Run() - { - rtspClient = new RtspClient(ipAddress, 554); - rtspClient.AutoReconnect = false; - Keepalive(); - DiSEqC_Opcode opcode = BuildDiseqcOpcode(); - string url = RtspClient.MakeUrl(opcode, frequency, isS2, symbolRate, null, false); - RtspDescribeResponse describe = rtspClient.GetDescribe(url); - SessionDescriptionProtocol sessionDescriptionProtocol = describe.GetSessionDescriptionProtocol(); - - packetQueue = new Queue(); - RtspSetupResponse setup = rtspClient.GetSetup(url, destinationPort); - if (setup.RtspStatusCode == 404) - { - logger.Fatal("Your SAT>IP server doesn't have a tuner available that can talk to the requested frequency."); - return; - } - setup.OnRtcpPacket += Setup_OnRtcpPacket; - setup.OnRtpPacket += Setup_OnRtpPacket; - - if (dataStorage == null) - dataStorage = new InMemoryScraperStorage(); - if (objectStorage == null) - objectStorage = new FilesystemStorage(new DirectoryInfo(".")); + if (args.Length == 10) + { + if (args[8].ToLowerInvariant().Equals("multicast")) + { + destinationIp = IPAddress.Parse(args[9]); + multicastMode = true; + } + else + { + logger.FatalFormat("Don't know what {0} means.", args[8]); + return; + } + } + } + + private IPAddress AutodetectIPAddress() + { + SsdpDevice firstSatIpServer = SsdpClient.GetFirstSatIpServer(1000, null); + if (firstSatIpServer == null) + { + logger.WarnFormat("Didn't find any SAT>IP servers."); + return null; + } + IPAddress ipAddress = firstSatIpServer.GetIpAddress(); + logger.InfoFormat("Found SAT>IP Server at {0}", ipAddress); + return ipAddress; + } + + private int symbolRate; + private bool isS2; + private int frequency; + private char polarity; + private int diseqcNumber; + private IPAddress ipAddress; + private RtspClient rtspClient; + public void Run() + { + rtspClient = new RtspClient(ipAddress, 554); + rtspClient.AutoReconnect = false; + Keepalive(); + DiSEqC_Opcode opcode = BuildDiseqcOpcode(); + string url = RtspClient.MakeUrl(opcode, frequency, isS2, symbolRate, null, false); + RtspDescribeResponse describe = rtspClient.GetDescribe(url); + SessionDescriptionProtocol sessionDescriptionProtocol = describe.GetSessionDescriptionProtocol(); + + packetQueue = new Queue(); + RtspSetupResponse setup = rtspClient.GetSetup(url, destinationPort, multicastMode, destinationIp); + if (setup.RtspStatusCode == 404) + { + logger.Fatal("Your SAT>IP server doesn't have a tuner available that can talk to the requested frequency."); + return; + } + setup.OnRtcpPacket += Setup_OnRtcpPacket; + setup.OnRtpPacket += Setup_OnRtpPacket; + + if (dataStorage == null) + dataStorage = new InMemoryScraperStorage(); + if (objectStorage == null) + objectStorage = new FilesystemStorage(new DirectoryInfo(".")); if (!playoutMode) { context = new SkyscraperContext(new TsContext(), dataStorage, objectStorage); context.EnableTimeout = true; context.TimeoutSeconds = 60; context.InitalizeFilterChain(); - } - - RtspPlayResponse play = rtspClient.GetPlay(setup); - DateTime lastTimestamp = DateTime.Now; - bool initMessagePrinted = false; - - while (true) - { + } + + RtspPlayResponse play = rtspClient.GetPlay(setup); + DateTime lastTimestamp = DateTime.Now; + bool initMessagePrinted = false; + + while (true) + { if (playoutMode) { Thread.Sleep(1000); @@ -152,8 +165,8 @@ namespace skyscraper8 logger.InfoFormat("Began SAT>IP playout to port {0}", destinationPort); initMessagePrinted = true; } - } - else + } + else { if (packetQueue.Count >= 1) { @@ -181,135 +194,136 @@ namespace skyscraper8 { Keepalive(url); lastTimestamp = DateTime.Now; - } - } - } - - rtspClient.GetTeardown(setup); - rtspClient.Dispose(); - } - - private FileStream fs; - private uint stuffingBytes; - private Queue packetQueue; - private ObjectStorage objectStorage; - private DataStorage dataStorage; - private SkyscraperContext context; - private void Setup_OnRtpPacket(byte[] data, int length) - { - for (int i = 12; i < length; i += 1) - { - if (data[i] == 'G') - { - byte[] buffer = new byte[188]; - Array.Copy(data, i, buffer, 0, 188); - lock (packetQueue) - { - packetQueue.Enqueue(buffer); - } - - DumpPacket(buffer); - i += 187; - } - else if (data[i] == 0xff) - { - stuffingBytes++; - } - } - } - - private void DumpPacket(byte[] buffer) - { - if (!ENABLE_TS_WRITER) - return; - - if (fs == null) - { - string fname = String.Format("{0}.ts", DateTime.Now.Ticks); - fs = File.OpenWrite(fname); - } - - fs.Write(buffer, 0, buffer.Length); - } - + } + } + } + + rtspClient.GetTeardown(setup); + rtspClient.Dispose(); + } + + private FileStream fs; + private uint stuffingBytes; + private Queue packetQueue; + private ObjectStorage objectStorage; + private DataStorage dataStorage; + private SkyscraperContext context; + private void Setup_OnRtpPacket(byte[] data, int length) + { + for (int i = 12; i < length; i += 1) + { + if (data[i] == 'G') + { + byte[] buffer = new byte[188]; + Array.Copy(data, i, buffer, 0, 188); + lock (packetQueue) + { + packetQueue.Enqueue(buffer); + } + + DumpPacket(buffer); + i += 187; + } + else if (data[i] == 0xff) + { + stuffingBytes++; + } + } + } + + private void DumpPacket(byte[] buffer) + { + if (!ENABLE_TS_WRITER) + return; + + if (fs == null) + { + string fname = String.Format("{0}.ts", DateTime.Now.Ticks); + fs = File.OpenWrite(fname); + } + + fs.Write(buffer, 0, buffer.Length); + } + private int rtcps; private IPAddress destinationIp; private int destinationPort; private bool playoutMode; + private bool multicastMode; - private void Setup_OnRtcpPacket(byte[] data, int length) - { - //rtcps++; - } - - private DiSEqC_Opcode BuildDiseqcOpcode() - { - DiSEqC_Opcode opcode = DiSEqC_Opcode.DISEQC_HIGH_NIBBLE; - switch (diseqcNumber) - { - case 1: - opcode |= DiSEqC_Opcode.DISEQC_OPTION_A; - opcode |= DiSEqC_Opcode.DISEQC_POSITION_A; - break; - case 2: - opcode |= DiSEqC_Opcode.DISEQC_OPTION_A; - opcode |= DiSEqC_Opcode.DISEQC_POSITION_B; - break; - case 3: - opcode |= DiSEqC_Opcode.DISEQC_OPTION_B; - opcode |= DiSEqC_Opcode.DISEQC_POSITION_A; - break; - case 4: - opcode |= DiSEqC_Opcode.DISEQC_OPTION_B; - opcode |= DiSEqC_Opcode.DISEQC_POSITION_B; - break; - default: - throw new ArgumentOutOfRangeException("Your DiSEqC position should be a number between 1 and 4."); - } - - switch (polarity) - { - case 'H': - opcode |= DiSEqC_Opcode.DISEQC_HORIZONTAL; - break; - case 'V': - opcode |= DiSEqC_Opcode.DISEQC_VERTICAL; - break; - default: - throw new ArgumentException("The polarity should be H or V."); - } - - return opcode; - } - - private bool ParseDvbStandard(string standard) - { - standard = standard.ToUpperInvariant(); - if (standard.StartsWith("DVB")) - standard = standard.Substring(3); - if (standard.StartsWith("-")) - standard = standard.Substring(1); - - switch (standard) - { - case "S": - return false; - case "S2": - return true; - case "S2X": - return true; - default: - throw new ArgumentException(String.Format("I have no idea what kind of Standard {0} is supposed to be.", standard)); - } - } - - private void Keepalive(string url = "/") - { - RtspOptionsResponse options = rtspClient.GetOptions("/"); - if (options.RtspStatusCode != 200) - { - throw new RtspException(String.Format("Unexpected RTSP Status code. Wanted {0}, got {1}", 200, options.RtspStatusCode)); - } - } - } -} + private void Setup_OnRtcpPacket(byte[] data, int length) + { + //rtcps++; + } + + private DiSEqC_Opcode BuildDiseqcOpcode() + { + DiSEqC_Opcode opcode = DiSEqC_Opcode.DISEQC_HIGH_NIBBLE; + switch (diseqcNumber) + { + case 1: + opcode |= DiSEqC_Opcode.DISEQC_OPTION_A; + opcode |= DiSEqC_Opcode.DISEQC_POSITION_A; + break; + case 2: + opcode |= DiSEqC_Opcode.DISEQC_OPTION_A; + opcode |= DiSEqC_Opcode.DISEQC_POSITION_B; + break; + case 3: + opcode |= DiSEqC_Opcode.DISEQC_OPTION_B; + opcode |= DiSEqC_Opcode.DISEQC_POSITION_A; + break; + case 4: + opcode |= DiSEqC_Opcode.DISEQC_OPTION_B; + opcode |= DiSEqC_Opcode.DISEQC_POSITION_B; + break; + default: + throw new ArgumentOutOfRangeException("Your DiSEqC position should be a number between 1 and 4."); + } + + switch (polarity) + { + case 'H': + opcode |= DiSEqC_Opcode.DISEQC_HORIZONTAL; + break; + case 'V': + opcode |= DiSEqC_Opcode.DISEQC_VERTICAL; + break; + default: + throw new ArgumentException("The polarity should be H or V."); + } + + return opcode; + } + + private bool ParseDvbStandard(string standard) + { + standard = standard.ToUpperInvariant(); + if (standard.StartsWith("DVB")) + standard = standard.Substring(3); + if (standard.StartsWith("-")) + standard = standard.Substring(1); + + switch (standard) + { + case "S": + return false; + case "S2": + return true; + case "S2X": + return true; + default: + throw new ArgumentException(String.Format("I have no idea what kind of Standard {0} is supposed to be.", standard)); + } + } + + private void Keepalive(string url = "/") + { + RtspOptionsResponse options = rtspClient.GetOptions("/"); + if (options.RtspStatusCode != 200) + { + throw new RtspException(String.Format("Unexpected RTSP Status code. Wanted {0}, got {1}", 200, options.RtspStatusCode)); + } + } + } +} diff --git a/skyscraper8/SatIp/RtspClient.cs b/skyscraper8/SatIp/RtspClient.cs index 56335ba..6a6891c 100644 --- a/skyscraper8/SatIp/RtspClient.cs +++ b/skyscraper8/SatIp/RtspClient.cs @@ -99,7 +99,7 @@ namespace skyscraper8.SatIp return result; } - public RtspSetupResponse GetSetup(string url, int destinationPort = 0) + public RtspSetupResponse GetSetup(string url, int destinationPort = 0, bool multicastMode = false, IPAddress multicastIp = null) { RtspSetupRequest request = new RtspSetupRequest(); request.RequestPath = url; @@ -123,7 +123,14 @@ namespace skyscraper8.SatIp rtcpSocket.Bind(new IPEndPoint(ListenIp, 0)); int rtcpPort = GetPortFromEndPoint(rtcpSocket.LocalEndPoint); - request.SetRtpAvpUnicast(rtpPort, rtcpPort); + if (multicastMode && multicastIp != null) + { + request.SetRtpAvpMulticast(multicastIp, rtpPort, rtcpPort); + } + else + { + request.SetRtpAvpUnicast(rtpPort, rtcpPort); + } RtspResponseHeader response = GetResponse(request.ListHeaders(RootPath)); RtspSetupResponse setupResponse = new RtspSetupResponse(response); diff --git a/skyscraper8/SatIp/RtspRequests/RtspSetupRequest.cs b/skyscraper8/SatIp/RtspRequests/RtspSetupRequest.cs index cb582bb..a6787da 100644 --- a/skyscraper8/SatIp/RtspRequests/RtspSetupRequest.cs +++ b/skyscraper8/SatIp/RtspRequests/RtspSetupRequest.cs @@ -1,57 +1,63 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace skyscraper8.SatIp.RtspRequests -{ - internal class RtspSetupRequest : RtspRequest - { - public RtspSetupRequest() : base("SETUP") - { - } - - public uint CSeq - { - set - { - base.args["CSeq"] = Convert.ToString(value); - } - get - { - return uint.Parse(base.args["CSeq"]); - } - } - - public string UserAgent - { - set - { - base.args["User-Agent"] = value; - } - get - { - return base.args["User-Agent"]; - } - } - - public string Transport - { - set - { - base.args["Transport"] = value; - } - get - { - return base.args["Transport"]; - } - } - - public void SetRtpAvpUnicast(int rtpPort, int rtcpPort) - { - Transport = String.Format("RTP/AVP;unicast;client_port={0}-{1}", rtpPort, rtcpPort); - } - } - -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.SatIp.RtspRequests +{ + internal class RtspSetupRequest : RtspRequest + { + public RtspSetupRequest() : base("SETUP") + { + } + + public uint CSeq + { + set + { + base.args["CSeq"] = Convert.ToString(value); + } + get + { + return uint.Parse(base.args["CSeq"]); + } + } + + public string UserAgent + { + set + { + base.args["User-Agent"] = value; + } + get + { + return base.args["User-Agent"]; + } + } + + public string Transport + { + set + { + base.args["Transport"] = value; + } + get + { + return base.args["Transport"]; + } + } + + public void SetRtpAvpUnicast(int rtpPort, int rtcpPort) + { + Transport = String.Format("RTP/AVP;unicast;client_port={0}-{1}", rtpPort, rtcpPort); + } + + public void SetRtpAvpMulticast(IPAddress targetIp, int rtpPort, int rtcpPort) + { + Transport = String.Format("RTP/AVP;multicast;destination={2};port={0}-{1}", rtpPort, rtcpPort, targetIp.ToString()); + } + } + +} diff --git a/skyscraper8/Skyscraper/IO/TunerInterface/RemoteStreamReaderTunerFactory.cs b/skyscraper8/Skyscraper/IO/TunerInterface/RemoteStreamReaderTunerFactory.cs index 6fdb6fa..fdcbe6a 100644 --- a/skyscraper8/Skyscraper/IO/TunerInterface/RemoteStreamReaderTunerFactory.cs +++ b/skyscraper8/Skyscraper/IO/TunerInterface/RemoteStreamReaderTunerFactory.cs @@ -6,7 +6,7 @@ namespace skyscraper5.Skyscraper.IO.TunerInterface { [SkyscraperPlugin] [TunerFactoryId(2,"skyscraper5 Remote Stream Reader")] - internal class RemoteStreamReaderTunerFactory : ITunerFactory + public class RemoteStreamReaderTunerFactory : ITunerFactory { public string Hostname { get; set; } diff --git a/skyscraper8/Skyscraper/TsRotationToCsv.cs b/skyscraper8/Skyscraper/TsRotationToCsv.cs new file mode 100644 index 0000000..4040a7c --- /dev/null +++ b/skyscraper8/Skyscraper/TsRotationToCsv.cs @@ -0,0 +1,112 @@ +using log4net; +using log4net.Repository.Hierarchy; +using skyscraper5.Docsis.MacManagement; +using skyscraper5.Skyscraper; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Skyscraper +{ + internal class TsRotationToCsv + { + public DirectoryInfo SourceDir { get; set; } + public FileInfo DestinationCsv { get; set; } + + private List files; + private ILog logger; + public void Run() + { + logger = LogManager.GetLogger(typeof(TsRotationToCsv)); + files = new List(); + ScrapeDirectory(SourceDir); + files.Sort(new FileInfoComparerByDate(logger)); + DumpCsv(); + } + + private void DumpCsv() + { + StreamWriter sw = new StreamWriter(DestinationCsv.FullName); + foreach (FileInfo file in files) + { + sw.WriteLine(String.Format("\"{0}\";{1};{2}", file.FullName, file.Length, file.LastWriteTime)); + } + sw.Flush(); + sw.Close(); + } + + private void ScrapeDirectory(DirectoryInfo di) + { + try + { + foreach (FileSystemInfo fsi in di.GetFileSystemInfos()) + { + switch (fsi) + { + case FileInfo fi: + if (fi.Extension.ToLowerInvariant().Equals(".ts")) + { + files.Add(fi); + if (files.Count % 100 == 0) + logger.InfoFormat("Listed {0} files.", files.Count); + } + break; + case DirectoryInfo subdirectory: + ScrapeDirectory(subdirectory); + break; + default: + throw new NotImplementedException(di.GetType().Name); + } + } + } + catch (Exception e) + { + logger.WarnFormat(e.Message); + } + } + + private class FileInfoComparerByDate : Comparer + { + private ILog logger; + private int ups, downs, stands; + + public FileInfoComparerByDate(ILog logger) + { + this.logger = logger; + } + + public override int Compare(FileInfo? x, FileInfo? y) + { + long xTime = x.LastWriteTime.ToUnixTime(); + long yTime = y.LastWriteTime.ToUnixTime(); + + int ops; + int v = xTime.CompareTo(yTime); + switch(v) + { + case -1: + ups++; + ops = ups; + break; + case 0: + stands++; + ops = stands; + break; + case 1: + downs++; + ops = downs; + break; + default: + throw new NotImplementedException(v.ToString()); + } + if (ops % 1000 == 0) + { + logger.InfoFormat("Sort progress: {0} up, {1} down, {2} stand.", ups, downs, stands); + } + return v; + } + } + } +} From f24d7ab78fd6d63fd5acf9e0bf9b7b77dc052634 Mon Sep 17 00:00:00 2001 From: Fey Date: Tue, 7 Apr 2026 22:16:49 +0200 Subject: [PATCH 3/4] Updated gitignore to not include the SAT>IP test build. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 585b9be..9c16ee6 100644 --- a/.gitignore +++ b/.gitignore @@ -134,3 +134,4 @@ imgui.ini /Documentation/TSDuck-Samples/experiment2/*.ts /.vs/skyscraper8/CopilotIndices/17.14.1431.25910 /.vs +/skyscraper8/bin/Debug/satip From 695ca5e69f47b570c83b1cc8e38acf8751af38ea Mon Sep 17 00:00:00 2001 From: Fey Date: Sat, 11 Apr 2026 16:36:52 +0200 Subject: [PATCH 4/4] Began moving the remnants of the blindscanning stuff into Voile. --- skyscraper8/Passing.cs | 293 ------------------ .../Skyscraper/Equipment/BaseEquipment.cs | 20 -- skyscraper8/Skyscraper/Equipment/Dish.cs | 57 ---- .../Equipment/EquipmentCollection.cs | 20 -- .../Equipment/EquipmentUtilities.cs | 57 ---- skyscraper8/Skyscraper/Equipment/LNB.cs | 59 ---- .../Equipment/SatellitePositionEntity.cs | 108 ------- .../BaseBlindscanJob.cs | 68 ++-- .../BlindscanJobConfiguration.cs | 27 +- .../FrequencyListGenerator/DbBlindscanJob.cs | 28 +- .../RemoteStreamReaderClient.cs | 5 +- .../Scraper/ISkyscraperUiJunction.cs | 3 +- .../Skyscraper/Scraper/Storage/DataStorage.cs | 12 - .../Storage/Filesystem/FilesystemStorage.cs | 133 +------- .../InMemory/InMemoryScraperStorage.cs | 56 ---- 15 files changed, 86 insertions(+), 860 deletions(-) delete mode 100644 skyscraper8/Passing.cs delete mode 100644 skyscraper8/Skyscraper/Equipment/BaseEquipment.cs delete mode 100644 skyscraper8/Skyscraper/Equipment/Dish.cs delete mode 100644 skyscraper8/Skyscraper/Equipment/EquipmentCollection.cs delete mode 100644 skyscraper8/Skyscraper/Equipment/EquipmentUtilities.cs delete mode 100644 skyscraper8/Skyscraper/Equipment/LNB.cs delete mode 100644 skyscraper8/Skyscraper/Equipment/SatellitePositionEntity.cs diff --git a/skyscraper8/Passing.cs b/skyscraper8/Passing.cs deleted file mode 100644 index b3eb855..0000000 --- a/skyscraper8/Passing.cs +++ /dev/null @@ -1,293 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Net.NetworkInformation; -using System.Reflection; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using log4net; -using skyscraper5.Dvb.Psi.Model; -using skyscraper5.Mpeg2; -using skyscraper5.Skyscraper; -using skyscraper5.Skyscraper.Headless; -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 skyscraper8.Skyscraper.Scraper.Storage; - -namespace skyscraper5 -{ - public class Passing - { - public DataStorage DataStorage { get; set; } - public ObjectStorage ObjectStorage { get; set; } - private IStreamReader streamReader; - private List tuners; - private List satellitePositions; - private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); - - public Passing() - { - - } - - public bool Boot() - { - - Ini ini = PluginManager.GetInstance().Ini; - - StorageConnectionManager connectionManager = StorageConnectionManager.GetInstance(); - - IEnumerable> allKnownFactoryNames = connectionManager.GetAllKnownFactoryNames(); - foreach (Tuple knownFactoryName in allKnownFactoryNames) - { - logger.InfoFormat("Found {0} Storage Factory #{1}, {2}",knownFactoryName.Item2 ? "Data" : "Object",knownFactoryName.Item1,knownFactoryName.Item3); - } - - logger.Debug("Acquiring Default Data Storage..."); - DataStorageFactory dataStorageFactory = connectionManager.GetDefaultDataStorageFactory(); - logger.Debug("Acquiring Default Object Storage..."); - ObjectStorageFactory objectStorageFactory = connectionManager.GetDefaultObjectStorageFactory(); - logger.Debug("Acquiring Data Storage..."); - DataStorage = dataStorageFactory.CreateDataStorage(); - if (DataStorage == null) - { - logger.FatalFormat("The data storage factory didn't create a data storage."); - return false; - } - - bool isEquivalent = objectStorageFactory.IsEquivalent(dataStorageFactory); - if (isEquivalent) - { - logger.Debug("Using the Data Storage as Object Storage."); - ObjectStorage = (ObjectStorage)DataStorage; - } - else - { - logger.Debug("Acquiring Object Storage..."); - ObjectStorage = objectStorageFactory.CreateObjectStorage(); - if (ObjectStorage == null) - { - logger.FatalFormat("The object storage factory didn't create an object storage."); - return false; - } - } - - TunerFactoryConnectionManager tunerFactoryConnectionManager = TunerFactoryConnectionManager.GetInstance(); - ReadOnlyCollection> tunerFactories = tunerFactoryConnectionManager.GetKnownFactories(); - int tunerFactory = ini.ReadValue("startup", "tunerFactory", 0); - KeyValuePair bootingTuner = tunerFactories.First(x => x.Key.Id == tunerFactory); - if (bootingTuner.Value == null) - { - Console.WriteLine("The tuner factory #{0} didn't load.", tunerFactory); - return false; - } - - TunerFactoryConnectionManager.ConfigureFactoryFromIni(bootingTuner, ini); - - streamReader = bootingTuner.Value.CreateStreamReader(); - if (streamReader == null) - { - Console.WriteLine("The tuner factory #{0} didn't create a stream reader."); - return false; - } - - try - { - streamReader.CheckForDVB(); - } - catch (BadImageFormatException e) - { - Console.WriteLine("The configured tuner factory is not suitable for the current processor architecture. Tuning won't work, therefore functionality will be severely limited. Please configure a Tuner Factory Class suitable for this processor architecture in order to get the best experience. If you need to run crazycat69's StreamReader.dll on 64-bit machines, try RemoteStreamReader."); - streamReader = new NullTunerFactory().CreateStreamReader(); - } - - List foundTuners = new List(); - bool checkForDvbExEx = streamReader.CheckForDVBExEx((index, name, type) => - { - TunerMetadata tuner = new TunerMetadata(index, name, type); - foundTuners.Add(tuner); - }); - - foreach (TunerMetadata foundTuner in foundTuners) - { - streamReader.StopDVB(); - - bool startDvbEx = streamReader.StartDvbEx(foundTuner.Index); - if (!startDvbEx) - { - Console.WriteLine("Failed to start {0}", foundTuner.Name); - Thread.Sleep(1000); - continue; - } - - foundTuner.Caps = streamReader.GetCaps(); - - byte[] macBuffer = new byte[6]; - bool mac = streamReader.GetMAC(macBuffer); - if (!mac) - { - Console.WriteLine("Failed to read MAC Address of {0}", foundTuner.Name); - Thread.Sleep(1000); - } - else - { - foundTuner.MacAddress = new PhysicalAddress(macBuffer); - } - - bool stopDvb = streamReader.StopDVB(); - if (!stopDvb) - { - Console.WriteLine("Failed to stop {0}", foundTuner.Name); - Thread.Sleep(1000); - continue; - } -; - if (DataStorage.UiTunerTestFor(foundTuner)) - { - DataStorage.UiTunerGetConfiguration(foundTuner); - } - - if (tuners == null) - tuners = new List(); - tuners.Add(foundTuner); - } - - satellitePositions = DataStorage.UiSatellitesListAll(); - - return true; - } - - private HeadlessJob GetNextJob() - { - HeadlessJob headlessJob = DataStorage.GetQueuedJob(); - if (headlessJob != null) - { - return headlessJob; - } - - return new HeadlessJob(HeadlessJobType.BlindscanEverything); - } - - public void Run() - { - while (true) - { - HeadlessJob headlessJob = GetNextJob(); - Run(headlessJob); - if (!headlessJob.isSynthetic) - { - DataStorage.SetQueuedJobComplete(headlessJob); - } - } - } - - private void Run(HeadlessJob job) - { - switch (job.jobType) - { - case HeadlessJobType.Sleep: - Thread.Sleep(job.iArg1); - break; - case HeadlessJobType.MassImport: - DirectoryInfo di = new DirectoryInfo(job.sArg1); - MassImportDirectory(di); - break; - case HeadlessJobType.BlindscanEverything: - PerformBlindscanEverything(); - break; - case HeadlessJobType.ReimportByTag1: - ReimportTag(job.iArg1); - break; - default: - throw new NotImplementedException(job.jobType.ToString()); - } - } - - private void PerformBlindscanEverything() - { - if (tuners == null) - tuners = new List(); - if (tuners.Count == 0) - throw new ApplicationException("I'd need to blindscan everything, but I don't have any tuners I could use!"); - - throw new NotImplementedException(nameof(PerformBlindscanEverything)); - } - - private void ReimportTag(int tag1) - { - IReadOnlyList queue = DataStorage.ListImportFileByTag1(tag1); - foreach(string filename in queue) - { - FileInfo fi = new FileInfo(filename); - if (!fi.Exists) - continue; - ScrapeStream(fi); - } - } - - public void MassImportDirectory(DirectoryInfo sourceDir) - { - foreach (FileSystemInfo fileSystemInfo in sourceDir.GetFileSystemInfos()) - { - DirectoryInfo di = fileSystemInfo as DirectoryInfo; - FileInfo fi = fileSystemInfo as FileInfo; - if (di != null) - { - MassImportDirectory(di); - } - else if (fi != null) - { - if (fi.Length == 0) - continue; - - if (!fi.Extension.ToLowerInvariant().Equals(".ts")) - continue; - - if (DataStorage.ImportFileKnown(fi)) - continue; - - FileStream fileStream = fi.OpenRead(); - Stopwatch stopwatch = Stopwatch.StartNew(); - int tstype; - ScrapeStream(fileStream,true, out tstype); - stopwatch.Stop(); - Console.WriteLine("Importing {0} took {1}",fi.Name, stopwatch.Elapsed); - DataStorage.WaitForCompletion(); - DataStorage.ImportMarkFileAsKnown(fi, stopwatch.Elapsed, tstype); - fileStream.Close(); - } - else - { - throw new NotImplementedException(fileSystemInfo.GetType().ToString()); - } - } - } - - private void ScrapeStream(FileInfo fi) - { - FileStream fileStream = fi.OpenRead(); - ScrapeStream(fileStream, true, out _); - fileStream.Close(); - fileStream.Dispose(); - } - - private void ScrapeStream(Stream inStream, bool disk, out int tstype) - { - SkyscraperContext skyscraperContext = new SkyscraperContext(new TsContext(), DataStorage,ObjectStorage); - skyscraperContext.SourceIsDisk = disk; - skyscraperContext.InitalizeFilterChain(); - skyscraperContext.IngestFromStream(inStream); - skyscraperContext.Dispose(); - tstype = skyscraperContext.SpecialTsType; - } - } -} diff --git a/skyscraper8/Skyscraper/Equipment/BaseEquipment.cs b/skyscraper8/Skyscraper/Equipment/BaseEquipment.cs deleted file mode 100644 index 566f850..0000000 --- a/skyscraper8/Skyscraper/Equipment/BaseEquipment.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Xml.Serialization; - -namespace skyscraper5.Skyscraper.Equipment -{ - public class BaseEquipment - { - [XmlIgnore] - public int Id { get; set; } - - [XmlAttribute] - public string Manufacturer { get; set; } - - [XmlAttribute] - public string Name { get; set; } - - [XmlIgnore] - public DateTime DateAdded { get; set; } - } -} diff --git a/skyscraper8/Skyscraper/Equipment/Dish.cs b/skyscraper8/Skyscraper/Equipment/Dish.cs deleted file mode 100644 index 35a558e..0000000 --- a/skyscraper8/Skyscraper/Equipment/Dish.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Xml.Serialization; - -namespace skyscraper5.Skyscraper.Equipment -{ - public class DishEntity : BaseEquipment - { - public DishEntity(string manufac, string name, int diameter, DishShape shape) - { - this.Manufacturer = manufac; - this.Name = name; - this.Diameter = diameter; - this.Shape = shape; - } - - public DishEntity() - { - } - - [XmlAttribute] - public int Diameter { get; set; } - - [XmlAttribute] - public DishShape Shape { get; set; } - - protected bool Equals(DishEntity other) - { - return Diameter == other.Diameter && Shape == other.Shape; - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((DishEntity)obj); - } - - public override int GetHashCode() - { - return HashCode.Combine(Diameter, (int)Shape); - } - - public override string ToString() - { - return this.Name; - } - } - - public enum DishShape : int - { - Offset, - PrimeFocus, - Mesh, - Other - } -} diff --git a/skyscraper8/Skyscraper/Equipment/EquipmentCollection.cs b/skyscraper8/Skyscraper/Equipment/EquipmentCollection.cs deleted file mode 100644 index 01f467b..0000000 --- a/skyscraper8/Skyscraper/Equipment/EquipmentCollection.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace skyscraper5.Skyscraper.Equipment; - -public class EquipmentCollection -{ - public EquipmentCollection() - { - Dishes = new List(); - LNBs = new List(); - SatellitePositions = new List(); - } - - public List Dishes { get; set; } - public List LNBs { get; set; } - public List SatellitePositions { get; set; } - - public override string ToString() - { - return String.Format("{0} dishes, {1} LNBs, {2} satellite positions", Dishes.Count, LNBs.Count, SatellitePositions.Count); - } -} diff --git a/skyscraper8/Skyscraper/Equipment/EquipmentUtilities.cs b/skyscraper8/Skyscraper/Equipment/EquipmentUtilities.cs deleted file mode 100644 index f76f107..0000000 --- a/skyscraper8/Skyscraper/Equipment/EquipmentUtilities.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Collections.Generic; -using skyscraper5.Skyscraper.Scraper.Storage; -using skyscraper8.Skyscraper.Scraper.Storage; - -namespace skyscraper5.Skyscraper.Equipment -{ - public static class EquipmentUtilities - { - public static void InsertDefaultLnbTypes(DataStorage storage) - { - List knownLnbTypes = storage.UiLnbTypesListAll(); - foreach (LnbEntity defaultLnbType in GetDefaultLnbTypes()) - { - if (!knownLnbTypes.Contains(defaultLnbType)) - storage.UiLnbTypesAdd(defaultLnbType); - } - } - - private static IEnumerable GetDefaultLnbTypes() - { - LnbEntity lnbType = new LnbEntity(); - lnbType.Lof1 = 9750; - lnbType.Lof2 = 10600; - lnbType.LofSw = 11700; - lnbType.MinimumFrequency = 10700; - lnbType.MaximumFrequency = 12750; - lnbType.Manufacturer = "Generic"; - lnbType.Name = "Universal LNB"; - yield return lnbType; - } - - public static void InsertDefaultDishTypes(DataStorage storage) - { - List knownDishTypes = storage.UiDishTypesListAll(); - foreach (DishEntity defaultDishType in GetDefaultDishTypes()) - { - if (!knownDishTypes.Contains(defaultDishType)) - storage.UiDishTypesAdd(defaultDishType); - } - } - - private static IEnumerable GetDefaultDishTypes() - { - int[] commonSizes = new int[] { 60, 80, 85, 100 }; - foreach (int commonSize in commonSizes) - { - DishEntity dishType = new DishEntity(); - dishType.Diameter = commonSize; - dishType.Shape = DishShape.Offset; - dishType.Manufacturer = "Generic"; - dishType.Name = String.Format("{0} cm Offset dish antenna", commonSize); - yield return dishType; - } - } - } -} diff --git a/skyscraper8/Skyscraper/Equipment/LNB.cs b/skyscraper8/Skyscraper/Equipment/LNB.cs deleted file mode 100644 index 9200aef..0000000 --- a/skyscraper8/Skyscraper/Equipment/LNB.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Xml.Serialization; - -namespace skyscraper5.Skyscraper.Equipment -{ - public class LnbEntity : BaseEquipment - { - public LnbEntity() { } - - public LnbEntity(string manufac, string name, int lof1, int lof2, int lofSw, int minFreq, int maxFreq) - { - this.Manufacturer = manufac; - this.Name = name; - this.Lof1 = lof1; - this.Lof2 = lof2; - this.LofSw = lofSw; - this.MinimumFrequency = minFreq; - this.MaximumFrequency = maxFreq; - } - - [XmlAttribute] - public int Lof1 { get; set; } - - [XmlAttribute] - public int Lof2 { get; set; } - - [XmlAttribute] - public int LofSw { get; set; } - - [XmlAttribute] - public int MinimumFrequency { get; set; } - - [XmlAttribute] - public int MaximumFrequency { get; set; } - - protected bool Equals(LnbEntity other) - { - return Lof1 == other.Lof1 && Lof2 == other.Lof2 && LofSw == other.LofSw && MinimumFrequency == other.MinimumFrequency && MaximumFrequency == other.MaximumFrequency; - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((LnbEntity)obj); - } - - public override int GetHashCode() - { - return HashCode.Combine(Lof1, Lof2, LofSw, MinimumFrequency, MaximumFrequency); - } - - public override string ToString() - { - return String.Format("{0} {1}", Manufacturer, Name); - } - } -} diff --git a/skyscraper8/Skyscraper/Equipment/SatellitePositionEntity.cs b/skyscraper8/Skyscraper/Equipment/SatellitePositionEntity.cs deleted file mode 100644 index c517183..0000000 --- a/skyscraper8/Skyscraper/Equipment/SatellitePositionEntity.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace skyscraper5.Skyscraper -{ - public class SatellitePositionEntity - { - public SatellitePositionEntity() - { - } - - public SatellitePositionEntity(float angle, string name) - { - this.angle = angle; - this.name = name; - } - - public float angle; - public string name; - - public int Checksum => GetChecksum(angle); - - public static int GetChecksum(float angle) - { - int result = (int)(angle * 10.0f); - return result; - } - - public override string ToString() - { - if (angle > 0) - { - return String.Format("{0}°E {1}", angle, name); - } - else - { - float tmpAngle = angle; - tmpAngle *= -1; - return String.Format("{0}°W {1}", tmpAngle, name); - } - } - - public static SatellitePositionEntity FromChecksum(int checksum) - { - float newAngle = checksum; - newAngle /= 10.0f; - return new SatellitePositionEntity(newAngle, "???"); - } - - protected bool Equals(SatellitePositionEntity other) - { - return angle.Equals(other.angle); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((SatellitePositionEntity)obj); - } - - public override int GetHashCode() - { - return HashCode.Combine(angle); - } - - - /// - /// Returns an integer value for the cardinal direction. - /// - /// Returns 0 for east, 1 for west, 2 if satellite is at 0.0 - public int GetCardinalDirectionAsInt() - { - if (angle > 0) - return 0; - else if (angle < 0) - return 1; - else - return 2; - } - - /// - /// Get the letter matching the cardinal direction of the satellite. - /// - /// Returns either 'E' or 'W' depending on the angle. - public char GetCardinalDirectionAsChar() - { - int cardinalDirectionAsInt = GetCardinalDirectionAsInt(); - return cardinalDirectionAsInt == 0 ? 'E' : 'W'; - } - - /// - /// Get a filename-safe number of the angle. Meaning the angle stripped of its sign and decimal separator. - /// - /// For example: For 19.2°E, this will return 192, For 34.5°W, this will return 345 - public int GetCleanAngle() - { - int cleanAngle = (int)(angle * 10.0f); - if (cleanAngle < 0) - cleanAngle /= -1; - return cleanAngle; - } - } -} diff --git a/skyscraper8/Skyscraper/FrequencyListGenerator/BaseBlindscanJob.cs b/skyscraper8/Skyscraper/FrequencyListGenerator/BaseBlindscanJob.cs index 55ace83..5f3d20d 100644 --- a/skyscraper8/Skyscraper/FrequencyListGenerator/BaseBlindscanJob.cs +++ b/skyscraper8/Skyscraper/FrequencyListGenerator/BaseBlindscanJob.cs @@ -13,7 +13,6 @@ 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 { @@ -94,12 +93,12 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator 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 lof1 = config.Lof1 * 1000; + int lof2 = config.Lof2 * 1000; + int lofSw = config.LofSw * 1000; int diseqc = config.TunerMetadata.DiseqcType; - int startFreq = config.LnbType.MinimumFrequency * 1000; - int endFreq = config.LnbType.MaximumFrequency * 1000; + int startFreq = config.MinimumFrequency * 1000; + int endFreq = config.MaximumFrequency * 1000; bool anythingSuceeded = false; nint allocHGlobal = Marshal.AllocHGlobal(ushort.MaxValue); @@ -395,15 +394,15 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator foundFrequencies.Add(blindscanSearchResult); } config.DataStorage.InsertSearchResult(jobInDb, true, searchResult, polarityIndex, new SearchResult2()); - config.Ui.OnBlindscanSearchResult1Callback(blindscanSearchResult, polarityIndex, config.LnbType.MinimumFrequency, config.LnbType.MaximumFrequency); + config.Ui.OnBlindscanSearchResult1Callback(blindscanSearchResult, polarityIndex, config.MinimumFrequency, config.MaximumFrequency); } public void RunScrape() { - int lof1 = config.LnbType.Lof1 * 1000; - int lof2 = config.LnbType.Lof2 * 1000; - int lofSw = config.LnbType.LofSw * 1000; + int lof1 = config.Lof1 * 1000; + int lof2 = config.Lof2 * 1000; + int lofSw = config.LofSw * 1000; foreach (BlindscanSearchResult blindscanResult in foundFrequencies) @@ -412,7 +411,7 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator blindscanResult.State = BlindscanResultState.Tuning; config.DataStorage.UpdateTransponderState(jobInDb, blindscanResult.IsSatellite(), blindscanResult.SearchResult, blindscanResult.State, blindscanResult.SearchResult2); - config.Ui.OnBlindscanBeforeSetChannel(blindscanResult, config.LnbType); + config.Ui.OnBlindscanBeforeSetChannel(blindscanResult); bool channel = config.StreamReader.SetChannel(blindscanResult.SearchResult.Freq, blindscanResult.SearchResult.SR, blindscanResult.SearchResult.Pol, blindscanResult.SearchResult.FEC, lof1, lof2, lofSw); if (!channel) { @@ -445,11 +444,11 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator 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; + int lof1 = config.Lof1 * 1000; + int lof2 = config.Lof2 * 1000; + int lofSw = config.LofSw * 1000; + int startFreq = config.MinimumFrequency * 1000; + int endFreq = config.MaximumFrequency * 1000; RfSpectrumData spectrumData = RfSpectrumData.Create(); @@ -574,14 +573,14 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator { int polarity = result.SearchResult.Pol; int freq = result.SearchResult.Freq; - bool isHighBand = freq > config.LnbType.LofSw * 1000; + bool isHighBand = freq > config.LofSw * 1000; bool isHorizontal = polarity == 0; SendDiseqcCommand(isHighBand, isHorizontal); 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, + config.Lof1 * 1000, config.Lof2 * 1000, + config.LofSw * 1000, 1000000, (STD_TYPE)result.SearchResult.StdType, ref satelliteSr)) { //No blindscan? No problem! Try anyway! @@ -600,7 +599,7 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator Thread.Sleep(1000); result.State = BlindscanResultState.Retrying; logger.Log(PluginLogLevel.Info, string.Format("Retrying BLScanEx... ({0}/{1})", i + 1, attempts + 1), 8); - bool retryResult = 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); + bool retryResult = config.StreamReader.BLScanEx(result.SearchResult.Freq, 5000, result.SearchResult.Pol, config.Lof1 * 1000, config.Lof2 * 1000, config.LofSw * 1000, 1000000, (STD_TYPE)result.SearchResult.StdType,ref satelliteSr); if (!retryResult) { result.State = BlindscanResultState.BlScanFailure; @@ -676,7 +675,7 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator if (plot != null) { result.State = BlindscanResultState.IqSaving; - config.ObjectStorage.StoreIqGraph(jobInDb.JobGuid, result.GetFrequency(), result.GetPolarity(config.LnbType.LofSw), plot); + config.ObjectStorage.StoreIqGraph(jobInDb.JobGuid, result.GetFrequency(), result.GetPolarity(config.LofSw), plot); } } @@ -707,22 +706,19 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator if (tsRecorder.PrepareRecording()) { DateTime now = DateTime.Now; - - int cardinalDirection = 0; - int angle = config.SatellitePosition.Checksum; - if (angle < 0) - { - angle *= -1; - cardinalDirection = 1; - } - + 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, - config.SatellitePosition.GetCleanAngle(), - config.SatellitePosition.GetCardinalDirectionAsChar()); - tsRecorder.SetNextFilename(recordingFilename); + "skyscraper_{0:D4}{1:D2}{2:D2}_{3:D2}{4:D2}_{8}_{5}_{6}_{7}.ts", + now.Year, //0 + now.Month, //1 + now.Day, //2 + now.Hour, //3 + now.Minute, //4 + result.GetFrequency() / 1000, //5 + result.GetPolarity(config.LofSw), //6 + result.GetSymbolRate() / 1000, //7 + config.GetFiveLetterSattelitePosition()); //8 + tsRecorder.SetNextFilename(recordingFilename); tsRecorder.CreateBufferedStream(); } } diff --git a/skyscraper8/Skyscraper/FrequencyListGenerator/BlindscanJobConfiguration.cs b/skyscraper8/Skyscraper/FrequencyListGenerator/BlindscanJobConfiguration.cs index 0588476..63ebd8b 100644 --- a/skyscraper8/Skyscraper/FrequencyListGenerator/BlindscanJobConfiguration.cs +++ b/skyscraper8/Skyscraper/FrequencyListGenerator/BlindscanJobConfiguration.cs @@ -4,7 +4,6 @@ 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; @@ -18,7 +17,7 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator public TunerMetadata TunerMetadata { get; set; } public int DiseqcIndex { get; set; } public IGpsReceiver Gps { get; set; } - public SatellitePositionEntity SatellitePosition { get; set; } + public double SatellitePosition { get; set; } public bool DoHorizontalHigh { get; set; } public bool DoHorizontalLow { get; set; } @@ -29,9 +28,27 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator public ObjectStorage ObjectStorage { get; set; } public ISkyscraperUiJunction Ui { get; set; } public bool DoCollectRfSpectrum { get; set; } - public LnbEntity LnbType { get; set; } public bool DoCollectIqGraphs { get; set; } public bool DoRecordTs { get; set; } - public Ini Ini { get; set; } - } + public Ini Ini { get; set; } + public int Lof1 { get; internal set; } + public int Lof2 { get; internal set; } + public int LofSw { get; internal set; } + public int MinimumFrequency { get; internal set; } + public int MaximumFrequency { get; internal set; } + + internal string GetFiveLetterSattelitePosition() + { + if (SatellitePosition >= 0) + { + return String.Format("{0:D4}E", (int)(SatellitePosition * 10)); + } + else + { + int westerner = (int)(SatellitePosition * 10); + westerner /= -1; + return String.Format("{0:D4}W", westerner); + } + } + } } diff --git a/skyscraper8/Skyscraper/FrequencyListGenerator/DbBlindscanJob.cs b/skyscraper8/Skyscraper/FrequencyListGenerator/DbBlindscanJob.cs index 26353fe..44fa95d 100644 --- a/skyscraper8/Skyscraper/FrequencyListGenerator/DbBlindscanJob.cs +++ b/skyscraper8/Skyscraper/FrequencyListGenerator/DbBlindscanJob.cs @@ -15,7 +15,7 @@ namespace skyscraper5.src.Skyscraper.FrequencyListGenerator public class DbBlindscanJob { public DbBlindscanJob(Guid jobGuid, PhysicalAddress tunerMac, STD_TYPE tunerStandard, int diseqCIndex, - IGpsReceiver jobContextGps, SatellitePositionEntity satellitePosition) + IGpsReceiver jobContextGps, double satellitePosition) { this.JobGuid = jobGuid; this.TunerMAC = tunerMac; @@ -37,7 +37,7 @@ namespace skyscraper5.src.Skyscraper.FrequencyListGenerator } - public SatellitePositionEntity SatPosition { get; private set; } + public double SatPosition { get; private set; } public GpsCoordinate? GpsCoordinate { get; private set; } @@ -68,8 +68,15 @@ namespace skyscraper5.src.Skyscraper.FrequencyListGenerator switch(mode) { case 1: - if (SatPosition != null) - return String.Format("{0:0.0}° {1}", SatPosition.angle, SatPosition.GetCardinalDirectionAsChar()); + if (SatPosition >= 0.0) + { + return String.Format("{0}°E", SatPosition); + } + else + { + double westerner = SatPosition /= -1; + return String.Format("{0}°W", westerner); + } return TunerStandard.ToString(); case 2: return String.Format("({0}/{1}/{2}/{3})", (int)HorizontalLowState, (int)HorizontalHighState, (int)VerticalLowState, (int)VerticalHighState); @@ -78,6 +85,19 @@ namespace skyscraper5.src.Skyscraper.FrequencyListGenerator } } + public string GetFiveLetterOrbitalPosition() + { + if (SatPosition >= 0) + { + return String.Format("{0:4}E", (int)(SatPosition * 10)); + } + else + { + double westerner = SatPosition /= -1; + return String.Format("{0:4}W", (int)(westerner * 10)); + } + } + } public enum DbBlindscanJobPolarizationStatus : int diff --git a/skyscraper8/Skyscraper/IO/RemoteStreamReader/RemoteStreamReaderClient.cs b/skyscraper8/Skyscraper/IO/RemoteStreamReader/RemoteStreamReaderClient.cs index cbca45a..add2d77 100644 --- a/skyscraper8/Skyscraper/IO/RemoteStreamReader/RemoteStreamReaderClient.cs +++ b/skyscraper8/Skyscraper/IO/RemoteStreamReader/RemoteStreamReaderClient.cs @@ -513,7 +513,10 @@ namespace skyscraper5.Skyscraper.IO.RemoteStreamReader { case RemoteStreamReaderConstants.COMMAND_SUCCESSFUL: pRFLevel = NetworkStreamExtensions.ReadDouble(TcpStream); - return true; + return true; + case RemoteStreamReaderConstants.COMMAND_FAILED: + pRFLevel = NetworkStreamExtensions.ReadDouble(TcpStream); + return false; default: throw new NotImplementedException(result.ToString()); } diff --git a/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs b/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs index 84e115b..82377e0 100644 --- a/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs +++ b/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs @@ -14,7 +14,6 @@ using skyscraper5.Mhp.Si.Model; using skyscraper5.Mpeg2.Descriptors; using skyscraper5.Mpeg2.Psi.Model; using skyscraper5.Scte35; -using skyscraper5.Skyscraper.Equipment; using skyscraper5.Skyscraper.IO.CrazycatStreamReader; using skyscraper5.Skyscraper.Net; using skyscraper5.src.InteractionChannel.Model; @@ -98,7 +97,7 @@ namespace skyscraper5.Skyscraper.Scraper /// Called before a SetChannel operation is performed. /// /// - void OnBlindscanBeforeSetChannel(BlindscanSearchResult blindscanResult, LnbEntity lnbType); + void OnBlindscanBeforeSetChannel(BlindscanSearchResult blindscanResult); /// /// Called after a band (meaning e.g. Horizontal High) has been scraped. diff --git a/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs index b351f78..d6b0048 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs @@ -12,13 +12,11 @@ using skyscraper5.Mpeg2.Psi.Model; using skyscraper5.Rds.Messages; using skyscraper5.Scte35; using skyscraper5.Skyscraper; -using skyscraper5.Skyscraper.Equipment; using skyscraper5.Skyscraper.Gps; using skyscraper5.Skyscraper.Headless; using skyscraper5.Skyscraper.IO.CrazycatStreamReader; using skyscraper5.Skyscraper.Scraper.Storage.Utilities; using skyscraper5.src.InteractionChannel.Model; -using skyscraper5.src.InteractionChannel.Model.Descriptors; using skyscraper5.src.Skyscraper.FrequencyListGenerator; using skyscraper5.src.Skyscraper.Scraper.Dns; using skyscraper5.Teletext; @@ -30,8 +28,6 @@ using System.Net.NetworkInformation; using skyscraper5.src.InteractionChannel.Model2; using skyscraper8.InteractionChannel.Model; using skyscraper8.InteractionChannel.Model2; -using skyscraper8.InteractionChannel.Model2.Descriptors; -using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform; namespace skyscraper8.Skyscraper.Scraper.Storage { @@ -85,9 +81,6 @@ namespace skyscraper8.Skyscraper.Scraper.Storage void T2MiSetTimestamp(int currentNetworkId, int currentTransportStreamId, int pid, DateTime resolveTime); bool TestForRelatedContent(EitEvent lEvent, RctLinkInfo rctLinkInfo); void SetRelatedContent(EitEvent lEvent, RctLinkInfo rctLinkInfo); - List UiSatellitesListAll(); - void UiSatellitesAdd(SatellitePositionEntity newPosition); - void UiSatellitesDelete(SatellitePositionEntity satellitePosition); bool UiTunerTestFor(TunerMetadata tuner); void UiTunerUpdate(TunerMetadata tuner); void UiTunerInsert(TunerMetadata tuner); @@ -107,11 +100,6 @@ namespace skyscraper8.Skyscraper.Scraper.Storage bool T2MiTestForTransmitter(int? currentNetworkId, int? currentTransportStreamId, int relatedPid, ushort txIdentifier); void T2MiRememberTransmitter(int? currentNetworkId, int? currentTransportStreamId, int relatedPid, ushort txIdentifier); void T2MiSetTransmitterTimeOffset(int? currentNetworkId, int? currentTransportStreamId, int relatedPid, ushort txIdentifier, ushort timeOffset); - List UiLnbTypesListAll(); - void UiLnbTypesAdd(LnbEntity defaultLnbType); - List UiDishTypesListAll(); - void UiDishTypesAdd(DishEntity defaultDishType); - IEnumerable> SelectAllPmt(); SdtService SelectSdtById(int networkId, int tsId, ushort programMappingProgramNumber); IEnumerable> SelectAllSdt(); diff --git a/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs index bc33494..92e4d3e 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs @@ -13,7 +13,6 @@ using skyscraper5.Mpeg2.Descriptors; using skyscraper5.Mpeg2.Psi.Model; using skyscraper5.Rds.Messages; using skyscraper5.Scte35; -using skyscraper5.Skyscraper.Equipment; using skyscraper5.Skyscraper.Gps; using skyscraper5.Skyscraper.Headless; using skyscraper5.Skyscraper.IO; @@ -789,48 +788,6 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem } } - public List UiSatellitesListAll() - { - string path = Path.Combine(rootDirectory.FullName, "satellites.json"); - FileInfo fi = new FileInfo(path); - if (!fi.Exists) - return new List(); - else - { - return JsonConvert.DeserializeObject>(File.ReadAllText(fi.FullName)); - } - } - - public void UiSatellitesAdd(SatellitePositionEntity newPosition) - { - string path = Path.Combine(rootDirectory.FullName, "satellites.json"); - FileInfo fi = new FileInfo(path); - List satellites; - if (!fi.Exists) - { - satellites = new List(); - } - else - { - satellites = JsonConvert.DeserializeObject>(File.ReadAllText(fi.FullName)); - } - - satellites.Add(newPosition); - EnsureDirectoryExists(fi.Directory); - File.WriteAllText(fi.FullName, JsonConvert.SerializeObject(satellites, Formatting.Indented)); - } - - public void UiSatellitesDelete(SatellitePositionEntity satellitePosition) - { - string path = Path.Combine(rootDirectory.FullName, "satellites.json"); - FileInfo fi = new FileInfo(path); - List satellites = JsonConvert.DeserializeObject>(File.ReadAllText(fi.FullName)); - - satellites.RemoveAll(x => x.Checksum == satellitePosition.Checksum); - - File.WriteAllText(fi.FullName, JsonConvert.SerializeObject(satellites, Formatting.Indented)); - } - public bool UiTunerTestFor(TunerMetadata tuner) { string fname = BitConverter.ToString(tuner.MacAddress.GetAddressBytes()); @@ -935,35 +892,6 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem File.WriteAllText(path, timeOffset.ToString()); } - public List UiLnbTypesListAll() - { - string path = Path.Combine(rootDirectory.FullName, "0-UI", "LnbTypes"); - DirectoryInfo di = new DirectoryInfo(path); - if (!di.Exists) - { - return new List(); - } - - List result = new List(); - FileInfo[] fileInfos = di.GetFiles("*.json"); - foreach (FileInfo fileInfo in fileInfos) - { - string fid = Path.GetFileNameWithoutExtension(fileInfo.Name); - if (!fid.IsNaturalNumeric()) - continue; - int iid = int.Parse(fid); - - string json = File.ReadAllText(fileInfo.FullName); - LnbEntity deserializeObject = JsonConvert.DeserializeObject(json); - if (deserializeObject.Id != iid) - continue; - if (result.Contains(deserializeObject)) - continue; - result.Add(deserializeObject); - } - - return result; - } private int GetNextJsonFileNumber(DirectoryInfo di) { @@ -988,61 +916,6 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem return result; } - public void UiLnbTypesAdd(LnbEntity defaultLnbType) - { - string path = Path.Combine(rootDirectory.FullName, "0-UI", "LnbTypes"); - DirectoryInfo di = new DirectoryInfo(path); - int fileId = GetNextJsonFileNumber(di); - defaultLnbType.Id = fileId; - defaultLnbType.DateAdded = DateTime.Now; - - path = Path.Combine(rootDirectory.FullName, "0-UI", "LnbTypes", fileId.ToString() + ".json"); - string json = JsonConvert.SerializeObject(defaultLnbType, jsonSerializerSettings); - File.WriteAllText(path, json); - } - - public List UiDishTypesListAll() - { - string path = Path.Combine(rootDirectory.FullName, "0-UI", "DishTypes"); - DirectoryInfo di = new DirectoryInfo(path); - if (!di.Exists) - { - return new List(); - } - - List result = new List(); - FileInfo[] fileInfos = di.GetFiles("*.json"); - foreach (FileInfo fileInfo in fileInfos) - { - string fid = Path.GetFileNameWithoutExtension(fileInfo.Name); - if (!fid.IsNaturalNumeric()) - continue; - int iid = int.Parse(fid); - - string json = File.ReadAllText(fileInfo.FullName); - DishEntity deserializeObject = JsonConvert.DeserializeObject(json); - if (deserializeObject.Id != iid) - continue; - if (result.Contains(deserializeObject)) - continue; - result.Add(deserializeObject); - } - - return result; - } - - public void UiDishTypesAdd(DishEntity defaultDishType) - { - string path = Path.Combine(rootDirectory.FullName, "0-UI", "DishTypes"); - DirectoryInfo di = new DirectoryInfo(path); - int fileId = GetNextJsonFileNumber(di); - defaultDishType.Id = fileId; - defaultDishType.DateAdded = DateTime.Now; - - path = Path.Combine(rootDirectory.FullName, "0-UI", "DishTypes", fileId.ToString() + ".json"); - string json = JsonConvert.SerializeObject(defaultDishType, jsonSerializerSettings); - File.WriteAllText(path, json); - } public object[] GetPluginConnector() { @@ -1243,7 +1116,7 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem { if (jobInDb.DateAdded == DateTime.MinValue) jobInDb.DateAdded = DateTime.Now; - string path = Path.Combine(rootDirectory.FullName, "0-Blindscan",jobInDb.SatPosition.Checksum.ToString(), jobInDb.JobGuid.ToString(), "index.json"); + string path = Path.Combine(rootDirectory.FullName, "0-Blindscan",jobInDb.GetFiveLetterOrbitalPosition(), jobInDb.JobGuid.ToString(), "index.json"); FileInfo fi = new FileInfo(path); EnsureDirectoryExists(fi.Directory); @@ -1260,7 +1133,7 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem SearchResult2 searchResult2) { string freq = satellite ? String.Format("{0}_{1}", searchResult.Freq, searchResult.Pol) : String.Format("{0}", searchResult2); - string path = Path.Combine(rootDirectory.FullName, "0-Blindscan", jobInDb.SatPosition.Checksum.ToString(), jobInDb.JobGuid.ToString(), freq + ".json"); + string path = Path.Combine(rootDirectory.FullName, "0-Blindscan", jobInDb.GetFiveLetterOrbitalPosition(), jobInDb.JobGuid.ToString(), freq + ".json"); string json = JsonConvert.SerializeObject(satellite ? searchResult : searchResult2, jsonSerializerSettings); File.WriteAllText(path, json); } @@ -1276,7 +1149,7 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem { string freq = resultSatellite ? String.Format("{0}_{1}", resultSr1.Freq, resultSr1.Pol) : String.Format("{0}", resultSr2); string jsonName = String.Format("{0}.json", humanReadableService.ServiceId); - string path = Path.Combine(rootDirectory.FullName, "0-Blindscan", jobInDb.SatPosition.Checksum.ToString(), jobInDb.JobGuid.ToString(), freq, jsonName); + string path = Path.Combine(rootDirectory.FullName, "0-Blindscan", jobInDb.GetFiveLetterOrbitalPosition(), jobInDb.JobGuid.ToString(), freq, jsonName); FileInfo fi = new FileInfo(path); EnsureDirectoryExists(fi.Directory); string json = JsonConvert.SerializeObject(humanReadableService, jsonSerializerSettings); diff --git a/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs index f0bdad5..3d5c79d 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs @@ -12,7 +12,6 @@ using skyscraper5.Mpeg2.Descriptors; using skyscraper5.Mpeg2.Psi.Model; using skyscraper5.Rds.Messages; using skyscraper5.Scte35; -using skyscraper5.Skyscraper.Equipment; using skyscraper5.Skyscraper.Gps; using skyscraper5.Skyscraper.Headless; using skyscraper5.Skyscraper.IO; @@ -771,27 +770,6 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory throw new NotImplementedException(); } - private List satellitePositions; - - public List UiSatellitesListAll() - { - if (satellitePositions == null) - satellitePositions = new List(); - return satellitePositions.ToList(); - } - - public void UiSatellitesAdd(SatellitePositionEntity newPosition) - { - if (satellitePositions == null) - satellitePositions = new List(); - satellitePositions.Add(newPosition); - } - - public void UiSatellitesDelete(SatellitePositionEntity satellitePosition) - { - satellitePositions.RemoveAll(x => x.Checksum == satellitePosition.Checksum); - } - private List uiTuners; public bool UiTunerTestFor(TunerMetadata tuner) @@ -905,40 +883,6 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory t2miTransmitters[t2miTransmitterId].TimeOffset = timeOffset; } - private List _lnbTypes; - - public List UiLnbTypesListAll() - { - if (_lnbTypes == null) - _lnbTypes = new List(); - return _lnbTypes; - } - - public void UiLnbTypesAdd(LnbEntity defaultLnbType) - { - if (_lnbTypes == null) - _lnbTypes = new List(); - if (!_lnbTypes.Contains(defaultLnbType)) - _lnbTypes.Add(defaultLnbType); - } - - private List _dishTypes; - - public List UiDishTypesListAll() - { - if (_dishTypes == null) - _dishTypes = new List(); - return _dishTypes; - - } - - public void UiDishTypesAdd(DishEntity defaultDishType) - { - if (_dishTypes == null) - _dishTypes = new List(); - if (!_dishTypes.Contains(defaultDishType)) - _dishTypes.Add(defaultDishType); - } public object[] GetPluginConnector() {