Discriminate between multiple virtual networks.
All checks were successful
🚀 Pack skyscraper8 / make-zip (push) Successful in 52s

This commit is contained in:
feyris-tan 2026-06-14 21:29:10 +02:00
parent c3fff246d5
commit 1b01ed8553
32 changed files with 1025 additions and 591 deletions

View File

@ -18,4 +18,14 @@ These will have IP packets forwarded to.
|ID|Type | |ID|Type |
|--|-----------| |--|-----------|
| 1|PCAP Writer| | 1|PCAP Writer|
| 2|Discard | | 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 |

View File

@ -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;
}
}
}

View File

@ -155,9 +155,14 @@ namespace skyscraper8.Atsc.A322
} }
} }
private Atsc3PlpVirtualNetworkIdentifier networkIdentifier;
private void HandleIpv4(byte[] newPacketPayload) 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) private void HandleLinkLayerSignalling(AdditionalHeaderForSignalingInformation signalingInformation, byte[] payload)

View File

@ -5,12 +5,13 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using skyscraper8.Atsc.A330; using skyscraper8.Atsc.A330;
using skyscraper8.Skyscraper.Net.VirtualNetworks;
namespace skyscraper8.Atsc.A322 namespace skyscraper8.Atsc.A322
{ {
internal interface IAtscPlpEventHandler internal interface IAtscPlpEventHandler
{ {
void OnIpDatagram(int pid, byte[] payload); void OnIpDatagram(VirtualNetworkIdentifier pid, byte[] payload);
void OnAtsc3LinkMappingTable(ushort plp, AdditionalHeaderForSignalingInformation signalingInformation, LinkMappingTable lmt); void OnAtsc3LinkMappingTable(ushort plp, AdditionalHeaderForSignalingInformation signalingInformation, LinkMappingTable lmt);
} }
} }

View File

@ -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();
}
}
}

View File

@ -115,7 +115,11 @@ namespace skyscraper8.Atsc.A324
} }
break; break;
case 4: //Deliver the packet 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; stateMachineState = 1;
break; break;
default: default:
@ -125,6 +129,7 @@ namespace skyscraper8.Atsc.A324
processed = true; processed = true;
} }
private StltpNetworkIdentifier networkIdentifier;
private SkyscraperContext context; private SkyscraperContext context;
public void SetContext(DateTime? currentTime, object skyscraperContext) public void SetContext(DateTime? currentTime, object skyscraperContext)
{ {

View File

@ -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)
{
}
}
}

View File

@ -9,6 +9,8 @@ using log4net;
using skyscraper5.Ietf.Rfc768; using skyscraper5.Ietf.Rfc768;
using skyscraper5.Mpeg2; using skyscraper5.Mpeg2;
using skyscraper5.Skyscraper.IO; using skyscraper5.Skyscraper.IO;
using skyscraper8.Dvb.DataBroadcasting;
using skyscraper8.Skyscraper.Net.VirtualNetworks;
namespace skyscraper5.Dvb.DataBroadcasting namespace skyscraper5.Dvb.DataBroadcasting
{ {
@ -59,6 +61,8 @@ namespace skyscraper5.Dvb.DataBroadcasting
{ {
return; return;
} }
EnsureVirtualNetworkIdentifier(sourcePid);
byte[] payload = ms.ReadBytes(length); byte[] payload = ms.ReadBytes(length);
if (llcSnap) if (llcSnap)
{ {
@ -71,6 +75,7 @@ namespace skyscraper5.Dvb.DataBroadcasting
} }
private bool announcedLlcTraffic; private bool announcedLlcTraffic;
private void HandleLlcSnap(int sourcePid, byte[] macAddress, byte[] payload) private void HandleLlcSnap(int sourcePid, byte[] macAddress, byte[] payload)
{ {
@ -81,12 +86,28 @@ namespace skyscraper5.Dvb.DataBroadcasting
} }
PhysicalAddress physicalAddress = new PhysicalAddress(macAddress); 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) 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.");
}
}
} }
} }
} }

View File

