Added a rudimentary ULE deframer.
This commit is contained in:
parent
0453a7115a
commit
8c76f9a421
24
skyscraper8/Ietf/IetfException.cs
Normal file
24
skyscraper8/Ietf/IetfException.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using skyscraper5;
|
||||||
|
|
||||||
|
namespace skyscraper8.Ietf
|
||||||
|
{
|
||||||
|
public class IetfException : SkyscraperException
|
||||||
|
{
|
||||||
|
public IetfException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public IetfException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public IetfException(string message, Exception inner) : base(message, inner)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
46
skyscraper8/Ietf/Rfc4236_ULE/UleContestant.cs
Normal file
46
skyscraper8/Ietf/Rfc4236_ULE/UleContestant.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using skyscraper5.Skyscraper.Plugins;
|
||||||
|
using skyscraper5.Skyscraper.Scraper;
|
||||||
|
using skyscraper5.Skyscraper.Scraper.StreamAutodetection;
|
||||||
|
|
||||||
|
namespace skyscraper8.Ietf.Rfc4236_ULE
|
||||||
|
{
|
||||||
|
[SkyscraperPlugin]
|
||||||
|
internal class UleContestant : Contestant, UleEventHandler
|
||||||
|
{
|
||||||
|
public UleContestant(int pid) : base("ULE", pid)
|
||||||
|
{
|
||||||
|
PacketProcessor = new UlePacketProcessor(pid, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DeclareWinner(SkyscraperContext skyscraperContext, int pid, ProgramContext programContext)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Introduce(ProgramContext programContext)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnEthernetFrame(int pid, PhysicalAddress destination, PhysicalAddress source, ushort etherType, byte[] contents)
|
||||||
|
{
|
||||||
|
Score++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnUleError(int pid, int errorNo)
|
||||||
|
{
|
||||||
|
Score--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
skyscraper8/Ietf/Rfc4236_ULE/UleEventHandler.cs
Normal file
24
skyscraper8/Ietf/Rfc4236_ULE/UleEventHandler.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace skyscraper8.Ietf.Rfc4236_ULE
|
||||||
|
{
|
||||||
|
internal interface UleEventHandler
|
||||||
|
{
|
||||||
|
void OnEthernetFrame(int pid, PhysicalAddress destination, PhysicalAddress source, ushort etherType, byte[] contents);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The UlePacketProcessor is supposed to call this whenever an Error occurs during deframing.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pid">The source PID of the ULE ES</param>
|
||||||
|
/// <param name="errorNo">
|
||||||
|
/// Set this to:
|
||||||
|
/// 1* for a CRC error.
|
||||||
|
/// </param>
|
||||||
|
void OnUleError(int pid, int errorNo);
|
||||||
|
}
|
||||||
|
}
|
||||||
23
skyscraper8/Ietf/Rfc4236_ULE/UleException.cs
Normal file
23
skyscraper8/Ietf/Rfc4236_ULE/UleException.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace skyscraper8.Ietf.Rfc4236_ULE
|
||||||
|
{
|
||||||
|
public class UleException : IetfException
|
||||||
|
{
|
||||||
|
public UleException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public UleException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public UleException(string message, Exception inner) : base(message, inner)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
176
skyscraper8/Ietf/Rfc4236_ULE/UlePacketProcessor.cs
Normal file
176
skyscraper8/Ietf/Rfc4236_ULE/UlePacketProcessor.cs
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using skyscraper5.Mpeg2;
|
||||||
|
using skyscraper5.Skyscraper.IO;
|
||||||
|
|
||||||
|
namespace skyscraper8.Ietf.Rfc4236_ULE
|
||||||
|
{
|
||||||
|
internal class UlePacketProcessor : ITsPacketProcessor, IPayloadUnitDecoder
|
||||||
|
{
|
||||||
|
private readonly int _pid;
|
||||||
|
private readonly UleEventHandler _eventHandler;
|
||||||
|
|
||||||
|
private bool reassemblyMode;
|
||||||
|
private int reassemblyRemainingBytes;
|
||||||
|
private MemoryStream reassemblyStream;
|
||||||
|
private long offset;
|
||||||
|
|
||||||
|
public UlePacketProcessor(int pid, UleEventHandler eventHandler)
|
||||||
|
{
|
||||||
|
_pid = pid;
|
||||||
|
_eventHandler = eventHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PushPacket(TsPacket packet)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (packet.PayloadUnitStart)
|
||||||
|
{
|
||||||
|
PushPusiPacket(packet);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (reassemblyMode)
|
||||||
|
{
|
||||||
|
int availableBytes = Math.Min(184, reassemblyRemainingBytes);
|
||||||
|
reassemblyStream.Write(packet.RawPacket, 4, availableBytes);
|
||||||
|
reassemblyRemainingBytes -= availableBytes;
|
||||||
|
if (reassemblyRemainingBytes == 0)
|
||||||
|
{
|
||||||
|
reassemblyMode = false;
|
||||||
|
reassemblyStream.Position = 0;
|
||||||
|
OnReassembledPacket(reassemblyStream);
|
||||||
|
reassemblyStream = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Es gibt keine neue Payload Unit, und wir bauen uns auch keine zusammen, also diese wegwerfen.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += 188;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PushPusiPacket(TsPacket packet)
|
||||||
|
{
|
||||||
|
bool multipleSndusInPacket = false;
|
||||||
|
|
||||||
|
MemoryStream payload = new MemoryStream(packet.RawPacket, false);
|
||||||
|
payload.Position += 4;
|
||||||
|
byte nextPacketOffset = payload.ReadUInt8();
|
||||||
|
if (!reassemblyMode)
|
||||||
|
payload.Position += nextPacketOffset;
|
||||||
|
|
||||||
|
while (payload.GetAvailableBytes() > 0)
|
||||||
|
{
|
||||||
|
if (reassemblyMode)
|
||||||
|
{
|
||||||
|
int availableBytes = Math.Min((int)payload.GetAvailableBytes(), reassemblyRemainingBytes);
|
||||||
|
byte[] stepBuffer = new byte[availableBytes];
|
||||||
|
int sucessfullyCopiedBytes = payload.Read(stepBuffer, 0, availableBytes);
|
||||||
|
if (sucessfullyCopiedBytes != availableBytes)
|
||||||
|
throw new UleException("Byte copy operation failed during reassembly.");
|
||||||
|
reassemblyStream.Write(stepBuffer, 0, sucessfullyCopiedBytes);
|
||||||
|
reassemblyRemainingBytes -= sucessfullyCopiedBytes;
|
||||||
|
if (reassemblyRemainingBytes == 0)
|
||||||
|
{
|
||||||
|
reassemblyMode = false;
|
||||||
|
reassemblyStream.Position = 0;
|
||||||
|
OnReassembledPacket(reassemblyStream);
|
||||||
|
reassemblyStream = null;
|
||||||
|
multipleSndusInPacket = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (payload.GetAvailableBytes() == 1)
|
||||||
|
{
|
||||||
|
/*"If only one byte remains unprocessed in the TS Packet payload
|
||||||
|
after completion of the Current SNDU, the Receiver MUST discard this
|
||||||
|
final byte of TS Packet payload."*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte lengthByteA = payload.ReadUInt8();
|
||||||
|
bool destinationAddressAbsent = (lengthByteA & 0x80) != 0;
|
||||||
|
|
||||||
|
byte lengthByteB = payload.ReadUInt8();
|
||||||
|
|
||||||
|
int length = lengthByteA & 0x7f;
|
||||||
|
length <<= 8;
|
||||||
|
length += lengthByteB;
|
||||||
|
length += 2;
|
||||||
|
|
||||||
|
if (length == 0x8001)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
reassemblyMode = true;
|
||||||
|
reassemblyRemainingBytes = length;
|
||||||
|
reassemblyStream = new MemoryStream();
|
||||||
|
reassemblyStream.WriteUInt8(lengthByteA);
|
||||||
|
reassemblyStream.WriteUInt8(lengthByteB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnReassembledPacket(MemoryStream ms)
|
||||||
|
{
|
||||||
|
bool crc = DvbCrc32.ValidateCrc(ms, 0, (int)ms.Length);
|
||||||
|
if (!crc)
|
||||||
|
{
|
||||||
|
_eventHandler.OnUleError(_pid, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte lengthByteA = ms.ReadUInt8();
|
||||||
|
bool destinationAddressAbsent = (lengthByteA & 0x80) != 0;
|
||||||
|
byte lengthBytesB = ms.ReadUInt8();
|
||||||
|
|
||||||
|
ushort typeField = ms.ReadUInt16BE();
|
||||||
|
|
||||||
|
PhysicalAddress destAddress = null;
|
||||||
|
if (!destinationAddressAbsent)
|
||||||
|
destAddress = new PhysicalAddress(ms.ReadBytes(6));
|
||||||
|
|
||||||
|
long packetSize = ms.GetAvailableBytes() - 4;
|
||||||
|
byte[] pdu = ms.ReadBytes(packetSize);
|
||||||
|
uint crc32 = ms.ReadUInt32BE();
|
||||||
|
|
||||||
|
switch (typeField)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
OnBridgedFrame(pdu);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException(String.Format("ULE Type 0x{0:X4}", typeField));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBridgedFrame(byte[] pdu)
|
||||||
|
{
|
||||||
|
MemoryStream ms = new MemoryStream(pdu, false);
|
||||||
|
PhysicalAddress destination = new PhysicalAddress(ms.ReadBytes(6));
|
||||||
|
PhysicalAddress source = new PhysicalAddress(ms.ReadBytes(6));
|
||||||
|
ushort etherType = ms.ReadUInt16BE();
|
||||||
|
byte[] contents = ms.ReadBytes(ms.GetAvailableBytes());
|
||||||
|
//_eventHandler.OnEthernetFrame(_pid, destination, source, etherType, contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PacketLoss()
|
||||||
|
{
|
||||||
|
reassemblyMode = false;
|
||||||
|
reassemblyRemainingBytes = 0;
|
||||||
|
reassemblyStream = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user