diff --git a/skyscraper8.Tests/AstraBarkerTransponderTests.cs b/skyscraper8.Tests/AstraBarkerTransponderTests.cs index 9f12657..f0ed3fc 100644 --- a/skyscraper8.Tests/AstraBarkerTransponderTests.cs +++ b/skyscraper8.Tests/AstraBarkerTransponderTests.cs @@ -30,8 +30,7 @@ namespace skyscraper8.Tests public void TestAstraSdt() { Stream stream = GetBarkerTransponder(); - if (stream == null) - return; + Skip.If(stream == null, "Barker Transponder stream not available."); SdtContestant contestant = new SdtContestant(0x002d); @@ -62,8 +61,7 @@ namespace skyscraper8.Tests public void TestAstraLcn() { Stream stream = GetBarkerTransponder(); - if (stream == null) - return; + Skip.If(stream == null, "Barker Transponder stream not available."); SgtCandidate contestant = new SgtCandidate(0x0777); SgtCandidate contestant2 = new SgtCandidate(0x0776); diff --git a/skyscraper8.Tests/GsType1SanityTest.cs b/skyscraper8.Tests/GsType1SanityTest.cs new file mode 100644 index 0000000..fbc2889 --- /dev/null +++ b/skyscraper8.Tests/GsType1SanityTest.cs @@ -0,0 +1,31 @@ +using System.Reflection; +using skyscraper5.Mpeg2; +using skyscraper8.Tests.Properties; + +namespace skyscraper8.Tests; + +public class GsType1SanityTest +{ + [Fact] + public void CheckBfbsCrc() + { + byte[] blob = Resources.Frame00001343_TSGS1_MIS000_SYNC001; + MemoryStream ms = new MemoryStream(blob, false); + bool result = DvbCrc32.ValidateCrc(ms, 0, (int)ms.Length); + Assert.True(result); + + blob = Resources.Frame00000008_TSGS1_MIS000_SYNC001; + ms = new MemoryStream(blob, false); + result = DvbCrc32.ValidateCrc(ms, 0, (int)ms.Length); + Assert.True(result); + } + + [Fact] + public void CheckBfbsCrcSpan() + { + byte[] blob = Resources.Frame00000012_TSGS1_MIS000_SYNC001; + ReadOnlySpan span = new ReadOnlySpan(blob); + bool result = DvbCrc32.ValidateCrc(span); + Assert.True(result); + } +} \ No newline at end of file diff --git a/skyscraper8.Tests/Properties/Resources.Designer.cs b/skyscraper8.Tests/Properties/Resources.Designer.cs index e70c8f6..f385bb9 100644 --- a/skyscraper8.Tests/Properties/Resources.Designer.cs +++ b/skyscraper8.Tests/Properties/Resources.Designer.cs @@ -1,10 +1,9 @@ //------------------------------------------------------------------------------ // -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.42000 +// This code was generated by a tool. // -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. // //------------------------------------------------------------------------------ @@ -12,46 +11,32 @@ namespace skyscraper8.Tests.Properties { using System; - /// - /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. - /// - // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert - // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. - // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen - // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [System.Diagnostics.DebuggerNonUserCodeAttribute()] + [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { - private static global::System.Resources.ResourceManager resourceMan; + private static System.Resources.ResourceManager resourceMan; - private static global::System.Globalization.CultureInfo resourceCulture; + private static System.Globalization.CultureInfo resourceCulture; - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } - /// - /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + internal static System.Resources.ResourceManager ResourceManager { get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("skyscraper8.Tests.Properties.Resources", typeof(Resources).Assembly); + if (object.Equals(null, resourceMan)) { + System.Resources.ResourceManager temp = new System.Resources.ResourceManager("skyscraper8.Tests.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - /// - /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle - /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + internal static System.Globalization.CultureInfo Culture { get { return resourceCulture; } @@ -60,9 +45,6 @@ namespace skyscraper8.Tests.Properties { } } - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. - /// internal static byte[] ModemCapabilitiesEncodingTest { get { object obj = ResourceManager.GetObject("ModemCapabilitiesEncodingTest", resourceCulture); @@ -70,9 +52,6 @@ namespace skyscraper8.Tests.Properties { } } - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. - /// internal static byte[] MultipartRegistrationResponseTest { get { object obj = ResourceManager.GetObject("MultipartRegistrationResponseTest", resourceCulture); @@ -80,19 +59,6 @@ namespace skyscraper8.Tests.Properties { } } - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. - /// - internal static byte[] MultipartRegistrationResponseTest2 { - get { - object obj = ResourceManager.GetObject("MultipartRegistrationResponseTest2", resourceCulture); - return ((byte[])(obj)); - } - } - - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. - /// internal static byte[] PushMacManagementMessage_Version4_Type45 { get { object obj = ResourceManager.GetObject("PushMacManagementMessage_Version4_Type45", resourceCulture); @@ -100,9 +66,6 @@ namespace skyscraper8.Tests.Properties { } } - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. - /// internal static byte[] ranging_response_test { get { object obj = ResourceManager.GetObject("ranging_response_test", resourceCulture); @@ -110,9 +73,13 @@ namespace skyscraper8.Tests.Properties { } } - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. - /// + internal static byte[] MultipartRegistrationResponseTest2 { + get { + object obj = ResourceManager.GetObject("MultipartRegistrationResponseTest2", resourceCulture); + return ((byte[])(obj)); + } + } + internal static byte[] test_1packet_01 { get { object obj = ResourceManager.GetObject("test-1packet-01", resourceCulture); @@ -120,9 +87,6 @@ namespace skyscraper8.Tests.Properties { } } - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. - /// internal static byte[] test_2packets_02_03 { get { object obj = ResourceManager.GetObject("test-2packets-02-03", resourceCulture); @@ -130,9 +94,6 @@ namespace skyscraper8.Tests.Properties { } } - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. - /// internal static byte[] test_3packets_04_05_06 { get { object obj = ResourceManager.GetObject("test-3packets-04-05-06", resourceCulture); @@ -140,9 +101,6 @@ namespace skyscraper8.Tests.Properties { } } - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. - /// internal static byte[] TransmitChannelConfigurationObject { get { object obj = ResourceManager.GetObject("TransmitChannelConfigurationObject", resourceCulture); @@ -150,14 +108,32 @@ namespace skyscraper8.Tests.Properties { } } - /// - /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. - /// internal static byte[] UpstreamChannelDescriptorTest { get { object obj = ResourceManager.GetObject("UpstreamChannelDescriptorTest", resourceCulture); return ((byte[])(obj)); } } + + internal static byte[] Frame00001343_TSGS1_MIS000_SYNC001 { + get { + object obj = ResourceManager.GetObject("Frame00001343_TSGS1_MIS000_SYNC001", resourceCulture); + return ((byte[])(obj)); + } + } + + internal static byte[] Frame00000008_TSGS1_MIS000_SYNC001 { + get { + object obj = ResourceManager.GetObject("Frame00000008_TSGS1_MIS000_SYNC001", resourceCulture); + return ((byte[])(obj)); + } + } + + internal static byte[] Frame00000012_TSGS1_MIS000_SYNC001 { + get { + object obj = ResourceManager.GetObject("Frame00000012_TSGS1_MIS000_SYNC001", resourceCulture); + return ((byte[])(obj)); + } + } } } diff --git a/skyscraper8.Tests/Properties/Resources.resx b/skyscraper8.Tests/Properties/Resources.resx index 927ac85..33cfa0a 100644 --- a/skyscraper8.Tests/Properties/Resources.resx +++ b/skyscraper8.Tests/Properties/Resources.resx @@ -148,4 +148,13 @@ ..\Resources\UpstreamChannelDescriptorTest.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\Frame00001343_TSGS1_MIS000_SYNC001.bbf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\Frame00000008_TSGS1_MIS000_SYNC001.bbf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\Frame00000012_TSGS1_MIS000_SYNC001.bbf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + \ No newline at end of file diff --git a/skyscraper8.Tests/Resources/Frame00000008_TSGS1_MIS000_SYNC001.bbf b/skyscraper8.Tests/Resources/Frame00000008_TSGS1_MIS000_SYNC001.bbf new file mode 100644 index 0000000..9e6a78c Binary files /dev/null and b/skyscraper8.Tests/Resources/Frame00000008_TSGS1_MIS000_SYNC001.bbf differ diff --git a/skyscraper8.Tests/Resources/Frame00000012_TSGS1_MIS000_SYNC001.bbf b/skyscraper8.Tests/Resources/Frame00000012_TSGS1_MIS000_SYNC001.bbf new file mode 100644 index 0000000..eb5ee33 Binary files /dev/null and b/skyscraper8.Tests/Resources/Frame00000012_TSGS1_MIS000_SYNC001.bbf differ diff --git a/skyscraper8.Tests/Resources/Frame00001343_TSGS1_MIS000_SYNC001.bbf b/skyscraper8.Tests/Resources/Frame00001343_TSGS1_MIS000_SYNC001.bbf new file mode 100644 index 0000000..d9c2a13 Binary files /dev/null and b/skyscraper8.Tests/Resources/Frame00001343_TSGS1_MIS000_SYNC001.bbf differ diff --git a/skyscraper8.Tests/SanityTests.cs b/skyscraper8.Tests/SanityTests.cs index 4072ada..e5ce016 100644 --- a/skyscraper8.Tests/SanityTests.cs +++ b/skyscraper8.Tests/SanityTests.cs @@ -19,6 +19,8 @@ namespace skyscraper8.Tests bool msbSet = (readUInt8 & 0x80) != 0; Assert.True(msbSet); + readUInt8 &= 0b01111111; + int result = ms.ReadUInt8(); result <<= 8; result += readUInt8; diff --git a/skyscraper8.Tests/TsDuckTestPatterns.cs b/skyscraper8.Tests/TsDuckTestPatterns.cs index 8b27163..e2a9d2b 100644 --- a/skyscraper8.Tests/TsDuckTestPatterns.cs +++ b/skyscraper8.Tests/TsDuckTestPatterns.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using skyscraper8.Skyscraper.Scraper.Storage; namespace skyscraper8.Tests { @@ -22,7 +23,10 @@ namespace skyscraper8.Tests foreach (byte[] buffer in buffers) { TsContext mpeg2 = new TsContext(); - SkyscraperContext skyscraper = new SkyscraperContext(mpeg2, null, null); + DataStorage ds = new InMemoryScraperStorageFactory().CreateDataStorage(); + ObjectStorage os = new NullObjectStorage(); + + SkyscraperContext skyscraper = new SkyscraperContext(mpeg2, ds, os); MemoryStream ms = new MemoryStream(buffer, false); skyscraper.InitalizeFilterChain(); diff --git a/skyscraper8.Tests/UselessCodeCoverageTests.cs b/skyscraper8.Tests/UselessCodeCoverageTests.cs new file mode 100644 index 0000000..406488b --- /dev/null +++ b/skyscraper8.Tests/UselessCodeCoverageTests.cs @@ -0,0 +1,13 @@ +using skyscraper5.Mpeg2; + +namespace skyscraper8.Tests; + +public class UselessCodeCoverageTests +{ + [Fact] + void PsiSectionTest() + { + PsiSection section = new PsiSection(); + section.Append(new byte[] { 3 }); + } +} \ No newline at end of file diff --git a/skyscraper8.sln.DotSettings.user b/skyscraper8.sln.DotSettings.user index 296c055..c34a7c8 100644 --- a/skyscraper8.sln.DotSettings.user +++ b/skyscraper8.sln.DotSettings.user @@ -1,6 +1,7 @@  ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -9,4 +10,13 @@ ForceIncluded ForceIncluded ForceIncluded + /home/schiemas/.cache/JetBrains/Rider2025.1/resharper-host/temp/Rider/vAny/CoverageData/_skyscraper8.1808907683/Snapshot/snapshot.utdcvr + <SessionState ContinuousTestingMode="0" IsActive="True" Name="CheckBfbsCrc #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> + <Solution /> +</SessionState> + <SessionState ContinuousTestingMode="0" Name="CheckBfbsCrc" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> + <TestAncestor> + <TestId>xUnit::84EE9FCD-2C7F-DF84-C1BA-99D018CE9412::net8.0::skyscraper8.Tests.GsType1SanityTest.CheckBfbsCrc</TestId> + </TestAncestor> +</SessionState> <data><HostParameters type="LocalHostParameters" /><Argument type="StandaloneArgument"><Arguments IsNull="False"></Arguments><FileName IsNull="False"></FileName><WorkingDirectory IsNull="False"></WorkingDirectory><Scope><ProcessFilters /></Scope></Argument><Info type="TimelineInfo" /><CoreOptions type="CoreOptions"><CoreTempPath IsNull="False"></CoreTempPath><RemoteEndPoint IsNull="False"></RemoteEndPoint><AdditionalEnvironmentVariables /></CoreOptions><HostOptions type="HostOptions"><HostTempPath IsNull="False"></HostTempPath></HostOptions></data> \ No newline at end of file diff --git a/skyscraper8/GS/POC/Pts2Bbf2.cs b/skyscraper8/GS/POC/Pts2Bbf2.cs new file mode 100644 index 0000000..3d40ced --- /dev/null +++ b/skyscraper8/GS/POC/Pts2Bbf2.cs @@ -0,0 +1,62 @@ +using log4net; +using skyscraper5.Mpeg2; +using skyscraper5.Skyscraper; +using skyscraper5.Skyscraper.IO; +using skyscraper5.Skyscraper.Scraper; +using skyscraper5.Skyscraper.Scraper.Storage.InMemory; +using skyscraper8.Skyscraper.Scraper.Storage; + +namespace skyscraper8.GSE; + +public class Pts2Bbf2 : IBbframeDeencapsulator +{ + private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); + private readonly FileInfo _fi; + private readonly DirectoryInfo outputDir; + + public Pts2Bbf2(FileInfo fi) + { + _fi = fi; + string outputPath = Path.Combine(_fi.Directory.FullName, Path.GetFileNameWithoutExtension(_fi.Name) + "_frames"); + outputDir = new DirectoryInfo(outputPath); + outputDir.EnsureExists(); + } + + public void Run() + { + TsContext mpeg2 = new TsContext(); + Stid135BbFrameReader bbFrameReader = new Stid135BbFrameReader(null, null, this); + mpeg2.RegisterPacketProcessor(0x010e, bbFrameReader); + + SkyscraperContext context = new SkyscraperContext(mpeg2, new InMemoryScraperStorage(), new NullObjectStorage()); + context.InitalizeFilterChain(); + + FileStream fileStream = _fi.OpenRead(); + context.IngestFromStream(fileStream); + } + + private int frameNo; + public void PushPacket(byte[] bbframe) + { + if (bbframe[0] != 0xb8) + { + return; + } + + BBHeader bbHeader = new BBHeader(bbframe, 1); + if (!bbHeader.Valid) + return; + + string fname = String.Format("Frame{0:D8}_TSGS{1}_MIS{2:D3}_SYNC{3:D3}.ts", ++frameNo,bbHeader.TsGs,bbHeader.SisMis ? bbHeader.Matype2 : 0,bbHeader.SyncByte); + + string outfname = Path.Combine(outputDir.FullName, fname); + ReadOnlySpan readOnlySpan = new ReadOnlySpan(bbframe, 11, bbframe.Length - 11); + byte[] buffer = readOnlySpan.ToArray(); + File.WriteAllBytes(outfname, buffer); + + if (IpPacketFinder.TestForHttpContents(buffer)) + { + logger.InfoFormat("Found unencrypted HTTP traffic in {0}", fname); + } + } +} \ No newline at end of file diff --git a/skyscraper8/Mpeg2/Crc32.cs b/skyscraper8/Mpeg2/Crc32.cs index 3c896f9..b2fb901 100644 --- a/skyscraper8/Mpeg2/Crc32.cs +++ b/skyscraper8/Mpeg2/Crc32.cs @@ -4,7 +4,7 @@ using static System.Collections.Specialized.BitVector32; namespace skyscraper5.Mpeg2 { - internal class DvbCrc32 + public class DvbCrc32 { private DvbCrc32() { @@ -112,6 +112,20 @@ namespace skyscraper5.Mpeg2 return crc == 0; } + public static bool ValidateCrc(ReadOnlySpan data) + { + uint crc = 0xffffffff; + + for (int i = 0; i < data.Length; i++) + { + uint b = (crc >> 24) & 0xff; + int c = (data[i]) & 0xff; + crc = (crc << 8) ^ table[b ^ c]; + } + + return crc == 0; + } + public static uint CreateCrc(MemoryStream ms, int offset, int end) { long restorePosition = ms.Position; diff --git a/skyscraper8/Program.cs b/skyscraper8/Program.cs index e91852c..65133f9 100644 --- a/skyscraper8/Program.cs +++ b/skyscraper8/Program.cs @@ -337,6 +337,14 @@ namespace skyscraper5 } } + if (args[0].ToLowerInvariant().Equals("pts2bbf2")) + { + FileInfo fi = new FileInfo(args[1]); + Pts2Bbf2 pts2Bbf2 = new Pts2Bbf2(fi); + pts2Bbf2.Run(); + return; + } + if (args[0].ToLowerInvariant().Equals("stid135test")) { FileInfo fi = new FileInfo(args[1]); diff --git a/skyscraper8/Skyscraper/IpPacketFinder.cs b/skyscraper8/Skyscraper/IpPacketFinder.cs index ea64f8d..65a02cb 100644 --- a/skyscraper8/Skyscraper/IpPacketFinder.cs +++ b/skyscraper8/Skyscraper/IpPacketFinder.cs @@ -86,5 +86,17 @@ namespace skyscraper5.Skyscraper return result; } + + public static bool TestForHttpContents(byte[] buffer) + { + for (int i = 0; i < buffer.Length - 5; i++) + if (buffer[i] == 0x48) + if (buffer[i + 1] == 0x54) + if (buffer[i + 2] == 0x54) + if (buffer[i + 3] == 0x50) + if (buffer[i + 4] == 0x2f) + return true; + return false; + } } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/NullObjectStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/NullObjectStorage.cs index bad78b9..d8106af 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/NullObjectStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/NullObjectStorage.cs @@ -13,7 +13,7 @@ using skyscraper8.Skyscraper.Drawing; namespace skyscraper8.Skyscraper.Scraper.Storage { - internal class NullObjectStorage : ObjectStorage + public class NullObjectStorage : ObjectStorage { public bool ObjectCarouselFileArrival(VfsFile vfsFile, int transportStreamId, int networkId) {