diff --git a/skyscraper8/GS/BBHeader.cs b/skyscraper8/GS/BBHeader.cs new file mode 100644 index 0000000..bd57e77 --- /dev/null +++ b/skyscraper8/GS/BBHeader.cs @@ -0,0 +1,82 @@ +using skyscraper5.Skyscraper; + +namespace skyscraper8.GSE; + +public class BBHeader : Validatable +{ + public BBHeader(byte[] bbframe, int offset) + { + ReadOnlySpan BbHeaderSpan = new ReadOnlySpan(bbframe, offset, 10); + + //byte 1, MATYPE-1 + TsGs = (BbHeaderSpan[0] & 0xc0) >> 6; + SisMis = (BbHeaderSpan[0] & 0x20) != 0; //1 single, 0 multi + CcmAcm = (BbHeaderSpan[0] & 0x10) != 0; //1 ccm, 0 acm + Issyi = (BbHeaderSpan[0] & 0x08) != 0; // + Npd = (BbHeaderSpan[0] & 0x04) != 0; + Ro = (BbHeaderSpan[0] & 0x03); + + Matype2 = (BbHeaderSpan[1]); + + UserPacketLength = BbHeaderSpan[2] << 8 | BbHeaderSpan[3]; + UserPacketLength /= 8; + + DataFieldLength = BbHeaderSpan[4] << 8 | BbHeaderSpan[5]; + DataFieldLength /= 8; + + SyncByte = BbHeaderSpan[6]; + + SyncD = BbHeaderSpan[7] << 8 | BbHeaderSpan[8]; + + ChecksumValid = DvbCrc8.Compute(BbHeaderSpan) == 0; + Valid = ChecksumValid; + } + + public bool ChecksumValid { get; private set; } + + public int SyncD { get; private set; } + + public byte SyncByte { get; private set; } + + public int DataFieldLength { get; private set; } + + public int UserPacketLength { get; private set; } + + /// + /// If MIS, this is the Input Stream Identifier + /// + public byte Matype2 { get; private set; } + + /// + /// Transmission Roll-off factor + /// + public int Ro { get; private set; } + + /// + /// Null Packet Deletion + /// + public bool Npd { get; private set; } + + /// + /// If true, the ISSY field is inserted after UP + /// + public bool Issyi { get; set; } + + /// + /// True if CCM, False if ACM + /// + public bool CcmAcm { get; private set; } + + /// + /// True if SIS, False if MIS + /// + public bool SisMis { get; private set; } + + /// + /// 0 = GS, packetized + /// 1 = GS, continuous + /// 2 = GSE-HEM + /// 3 = Transport + /// + public int TsGs { get; private set; } +} \ No newline at end of file diff --git a/skyscraper8/GS/BBframeDeencapsulator3.cs b/skyscraper8/GS/BBframeDeencapsulator3.cs new file mode 100644 index 0000000..791235c --- /dev/null +++ b/skyscraper8/GS/BBframeDeencapsulator3.cs @@ -0,0 +1,40 @@ +using log4net; + +namespace skyscraper8.GSE; + +public class BbframeDeencapsulator3 : IBbframeDeencapsulator +{ + private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); + private long numPushed; + public void PushPacket(byte[] bbframe) + { + //byte 0, sync byte + if (bbframe[0] != 0xb8) + { + if (numPushed == 0) + { + logger.InfoFormat("The stream started in the middle of a BBFrame, let's skip to the start of the next one."); + } + return; + } + numPushed++; + + BBHeader bbHeader = new BBHeader(bbframe, 1); + if (!bbHeader.ChecksumValid) + return; + if (!bbHeader.Valid) + return; + + if (mis == null) + mis = new IMisHandler[256]; + if (mis[bbHeader.Matype2] == null) + { + logger.InfoFormat("Found a stream on MIS {0}",bbHeader.Matype2); + mis[bbHeader.Matype2] = new GsTypeDetector(); + } + + mis[bbHeader.Matype2].PushFrame(bbHeader, new ReadOnlySpan(bbframe, 11, bbframe.Length - 11)); + } + + private IMisHandler[] mis; +} \ No newline at end of file diff --git a/skyscraper8/GSE/BbframeDumper.cs b/skyscraper8/GS/BbframeDumper.cs similarity index 100% rename from skyscraper8/GSE/BbframeDumper.cs rename to skyscraper8/GS/BbframeDumper.cs diff --git a/skyscraper8/GS/Crc8.cs b/skyscraper8/GS/Crc8.cs new file mode 100644 index 0000000..994613e --- /dev/null +++ b/skyscraper8/GS/Crc8.cs @@ -0,0 +1,26 @@ +namespace skyscraper8.GSE; + +public static class DvbCrc8 +{ + private const byte Polynomial = 0xD5; // x^8 + x^7 + x^6 + x^4 + x^2 + 1 + + public static byte Compute(ReadOnlySpan data) + { + byte crc = 0x00; + + foreach (byte b in data) + { + crc ^= b; // XOR byte into top of crc register + + for (int i = 0; i < 8; i++) + { + if ((crc & 0x80) != 0) + crc = (byte)((crc << 1) ^ Polynomial); + else + crc <<= 1; + } + } + + return crc; + } +} \ No newline at end of file diff --git a/skyscraper8/GS/GsTypeDetector.cs b/skyscraper8/GS/GsTypeDetector.cs new file mode 100644 index 0000000..3ef824d --- /dev/null +++ b/skyscraper8/GS/GsTypeDetector.cs @@ -0,0 +1,9 @@ +namespace skyscraper8.GSE; + +public class GsTypeDetector : IMisHandler +{ + public void PushFrame(BBHeader bbHeader, ReadOnlySpan readOnlySpan) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/skyscraper8/GSE/IBbframeDeencapsulator.cs b/skyscraper8/GS/IBbframeDeencapsulator.cs similarity index 100% rename from skyscraper8/GSE/IBbframeDeencapsulator.cs rename to skyscraper8/GS/IBbframeDeencapsulator.cs diff --git a/skyscraper8/GS/IMisHandler.cs b/skyscraper8/GS/IMisHandler.cs new file mode 100644 index 0000000..93e7c51 --- /dev/null +++ b/skyscraper8/GS/IMisHandler.cs @@ -0,0 +1,6 @@ +namespace skyscraper8.GSE; + +public interface IMisHandler +{ + void PushFrame(BBHeader bbHeader, ReadOnlySpan readOnlySpan); +} \ No newline at end of file diff --git a/skyscraper8/GSE/BbfUdpDecap.cs b/skyscraper8/GS/POC/BbfUdpDecap.cs similarity index 100% rename from skyscraper8/GSE/BbfUdpDecap.cs rename to skyscraper8/GS/POC/BbfUdpDecap.cs diff --git a/skyscraper8/GSE/Pts2Bbf.cs b/skyscraper8/GS/POC/Pts2Bbf.cs similarity index 85% rename from skyscraper8/GSE/Pts2Bbf.cs rename to skyscraper8/GS/POC/Pts2Bbf.cs index 3996159..e88fd63 100644 --- a/skyscraper8/GSE/Pts2Bbf.cs +++ b/skyscraper8/GS/POC/Pts2Bbf.cs @@ -11,7 +11,7 @@ public class Pts2Bbf { private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); - public static void Run(FileInfo file, bool useUdpDecap = false) + public static void Run(FileInfo file, bool useUdpDecap = false, IPEndPoint ipEndPoint = null) { if (!file.Exists) { @@ -24,10 +24,14 @@ public class Pts2Bbf { string changeExtension = Path.ChangeExtension(file.FullName, ".sdecap"); BbfUdpDecap.UdpDecapFileOutput udpDecapSink = new BbfUdpDecap.UdpDecapFileOutput(new FileInfo(changeExtension)); - + + if (ipEndPoint == null) + { + ipEndPoint = new IPEndPoint(IPAddress.Parse("239.199.2.1"), 1234); + } BbfUdpDecap bbfUdpDecap = new BbfUdpDecap(); - bbfUdpDecap.SetTargetPort(1234); - bbfUdpDecap.SetTargetIp(IPAddress.Parse("239.199.2.1")); + bbfUdpDecap.SetTargetPort(ipEndPoint.Port); + bbfUdpDecap.SetTargetIp(ipEndPoint.Address); bbfUdpDecap.Sink = udpDecapSink; dumper = bbfUdpDecap; } @@ -40,7 +44,7 @@ public class Pts2Bbf FileStream fileStream = file.OpenRead(); TsContext mpeg2 = new TsContext(); - mpeg2.RegisterPacketProcessor(0x010e, new Stid135BbFrameReader(new NullGsEventHandler(),dumper)); + mpeg2.RegisterPacketProcessor(0x010e, new Stid135BbFrameReader(dumper)); DataStorage dataStorage = new InMemoryScraperStorage(); ObjectStorage objectStorage = new NullObjectStorage(); SkyscraperContext skyscraper = new SkyscraperContext(mpeg2, dataStorage, objectStorage); diff --git a/skyscraper8/GS/POC/Stid135Test.cs b/skyscraper8/GS/POC/Stid135Test.cs new file mode 100644 index 0000000..396c001 --- /dev/null +++ b/skyscraper8/GS/POC/Stid135Test.cs @@ -0,0 +1,29 @@ +using log4net; +using skyscraper5.Mpeg2; +using skyscraper5.Skyscraper.Scraper; +using skyscraper5.Skyscraper.Scraper.Storage.InMemory; +using skyscraper8.Skyscraper.Scraper.Storage; + +namespace skyscraper8.GSE; + +public class Stid135Test +{ + private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); + public static void Run(FileInfo file) + { + FileStream fileStream = file.OpenRead(); + + BbframeDeencapsulator3 decap = new BbframeDeencapsulator3(); + + TsContext mpeg2 = new TsContext(); + mpeg2.RegisterPacketProcessor(0x010e, new Stid135BbFrameReader(decap)); + DataStorage dataStorage = new InMemoryScraperStorage(); + ObjectStorage objectStorage = new NullObjectStorage(); + SkyscraperContext skyscraper = new SkyscraperContext(mpeg2, dataStorage, objectStorage); + skyscraper.InitalizeFilterChain(); + skyscraper.IngestFromStream(fileStream); + + fileStream.Close(); + logger.Info("STiD135 Tester exiting"); + } +} \ No newline at end of file diff --git a/skyscraper8/GSE/Stid135BbFrameReader.cs b/skyscraper8/GS/Stid135BbFrameReader.cs similarity index 66% rename from skyscraper8/GSE/Stid135BbFrameReader.cs rename to skyscraper8/GS/Stid135BbFrameReader.cs index e42f903..0a1dba5 100644 --- a/skyscraper8/GSE/Stid135BbFrameReader.cs +++ b/skyscraper8/GS/Stid135BbFrameReader.cs @@ -11,15 +11,13 @@ namespace skyscraper8.GSE { internal class Stid135BbFrameReader : ITsPacketProcessor { - private IGsEventHandler mpeEventHandler; private IBbframeDeencapsulator deencapsulator; - public Stid135BbFrameReader(IGsEventHandler mpeEventHandler, IBbframeDeencapsulator deencapsulator = null) + public Stid135BbFrameReader(IBbframeDeencapsulator deencapsulator = null) { if (deencapsulator == null) - deencapsulator = new BbframeDeencapsulator(); + deencapsulator = new BbframeDeencapsulator3(); - this.mpeEventHandler = mpeEventHandler; this.deencapsulator = deencapsulator; } @@ -56,21 +54,6 @@ namespace skyscraper8.GSE { outbuf.Write(packets, 9, packets[7] - 1); } - /*if ((packets[8] & 0xff) == 0xb8) - { - if (outbuf != null) - { - byte[] chi = outbuf.ToArray(); - deencapsulator.PushPacket(chi); - } - outbuf = new MemoryStream(); - outbuf.Write(packets,9, packets[7] - 1); - } - else - { - if (outbuf != null) - outbuf.Write(packets, 9, packets[7] - 1); - }*/ } } } diff --git a/skyscraper8/GSE/BbframeDeencapsulator.cs b/skyscraper8/GSE/BbframeDeencapsulator.cs deleted file mode 100644 index 523545b..0000000 --- a/skyscraper8/GSE/BbframeDeencapsulator.cs +++ /dev/null @@ -1,446 +0,0 @@ -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; -using log4net; - -namespace skyscraper8.GSE -{ - internal class BbframeDeencapsulator : IBbframeDeencapsulator - { - private bool interruptedGseHem; - private MemoryStream interruptedGseHemBuffer; - private bool interruptedGseHemWantsCrc32; - public IGsEventHandler MpeEventHandler { get; set; } - - private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); - - private bool shownNonGseWarning; - - public void PushPacket(byte[] bbframe) - { - MemoryStream ms = new MemoryStream(bbframe, false); - //BBHeader - byte matype1 = ms.ReadUInt8(); - int tsGsField = (matype1 & 0xc0) >> 6; - bool sisMisField = (matype1 & 0x20) != 0; - bool ccmAcmField = (matype1 & 0x10) != 0; - bool issyi = (matype1 & 0x08) != 0; - bool npd = (matype1 & 0x04) != 0; - int ro = matype1 & 0x03; - - byte matype2 = ms.ReadUInt8(); - - ushort userPacketLength = ms.ReadUInt16BE(); - ushort dataFieldLength = ms.ReadUInt16BE(); - byte sync = ms.ReadUInt8(); - ushort syncd = ms.ReadUInt16BE(); - byte crc8 = ms.ReadUInt8(); - - if (userPacketLength == 0 && dataFieldLength == 0) - return; - - switch (tsGsField) - { - case 1: - if (sync != 0) - { - if (!shownNonGseWarning) - { - logger.WarnFormat("This stream is a valid GS, but also contains packets which are not GSE (type 0), but of type {0} . Please share a sample of this stream!", sync); - shownNonGseWarning = true; - } - return; - } - int bytes = dataFieldLength / 8; - if (ms.GetAvailableBytes() < bytes) - return; - HandleContinous(ms); - break; - case 2: - int hemBytes = dataFieldLength / 8; - if (ms.GetAvailableBytes() < hemBytes) - return; - HandleGseHem(ms); - break; - default: //0 = generic packetized, 1 = generic continouus, 2 = gse, 3 = ts - logger.Warn(string.Format("Unsupported: TS/GS field says 0x{0:X2}, please share a sample of this stream.", tsGsField)); - break; - } - } - - private GseFragmentation[] gseFragmentations; - private void HandleContinous(MemoryStream ms) - { - ms.Position = 10; - - - while (ms.GetAvailableBytes() > 0) - { - GsePacket packet = GsePacket.Read(ms); - if (packet.IsPadding) - { - break; - } - - if (!packet.Valid) - { - break; - } - - if (packet.IsCompletePacket) - { - if (ValidateEthertype(packet.ProtocolType.Value)) - { - MpeEventHandler.OnIpDatagram(PID, packet.GseData); - } - else - { - logger.WarnFormat("Unknown EtherType: 0x{0:X4}", packet.ProtocolType.Value); - } - continue; - } - - if (packet.StartIndicator && !packet.EndIndicator) - { - if (gseFragmentations == null) - gseFragmentations = new GseFragmentation[256]; - - gseFragmentations[packet.FragmentId.Value] = new GseFragmentation(); - gseFragmentations[packet.FragmentId.Value].AddPacket(packet); - continue; - } - - if (!packet.StartIndicator && packet.EndIndicator) - { - if (gseFragmentations == null) - continue; - if (gseFragmentations[packet.FragmentId.Value] == null) - continue; - - gseFragmentations[packet.FragmentId.Value].AddPacket(packet); - continue; - } - - if (!packet.StartIndicator && !packet.EndIndicator) - { - if (gseFragmentations == null) - continue; - - throw new NotImplementedException(); - } - - throw new NotImplementedException(); - } - } - - private bool gseNeedMore; - private MemoryStream gseAssembler; - public int PID; - - private void HandleGseHem(MemoryStream ms) - { - ms.Position = 10; - byte syncByte = ms.ReadUInt8(); - ms.Position = 10; - - long availableBytes = ms.GetAvailableBytes(); - byte[] readBytes = ms.ReadBytes(availableBytes); - - GseAssemblyState assemblyState = ValidateGse(gseAssembler, true); - if (assemblyState == GseAssemblyState.NOT_YET_BEGUN) - { - if ((syncByte & 0xc0) == 0xc0) - { - //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; - } - } - else if (assemblyState == GseAssemblyState.NEED_MORE_DATA) - { - 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) - { - - } - gseAssembler = null; - HandleGseHem(ms); - return; - } - else if (assemblyState == GseAssemblyState.BROKEN_SUSPECT_ETHERTYPE) - { - gseAssembler = null; - HandleGseHem(ms); - return; - } - else if (assemblyState == GseAssemblyState.BROKEN_NEGATIVE_LENGTH) - { - gseAssembler = null; - HandleGseHem(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, - VALID_NULL_PACKET, //somehow these only show up on TBS6903x, not DD Max SX8? - } - - private GseAssemblyState ValidateGse(MemoryStream ms, bool tryFix = false) - { - if (ms == null) - return GseAssemblyState.NOT_YET_BEGUN; - - long backupPosition = ms.Position; - ms.Position = 0; - while (ms.GetAvailableBytes() > 2) - { - long fixPosition = ms.Position; - - //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) - { - if (tryFix) - { - ms.Position = fixPosition; - ms.WriteUInt8Repeat(0, (int)ms.GetAvailableBytes()); - break; - } - ms.Position = backupPosition; - return GseAssemblyState.BROKEN_SUSPECT_LENGTH; - } - - if (!startIndicator || !endIndicator) - { - byte fragId = ms.ReadUInt8(); - gseLength--; - } - - if (startIndicator && !endIndicator) - { - if (2 > ms.GetAvailableBytes()) - { - ms.Position = backupPosition; - return GseAssemblyState.NEED_MORE_DATA; - } - 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)) - { - if (tryFix) - { - ms.Position = fixPosition; - ms.WriteUInt8Repeat(0, (int)ms.GetAvailableBytes()); - break; - } - 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) - { - if (tryFix) - { - ms.Position = fixPosition; - ms.WriteUInt8Repeat(0, (int)ms.GetAvailableBytes()); - break; - } - 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) - { - if (4 > ms.GetAvailableBytes()) - { - ms.Position = backupPosition; - return GseAssemblyState.NEED_MORE_DATA; - } - 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 - 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 - return; - } - else - { - byte byteB = ms.ReadUInt8(); - int gseLength = byteA & 0x0f; - gseLength <<= 8; - gseLength += byteB; - - if (!startIndicator || !endIndicator) - { - byte fragId = ms.ReadUInt8(); - gseLength--; - } - - if (startIndicator && !endIndicator) - { - ushort totalLength = ms.ReadUInt16BE(); - gseLength -= 2; - } - - if (startIndicator) - { - protocolType = ms.ReadUInt16BE(); - gseLength -= 2; - if (labelIndicator == 0) - { - 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; - - byte[] payload = ms.ReadBytes(gseLength); - if (!startIndicator && endIndicator) - { - uint crc32 = ms.ReadUInt32BE(); - int endCrc32 = (int)ms.Position; - 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/GSE/GsEventHandler.cs b/skyscraper8/GSE/GsEventHandler.cs deleted file mode 100644 index 6c9e640..0000000 --- a/skyscraper8/GSE/GsEventHandler.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace skyscraper5.Skyscraper -{ - internal interface IGsEventHandler - { - void OnIpDatagram(int pid, byte[] payload); - void GsIpTrafficDetected(); - } -} diff --git a/skyscraper8/GSE/GseFragmentation.cs b/skyscraper8/GSE/GseFragmentation.cs deleted file mode 100644 index 5d6d700..0000000 --- a/skyscraper8/GSE/GseFragmentation.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace skyscraper8.GSE -{ - internal class GseFragmentation - { - public void AddPacket(GsePacket packet) - { - if (spanningGsePackets == null) - { - spanningGsePackets = new List(); - TotalLength = packet.TotalLength.Value; - } - - spanningGsePackets.Add(packet); - } - - public ushort TotalLength { get; private set; } - - private List spanningGsePackets; - } -} diff --git a/skyscraper8/GSE/GsePacket.cs b/skyscraper8/GSE/GsePacket.cs deleted file mode 100644 index d3ec9d3..0000000 --- a/skyscraper8/GSE/GsePacket.cs +++ /dev/null @@ -1,167 +0,0 @@ -using skyscraper5.Skyscraper.IO; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.NetworkInformation; -using System.Text; -using System.Threading.Tasks; -using skyscraper5.Skyscraper; - -namespace skyscraper8.GSE -{ - internal class GsePacket : Validatable - { - public static GsePacket Read(MemoryStream ms) - { - GsePacket packet = new GsePacket(); - - byte byteA = ms.ReadUInt8(); - packet.StartIndicator = (byteA & 0x80) != 0; - packet.EndIndicator = (byteA & 0x40) != 0; - packet.LabelIndicator = (byteA & 0x30) >> 4; - if (!packet.StartIndicator && !packet.EndIndicator && packet.LabelIndicator == 0) - { - //End of baseband frame - return packet; - } - else - { - byte byteB = ms.ReadUInt8(); - int gseLength = byteA & 0x0f; - gseLength <<= 8; - gseLength += byteB; - - if (!packet.StartIndicator || !packet.EndIndicator) - { - packet.FragmentId = ms.ReadUInt8(); - gseLength--; - } - - if (packet.StartIndicator && !packet.EndIndicator) - { - packet.TotalLength = ms.ReadUInt16BE(); - gseLength -= 2; - } - - if (packet.StartIndicator) - { - packet.ProtocolType = ms.ReadUInt16BE(); - gseLength -= 2; - if (packet.LabelIndicator == 0) - { - packet.Label = new SixByteGseLabel(ms.ReadBytes(6)); - gseLength -= 6; - } - else if (packet.LabelIndicator == 1) - { - packet.Label = new ThreeByteGseLabel(ms.ReadBytes(3)); - gseLength -= 3; - } - } - - if (!packet.StartIndicator && packet.EndIndicator) - gseLength -= 4; - - if (gseLength < 0) - { - packet.Valid = false; - return packet; - } - if (gseLength > ms.GetAvailableBytes()) - { - packet.Valid = false; - return packet; - } - packet.GseData = ms.ReadBytes(gseLength); - - if (!packet.StartIndicator && packet.EndIndicator) - packet.Crc32 = ms.ReadUInt32BE(); - } - - packet.Valid = true; - return packet; - } - - public uint? Crc32 { get; set; } - - public byte[] GseData { get; set; } - - public GseLabel Label { get; set; } - public ushort? ProtocolType { get; set; } - - public ushort? TotalLength { get; set; } - public byte? FragmentId { get; set; } - public int LabelIndicator { get; private set; } - public bool EndIndicator { get; private set; } - public bool StartIndicator { get; private set; } - public bool IsPadding - { - get - { - return !StartIndicator && !EndIndicator && LabelIndicator == 0; - } - } - - public bool IsCompletePacket - { - get - { - return StartIndicator && EndIndicator; - } - } - } - - public abstract class GseLabel : Validatable - { - public abstract int LabelLength { get; } - public abstract string ToString(); - } - - public class ThreeByteGseLabel : GseLabel - { - public ThreeByteGseLabel(byte[] buffer) - { - if (buffer.Length != 3) - { - Valid = false; - return; - } - - LabelBytes = buffer; - Valid = true; - } - - public byte[] LabelBytes { get; private set; } - - public override string ToString() - { - return BitConverter.ToString(LabelBytes); - } - - public override int LabelLength => 3; - } - - public class SixByteGseLabel : GseLabel - { - public SixByteGseLabel(byte[] buffer) - { - if (buffer.Length != 6) - { - Valid = false; - return; - } - - MacAddress = new PhysicalAddress(buffer); - Valid = true; - } - - public PhysicalAddress MacAddress { get; private set; } - - public override string ToString() - { - return MacAddress.ToString(); - } - - public override int LabelLength => 6; - } -} diff --git a/skyscraper8/GSE/NullGsEventHandler.cs b/skyscraper8/GSE/NullGsEventHandler.cs deleted file mode 100644 index 3d29335..0000000 --- a/skyscraper8/GSE/NullGsEventHandler.cs +++ /dev/null @@ -1,16 +0,0 @@ -using skyscraper5.Skyscraper; - -namespace skyscraper8.GSE; - -public class NullGsEventHandler : IGsEventHandler -{ - public void OnIpDatagram(int pid, byte[] payload) - { - - } - - public void GsIpTrafficDetected() - { - - } -} \ No newline at end of file diff --git a/skyscraper8/Program.cs b/skyscraper8/Program.cs index c4dfb54..09db3be 100644 --- a/skyscraper8/Program.cs +++ b/skyscraper8/Program.cs @@ -323,6 +323,13 @@ namespace skyscraper5 return; } } + + if (args[0].ToLowerInvariant().Equals("stid135test")) + { + FileInfo fi = new FileInfo(args[1]); + Stid135Test.Run(fi); + return; + } } /*Passing passing = new Passing(); diff --git a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs index 82b878e..0ecfeb2 100644 --- a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs +++ b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs @@ -92,7 +92,7 @@ namespace skyscraper5.Skyscraper.Scraper IEitEventHandler, IAitEventHandler, ISubtitleEventHandler, UpdateNotificationEventHandler, DataCarouselEventHandler, RdsEventHandler, IScte35EventHandler, IAutodetectionEventHandler, IRstEventHandler, IRntEventHandler, IMultiprotocolEncapsulationEventHandler, ObjectCarouselEventHandler, T2MIEventHandler, - IDisposable, IFrameGrabberEventHandler, IntEventHandler, IRctEventHandler, IGsEventHandler, ISkyscraperContext, IDocsisEventHandler, AbertisDecoderEventHandler, Id3Handler, + IDisposable, IFrameGrabberEventHandler, IntEventHandler, IRctEventHandler, ISkyscraperContext, IDocsisEventHandler, AbertisDecoderEventHandler, Id3Handler, InteractionChannelHandler, SgtEventHandler, IDvbNipEventHandler, UleEventHandler, OtvSsuHandler, NdsSsuHandler { public const bool ALLOW_STREAM_TYPE_AUTODETECTION = true; @@ -301,7 +301,7 @@ namespace skyscraper5.Skyscraper.Scraper { if (!DvbContext.IsPidProcessorPresent(0x010e)) { - DvbContext.RegisterPacketProcessor(0x010e, new Stid135BbFrameReader(this)); + DvbContext.RegisterPacketProcessor(0x010e, new Stid135BbFrameReader()); UiJunction?.SetGseMode(); LogEvent(SkyscraperContextEvent.SpecialTsMode, "STiD135 encapsulated GS detected."); SpecialTsType = 3; @@ -356,7 +356,7 @@ namespace skyscraper5.Skyscraper.Scraper { if (!DvbContext.IsPidProcessorPresent(0x010e)) { - DvbContext.RegisterPacketProcessor(0x010e, new Stid135BbFrameReader(this)); + DvbContext.RegisterPacketProcessor(0x010e, new Stid135BbFrameReader()); UiJunction?.SetGseMode(); LogEvent(SkyscraperContextEvent.SpecialTsMode, "STiD135 encapsulated GS detected."); SpecialTsType = 3;