Sucessfulyl parsed our very first BFBS GSE Frame.
Some checks failed
🚀 Pack skyscraper8 / make-zip (push) Failing after 2m0s

This commit is contained in:
feyris-tan 2025-11-07 14:03:27 +01:00
parent fc8053451a
commit 33d17a730b
3 changed files with 149 additions and 6 deletions

View File

@ -5,6 +5,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using skyscraper5.Mpeg2; using skyscraper5.Mpeg2;
using skyscraper8.GSE; using skyscraper8.GSE;
using skyscraper8.GSE.GSE;
using skyscraper8.Skyscraper.IO; using skyscraper8.Skyscraper.IO;
using skyscraper8.Skyscraper.Scraper; using skyscraper8.Skyscraper.Scraper;
@ -15,6 +16,8 @@ namespace skyscraper8.GS.GSE_BFBS
private readonly byte _misId; private readonly byte _misId;
private readonly ISubTsHandler _subTsHandler; private readonly ISubTsHandler _subTsHandler;
private GseLabel lastLabel;
public BfbsGseReader(byte misId, ISubTsHandler subTsHandler) public BfbsGseReader(byte misId, ISubTsHandler subTsHandler)
{ {
_misId = misId; _misId = misId;
@ -32,6 +35,82 @@ namespace skyscraper8.GS.GSE_BFBS
StreamlikeSpan span = new StreamlikeSpan(readOnlySpan); StreamlikeSpan span = new StreamlikeSpan(readOnlySpan);
while (span.GetAvailableBytes() >= 1)
{
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
{
int gseLength = (byteA & 0x0f) << 8;
gseLength += span.ReadUInt8();
byte? fragId = null;
if (!startIndicator || !endIndicator)
{
fragId = span.ReadUInt8();
gseLength -= 1;
}
ushort? totalLength = null;
if ((startIndicator) && !endIndicator)
{
totalLength = span.ReadUInt16BE();
gseLength -= 2;
}
GseLabel label = null;
ushort? protocolType = null;
if (startIndicator)
{
protocolType = span.ReadUInt16BE();
gseLength -= 2;
if (labelTypeIndicator == 0)
{
label = new _6byteLabel(span.ReadBytes(6));
gseLength -= 6;
}
else if (labelTypeIndicator == 1)
{
label = new _3byteLabel(span.ReadBytes(3));
gseLength -= 3;
}
else if (labelTypeIndicator == 2)
{
label = BroadcastLabel.GetInstance();
}
else if (labelTypeIndicator == 3)
{
label = lastLabel;
}
}
if (!startIndicator && endIndicator)
gseLength -= 4;
ReadOnlySpan<byte> gseDataBytes = span.ReadBytes(gseLength);
if (!startIndicator && endIndicator)
{
uint crc32 = span.ReadUInt32BE();
throw new NotImplementedException("crc32");
}
HandleGseFrame(startIndicator, endIndicator, fragId, totalLength, label, protocolType,
gseDataBytes);
}
}
}
private void HandleGseFrame(bool startIndicator, bool endIndicator, byte? fragId, ushort? totalLength, GseLabel label, ushort? protocolType, ReadOnlySpan<byte> gseDataBytes)
{
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }

View File

@ -29,16 +29,29 @@ public class _3byteLabel : GseLabel
{ {
public _3byteLabel(byte[] buffer) public _3byteLabel(byte[] buffer)
{ {
Label = buffer; this.buffer = buffer;
} }
public byte[] Label { get; private set; }
override public string ToString() private byte[] buffer;
public byte GroupId => buffer[0];
public ushort LogonId
{ {
return BitConverter.ToString(Label); get
{
ushort result = buffer[1];
result <<= 8;
result += buffer[2];
return result;
}
} }
public override string ToString()
{
return $"{nameof(GroupId)}: {GroupId}, {nameof(LogonId)}: {LogonId}";
}
override public int Length => 3; override public int Length => 3;
} }

View File

@ -69,6 +69,57 @@ namespace skyscraper8.Skyscraper.IO
public bool CanWrite => true; public bool CanWrite => true;
public long Length => internalLength; public long Length => internalLength;
public long Position => internalPosition; public long Position => internalPosition;
public byte ReadUInt8()
{
byte result = _readOnlySpan[internalPosition];
internalPosition++;
return result;
}
public ushort ReadUInt16BE()
{
ushort a = _readOnlySpan[internalPosition];
a <<= 8;
a += _readOnlySpan[internalPosition + 1];
internalPosition += 2;
return a;
}
public byte[] ReadBytes(int i)
{
byte[] buffer = new byte[i];
if (Read(buffer, 0, i) != i)
{
throw new IOException(String.Format("Failed to read {0} bytes", i));
}
return buffer;
}
public ReadOnlySpan<byte> ReadSpan(int length)
{
ReadOnlySpan<byte> buffer = _readOnlySpan.Slice(internalPosition, length);
internalPosition += length;
return buffer;
}
public uint ReadUInt32BE()
{
uint result = _readOnlySpan[internalPosition];
result <<= 8;
result += _readOnlySpan[internalPosition + 1];
result <<= 8;
result += _readOnlySpan[internalPosition + 2];
result <<= 8;
result += _readOnlySpan[internalPosition + 3];
internalPosition += 4;
return result;
}
public int GetAvailableBytes()
{
return internalLength - internalPosition;
}
} }
class TelepathyStream : Stream class TelepathyStream : Stream