@ -5,15 +5,16 @@ using System.Net.NetworkInformation;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using skyscraper5.Ietf.Rfc971; using skyscraper5.Ietf.Rfc971;
using skyscraper8.Skyscraper.Net.VirtualNetworks;
namespace skyscraper5.Dvb.DataBroadcasting namespace skyscraper8.Dvb.DataBroadcasting
{ {
public interface IMultiprotocolEncapsulationEventHandler public interface IMultiprotocolEncapsulationEventHandler
{ {
void OnIpv4PacketArrival(InternetHeader internetHeader, byte[] ipv4Packet); void OnIpv4PacketArrival(VirtualNetworkIdentifier networkId, InternetHeader internetHeader, byte[] ipv4Packet);
void OnIpDatagram(int sourcePid, byte[] payload); 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);
} }

View File

@ -10,6 +10,7 @@ namespace skyscraper5.Dvb
{ {
class DvbException : Mpeg2Exception class DvbException : Mpeg2Exception
{ {
public DvbException(string s, params object[] args) public DvbException(string s, params object[] args)
: base(String.Format(s, args)) : base(String.Format(s, args))
{ {

View File

@ -1,255 +1,260 @@
using skyscraper5.Dvb.DataBroadcasting; using skyscraper5.Dvb.DataBroadcasting;
using skyscraper5.Mpeg2; using skyscraper5.Mpeg2;
using skyscraper5.Skyscraper.IO; using skyscraper5.Skyscraper.IO;
using skyscraper5.src.InteractionChannel; using skyscraper5.src.InteractionChannel;
using skyscraper8.GSE; using skyscraper8.GSE;
using skyscraper8.GSE.GSE; using skyscraper8.GSE.GSE;
using skyscraper8.Skyscraper.IO; using skyscraper8.Skyscraper.IO;
using skyscraper8.Skyscraper.Scraper; using skyscraper8.Skyscraper.Scraper;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using static skyscraper5.Dvb.Descriptors.ContentIdentifierDescriptor; using static skyscraper5.Dvb.Descriptors.ContentIdentifierDescriptor;
namespace skyscraper8.GS.GSE_BFBS namespace skyscraper8.GS.GSE_BFBS
{ {
internal class BfbsGseReader : IMisHandler internal class BfbsGseReader : IMisHandler
{ {
private GseLabel lastLabel; private GseLabel lastLabel;
private int frameNo; private int frameNo;
public GsContextDto Context { get; set; } public GsContextDto Context { get; set; }
public BfbsGseReader(GsContextDto context) public BfbsGseReader(GsContextDto context)
{ {
this.Context = context; this.Context = context;
} }
private bool CheckAllZeroes(ReadOnlySpan<byte> span) private bool CheckAllZeroes(ReadOnlySpan<byte> span)
{ {
for (int i = 0; i < span.Length - 4; i++) for (int i = 0; i < span.Length - 4; i++)
{ {
if (span[i] != 0) if (span[i] != 0)
{ {
return false; return false;
} }
} }
return true; return true;
} }
public void PushFrame(BBHeader bbHeader, ReadOnlySpan<byte> readOnlySpan) public void PushFrame(BBHeader bbHeader, ReadOnlySpan<byte> readOnlySpan)
{ {
frameNo++; frameNo++;
bool validCrc = DvbCrc32.ValidateCrc(readOnlySpan); bool validCrc = DvbCrc32.ValidateCrc(readOnlySpan);
if (!validCrc) if (!validCrc)
return; return;
if (readOnlySpan[0] == 0 && readOnlySpan[1] == 0 && readOnlySpan[2] == 0 && readOnlySpan[3] == 0) if (readOnlySpan[0] == 0 && readOnlySpan[1] == 0 && readOnlySpan[2] == 0 && readOnlySpan[3] == 0)
{ {
if (CheckAllZeroes(readOnlySpan)) if (CheckAllZeroes(readOnlySpan))
{ {
return; return;
} }
else else
{ {
throw new NotImplementedException("A BBFrame with data offset not at 0 was found. This not supported yet, please share a sample of this."); 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); StreamlikeSpan span = new StreamlikeSpan(readOnlySpan);
while (span.GetAvailableBytes() > 4) while (span.GetAvailableBytes() > 4)
{ {
byte byteA = span.ReadUInt8(); byte byteA = span.ReadUInt8();
bool startIndicator = (byteA & 0x80) != 0; bool startIndicator = (byteA & 0x80) != 0;
bool endIndicator = (byteA & 0x40) != 0; bool endIndicator = (byteA & 0x40) != 0;
int labelTypeIndicator = (byteA & 0x30) >> 4; int labelTypeIndicator = (byteA & 0x30) >> 4;
if (!startIndicator && !endIndicator && labelTypeIndicator == 0) if (!startIndicator && !endIndicator && labelTypeIndicator == 0)
{ {
//padding bits, packet has ended. //padding bits, packet has ended.
return; return;
} }
else else
{ {
GsePacket gsePacket = new GsePacket(startIndicator, endIndicator, labelTypeIndicator); GsePacket gsePacket = new GsePacket(startIndicator, endIndicator, labelTypeIndicator);
int gseLength = (byteA & 0x0f) << 8; int gseLength = (byteA & 0x0f) << 8;
gseLength += span.ReadUInt8(); gseLength += span.ReadUInt8();
gsePacket.FragmentId = null; gsePacket.FragmentId = null;
if (!startIndicator || !endIndicator) if (!startIndicator || !endIndicator)
{ {
gsePacket.FragmentId = span.ReadUInt8(); gsePacket.FragmentId = span.ReadUInt8();
gseLength -= 1; gseLength -= 1;
} }
if ((startIndicator) && !endIndicator) if ((startIndicator) && !endIndicator)
{ {
gsePacket.TotalLength = span.ReadUInt16BE(); gsePacket.TotalLength = span.ReadUInt16BE();
gseLength -= 2; gseLength -= 2;
} }
if (startIndicator) if (startIndicator)
{ {
gsePacket.ProtocolType = span.ReadUInt16BE(); gsePacket.ProtocolType = span.ReadUInt16BE();
gseLength -= 2; gseLength -= 2;
if (labelTypeIndicator == 0) if (labelTypeIndicator == 0)
{ {
gsePacket.Label = new _6byteLabel(span.ReadBytes(6)); gsePacket.Label = new _6byteLabel(span.ReadBytes(6));
gseLength -= 6; gseLength -= 6;
} }
else if (labelTypeIndicator == 1) else if (labelTypeIndicator == 1)
{ {
gsePacket.Label = new _3byteLabel(span.ReadBytes(3)); gsePacket.Label = new _3byteLabel(span.ReadBytes(3));
gseLength -= 3; gseLength -= 3;
} }
else if (labelTypeIndicator == 2) else if (labelTypeIndicator == 2)
{ {
gsePacket.Label = BroadcastLabel.GetInstance(); gsePacket.Label = BroadcastLabel.GetInstance();
} }
else if (labelTypeIndicator == 3) else if (labelTypeIndicator == 3)
{ {
gsePacket.Label = lastLabel; gsePacket.Label = lastLabel;
} }
lastLabel = gsePacket.Label; lastLabel = gsePacket.Label;
} }
if (!startIndicator && endIndicator) if (!startIndicator && endIndicator)
gseLength -= 4; gseLength -= 4;
if (span.GetAvailableBytes() < gseLength) if (span.GetAvailableBytes() < gseLength)
{ {
//broken gse packet, invalid length //broken gse packet, invalid length
return; return;
} }
gsePacket.GseDataBytes = span.ReadBytes(gseLength); gsePacket.GseDataBytes = span.ReadBytes(gseLength);
if (!startIndicator && endIndicator) if (!startIndicator && endIndicator)
{ {
gsePacket.Crc32 = span.ReadUInt32BE(); gsePacket.Crc32 = span.ReadUInt32BE();
} }
HandleGseFrame(gsePacket); HandleGseFrame(gsePacket);
} }
} }
} }
private GseFragmentation[] fragmentations; private GseFragmentation[] fragmentations;
private void HandleGseFrame(GsePacket gsePacket) private void HandleGseFrame(GsePacket gsePacket)
{ {
if (gsePacket.StartIndicator & gsePacket.EndIndicator) if (gsePacket.StartIndicator & gsePacket.EndIndicator)
{ {
HandleAssembledFrame(gsePacket.ProtocolType.Value, gsePacket.GseDataBytes, gsePacket.Label); HandleAssembledFrame(gsePacket.ProtocolType.Value, gsePacket.GseDataBytes, gsePacket.Label);
return; return;
} }
if (!gsePacket.StartIndicator && gsePacket.EndIndicator) if (!gsePacket.StartIndicator && gsePacket.EndIndicator)
{ {
if (fragmentations == null) if (fragmentations == null)
{ {
//This stream had no fragmentations yet, so we cannot reassemble this packet. //This stream had no fragmentations yet, so we cannot reassemble this packet.
return; return;
} }
if (fragmentations[gsePacket.FragmentId.Value] == null) if (fragmentations[gsePacket.FragmentId.Value] == null)
{ {
//The previous fragments are missing, so we cannot reassemble this packet. //The previous fragments are missing, so we cannot reassemble this packet.
return; return;
} }
fragmentations[gsePacket.FragmentId.Value].AddFragement(gsePacket); fragmentations[gsePacket.FragmentId.Value].AddFragement(gsePacket);
if (fragmentations[gsePacket.FragmentId.Value].Validate()) if (fragmentations[gsePacket.FragmentId.Value].Validate())
{ {
byte[] gseDataBytes = fragmentations[gsePacket.FragmentId.Value].GetGseDataBytes(); byte[] gseDataBytes = fragmentations[gsePacket.FragmentId.Value].GetGseDataBytes();
ushort protocolType = fragmentations[gsePacket.FragmentId.Value].ProtocolType; ushort protocolType = fragmentations[gsePacket.FragmentId.Value].ProtocolType;
HandleAssembledFrame(protocolType, gseDataBytes, fragmentations[gsePacket.FragmentId.Value].Label); HandleAssembledFrame(protocolType, gseDataBytes, fragmentations[gsePacket.FragmentId.Value].Label);
fragmentations[gsePacket.FragmentId.Value] = null; fragmentations[gsePacket.FragmentId.Value] = null;
return; return;
} }
else else
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
if (gsePacket.StartIndicator && !gsePacket.EndIndicator) if (gsePacket.StartIndicator && !gsePacket.EndIndicator)
{ {
fragmentations = new GseFragmentation[256]; fragmentations = new GseFragmentation[256];
fragmentations[gsePacket.FragmentId.Value] = new GseFragmentation(gsePacket); fragmentations[gsePacket.FragmentId.Value] = new GseFragmentation(gsePacket);
return; return;
} }
if (!gsePacket.StartIndicator && !gsePacket.EndIndicator) if (!gsePacket.StartIndicator && !gsePacket.EndIndicator)
{ {
if (fragmentations == null) if (fragmentations == null)
{ {
//This stream had no fragmentations yet, so we cannot reassemble this packet. //This stream had no fragmentations yet, so we cannot reassemble this packet.
return; return;
} }
if (fragmentations[gsePacket.FragmentId.Value] == null) if (fragmentations[gsePacket.FragmentId.Value] == null)
{ {
//The previous fragments are missing, so we cannot reassemble this packet. //The previous fragments are missing, so we cannot reassemble this packet.
return; return;
} }
fragmentations[gsePacket.FragmentId.Value].AddFragement(gsePacket); fragmentations[gsePacket.FragmentId.Value].AddFragement(gsePacket);
return; return;
} }
throw new NotImplementedException( throw new NotImplementedException(
"A unknown frame type was encountered. Please share a sample of this stream."); "A unknown frame type was encountered. Please share a sample of this stream.");
} }
private void HandleAssembledFrame(ushort protocolType, byte[] buffer, GseLabel label) private MisNetworkIdentifier networkIdentifier;
{ private void HandleAssembledFrame(ushort protocolType, byte[] buffer, GseLabel label)
Context.UiJunction?.EnableUiFeature(SkyscraperUiFeature.GseAnalysis); {
Context.UiJunction?.NotifyGsePacket(protocolType, buffer, label); Context.UiJunction?.EnableUiFeature(SkyscraperUiFeature.GseAnalysis);
switch (protocolType) Context.UiJunction?.NotifyGsePacket(protocolType, buffer, label);
{ switch (protocolType)
case 0x0081: {
//Network clock reference case 0x0081:
HandleNetworkClockReference(buffer); //Network clock reference
return; HandleNetworkClockReference(buffer);
case 0x0082: return;
//Lower Layer Signalling, see en_30154502v010401p.pdf, page 49 case 0x0082:
HandleLowerLayerSignalling(buffer, label); //Lower Layer Signalling, see en_30154502v010401p.pdf, page 49
return; HandleLowerLayerSignalling(buffer, label);
case 0x0091: return;
//according to https://www.iana.org/assignments/ule-next-headers/ule-next-headers.xhtml it's private case 0x0091:
return; //according to https://www.iana.org/assignments/ule-next-headers/ule-next-headers.xhtml it's private
case 0x0800: return;
Context.IpOutput.OnIpDatagram(0x010e, buffer); case 0x0800:
return; if (networkIdentifier == null)
default: {
throw new NotImplementedException(protocolType.ToString()); networkIdentifier = new MisNetworkIdentifier(Context.GetMisId());
} }
} Context.IpOutput.OnIpDatagram(networkIdentifier, buffer);
return;
private GseL2SHandler rcs2; default:
private void HandleLowerLayerSignalling(byte[] buffer, GseLabel label) throw new NotImplementedException(protocolType.ToString());
{ }
if (rcs2 == null) }
{
rcs2 = new GseL2SHandler(Context); private GseL2SHandler rcs2;
} private void HandleLowerLayerSignalling(byte[] buffer, GseLabel label)
{
rcs2.PushPacket(buffer, label); if (rcs2 == null)
{
} rcs2 = new GseL2SHandler(Context);
}
private void HandleNetworkClockReference(byte[] buffer)
{ rcs2.PushPacket(buffer, label);
MemoryStream binaryReader = new MemoryStream(buffer);
uint pcrA = binaryReader.ReadUInt32BE(); }
ushort pcrB = binaryReader.ReadUInt16BE();
ulong pcr_base = ((ulong)pcrA << 1) | ((ulong)pcrB >> 15); private void HandleNetworkClockReference(byte[] buffer)
ulong pcr_ext = (ulong)pcrB & 0x01ff; {
ulong PCR = pcr_base * 300 + pcr_ext; MemoryStream binaryReader = new MemoryStream(buffer);
ulong seconds = PCR / 27000000; 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;
}
}
}

View File

@ -98,6 +98,7 @@ class GseHemReader : IMisHandler
} }
} }
private MisNetworkIdentifier networkIdentifier;
private void HandlePacket(GsePacket packet) private void HandlePacket(GsePacket packet)
{ {
Context.UiJunction?.EnableUiFeature(SkyscraperUiFeature.GseAnalysis); Context.UiJunction?.EnableUiFeature(SkyscraperUiFeature.GseAnalysis);
@ -107,7 +108,11 @@ class GseHemReader : IMisHandler
switch (packet.ProtocolType) switch (packet.ProtocolType)
{ {
case 0x0800: case 0x0800:
Context.IpOutput.OnIpDatagram(0x010e,packet.GseDataBytes); if (networkIdentifier == null)
{
networkIdentifier = new MisNetworkIdentifier(Context.GetMisId());
}
Context.IpOutput.OnIpDatagram(networkIdentifier,packet.GseDataBytes);
return; return;
default: 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); logger.WarnFormat("This GSE-HEM stream contains traffic other than IP. IP is type 0x0800, but we got 0x{0:X4} here.", packet.ProtocolType);

View File

@ -150,12 +150,22 @@ public class GseWithRollingSyncByteReader : IMisHandler
throw new NotImplementedException(); throw new NotImplementedException();
} }
private MisNetworkIdentifier networkIdentifier;
private void EnsureNetworkIdentifier()
{
if (networkIdentifier == null)
{
networkIdentifier = new MisNetworkIdentifier(Context.GetMisId());
}
}
private ulong aolSerial; private ulong aolSerial;
private void HandleProprietaryAolJunk(byte[] buffer, ushort protocolType) private void HandleProprietaryAolJunk(byte[] buffer, ushort protocolType)
{ {
if (buffer[0] == 0x45) if (buffer[0] == 0x45)
{ {
Context.IpOutput.OnIpDatagram(0x0118, buffer); EnsureNetworkIdentifier();
Context.IpOutput.OnIpDatagram(networkIdentifier, buffer);
return; return;
} }
/*aolSerial++; /*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 //according to https://www.iana.org/assignments/ule-next-headers/ule-next-headers.xhtml it's private
return; return;
case 0x0800: case 0x0800:
Context.IpOutput.OnIpDatagram(0x010e, buffer); EnsureNetworkIdentifier();
Context.IpOutput.OnIpDatagram(networkIdentifier, buffer);
return; return;
default: default:
if (warnedEthertypes == null) if (warnedEthertypes == null)

View File

@ -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 bool[] warnedEthertypes;
private GseFragmentation[] fragmentations; private GseFragmentation[] fragmentations;
private void ProcessPacket(GsePacket child) private void ProcessPacket(GsePacket child)
@ -123,7 +133,8 @@ internal class GseReader : IMisHandler
currentFragmentation.AddFragement(child); currentFragmentation.AddFragement(child);
if (currentFragmentation.Validate()) if (currentFragmentation.Validate())
{ {
Context.IpOutput.OnIpDatagram(0x010e,currentFragmentation.GetGseDataBytes()); EnsureNetworkIdentifier();
Context.IpOutput.OnIpDatagram(networkIdentifier,currentFragmentation.GetGseDataBytes());
} }
fragmentations[child.FragmentId.Value] = null; fragmentations[child.FragmentId.Value] = null;
@ -160,7 +171,8 @@ internal class GseReader : IMisHandler
switch (child.ProtocolType) switch (child.ProtocolType)
{ {
case 0x0800: case 0x0800:
Context.IpOutput.OnIpDatagram(0x010e, child.GseDataBytes); EnsureNetworkIdentifier();
Context.IpOutput.OnIpDatagram(networkIdentifier, child.GseDataBytes);
break; break;
default: default:
if (warnedEthertypes == null) if (warnedEthertypes == null)

View File

@ -5,9 +5,9 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using skyscraper5.Dvb.DataBroadcasting;
using skyscraper5.Skyscraper.Scraper; using skyscraper5.Skyscraper.Scraper;
using skyscraper5.src.InteractionChannel; using skyscraper5.src.InteractionChannel;
using skyscraper8.Dvb.DataBroadcasting;
using skyscraper8.Skyscraper.Scraper; using skyscraper8.Skyscraper.Scraper;
namespace skyscraper8.GS namespace skyscraper8.GS

View File

@ -21,7 +21,8 @@ namespace skyscraper8.GS
private ILog logger; private ILog logger;
private bool notified; private bool notified;
private MisNetworkIdentifier networkIdentifier;
public GsContextDto Context { get; set; } public GsContextDto Context { get; set; }
public void PushFrame(BBHeader bbHeader, ReadOnlySpan<byte> readOnlySpan) public void PushFrame(BBHeader bbHeader, ReadOnlySpan<byte> readOnlySpan)
{ {
@ -40,7 +41,11 @@ namespace skyscraper8.GS
foreach (byte[] packet in packets) foreach (byte[] packet in packets)
{ {
Context.IpOutput.OnIpDatagram(0x0118, packet); if (networkIdentifier == null)
{
networkIdentifier = new MisNetworkIdentifier(Context.GetMisId());
}
Context.IpOutput.OnIpDatagram(networkIdentifier, packet);
} }
} }
} }

View File

@ -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;
}
}
}

View File

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using skyscraper5.Skyscraper.Plugins; using skyscraper5.Skyscraper.Plugins;
using skyscraper5.Skyscraper.Scraper; using skyscraper5.Skyscraper.Scraper;
using skyscraper5.Skyscraper.Scraper.StreamAutodetection; using skyscraper5.Skyscraper.Scraper.StreamAutodetection;
using skyscraper8.Skyscraper.Net.VirtualNetworks;
namespace skyscraper8.Ietf.Rfc4236_ULE 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++; 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++; Score++;
} }
public void OnUleError(int pid, int errorNo) public void OnUleError(VirtualNetworkIdentifier pid, int errorNo)
{ {
Score--; Score--;
} }

View File

@ -4,12 +4,13 @@ using System.Linq;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using skyscraper8.Skyscraper.Net.VirtualNetworks;
namespace skyscraper8.Ietf.Rfc4236_ULE namespace skyscraper8.Ietf.Rfc4236_ULE
{ {
internal interface UleEventHandler 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);
/// <summary> /// <summary>
/// The UlePacketProcessor is supposed to call this whenever an Error occurs during deframing. /// 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. /// 1* for a CRC error.
/// 2* for an invalid adaptation field control. /// 2* for an invalid adaptation field control.
/// </param> /// </param>
void OnUleError(int pid, int errorNo); void OnUleError(VirtualNetworkIdentifier pid, int errorNo);
} }
} }

View File

@ -7,6 +7,7 @@ using System.Linq;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using skyscraper8.Skyscraper.Net.VirtualNetworks;
namespace skyscraper8.Ietf.Rfc4236_ULE namespace skyscraper8.Ietf.Rfc4236_ULE
{ {
@ -22,10 +23,13 @@ namespace skyscraper8.Ietf.Rfc4236_ULE
private MemoryStream reassemblyStream; private MemoryStream reassemblyStream;
private long offset; private long offset;
private PidNetworkIdentifier networkIdentifier;
public UlePacketProcessor(int pid, UleEventHandler eventHandler) public UlePacketProcessor(int pid, UleEventHandler eventHandler)
{ {
_pid = pid; _pid = pid;
_eventHandler = eventHandler; _eventHandler = eventHandler;
networkIdentifier = new PidNetworkIdentifier((ushort)pid);
} }
public void PushPacket(TsPacket packet) public void PushPacket(TsPacket packet)
@ -34,7 +38,7 @@ namespace skyscraper8.Ietf.Rfc4236_ULE
Span<byte> packetPayload = packet.GetPayload(); Span<byte> packetPayload = packet.GetPayload();
if (packetAdaptionField != null || packetPayload == null) if (packetAdaptionField != null || packetPayload == null)
{ {
_eventHandler.OnUleError(_pid, 2); _eventHandler.OnUleError(networkIdentifier, 2);
return; return;
} }
if (packet.PayloadUnitStart) if (packet.PayloadUnitStart)
@ -135,7 +139,7 @@ namespace skyscraper8.Ietf.Rfc4236_ULE
bool crc = DvbCrc32.ValidateCrc(ms, 0, (int)ms.Length); bool crc = DvbCrc32.ValidateCrc(ms, 0, (int)ms.Length);
if (!crc) if (!crc)
{ {
_eventHandler.OnUleError(_pid, 1); _eventHandler.OnUleError(networkIdentifier, 1);
return; return;
} }
@ -202,7 +206,7 @@ namespace skyscraper8.Ietf.Rfc4236_ULE
PhysicalAddress source = new PhysicalAddress(ms.ReadBytes(6)); PhysicalAddress source = new PhysicalAddress(ms.ReadBytes(6));
ushort etherType = ms.ReadUInt16BE(); ushort etherType = ms.ReadUInt16BE();
byte[] contents = ms.ReadBytes(ms.GetAvailableBytes()); byte[] contents = ms.ReadBytes(ms.GetAvailableBytes());
_eventHandler.OnLlcFrame((ushort)_pid, source, destination, etherType, contents); _eventHandler.OnLlcFrame(networkIdentifier, source, destination, etherType, contents);
} }
public void PacketLoss() public void PacketLoss()

View File

@ -4,12 +4,13 @@ using System.Linq;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using skyscraper8.Skyscraper.Net.VirtualNetworks;
namespace skyscraper8.Skyscraper.Net namespace skyscraper8.Skyscraper.Net
{ {
internal interface IpTrafficHandler : IDisposable internal interface IpTrafficHandler : IDisposable
{ {
void HandleIpPacket(int pid, byte[] payload); void HandleIpPacket(VirtualNetworkIdentifier pid, byte[] payload);
void HandleLlcFrame(ushort pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents); void HandleLlcFrame(VirtualNetworkIdentifier pid, PhysicalAddress source, PhysicalAddress destination, ushort etherType, byte[] contents);
} }
} }

View File

@ -7,6 +7,7 @@ using System.Linq;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using skyscraper8.Skyscraper.Net.VirtualNetworks;
namespace skyscraper8.Skyscraper.Net 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)
{ {
} }

View File

@ -9,6 +9,7 @@ using System.Linq;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using skyscraper8.Skyscraper.Net.VirtualNetworks;
namespace skyscraper8.Skyscraper.Net.Pcap namespace skyscraper8.Skyscraper.Net.Pcap
{ {
@ -18,33 +19,33 @@ namespace skyscraper8.Skyscraper.Net.Pcap
internal class PcapIpTrafficHandler : IpTrafficHandler internal class PcapIpTrafficHandler : IpTrafficHandler
{ {
private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
private PcapWriter[] pcapWritersIp; private Dictionary<VirtualNetworkIdentifier,PcapWriter> pcapWritersIp;
private PcapWriter[] pcapWritersLlc; private Dictionary<VirtualNetworkIdentifier,PcapWriter> pcapWritersLlc;
private DirectoryInfo outputDirectory; private DirectoryInfo outputDirectory;
public void HandleIpPacket(int pid, byte[] payload) public void HandleIpPacket(VirtualNetworkIdentifier network, byte[] payload)
{ {
if (pcapWritersIp == null) if (pcapWritersIp == null)
{ {
pcapWritersIp = new PcapWriter[0x2000]; pcapWritersIp = new Dictionary<VirtualNetworkIdentifier, PcapWriter>();
EnsureOutputdirExists(); 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) if (outputDirectory != null)
{ {
fname = Path.Combine(outputDirectory.FullName, fname); fname = Path.Combine(outputDirectory.FullName, fname);
} }
logger.InfoFormat("Opening file for writing: {0}", fname); logger.InfoFormat("Opening file for writing: {0}", fname);
FileStream fs = File.OpenWrite(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[] contents)
{ {
byte[] dstAddr = destination.GetAddressBytes(); byte[] dstAddr = destination.GetAddressBytes();
@ -65,13 +66,13 @@ namespace skyscraper8.Skyscraper.Net.Pcap
if (pcapWritersLlc == null) if (pcapWritersLlc == null)
{ {
pcapWritersLlc = new PcapWriter[0x1fff]; pcapWritersLlc = new Dictionary<VirtualNetworkIdentifier, PcapWriter>();
EnsureOutputdirExists(); 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) if (outputDirectory != null)
{ {
fname = Path.Combine(outputDirectory.FullName, fname); fname = Path.Combine(outputDirectory.FullName, fname);
@ -79,31 +80,10 @@ namespace skyscraper8.Skyscraper.Net.Pcap
logger.InfoFormat("Opening file for writing: {0}", fname); logger.InfoFormat("Opening file for writing: {0}", fname);
FileStream fs = File.OpenWrite(fname); FileStream fs = File.OpenWrite(fname);
pcapWritersLlc[pid] = new PcapWriter(fs, TcpdumpNetworkType.UserDefined); pcapWritersLlc[network] = new PcapWriter(fs, TcpdumpNetworkType.UserDefined);
} }
/* pcapWritersLlc[network].WritePacket(contents);
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);
} }
@ -123,10 +103,17 @@ namespace skyscraper8.Skyscraper.Net.Pcap
{ {
if (pcapWritersIp != null) if (pcapWritersIp != null)
{ {
for (int i = 0; i < pcapWritersIp.Length; i++) foreach (KeyValuePair<VirtualNetworkIdentifier, PcapWriter> kvp in pcapWritersIp)
{ {
if (pcapWritersIp[i] != null) kvp.Value.Dispose();
pcapWritersIp[i].Dispose(); }
}
if (pcapWritersLlc != null)
{
foreach (KeyValuePair<VirtualNetworkIdentifier, PcapWriter> kvp in pcapWritersLlc)
{
kvp.Value.Dispose();
} }
} }
} }

View File

@ -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)
{
}
}
}

View File

@ -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<VirtualNetworkIdentifier, AtmAdaptationLayer5NetworkIdentifier> wraps;
public static VirtualNetworkIdentifier GetWrap(VirtualNetworkIdentifier network)
{
if (wraps == null)
{
wraps = new Dictionary<VirtualNetworkIdentifier, AtmAdaptationLayer5NetworkIdentifier>();
}
if (wraps.ContainsKey(network))
{
return wraps[network];
}
else
{
AtmAdaptationLayer5NetworkIdentifier child = new AtmAdaptationLayer5NetworkIdentifier(network);
wraps.Add(network, child);
return child;
}
}
}
}

View File

@ -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
{
/// <summary>
/// Use this identifier when a IP/Network packets are directly encapsulated into a PID, for example by MPE or ULE.
/// </summary>
[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; }
}
}

View File

@ -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)
{
}
}
}

View File

@ -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;
}
}
}

View File

@ -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();
/// <summary>
/// Get an network type dependant ID of the specific network. This can be for example a VLAN ID, or a PID.
/// </summary>
/// <returns>The type-dependant identifier of the network in question.</returns>
public abstract int GetIdentifier();
/// <summary>
/// Gets an identifier to identify a network type.
/// </summary>
/// <returns></returns>
/// <exception cref="VirtualNetworkException"></exception>
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();
}
}
}

View File

@ -1,254 +1,255 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using moe.yo3explorer.skyscraper8.DVBI.Model; using moe.yo3explorer.skyscraper8.DVBI.Model;
using skyscraper5.Docsis; using skyscraper5.Docsis;
using skyscraper5.Docsis.MacManagement; using skyscraper5.Docsis.MacManagement;
using skyscraper5.Dvb.DataBroadcasting.IntModel; using skyscraper5.Dvb.DataBroadcasting.IntModel;
using skyscraper5.Dvb.DataBroadcasting.SkyscraperVfs; using skyscraper5.Dvb.DataBroadcasting.SkyscraperVfs;
using skyscraper5.Dvb.Descriptors; using skyscraper5.Dvb.Descriptors;
using skyscraper5.Dvb.Psi.Model; using skyscraper5.Dvb.Psi.Model;
using skyscraper5.Mhp.Si.Model; using skyscraper5.Mhp.Si.Model;
using skyscraper5.Mpeg2.Descriptors; using skyscraper5.Mpeg2.Descriptors;
using skyscraper5.Mpeg2.Psi.Model; using skyscraper5.Mpeg2.Psi.Model;
using skyscraper5.Scte35; using skyscraper5.Scte35;
using skyscraper5.Skyscraper.IO.CrazycatStreamReader; using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
using skyscraper5.Skyscraper.Net; using skyscraper5.Skyscraper.Net;
using skyscraper5.src.InteractionChannel.Model; using skyscraper5.src.InteractionChannel.Model;
using skyscraper5.src.InteractionChannel.Model2; using skyscraper5.src.InteractionChannel.Model2;
using skyscraper5.src.Skyscraper.FrequencyListGenerator; using skyscraper5.src.Skyscraper.FrequencyListGenerator;
using skyscraper5.T2MI.Packets; using skyscraper5.T2MI.Packets;
using skyscraper5.Teletext.Wss; using skyscraper5.Teletext.Wss;
using skyscraper8.DvbNip; using skyscraper8.DvbNip;
using skyscraper8.DvbNip.UiIntegration; using skyscraper8.DvbNip.UiIntegration;
using skyscraper8.DvbSis; using skyscraper8.DvbSis;
using skyscraper8.GSE; using skyscraper8.GSE;
using skyscraper8.GSE.GSE; using skyscraper8.GSE.GSE;
using skyscraper8.Ietf.FLUTE; using skyscraper8.Ietf.FLUTE;
using skyscraper8.InteractionChannel.Model; using skyscraper8.InteractionChannel.Model;
using skyscraper8.InteractionChannel.Model2; using skyscraper8.InteractionChannel.Model2;
using skyscraper8.Ses; using skyscraper8.Ses;
using skyscraper8.Skyscraper.Drawing; using skyscraper8.Skyscraper.Drawing;
using skyscraper8.Skyscraper.FrequencyListGenerator; using skyscraper8.Skyscraper.FrequencyListGenerator;
using skyscraper8.Skyscraper.Scraper; using skyscraper8.Skyscraper.Net.VirtualNetworks;
using skyscraper8.T2MI.Packets; using skyscraper8.Skyscraper.Scraper;
using skyscraper8.T2MI.Packets;
namespace skyscraper5.Skyscraper.Scraper
{ namespace skyscraper5.Skyscraper.Scraper
public interface ISkyscraperUiJunction {
{ public interface ISkyscraperUiJunction
void NotifyEvent(EitEvent eitEvent); {
void NotifySdtService(SdtService sdtService); void NotifyEvent(EitEvent eitEvent);
void NotifyPatProgram(int pmtPid, ushort programId); void NotifySdtService(SdtService sdtService);
void NotifyPmtProgram(ProgramMapping result, int pmtPid); void NotifyPatProgram(int pmtPid, ushort programId);
void NotifyMpeTraffic(IpTrafficInfo iti, byte[] ipv4PacketLength); void NotifyPmtProgram(ProgramMapping result, int pmtPid);
void NotifyAit(AitApplication aitApplication); void NotifyMpeTraffic(VirtualNetworkIdentifier networkId, IpTrafficInfo iti, byte[] ipv4PacketLength);
void DsmCcModuleAdd(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion); void NotifyAit(AitApplication aitApplication);
void DsmCcModuleProgress(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion, double moduleInfoDownloadProgress); void DsmCcModuleAdd(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion);
void DsmCcModuleComplete(int elementaryPid, ushort moduleModuleId, byte moduleModuleVersion); void DsmCcModuleProgress(int elementaryPid, ushort moduleInfoModuleId, byte moduleInfoModuleVersion, double moduleInfoDownloadProgress);
void NotifyWss(ushort programNumber, WssDataBlock wssDataBlock, int pid); void DsmCcModuleComplete(int elementaryPid, ushort moduleModuleId, byte moduleModuleVersion);
void NotifyStreamTypeDetection(string contestantTag, int pid); void NotifyWss(ushort programNumber, WssDataBlock wssDataBlock, int pid);
void NotifyBat(BatBouquet batBouquet); void NotifyStreamTypeDetection(string contestantTag, int pid);
void DsmCcVfs(VfsFile vfsFile); void NotifyBat(BatBouquet batBouquet);
void NotifyTot(DateTime utcTime, LocalTimeOffsetDescriptor ltod); void DsmCcVfs(VfsFile vfsFile);
void NotifyTdt(DateTime utcTime); void NotifyTot(DateTime utcTime, LocalTimeOffsetDescriptor ltod);
void NotifyCat(CaDescriptor caDescriptor); void NotifyTdt(DateTime utcTime);
void NotifyScte35(ushort programNumber, SpliceInsert spliceInsert); void NotifyCat(CaDescriptor caDescriptor);
void NotifyScte35(ushort programNumber, TimeSignal spliceInsert); void NotifyScte35(ushort programNumber, SpliceInsert spliceInsert);
void NotifyDocsisFrequency(uint? frequency, bool isUpstream, object mmm); void NotifyScte35(ushort programNumber, TimeSignal spliceInsert);
void ShowFramegrab(int currentNetworkId, int transportStreamId, ushort mappingProgramNumber, int mappingStreamElementaryPid, byte[] imageData); void NotifyDocsisFrequency(uint? frequency, bool isUpstream, object mmm);
void ShowFramegrab(int currentNetworkId, int transportStreamId, ushort mappingProgramNumber, int mappingStreamElementaryPid, byte[] imageData);
IEnumerable<HumanReadableService> GetServices();
void OnBlindscanOpenFoundFrquenciesWindow(List<BlindscanSearchResult> foundFrequencies, STD_TYPE tunerMetadataType); IEnumerable<HumanReadableService> GetServices();
void OnBlindscanJobDone(bool success); void OnBlindscanOpenFoundFrquenciesWindow(List<BlindscanSearchResult> foundFrequencies, STD_TYPE tunerMetadataType);
void OnBlindscanErrorMessage(string blindscanningLowHorizontalAreaFailed); void OnBlindscanJobDone(bool success);
void OnBlindscanErrorMessage(string blindscanningLowHorizontalAreaFailed);
/// <summary>
/// Called after the part of a band (e.g. Horizontal High) has completed blindscanning. /// <summary>
/// Is supposed to move the puppets in the SDL2 based UI to their home position. /// Called after the part of a band (e.g. Horizontal High) has completed blindscanning.
/// </summary> /// Is supposed to move the puppets in the SDL2 based UI to their home position.
void OnBlindscanBandComplete(); /// </summary>
void OnBlindscanBandComplete();
/// <summary>
/// Called before a BLScan operation begins. /// <summary>
/// </summary> /// Called before a BLScan operation begins.
/// <param name="minimum">The minimum frequency to scan</param> /// </summary>
/// <param name="currentProgress">The Frequency on which we're starting.</param> /// <param name="minimum">The minimum frequency to scan</param>
/// <param name="maximum">The maximum frequency to scan</param> /// <param name="currentProgress">The Frequency on which we're starting.</param>
void OnBlindscanBeforeBLScan(int minimum, int currentProgress, int maximum); /// <param name="maximum">The maximum frequency to scan</param>
void OnBlindscanBeforeBLScan(int minimum, int currentProgress, int maximum);
/// <summary>
/// Called before a BLScan operation ends. /// <summary>
/// </summary> /// Called before a BLScan operation ends.
void OnBlindscanAfterBLScan(); /// </summary>
void OnBlindscanAfterBLScan();
/// <summary>
/// Called when a transponder is found during a BLScan2. /// <summary>
/// </summary> /// Called when a transponder is found during a BLScan2.
/// <param name="searchResult"></param> /// </summary>
/// <param name="polarityIndex"></param> /// <param name="searchResult"></param>
/// <param name="lnbTypeMinimumFrequency"></param> /// <param name="polarityIndex"></param>
/// <param name="lnbTypeMaximumFrequency"></param> /// <param name="lnbTypeMinimumFrequency"></param>
void OnBlindscanSearchResult1Callback(BlindscanSearchResult searchResult, int polarityIndex, int lnbTypeMinimumFrequency, int lnbTypeMaximumFrequency); /// <param name="lnbTypeMaximumFrequency"></param>
void OnBlindscanSearchResult1Callback(BlindscanSearchResult searchResult, int polarityIndex, int lnbTypeMinimumFrequency, int lnbTypeMaximumFrequency);
/// <summary>
/// Called before a SetChannel operation is performed. /// <summary>
/// </summary> /// Called before a SetChannel operation is performed.
/// <param name="blindscanResult"></param> /// </summary>
void OnBlindscanBeforeSetChannel(BlindscanSearchResult blindscanResult); /// <param name="blindscanResult"></param>
void OnBlindscanBeforeSetChannel(BlindscanSearchResult blindscanResult);
/// <summary>
/// Called after a band (meaning e.g. Horizontal High) has been scraped. /// <summary>
/// In the SDL2 version, this is supposed to move the puppets back to their home position. /// Called after a band (meaning e.g. Horizontal High) has been scraped.
/// </summary> /// In the SDL2 version, this is supposed to move the puppets back to their home position.
void OnScrapeBandComplete(); /// </summary>
void OnScrapeBandComplete();
/// <summary>
/// Called after a single transponder has been scraped. /// <summary>
/// In the SDL2 version, this is supposed to hide the pressure plate representing the transponder. /// Called after a single transponder has been scraped.
/// </summary> /// In the SDL2 version, this is supposed to hide the pressure plate representing the transponder.
/// <param name="blindscanResult"></param> /// </summary>
void OnBlindscanScrapeTransponderComplete(BlindscanSearchResult blindscanResult); /// <param name="blindscanResult"></param>
void OnBlindscanScrapeTransponderComplete(BlindscanSearchResult blindscanResult);
/// <summary>
/// Called when beginning to gather the RF Spectrum. /// <summary>
/// In the SDL2 version, this is supposed to create the ScottPlot window. /// Called when beginning to gather the RF Spectrum.
/// </summary> /// In the SDL2 version, this is supposed to create the ScottPlot window.
void OnBlindscanBeginRfSpectrum(); /// </summary>
void OnBlindscanBeginRfSpectrum();
/// <summary>
/// Called when a data point for the RF Spectrum is available. /// <summary>
/// </summary> /// Called when a data point for the RF Spectrum is available.
/// <param name="polarization"></param> /// </summary>
/// <param name="frequency"></param> /// <param name="polarization"></param>
/// <param name="rf"></param> /// <param name="frequency"></param>
void OnBlindscanRfSpectrumEnqueueSample(SatelliteDeliverySystemDescriptor.PolarizationEnum polarization, int frequency, double rf); /// <param name="rf"></param>
void OnBlindscanRfSpectrumEnqueueSample(SatelliteDeliverySystemDescriptor.PolarizationEnum polarization, int frequency, double rf);
/// <summary>
/// Called when the gathering of the RF Spectrum has been completed. /// <summary>
/// In the SDL2 version, this is supposed to close the ScottPlotWindow. /// Called when the gathering of the RF Spectrum has been completed.
/// </summary> /// In the SDL2 version, this is supposed to close the ScottPlotWindow.
void OnBlindscanEndRfSpectrum(); /// </summary>
void OnBlindscanEndRfSpectrum();
/// <summary>
/// Called when beginning to gather an IQ Spectrum. /// <summary>
/// In the SDL2 version, this is supposed to create a Surface for Pixel drawing. /// Called when beginning to gather an IQ Spectrum.
/// </summary> /// In the SDL2 version, this is supposed to create a Surface for Pixel drawing.
/// <param name="result"></param> /// </summary>
void OnBlindscanBeginIqSpectrum(IqChartData result); /// <param name="result"></param>
void OnBlindscanBeginIqSpectrum(IqChartData result);
/// <summary>
/// Called when the gathering of an IQ Spectrum has been completed. /// <summary>
/// In the SDL2 version, this is supposed to remove the Surface for Pixel drawing. /// Called when the gathering of an IQ Spectrum has been completed.
/// </summary> /// In the SDL2 version, this is supposed to remove the Surface for Pixel drawing.
void OnBlindscanEndIq(); /// </summary>
void OnBlindscanEndIq();
/// <summary>
/// Called when a lock couldn't be acquired. /// <summary>
/// In the SDL2 version, this is supposed to play the fail.wav sound. /// Called when a lock couldn't be acquired.
/// </summary> /// In the SDL2 version, this is supposed to play the fail.wav sound.
/// <param name="satelliteSr"></param> /// </summary>
/// <param name="resultState"></param> /// <param name="satelliteSr"></param>
void OnBlindscanLockFail(SearchResult satelliteSr, BlindscanResultState resultState); /// <param name="resultState"></param>
void OnBlindscanLockFail(SearchResult satelliteSr, BlindscanResultState resultState);
/// <summary>
/// Called before SetFilter is called. /// <summary>
/// In the SDL2 version, this is supposed to: /// Called before SetFilter is called.
/// 1) Spawn all these nice windows about PAT, CAT, PMT, EIT, etc... /// In the SDL2 version, this is supposed to:
/// 2) Play the Success1.wav /// 1) Spawn all these nice windows about PAT, CAT, PMT, EIT, etc...
/// 3) Set the packet counters in foundFrequenciesWindow to 0. /// 2) Play the Success1.wav
/// 4) Enable the Zap now button in the foundFrequenciesWindow. /// 3) Set the packet counters in foundFrequenciesWindow to 0.
/// </summary> /// 4) Enable the Zap now button in the foundFrequenciesWindow.
void OnBlindscanFilterSetUp(); /// </summary>
void OnBlindscanFilterSetUp();
/// <summary>
/// Called after we're done collecting packets from a transponder. /// <summary>
/// In the SDL2 version, this is supposed to: /// Called after we're done collecting packets from a transponder.
/// 1) Disable the Zap now button in the foundFrequenciesWindow. /// In the SDL2 version, this is supposed to:
/// </summary> /// 1) Disable the Zap now button in the foundFrequenciesWindow.
void OnBlindscanScrapeStopCondition(); /// </summary>
void OnBlindscanScrapeStopCondition();
/// <summary>
/// Called after the packets collected from the transponder have all been processed. /// <summary>
/// In the SDL2 version, this is supposed to: /// Called after the packets collected from the transponder have all been processed.
/// 1) Hide all the windows about DVB Tables /// In the SDL2 version, this is supposed to:
/// </summary> /// 1) Hide all the windows about DVB Tables
void OnBlindscanAfterPacketDrain(); /// </summary>
void OnBlindscanAfterPacketDrain();
/// <summary>
/// Called when StreamReader has invoked a DvbCallback. /// <summary>
/// </summary> /// Called when StreamReader has invoked a DvbCallback.
/// <param name="errorCount">1 when the packet size is odd. 2 when out of memory</param> /// </summary>
/// <param name="length">The size of the data StreamReader gave to the DvbCallback</param> /// <param name="errorCount">1 when the packet size is odd. 2 when out of memory</param>
void OnBlindscanPacketError(int errorCount, int length); /// <param name="length">The size of the data StreamReader gave to the DvbCallback</param>
void OnBlindscanPacketError(int errorCount, int length);
void OnBlindscanPacketOk(int numPackets, int packetsQueueCount);
void OnBlindscanPacketOk(int numPackets, int packetsQueueCount);
/// <summary>
/// Checks whether the user asks to abort scraping and switch to the next transponder. /// <summary>
/// </summary> /// Checks whether the user asks to abort scraping and switch to the next transponder.
/// <returns>Returns true if the button has been pressed.</returns> /// </summary>
bool IsZapNowRequested(); /// <returns>Returns true if the button has been pressed.</returns>
bool IsZapNowRequested();
/// <summary>
/// Checks whether the user asks not to zap automatically. /// <summary>
/// </summary> /// Checks whether the user asks not to zap automatically.
/// <returns>Returns true if the "Do not auto-zap" checkbox is checked in the FoundFrequenciesWIndow</returns> /// </summary>
bool MayAutoZap(); /// <returns>Returns true if the "Do not auto-zap" checkbox is checked in the FoundFrequenciesWIndow</returns>
void NotifyNit(NitNetwork nitNetwork); bool MayAutoZap();
void EnableUiFeature(SkyscraperUiFeature bbframeAnalysis); void NotifyNit(NitNetwork nitNetwork);
void OnIpMacNotification(int sourcePid, Platform platform, Target target, Operational operational); void EnableUiFeature(SkyscraperUiFeature bbframeAnalysis);
void OnSsuNotification(Dvb.SystemSoftwareUpdate.Model.UpdateNotificationGroup common, Dvb.SystemSoftwareUpdate.Model.UpdateNotificationTarget target, ushort programNumber); void OnIpMacNotification(int sourcePid, Platform platform, Target target, Operational operational);
void OnSsuNotification(Dvb.SystemSoftwareUpdate.Model.UpdateNotificationGroup common, Dvb.SystemSoftwareUpdate.Model.UpdateNotificationTarget target, ushort programNumber);
/// <summary>
/// /// <summary>
/// </summary> ///
/// <param name="bbHeader"></param> /// </summary>
/// <param name="payload">The payload begins at byte 11</param> /// <param name="bbHeader"></param>
void OnBbframe(BBHeader bbHeader, byte[] payload); /// <param name="payload">The payload begins at byte 11</param>
void OnDetectionOfInnerTs(SkyscraperContext child, object identifier); void OnBbframe(BBHeader bbHeader, byte[] payload);
void NotifyGsePacket(ushort value, byte[] gseDataBytes, GseLabel label); void OnDetectionOfInnerTs(SkyscraperContext child, object identifier);
void OnDvbNipFileArrival(FluteUiHandle fuh); void NotifyGsePacket(ushort value, byte[] gseDataBytes, GseLabel label);
void OnDvbNipMulticastGatewayConfiguration(NipActualCarrierInformation carrier, MulticastGatewayConfigurationType multicastGatewayConfiguration); void OnDvbNipFileArrival(FluteUiHandle fuh);
void OnDvbNipCarrierDetected(NipActualCarrierInformation currentCarrierInformation); void OnDvbNipMulticastGatewayConfiguration(NipActualCarrierInformation carrier, MulticastGatewayConfigurationType multicastGatewayConfiguration);
void OnDvbNipPrivateDataSignallingManifest(PrivateDataSignallingManifestType privateDataSignallingManifest); void OnDvbNipCarrierDetected(NipActualCarrierInformation currentCarrierInformation);
void OnDvbNipServiceListEntryPoints(NipActualCarrierInformation currentCarrierInformation, ServiceListEntryPoints serviceListEntryPoints, DateTime dvbNipTime); void OnDvbNipPrivateDataSignallingManifest(PrivateDataSignallingManifestType privateDataSignallingManifest);
void OnDvbNipServiceList(NipActualCarrierInformation currentCarrierInformation, string serviceListId1, ServiceListType serviceListId2); void OnDvbNipServiceListEntryPoints(NipActualCarrierInformation currentCarrierInformation, ServiceListEntryPoints serviceListEntryPoints, DateTime dvbNipTime);
void OnDvbNipTimeOffsetFile(NipActualCarrierInformation currentCarrierInformation, TimeOffsetFileType timeOffsetFile); void OnDvbNipServiceList(NipActualCarrierInformation currentCarrierInformation, string serviceListId1, ServiceListType serviceListId2);
void OnDvbNipNetworkInformationFile(NipActualCarrierInformation currentCarrierInformation, NetworkInformationFileType networkInformationFile); void OnDvbNipTimeOffsetFile(NipActualCarrierInformation currentCarrierInformation, TimeOffsetFileType timeOffsetFile);
void DvbNipServiceInformation(NipActualCarrierInformation currentCarrierInformation, ServiceInformationFileType serviceInformationFile); void OnDvbNipNetworkInformationFile(NipActualCarrierInformation currentCarrierInformation, NetworkInformationFileType networkInformationFile);
void OnDvbNipFileAnnouncement(FDTInstanceType flute); void DvbNipServiceInformation(NipActualCarrierInformation currentCarrierInformation, ServiceInformationFileType serviceInformationFile);
void OnAstraSgtList(SgtList list); void OnDvbNipFileAnnouncement(FDTInstanceType flute);
void OnAstraSgtService(SgtService child); void OnAstraSgtList(SgtList list);
void NotifyTransportStreamId(int tsid, int nid); void OnAstraSgtService(SgtService child);
void OnDvbSisCat(int sourcePid, SisCatContainer catContainer); void NotifyTransportStreamId(int tsid, int nid);
void OnDvbSisEit(int sourcePid, SisEitContainer eitContainer); void OnDvbSisCat(int sourcePid, SisCatContainer catContainer);
void OnDvbSisFti(int relatedPid, _0xF0_FramingTimingInformation fti); void OnDvbSisEit(int sourcePid, SisEitContainer eitContainer);
void OnDvbSisTimestamp(int pid, _0x20_DvbT2Timestamp t2Timestamp); void OnDvbSisFti(int relatedPid, _0xF0_FramingTimingInformation fti);
void OnDvbSisPat(int sourcePid, SisPatContainer patContainer); void OnDvbSisTimestamp(int pid, _0x20_DvbT2Timestamp t2Timestamp);
void OnDvbSisSdt(int sourcePid, SisSdtContainer sdtContainer); void OnDvbSisPat(int sourcePid, SisPatContainer patContainer);
void OnDvbSisDsaci(ushort currentDsaGroupId, int versionNumber, byte sectionNumber, byte lastSectionNumber, Stream dsaci); void OnDvbSisSdt(int sourcePid, SisSdtContainer sdtContainer);
void OnDvbSisPmt(int sourcePid, SisPmtContainer pmtContainer); void OnDvbSisDsaci(ushort currentDsaGroupId, int versionNumber, byte sectionNumber, byte lastSectionNumber, Stream dsaci);
void OnDvbSisNit(int sourcePid, SisNitContainer nitContainer); void OnDvbSisPmt(int sourcePid, SisPmtContainer pmtContainer);
void OnDvbSisTdt(int sourcePid, DateTime? utcTime); void OnDvbSisNit(int sourcePid, SisNitContainer nitContainer);
void OnRcs2Rmt(Rmt rmt); void OnDvbSisTdt(int sourcePid, DateTime? utcTime);
void OnRcs2Tmst(ushort networkId, Tmst tmst); void OnRcs2Rmt(Rmt rmt);
void OnRcs2Tmst2(ushort interactiveNetworkId, Tmst2 tmst2); void OnRcs2Tmst(ushort networkId, Tmst tmst);
void OnRcs2Tdt(ushort interactiveNetworkId, Rcs2Tdt tdt); void OnRcs2Tmst2(ushort interactiveNetworkId, Tmst2 tmst2);
void OnRcs2Nit(ushort interactiveNetworkId, RcsNit nit); void OnRcs2Tdt(ushort interactiveNetworkId, Rcs2Tdt tdt);
void OnRcs2Bct(ushort networkId, Bct bct); void OnRcs2Nit(ushort interactiveNetworkId, RcsNit nit);
void OnRcs2Fct2(ushort networkId, Fct2 fct2); void OnRcs2Bct(ushort networkId, Bct bct);
void OnRcs2Tbtp2(ushort interactiveNetworkId, Tbtp2 tbtp2); void OnRcs2Fct2(ushort networkId, Fct2 fct2);
void OnRcs2Tct(ushort interactiveNetworkId, Tct tct); void OnRcs2Tbtp2(ushort interactiveNetworkId, Tbtp2 tbtp2);
void OnRcs2Tbtp(ushort interactiveNetworkId, Tbtp tbtp); void OnRcs2Tct(ushort interactiveNetworkId, Tct tct);
void OnRcs2Sct(ushort interactiveNetworkId, Sct sct); void OnRcs2Tbtp(ushort interactiveNetworkId, Tbtp tbtp);
void OnRcs2Sct(ushort interactiveNetworkId, Sct sct);
void OnRcs2Spt(ushort interactiveNetworkId, Spt spt); void OnRcs2Spt(ushort interactiveNetworkId, Spt spt);
void WneStoryDetect(uint embeddedSessionId); void WneStoryDetect(uint embeddedSessionId);
void WneStoryError(uint sessionId); void WneStoryError(uint sessionId);
void WneStoryProgress(uint sessionId, string filename, long fileCaught, uint fileSize); void WneStoryProgress(uint sessionId, string filename, long fileCaught, uint fileSize);
void WneStoryComplete(uint sessionId, string filename); void WneStoryComplete(uint sessionId, string filename);
} }
} }

View File

@ -92,9 +92,11 @@ using skyscraper8.Atsc.A322;
using skyscraper8.Atsc.A330; using skyscraper8.Atsc.A330;
using skyscraper8.Atsc.A331; using skyscraper8.Atsc.A331;
using skyscraper8.Atsc.A331.Schema; using skyscraper8.Atsc.A331.Schema;
using skyscraper8.Skyscraper.Net.VirtualNetworks;
using Tsubasa.IO; using Tsubasa.IO;
using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform; using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform;
using RntParser = skyscraper5.Dvb.TvAnytime.RntParser; using RntParser = skyscraper5.Dvb.TvAnytime.RntParser;
using skyscraper8.Dvb.DataBroadcasting;
namespace skyscraper5.Skyscraper.Scraper namespace skyscraper5.Skyscraper.Scraper
{ {
@ -1744,12 +1746,19 @@ namespace skyscraper5.Skyscraper.Scraper
} }
private IpTrafficHandler ipTrafficHandler; private IpTrafficHandler ipTrafficHandler;
public void OnIpDatagram(int pid, byte[] payload) public void OnIpDatagram(VirtualNetworkIdentifier networkId, byte[] payload)
{ {
UiJunction?.EnableUiFeature(SkyscraperUiFeature.IpTrafficAnalysis); 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(); StorageConnectionManager storageConnectionManager = StorageConnectionManager.GetInstance();
ipTrafficHandler = storageConnectionManager.GetDefaultIpTrafficHandler(); ipTrafficHandler = storageConnectionManager.GetDefaultIpTrafficHandler();
@ -1759,7 +1768,7 @@ namespace skyscraper5.Skyscraper.Scraper
return; return;
} }
ipTrafficHandler?.HandleIpPacket(pid, payload); ipTrafficHandler?.HandleIpPacket(networkId, payload);
int ipVersion = (payload[0] & 0xf0) >> 4; int ipVersion = (payload[0] & 0xf0) >> 4;
if (ipVersion == 4) if (ipVersion == 4)
@ -1778,7 +1787,7 @@ namespace skyscraper5.Skyscraper.Scraper
return; return;
byte[] ipv4Packet = new byte[payload.Length - ihl]; byte[] ipv4Packet = new byte[payload.Length - ihl];
Array.Copy(payload, ihl, ipv4Packet, 0, payload.Length - ihl); Array.Copy(payload, ihl, ipv4Packet, 0, payload.Length - ihl);
OnIpv4PacketArrival(internetHeader, ipv4Packet); OnIpv4PacketArrival(networkId, internetHeader, ipv4Packet);
} }
else if (ipVersion == 6) else if (ipVersion == 6)
{ {
@ -1805,7 +1814,7 @@ namespace skyscraper5.Skyscraper.Scraper
InternetHeader ipv6Header = new InternetHeader(trafficClass, flowLabel, payloadLength, nextHeader, hopLimit, sourceAddress, destinationAddress); InternetHeader ipv6Header = new InternetHeader(trafficClass, flowLabel, payloadLength, nextHeader, hopLimit, sourceAddress, destinationAddress);
if (ipv6Stream.GetAvailableBytes() >= payloadLength) if (ipv6Stream.GetAvailableBytes() >= payloadLength)
{ {
OnIpv4PacketArrival(ipv6Header, ipv6Stream.ReadBytes(payloadLength)); OnIpv4PacketArrival(networkId, ipv6Header, ipv6Stream.ReadBytes(payloadLength));
} }
return; return;
} }
@ -1852,7 +1861,7 @@ namespace skyscraper5.Skyscraper.Scraper
return result; 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. //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. //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)); 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)) if (trafficInfos.Add(iti))
{ {
LogEvent(SkyscraperContextEvent.IpTraffic, iti.ToString()); LogEvent(SkyscraperContextEvent.IpTraffic, String.Format("[{0}] {1}",networkId.GetHumanReadableName(), iti.ToString()));
} }
if (mpePlugins == null) if (mpePlugins == null)
@ -3015,20 +3024,28 @@ namespace skyscraper5.Skyscraper.Scraper
lastEventTimestamp = DateTime.Now; 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)) if (Array.TrueForAll(contents, x => x == 0))
return; return;
TeiOnOffFilter.SetExempt(pid);
PidNetworkIdentifier pidId = network as PidNetworkIdentifier;
if (pidId != null)
{
TeiOnOffFilter.SetExempt(pidId.PID);
}
if (etherType <= 1500) if (etherType <= 1500)
{ {
OnLlcFrame((ushort)pid, source, destination, etherType, contents); OnLlcFrame(network, source, destination, etherType, contents);
return; return;
} }
switch (etherType) switch (etherType)
{ {
case 0x0800: case 0x0800:
OnIpDatagram(pid, contents); //IPv4
OnIpDatagram(network, contents);
return; return;
case 0x22e3: case 0x22e3:
//This is related to G.9961, a PowerLine standard specified by ITU-T T-REC-G.9961 //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. //This is an IPX Frame. We don't need it.
return; return;
case 0x86dd: case 0x86dd:
OnIpDatagram(pid, contents); //IPv6
OnIpDatagram(network, contents);
return; return;
case 0x88e1: case 0x88e1:
//This is related to FRITZ!Powerline. //This is related to FRITZ!Powerline.
@ -3070,13 +3088,14 @@ namespace skyscraper5.Skyscraper.Scraper
//Something proprietary. No idea. //Something proprietary. No idea.
return; return;
case 0xf67f: 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) 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]); (contents[26], contents[27]) = (contents[27], contents[26]);
ushort newEtherType = BitConverter.ToUInt16(contents, 26); ushort newEtherType = BitConverter.ToUInt16(contents, 26);
byte[] newPacket = new byte[contents.Length - 28]; byte[] newPacket = new byte[contents.Length - 28];
Array.Copy(contents, 28, newPacket, 0, newPacket.Length); Array.Copy(contents, 28, newPacket, 0, newPacket.Length);
OnEthernetFrame(pid, destination, source, newEtherType, newPacket); OnEthernetFrame(AtmAdaptationLayer5NetworkIdentifier.GetWrap(network), destination, source, newEtherType, newPacket);
} }
return; return;
case 0x94ad: 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(); 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); UiJunction?.EnableUiFeature(SkyscraperUiFeature.LlcSnapTrafficAnalysis);
if (ipTrafficHandler == null) if (ipTrafficHandler == null)
@ -3172,7 +3191,7 @@ namespace skyscraper5.Skyscraper.Scraper
PhysicalAddress ethernetSrc = llcStream.ReadMacAddress(); PhysicalAddress ethernetSrc = llcStream.ReadMacAddress();
ushort ethernetType = llcStream.ReadUInt16BE(); ushort ethernetType = llcStream.ReadUInt16BE();
byte[] ethernetPayload = llcStream.ReadBytes(llcStream.GetAvailableBytes()); byte[] ethernetPayload = llcStream.ReadBytes(llcStream.GetAvailableBytes());
OnEthernetFrame(pid, ethernetDst, ethernetSrc, ethernetType, ethernetPayload); OnEthernetFrame(AtmAdaptationLayer5NetworkIdentifier.GetWrap(pid), ethernetDst, ethernetSrc, ethernetType, ethernetPayload);
return; return;
} }
else else

View File

@ -10,6 +10,8 @@ using skyscraper5.Ietf.Rfc2460;
using skyscraper5.Ietf.Rfc971; using skyscraper5.Ietf.Rfc971;
using skyscraper5.Mpeg2; using skyscraper5.Mpeg2;
using skyscraper5.Skyscraper.Plugins; using skyscraper5.Skyscraper.Plugins;
using skyscraper8.Dvb.DataBroadcasting;
using skyscraper8.Skyscraper.Net.VirtualNetworks;
namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants 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++; Score++;
} }
public void OnIpDatagram(int sourcePid, byte[] payload) public void OnIpDatagram(VirtualNetworkIdentifier sourceNetwork, byte[] payload)
{ {
int ipVersion = (payload[0] & 0xf0) >> 4; int ipVersion = (payload[0] & 0xf0) >> 4;
if (ipVersion == 4) if (ipVersion == 4)
@ -66,7 +68,7 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants
byte[] ipv4Packet = new byte[testLength]; byte[] ipv4Packet = new byte[testLength];
Array.Copy(payload, ihl, ipv4Packet, 0, testLength); Array.Copy(payload, ihl, ipv4Packet, 0, testLength);
OnIpv4PacketArrival(internetHeader, ipv4Packet); OnIpv4PacketArrival(sourceNetwork, internetHeader, ipv4Packet);
} }
else if (ipVersion == 6) 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++; Score++;
} }