From 4e651ccdcec73d2ad633d7d515d721b765e975ab Mon Sep 17 00:00:00 2001 From: feyris-tan Date: Sat, 4 Oct 2025 20:51:01 +0200 Subject: [PATCH] A lot of things happened during my vacation. --- .../MinioObjectStorage.cs | 16 +- .../skyscraper5.Data.PostgreSql/Dns.cs | 2 + .../skyscraper5.Data.PostgreSql/Dvbi.cs | 3 + .../InteractionChannel.cs | 15 +- .../skyscraper5.Data.PostgreSql/Sdt.cs | 6 +- GUIs/skyscraper8.UI.ImGui/Forms/LogWindow.cs | 4 +- GUIs/skyscraper8.UI.ImGui/JobContext.cs | 2 +- GUIs/skyscraper8.UI.ImGui/Jobs/Blindscan.cs | 61 ++--- .../Jobs/CoopBlindscan.cs | 53 ++-- .../Jobs/InheritedBlindscanConfigWindow.cs | 5 +- .../Jobs/InheritedBlindscanUiJunction.cs | 6 +- GUIs/skyscraper8.UI.ImGui/Program.cs | 22 +- MpePlugins/skyscraper5.DNS/PluginDns.cs | 10 + skyscraper8/DvbI/DvbIFilesystemProcessor.cs | 9 +- skyscraper8/DvbNip/DvbNipReceiver.cs | 5 + skyscraper8/Ietf/FLUTE/FluteListener.cs | 3 + skyscraper8/Ietf/FLUTE/LctFrame.cs | 9 +- skyscraper8/Ietf/FLUTE/LctHeader.cs | 26 +- .../InteractionChannelHandler.cs | 4 +- .../0xa1_CorrectionMessageDescriptor.cs | 32 ++- .../0xaf_ConnectionControlDescriptor.cs | 2 +- skyscraper8/InteractionChannel/Model/Tim.cs | 6 + .../NullInteractionChannelHandler.cs | 12 +- .../Descriptors/0x00_ApplicationDescriptor.cs | 1 + .../0x01_ApplicationNameDescriptor.cs | 1 + .../0x02_TransportProtocolDescriptor.cs | 1 + .../0x03_DvbJApplicationDescriptor.cs | 1 + .../0x04_DvbJApplicationLocationDescriptor.cs | 1 + ...ernalApplicationAuthorisationDescriptor.cs | 1 + .../0x10_ApplicationStorageDescriptor.cs | 1 + .../0x13_ProviderUsageDescriptor.cs | 41 +++ ...x15_SimpleApplicationLocationDescriptor.cs | 11 +- .../0x16_ApplicationUsageDescriptor.cs | 1 + ...x17_SimpleApplicationBoundaryDescriptor.cs | 1 + .../0x66_OcapAbstractServiceDescriptor.cs | 1 + .../0x67_OcapUnboundApplicationDescriptor.cs | 1 + .../0x69_OcapApplicationStorageDescriptor.cs | 1 + .../Mhp/Descriptors/0x70_LabelDescriptor.cs | 1 + .../0x72_ConnectionRequirementDescriptor.cs | 1 + skyscraper8/Mhp/Si/AitParser.cs | 2 + skyscraper8/Program.cs | 2 +- skyscraper8/Properties/launchSettings.json | 2 +- skyscraper8/QuickAndDirtySatIpClient.cs | 7 +- skyscraper8/SatIp/RtspClient.cs | 22 +- .../Skyscraper/BbframeDeencapsulator.cs | 248 +++++++++++++++--- .../Skyscraper/DigitalDevicesBbFrameReader.cs | 33 +-- .../BaseBlindscanJob.cs | 2 +- .../CoopBlindscanStreamReaderProxy.cs | 2 +- .../SatIpWithStreamReaderProxy.cs | 17 +- skyscraper8/Skyscraper/IpPacketFinder.cs | 14 +- .../Skyscraper/Scraper/CaSystemNames.cs | 6 +- .../Skyscraper/Scraper/SkyscraperContext.cs | 16 +- .../InMemory/InMemoryScraperStorage.cs | 7 +- .../InteractionChannelContestant.cs | 17 +- skyscraper8/Skyscraper/Text/AsciiTable.cs | 1 + .../Skyscraper/Text/En300468TextDecoder.cs | 14 +- .../Text/Encodings/dvb-iso-8859-1.cs | 4 + .../Text/Encodings/dvb-iso-8859-11.cs | 2 + .../Text/Encodings/dvb-iso-8859-13.cs | 10 +- .../Text/Encodings/dvb-iso-8859-6.cs | 7 + .../T2MI/Packets/0x21_IndividualAddressing.cs | 7 +- .../Packets/AdressingFunctions/0x04_CellId.cs | 31 +++ .../Packets/AdressingFunctions/0x12_TrPapr.cs | 29 ++ .../AdressingFunctions/0x17_Frequency.cs | 31 +++ skyscraper8/T2MI/T2MIDecoder.cs | 5 + 65 files changed, 726 insertions(+), 191 deletions(-) create mode 100644 skyscraper8/Mhp/Descriptors/0x13_ProviderUsageDescriptor.cs create mode 100644 skyscraper8/T2MI/Packets/AdressingFunctions/0x04_CellId.cs create mode 100644 skyscraper8/T2MI/Packets/AdressingFunctions/0x12_TrPapr.cs create mode 100644 skyscraper8/T2MI/Packets/AdressingFunctions/0x17_Frequency.cs diff --git a/BlobStorages/skyscraper5.Data.Minio/MinioObjectStorage.cs b/BlobStorages/skyscraper5.Data.Minio/MinioObjectStorage.cs index 83ef2b6..4c7ffe4 100644 --- a/BlobStorages/skyscraper5.Data.Minio/MinioObjectStorage.cs +++ b/BlobStorages/skyscraper5.Data.Minio/MinioObjectStorage.cs @@ -52,6 +52,7 @@ namespace skyscraper5.Data putObjectArgs = putObjectArgs.WithHeaders(optionalData); if (buffer.CanSeek) { + buffer.Position = 0; putObjectArgs = putObjectArgs.WithObjectSize(buffer.Length); } else if (optionalData.ContainsKey("X-Skyscraper-Content-Length")) @@ -72,7 +73,20 @@ namespace skyscraper5.Data { if (task.IsFaulted) { - throw new MinioException("A minio upload task failed."); + AggregateException exception = task.Exception; + MinioException me = exception.InnerException as MinioException; + if (me != null) + { + if (me.ServerResponse == null) + throw new UnexpectedMinioException("Minio Server Response was null."); + System.Net.Http.HttpResponseMessage response = me.ServerResponse.Response; + if (response.StatusCode != HttpStatusCode.OK) + { + throw new MinioException("A minio upload task failed.", me); + } + } + else + throw new NotImplementedException(); } droppedFiles.Add(fullName); diff --git a/DataTableStorages/skyscraper5.Data.PostgreSql/Dns.cs b/DataTableStorages/skyscraper5.Data.PostgreSql/Dns.cs index b4280cd..7e51007 100644 --- a/DataTableStorages/skyscraper5.Data.PostgreSql/Dns.cs +++ b/DataTableStorages/skyscraper5.Data.PostgreSql/Dns.cs @@ -188,6 +188,8 @@ namespace skyscraper5.Data.PostgreSql private bool TestForDnsRecord(NpgsqlConnection x, DnsRecord record, long domainId, long? ipId) { + record.ResourceData = record.ResourceData.Trim('\0'); + NpgsqlCommand command = x.CreateCommand(); command.CommandText = "SELECT dateadded FROM dns_records WHERE domain_id = @did AND record_type = @rt AND resource_data = @rd"; command.Parameters.AddWithValue("@did", domainId); diff --git a/DataTableStorages/skyscraper5.Data.PostgreSql/Dvbi.cs b/DataTableStorages/skyscraper5.Data.PostgreSql/Dvbi.cs index 8e0a895..b6a7880 100644 --- a/DataTableStorages/skyscraper5.Data.PostgreSql/Dvbi.cs +++ b/DataTableStorages/skyscraper5.Data.PostgreSql/Dvbi.cs @@ -106,6 +106,9 @@ namespace skyscraper5.Data.PostgreSql public void UpdateDvbiServiceListLastCheckedDate(string id, DateTime currentTime) { EnqueueTask(x => UpdateDvbiServiceListLastCheckedDateEx(x, id, currentTime)); + if (_knownDvbiServiceListUpdateDates == null) + _knownDvbiServiceListUpdateDates = new Dictionary(); + _knownDvbiServiceListUpdateDates[id] = currentTime; } diff --git a/DataTableStorages/skyscraper5.Data.PostgreSql/InteractionChannel.cs b/DataTableStorages/skyscraper5.Data.PostgreSql/InteractionChannel.cs index c890798..85cb480 100644 --- a/DataTableStorages/skyscraper5.Data.PostgreSql/InteractionChannel.cs +++ b/DataTableStorages/skyscraper5.Data.PostgreSql/InteractionChannel.cs @@ -561,7 +561,7 @@ namespace skyscraper5.Data.PostgreSql timNid = interactiveNetworkId; NpgsqlCommand command = x.CreateCommand(); command.CommandText = "INSERT INTO dvb_ic_fct (nid, frame_id, frame_duration, total_timeslot_count, start_timeslot_number)" + - "VALUES (@nid,@fid,@fduration,@ttcount,@stnumber)RETURNING uuid"; + "VALUES (@nid,@fid,@fduration,@ttcount,@stnumber) RETURNING uuid"; command.Parameters.AddWithValue("@nid", NpgsqlTypes.NpgsqlDbType.Integer, (int)interactiveNetworkId); command.Parameters.AddWithValue("@fid", NpgsqlTypes.NpgsqlDbType.Integer, (int)frame.FrameId); command.Parameters.AddWithValue("@fduration", NpgsqlTypes.NpgsqlDbType.Bigint, (long)frame.FrameDuration); @@ -660,7 +660,18 @@ namespace skyscraper5.Data.PostgreSql private void CreateTimEx(NpgsqlConnection x, PhysicalAddress mac, ushort nid) { - NpgsqlCommand command = x.CreateCommand(); + NpgsqlCommand testCommand = x.CreateCommand(); + testCommand.CommandText = "SELECT dateadded FROM dvb_ic_tim WHERE mac = @mac AND nid = @nid"; + testCommand.Parameters.AddWithValue("@mac", NpgsqlTypes.NpgsqlDbType.MacAddr, mac); + testCommand.Parameters.AddWithValue("@nid", NpgsqlTypes.NpgsqlDbType.Integer, (int)nid); + NpgsqlDataReader dataReader = testCommand.ExecuteReader(); + bool alreadyKnown = dataReader.Read(); + dataReader.Close(); + if (alreadyKnown) + return; + + + NpgsqlCommand command = x.CreateCommand(); command.CommandText = "INSERT INTO dvb_ic_tim (mac,nid) VALUES (@mac,@nid)"; command.Parameters.AddWithValue("@mac", NpgsqlTypes.NpgsqlDbType.MacAddr, mac); command.Parameters.AddWithValue("@nid", NpgsqlTypes.NpgsqlDbType.Integer, (int)nid); diff --git a/DataTableStorages/skyscraper5.Data.PostgreSql/Sdt.cs b/DataTableStorages/skyscraper5.Data.PostgreSql/Sdt.cs index 4265d36..7011c6d 100644 --- a/DataTableStorages/skyscraper5.Data.PostgreSql/Sdt.cs +++ b/DataTableStorages/skyscraper5.Data.PostgreSql/Sdt.cs @@ -175,8 +175,8 @@ namespace skyscraper5.Data.PostgreSql NpgsqlCommand cmd = connection.CreateCommand(); cmd.CommandText = "insert into dvb_sdt_messages (tsid, onid, sid, msgid, language_code, message, dateadded)\r\nvalues (@tsid,@onid,@sid,@msgid,@language,@message,DEFAULT)"; - cmd.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, transportStreamId); - cmd.Parameters.AddWithValue("@onid", NpgsqlDbType.Integer, originalNetworkId); + cmd.Parameters.AddWithValue("@tsid", NpgsqlDbType.Integer, (int)transportStreamId); + cmd.Parameters.AddWithValue("@onid", NpgsqlDbType.Integer, (int)originalNetworkId); cmd.Parameters.AddWithValue("@sid", NpgsqlDbType.Integer, (int)sdtService.ServiceId); cmd.Parameters.Add("@msgid", NpgsqlDbType.Integer); cmd.Parameters.Add("@language", NpgsqlDbType.Varchar); @@ -184,7 +184,7 @@ namespace skyscraper5.Data.PostgreSql foreach (MessageDescriptor message in sdtService.Messages) { - cmd.Parameters["@msgid"].Value = message.MessageId; + cmd.Parameters["@msgid"].Value = (int)message.MessageId; cmd.Parameters["@language"].Value = message.Iso639LanguageCode; cmd.Parameters["@message"].Value = message.Message; cmd.ExecuteNonQuery(); diff --git a/GUIs/skyscraper8.UI.ImGui/Forms/LogWindow.cs b/GUIs/skyscraper8.UI.ImGui/Forms/LogWindow.cs index ba00b96..2f52e48 100644 --- a/GUIs/skyscraper8.UI.ImGui/Forms/LogWindow.cs +++ b/GUIs/skyscraper8.UI.ImGui/Forms/LogWindow.cs @@ -12,7 +12,7 @@ using skyscraper8.Skyscraper.Plugins; namespace SDL2Demo.Forms { - internal class LogWindow : PluginAppenderEx, IRenderable + /*internal class LogWindow : PluginAppenderEx, IRenderable { public LogWindow() { @@ -158,5 +158,5 @@ namespace SDL2Demo.Forms { Log(String.Format("{0} {1} [{2}] {3}", mappedTime.ToShortDateString(), mappedTime.ToShortTimeString(), mappedLoggerName, mappedMessage)); } - } + }*/ } diff --git a/GUIs/skyscraper8.UI.ImGui/JobContext.cs b/GUIs/skyscraper8.UI.ImGui/JobContext.cs index 094a808..4b988fa 100644 --- a/GUIs/skyscraper8.UI.ImGui/JobContext.cs +++ b/GUIs/skyscraper8.UI.ImGui/JobContext.cs @@ -27,7 +27,7 @@ namespace SDL2Demo public List Renderables { get; set; } public List PressurePlates { get; set; } - public LogWindow LogWindow { get; set; } + //public LogWindow LogWindow { get; set; } public bool MemorySaverMode { get; set; } public IStreamReader StreamReader { get; set; } public Ini Ini { get; set; } diff --git a/GUIs/skyscraper8.UI.ImGui/Jobs/Blindscan.cs b/GUIs/skyscraper8.UI.ImGui/Jobs/Blindscan.cs index 98b3aa1..ccf215b 100644 --- a/GUIs/skyscraper8.UI.ImGui/Jobs/Blindscan.cs +++ b/GUIs/skyscraper8.UI.ImGui/Jobs/Blindscan.cs @@ -245,7 +245,7 @@ namespace SDL2Demo.Jobs jobStorage.InsertBlindscanJob(jobInDb); } - JobContext.LogWindow.Log("Attempting to start the tuner...", 8); + //JobContext.LogWindow.Log("Attempting to start the tuner...", 8); if (!streamReader.StartDvbEx(SelectedBlindscanTarget.tunerIndex)) { JobContext.MessageQueue.Enqueue(new MessageWindow("Failed to start tuner.")); @@ -253,7 +253,7 @@ namespace SDL2Demo.Jobs return; } - JobContext.LogWindow.Log("Tuner started", 8); + //JobContext.LogWindow.Log("Tuner started", 8); foundFrequencies = new List(); ourFoundFrequenciesWindow = new FoundFrequenciesWindow(foundFrequencies, SelectedBlindscanTarget.tunerStandard, JobContext); @@ -458,7 +458,7 @@ namespace SDL2Demo.Jobs { if (SendDiseqcCommand(diseqc, false, true)) { - JobContext.LogWindow.Log(String.Format("Scanning low horizontal band...")); + //JobContext.LogWindow.Log(String.Format("Scanning low horizontal band...")); jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING; jobStorage.UpdateJobState(jobInDb); bool hLower = BlScan2Wrap(startFreq, lofSw, 0, lof1, lof2, lofSw,allocHGlobal, ref tpNum,((ref SearchResult searchResult) => SearchResult1Callback(searchResult,1))); @@ -466,7 +466,7 @@ namespace SDL2Demo.Jobs JobContext.Puppets[1].AutoMoveToHome(); if (!hLower) { - JobContext.MessageQueue.Enqueue(new MessageWindow("Blindscanning low horizontal area failed.")); + //JobContext.MessageQueue.Enqueue(new MessageWindow("Blindscanning low horizontal area failed.")); jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_FAILED; jobStorage.UpdateJobState(jobInDb); } @@ -494,7 +494,7 @@ namespace SDL2Demo.Jobs if (SendDiseqcCommand(diseqc, true, true)) { SendDiseqcCommand(diseqc, true, true); - JobContext.LogWindow.Log(String.Format("Scanning high horizontal band...")); + //JobContext.LogWindow.Log(String.Format("Scanning high horizontal band...")); jobInDb.HorizontalHighState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING; jobStorage.UpdateJobState(jobInDb); bool hUpper = BlScan2Wrap(lofSw, endFreq, 0, lof1, lof2, lofSw,allocHGlobal, ref tpNum,((ref SearchResult searchResult) => SearchResult1Callback(searchResult,2))); @@ -529,7 +529,7 @@ namespace SDL2Demo.Jobs { if (SendDiseqcCommand(diseqc, false, false)) { - JobContext.LogWindow.Log(String.Format("Scanning low vertical band...")); + //JobContext.LogWindow.Log(String.Format("Scanning low vertical band...")); jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING; jobStorage.UpdateJobState(jobInDb); bool vLower = BlScan2Wrap(startFreq, lofSw, 1, lof1, lof2, lofSw,allocHGlobal, ref tpNum,((ref SearchResult searchResult) => SearchResult1Callback(searchResult,3))); @@ -564,7 +564,7 @@ namespace SDL2Demo.Jobs { if (SendDiseqcCommand(diseqc, true, false)) { - JobContext.LogWindow.Log(String.Format("Scanning high vertical band...")); + //JobContext.LogWindow.Log(String.Format("Scanning high vertical band...")); jobInDb.VerticalHighState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING; jobStorage.UpdateJobState(jobInDb); bool vUpper = BlScan2Wrap(lofSw, endFreq, 1, lof1, lof2, lofSw, allocHGlobal, ref tpNum, ((ref SearchResult searchResult) => SearchResult1Callback(searchResult,4))); @@ -599,7 +599,7 @@ namespace SDL2Demo.Jobs { if (SendDiseqcCommand(diseqc, false, true)) { - JobContext.LogWindow.Log(String.Format("Scanning left circular band...")); + //JobContext.LogWindow.Log(String.Format("Scanning left circular band...")); jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING; jobStorage.UpdateJobState(jobInDb); bool lCirc = BlScan2Wrap(startFreq, endFreq, 0, lof1, lof2, lofSw, allocHGlobal, ref tpNum, ((ref SearchResult searchResult) => SearchResult1Callback(searchResult,1))); @@ -630,7 +630,7 @@ namespace SDL2Demo.Jobs } if (SendDiseqcCommand(diseqc, false, false)) { - JobContext.LogWindow.Log(String.Format("Scanning right circular band...")); + //JobContext.LogWindow.Log(String.Format("Scanning right circular band...")); jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING; jobStorage.UpdateJobState(jobInDb); bool rCirc = BlScan2Wrap(startFreq, endFreq, 1, lof1, lof2, lofSw, allocHGlobal, ref tpNum, ((ref SearchResult searchResult) => SearchResult1Callback(searchResult,3))); @@ -709,7 +709,7 @@ namespace SDL2Demo.Jobs foundFrequencies.Add(blindscanResult); } - JobContext.LogWindow.Log(String.Format("Found frequency: {0}, {1}", searchResult.Freq / 1000,searchResult.Pol == 0 ? "H" : "V")); + //JobContext.LogWindow.Log(String.Format("Found frequency: {0}, {1}", searchResult.Freq / 1000,searchResult.Pol == 0 ? "H" : "V")); SoundPlayer.PlaySoundFile("lock.wav"); _blindscanProgressWindow.Progress = searchResult.Freq; @@ -731,7 +731,7 @@ namespace SDL2Demo.Jobs foundFrequencies.Add(blindscanResult); } - JobContext.LogWindow.Log(String.Format("Found frequency: {0}", searchResult.Freq / 1000)); + //JobContext.LogWindow.Log(String.Format("Found frequency: {0}", searchResult.Freq / 1000)); SoundPlayer.PlaySoundFile("lock.wav"); jobStorage.InsertSearchResult(jobInDb, false, new SearchResult(), 7, searchResult); @@ -776,16 +776,15 @@ namespace SDL2Demo.Jobs } } - JobContext.LogWindow.Log(String.Format("Send DiSEqC Command {0:X2}", (byte)myOpcode), 8); + //JobContext.LogWindow.Log(String.Format("Send DiSEqC Command {0:X2}", (byte)myOpcode), 8); DateTime started = DateTime.Now; bool result = streamReader.SendDiSEqC((uint)diseqcType, myOpcode); TimeSpan timeTaken = DateTime.Now - started; - JobContext.LogWindow.Log(String.Format("DiSEqC Comannd sent in {0:F1} seconds.", timeTaken.TotalSeconds)); + //JobContext.LogWindow.Log(String.Format("DiSEqC Comannd sent in {0:F1} seconds.", timeTaken.TotalSeconds)); if (timeTaken.TotalSeconds > 10) { - JobContext.LogWindow.Log( - String.Format("Something went wrong while performing the DiSEqC operation, trying again..."), 8); + //JobContext.LogWindow.Log(String.Format("Something went wrong while performing the DiSEqC operation, trying again..."), 8); Thread.Sleep(1000); return SendDiseqcCommand(diseqcType, highBand, horizontal); } @@ -929,7 +928,7 @@ namespace SDL2Demo.Jobs } else { - JobContext.LogWindow.Log(String.Format("odd packet size!"), 8); + //JobContext.LogWindow.Log(String.Format("odd packet size!"), 8); } } @@ -987,8 +986,7 @@ namespace SDL2Demo.Jobs if (packetsQueue.Count == 0) return; - JobContext.LogWindow.Log( - String.Format("{0} packets left after switching off the filter.", packetsQueue.Count), 8); + //JobContext.LogWindow.Log(String.Format("{0} packets left after switching off the filter.", packetsQueue.Count), 8); DateTime startedAt = DateTime.Now; byte[] singlePacketBuffer = new byte[188]; @@ -1009,14 +1007,11 @@ namespace SDL2Demo.Jobs drainTickerNow = DateTime.Now; if (drainTickerNow.Second != drainTickerPrevious.Second) { - JobContext.LogWindow.Log( - String.Format("{0} packets left ({1}).", packetsQueue.Count, drainTickerNow.ToLongTimeString()), - 8); + //JobContext.LogWindow.Log(String.Format("{0} packets left ({1}).", packetsQueue.Count, drainTickerNow.ToLongTimeString()),8); } } - JobContext.LogWindow.Log( - String.Format("Packets drained in {0} seconds.", (DateTime.Now - startedAt).TotalSeconds), 8); + //JobContext.LogWindow.Log(String.Format("Packets drained in {0} seconds.", (DateTime.Now - startedAt).TotalSeconds), 8); } private void RunSkyscraper(BlindscanResult result) @@ -1056,7 +1051,7 @@ namespace SDL2Demo.Jobs */ - JobContext.LogWindow.Log(String.Format("Trying to BLScanEx..."), 8); + //JobContext.LogWindow.Log(String.Format("Trying to BLScanEx..."), 8); if (!streamReader.BLScanEx(result.sr1.Freq, 5000, result.sr1.Pol, SelectedBlindscanTarget.lnbType.Lof1 * 1000, SelectedBlindscanTarget.lnbType.Lof2 * 1000, SelectedBlindscanTarget.lnbType.LofSw * 1000, 1000000, (STD_TYPE)result.sr1.StdType, @@ -1071,7 +1066,7 @@ namespace SDL2Demo.Jobs if (!satelliteSr.Lock) { - JobContext.LogWindow.Log(String.Format("Trying to SetChannel..."), 8); + //JobContext.LogWindow.Log(String.Format("Trying to SetChannel..."), 8); bool channel = streamReader.SetChannel(result.sr1.Freq, result.sr1.SR, result.sr1.Freq, result.sr1.FEC, SelectedBlindscanTarget.lnbType.Lof1 * 1000, SelectedBlindscanTarget.lnbType.Lof2 * 1000, SelectedBlindscanTarget.lnbType.LofSw * 1000); if (!channel) { @@ -1082,7 +1077,7 @@ namespace SDL2Demo.Jobs } else { - JobContext.LogWindow.Log(String.Format("Trying to get SignalInfo..."), 8); + //JobContext.LogWindow.Log(String.Format("Trying to get SignalInfo..."), 8); bool signalInfo = streamReader.SignalInfo(ref satelliteSr); if (!signalInfo) { @@ -1118,7 +1113,7 @@ namespace SDL2Demo.Jobs } else if (caps.HasFlag(Caps.SR_SIGINFO2)) { - JobContext.LogWindow.Log(String.Format("Trying to SetChannel2..."), 8); + //JobContext.LogWindow.Log(String.Format("Trying to SetChannel2..."), 8); bool channel2 = streamReader.SetChannel2((uint)result.sr2.Freq, (uint)result.sr2.BW); if (!channel2) { @@ -1128,7 +1123,7 @@ namespace SDL2Demo.Jobs return; } - JobContext.LogWindow.Log(String.Format("Trying to get SignalInfo2..."), 8); + //JobContext.LogWindow.Log(String.Format("Trying to get SignalInfo2..."), 8); bool signalInfo2 = streamReader.SignalInfo2(ref cableSr); if (!signalInfo2) { @@ -1155,7 +1150,7 @@ namespace SDL2Demo.Jobs { if (misMode) { - JobContext.LogWindow.Log(String.Format("Selecting MIS IS {0}", satelliteSr.IS[mis]), 8); + //JobContext.LogWindow.Log(String.Format("Selecting MIS IS {0}", satelliteSr.IS[mis]), 8); bool misSel = streamReader.MISSel(misMode, satelliteSr.IS[mis], 0xff); if (!misSel) { @@ -1183,7 +1178,7 @@ namespace SDL2Demo.Jobs } IntPtr filterReference = IntPtr.MaxValue; - JobContext.LogWindow.Log(String.Format("Set-Up filter..."), 8); + //JobContext.LogWindow.Log(String.Format("Set-Up filter..."), 8); packetsToDrop = 1024; packetsQueue = new Queue(); ourFoundFrequenciesWindow.statusPacketsInqueue = 0; @@ -1196,7 +1191,7 @@ namespace SDL2Demo.Jobs SoundPlayer.PlaySoundFile("fail.wav"); return; } - JobContext.LogWindow.Log(String.Format("Filter set-up complete!"), 8); + //JobContext.LogWindow.Log(String.Format("Filter set-up complete!"), 8); //Use the Filter result.State = BlindscanResultState.Scraping; @@ -1246,7 +1241,7 @@ namespace SDL2Demo.Jobs } ourFoundFrequenciesWindow.allowZapNow = false; //Stop Filter - JobContext.LogWindow.Log(String.Format("Deleting Filter..."), 8); + //JobContext.LogWindow.Log(String.Format("Deleting Filter..."), 8); bool stopped = streamReader.DelFilter(filterReference); if (!stopped) { @@ -1254,7 +1249,7 @@ namespace SDL2Demo.Jobs jobStorage.UpdateTransponderState(jobInDb, result.Satellite, result.sr1, result.State, result.sr2); return; } - JobContext.LogWindow.Log(String.Format("Deleted filter!"), 8); + //JobContext.LogWindow.Log(String.Format("Deleted filter!"), 8); DrainPackets(); skyscraperContext.Dispose(); diff --git a/GUIs/skyscraper8.UI.ImGui/Jobs/CoopBlindscan.cs b/GUIs/skyscraper8.UI.ImGui/Jobs/CoopBlindscan.cs index 7ad08ff..21ec9f3 100644 --- a/GUIs/skyscraper8.UI.ImGui/Jobs/CoopBlindscan.cs +++ b/GUIs/skyscraper8.UI.ImGui/Jobs/CoopBlindscan.cs @@ -299,7 +299,7 @@ namespace SDL2Demo.Jobs SetTuner(1); if (SendDiseqcCommand(false, true)) { - JobContext.LogWindow.Log(String.Format("Scanning low horizontal band...")); + //JobContext.LogWindow.Log(String.Format("Scanning low horizontal band...")); jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING; jobStorage.UpdateJobState(jobInDb); bool hLower = BlScan2Wrap(startFreq, lofSw, 0, lof1, lof2, lofSw, allocHGlobal, ref tpNum, ((ref SearchResult searchResult) => SearchResult1Callback(searchResult, 1))); @@ -337,7 +337,7 @@ namespace SDL2Demo.Jobs SetTuner(1); if (SendDiseqcCommand(true, true)) { - JobContext.LogWindow.Log(String.Format("Scanning high horizontal band...")); + //JobContext.LogWindow.Log(String.Format("Scanning high horizontal band...")); jobInDb.HorizontalHighState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING; jobStorage.UpdateJobState(jobInDb); bool hUpper = BlScan2Wrap(lofSw, endFreq, 0, lof1, lof2, lofSw, allocHGlobal, ref tpNum, ((ref SearchResult searchResult) => SearchResult1Callback(searchResult, 2))); @@ -375,7 +375,7 @@ namespace SDL2Demo.Jobs SetTuner(1); if (SendDiseqcCommand(false, false)) { - JobContext.LogWindow.Log(String.Format("Scanning low vertical band...")); + //JobContext.LogWindow.Log(String.Format("Scanning low vertical band...")); jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING; jobStorage.UpdateJobState(jobInDb); bool vLower = BlScan2Wrap(startFreq, lofSw, 1, lof1, lof2, lofSw, allocHGlobal, ref tpNum, ((ref SearchResult searchResult) => SearchResult1Callback(searchResult, 3))); @@ -413,7 +413,7 @@ namespace SDL2Demo.Jobs SetTuner(1); if (SendDiseqcCommand(true, false)) { - JobContext.LogWindow.Log(String.Format("Scanning high vertical band...")); + //JobContext.LogWindow.Log(String.Format("Scanning high vertical band...")); jobInDb.VerticalHighState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING; jobStorage.UpdateJobState(jobInDb); bool vUpper = BlScan2Wrap(lofSw, endFreq, 1, lof1, lof2, lofSw, allocHGlobal, ref tpNum, ((ref SearchResult searchResult) => SearchResult1Callback(searchResult, 4))); @@ -451,7 +451,7 @@ namespace SDL2Demo.Jobs SetTuner(1); if (SendDiseqcCommand(false, true)) { - JobContext.LogWindow.Log(String.Format("Scanning left circular band...")); + //JobContext.LogWindow.Log(String.Format("Scanning left circular band...")); jobInDb.HorizontalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING; jobStorage.UpdateJobState(jobInDb); bool lCirc = BlScan2Wrap(startFreq, endFreq, 0, lof1, lof2, lofSw, allocHGlobal, ref tpNum, ((ref SearchResult searchResult) => SearchResult1Callback(searchResult, 1))); @@ -485,7 +485,7 @@ namespace SDL2Demo.Jobs SetTuner(1); if (SendDiseqcCommand(false, false)) { - JobContext.LogWindow.Log(String.Format("Scanning right circular band...")); + //JobContext.LogWindow.Log(String.Format("Scanning right circular band...")); jobInDb.VerticalLowState = DbBlindscanJobPolarizationStatus.SELECTED_BLINDSCANNING; jobStorage.UpdateJobState(jobInDb); bool rCirc = BlScan2Wrap(startFreq, endFreq, 1, lof1, lof2, lofSw, allocHGlobal, ref tpNum, ((ref SearchResult searchResult) => SearchResult1Callback(searchResult, 3))); @@ -622,16 +622,15 @@ namespace SDL2Demo.Jobs throw new ArgumentOutOfRangeException("DiSEqC Switch Position"); } - JobContext.LogWindow.Log(String.Format("Send DiSEqC Command {0:X2}", (byte)myOpcode), 8); + //JobContext.LogWindow.Log(String.Format("Send DiSEqC Command {0:X2}", (byte)myOpcode), 8); DateTime started = DateTime.Now; bool result = streamReader.SendDiSEqC((uint)2, myOpcode); TimeSpan timeTaken = DateTime.Now - started; - JobContext.LogWindow.Log(String.Format("DiSEqC Comannd sent in {0:F1} seconds.", timeTaken.TotalSeconds)); + //JobContext.LogWindow.Log(String.Format("DiSEqC Comannd sent in {0:F1} seconds.", timeTaken.TotalSeconds)); if (timeTaken.TotalSeconds > 10) { - JobContext.LogWindow.Log( - String.Format("Something went wrong while performing the DiSEqC operation, trying again..."), 8); + //JobContext.LogWindow.Log(String.Format("Something went wrong while performing the DiSEqC operation, trying again..."), 8); Thread.Sleep(1000); return SendDiseqcCommand(highBand, horizontal); } @@ -653,7 +652,7 @@ namespace SDL2Demo.Jobs foundFrequencies.Add(blindscanResult); } - JobContext.LogWindow.Log(String.Format("Found frequency: {0}, {1}", searchResult.Freq / 1000, searchResult.Pol == 0 ? "H" : "V")); + //JobContext.LogWindow.Log(String.Format("Found frequency: {0}, {1}", searchResult.Freq / 1000, searchResult.Pol == 0 ? "H" : "V")); SoundPlayer.PlaySoundFile("lock.wav"); _blindscanProgressWindow.Progress = searchResult.Freq; @@ -865,7 +864,7 @@ namespace SDL2Demo.Jobs if (caps.HasFlag(Caps.SR_SIGINFO)) { - JobContext.LogWindow.Log(String.Format("Trying to BLScanEx..."), 8); + //JobContext.LogWindow.Log(String.Format("Trying to BLScanEx..."), 8); if (!streamReader.BLScanEx(result.sr1.Freq, 5000, result.sr1.Pol, Configuration.LnbType.Lof1 * 1000, Configuration.LnbType.Lof2 * 1000, Configuration.LnbType.LofSw * 1000, 1000000, (STD_TYPE)result.sr1.StdType, @@ -880,7 +879,7 @@ namespace SDL2Demo.Jobs if (!satelliteSr.Lock) { - JobContext.LogWindow.Log(String.Format("Trying to SetChannel..."), 8); + //JobContext.LogWindow.Log(String.Format("Trying to SetChannel..."), 8); bool channel = streamReader.SetChannel(result.sr1.Freq, result.sr1.SR, result.sr1.Freq, result.sr1.FEC, Configuration.LnbType.Lof1 * 1000, Configuration.LnbType.Lof2 * 1000, Configuration.LnbType.LofSw * 1000); if (!channel) { @@ -891,7 +890,7 @@ namespace SDL2Demo.Jobs } else { - JobContext.LogWindow.Log(String.Format("Trying to get SignalInfo..."), 8); + //JobContext.LogWindow.Log(String.Format("Trying to get SignalInfo..."), 8); bool signalInfo = streamReader.SignalInfo(ref satelliteSr); if (!signalInfo) { @@ -927,7 +926,7 @@ namespace SDL2Demo.Jobs } else if (caps.HasFlag(Caps.SR_SIGINFO2)) { - JobContext.LogWindow.Log(String.Format("Trying to SetChannel2..."), 8); + //JobContext.LogWindow.Log(String.Format("Trying to SetChannel2..."), 8); bool channel2 = streamReader.SetChannel2((uint)result.sr2.Freq, (uint)result.sr2.BW); if (!channel2) { @@ -937,7 +936,7 @@ namespace SDL2Demo.Jobs return; } - JobContext.LogWindow.Log(String.Format("Trying to get SignalInfo2..."), 8); + //JobContext.LogWindow.Log(String.Format("Trying to get SignalInfo2..."), 8); bool signalInfo2 = streamReader.SignalInfo2(ref cableSr); if (!signalInfo2) { @@ -975,7 +974,7 @@ namespace SDL2Demo.Jobs { if (misMode) { - JobContext.LogWindow.Log(String.Format("Selecting MIS IS {0}", satelliteSr.IS[mis]), 8); + //JobContext.LogWindow.Log(String.Format("Selecting MIS IS {0}", satelliteSr.IS[mis]), 8); bool misSel = streamReader.MISSel(misMode, satelliteSr.IS[mis], 0xff); if (!misSel) { @@ -1003,7 +1002,7 @@ namespace SDL2Demo.Jobs } IntPtr filterReference = IntPtr.MaxValue; - JobContext.LogWindow.Log(String.Format("Set-Up filter..."), 8); + //JobContext.LogWindow.Log(String.Format("Set-Up filter..."), 8); packetsToDrop = 1024; packetsQueue = new Queue(); ourFoundFrequenciesWindow.statusPacketsInqueue = 0; @@ -1016,7 +1015,7 @@ namespace SDL2Demo.Jobs SoundPlayer.PlaySoundFile("fail.wav"); return; } - JobContext.LogWindow.Log(String.Format("Filter set-up complete!"), 8); + //JobContext.LogWindow.Log(String.Format("Filter set-up complete!"), 8); //Use the Filter result.State = BlindscanResultState.Scraping; @@ -1067,7 +1066,7 @@ namespace SDL2Demo.Jobs } ourFoundFrequenciesWindow.allowZapNow = false; //Stop Filter - JobContext.LogWindow.Log(String.Format("Deleting Filter..."), 8); + //JobContext.LogWindow.Log(String.Format("Deleting Filter..."), 8); bool stopped = streamReader.DelFilter(filterReference); if (!stopped) { @@ -1075,7 +1074,7 @@ namespace SDL2Demo.Jobs jobStorage.UpdateTransponderState(jobInDb, result.Satellite, result.sr1, result.State, result.sr2); return; } - JobContext.LogWindow.Log(String.Format("Deleted filter!"), 8); + //JobContext.LogWindow.Log(String.Format("Deleted filter!"), 8); DrainPackets(); skyscraperContext.Dispose(); @@ -1131,7 +1130,7 @@ namespace SDL2Demo.Jobs } else { - JobContext.LogWindow.Log(String.Format("odd packet size!"), 8); + //JobContext.LogWindow.Log(String.Format("odd packet size!"), 8); } } @@ -1184,8 +1183,7 @@ namespace SDL2Demo.Jobs if (packetsQueue.Count == 0) return; - JobContext.LogWindow.Log( - String.Format("{0} packets left after switching off the filter.", packetsQueue.Count), 8); + //JobContext.LogWindow.Log(String.Format("{0} packets left after switching off the filter.", packetsQueue.Count), 8); DateTime startedAt = DateTime.Now; byte[] singlePacketBuffer = new byte[188]; @@ -1206,14 +1204,11 @@ namespace SDL2Demo.Jobs drainTickerNow = DateTime.Now; if (drainTickerNow.Second != drainTickerPrevious.Second) { - JobContext.LogWindow.Log( - String.Format("{0} packets left ({1}).", packetsQueue.Count, drainTickerNow.ToLongTimeString()), - 8); + //JobContext.LogWindow.Log(String.Format("{0} packets left ({1}).", packetsQueue.Count, drainTickerNow.ToLongTimeString()),8); } } - JobContext.LogWindow.Log( - String.Format("Packets drained in {0} seconds.", (DateTime.Now - startedAt).TotalSeconds), 8); + //JobContext.LogWindow.Log(String.Format("Packets drained in {0} seconds.", (DateTime.Now - startedAt).TotalSeconds), 8); } #endregion diff --git a/GUIs/skyscraper8.UI.ImGui/Jobs/InheritedBlindscanConfigWindow.cs b/GUIs/skyscraper8.UI.ImGui/Jobs/InheritedBlindscanConfigWindow.cs index bb6f137..c93b104 100644 --- a/GUIs/skyscraper8.UI.ImGui/Jobs/InheritedBlindscanConfigWindow.cs +++ b/GUIs/skyscraper8.UI.ImGui/Jobs/InheritedBlindscanConfigWindow.cs @@ -104,7 +104,7 @@ namespace SDL2Demo.Jobs bjc.DoHorizontalLow = settingsWindowScanHorizontalLow; bjc.DoHorizontalHigh = settingsWindowScanHorizontalHigh; bjc.DoVerticalLow = settingsWindowScanVerticalLow; - bjc.DoVerticalHigh = settingsWindowScanHorizontalHigh; + bjc.DoVerticalHigh = settingsWindowScanVerticalHigh; bjc.DoCollectIqGraphs = settingsWindowCollectIqGraphs; bjc.DoCollectRfSpectrum = settingsWindowCollectRfSpectrum; bjc.DoRecordTs = settingsWindowCaptureFile; @@ -170,8 +170,7 @@ namespace SDL2Demo.Jobs ImGui.Text("This assumes that both tuners are connected to the same antenna set-up, using e.g. a splitter."); ImGui.PushID("tunerB"); - if (settingsWindowSetFilterTunerSelection - 1 < tuners.Count) - settingsWindowSetFilterTunerSelection = 0; + if (ImGui.BeginCombo("Tuner for BLScanEx and RFScan", tuners[settingsWindowSetFilterTunerSelection].Name)) { for (int i = 0; i < tuners.Count; i++) diff --git a/GUIs/skyscraper8.UI.ImGui/Jobs/InheritedBlindscanUiJunction.cs b/GUIs/skyscraper8.UI.ImGui/Jobs/InheritedBlindscanUiJunction.cs index 58b4220..8d380cb 100644 --- a/GUIs/skyscraper8.UI.ImGui/Jobs/InheritedBlindscanUiJunction.cs +++ b/GUIs/skyscraper8.UI.ImGui/Jobs/InheritedBlindscanUiJunction.cs @@ -953,6 +953,10 @@ namespace SDL2Demo.Jobs id.pid = elementaryPid; id.moduleId = moduleInfoModuleId; id.moduleVersion = moduleInfoModuleVersion; + + if (dsmCcDisplay.ContainsKey(id)) + return; + lock (dsmCcDisplay) { dsmCcDisplay.Add(id, 0); @@ -1507,7 +1511,7 @@ namespace SDL2Demo.Jobs public void NotifyBlockstreamCarrier() { - throw new NotImplementedException(); + } #region Database Callbacks diff --git a/GUIs/skyscraper8.UI.ImGui/Program.cs b/GUIs/skyscraper8.UI.ImGui/Program.cs index 29ad78a..e20208b 100644 --- a/GUIs/skyscraper8.UI.ImGui/Program.cs +++ b/GUIs/skyscraper8.UI.ImGui/Program.cs @@ -106,9 +106,9 @@ namespace SkyscraperUI object2Surface.Dispose(); object2Charset = new CharSet(object2Texture) { CharacterNumber = 4 }; - logWindow = new LogWindow(); - logWindow.Register(); - logWindow.IsOpen = ini.ReadValue("ui", "enable_log", true); ; + //logWindow = new LogWindow(); + //logWindow.Register(); + //logWindow.IsOpen = ini.ReadValue("ui", "enable_log", true); ; uiBlockingWindow = new UiBlockingWindow(); messageWindows = new List(); @@ -214,7 +214,7 @@ namespace SkyscraperUI private List satellitePositions; private List lnbTypes; private List dishTypes; - private LogWindow logWindow; + //private LogWindow logWindow; private ScrapeFromTcp scrapeFromTcpWindow; private JobContext jobContext; private CharSet object2Charset; @@ -257,7 +257,7 @@ namespace SkyscraperUI if (jobContext.MessageQueue.Count != 0) { MessageWindow messageWindow = jobContext.MessageQueue.Dequeue(); - logWindow.Log(messageWindow.Message); + //logWindow.Log(messageWindow.Message); messageWindows.Add(messageWindow); } @@ -266,7 +266,7 @@ namespace SkyscraperUI foreach (CharSet charSet in charsets) charSet.AutoMoveToHome(); - logWindow.Log(String.Format("Job completed: {0}", jobContext.Job.ToString())); + //logWindow.Log(String.Format("Job completed: {0}", jobContext.Job.ToString())); SoundPlayer.PlaySoundFile("Teleport2.wav"); jobContext = null; } @@ -496,8 +496,10 @@ namespace SkyscraperUI showPuppets = !showPuppets; if (ImGui.MenuItem("Show ImGui Demo Window", "", showDemoWindow)) showDemoWindow = !showDemoWindow; + /* if (ImGui.MenuItem("Show Log Window", "", logWindow.IsOpen)) logWindow.IsOpen = !logWindow.IsOpen; + */ if (ImGui.MenuItem("Auto-Show Log Window when job starts", "", showLogWindowOnJobStart)) showLogWindowOnJobStart = !showLogWindowOnJobStart; if (ImGui.MenuItem("Show GPS Location", "", IsDisplayingGpsLocation(), CanShowGpsLocation())) @@ -786,7 +788,7 @@ namespace SkyscraperUI } } - logWindow.Render(); + //logWindow.Render(); foreach (MessageWindow messageWindow in messageWindows) { @@ -818,8 +820,10 @@ namespace SkyscraperUI jobContext = new JobContext(); } + /* if (showLogWindowOnJobStart) logWindow.IsOpen = true; + */ job.JobContext = jobContext; @@ -827,7 +831,7 @@ namespace SkyscraperUI jobContext.ImgUiDevice = imGuiDevice; jobContext.Ini = ini; jobContext.StreamReader = streamReader; - jobContext.LogWindow = logWindow; + //jobContext.LogWindow = logWindow; jobContext.PressurePlates = new List(); jobContext.RNG = rng; jobContext.MessageQueue = new Queue(); @@ -837,7 +841,7 @@ namespace SkyscraperUI jobContext.Puppets = charsets; jobContext.DataStorage = dataStorage; jobContext.ObjectStorage = objectStorage; - jobContext.ScraperEventLogger = logWindow; + //jobContext.ScraperEventLogger = logWindow; jobContext.Thread = new Thread(job.Run); jobContext.Thread.Name = "Current Job"; jobContext.Thread.Start(); diff --git a/MpePlugins/skyscraper5.DNS/PluginDns.cs b/MpePlugins/skyscraper5.DNS/PluginDns.cs index 5a20fe5..31be9fe 100644 --- a/MpePlugins/skyscraper5.DNS/PluginDns.cs +++ b/MpePlugins/skyscraper5.DNS/PluginDns.cs @@ -71,6 +71,16 @@ namespace skyscraper5.DNS string nsrr = nameServerResourceRecord.NSDomainName.ToString(); return nsrr; } + MailExchangeResourceRecord mxRecord = record as MailExchangeResourceRecord; + if (mxRecord != null) + { + string mxrr = JsonConvert.SerializeObject(new + { + Preference = mxRecord.Preference, + ExchangeDomainName = mxRecord.ExchangeDomainName.ToString() + }); + return mxrr; + } throw new NotImplementedException(record.GetType().Name.ToString()); } diff --git a/skyscraper8/DvbI/DvbIFilesystemProcessor.cs b/skyscraper8/DvbI/DvbIFilesystemProcessor.cs index a3adc68..f267a74 100644 --- a/skyscraper8/DvbI/DvbIFilesystemProcessor.cs +++ b/skyscraper8/DvbI/DvbIFilesystemProcessor.cs @@ -88,7 +88,14 @@ namespace skyscraper8.DvbI byte[] serviceListBytes = vfs.GetFile(serviceList.URI); ServiceListType serviceListData = DvbIUtils.UnpackServiceList(serviceListBytes); HandleServiceList(serviceListData, dataStorage, serviceList.Id); - dataStorage.UpdateDvbiServiceListLastCheckedDate(serviceList.Id, context.CurrentTime); + if (!dataStorage.TestForDvbiServiceList(serviceList.Id)) + { + dataStorage.InsertDvbiServiceList(serviceList); + } + else + { + dataStorage.UpdateDvbiServiceListLastCheckedDate(serviceList.Id, context.CurrentTime); + } } } diff --git a/skyscraper8/DvbNip/DvbNipReceiver.cs b/skyscraper8/DvbNip/DvbNipReceiver.cs index 530b9eb..b10ca4f 100644 --- a/skyscraper8/DvbNip/DvbNipReceiver.cs +++ b/skyscraper8/DvbNip/DvbNipReceiver.cs @@ -12,6 +12,7 @@ using System.Text; using System.Threading.Tasks; using moe.yo3explorer.skyscraper8.DVBI.Model; using skyscraper8.DvbI; +using System.Reflection.Metadata.Ecma335; namespace skyscraper8.DvbNip { @@ -64,6 +65,10 @@ namespace skyscraper8.DvbNip } UserDatagram udpPacket = new UserDatagram(ipv4Packet); LctFrame lctFrame = new LctFrame(udpPacket.Payload); + if (lctFrame.LctHeader == null) + { + return; + } if (lctFrame.LctHeader.TimeExtenstion != null) { this.currentTime = lctFrame.LctHeader.TimeExtenstion.Sct; diff --git a/skyscraper8/Ietf/FLUTE/FluteListener.cs b/skyscraper8/Ietf/FLUTE/FluteListener.cs index 1da3b8f..e830616 100644 --- a/skyscraper8/Ietf/FLUTE/FluteListener.cs +++ b/skyscraper8/Ietf/FLUTE/FluteListener.cs @@ -72,6 +72,9 @@ namespace skyscraper8.Ietf.FLUTE if (blocks == null) blocks = new Dictionary, FluteBlock>(); + if (lctFrame.FecHeader == null) + return; + ushort sbn = lctFrame.FecHeader.SourceBlockNumber; ushort esi = lctFrame.FecHeader.EncodingSymbolId; diff --git a/skyscraper8/Ietf/FLUTE/LctFrame.cs b/skyscraper8/Ietf/FLUTE/LctFrame.cs index 2d3c5b5..0ef7fde 100644 --- a/skyscraper8/Ietf/FLUTE/LctFrame.cs +++ b/skyscraper8/Ietf/FLUTE/LctFrame.cs @@ -1,9 +1,11 @@ using skyscraper5.Skyscraper.IO; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; +using skyscraper5.Skyscraper; namespace skyscraper8.Ietf.FLUTE { @@ -25,7 +27,10 @@ namespace skyscraper8.Ietf.FLUTE this.CloseObjectFlag = (byteB & 0x01) != 0; if (this.Version != 1) - throw new NotSupportedException(String.Format("FLUTE Version {0}", Version)); + { + Debug.WriteLine(String.Format("FLUTE Version {0}", Version)); + return; + } int HeaderLength = ms.ReadUInt8(); HeaderLength *= 4; @@ -35,6 +40,8 @@ namespace skyscraper8.Ietf.FLUTE byte[] headerBuffer = ms.ReadBytes(HeaderLength); this.LctHeader = new LctHeader(headerBuffer,CongestionControlFlag,TransportSessionIdentifierFlag,TransportObjectIdentifierFlag,HalfWordFlag); + if (!this.LctHeader.Valid) + return; if (ms.GetAvailableBytes() < 4) return; diff --git a/skyscraper8/Ietf/FLUTE/LctHeader.cs b/skyscraper8/Ietf/FLUTE/LctHeader.cs index c43f520..39d83cb 100644 --- a/skyscraper8/Ietf/FLUTE/LctHeader.cs +++ b/skyscraper8/Ietf/FLUTE/LctHeader.cs @@ -2,13 +2,15 @@ using skyscraper8.DvbNip; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; +using skyscraper5.Skyscraper; namespace skyscraper8.Ietf.FLUTE { - internal class LctHeader + internal class LctHeader : Validatable { /// /// @@ -32,6 +34,11 @@ namespace skyscraper8.Ietf.FLUTE CongestionControlInformation = ReadField(ms, cciLength); TransportSessionIdentifier = ReadField(ms, tsiLength); TransportObjectIdentifier = ReadField(ms, toiLength); + if (CongestionControlInformation == UInt64.MaxValue || TransportSessionIdentifier == UInt64.MaxValue || TransportObjectIdentifier == UInt64.MaxValue) + { + Valid = false; + return; + } while (ms.GetAvailableBytes() >= 1) { @@ -49,7 +56,9 @@ namespace skyscraper8.Ietf.FLUTE this.ContentEncoding = new ContentEncodingOfFdtInstance(fixedHeaderExtension); break; default: - throw new NotImplementedException(String.Format("LCT Header Extension {0}", extensionId)); + Debug.WriteLine(String.Format("LCT Header Extension {0}", extensionId)); + Valid = false; + return; } } else @@ -58,6 +67,11 @@ namespace skyscraper8.Ietf.FLUTE headerExtensionLength *= 4; if (headerExtensionLength >= 2) headerExtensionLength -= 2; + if (headerExtensionLength > ms.GetAvailableBytes()) + { + Valid = false; + return; + } byte[] extensionBuffer = ms.ReadBytes(headerExtensionLength); switch(extensionId) { @@ -73,11 +87,15 @@ namespace skyscraper8.Ietf.FLUTE this.NipActualCarrierInformation = new NipActualCarrierInformation(extensionBuffer); break; default: - throw new NotImplementedException(String.Format("LCT Header Extension {0}", extensionId)); + Debug.WriteLine(String.Format("LCT Header Extension {0}", extensionId)); + Valid = false; + return; } } } + + Valid = true; } private ulong ReadField(Stream stream, int bits) @@ -93,7 +111,7 @@ namespace skyscraper8.Ietf.FLUTE case 64: return stream.ReadUInt64BE(); default: - throw new NotImplementedException(String.Format("{0} bits.", bits)); + return UInt64.MaxValue; } } public ulong CongestionControlInformation { get; private set; } diff --git a/skyscraper8/InteractionChannel/InteractionChannelHandler.cs b/skyscraper8/InteractionChannel/InteractionChannelHandler.cs index a746e21..e189686 100644 --- a/skyscraper8/InteractionChannel/InteractionChannelHandler.cs +++ b/skyscraper8/InteractionChannel/InteractionChannelHandler.cs @@ -26,5 +26,7 @@ namespace skyscraper5.src.InteractionChannel void OnNetworkLayerInfo(PhysicalAddress macAddress, _0xa0_NetworkLayerInfoDescriptor descriptor); void OnTransmissionModeSupport(ushort interactiveNetworkId, Tmst tmst); int GetRmtTransmissionStandard(ushort networkId); - } + void OnReturnTransmissionMOdes(PhysicalAddress macAddress, _0xb2_ReturnTransmissionModesDescriptor descriptor); + void OnConnectionControl(PhysicalAddress macAddress, _0xaf_ConnectionControlDescriptor descriptor); + } } diff --git a/skyscraper8/InteractionChannel/Model/Descriptors/0xa1_CorrectionMessageDescriptor.cs b/skyscraper8/InteractionChannel/Model/Descriptors/0xa1_CorrectionMessageDescriptor.cs index e895aaa..e48977c 100644 --- a/skyscraper8/InteractionChannel/Model/Descriptors/0xa1_CorrectionMessageDescriptor.cs +++ b/skyscraper8/InteractionChannel/Model/Descriptors/0xa1_CorrectionMessageDescriptor.cs @@ -13,8 +13,8 @@ namespace skyscraper5.src.InteractionChannel.Model.Descriptors { [SkyscraperPlugin] [TsDescriptor(0xa1, "TIM")] - public class _0xa1_CorrectionMessageDescriptor : TsDescriptor - { + public class _0xa1_CorrectionMessageDescriptor : TsDescriptor, IEquatable<_0xa1_CorrectionMessageDescriptor?> + { public _0xa1_CorrectionMessageDescriptor(byte[] buffer) { MemoryStream ms = new MemoryStream(buffer, false); @@ -79,5 +79,31 @@ namespace skyscraper5.src.InteractionChannel.Model.Descriptors EsN0 == descriptor.EsN0 && FrequencyCorrection == descriptor.FrequencyCorrection; } - } + + public bool Equals(_0xa1_CorrectionMessageDescriptor? other) + { + return other is not null && + SlotType == other.SlotType && + BurstTimeScaling == other.BurstTimeScaling && + BurstTimeCorrection == other.BurstTimeCorrection && + PowerCorrection == other.PowerCorrection && + EsN0 == other.EsN0 && + FrequencyCorrection == other.FrequencyCorrection; + } + + public override int GetHashCode() + { + return HashCode.Combine(SlotType, BurstTimeScaling, BurstTimeCorrection, PowerCorrection, EsN0, FrequencyCorrection); + } + + public static bool operator ==(_0xa1_CorrectionMessageDescriptor? left, _0xa1_CorrectionMessageDescriptor? right) + { + return EqualityComparer<_0xa1_CorrectionMessageDescriptor>.Default.Equals(left, right); + } + + public static bool operator !=(_0xa1_CorrectionMessageDescriptor? left, _0xa1_CorrectionMessageDescriptor? right) + { + return !(left == right); + } + } } diff --git a/skyscraper8/InteractionChannel/Model/Descriptors/0xaf_ConnectionControlDescriptor.cs b/skyscraper8/InteractionChannel/Model/Descriptors/0xaf_ConnectionControlDescriptor.cs index 6e0000c..61f0217 100644 --- a/skyscraper8/InteractionChannel/Model/Descriptors/0xaf_ConnectionControlDescriptor.cs +++ b/skyscraper8/InteractionChannel/Model/Descriptors/0xaf_ConnectionControlDescriptor.cs @@ -12,7 +12,7 @@ namespace skyscraper5.src.InteractionChannel.Model.Descriptors { [SkyscraperPlugin] [TsDescriptor(0xaf,"TIM")] - internal class _0xaf_ConnectionControlDescriptor : TsDescriptor + public class _0xaf_ConnectionControlDescriptor : TsDescriptor { public _0xaf_ConnectionControlDescriptor(byte[] buffer) { diff --git a/skyscraper8/InteractionChannel/Model/Tim.cs b/skyscraper8/InteractionChannel/Model/Tim.cs index 26c10b5..bfcdbeb 100644 --- a/skyscraper8/InteractionChannel/Model/Tim.cs +++ b/skyscraper8/InteractionChannel/Model/Tim.cs @@ -273,9 +273,15 @@ namespace skyscraper5.src.InteractionChannel.Model case 0xac: handler.OnCorrectionControl(macAddress, (_0xac_CorrectionControlDescriptor)descriptor); break; + case 0xaf: + handler.OnConnectionControl(macAddress, (_0xaf_ConnectionControlDescriptor)descriptor); + break; case 0xa0: handler.OnNetworkLayerInfo(macAddress, (_0xa0_NetworkLayerInfoDescriptor)descriptor); break; + case 0xb2: + handler.OnReturnTransmissionMOdes(macAddress, (_0xb2_ReturnTransmissionModesDescriptor)descriptor); + break; default: if (id >= 0xe0 && id <= 0xfe) break; diff --git a/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs b/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs index ccb8771..836625c 100644 --- a/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs +++ b/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs @@ -17,7 +17,11 @@ namespace skyscraper5.src.InteractionChannel return 0; } - public void OnContentionControl(PhysicalAddress macAddress, _0xab_ContentionControlDescriptor ccd) + public void OnConnectionControl(PhysicalAddress macAddress, _0xaf_ConnectionControlDescriptor descriptor) + { + } + + public void OnContentionControl(PhysicalAddress macAddress, _0xab_ContentionControlDescriptor ccd) { } @@ -54,7 +58,11 @@ namespace skyscraper5.src.InteractionChannel { } - public void OnSatellitePosition(ushort interactiveNetworkId, Spt spt) + public void OnReturnTransmissionMOdes(PhysicalAddress macAddress, _0xb2_ReturnTransmissionModesDescriptor descriptor) + { + } + + public void OnSatellitePosition(ushort interactiveNetworkId, Spt spt) { } diff --git a/skyscraper8/Mhp/Descriptors/0x00_ApplicationDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x00_ApplicationDescriptor.cs index 3512529..cd42db7 100644 --- a/skyscraper8/Mhp/Descriptors/0x00_ApplicationDescriptor.cs +++ b/skyscraper8/Mhp/Descriptors/0x00_ApplicationDescriptor.cs @@ -44,6 +44,7 @@ namespace skyscraper5.Mhp.Descriptors { TransportProtocolLabel[i] = ms.ReadUInt8(); } + Valid = true; } public byte[] TransportProtocolLabel { get; private set; } diff --git a/skyscraper8/Mhp/Descriptors/0x01_ApplicationNameDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x01_ApplicationNameDescriptor.cs index 6fe9e82..7967190 100644 --- a/skyscraper8/Mhp/Descriptors/0x01_ApplicationNameDescriptor.cs +++ b/skyscraper8/Mhp/Descriptors/0x01_ApplicationNameDescriptor.cs @@ -27,6 +27,7 @@ namespace skyscraper5.Mhp.Descriptors temp.Add(key, value); } ApplicationNames = new ReadOnlyDictionary(temp); + Valid = true; } public ReadOnlyDictionary ApplicationNames { get; } diff --git a/skyscraper8/Mhp/Descriptors/0x02_TransportProtocolDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x02_TransportProtocolDescriptor.cs index ecb973a..72e0f94 100644 --- a/skyscraper8/Mhp/Descriptors/0x02_TransportProtocolDescriptor.cs +++ b/skyscraper8/Mhp/Descriptors/0x02_TransportProtocolDescriptor.cs @@ -38,6 +38,7 @@ namespace skyscraper5.Mhp.Descriptors break; } } + Valid = true; } public byte TransportProtocolLabel { get; private set; } diff --git a/skyscraper8/Mhp/Descriptors/0x03_DvbJApplicationDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x03_DvbJApplicationDescriptor.cs index dcb4ab8..a7fccf2 100644 --- a/skyscraper8/Mhp/Descriptors/0x03_DvbJApplicationDescriptor.cs +++ b/skyscraper8/Mhp/Descriptors/0x03_DvbJApplicationDescriptor.cs @@ -25,6 +25,7 @@ namespace skyscraper5.Mhp.Descriptors } Args = result.ToArray(); + Valid = true; } public string[] Args { get; private set; } diff --git a/skyscraper8/Mhp/Descriptors/0x04_DvbJApplicationLocationDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x04_DvbJApplicationLocationDescriptor.cs index a096837..859f732 100644 --- a/skyscraper8/Mhp/Descriptors/0x04_DvbJApplicationLocationDescriptor.cs +++ b/skyscraper8/Mhp/Descriptors/0x04_DvbJApplicationLocationDescriptor.cs @@ -22,6 +22,7 @@ namespace skyscraper5.Mhp.Descriptors byte classPathExtensionLength = ms.ReadUInt8(); ClassPathExtension = Encoding.ASCII.GetString(ms.ReadBytes(classPathExtensionLength)); InitialClass = Encoding.ASCII.GetString(ms.ReadBytes(ms.GetAvailableBytes())); + Valid = true; } public string InitialClass { get; private set; } diff --git a/skyscraper8/Mhp/Descriptors/0x05_ExternalApplicationAuthorisationDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x05_ExternalApplicationAuthorisationDescriptor.cs index 95bcd3e..981377e 100644 --- a/skyscraper8/Mhp/Descriptors/0x05_ExternalApplicationAuthorisationDescriptor.cs +++ b/skyscraper8/Mhp/Descriptors/0x05_ExternalApplicationAuthorisationDescriptor.cs @@ -27,6 +27,7 @@ namespace skyscraper5.Mhp.Descriptors child.ApplicationId = ms.ReadUInt16BE(); child.ApplicationPriority = ms.ReadUInt8(); } + Valid = true; } public ExternalAuthorization[] Authorisations { get; set; } diff --git a/skyscraper8/Mhp/Descriptors/0x10_ApplicationStorageDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x10_ApplicationStorageDescriptor.cs index c71d904..83fad6f 100644 --- a/skyscraper8/Mhp/Descriptors/0x10_ApplicationStorageDescriptor.cs +++ b/skyscraper8/Mhp/Descriptors/0x10_ApplicationStorageDescriptor.cs @@ -27,6 +27,7 @@ namespace skyscraper5.Mhp.Descriptors Version = ms.ReadUInt32BE() & 0xefffffff; Priority = ms.ReadUInt8(); + Valid = true; } public byte Priority { get; private set; } diff --git a/skyscraper8/Mhp/Descriptors/0x13_ProviderUsageDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x13_ProviderUsageDescriptor.cs new file mode 100644 index 0000000..c0580e8 --- /dev/null +++ b/skyscraper8/Mhp/Descriptors/0x13_ProviderUsageDescriptor.cs @@ -0,0 +1,41 @@ +using skyscraper5.Mpeg2; +using skyscraper5.Skyscraper.IO; +using skyscraper5.Skyscraper.Plugins; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Mhp.Descriptors +{ + [SkyscraperPlugin] + [TsDescriptor(0x13, "AIT")] + internal class _0x13_ProviderUsageDescriptor : TsDescriptor + { + public _0x13_ProviderUsageDescriptor(byte[] buffer) + { + MemoryStream ms = new MemoryStream(buffer, false); + while (ms.GetAvailableBytes() > 2) + { + byte providerNameLength = ms.ReadUInt8(); + if (providerNameLength > 0) + { + if (ms.GetAvailableBytes() > providerNameLength) + { + if (providerNames == null) + providerNames = new List(); + providerNames.Add(ms.ReadUTF8FixedLength(providerNameLength)); + Valid = true; + } + } + } + if (providerNames == null) + Valid = false; + else if (providerNames.Count == 0) + Valid = false; + } + + private List providerNames; + } +} diff --git a/skyscraper8/Mhp/Descriptors/0x15_SimpleApplicationLocationDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x15_SimpleApplicationLocationDescriptor.cs index a691304..5ea4fd5 100644 --- a/skyscraper8/Mhp/Descriptors/0x15_SimpleApplicationLocationDescriptor.cs +++ b/skyscraper8/Mhp/Descriptors/0x15_SimpleApplicationLocationDescriptor.cs @@ -13,11 +13,12 @@ namespace skyscraper5.Mhp.Descriptors class SimpleApplicationLocationDescriptor : TsDescriptor { - public SimpleApplicationLocationDescriptor(byte[] buffer) - { - InitialPath = Encoding.ASCII.GetString(buffer); - } + public SimpleApplicationLocationDescriptor(byte[] buffer) + { + InitialPath = Encoding.ASCII.GetString(buffer); + Valid = true; + } - public string InitialPath { get; private set; } + public string InitialPath { get; private set; } } } diff --git a/skyscraper8/Mhp/Descriptors/0x16_ApplicationUsageDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x16_ApplicationUsageDescriptor.cs index d091291..e6cf78c 100644 --- a/skyscraper8/Mhp/Descriptors/0x16_ApplicationUsageDescriptor.cs +++ b/skyscraper8/Mhp/Descriptors/0x16_ApplicationUsageDescriptor.cs @@ -15,6 +15,7 @@ namespace skyscraper5.Mhp.Descriptors public ApplicationUsageDescriptor(byte[] buffer) { UsageType = buffer[0]; + Valid = true; } public byte UsageType { get; private set; } diff --git a/skyscraper8/Mhp/Descriptors/0x17_SimpleApplicationBoundaryDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x17_SimpleApplicationBoundaryDescriptor.cs index 3c9e29c..9df1007 100644 --- a/skyscraper8/Mhp/Descriptors/0x17_SimpleApplicationBoundaryDescriptor.cs +++ b/skyscraper8/Mhp/Descriptors/0x17_SimpleApplicationBoundaryDescriptor.cs @@ -24,6 +24,7 @@ namespace skyscraper5.Mhp.Descriptors byte boundaryExtensionLength = ms.ReadUInt8(); BoundaryExtensions[i] = Encoding.ASCII.GetString(ms.ReadBytes(boundaryExtensionLength)); } + Valid = true; } public string[] BoundaryExtensions { get; } diff --git a/skyscraper8/Mhp/Descriptors/0x66_OcapAbstractServiceDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x66_OcapAbstractServiceDescriptor.cs index 16b7778..635db8f 100644 --- a/skyscraper8/Mhp/Descriptors/0x66_OcapAbstractServiceDescriptor.cs +++ b/skyscraper8/Mhp/Descriptors/0x66_OcapAbstractServiceDescriptor.cs @@ -27,6 +27,7 @@ namespace skyscraper5.Mhp.Descriptors AutoSelect = (ms.ReadUInt8() & 0x01) != 0; ServiceName = Encoding.ASCII.GetString(ms.ReadBytes(ms.GetAvailableBytes())); + Valid = true; } public string ServiceName { get; private set; } diff --git a/skyscraper8/Mhp/Descriptors/0x67_OcapUnboundApplicationDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x67_OcapUnboundApplicationDescriptor.cs index 21e350b..55e8a22 100644 --- a/skyscraper8/Mhp/Descriptors/0x67_OcapUnboundApplicationDescriptor.cs +++ b/skyscraper8/Mhp/Descriptors/0x67_OcapUnboundApplicationDescriptor.cs @@ -22,6 +22,7 @@ namespace skyscraper5.Mhp.Descriptors MemoryStream ms = new MemoryStream(buffer); ServiceId = ms.ReadUInt24BE(); VersionNumber = ms.ReadUInt32BE(); + Valid = true; } public uint VersionNumber { get; private set; } diff --git a/skyscraper8/Mhp/Descriptors/0x69_OcapApplicationStorageDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x69_OcapApplicationStorageDescriptor.cs index 1738ffc..15076fb 100644 --- a/skyscraper8/Mhp/Descriptors/0x69_OcapApplicationStorageDescriptor.cs +++ b/skyscraper8/Mhp/Descriptors/0x69_OcapApplicationStorageDescriptor.cs @@ -17,6 +17,7 @@ namespace skyscraper5.Mhp.Descriptors (buffer[1], buffer[0]) = (buffer[0], buffer[1]); StoragePriority = BitConverter.ToUInt16(buffer, 0); LaunchOrder = buffer[2]; + Valid = true; } public byte LaunchOrder { get; private set; } diff --git a/skyscraper8/Mhp/Descriptors/0x70_LabelDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x70_LabelDescriptor.cs index e904c05..1f17fe0 100644 --- a/skyscraper8/Mhp/Descriptors/0x70_LabelDescriptor.cs +++ b/skyscraper8/Mhp/Descriptors/0x70_LabelDescriptor.cs @@ -16,6 +16,7 @@ namespace skyscraper5.Mhp.Descriptors { Label = Encoding.ASCII.GetString(buffer); Label = Label.Trim('\0'); + Valid = true; } public string Label { get; private set; } diff --git a/skyscraper8/Mhp/Descriptors/0x72_ConnectionRequirementDescriptor.cs b/skyscraper8/Mhp/Descriptors/0x72_ConnectionRequirementDescriptor.cs index 06010fc..c53cfd3 100644 --- a/skyscraper8/Mhp/Descriptors/0x72_ConnectionRequirementDescriptor.cs +++ b/skyscraper8/Mhp/Descriptors/0x72_ConnectionRequirementDescriptor.cs @@ -18,6 +18,7 @@ namespace skyscraper5.Mhp.Descriptors public ConnectionRequirementDescriptor(byte[] buffer) { IpConnectionRequired = (buffer[0] & 0x01) != 0; + Valid = true; } public bool IpConnectionRequired { get; private set; } diff --git a/skyscraper8/Mhp/Si/AitParser.cs b/skyscraper8/Mhp/Si/AitParser.cs index 15daf01..9bbb16e 100644 --- a/skyscraper8/Mhp/Si/AitParser.cs +++ b/skyscraper8/Mhp/Si/AitParser.cs @@ -131,6 +131,8 @@ namespace skyscraper5.Mhp.Si IEnumerable descriptors = TsDescriptorUnpacker.GetInstance().UnpackDescriptors(input, "AIT"); foreach (TsDescriptor tsDescriptor in descriptors) { + if (!tsDescriptor.Valid) + continue; //See Page 248 on ETSI TS 102 812 string name = tsDescriptor.GetType().Name; switch (name) diff --git a/skyscraper8/Program.cs b/skyscraper8/Program.cs index 6963cde..e827496 100644 --- a/skyscraper8/Program.cs +++ b/skyscraper8/Program.cs @@ -40,7 +40,7 @@ namespace skyscraper5 class Program { private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); - private const int PUBLIC_RELEASE = 8; + private const int PUBLIC_RELEASE = 9; private static void IntegrationTest() { /*List ssdpDevices = SsdpClient.GetSsdpDevices(1000).ToList(); diff --git a/skyscraper8/Properties/launchSettings.json b/skyscraper8/Properties/launchSettings.json index 6ebaf7b..5820aa7 100644 --- a/skyscraper8/Properties/launchSettings.json +++ b/skyscraper8/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "skyscraper8": { "commandName": "Project", - "commandLineArgs": "\"C:\\devel\\skyscraper8\\skyscraper8\\bin\\Debug\\net8.0\\638938290099956387.ts\"", + "commandLineArgs": "cscan tcp://127.0.0.1:6969", "remoteDebugEnabled": false }, "Container (Dockerfile)": { diff --git a/skyscraper8/QuickAndDirtySatIpClient.cs b/skyscraper8/QuickAndDirtySatIpClient.cs index 80af382..96d549d 100644 --- a/skyscraper8/QuickAndDirtySatIpClient.cs +++ b/skyscraper8/QuickAndDirtySatIpClient.cs @@ -100,12 +100,17 @@ namespace skyscraper8 rtspClient.AutoReconnect = false; Keepalive(); DiSEqC_Opcode opcode = BuildDiseqcOpcode(); - string url = RtspClient.MakeUrl(opcode, frequency, isS2, symbolRate); + 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); + 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; diff --git a/skyscraper8/SatIp/RtspClient.cs b/skyscraper8/SatIp/RtspClient.cs index 5cd33c8..cb14525 100644 --- a/skyscraper8/SatIp/RtspClient.cs +++ b/skyscraper8/SatIp/RtspClient.cs @@ -253,7 +253,17 @@ namespace skyscraper8.SatIp this.ListenIp = GetListenIp(this.TcpClient.Client.LocalEndPoint); } - public static string MakeUrl(DiSEqC_Opcode diseqcChannel, int freq, bool isS2, int symbolrate) + /// + /// 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; @@ -300,6 +310,16 @@ namespace skyscraper8.SatIp 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(); } diff --git a/skyscraper8/Skyscraper/BbframeDeencapsulator.cs b/skyscraper8/Skyscraper/BbframeDeencapsulator.cs index 595b1f8..d1d29ab 100644 --- a/skyscraper8/Skyscraper/BbframeDeencapsulator.cs +++ b/skyscraper8/Skyscraper/BbframeDeencapsulator.cs @@ -1,12 +1,15 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.NetworkInformation; -using System.Text; -using System.Threading.Tasks; +using log4net; using skyscraper5.Mpeg2; using skyscraper5.Skyscraper; using skyscraper5.Skyscraper.IO; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; namespace skyscraper8.Skyscraper { @@ -15,8 +18,11 @@ namespace skyscraper8.Skyscraper private bool interruptedGseHem; private MemoryStream interruptedGseHemBuffer; private bool interruptedGseHemWantsCrc32; + public IGsEventHandler MpeEventHandler { get; set; } - public void PushPacket(byte[] bbframe) + private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); + + public void PushPacket(byte[] bbframe) { MemoryStream ms = new MemoryStream(bbframe, false); //BBHeader @@ -44,42 +50,208 @@ namespace skyscraper8.Skyscraper return; HandleGse(ms); break; - default: //0 = generic packetized, 1 = generic continouus, 2 = gse, 3 = ts - throw new NotImplementedException(String.Format("TS/GS field says 0x{0:X2}", tsGsField)); + default: //0 = generic packetized, 1 = generic continouus, 2 = gse, 3 = ts + logger.Warn(String.Format("Unsupported: TS/GS field says 0x{0:X2}", tsGsField)); + break; } } - private bool isGseSynced; - private int gseNeeded; - private MemoryStream gseNeededBuffer; + private bool gseNeedMore; + private MemoryStream gseAssembler; + public int PID; + private void HandleGse(MemoryStream ms) { - if (!isGseSynced) + ms.Position = 10; + byte syncByte = ms.ReadUInt8(); + ms.Position = 10; + + long availableBytes = ms.GetAvailableBytes(); + byte[] readBytes = ms.ReadBytes(availableBytes); + + GseAssemblyState assemblyState = ValidateGse(gseAssembler); + if (assemblyState == GseAssemblyState.NOT_YET_BEGUN) { - ms.Position = 10; - byte syncByte = ms.ReadUInt8(); - ms.Position = 10; if ((syncByte & 0xc0) == 0xc0) { - isGseSynced = true; + //Aktuell ist der GSE Assembler nicht beschäftigt, aber wir haben ein Sync-Byte, also kann er loslegen. + gseAssembler = new MemoryStream(); + gseAssembler.Write(readBytes, 0, readBytes.Length); + return; } else { + //Aktuell ist der GSE Assembler nicht beschäftigt, und wir haben kein gültiges Sync-Byte, also weg damit. + //Console.WriteLine("gse not in sync yet. sync byte = {0}", syncByte); return; } } - if (gseNeeded > 0) + else if (assemblyState == GseAssemblyState.NEED_MORE_DATA) { - int blockSize = (int)System.Math.Min(gseNeeded, ms.GetAvailableBytes()); - gseNeededBuffer.Write(ms.ReadBytes(blockSize), 0, blockSize); - gseNeeded -= blockSize; - if (gseNeeded == 0) + gseAssembler.Write(readBytes, 0, readBytes.Length); + return; + } + else if (assemblyState == GseAssemblyState.VALID) + { + gseAssembler.Position = 0; + AssembleGse(gseAssembler); + //Console.WriteLine("assembled {0} next sync byte is {1}", sucessfulAssembles++,syncByte); + if (sucessfulAssembles == 181) { - int payloadSize = (int)gseNeededBuffer.Position; - gseNeededBuffer.Position = 0; - byte[] payloadBuffer = gseNeededBuffer.ReadBytes(payloadSize); + + } + gseAssembler = null; + HandleGse(ms); + return; + } + else if (assemblyState == GseAssemblyState.BROKEN_SUSPECT_ETHERTYPE) + { + gseAssembler = null; + HandleGse(ms); + return; + } + else if (assemblyState == GseAssemblyState.BROKEN_NEGATIVE_LENGTH) + { + gseAssembler = null; + HandleGse(ms); + return; + } + else + { + throw new NotImplementedException(String.Format("Unknown GSE assembler state: {0}, sync byte 0x{1}", assemblyState, syncByte)); + } + } + + private long sucessfulAssembles; + enum GseAssemblyState + { + NOT_YET_BEGUN, + VALID, + BROKEN_NEGATIVE_LENGTH, + NEED_MORE_DATA, + BROKEN_SUSPECT_LENGTH, + BROKEN_SUSPECT_ETHERTYPE + } + + private GseAssemblyState ValidateGse(MemoryStream ms) + { + if (ms == null) + return GseAssemblyState.NOT_YET_BEGUN; + + long backupPosition = ms.Position; + ms.Position = 0; + while (ms.GetAvailableBytes() > 2) + { + //GSE-Header + byte byteA = ms.ReadUInt8(); + bool startIndicator = (byteA & 0x80) != 0; + bool endIndicator = (byteA & 0x40) != 0; + int labelIndicator = (byteA & 0x30) >> 4; + if (!startIndicator && !endIndicator && labelIndicator == 0) + { + //end of base band frame + ms.Position = backupPosition; + return GseAssemblyState.VALID; + } + else + { + byte byteB = ms.ReadUInt8(); + int gseLength = byteA & 0x0f; + gseLength <<= 8; + gseLength += byteB; + //Console.WriteLine("GSE Length: {0}", gseLength); + if (gseLength > 9000) + { + ms.Position = backupPosition; + return GseAssemblyState.BROKEN_SUSPECT_LENGTH; + } + + if (!startIndicator || !endIndicator) + { + byte fragId = ms.ReadUInt8(); + gseLength--; + } + + if (startIndicator && !endIndicator) + { + ushort totalLength = ms.ReadUInt16BE(); + gseLength -= 2; + } + + if (startIndicator) + { + if (2 > ms.GetAvailableBytes()) + { + ms.Position = backupPosition; + return GseAssemblyState.NEED_MORE_DATA; + } + ushort protocolType = ms.ReadUInt16BE(); + if (!ValidateEthertype(protocolType)) + { + ms.Position = backupPosition; + return GseAssemblyState.BROKEN_SUSPECT_ETHERTYPE; + } + gseLength -= 2; + if (labelIndicator == 0) + { + if (6 > ms.GetAvailableBytes()) + { + ms.Position = backupPosition; + return GseAssemblyState.NEED_MORE_DATA; + } + PhysicalAddress sixByteLabel = new PhysicalAddress(ms.ReadBytes(6)); + gseLength -= 6; + } + else if (labelIndicator == 1) + { + byte[] threeByteLabel = ms.ReadBytes(3); + gseLength -= 3; + } + } + + if (!startIndicator && endIndicator) + gseLength -= 4; + + int startCrc32 = (int)ms.Position; + + if (gseLength < 0) + { + ms.Position = backupPosition; + return GseAssemblyState.BROKEN_NEGATIVE_LENGTH; + } + + if (gseLength > ms.GetAvailableBytes()) + { + ms.Position = backupPosition; + return GseAssemblyState.NEED_MORE_DATA; + } + + ms.Position += gseLength; + if (!startIndicator && endIndicator) + { + uint crc32 = ms.ReadUInt32BE(); + int endCrc32 = (int)ms.Position; + DvbCrc32.ValidateCrc(ms, startCrc32, endCrc32); + } } } + + ms.Position = backupPosition; + return GseAssemblyState.VALID; + } + + private bool ValidateEthertype(ushort ethertype) + { + if (ethertype == 0x0800) + return true; //IPv4 + if (ethertype == 0x86DD) + return true; //IPv6 + else + return false; //There are many more valid values, but since we don't speak anything aside from IPv4/IPv6, we discard it. + } + private void AssembleGse(MemoryStream ms) + { + ushort protocolType = 0; while (ms.GetAvailableBytes() > 2) { //GSE-Header @@ -98,7 +270,7 @@ namespace skyscraper8.Skyscraper int gseLength = byteA & 0x0f; gseLength <<= 8; gseLength += byteB; - + if (!startIndicator || !endIndicator) { byte fragId = ms.ReadUInt8(); @@ -113,7 +285,7 @@ namespace skyscraper8.Skyscraper if (startIndicator) { - ushort protocolType = ms.ReadUInt16BE(); + protocolType = ms.ReadUInt16BE(); gseLength -= 2; if (labelIndicator == 0) { @@ -131,15 +303,7 @@ namespace skyscraper8.Skyscraper gseLength -= 4; int startCrc32 = (int)ms.Position; - - if (gseLength > ms.GetAvailableBytes()) - { - gseNeeded = gseLength; - gseNeededBuffer = new MemoryStream(); - gseNeeded -= (int)ms.GetAvailableBytes(); - gseNeededBuffer.Write(ms.ReadBytes(ms.GetAvailableBytes())); - return; - } + byte[] payload = ms.ReadBytes(gseLength); if (!startIndicator && endIndicator) { @@ -148,9 +312,19 @@ namespace skyscraper8.Skyscraper DvbCrc32.ValidateCrc(ms, startCrc32, endCrc32); } - + switch (protocolType) + { + case 0x0800: //IPv4 + MpeEventHandler.OnIpDatagram(PID, payload); + break; + default: + //throw new NotImplementedException(String.Format("Unknown GSE Protocol ID 0x{0:X4}", protocolType)); + break; + } } } } + + } } diff --git a/skyscraper8/Skyscraper/DigitalDevicesBbFrameReader.cs b/skyscraper8/Skyscraper/DigitalDevicesBbFrameReader.cs index 03872c8..7787b96 100644 --- a/skyscraper8/Skyscraper/DigitalDevicesBbFrameReader.cs +++ b/skyscraper8/Skyscraper/DigitalDevicesBbFrameReader.cs @@ -40,36 +40,13 @@ namespace skyscraper5.src.Skyscraper { byte[] chi = outbuf.ToArray(); if (deencapsulator == null) + { deencapsulator = new BbframeDeencapsulator(); + deencapsulator.MpeEventHandler = mpeEventHandler; + deencapsulator.PID = pid; + } + deencapsulator.PushPacket(chi); - /*List ipPackets = IpPacketFinder.LookForIpPackets(outbuf.ToArray()); - if (ipPackets != null) - { - foreach (byte[] ipPacket in ipPackets) - { - mpeEventHandler.OnIpDatagram(0x118, ipPacket); - packetsRecovered++; - } - } - else - { - packetsLost++; - }*/ - /*byte[] ipPacket = IpPacketFinder.LookForIpPacket(outbuf.ToArray(), 32); - if (ipPacket != null) - { - if (!annoncementDone) - { - mpeEventHandler.GsIpTrafficDetected(); - annoncementDone = true; - } - mpeEventHandler.OnIpDatagram(0x0118, ipPacket); - packetsRecovered++; - } - else - { - packetsLost++; - }*/ } outbuf = new MemoryStream(); outbuf.Write(packets,9, packets[7] - 1); diff --git a/skyscraper8/Skyscraper/FrequencyListGenerator/BaseBlindscanJob.cs b/skyscraper8/Skyscraper/FrequencyListGenerator/BaseBlindscanJob.cs index 6f0174c..b75338d 100644 --- a/skyscraper8/Skyscraper/FrequencyListGenerator/BaseBlindscanJob.cs +++ b/skyscraper8/Skyscraper/FrequencyListGenerator/BaseBlindscanJob.cs @@ -735,7 +735,7 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator config.DataStorage.UpdateTransponderState(jobInDb, result.IsSatellite(), result.SearchResult, result.State, result.SearchResult2); config.Ui.OnBlindscanFilterSetUp(); - SkipFilter skipper = new SkipFilter(SkipFilter.CRAZYSCAN_BUFFER * 8); + SkipFilter skipper = new SkipFilter(SkipFilter.CRAZYSCAN_BUFFER * 10); skyscraperContext = SkyscraperContextFactory.CreateSkyscraper(config.DataStorage, config.ObjectStorage); skyscraperContext.TcpProxyEnabled = true; skyscraperContext.UiJunction = config.Ui; diff --git a/skyscraper8/Skyscraper/FrequencyListGenerator/CoopBlindscanStreamReaderProxy.cs b/skyscraper8/Skyscraper/FrequencyListGenerator/CoopBlindscanStreamReaderProxy.cs index f484657..3c426d4 100644 --- a/skyscraper8/Skyscraper/FrequencyListGenerator/CoopBlindscanStreamReaderProxy.cs +++ b/skyscraper8/Skyscraper/FrequencyListGenerator/CoopBlindscanStreamReaderProxy.cs @@ -333,7 +333,7 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator public bool MISSel(bool bEnable, byte misFilter, byte misFilterMask) { - throw new NotImplementedException(); + return _proxiedStreamReader.MISSel(bEnable, misFilter, misFilterMask); } public bool PLSSel(byte plsMode, uint code) diff --git a/skyscraper8/Skyscraper/FrequencyListGenerator/SatIpWithStreamReaderProxy.cs b/skyscraper8/Skyscraper/FrequencyListGenerator/SatIpWithStreamReaderProxy.cs index 0d116cb..a8a563f 100644 --- a/skyscraper8/Skyscraper/FrequencyListGenerator/SatIpWithStreamReaderProxy.cs +++ b/skyscraper8/Skyscraper/FrequencyListGenerator/SatIpWithStreamReaderProxy.cs @@ -86,7 +86,7 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator public bool StopDVB() { - throw new NotImplementedException(); + return ProxiedStreamReader.StopDVB(); } public bool GetTunerType(ref STD_TYPE type) @@ -144,7 +144,7 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator { rtspClient = new RtspClient(satIpServerAddress, 554); RtspKeepalive(); - rtspUrl = RtspClient.MakeUrl(satIpDiseqc, satipFrequency, satIpS2Mode, satipSymbolrate); + rtspUrl = RtspClient.MakeUrl(satIpDiseqc, satipFrequency, satIpS2Mode, satipSymbolrate, satIpMisEnabled ? satIpMisFilter : null, false); RtspDescribeResponse describe = rtspClient.GetDescribe(rtspUrl); if (describe.RtspStatusCode != 200) { @@ -316,7 +316,7 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator public bool RFScan(int freq, int pol, int lof1, int lof2, int lofsw, out double pRFLevel) { - throw new NotImplementedException(); + return ProxiedStreamReader.RFScan(freq, pol, lof1, lof2, lofsw, out pRFLevel); } public bool FFTInit() @@ -339,6 +339,7 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator public bool BLScanEx(int freq, int freq_range, int pol, int lof1, int lof2, int lofsw, int minsr, STD_TYPE std, ref SearchResult pSearchResult) { + satIpMisEnabled = false; bool result = ProxiedStreamReader.BLScanEx(freq, freq_range, pol, lof1, lof2, lofsw, minsr, std, ref pSearchResult); if (result) { @@ -396,7 +397,7 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator public bool IQScan(uint input, sbyte[] pIQ, uint num) { - throw new NotImplementedException(); + return ProxiedStreamReader.IQScan(input, pIQ, num); } public bool IQScan2(uint point, short[] pIQ, uint num) @@ -429,9 +430,15 @@ namespace skyscraper8.Skyscraper.FrequencyListGenerator throw new NotImplementedException(); } + private bool satIpMisEnabled; + private byte satIpMisFilter; + private byte satIpMisFilterMask; public bool MISSel(bool bEnable, byte misFilter, byte misFilterMask) { - throw new NotImplementedException(); + this.satIpMisEnabled = bEnable; + this.satIpMisFilter = misFilter; + this.satIpMisFilterMask = misFilterMask; + return ProxiedStreamReader.MISSel(bEnable, misFilter, misFilterMask); } public bool PLSSel(byte plsMode, uint code) diff --git a/skyscraper8/Skyscraper/IpPacketFinder.cs b/skyscraper8/Skyscraper/IpPacketFinder.cs index 45dd2bc..ea64f8d 100644 --- a/skyscraper8/Skyscraper/IpPacketFinder.cs +++ b/skyscraper8/Skyscraper/IpPacketFinder.cs @@ -10,6 +10,11 @@ namespace skyscraper5.Skyscraper internal class IpPacketFinder { public static byte[] LookForIpPacket(byte[] gsPacket, int searchDepth = 16) + { + int offset; + return LookForIpPacket(gsPacket, out offset, searchDepth); + } + public static byte[] LookForIpPacket(byte[] gsPacket, out int offset, int searchDepth = 16) { byte[] ipBuffer = new byte[20]; @@ -17,7 +22,10 @@ namespace skyscraper5.Skyscraper { int v4HeaderEnd = i + 20; if (v4HeaderEnd > gsPacket.Length) + { + offset = -1; return null; + } if (gsPacket[i] == 0x45) { @@ -28,15 +36,19 @@ namespace skyscraper5.Skyscraper int payloadStart = i + ipBuffer.Length; int payloadEnd = i + ipv4.TotalLength; if (payloadEnd > gsPacket.Length) + { + offset = -1; return null; + } int packetLength = payloadEnd - i; byte[] finalPacket = new byte[packetLength]; Array.Copy(gsPacket, i, finalPacket, 0, packetLength); + offset = i; return finalPacket; } } - + offset = -1; return null; } diff --git a/skyscraper8/Skyscraper/Scraper/CaSystemNames.cs b/skyscraper8/Skyscraper/Scraper/CaSystemNames.cs index 382297d..8ba068b 100644 --- a/skyscraper8/Skyscraper/Scraper/CaSystemNames.cs +++ b/skyscraper8/Skyscraper/Scraper/CaSystemNames.cs @@ -80,7 +80,8 @@ namespace skyscraper5.Skyscraper.Scraper 0x06EA, /* TSReaderLite */ 0x0692, 0x0919, 0x0961, 0x09ac, - 0x0642 + 0x0642, + 0x0652 }; public static string GetHumanReadableName(ushort id) @@ -319,6 +320,9 @@ namespace skyscraper5.Skyscraper.Scraper if ((id >= 0x1ec0) && (id <= 0x1ec2)) return "Cryptoguard"; + if ((id == 0x0652) ||(id == 0x0651)) + return "Irdeto"; + return "???"; } } diff --git a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs index 4a7bdbb..bc3e32f 100644 --- a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs +++ b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs @@ -1668,6 +1668,10 @@ namespace skyscraper5.Skyscraper.Scraper StorageConnectionManager storageConnectionManager = StorageConnectionManager.GetInstance(); ipTrafficHandler = storageConnectionManager.GetDefaultIpTrafficHandler(); } + if (payload.Length == 0) + { + return; + } ipTrafficHandler?.HandlePacket(pid, payload); @@ -2481,7 +2485,7 @@ namespace skyscraper5.Skyscraper.Scraper public void AutodetectionRuleOut(int pid, Contestant contestant, ProgramContext programContext) { - LogEvent(SkyscraperContextEvent.StreamTypeAutodetection, String.Format("PID 0x{0:X4} probably isn't a {1}", pid, contestant.Tag)); + //LogEvent(SkyscraperContextEvent.StreamTypeAutodetection, String.Format("PID 0x{0:X4} probably isn't a {1}", pid, contestant.Tag)); } void SgtEventHandler.AnnounceSgtList(SgtList list) @@ -2996,5 +3000,15 @@ namespace skyscraper5.Skyscraper.Scraper { return ObjectStorage.NdsSsuTestFile(CurrentNetworkId, CurrentTransportStreamId, pid, tableIdExtension); } + + public void OnReturnTransmissionMOdes(PhysicalAddress macAddress, _0xb2_ReturnTransmissionModesDescriptor descriptor) + { + //TODO: Implement this. + } + + public void OnConnectionControl(PhysicalAddress macAddress, _0xaf_ConnectionControlDescriptor descriptor) + { + //TODO: Implement this. + } } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs index c047c50..9441e6a 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs @@ -1363,9 +1363,14 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory _timContainers.Add(mac, new TimContainer()); } + private HashSet> _timCorrections; public bool CorrectTim(PhysicalAddress mac, _0xa1_CorrectionMessageDescriptor cmd) { - throw new NotImplementedException(); + if (_timCorrections == null) + _timCorrections = new HashSet>(); + + Tuple child = new Tuple(mac, cmd); + return _timCorrections.Add(child); } public bool ContentionTim(PhysicalAddress mac, _0xab_ContentionControlDescriptor ccdNew) diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs index 111922c..f2b2b06 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs @@ -15,7 +15,7 @@ using System.Threading.Tasks; namespace skyscraper5.src.Skyscraper.Scraper.StreamAutodetection.Contestants { [SkyscraperPlugin] - internal class InteractionChannelContestant : Contestant, InteractionChannelHandler, IDisposable + internal class InteractionChannelContestant : Contestant, InteractionChannelHandler, IDisposable { public InteractionChannelContestant(int pid) : base("Interaction channel for satellite distribution systems",pid) @@ -170,5 +170,18 @@ namespace skyscraper5.src.Skyscraper.Scraper.StreamAutodetection.Contestants } } } - } + + public void OnReturnTransmissionMOdes(PhysicalAddress macAddress, _0xb2_ReturnTransmissionModesDescriptor descriptor) + { + if (descriptor.Superframes.Length > 0) + { + Score++; + } + } + + public void OnConnectionControl(PhysicalAddress macAddress, _0xaf_ConnectionControlDescriptor descriptor) + { + Score++; + } + } } diff --git a/skyscraper8/Skyscraper/Text/AsciiTable.cs b/skyscraper8/Skyscraper/Text/AsciiTable.cs index cf81753..10d616f 100644 --- a/skyscraper8/Skyscraper/Text/AsciiTable.cs +++ b/skyscraper8/Skyscraper/Text/AsciiTable.cs @@ -139,6 +139,7 @@ namespace skyscraper5.Skyscraper.Text case 0x7c: resultBuilder.Append('|'); break; case 0x7d: resultBuilder.Append('}'); break; case 0x7e: resultBuilder.Append('~'); break; + case 0x7f: resultBuilder.Append('\u007f'); break; default: throw new NotImplementedException(String.Format("0x{0:X2}", req)); } diff --git a/skyscraper8/Skyscraper/Text/En300468TextDecoder.cs b/skyscraper8/Skyscraper/Text/En300468TextDecoder.cs index c0c1950..990ee4e 100644 --- a/skyscraper8/Skyscraper/Text/En300468TextDecoder.cs +++ b/skyscraper8/Skyscraper/Text/En300468TextDecoder.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Text; using skyscraper5.Dvb; using skyscraper5.Skyscraper.Plugins; @@ -64,6 +65,9 @@ namespace skyscraper5.Skyscraper.Text public string Decode(byte[] buffer, int offset, int length) { byte[] copy = new byte[length]; + int endOffset = offset + length; + if (endOffset > buffer.Length) + return null; Array.Copy(buffer, offset, copy, 0, length); return Decode(copy); } @@ -93,7 +97,10 @@ namespace skyscraper5.Skyscraper.Text ushort sb = buffer[1]; ushort tb = buffer[2]; if (sb != 0x00) - throw new NotImplementedException("reserved"); + { + Debug.WriteLine(String.Format("Found invalid character coding: 0x{0:X2}{1:X2}", buffer[0], sb)); + return null; + } if (tb >= 0x10) throw new NotImplementedException("reserved"); lastUsedEncoding = iso8859Mapping[tb]; @@ -111,8 +118,9 @@ namespace skyscraper5.Skyscraper.Text _textDecoders = PluginManager.GetInstance().GetTextDecoders(); TextDecoder matchingTextDecoder = _textDecoders[buffer[1]]; if (matchingTextDecoder == null) - { - throw new TextException(String.Format("No decoder for Encoding type ID 0x{0:X2}", buffer[1])); + { + //TODO: Add logger message here. + return null; } return matchingTextDecoder.Decode(buffer); } diff --git a/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-1.cs b/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-1.cs index 86dd20f..747e1f4 100644 --- a/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-1.cs +++ b/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-1.cs @@ -26,11 +26,13 @@ namespace skyscraper5.Skyscraper.Text.Encodings case 0xb2: resultBuilder.Append('²'); break; case 0xb4: resultBuilder.Append('´'); break; case 0xbc: resultBuilder.Append('¼'); break; + case 0xc0: resultBuilder.Append('À'); break; case 0xc1: resultBuilder.Append('Á'); break; case 0xc4: resultBuilder.Append('Ä'); break; case 0xc7: resultBuilder.Append('Ç'); break; case 0xc9: resultBuilder.Append('É'); break; case 0xcb: resultBuilder.Append('¼'); break; + case 0xd6: resultBuilder.Append('Ö'); break; case 0xdc: resultBuilder.Append('Ü'); break; case 0xdf: resultBuilder.Append('ß'); break; case 0xe0: resultBuilder.Append('à'); break; @@ -45,6 +47,7 @@ namespace skyscraper5.Skyscraper.Text.Encodings case 0xeb: resultBuilder.Append('ë'); break; case 0xec: resultBuilder.Append('ì'); break; case 0xed: resultBuilder.Append('í'); break; + case 0xee: resultBuilder.Append('î'); break; case 0xef: resultBuilder.Append('ï'); break; case 0xf1: resultBuilder.Append('ñ'); break; case 0xf2: resultBuilder.Append('ò'); break; @@ -54,6 +57,7 @@ namespace skyscraper5.Skyscraper.Text.Encodings case 0xf8: resultBuilder.Append('ø'); break; case 0xf9: resultBuilder.Append('ù'); break; case 0xfa: resultBuilder.Append('ú'); break; + case 0xfb: resultBuilder.Append('û'); break; case 0xfc: resultBuilder.Append('ü'); break; default: throw new NotImplementedException(String.Format("0x{0:X2}", preprocessed[i])); diff --git a/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-11.cs b/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-11.cs index 5828aa5..3538605 100644 --- a/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-11.cs +++ b/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-11.cs @@ -23,6 +23,7 @@ namespace skyscraper5.Skyscraper.Text.Encodings { case 0x7f: break; case 0xa0: resultBuilder.Append('\u00a0'); break; + case 0xa7: resultBuilder.Append('§'); break; case 0xa9: resultBuilder.Append('Đ'); break; case 0xaa: resultBuilder.Append('Š'); break; case 0xac: resultBuilder.Append('Ž'); break; @@ -32,6 +33,7 @@ namespace skyscraper5.Skyscraper.Text.Encodings case 0xb9: resultBuilder.Append('đ'); break; case 0xba: resultBuilder.Append('š'); break; case 0xbc: resultBuilder.Append('ž'); break; + case 0xbd: resultBuilder.Append('―'); break; case 0xbe: resultBuilder.Append('ū'); break; case 0xc1: resultBuilder.Append('Á'); break; case 0xc2: resultBuilder.Append('Â'); break; diff --git a/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-13.cs b/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-13.cs index 2a40135..2b4a0e8 100644 --- a/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-13.cs +++ b/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-13.cs @@ -14,7 +14,7 @@ namespace skyscraper5.Skyscraper.Text.Encodings StringBuilder resultBuilder = new StringBuilder(); for (int i = 0; i < preprocessed.Length; i++) { - if (preprocessed[i] <= 0x7e) + if (preprocessed[i] <= 0x7f) { AsciiTable.GetAsciiChar(preprocessed[i], resultBuilder); continue; @@ -23,20 +23,25 @@ namespace skyscraper5.Skyscraper.Text.Encodings { case 0xa0: resultBuilder.Append('\u00a0'); break; case 0xa1: resultBuilder.Append('”'); break; + case 0xa2: resultBuilder.Append("¢"); break; case 0xa3: resultBuilder.Append('£'); break; case 0xa5: resultBuilder.Append('„'); break; case 0xa7: resultBuilder.Append('§'); break; case 0xa8: resultBuilder.Append('Ø'); break; + case 0xa9: resultBuilder.Append('©'); break; + case 0xaa: resultBuilder.Append('Ŗ'); break; case 0xab: resultBuilder.Append('«'); break; case 0xac: resultBuilder.Append('¬'); break; case 0xad: resultBuilder.Append('\u00ad'); break; case 0xae: resultBuilder.Append('®'); break; + case 0xaf: resultBuilder.Append('Æ'); break; case 0xb0: resultBuilder.Append('°'); break; case 0xb4: resultBuilder.Append('“'); break; case 0xb8: resultBuilder.Append('ø'); break; case 0xb9: resultBuilder.Append('¹'); break; case 0xbb: resultBuilder.Append('»'); break; case 0xbf: resultBuilder.Append('æ'); break; + case 0xc2: resultBuilder.Append('Ā'); break; case 0xc3: resultBuilder.Append('Ć'); break; case 0xc4: resultBuilder.Append('Ä'); break; case 0xc5: resultBuilder.Append('Å'); break; @@ -44,11 +49,13 @@ namespace skyscraper5.Skyscraper.Text.Encodings case 0xc8: resultBuilder.Append('Č'); break; case 0xc9: resultBuilder.Append('É'); break; case 0xca: resultBuilder.Append('Ź'); break; + case 0xcc: resultBuilder.Append('Ģ'); break; case 0xce: resultBuilder.Append('Ī'); break; case 0xcf: resultBuilder.Append('Ļ'); break; case 0xd0: resultBuilder.Append('Š'); break; case 0xd1: resultBuilder.Append('Ń'); break; case 0xd3: resultBuilder.Append('Ó'); break; + case 0xd4: resultBuilder.Append('Ō'); break; case 0xd6: resultBuilder.Append('Ö'); break; case 0xd9: resultBuilder.Append('Ł'); break; case 0xda: resultBuilder.Append('Ś'); break; @@ -66,6 +73,7 @@ namespace skyscraper5.Skyscraper.Text.Encodings case 0xe9: resultBuilder.Append('é'); break; case 0xea: resultBuilder.Append('ź'); break; case 0xeb: resultBuilder.Append('ė'); break; + case 0xec: resultBuilder.Append('ģ'); break; case 0xed: resultBuilder.Append('ķ'); break; case 0xee: resultBuilder.Append('ī'); break; case 0xf0: resultBuilder.Append('š'); break; diff --git a/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-6.cs b/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-6.cs index 6bd0821..c3eef64 100644 --- a/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-6.cs +++ b/skyscraper8/Skyscraper/Text/Encodings/dvb-iso-8859-6.cs @@ -18,7 +18,9 @@ namespace skyscraper5.Skyscraper.Text.Encodings switch (preprocessed[i]) { case 0x00: break; //Null + case 0x03: return resultBuilder.ToString().ToCharArray(); //End of Text case 0x0a: resultBuilder.Append('\n'); break; + case 0x0d: resultBuilder.Append('\u0013'); break; //Carriage return case 0x10: break; //Data Link Escape case 0x12: break; //Device Control 2 case 0x13: break; //Device Control 3 @@ -49,6 +51,7 @@ namespace skyscraper5.Skyscraper.Text.Encodings case 0x39: resultBuilder.Append(!arabMode ? '9' : '٩'); break; case 0x3a: resultBuilder.Append(':'); break; case 0x3b: resultBuilder.Append(';'); break; + case 0x3c: resultBuilder.Append('<'); break; case 0x3f: resultBuilder.Append('?'); break; case 0x40: resultBuilder.Append('@'); break; case 0x41: resultBuilder.Append('A'); arabMode = false; break; @@ -104,6 +107,7 @@ namespace skyscraper5.Skyscraper.Text.Encodings case 0x79: resultBuilder.Append('y'); arabMode = false; break; case 0x7a: resultBuilder.Append('z'); arabMode = false; break; case 0xa0: resultBuilder.Append('\u00a0'); break; + case 0xa4: resultBuilder.Append('\u00a4'); break; case 0xac: resultBuilder.Append('،'); arabMode = true; break; case 0xb2: break; case 0xbb: resultBuilder.Append('؛'); arabMode = true; break; @@ -135,6 +139,7 @@ namespace skyscraper5.Skyscraper.Text.Encodings case 0xd9: resultBuilder.Append('ع'); arabMode = true; break; case 0xda: resultBuilder.Append('غ'); arabMode = true; break; case 0xdb: resultBuilder.Append('؛'); arabMode = true; break; + case 0xdd: break; //doesn't seem to be mapped? case 0xe0: resultBuilder.Append('ـ'); arabMode = true; break; case 0xe1: resultBuilder.Append('ف'); arabMode = true; break; case 0xe2: resultBuilder.Append('ق'); arabMode = true; break; @@ -154,6 +159,8 @@ namespace skyscraper5.Skyscraper.Text.Encodings case 0xf0: resultBuilder.Append('\u0650'); arabMode = true; break; case 0xf1: resultBuilder.Append('\u0651'); arabMode = true; break; case 0xf2: resultBuilder.Append('\u0652'); arabMode = true; break; + case 0xfb: break; + case 0xfc: break; default: throw new NotImplementedException(String.Format("0x{0:X2}", preprocessed[i])); } diff --git a/skyscraper8/T2MI/Packets/0x21_IndividualAddressing.cs b/skyscraper8/T2MI/Packets/0x21_IndividualAddressing.cs index 472938b..d54ba58 100644 --- a/skyscraper8/T2MI/Packets/0x21_IndividualAddressing.cs +++ b/skyscraper8/T2MI/Packets/0x21_IndividualAddressing.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using skyscraper5.Skyscraper.IO; using skyscraper5.Skyscraper.Plugins; using skyscraper5.T2MI.Packets.AdressingFunctions; +using skyscraper8.T2MI.Packets.AdressingFunctions; namespace skyscraper5.T2MI.Packets { @@ -86,16 +87,16 @@ namespace skyscraper5.T2MI.Packets case 0x01: throw new NotImplementedException("Transmitter frequency offset"); case 0x02: result = new _0x02_TransmitterPower(functionBody); break; case 0x03: throw new NotImplementedException("Private data"); - case 0x04: throw new NotImplementedException("Cell ID"); + case 0x04: result = new _0x04_CellId(functionBody); break; case 0x05: throw new NotImplementedException("Enable"); case 0x06: throw new NotImplementedException("Bandwidth"); case 0x10: throw new NotImplementedException("ACE-PAPR"); case 0x11: result = new _0x11_TransmitterMisoGroup(functionBody); break; - case 0x12: throw new NotImplementedException("TR-PAPR"); + case 0x12: result = new _0x12_TrPapr(functionBody); break; case 0x13: result = new _0x13_L1AcePapr(functionBody); break; case 0x15: throw new NotImplementedException("TX-SIG FEF: Sequence Numbers"); case 0x16: throw new NotImplementedException("TX-SIG Aux stream: Transmitter ID"); - case 0x17: throw new NotImplementedException("Frequency"); + case 0x17: result = new _0x17_Frequency(functionBody); break; } if (result == null) diff --git a/skyscraper8/T2MI/Packets/AdressingFunctions/0x04_CellId.cs b/skyscraper8/T2MI/Packets/AdressingFunctions/0x04_CellId.cs new file mode 100644 index 0000000..7be1242 --- /dev/null +++ b/skyscraper8/T2MI/Packets/AdressingFunctions/0x04_CellId.cs @@ -0,0 +1,31 @@ +using skyscraper5.Skyscraper.IO; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper5.T2MI.Packets.AdressingFunctions +{ + internal class _0x04_CellId : AddressingFunction + { + public _0x04_CellId(byte[] buffer) + : base(0x02, true, true) + { + if (buffer.Length != 3) + { + Valid = false; + return; + } + + MemoryStream ms = new MemoryStream(buffer, false); + CellId = ms.ReadUInt16BE(); + + byte v = ms.ReadUInt8(); + WaitForEnableFlag = (v & 0x80) != 0; + } + + public ushort CellId { get; } + public bool WaitForEnableFlag { get; } + } +} diff --git a/skyscraper8/T2MI/Packets/AdressingFunctions/0x12_TrPapr.cs b/skyscraper8/T2MI/Packets/AdressingFunctions/0x12_TrPapr.cs new file mode 100644 index 0000000..097290a --- /dev/null +++ b/skyscraper8/T2MI/Packets/AdressingFunctions/0x12_TrPapr.cs @@ -0,0 +1,29 @@ +using skyscraper5.Skyscraper.IO; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper5.T2MI.Packets.AdressingFunctions +{ + internal class _0x12_TrPapr : AddressingFunction + { + public _0x12_TrPapr(byte[] buffer) + : base(0x12, false, true) + { + if (buffer.Length != 5) + { + Valid = false; + return; + } + + MemoryStream ms = new MemoryStream(buffer, false); + TrClippingThreshold = ms.ReadUInt16BE() & 0x0fff; + NumberOfIterations = ms.ReadUInt24BE() & 0x3ff; + } + + public int TrClippingThreshold { get; } + public uint NumberOfIterations { get; } + } +} diff --git a/skyscraper8/T2MI/Packets/AdressingFunctions/0x17_Frequency.cs b/skyscraper8/T2MI/Packets/AdressingFunctions/0x17_Frequency.cs new file mode 100644 index 0000000..868f50e --- /dev/null +++ b/skyscraper8/T2MI/Packets/AdressingFunctions/0x17_Frequency.cs @@ -0,0 +1,31 @@ +using skyscraper5.Skyscraper.IO; +using skyscraper5.T2MI.Packets.AdressingFunctions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.T2MI.Packets.AdressingFunctions +{ + internal class _0x17_Frequency : AddressingFunction + { + public _0x17_Frequency(byte[] buffer) : base(0x17, false, true) + { + if (buffer.Length != 5) + { + Valid = false; + return; + } + MemoryStream ms = new MemoryStream(buffer, false); + InBitStream ibs = new InBitStream(ms); + + RfIdx = ibs.ReadBitsAsByte(3); + Frequency = ibs.ReadBitsAsULong(32); + Valid = true; + } + + public byte RfIdx { get; } + public ulong Frequency { get; } + } +} diff --git a/skyscraper8/T2MI/T2MIDecoder.cs b/skyscraper8/T2MI/T2MIDecoder.cs index 817ac16..884204e 100644 --- a/skyscraper8/T2MI/T2MIDecoder.cs +++ b/skyscraper8/T2MI/T2MIDecoder.cs @@ -50,6 +50,8 @@ namespace skyscraper5.T2MI byte offsetAccordingToPus = 0; if (packetPayloadUnitStart) { + if (ms.Position == ms.Length) + return; offsetAccordingToPus = ms.ReadUInt8(); } while (ms.GetAvailableBytes() > 0) @@ -182,6 +184,9 @@ namespace skyscraper5.T2MI _0x31_IqData iqData = (_0x31_IqData)t2MiPacket; t2MiEventHandler.OnT2MiIqData(RelatedPid, iqData); break; + case 0x30: + //Null. Nothing happens here. + break; case 0x33: _0x33_Subpart subpart = (_0x33_Subpart)t2MiPacket; if (subpart.PreferDiscard)