diff --git a/Documentation/storage_system_ids.md b/Documentation/storage_system_ids.md index 9f99f27..a957999 100644 --- a/Documentation/storage_system_ids.md +++ b/Documentation/storage_system_ids.md @@ -18,4 +18,14 @@ These will have IP packets forwarded to. |ID|Type | |--|-----------| | 1|PCAP Writer| -| 2|Discard | \ No newline at end of file +| 2|Discard | + +#Network Types +These identify sources from which a network packet may come from. +|ID|Type | +|--|----------| +| 0|Reserved | +| 1|ATSC3 PLP | +| 2|MPEG-2 PID| +| 3|DVB MIS | +| 4|AAL5 | \ No newline at end of file diff --git a/skyscraper8/Atsc/A322/Atsc3PlpVirtualNetworkIdentifier.cs b/skyscraper8/Atsc/A322/Atsc3PlpVirtualNetworkIdentifier.cs new file mode 100644 index 0000000..73409e9 --- /dev/null +++ b/skyscraper8/Atsc/A322/Atsc3PlpVirtualNetworkIdentifier.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using skyscraper8.Skyscraper.Net.VirtualNetworks; + +namespace skyscraper8.Atsc.A322 +{ + [VirtualNetworkId(1)] + internal class Atsc3PlpVirtualNetworkIdentifier : VirtualNetworkIdentifier + { + public ushort PlpId { get; } + + public Atsc3PlpVirtualNetworkIdentifier(ushort plpId) + { + PlpId = plpId; + } + + public override string GetCaptureFilenamePrefix() + { + return String.Format("atsc3plp{0}", PlpId); + } + + public override string GetHumanReadableName() + { + return String.Format("ATSC3 PLP {0}", PlpId); + } + + public override int GetIdentifier() + { + return PlpId; + } + } +} diff --git a/skyscraper8/Atsc/A322/AtscPlpBasebandParser.cs b/skyscraper8/Atsc/A322/AtscPlpBasebandParser.cs index 527a2da..5153d63 100644 --- a/skyscraper8/Atsc/A322/AtscPlpBasebandParser.cs +++ b/skyscraper8/Atsc/A322/AtscPlpBasebandParser.cs @@ -155,9 +155,14 @@ namespace skyscraper8.Atsc.A322 } } + private Atsc3PlpVirtualNetworkIdentifier networkIdentifier; private void HandleIpv4(byte[] newPacketPayload) { - _eventHandler?.OnIpDatagram(0x1ffd, newPacketPayload); + if (networkIdentifier == null) + { + networkIdentifier = new Atsc3PlpVirtualNetworkIdentifier(_plpId); + } + _eventHandler?.OnIpDatagram(networkIdentifier, newPacketPayload); } private void HandleLinkLayerSignalling(AdditionalHeaderForSignalingInformation signalingInformation, byte[] payload) diff --git a/skyscraper8/Atsc/A322/IAtscPlpEventHandler.cs b/skyscraper8/Atsc/A322/IAtscPlpEventHandler.cs index 764955c..0463f69 100644 --- a/skyscraper8/Atsc/A322/IAtscPlpEventHandler.cs +++ b/skyscraper8/Atsc/A322/IAtscPlpEventHandler.cs @@ -5,12 +5,13 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using skyscraper8.Atsc.A330; +using skyscraper8.Skyscraper.Net.VirtualNetworks; namespace skyscraper8.Atsc.A322 { internal interface IAtscPlpEventHandler { - void OnIpDatagram(int pid, byte[] payload); + void OnIpDatagram(VirtualNetworkIdentifier pid, byte[] payload); void OnAtsc3LinkMappingTable(ushort plp, AdditionalHeaderForSignalingInformation signalingInformation, LinkMappingTable lmt); } } diff --git a/skyscraper8/Atsc/A324/StltpNetworkIdentifier.cs b/skyscraper8/Atsc/A324/StltpNetworkIdentifier.cs new file mode 100644 index 0000000..26410de --- /dev/null +++ b/skyscraper8/Atsc/A324/StltpNetworkIdentifier.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using skyscraper8.Skyscraper.Net.VirtualNetworks; + +namespace skyscraper8.Atsc.A324 +{ + [VirtualNetworkId(3)] + internal class StltpNetworkIdentifier : VirtualNetworkIdentifier + { + public StltpNetworkIdentifier() + { + this.guid = Guid.NewGuid(); + } + + private Guid guid; + + public override string GetCaptureFilenamePrefix() + { + return "stltp"; + } + + public override string GetHumanReadableName() + { + return "ATSC3 STLTP"; + } + + public override int GetIdentifier() + { + return guid.GetHashCode(); + } + } +} diff --git a/skyscraper8/Atsc/A324/StltpReceiver.cs b/skyscraper8/Atsc/A324/StltpReceiver.cs index 561b72f..6179c06 100644 --- a/skyscraper8/Atsc/A324/StltpReceiver.cs +++ b/skyscraper8/Atsc/A324/StltpReceiver.cs @@ -115,7 +115,11 @@ namespace skyscraper8.Atsc.A324 } break; case 4: //Deliver the packet - context.OnIpDatagram(0x1fff, currentIpPacketBuffer.AsSpan().Slice(0, currentIpPacketBufferOffset).ToArray()); + if (networkIdentifier == null) + { + networkIdentifier = new StltpNetworkIdentifier(); + } + context.OnIpDatagram(networkIdentifier, currentIpPacketBuffer.AsSpan().Slice(0, currentIpPacketBufferOffset).ToArray()); stateMachineState = 1; break; default: @@ -125,6 +129,7 @@ namespace skyscraper8.Atsc.A324 processed = true; } + private StltpNetworkIdentifier networkIdentifier; private SkyscraperContext context; public void SetContext(DateTime? currentTime, object skyscraperContext) { diff --git a/skyscraper8/Dvb/DataBroadcasting/DataBroadcastingException.cs b/skyscraper8/Dvb/DataBroadcasting/DataBroadcastingException.cs new file mode 100644 index 0000000..991f89f --- /dev/null +++ b/skyscraper8/Dvb/DataBroadcasting/DataBroadcastingException.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using skyscraper5.Dvb; + +namespace skyscraper8.Dvb.DataBroadcasting +{ + class DataBroadcastingException : DvbException + { + + public DataBroadcastingException(string message) : base(message) + { + } + + public DataBroadcastingException(string message, Exception inner) : base(message, inner) + { + } + } +} diff --git a/skyscraper8/Dvb/DataBroadcasting/MultiprotocolEncapsulationDecoder.cs b/skyscraper8/Dvb/DataBroadcasting/MultiprotocolEncapsulationDecoder.cs index fffc4e7..df64e9e 100644 --- a/skyscraper8/Dvb/DataBroadcasting/MultiprotocolEncapsulationDecoder.cs +++ b/skyscraper8/Dvb/DataBroadcasting/MultiprotocolEncapsulationDecoder.cs @@ -9,6 +9,8 @@ using log4net; using skyscraper5.Ietf.Rfc768; using skyscraper5.Mpeg2; using skyscraper5.Skyscraper.IO; +using skyscraper8.Dvb.DataBroadcasting; +using skyscraper8.Skyscraper.Net.VirtualNetworks; namespace skyscraper5.Dvb.DataBroadcasting { @@ -59,6 +61,8 @@ namespace skyscraper5.Dvb.DataBroadcasting { return; } + + EnsureVirtualNetworkIdentifier(sourcePid); byte[] payload = ms.ReadBytes(length); if (llcSnap) { @@ -71,6 +75,7 @@ namespace skyscraper5.Dvb.DataBroadcasting } + private bool announcedLlcTraffic; private void HandleLlcSnap(int sourcePid, byte[] macAddress, byte[] payload) { @@ -81,12 +86,28 @@ namespace skyscraper5.Dvb.DataBroadcasting } PhysicalAddress physicalAddress = new PhysicalAddress(macAddress); - EventHandler.OnLlcFrame((ushort)sourcePid, PhysicalAddress.None, physicalAddress, (ushort)payload.Length, payload); + EventHandler.OnLlcFrame(networkIdentifier, PhysicalAddress.None, physicalAddress, (ushort)payload.Length, payload); } private void HandleIpDatagram(int sourcePid, byte[] payload) { - EventHandler.OnIpDatagram(sourcePid, payload); + EventHandler.OnIpDatagram(networkIdentifier, payload); + } + + private PidNetworkIdentifier networkIdentifier; + private void EnsureVirtualNetworkIdentifier(int sourcePid) + { + if (networkIdentifier == null) + { + networkIdentifier = new PidNetworkIdentifier((ushort)sourcePid); + } + else + { + if (networkIdentifier.PID != sourcePid) + { + throw new DataBroadcastingException("Re-using the same MPE Decoder for multiple PIDs is not supported yet."); + } + } } } } diff --git a/skyscraper8/Dvb/DataBroadcasting/MultiprotocolEncapsulationEventHandler.cs b/skyscraper8/Dvb/DataBroadcasting/MultiprotocolEncapsulationEventHandler.cs index 12c9a17..9ac98d2 100644 --- a/skyscraper8/Dvb/DataBroadcasting/MultiprotocolEncapsulationEventHandler.cs +++ b/skyscraper8/Dvb/DataBroadcasting/MultiprotocolEncapsulationEventHandler.cs @@ -5,15 +5,16 @@ using System.Net.NetworkInformation; using System.Text; using System.Threading.Tasks; using skyscraper5.Ietf.Rfc971; +using skyscraper8.Skyscraper.Net.VirtualNetworks; -namespace skyscraper5.Dvb.DataBroadcasting +namespace skyscraper8.Dvb.DataBroadcasting { public interface IMultiprotocolEncapsulationEventHandler { - void OnIpv4PacketArrival(InternetHeader internetHeader, byte[] ipv4Packet); - void OnIpDatagram(int sourcePid, byte[] payload); + void OnIpv4PacketArrival(VirtualNetworkIdentifier networkId, InternetHeader internetHeader, byte[] ipv4Packet); + void OnIpDatagram(VirtualNetworkIdentifier sourcePid, byte[] payload); - void OnLlcFrame(ushort pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents); + void OnLlcFrame(VirtualNetworkIdentifier pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents); } diff --git a/skyscraper8/Dvb/DvbException.cs b/skyscraper8/Dvb/DvbException.cs index bad4055..82276e1 100644 --- a/skyscraper8/Dvb/DvbException.cs +++ b/skyscraper8/Dvb/DvbException.cs @@ -10,6 +10,7 @@ namespace skyscraper5.Dvb { class DvbException : Mpeg2Exception { + public DvbException(string s, params object[] args) : base(String.Format(s, args)) { diff --git a/skyscraper8/GS/GSE-BFBS/BfbsGseReader.cs b/skyscraper8/GS/GSE-BFBS/BfbsGseReader.cs index 6c6cb7f..86fe414 100644 --- a/skyscraper8/GS/GSE-BFBS/BfbsGseReader.cs +++ b/skyscraper8/GS/GSE-BFBS/BfbsGseReader.cs @@ -1,255 +1,260 @@ -using skyscraper5.Dvb.DataBroadcasting; -using skyscraper5.Mpeg2; -using skyscraper5.Skyscraper.IO; -using skyscraper5.src.InteractionChannel; -using skyscraper8.GSE; -using skyscraper8.GSE.GSE; -using skyscraper8.Skyscraper.IO; -using skyscraper8.Skyscraper.Scraper; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using static skyscraper5.Dvb.Descriptors.ContentIdentifierDescriptor; - -namespace skyscraper8.GS.GSE_BFBS -{ - internal class BfbsGseReader : IMisHandler - { - private GseLabel lastLabel; - private int frameNo; - public GsContextDto Context { get; set; } - - public BfbsGseReader(GsContextDto context) - { - this.Context = context; - } - - private bool CheckAllZeroes(ReadOnlySpan span) - { - for (int i = 0; i < span.Length - 4; i++) - { - if (span[i] != 0) - { - return false; - } - } - - return true; - } - - public void PushFrame(BBHeader bbHeader, ReadOnlySpan readOnlySpan) - { - frameNo++; - bool validCrc = DvbCrc32.ValidateCrc(readOnlySpan); - if (!validCrc) - return; - - if (readOnlySpan[0] == 0 && readOnlySpan[1] == 0 && readOnlySpan[2] == 0 && readOnlySpan[3] == 0) - { - if (CheckAllZeroes(readOnlySpan)) - { - return; - } - else - { - throw new NotImplementedException("A BBFrame with data offset not at 0 was found. This not supported yet, please share a sample of this."); - } - } - - - StreamlikeSpan span = new StreamlikeSpan(readOnlySpan); - - while (span.GetAvailableBytes() > 4) - { - byte byteA = span.ReadUInt8(); - bool startIndicator = (byteA & 0x80) != 0; - bool endIndicator = (byteA & 0x40) != 0; - int labelTypeIndicator = (byteA & 0x30) >> 4; - if (!startIndicator && !endIndicator && labelTypeIndicator == 0) - { - //padding bits, packet has ended. - return; - } - else - { - GsePacket gsePacket = new GsePacket(startIndicator, endIndicator, labelTypeIndicator); - int gseLength = (byteA & 0x0f) << 8; - gseLength += span.ReadUInt8(); - - gsePacket.FragmentId = null; - if (!startIndicator || !endIndicator) - { - gsePacket.FragmentId = span.ReadUInt8(); - gseLength -= 1; - } - - if ((startIndicator) && !endIndicator) - { - gsePacket.TotalLength = span.ReadUInt16BE(); - gseLength -= 2; - } - - if (startIndicator) - { - gsePacket.ProtocolType = span.ReadUInt16BE(); - gseLength -= 2; - if (labelTypeIndicator == 0) - { - gsePacket.Label = new _6byteLabel(span.ReadBytes(6)); - gseLength -= 6; - } - else if (labelTypeIndicator == 1) - { - gsePacket.Label = new _3byteLabel(span.ReadBytes(3)); - gseLength -= 3; - } - else if (labelTypeIndicator == 2) - { - gsePacket.Label = BroadcastLabel.GetInstance(); - } - else if (labelTypeIndicator == 3) - { - gsePacket.Label = lastLabel; - } - lastLabel = gsePacket.Label; - } - - if (!startIndicator && endIndicator) - gseLength -= 4; - +using skyscraper5.Dvb.DataBroadcasting; +using skyscraper5.Mpeg2; +using skyscraper5.Skyscraper.IO; +using skyscraper5.src.InteractionChannel; +using skyscraper8.GSE; +using skyscraper8.GSE.GSE; +using skyscraper8.Skyscraper.IO; +using skyscraper8.Skyscraper.Scraper; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static skyscraper5.Dvb.Descriptors.ContentIdentifierDescriptor; + +namespace skyscraper8.GS.GSE_BFBS +{ + internal class BfbsGseReader : IMisHandler + { + private GseLabel lastLabel; + private int frameNo; + public GsContextDto Context { get; set; } + + public BfbsGseReader(GsContextDto context) + { + this.Context = context; + } + + private bool CheckAllZeroes(ReadOnlySpan span) + { + for (int i = 0; i < span.Length - 4; i++) + { + if (span[i] != 0) + { + return false; + } + } + + return true; + } + + public void PushFrame(BBHeader bbHeader, ReadOnlySpan readOnlySpan) + { + frameNo++; + bool validCrc = DvbCrc32.ValidateCrc(readOnlySpan); + if (!validCrc) + return; + + if (readOnlySpan[0] == 0 && readOnlySpan[1] == 0 && readOnlySpan[2] == 0 && readOnlySpan[3] == 0) + { + if (CheckAllZeroes(readOnlySpan)) + { + return; + } + else + { + throw new NotImplementedException("A BBFrame with data offset not at 0 was found. This not supported yet, please share a sample of this."); + } + } + + + StreamlikeSpan span = new StreamlikeSpan(readOnlySpan); + + while (span.GetAvailableBytes() > 4) + { + byte byteA = span.ReadUInt8(); + bool startIndicator = (byteA & 0x80) != 0; + bool endIndicator = (byteA & 0x40) != 0; + int labelTypeIndicator = (byteA & 0x30) >> 4; + if (!startIndicator && !endIndicator && labelTypeIndicator == 0) + { + //padding bits, packet has ended. + return; + } + else + { + GsePacket gsePacket = new GsePacket(startIndicator, endIndicator, labelTypeIndicator); + int gseLength = (byteA & 0x0f) << 8; + gseLength += span.ReadUInt8(); + + gsePacket.FragmentId = null; + if (!startIndicator || !endIndicator) + { + gsePacket.FragmentId = span.ReadUInt8(); + gseLength -= 1; + } + + if ((startIndicator) && !endIndicator) + { + gsePacket.TotalLength = span.ReadUInt16BE(); + gseLength -= 2; + } + + if (startIndicator) + { + gsePacket.ProtocolType = span.ReadUInt16BE(); + gseLength -= 2; + if (labelTypeIndicator == 0) + { + gsePacket.Label = new _6byteLabel(span.ReadBytes(6)); + gseLength -= 6; + } + else if (labelTypeIndicator == 1) + { + gsePacket.Label = new _3byteLabel(span.ReadBytes(3)); + gseLength -= 3; + } + else if (labelTypeIndicator == 2) + { + gsePacket.Label = BroadcastLabel.GetInstance(); + } + else if (labelTypeIndicator == 3) + { + gsePacket.Label = lastLabel; + } + lastLabel = gsePacket.Label; + } + + if (!startIndicator && endIndicator) + gseLength -= 4; + if (span.GetAvailableBytes() < gseLength) { //broken gse packet, invalid length return; - } - gsePacket.GseDataBytes = span.ReadBytes(gseLength); - - if (!startIndicator && endIndicator) - { - gsePacket.Crc32 = span.ReadUInt32BE(); - } - - HandleGseFrame(gsePacket); - } - } - } - - private GseFragmentation[] fragmentations; - private void HandleGseFrame(GsePacket gsePacket) - { - if (gsePacket.StartIndicator & gsePacket.EndIndicator) - { - HandleAssembledFrame(gsePacket.ProtocolType.Value, gsePacket.GseDataBytes, gsePacket.Label); - return; - } - - if (!gsePacket.StartIndicator && gsePacket.EndIndicator) - { - if (fragmentations == null) - { - //This stream had no fragmentations yet, so we cannot reassemble this packet. - return; - } - - if (fragmentations[gsePacket.FragmentId.Value] == null) - { - //The previous fragments are missing, so we cannot reassemble this packet. - return; - } - - fragmentations[gsePacket.FragmentId.Value].AddFragement(gsePacket); - if (fragmentations[gsePacket.FragmentId.Value].Validate()) - { - byte[] gseDataBytes = fragmentations[gsePacket.FragmentId.Value].GetGseDataBytes(); - ushort protocolType = fragmentations[gsePacket.FragmentId.Value].ProtocolType; - HandleAssembledFrame(protocolType, gseDataBytes, fragmentations[gsePacket.FragmentId.Value].Label); - fragmentations[gsePacket.FragmentId.Value] = null; - return; - } - else - { - throw new NotImplementedException(); - } - } - - if (gsePacket.StartIndicator && !gsePacket.EndIndicator) - { - fragmentations = new GseFragmentation[256]; - fragmentations[gsePacket.FragmentId.Value] = new GseFragmentation(gsePacket); - return; - } - - if (!gsePacket.StartIndicator && !gsePacket.EndIndicator) - { - if (fragmentations == null) - { - //This stream had no fragmentations yet, so we cannot reassemble this packet. - return; - } - - if (fragmentations[gsePacket.FragmentId.Value] == null) - { - //The previous fragments are missing, so we cannot reassemble this packet. - return; - } - - fragmentations[gsePacket.FragmentId.Value].AddFragement(gsePacket); - return; - } - - throw new NotImplementedException( - "A unknown frame type was encountered. Please share a sample of this stream."); - } - - private void HandleAssembledFrame(ushort protocolType, byte[] buffer, GseLabel label) - { - Context.UiJunction?.EnableUiFeature(SkyscraperUiFeature.GseAnalysis); - Context.UiJunction?.NotifyGsePacket(protocolType, buffer, label); - switch (protocolType) - { - case 0x0081: - //Network clock reference - HandleNetworkClockReference(buffer); - return; - case 0x0082: - //Lower Layer Signalling, see en_30154502v010401p.pdf, page 49 - HandleLowerLayerSignalling(buffer, label); - return; - case 0x0091: - //according to https://www.iana.org/assignments/ule-next-headers/ule-next-headers.xhtml it's private - return; - case 0x0800: - Context.IpOutput.OnIpDatagram(0x010e, buffer); - return; - default: - throw new NotImplementedException(protocolType.ToString()); - } - } - - private GseL2SHandler rcs2; - private void HandleLowerLayerSignalling(byte[] buffer, GseLabel label) - { - if (rcs2 == null) - { - rcs2 = new GseL2SHandler(Context); - } - - rcs2.PushPacket(buffer, label); - - } - - private void HandleNetworkClockReference(byte[] buffer) - { - MemoryStream binaryReader = new MemoryStream(buffer); - uint pcrA = binaryReader.ReadUInt32BE(); - ushort pcrB = binaryReader.ReadUInt16BE(); - ulong pcr_base = ((ulong)pcrA << 1) | ((ulong)pcrB >> 15); - ulong pcr_ext = (ulong)pcrB & 0x01ff; - ulong PCR = pcr_base * 300 + pcr_ext; - ulong seconds = PCR / 27000000; - } - } -} + } + gsePacket.GseDataBytes = span.ReadBytes(gseLength); + + if (!startIndicator && endIndicator) + { + gsePacket.Crc32 = span.ReadUInt32BE(); + } + + HandleGseFrame(gsePacket); + } + } + } + + private GseFragmentation[] fragmentations; + private void HandleGseFrame(GsePacket gsePacket) + { + if (gsePacket.StartIndicator & gsePacket.EndIndicator) + { + HandleAssembledFrame(gsePacket.ProtocolType.Value, gsePacket.GseDataBytes, gsePacket.Label); + return; + } + + if (!gsePacket.StartIndicator && gsePacket.EndIndicator) + { + if (fragmentations == null) + { + //This stream had no fragmentations yet, so we cannot reassemble this packet. + return; + } + + if (fragmentations[gsePacket.FragmentId.Value] == null) + { + //The previous fragments are missing, so we cannot reassemble this packet. + return; + } + + fragmentations[gsePacket.FragmentId.Value].AddFragement(gsePacket); + if (fragmentations[gsePacket.FragmentId.Value].Validate()) + { + byte[] gseDataBytes = fragmentations[gsePacket.FragmentId.Value].GetGseDataBytes(); + ushort protocolType = fragmentations[gsePacket.FragmentId.Value].ProtocolType; + HandleAssembledFrame(protocolType, gseDataBytes, fragmentations[gsePacket.FragmentId.Value].Label); + fragmentations[gsePacket.FragmentId.Value] = null; + return; + } + else + { + throw new NotImplementedException(); + } + } + + if (gsePacket.StartIndicator && !gsePacket.EndIndicator) + { + fragmentations = new GseFragmentation[256]; + fragmentations[gsePacket.FragmentId.Value] = new GseFragmentation(gsePacket); + return; + } + + if (!gsePacket.StartIndicator && !gsePacket.EndIndicator) + { + if (fragmentations == null) + { + //This stream had no fragmentations yet, so we cannot reassemble this packet. + return; + } + + if (fragmentations[gsePacket.FragmentId.Value] == null) + { + //The previous fragments are missing, so we cannot reassemble this packet. + return; + } + + fragmentations[gsePacket.FragmentId.Value].AddFragement(gsePacket); + return; + } + + throw new NotImplementedException( + "A unknown frame type was encountered. Please share a sample of this stream."); + } + + private MisNetworkIdentifier networkIdentifier; + private void HandleAssembledFrame(ushort protocolType, byte[] buffer, GseLabel label) + { + Context.UiJunction?.EnableUiFeature(SkyscraperUiFeature.GseAnalysis); + Context.UiJunction?.NotifyGsePacket(protocolType, buffer, label); + switch (protocolType) + { + case 0x0081: + //Network clock reference + HandleNetworkClockReference(buffer); + return; + case 0x0082: + //Lower Layer Signalling, see en_30154502v010401p.pdf, page 49 + HandleLowerLayerSignalling(buffer, label); + return; + case 0x0091: + //according to https://www.iana.org/assignments/ule-next-headers/ule-next-headers.xhtml it's private + return; + case 0x0800: + if (networkIdentifier == null) + { + networkIdentifier = new MisNetworkIdentifier(Context.GetMisId()); + } + Context.IpOutput.OnIpDatagram(networkIdentifier, buffer); + return; + default: + throw new NotImplementedException(protocolType.ToString()); + } + } + + private GseL2SHandler rcs2; + private void HandleLowerLayerSignalling(byte[] buffer, GseLabel label) + { + if (rcs2 == null) + { + rcs2 = new GseL2SHandler(Context); + } + + rcs2.PushPacket(buffer, label); + + } + + private void HandleNetworkClockReference(byte[] buffer) + { + MemoryStream binaryReader = new MemoryStream(buffer); + uint pcrA = binaryReader.ReadUInt32BE(); + ushort pcrB = binaryReader.ReadUInt16BE(); + ulong pcr_base = ((ulong)pcrA << 1) | ((ulong)pcrB >> 15); + ulong pcr_ext = (ulong)pcrB & 0x01ff; + ulong PCR = pcr_base * 300 + pcr_ext; + ulong seconds = PCR / 27000000; + } + } +} diff --git a/skyscraper8/GS/GSE-HEM/GseHemReader.cs b/skyscraper8/GS/GSE-HEM/GseHemReader.cs index f1dcbac..fa9255c 100644 --- a/skyscraper8/GS/GSE-HEM/GseHemReader.cs +++ b/skyscraper8/GS/GSE-HEM/GseHemReader.cs @@ -98,6 +98,7 @@ class GseHemReader : IMisHandler } } + private MisNetworkIdentifier networkIdentifier; private void HandlePacket(GsePacket packet) { Context.UiJunction?.EnableUiFeature(SkyscraperUiFeature.GseAnalysis); @@ -107,7 +108,11 @@ class GseHemReader : IMisHandler switch (packet.ProtocolType) { case 0x0800: - Context.IpOutput.OnIpDatagram(0x010e,packet.GseDataBytes); + if (networkIdentifier == null) + { + networkIdentifier = new MisNetworkIdentifier(Context.GetMisId()); + } + Context.IpOutput.OnIpDatagram(networkIdentifier,packet.GseDataBytes); return; default: logger.WarnFormat("This GSE-HEM stream contains traffic other than IP. IP is type 0x0800, but we got 0x{0:X4} here.", packet.ProtocolType); diff --git a/skyscraper8/GS/GSE-RollingSyncByte/GseWithRollingSyncByteReader.cs b/skyscraper8/GS/GSE-RollingSyncByte/GseWithRollingSyncByteReader.cs index 588c8fc..d1f6570 100644 --- a/skyscraper8/GS/GSE-RollingSyncByte/GseWithRollingSyncByteReader.cs +++ b/skyscraper8/GS/GSE-RollingSyncByte/GseWithRollingSyncByteReader.cs @@ -150,12 +150,22 @@ public class GseWithRollingSyncByteReader : IMisHandler throw new NotImplementedException(); } + private MisNetworkIdentifier networkIdentifier; + private void EnsureNetworkIdentifier() + { + if (networkIdentifier == null) + { + networkIdentifier = new MisNetworkIdentifier(Context.GetMisId()); + } + } + private ulong aolSerial; private void HandleProprietaryAolJunk(byte[] buffer, ushort protocolType) { if (buffer[0] == 0x45) { - Context.IpOutput.OnIpDatagram(0x0118, buffer); + EnsureNetworkIdentifier(); + Context.IpOutput.OnIpDatagram(networkIdentifier, buffer); return; } /*aolSerial++; @@ -177,7 +187,8 @@ public class GseWithRollingSyncByteReader : IMisHandler //according to https://www.iana.org/assignments/ule-next-headers/ule-next-headers.xhtml it's private return; case 0x0800: - Context.IpOutput.OnIpDatagram(0x010e, buffer); + EnsureNetworkIdentifier(); + Context.IpOutput.OnIpDatagram(networkIdentifier, buffer); return; default: if (warnedEthertypes == null) diff --git a/skyscraper8/GS/GSE/GseReader.cs b/skyscraper8/GS/GSE/GseReader.cs index 8abf220..5af6ef2 100644 --- a/skyscraper8/GS/GSE/GseReader.cs +++ b/skyscraper8/GS/GSE/GseReader.cs @@ -109,6 +109,16 @@ internal class GseReader : IMisHandler } } + private MisNetworkIdentifier networkIdentifier; + + private void EnsureNetworkIdentifier() + { + if (networkIdentifier == null) + { + networkIdentifier = new MisNetworkIdentifier(Context.GetMisId()); + } + } + private bool[] warnedEthertypes; private GseFragmentation[] fragmentations; private void ProcessPacket(GsePacket child) @@ -123,7 +133,8 @@ internal class GseReader : IMisHandler currentFragmentation.AddFragement(child); if (currentFragmentation.Validate()) { - Context.IpOutput.OnIpDatagram(0x010e,currentFragmentation.GetGseDataBytes()); + EnsureNetworkIdentifier(); + Context.IpOutput.OnIpDatagram(networkIdentifier,currentFragmentation.GetGseDataBytes()); } fragmentations[child.FragmentId.Value] = null; @@ -160,7 +171,8 @@ internal class GseReader : IMisHandler switch (child.ProtocolType) { case 0x0800: - Context.IpOutput.OnIpDatagram(0x010e, child.GseDataBytes); + EnsureNetworkIdentifier(); + Context.IpOutput.OnIpDatagram(networkIdentifier, child.GseDataBytes); break; default: if (warnedEthertypes == null) diff --git a/skyscraper8/GS/GsContextDto.cs b/skyscraper8/GS/GsContextDto.cs index 3b40a0a..e2bbe87 100644 --- a/skyscraper8/GS/GsContextDto.cs +++ b/skyscraper8/GS/GsContextDto.cs @@ -5,9 +5,9 @@ using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; -using skyscraper5.Dvb.DataBroadcasting; using skyscraper5.Skyscraper.Scraper; using skyscraper5.src.InteractionChannel; +using skyscraper8.Dvb.DataBroadcasting; using skyscraper8.Skyscraper.Scraper; namespace skyscraper8.GS diff --git a/skyscraper8/GS/IPv4PacketBruteforce.cs b/skyscraper8/GS/IPv4PacketBruteforce.cs index 5ccce53..da104da 100644 --- a/skyscraper8/GS/IPv4PacketBruteforce.cs +++ b/skyscraper8/GS/IPv4PacketBruteforce.cs @@ -21,7 +21,8 @@ namespace skyscraper8.GS private ILog logger; private bool notified; - + private MisNetworkIdentifier networkIdentifier; + public GsContextDto Context { get; set; } public void PushFrame(BBHeader bbHeader, ReadOnlySpan readOnlySpan) { @@ -40,7 +41,11 @@ namespace skyscraper8.GS foreach (byte[] packet in packets) { - Context.IpOutput.OnIpDatagram(0x0118, packet); + if (networkIdentifier == null) + { + networkIdentifier = new MisNetworkIdentifier(Context.GetMisId()); + } + Context.IpOutput.OnIpDatagram(networkIdentifier, packet); } } } diff --git a/skyscraper8/GS/MisNetworkIdentifier.cs b/skyscraper8/GS/MisNetworkIdentifier.cs new file mode 100644 index 0000000..31b7f2e --- /dev/null +++ b/skyscraper8/GS/MisNetworkIdentifier.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using skyscraper8.Skyscraper.Net.VirtualNetworks; + +namespace skyscraper8.GS +{ + [VirtualNetworkId(3)] + internal class MisNetworkIdentifier : VirtualNetworkIdentifier + { + private readonly byte _getMisId; + + public MisNetworkIdentifier(byte getMisId) + { + _getMisId = getMisId; + } + + public override string GetCaptureFilenamePrefix() + { + return String.Format("mis{0}", _getMisId); + } + + public override string GetHumanReadableName() + { + return String.Format("MIS {0}", _getMisId); + } + + public override int GetIdentifier() + { + return _getMisId; + } + } +} diff --git a/skyscraper8/Ietf/Rfc4236_ULE/UleContestant.cs b/skyscraper8/Ietf/Rfc4236_ULE/UleContestant.cs index f1d998a..0c04872 100644 --- a/skyscraper8/Ietf/Rfc4236_ULE/UleContestant.cs +++ b/skyscraper8/Ietf/Rfc4236_ULE/UleContestant.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using skyscraper5.Skyscraper.Plugins; using skyscraper5.Skyscraper.Scraper; using skyscraper5.Skyscraper.Scraper.StreamAutodetection; +using skyscraper8.Skyscraper.Net.VirtualNetworks; namespace skyscraper8.Ietf.Rfc4236_ULE { @@ -33,17 +34,17 @@ namespace skyscraper8.Ietf.Rfc4236_ULE } - public void OnEthernetFrame(int pid, PhysicalAddress destination, PhysicalAddress source, ushort etherType, byte[] contents) + public void OnEthernetFrame(VirtualNetworkIdentifier pid, PhysicalAddress destination, PhysicalAddress source, ushort etherType, byte[] contents) { Score++; } - public void OnLlcFrame(ushort pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents) + public void OnLlcFrame(VirtualNetworkIdentifier pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents) { Score++; } - public void OnUleError(int pid, int errorNo) + public void OnUleError(VirtualNetworkIdentifier pid, int errorNo) { Score--; } diff --git a/skyscraper8/Ietf/Rfc4236_ULE/UleEventHandler.cs b/skyscraper8/Ietf/Rfc4236_ULE/UleEventHandler.cs index 874545a..1c5a23d 100644 --- a/skyscraper8/Ietf/Rfc4236_ULE/UleEventHandler.cs +++ b/skyscraper8/Ietf/Rfc4236_ULE/UleEventHandler.cs @@ -4,12 +4,13 @@ using System.Linq; using System.Net.NetworkInformation; using System.Text; using System.Threading.Tasks; +using skyscraper8.Skyscraper.Net.VirtualNetworks; namespace skyscraper8.Ietf.Rfc4236_ULE { internal interface UleEventHandler { - void OnLlcFrame(ushort pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents); + void OnLlcFrame(VirtualNetworkIdentifier pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents); /// /// The UlePacketProcessor is supposed to call this whenever an Error occurs during deframing. @@ -20,6 +21,6 @@ namespace skyscraper8.Ietf.Rfc4236_ULE /// 1* for a CRC error. /// 2* for an invalid adaptation field control. /// - void OnUleError(int pid, int errorNo); + void OnUleError(VirtualNetworkIdentifier pid, int errorNo); } } diff --git a/skyscraper8/Ietf/Rfc4236_ULE/UlePacketProcessor.cs b/skyscraper8/Ietf/Rfc4236_ULE/UlePacketProcessor.cs index 478efe8..55eca52 100644 --- a/skyscraper8/Ietf/Rfc4236_ULE/UlePacketProcessor.cs +++ b/skyscraper8/Ietf/Rfc4236_ULE/UlePacketProcessor.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Net.NetworkInformation; using System.Text; using System.Threading.Tasks; +using skyscraper8.Skyscraper.Net.VirtualNetworks; namespace skyscraper8.Ietf.Rfc4236_ULE { @@ -22,10 +23,13 @@ namespace skyscraper8.Ietf.Rfc4236_ULE private MemoryStream reassemblyStream; private long offset; + private PidNetworkIdentifier networkIdentifier; + public UlePacketProcessor(int pid, UleEventHandler eventHandler) { _pid = pid; _eventHandler = eventHandler; + networkIdentifier = new PidNetworkIdentifier((ushort)pid); } public void PushPacket(TsPacket packet) @@ -34,7 +38,7 @@ namespace skyscraper8.Ietf.Rfc4236_ULE Span packetPayload = packet.GetPayload(); if (packetAdaptionField != null || packetPayload == null) { - _eventHandler.OnUleError(_pid, 2); + _eventHandler.OnUleError(networkIdentifier, 2); return; } if (packet.PayloadUnitStart) @@ -135,7 +139,7 @@ namespace skyscraper8.Ietf.Rfc4236_ULE bool crc = DvbCrc32.ValidateCrc(ms, 0, (int)ms.Length); if (!crc) { - _eventHandler.OnUleError(_pid, 1); + _eventHandler.OnUleError(networkIdentifier, 1); return; } @@ -202,7 +206,7 @@ namespace skyscraper8.Ietf.Rfc4236_ULE PhysicalAddress source = new PhysicalAddress(ms.ReadBytes(6)); ushort etherType = ms.ReadUInt16BE(); byte[] contents = ms.ReadBytes(ms.GetAvailableBytes()); - _eventHandler.OnLlcFrame((ushort)_pid, source, destination, etherType, contents); + _eventHandler.OnLlcFrame(networkIdentifier, source, destination, etherType, contents); } public void PacketLoss() diff --git a/skyscraper8/Skyscraper/Net/IpTrafficHandler.cs b/skyscraper8/Skyscraper/Net/IpTrafficHandler.cs index eb58c21..09d852a 100644 --- a/skyscraper8/Skyscraper/Net/IpTrafficHandler.cs +++ b/skyscraper8/Skyscraper/Net/IpTrafficHandler.cs @@ -4,12 +4,13 @@ using System.Linq; using System.Net.NetworkInformation; using System.Text; using System.Threading.Tasks; +using skyscraper8.Skyscraper.Net.VirtualNetworks; namespace skyscraper8.Skyscraper.Net { internal interface IpTrafficHandler : IDisposable { - void HandleIpPacket(int pid, byte[] payload); - void HandleLlcFrame(ushort pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents); + void HandleIpPacket(VirtualNetworkIdentifier pid, byte[] payload); + void HandleLlcFrame(VirtualNetworkIdentifier pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents); } } diff --git a/skyscraper8/Skyscraper/Net/NullIpTrafficHandler.cs b/skyscraper8/Skyscraper/Net/NullIpTrafficHandler.cs index 45cb27a..268ba33 100644 --- a/skyscraper8/Skyscraper/Net/NullIpTrafficHandler.cs +++ b/skyscraper8/Skyscraper/Net/NullIpTrafficHandler.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Net.NetworkInformation; using System.Text; using System.Threading.Tasks; +using skyscraper8.Skyscraper.Net.VirtualNetworks; namespace skyscraper8.Skyscraper.Net { @@ -20,12 +21,12 @@ namespace skyscraper8.Skyscraper.Net } - public void HandleIpPacket(int pid, byte[] payload) + public void HandleIpPacket(VirtualNetworkIdentifier pid, byte[] payload) { } - public void HandleLlcFrame(ushort pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents) + public void HandleLlcFrame(VirtualNetworkIdentifier pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents) { } diff --git a/skyscraper8/Skyscraper/Net/Pcap/PcapIpTrafficHandler.cs b/skyscraper8/Skyscraper/Net/Pcap/PcapIpTrafficHandler.cs index 2460b79..080673b 100644 --- a/skyscraper8/Skyscraper/Net/Pcap/PcapIpTrafficHandler.cs +++ b/skyscraper8/Skyscraper/Net/Pcap/PcapIpTrafficHandler.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Net.NetworkInformation; using System.Text; using System.Threading.Tasks; +using skyscraper8.Skyscraper.Net.VirtualNetworks; namespace skyscraper8.Skyscraper.Net.Pcap { @@ -18,33 +19,33 @@ namespace skyscraper8.Skyscraper.Net.Pcap internal class PcapIpTrafficHandler : IpTrafficHandler { private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); - private PcapWriter[] pcapWritersIp; - private PcapWriter[] pcapWritersLlc; + private Dictionary pcapWritersIp; + private Dictionary pcapWritersLlc; private DirectoryInfo outputDirectory; - public void HandleIpPacket(int pid, byte[] payload) + public void HandleIpPacket(VirtualNetworkIdentifier network, byte[] payload) { if (pcapWritersIp == null) { - pcapWritersIp = new PcapWriter[0x2000]; + pcapWritersIp = new Dictionary(); EnsureOutputdirExists(); } - if (pcapWritersIp[pid] == null) + if (!pcapWritersIp.ContainsKey(network)) { - string fname = String.Format("{0:X4},{1}.pcap", pid, DateTime.Now.Ticks); + string fname = String.Format("{0},{1}.pcap", network.GetCaptureFilenamePrefix(), DateTime.Now.Ticks); if (outputDirectory != null) { fname = Path.Combine(outputDirectory.FullName, fname); } logger.InfoFormat("Opening file for writing: {0}", fname); FileStream fs = File.OpenWrite(fname); - pcapWritersIp[pid] = new PcapWriter(fs, TcpdumpNetworkType.RawIp); + pcapWritersIp[network] = new PcapWriter(fs, TcpdumpNetworkType.RawIp); } - pcapWritersIp[pid].WritePacket(payload); + pcapWritersIp[network].WritePacket(payload); } - public void HandleLlcFrame(ushort pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, + public void HandleLlcFrame(VirtualNetworkIdentifier network, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents) { byte[] dstAddr = destination.GetAddressBytes(); @@ -65,13 +66,13 @@ namespace skyscraper8.Skyscraper.Net.Pcap if (pcapWritersLlc == null) { - pcapWritersLlc = new PcapWriter[0x1fff]; + pcapWritersLlc = new Dictionary(); EnsureOutputdirExists(); } - if (pcapWritersLlc[pid] == null) + if (pcapWritersLlc[network] == null) { - string fname = String.Format("{0:X4},llc,{1}.pcap", pid, DateTime.Now.Ticks); + string fname = String.Format("{0:X4},llc,{1}.pcap", network, DateTime.Now.Ticks); if (outputDirectory != null) { fname = Path.Combine(outputDirectory.FullName, fname); @@ -79,31 +80,10 @@ namespace skyscraper8.Skyscraper.Net.Pcap logger.InfoFormat("Opening file for writing: {0}", fname); FileStream fs = File.OpenWrite(fname); - pcapWritersLlc[pid] = new PcapWriter(fs, TcpdumpNetworkType.UserDefined); + pcapWritersLlc[network] = new PcapWriter(fs, TcpdumpNetworkType.UserDefined); } - - /* - byte[] ethernetFrame = new byte[contents.Length + 14]; - Array.Copy(dstAddr, 0, ethernetFrame, 0, dstAddr.Length); - Array.Copy(srcAddr, 0, ethernetFrame, 6, srcAddr.Length); - - byte[] etherTypeBytes = BitConverter.GetBytes(etherType); - if (BitConverter.IsLittleEndian) - { - ethernetFrame[12] = etherTypeBytes[1]; - ethernetFrame[13] = etherTypeBytes[0]; - } - else - { - ethernetFrame[12] = etherTypeBytes[0]; - ethernetFrame[13] = etherTypeBytes[1]; - } - - - - Array.Copy(contents, 0, ethernetFrame, 14, contents.Length); - pcapWritersLlc[pid].WritePacket(ethernetFrame);*/ - pcapWritersLlc[pid].WritePacket(contents); + + pcapWritersLlc[network].WritePacket(contents); } @@ -123,10 +103,17 @@ namespace skyscraper8.Skyscraper.Net.Pcap { if (pcapWritersIp != null) { - for (int i = 0; i < pcapWritersIp.Length; i++) + foreach (KeyValuePair kvp in pcapWritersIp) { - if (pcapWritersIp[i] != null) - pcapWritersIp[i].Dispose(); + kvp.Value.Dispose(); + } + } + + if (pcapWritersLlc != null) + { + foreach (KeyValuePair kvp in pcapWritersLlc) + { + kvp.Value.Dispose(); } } } diff --git a/skyscraper8/Skyscraper/Net/SkyscraperNetException.cs b/skyscraper8/Skyscraper/Net/SkyscraperNetException.cs new file mode 100644 index 0000000..b182f0e --- /dev/null +++ b/skyscraper8/Skyscraper/Net/SkyscraperNetException.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Skyscraper.Net +{ + public class SkyscraperNetException : SkyscraperCoreException + { + public SkyscraperNetException() + { + } + + public SkyscraperNetException(string message) : base(message) + { + } + + public SkyscraperNetException(string message, Exception inner) : base(message, inner) + { + } + } +} diff --git a/skyscraper8/Skyscraper/Net/VirtualNetworks/AtmAdaptationLayer5NetworkIdentifier.cs b/skyscraper8/Skyscraper/Net/VirtualNetworks/AtmAdaptationLayer5NetworkIdentifier.cs new file mode 100644 index 0000000..57dc021 --- /dev/null +++ b/skyscraper8/Skyscraper/Net/VirtualNetworks/AtmAdaptationLayer5NetworkIdentifier.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Skyscraper.Net.VirtualNetworks +{ + [VirtualNetworkId(4)] + internal class AtmAdaptationLayer5NetworkIdentifier : VirtualNetworkIdentifier + { + private VirtualNetworkIdentifier wrapped; + private int identifier; + + public AtmAdaptationLayer5NetworkIdentifier(VirtualNetworkIdentifier wrapped) + { + this.wrapped = wrapped; + this.identifier = new Random().Next(); + } + + + public override string GetCaptureFilenamePrefix() + { + return String.Format("AAL5,{0}", wrapped.GetCaptureFilenamePrefix()); + } + + public override string GetHumanReadableName() + { + return String.Format("AAL5 on {0}", wrapped.GetHumanReadableName()); + } + + public override int GetIdentifier() + { + return identifier; + } + + private static Dictionary wraps; + public static VirtualNetworkIdentifier GetWrap(VirtualNetworkIdentifier network) + { + if (wraps == null) + { + wraps = new Dictionary(); + } + + if (wraps.ContainsKey(network)) + { + return wraps[network]; + } + else + { + AtmAdaptationLayer5NetworkIdentifier child = new AtmAdaptationLayer5NetworkIdentifier(network); + wraps.Add(network, child); + return child; + } + } + } +} diff --git a/skyscraper8/Skyscraper/Net/VirtualNetworks/PidNetworkIdentifier.cs b/skyscraper8/Skyscraper/Net/VirtualNetworks/PidNetworkIdentifier.cs new file mode 100644 index 0000000..74186fa --- /dev/null +++ b/skyscraper8/Skyscraper/Net/VirtualNetworks/PidNetworkIdentifier.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Skyscraper.Net.VirtualNetworks +{ + /// + /// Use this identifier when a IP/Network packets are directly encapsulated into a PID, for example by MPE or ULE. + /// + [VirtualNetworkId(2)] + internal class PidNetworkIdentifier : VirtualNetworkIdentifier + { + public PidNetworkIdentifier(ushort pid) + { + this.PID = pid; + } + + public override string GetCaptureFilenamePrefix() + { + string fname = String.Format("{0:X4}", PID); + return fname; + } + + public override string GetHumanReadableName() + { + return String.Format("PID 0x{0:X4}", PID); + } + + public override int GetIdentifier() + { + return PID; + } + + public ushort PID { get; } + } +} diff --git a/skyscraper8/Skyscraper/Net/VirtualNetworks/VirtualNetworkException.cs b/skyscraper8/Skyscraper/Net/VirtualNetworks/VirtualNetworkException.cs new file mode 100644 index 0000000..71e3db9 --- /dev/null +++ b/skyscraper8/Skyscraper/Net/VirtualNetworks/VirtualNetworkException.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Skyscraper.Net.VirtualNetworks +{ + public class VirtualNetworkException : SkyscraperNetException + { + public VirtualNetworkException() + { + } + + public VirtualNetworkException(string message) : base(message) + { + } + + public VirtualNetworkException(string message, Exception inner) : base(message, inner) + { + } + } +} diff --git a/skyscraper8/Skyscraper/Net/VirtualNetworks/VirtualNetworkIdAttribute.cs b/skyscraper8/Skyscraper/Net/VirtualNetworks/VirtualNetworkIdAttribute.cs new file mode 100644 index 0000000..e0c239a --- /dev/null +++ b/skyscraper8/Skyscraper/Net/VirtualNetworks/VirtualNetworkIdAttribute.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Skyscraper.Net.VirtualNetworks +{ + [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] + public sealed class VirtualNetworkIdAttribute : Attribute + { + public int NetworkTypeId { get; } + + public VirtualNetworkIdAttribute(int NetworkTypeId) + { + this.NetworkTypeId = NetworkTypeId; + } + + } +} diff --git a/skyscraper8/Skyscraper/Net/VirtualNetworks/VirtualNetworkIdentifier.cs b/skyscraper8/Skyscraper/Net/VirtualNetworks/VirtualNetworkIdentifier.cs new file mode 100644 index 0000000..0874e5b --- /dev/null +++ b/skyscraper8/Skyscraper/Net/VirtualNetworks/VirtualNetworkIdentifier.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Skyscraper.Net.VirtualNetworks +{ + public abstract class VirtualNetworkIdentifier + { + + public abstract string GetCaptureFilenamePrefix(); + public abstract string GetHumanReadableName(); + + /// + /// Get an network type dependant ID of the specific network. This can be for example a VLAN ID, or a PID. + /// + /// The type-dependant identifier of the network in question. + public abstract int GetIdentifier(); + + /// + /// Gets an identifier to identify a network type. + /// + /// + /// + public int GetNetworkTypeId() + { + Type type = this.GetType(); + object[] customAttributes = type.GetCustomAttributes(typeof(VirtualNetworkIdAttribute), false); + if (customAttributes == null) + throw new VirtualNetworkException("Could not get the virtual network id attributes."); + if (customAttributes.Length == 0) + throw new VirtualNetworkException("The virtual network id attribute was empty."); + + VirtualNetworkIdAttribute vlanAttribute = customAttributes[0] as VirtualNetworkIdAttribute; + if (vlanAttribute.NetworkTypeId == 0) + throw new VirtualNetworkException("A virtual Network Type ID may not be zero."); + + return vlanAttribute.NetworkTypeId; + } + public override string ToString() + { + return GetHumanReadableName(); + } + } +} diff --git a/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs b/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs index d07519a..d604b5d 100644 --- a/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs +++ b/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs @@ -1,254 +1,255 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using moe.yo3explorer.skyscraper8.DVBI.Model; -using skyscraper5.Docsis; -using skyscraper5.Docsis.MacManagement; -using skyscraper5.Dvb.DataBroadcasting.IntModel; -using skyscraper5.Dvb.DataBroadcasting.SkyscraperVfs; -using skyscraper5.Dvb.Descriptors; -using skyscraper5.Dvb.Psi.Model; -using skyscraper5.Mhp.Si.Model; -using skyscraper5.Mpeg2.Descriptors; -using skyscraper5.Mpeg2.Psi.Model; -using skyscraper5.Scte35; -using skyscraper5.Skyscraper.IO.CrazycatStreamReader; -using skyscraper5.Skyscraper.Net; -using skyscraper5.src.InteractionChannel.Model; -using skyscraper5.src.InteractionChannel.Model2; -using skyscraper5.src.Skyscraper.FrequencyListGenerator; -using skyscraper5.T2MI.Packets; -using skyscraper5.Teletext.Wss; -using skyscraper8.DvbNip; -using skyscraper8.DvbNip.UiIntegration; -using skyscraper8.DvbSis; -using skyscraper8.GSE; -using skyscraper8.GSE.GSE; -using skyscraper8.Ietf.FLUTE; -using skyscraper8.InteractionChannel.Model; -using skyscraper8.InteractionChannel.Model2; -using skyscraper8.Ses; -using skyscraper8.Skyscraper.Drawing; -using skyscraper8.Skyscraper.FrequencyListGenerator; -using skyscraper8.Skyscraper.Scraper; -using skyscraper8.T2MI.Packets; - -namespace skyscraper5.Skyscraper.Scraper -{ - public interface ISkyscraperUiJunction - { - void NotifyEvent(EitEvent eitEvent); - void NotifySdtService(SdtService sdtService); - void NotifyPatProgram(int pmtPid, ushort programId); - void NotifyPmtProgram(ProgramMapping result, int pmtPid); - void NotifyMpeTraffic(IpTrafficInfo iti, byte[] ipv4PacketLength); - void NotifyAit(AitApplication aitApplication); - void DsmCcModuleAdd(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion); - void DsmCcModuleProgress(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion, double moduleInfoDownloadProgress); - void DsmCcModuleComplete(int elementaryPid, ushort moduleModuleId, byte moduleModuleVersion); - void NotifyWss(ushort programNumber, WssDataBlock wssDataBlock, int pid); - void NotifyStreamTypeDetection(string contestantTag, int pid); - void NotifyBat(BatBouquet batBouquet); - void DsmCcVfs(VfsFile vfsFile); - void NotifyTot(DateTime utcTime, LocalTimeOffsetDescriptor ltod); - void NotifyTdt(DateTime utcTime); - void NotifyCat(CaDescriptor caDescriptor); - void NotifyScte35(ushort programNumber, SpliceInsert spliceInsert); - void NotifyScte35(ushort programNumber, TimeSignal spliceInsert); - void NotifyDocsisFrequency(uint? frequency, bool isUpstream, object mmm); - void ShowFramegrab(int currentNetworkId, int transportStreamId, ushort mappingProgramNumber, int mappingStreamElementaryPid, byte[] imageData); - - IEnumerable GetServices(); - void OnBlindscanOpenFoundFrquenciesWindow(List foundFrequencies, STD_TYPE tunerMetadataType); - void OnBlindscanJobDone(bool success); - void OnBlindscanErrorMessage(string blindscanningLowHorizontalAreaFailed); - - /// - /// Called after the part of a band (e.g. Horizontal High) has completed blindscanning. - /// Is supposed to move the puppets in the SDL2 based UI to their home position. - /// - void OnBlindscanBandComplete(); - - /// - /// Called before a BLScan operation begins. - /// - /// The minimum frequency to scan - /// The Frequency on which we're starting. - /// The maximum frequency to scan - void OnBlindscanBeforeBLScan(int minimum, int currentProgress, int maximum); - - /// - /// Called before a BLScan operation ends. - /// - void OnBlindscanAfterBLScan(); - - /// - /// Called when a transponder is found during a BLScan2. - /// - /// - /// - /// - /// - void OnBlindscanSearchResult1Callback(BlindscanSearchResult searchResult, int polarityIndex, int lnbTypeMinimumFrequency, int lnbTypeMaximumFrequency); - - /// - /// Called before a SetChannel operation is performed. - /// - /// - void OnBlindscanBeforeSetChannel(BlindscanSearchResult blindscanResult); - - /// - /// Called after a band (meaning e.g. Horizontal High) has been scraped. - /// In the SDL2 version, this is supposed to move the puppets back to their home position. - /// - void OnScrapeBandComplete(); - - /// - /// Called after a single transponder has been scraped. - /// In the SDL2 version, this is supposed to hide the pressure plate representing the transponder. - /// - /// - void OnBlindscanScrapeTransponderComplete(BlindscanSearchResult blindscanResult); - - /// - /// Called when beginning to gather the RF Spectrum. - /// In the SDL2 version, this is supposed to create the ScottPlot window. - /// - void OnBlindscanBeginRfSpectrum(); - - /// - /// Called when a data point for the RF Spectrum is available. - /// - /// - /// - /// - void OnBlindscanRfSpectrumEnqueueSample(SatelliteDeliverySystemDescriptor.PolarizationEnum polarization, int frequency, double rf); - - /// - /// Called when the gathering of the RF Spectrum has been completed. - /// In the SDL2 version, this is supposed to close the ScottPlotWindow. - /// - void OnBlindscanEndRfSpectrum(); - - /// - /// Called when beginning to gather an IQ Spectrum. - /// In the SDL2 version, this is supposed to create a Surface for Pixel drawing. - /// - /// - void OnBlindscanBeginIqSpectrum(IqChartData result); - - /// - /// Called when the gathering of an IQ Spectrum has been completed. - /// In the SDL2 version, this is supposed to remove the Surface for Pixel drawing. - /// - void OnBlindscanEndIq(); - - /// - /// Called when a lock couldn't be acquired. - /// In the SDL2 version, this is supposed to play the fail.wav sound. - /// - /// - /// - void OnBlindscanLockFail(SearchResult satelliteSr, BlindscanResultState resultState); - - /// - /// Called before SetFilter is called. - /// In the SDL2 version, this is supposed to: - /// 1) Spawn all these nice windows about PAT, CAT, PMT, EIT, etc... - /// 2) Play the Success1.wav - /// 3) Set the packet counters in foundFrequenciesWindow to 0. - /// 4) Enable the Zap now button in the foundFrequenciesWindow. - /// - void OnBlindscanFilterSetUp(); - - /// - /// Called after we're done collecting packets from a transponder. - /// In the SDL2 version, this is supposed to: - /// 1) Disable the Zap now button in the foundFrequenciesWindow. - /// - void OnBlindscanScrapeStopCondition(); - - /// - /// Called after the packets collected from the transponder have all been processed. - /// In the SDL2 version, this is supposed to: - /// 1) Hide all the windows about DVB Tables - /// - void OnBlindscanAfterPacketDrain(); - - /// - /// Called when StreamReader has invoked a DvbCallback. - /// - /// 1 when the packet size is odd. 2 when out of memory - /// The size of the data StreamReader gave to the DvbCallback - void OnBlindscanPacketError(int errorCount, int length); - - void OnBlindscanPacketOk(int numPackets, int packetsQueueCount); - - /// - /// Checks whether the user asks to abort scraping and switch to the next transponder. - /// - /// Returns true if the button has been pressed. - bool IsZapNowRequested(); - - /// - /// Checks whether the user asks not to zap automatically. - /// - /// Returns true if the "Do not auto-zap" checkbox is checked in the FoundFrequenciesWIndow - bool MayAutoZap(); - void NotifyNit(NitNetwork nitNetwork); - void EnableUiFeature(SkyscraperUiFeature bbframeAnalysis); - void OnIpMacNotification(int sourcePid, Platform platform, Target target, Operational operational); - void OnSsuNotification(Dvb.SystemSoftwareUpdate.Model.UpdateNotificationGroup common, Dvb.SystemSoftwareUpdate.Model.UpdateNotificationTarget target, ushort programNumber); - - - /// - /// - /// - /// - /// The payload begins at byte 11 - void OnBbframe(BBHeader bbHeader, byte[] payload); - void OnDetectionOfInnerTs(SkyscraperContext child, object identifier); - void NotifyGsePacket(ushort value, byte[] gseDataBytes, GseLabel label); - void OnDvbNipFileArrival(FluteUiHandle fuh); - void OnDvbNipMulticastGatewayConfiguration(NipActualCarrierInformation carrier, MulticastGatewayConfigurationType multicastGatewayConfiguration); - void OnDvbNipCarrierDetected(NipActualCarrierInformation currentCarrierInformation); - void OnDvbNipPrivateDataSignallingManifest(PrivateDataSignallingManifestType privateDataSignallingManifest); - void OnDvbNipServiceListEntryPoints(NipActualCarrierInformation currentCarrierInformation, ServiceListEntryPoints serviceListEntryPoints, DateTime dvbNipTime); - void OnDvbNipServiceList(NipActualCarrierInformation currentCarrierInformation, string serviceListId1, ServiceListType serviceListId2); - void OnDvbNipTimeOffsetFile(NipActualCarrierInformation currentCarrierInformation, TimeOffsetFileType timeOffsetFile); - void OnDvbNipNetworkInformationFile(NipActualCarrierInformation currentCarrierInformation, NetworkInformationFileType networkInformationFile); - void DvbNipServiceInformation(NipActualCarrierInformation currentCarrierInformation, ServiceInformationFileType serviceInformationFile); - void OnDvbNipFileAnnouncement(FDTInstanceType flute); - void OnAstraSgtList(SgtList list); - void OnAstraSgtService(SgtService child); - void NotifyTransportStreamId(int tsid, int nid); - void OnDvbSisCat(int sourcePid, SisCatContainer catContainer); - void OnDvbSisEit(int sourcePid, SisEitContainer eitContainer); - void OnDvbSisFti(int relatedPid, _0xF0_FramingTimingInformation fti); - void OnDvbSisTimestamp(int pid, _0x20_DvbT2Timestamp t2Timestamp); - void OnDvbSisPat(int sourcePid, SisPatContainer patContainer); - void OnDvbSisSdt(int sourcePid, SisSdtContainer sdtContainer); - void OnDvbSisDsaci(ushort currentDsaGroupId, int versionNumber, byte sectionNumber, byte lastSectionNumber, Stream dsaci); - void OnDvbSisPmt(int sourcePid, SisPmtContainer pmtContainer); - void OnDvbSisNit(int sourcePid, SisNitContainer nitContainer); - void OnDvbSisTdt(int sourcePid, DateTime? utcTime); - void OnRcs2Rmt(Rmt rmt); - void OnRcs2Tmst(ushort networkId, Tmst tmst); - void OnRcs2Tmst2(ushort interactiveNetworkId, Tmst2 tmst2); - void OnRcs2Tdt(ushort interactiveNetworkId, Rcs2Tdt tdt); - void OnRcs2Nit(ushort interactiveNetworkId, RcsNit nit); - void OnRcs2Bct(ushort networkId, Bct bct); - void OnRcs2Fct2(ushort networkId, Fct2 fct2); - void OnRcs2Tbtp2(ushort interactiveNetworkId, Tbtp2 tbtp2); - void OnRcs2Tct(ushort interactiveNetworkId, Tct tct); - void OnRcs2Tbtp(ushort interactiveNetworkId, Tbtp tbtp); - void OnRcs2Sct(ushort interactiveNetworkId, Sct sct); +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using moe.yo3explorer.skyscraper8.DVBI.Model; +using skyscraper5.Docsis; +using skyscraper5.Docsis.MacManagement; +using skyscraper5.Dvb.DataBroadcasting.IntModel; +using skyscraper5.Dvb.DataBroadcasting.SkyscraperVfs; +using skyscraper5.Dvb.Descriptors; +using skyscraper5.Dvb.Psi.Model; +using skyscraper5.Mhp.Si.Model; +using skyscraper5.Mpeg2.Descriptors; +using skyscraper5.Mpeg2.Psi.Model; +using skyscraper5.Scte35; +using skyscraper5.Skyscraper.IO.CrazycatStreamReader; +using skyscraper5.Skyscraper.Net; +using skyscraper5.src.InteractionChannel.Model; +using skyscraper5.src.InteractionChannel.Model2; +using skyscraper5.src.Skyscraper.FrequencyListGenerator; +using skyscraper5.T2MI.Packets; +using skyscraper5.Teletext.Wss; +using skyscraper8.DvbNip; +using skyscraper8.DvbNip.UiIntegration; +using skyscraper8.DvbSis; +using skyscraper8.GSE; +using skyscraper8.GSE.GSE; +using skyscraper8.Ietf.FLUTE; +using skyscraper8.InteractionChannel.Model; +using skyscraper8.InteractionChannel.Model2; +using skyscraper8.Ses; +using skyscraper8.Skyscraper.Drawing; +using skyscraper8.Skyscraper.FrequencyListGenerator; +using skyscraper8.Skyscraper.Net.VirtualNetworks; +using skyscraper8.Skyscraper.Scraper; +using skyscraper8.T2MI.Packets; + +namespace skyscraper5.Skyscraper.Scraper +{ + public interface ISkyscraperUiJunction + { + void NotifyEvent(EitEvent eitEvent); + void NotifySdtService(SdtService sdtService); + void NotifyPatProgram(int pmtPid, ushort programId); + void NotifyPmtProgram(ProgramMapping result, int pmtPid); + void NotifyMpeTraffic(VirtualNetworkIdentifier networkId, IpTrafficInfo iti, byte[] ipv4PacketLength); + void NotifyAit(AitApplication aitApplication); + void DsmCcModuleAdd(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion); + void DsmCcModuleProgress(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion, double moduleInfoDownloadProgress); + void DsmCcModuleComplete(int elementaryPid, ushort moduleModuleId, byte moduleModuleVersion); + void NotifyWss(ushort programNumber, WssDataBlock wssDataBlock, int pid); + void NotifyStreamTypeDetection(string contestantTag, int pid); + void NotifyBat(BatBouquet batBouquet); + void DsmCcVfs(VfsFile vfsFile); + void NotifyTot(DateTime utcTime, LocalTimeOffsetDescriptor ltod); + void NotifyTdt(DateTime utcTime); + void NotifyCat(CaDescriptor caDescriptor); + void NotifyScte35(ushort programNumber, SpliceInsert spliceInsert); + void NotifyScte35(ushort programNumber, TimeSignal spliceInsert); + void NotifyDocsisFrequency(uint? frequency, bool isUpstream, object mmm); + void ShowFramegrab(int currentNetworkId, int transportStreamId, ushort mappingProgramNumber, int mappingStreamElementaryPid, byte[] imageData); + + IEnumerable GetServices(); + void OnBlindscanOpenFoundFrquenciesWindow(List foundFrequencies, STD_TYPE tunerMetadataType); + void OnBlindscanJobDone(bool success); + void OnBlindscanErrorMessage(string blindscanningLowHorizontalAreaFailed); + + /// + /// Called after the part of a band (e.g. Horizontal High) has completed blindscanning. + /// Is supposed to move the puppets in the SDL2 based UI to their home position. + /// + void OnBlindscanBandComplete(); + + /// + /// Called before a BLScan operation begins. + /// + /// The minimum frequency to scan + /// The Frequency on which we're starting. + /// The maximum frequency to scan + void OnBlindscanBeforeBLScan(int minimum, int currentProgress, int maximum); + + /// + /// Called before a BLScan operation ends. + /// + void OnBlindscanAfterBLScan(); + + /// + /// Called when a transponder is found during a BLScan2. + /// + /// + /// + /// + /// + void OnBlindscanSearchResult1Callback(BlindscanSearchResult searchResult, int polarityIndex, int lnbTypeMinimumFrequency, int lnbTypeMaximumFrequency); + + /// + /// Called before a SetChannel operation is performed. + /// + /// + void OnBlindscanBeforeSetChannel(BlindscanSearchResult blindscanResult); + + /// + /// Called after a band (meaning e.g. Horizontal High) has been scraped. + /// In the SDL2 version, this is supposed to move the puppets back to their home position. + /// + void OnScrapeBandComplete(); + + /// + /// Called after a single transponder has been scraped. + /// In the SDL2 version, this is supposed to hide the pressure plate representing the transponder. + /// + /// + void OnBlindscanScrapeTransponderComplete(BlindscanSearchResult blindscanResult); + + /// + /// Called when beginning to gather the RF Spectrum. + /// In the SDL2 version, this is supposed to create the ScottPlot window. + /// + void OnBlindscanBeginRfSpectrum(); + + /// + /// Called when a data point for the RF Spectrum is available. + /// + /// + /// + /// + void OnBlindscanRfSpectrumEnqueueSample(SatelliteDeliverySystemDescriptor.PolarizationEnum polarization, int frequency, double rf); + + /// + /// Called when the gathering of the RF Spectrum has been completed. + /// In the SDL2 version, this is supposed to close the ScottPlotWindow. + /// + void OnBlindscanEndRfSpectrum(); + + /// + /// Called when beginning to gather an IQ Spectrum. + /// In the SDL2 version, this is supposed to create a Surface for Pixel drawing. + /// + /// + void OnBlindscanBeginIqSpectrum(IqChartData result); + + /// + /// Called when the gathering of an IQ Spectrum has been completed. + /// In the SDL2 version, this is supposed to remove the Surface for Pixel drawing. + /// + void OnBlindscanEndIq(); + + /// + /// Called when a lock couldn't be acquired. + /// In the SDL2 version, this is supposed to play the fail.wav sound. + /// + /// + /// + void OnBlindscanLockFail(SearchResult satelliteSr, BlindscanResultState resultState); + + /// + /// Called before SetFilter is called. + /// In the SDL2 version, this is supposed to: + /// 1) Spawn all these nice windows about PAT, CAT, PMT, EIT, etc... + /// 2) Play the Success1.wav + /// 3) Set the packet counters in foundFrequenciesWindow to 0. + /// 4) Enable the Zap now button in the foundFrequenciesWindow. + /// + void OnBlindscanFilterSetUp(); + + /// + /// Called after we're done collecting packets from a transponder. + /// In the SDL2 version, this is supposed to: + /// 1) Disable the Zap now button in the foundFrequenciesWindow. + /// + void OnBlindscanScrapeStopCondition(); + + /// + /// Called after the packets collected from the transponder have all been processed. + /// In the SDL2 version, this is supposed to: + /// 1) Hide all the windows about DVB Tables + /// + void OnBlindscanAfterPacketDrain(); + + /// + /// Called when StreamReader has invoked a DvbCallback. + /// + /// 1 when the packet size is odd. 2 when out of memory + /// The size of the data StreamReader gave to the DvbCallback + void OnBlindscanPacketError(int errorCount, int length); + + void OnBlindscanPacketOk(int numPackets, int packetsQueueCount); + + /// + /// Checks whether the user asks to abort scraping and switch to the next transponder. + /// + /// Returns true if the button has been pressed. + bool IsZapNowRequested(); + + /// + /// Checks whether the user asks not to zap automatically. + /// + /// Returns true if the "Do not auto-zap" checkbox is checked in the FoundFrequenciesWIndow + bool MayAutoZap(); + void NotifyNit(NitNetwork nitNetwork); + void EnableUiFeature(SkyscraperUiFeature bbframeAnalysis); + void OnIpMacNotification(int sourcePid, Platform platform, Target target, Operational operational); + void OnSsuNotification(Dvb.SystemSoftwareUpdate.Model.UpdateNotificationGroup common, Dvb.SystemSoftwareUpdate.Model.UpdateNotificationTarget target, ushort programNumber); + + + /// + /// + /// + /// + /// The payload begins at byte 11 + void OnBbframe(BBHeader bbHeader, byte[] payload); + void OnDetectionOfInnerTs(SkyscraperContext child, object identifier); + void NotifyGsePacket(ushort value, byte[] gseDataBytes, GseLabel label); + void OnDvbNipFileArrival(FluteUiHandle fuh); + void OnDvbNipMulticastGatewayConfiguration(NipActualCarrierInformation carrier, MulticastGatewayConfigurationType multicastGatewayConfiguration); + void OnDvbNipCarrierDetected(NipActualCarrierInformation currentCarrierInformation); + void OnDvbNipPrivateDataSignallingManifest(PrivateDataSignallingManifestType privateDataSignallingManifest); + void OnDvbNipServiceListEntryPoints(NipActualCarrierInformation currentCarrierInformation, ServiceListEntryPoints serviceListEntryPoints, DateTime dvbNipTime); + void OnDvbNipServiceList(NipActualCarrierInformation currentCarrierInformation, string serviceListId1, ServiceListType serviceListId2); + void OnDvbNipTimeOffsetFile(NipActualCarrierInformation currentCarrierInformation, TimeOffsetFileType timeOffsetFile); + void OnDvbNipNetworkInformationFile(NipActualCarrierInformation currentCarrierInformation, NetworkInformationFileType networkInformationFile); + void DvbNipServiceInformation(NipActualCarrierInformation currentCarrierInformation, ServiceInformationFileType serviceInformationFile); + void OnDvbNipFileAnnouncement(FDTInstanceType flute); + void OnAstraSgtList(SgtList list); + void OnAstraSgtService(SgtService child); + void NotifyTransportStreamId(int tsid, int nid); + void OnDvbSisCat(int sourcePid, SisCatContainer catContainer); + void OnDvbSisEit(int sourcePid, SisEitContainer eitContainer); + void OnDvbSisFti(int relatedPid, _0xF0_FramingTimingInformation fti); + void OnDvbSisTimestamp(int pid, _0x20_DvbT2Timestamp t2Timestamp); + void OnDvbSisPat(int sourcePid, SisPatContainer patContainer); + void OnDvbSisSdt(int sourcePid, SisSdtContainer sdtContainer); + void OnDvbSisDsaci(ushort currentDsaGroupId, int versionNumber, byte sectionNumber, byte lastSectionNumber, Stream dsaci); + void OnDvbSisPmt(int sourcePid, SisPmtContainer pmtContainer); + void OnDvbSisNit(int sourcePid, SisNitContainer nitContainer); + void OnDvbSisTdt(int sourcePid, DateTime? utcTime); + void OnRcs2Rmt(Rmt rmt); + void OnRcs2Tmst(ushort networkId, Tmst tmst); + void OnRcs2Tmst2(ushort interactiveNetworkId, Tmst2 tmst2); + void OnRcs2Tdt(ushort interactiveNetworkId, Rcs2Tdt tdt); + void OnRcs2Nit(ushort interactiveNetworkId, RcsNit nit); + void OnRcs2Bct(ushort networkId, Bct bct); + void OnRcs2Fct2(ushort networkId, Fct2 fct2); + void OnRcs2Tbtp2(ushort interactiveNetworkId, Tbtp2 tbtp2); + void OnRcs2Tct(ushort interactiveNetworkId, Tct tct); + void OnRcs2Tbtp(ushort interactiveNetworkId, Tbtp tbtp); + void OnRcs2Sct(ushort interactiveNetworkId, Sct sct); void OnRcs2Spt(ushort interactiveNetworkId, Spt spt); void WneStoryDetect(uint embeddedSessionId); void WneStoryError(uint sessionId); void WneStoryProgress(uint sessionId, string filename, long fileCaught, uint fileSize); void WneStoryComplete(uint sessionId, string filename); - } -} + } +} diff --git a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs index 01d8921..120981e 100644 --- a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs +++ b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs @@ -92,9 +92,11 @@ using skyscraper8.Atsc.A322; using skyscraper8.Atsc.A330; using skyscraper8.Atsc.A331; using skyscraper8.Atsc.A331.Schema; +using skyscraper8.Skyscraper.Net.VirtualNetworks; using Tsubasa.IO; using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform; using RntParser = skyscraper5.Dvb.TvAnytime.RntParser; +using skyscraper8.Dvb.DataBroadcasting; namespace skyscraper5.Skyscraper.Scraper { @@ -1744,12 +1746,19 @@ namespace skyscraper5.Skyscraper.Scraper } + private IpTrafficHandler ipTrafficHandler; - public void OnIpDatagram(int pid, byte[] payload) + public void OnIpDatagram(VirtualNetworkIdentifier networkId, byte[] payload) { UiJunction?.EnableUiFeature(SkyscraperUiFeature.IpTrafficAnalysis); - TeiOnOffFilter.SetExempt(pid); - if (ipTrafficHandler == null) + + PidNetworkIdentifier pidNetworkIdentifier = networkId as PidNetworkIdentifier; + if (pidNetworkIdentifier != null) + { + TeiOnOffFilter.SetExempt(pidNetworkIdentifier.PID); + } + + if (ipTrafficHandler == null) { StorageConnectionManager storageConnectionManager = StorageConnectionManager.GetInstance(); ipTrafficHandler = storageConnectionManager.GetDefaultIpTrafficHandler(); @@ -1759,7 +1768,7 @@ namespace skyscraper5.Skyscraper.Scraper return; } - ipTrafficHandler?.HandleIpPacket(pid, payload); + ipTrafficHandler?.HandleIpPacket(networkId, payload); int ipVersion = (payload[0] & 0xf0) >> 4; if (ipVersion == 4) @@ -1778,7 +1787,7 @@ namespace skyscraper5.Skyscraper.Scraper return; byte[] ipv4Packet = new byte[payload.Length - ihl]; Array.Copy(payload, ihl, ipv4Packet, 0, payload.Length - ihl); - OnIpv4PacketArrival(internetHeader, ipv4Packet); + OnIpv4PacketArrival(networkId, internetHeader, ipv4Packet); } else if (ipVersion == 6) { @@ -1805,7 +1814,7 @@ namespace skyscraper5.Skyscraper.Scraper InternetHeader ipv6Header = new InternetHeader(trafficClass, flowLabel, payloadLength, nextHeader, hopLimit, sourceAddress, destinationAddress); if (ipv6Stream.GetAvailableBytes() >= payloadLength) { - OnIpv4PacketArrival(ipv6Header, ipv6Stream.ReadBytes(payloadLength)); + OnIpv4PacketArrival(networkId, ipv6Header, ipv6Stream.ReadBytes(payloadLength)); } return; } @@ -1852,7 +1861,7 @@ namespace skyscraper5.Skyscraper.Scraper return result; } - public void OnIpv4PacketArrival(InternetHeader internetHeader, byte[] ipv4Packet) + public void OnIpv4PacketArrival(VirtualNetworkIdentifier networkId, InternetHeader internetHeader, byte[] ipv4Packet) { //There are as many use cases as there are internet applications in these. //Not really required to decode all of them, if you ask me. @@ -1870,11 +1879,11 @@ namespace skyscraper5.Skyscraper.Scraper { LogEvent(SkyscraperContextEvent.LearnDns, String.Format("{0} = {1}", DnsCache.LastLearned.Value, DnsCache.LastLearned.Key)); } - UiJunction?.NotifyMpeTraffic(iti, ipv4Packet); + UiJunction?.NotifyMpeTraffic(networkId, iti, ipv4Packet); if (trafficInfos.Add(iti)) { - LogEvent(SkyscraperContextEvent.IpTraffic, iti.ToString()); + LogEvent(SkyscraperContextEvent.IpTraffic, String.Format("[{0}] {1}",networkId.GetHumanReadableName(), iti.ToString())); } if (mpePlugins == null) @@ -3015,20 +3024,28 @@ namespace skyscraper5.Skyscraper.Scraper lastEventTimestamp = DateTime.Now; } - public void OnEthernetFrame(int pid, PhysicalAddress destination, PhysicalAddress source, ushort etherType, byte[] contents) + public void OnEthernetFrame(VirtualNetworkIdentifier network, PhysicalAddress destination, PhysicalAddress source, ushort etherType, byte[] contents) { if (Array.TrueForAll(contents, x => x == 0)) return; - TeiOnOffFilter.SetExempt(pid); + + PidNetworkIdentifier pidId = network as PidNetworkIdentifier; + if (pidId != null) + { + TeiOnOffFilter.SetExempt(pidId.PID); + } + + if (etherType <= 1500) { - OnLlcFrame((ushort)pid, source, destination, etherType, contents); + OnLlcFrame(network, source, destination, etherType, contents); return; } switch (etherType) { case 0x0800: - OnIpDatagram(pid, contents); + //IPv4 + OnIpDatagram(network, contents); return; case 0x22e3: //This is related to G.9961, a PowerLine standard specified by ITU-T T-REC-G.9961 @@ -3045,7 +3062,8 @@ namespace skyscraper5.Skyscraper.Scraper //This is an IPX Frame. We don't need it. return; case 0x86dd: - OnIpDatagram(pid, contents); + //IPv6 + OnIpDatagram(network, contents); return; case 0x88e1: //This is related to FRITZ!Powerline. @@ -3070,13 +3088,14 @@ namespace skyscraper5.Skyscraper.Scraper //Something proprietary. No idea. return; case 0xf67f: + //ATM Adaptation Layer 5 if (contents[20] == 0xaa && contents[21] == 0xaa && contents[22] == 0x03 && contents[23] == 0x00 && contents[24] == 0x00 && contents[25] == 0x00) { (contents[26], contents[27]) = (contents[27], contents[26]); ushort newEtherType = BitConverter.ToUInt16(contents, 26); byte[] newPacket = new byte[contents.Length - 28]; Array.Copy(contents, 28, newPacket, 0, newPacket.Length); - OnEthernetFrame(pid, destination, source, newEtherType, newPacket); + OnEthernetFrame(AtmAdaptationLayer5NetworkIdentifier.GetWrap(network), destination, source, newEtherType, newPacket); } return; case 0x94ad: @@ -3102,12 +3121,12 @@ namespace skyscraper5.Skyscraper.Scraper } } - public void OnUleError(int pid, int errorNo) + public void OnUleError(VirtualNetworkIdentifier pid, int errorNo) { throw new NotImplementedException(); } - public void OnLlcFrame(ushort pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents) + public void OnLlcFrame(VirtualNetworkIdentifier pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents) { UiJunction?.EnableUiFeature(SkyscraperUiFeature.LlcSnapTrafficAnalysis); if (ipTrafficHandler == null) @@ -3172,7 +3191,7 @@ namespace skyscraper5.Skyscraper.Scraper PhysicalAddress ethernetSrc = llcStream.ReadMacAddress(); ushort ethernetType = llcStream.ReadUInt16BE(); byte[] ethernetPayload = llcStream.ReadBytes(llcStream.GetAvailableBytes()); - OnEthernetFrame(pid, ethernetDst, ethernetSrc, ethernetType, ethernetPayload); + OnEthernetFrame(AtmAdaptationLayer5NetworkIdentifier.GetWrap(pid), ethernetDst, ethernetSrc, ethernetType, ethernetPayload); return; } else diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/MpeContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/MpeContestant.cs index 14670a4..2cf6cf4 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/MpeContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/MpeContestant.cs @@ -10,6 +10,8 @@ using skyscraper5.Ietf.Rfc2460; using skyscraper5.Ietf.Rfc971; using skyscraper5.Mpeg2; using skyscraper5.Skyscraper.Plugins; +using skyscraper8.Dvb.DataBroadcasting; +using skyscraper8.Skyscraper.Net.VirtualNetworks; namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants { @@ -36,12 +38,12 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants } - public void OnIpv4PacketArrival(InternetHeader internetHeader, byte[] ipv4Packet) + public void OnIpv4PacketArrival(VirtualNetworkIdentifier networkId, InternetHeader internetHeader, byte[] ipv4Packet) { Score++; } - public void OnIpDatagram(int sourcePid, byte[] payload) + public void OnIpDatagram(VirtualNetworkIdentifier sourceNetwork, byte[] payload) { int ipVersion = (payload[0] & 0xf0) >> 4; if (ipVersion == 4) @@ -66,7 +68,7 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants byte[] ipv4Packet = new byte[testLength]; Array.Copy(payload, ihl, ipv4Packet, 0, testLength); - OnIpv4PacketArrival(internetHeader, ipv4Packet); + OnIpv4PacketArrival(sourceNetwork, internetHeader, ipv4Packet); } else if (ipVersion == 6) { @@ -87,7 +89,7 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants } } - public void OnLlcFrame(ushort pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents) + public void OnLlcFrame(VirtualNetworkIdentifier pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents) { Score++; }