Can now parse RMT, CMT and TBTP2 from GSE packets.
Some checks failed
🚀 Pack skyscraper8 / make-zip (push) Failing after 1m29s

This commit is contained in:
feyris-tan 2025-11-09 12:16:44 +01:00
parent 8f2c31f10d
commit c64a0f5c46
5 changed files with 87 additions and 39 deletions

View File

@ -3,6 +3,9 @@ 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 skyscraper5.src.InteractionChannel;
using skyscraper5.src.InteractionChannel.Model;
using skyscraper5.src.InteractionChannel.Model2;
using skyscraper8.InteractionChannel; using skyscraper8.InteractionChannel;
namespace skyscraper8.GS.GSE_BFBS namespace skyscraper8.GS.GSE_BFBS
@ -19,9 +22,46 @@ namespace skyscraper8.GS.GSE_BFBS
public void PushPacket(byte[] buffer) public void PushPacket(byte[] buffer)
{ {
GseTableStructure gseTableStructure = new GseTableStructure(buffer); GseTableStructure gseTableStructure = new GseTableStructure(buffer);
if (!gseTableStructure.Valid)
{
Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.GseTableStructureInvalid);
return;
}
MemoryStream ms = new MemoryStream(gseTableStructure.TableContent, false);
switch (gseTableStructure.TableId) switch (gseTableStructure.TableId)
{ {
case 0x41:
Rmt rmt = new Rmt(ms, true);
if (!rmt.Valid)
{
Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.RmtInvalid);
return;
}
Context.Rcs2Output.OnRcsMap(rmt);
return;
case 0xa4:
Cmt cmt = new Cmt(ms);
if (!cmt.Valid)
{
Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.CmtInvalid);
return;
}
Context.Rcs2Output.OnCorrectionMessage(gseTableStructure.InteractiveNetworkId, cmt);
return;
case 0xad:
Tbtp2 tbtp2 = new Tbtp2(ms);
if (!tbtp2.Valid)
{
Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.Tbtp2Invalid);
return;
}
Context.Rcs2Output.OnTerminalBurstTimePlan2(gseTableStructure.InteractiveNetworkId, tbtp2);
return;
default: default:
//See en_30154502v010401p.pdf
//page 49
throw new NotImplementedException(String.Format( throw new NotImplementedException(String.Format(
"Unknown DVB-RCS2 Table Id: 0x{0:X2}\nIf this is reproducible on this stream, please consider submitting me a sample.", "Unknown DVB-RCS2 Table Id: 0x{0:X2}\nIf this is reproducible on this stream, please consider submitting me a sample.",
gseTableStructure.TableId)); gseTableStructure.TableId));

View File

@ -3,6 +3,7 @@ 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 skyscraper5.Skyscraper;
using skyscraper5.Skyscraper.IO; using skyscraper5.Skyscraper.IO;
namespace skyscraper8.InteractionChannel namespace skyscraper8.InteractionChannel
@ -10,7 +11,7 @@ namespace skyscraper8.InteractionChannel
/// <summary> /// <summary>
/// Represents the structure in ETSI EN 301 545-2 V1.4.1, clause 6.4.3.1.1 /// Represents the structure in ETSI EN 301 545-2 V1.4.1, clause 6.4.3.1.1
/// </summary> /// </summary>
internal class GseTableStructure internal class GseTableStructure : Validatable
{ {
public GseTableStructure(byte[] buffer) public GseTableStructure(byte[] buffer)
{ {
@ -23,6 +24,7 @@ namespace skyscraper8.InteractionChannel
CurrentNextIndicator = (byteA & 0x01) != 0; CurrentNextIndicator = (byteA & 0x01) != 0;
TableContent = ms.ReadBytes(ms.GetAvailableBytes()); TableContent = ms.ReadBytes(ms.GetAvailableBytes());
Valid = true;
} }
public byte[] TableContent { get; private set; } public byte[] TableContent { get; private set; }

View File

@ -22,6 +22,7 @@ namespace skyscraper5.src.InteractionChannel
Fct2Invalid, Fct2Invalid,
Tbtp2Invalid, Tbtp2Invalid,
Tmst2Invalid, Tmst2Invalid,
BctInvalid BctInvalid,
GseTableStructureInvalid
} }
} }

View File

@ -6,6 +6,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using skyscraper5.Mpeg2;
namespace skyscraper5.src.InteractionChannel.Model namespace skyscraper5.src.InteractionChannel.Model
{ {

View File

@ -16,48 +16,51 @@ namespace skyscraper5.src.InteractionChannel.Model
{ {
private static TsDescriptorUnpacker tsDescriptorUnpacker; private static TsDescriptorUnpacker tsDescriptorUnpacker;
public Rmt(MemoryStream ms) public Rmt(MemoryStream ms, bool gseMode = false)
{ {
if (tsDescriptorUnpacker == null) if (tsDescriptorUnpacker == null)
tsDescriptorUnpacker = TsDescriptorUnpacker.GetInstance(); tsDescriptorUnpacker = TsDescriptorUnpacker.GetInstance();
byte tableId = ms.ReadUInt8(); if (!gseMode)
if (tableId != 0x41)
{ {
Valid = false; byte tableId = ms.ReadUInt8();
return; if (tableId != 0x41)
{
Valid = false;
return;
}
byte byteA = ms.ReadUInt8();
bool sectionSyntaxIndicator = (byteA & 0x80) != 1;
if (!sectionSyntaxIndicator)
{
Valid = false;
return;
}
bool reservedFutureUse = (byteA & 0x40) != 1;
int reserved = (byteA & 0x30) >> 4;
int sectionLength = (byteA & 0x0f);
sectionLength <<= 8;
sectionLength += ms.ReadUInt8();
if (sectionLength != ms.GetAvailableBytes())
{
Valid = false;
return;
}
NetworkId = ms.ReadUInt16BE();
byte byteB = ms.ReadUInt8();
reserved = (byteB & 0xc0) >> 6;
int versionNumber = (byteB & 0x3e) >> 1;
bool currentNextIndicator = (byteB & 0x01) != 0;
byte sectionNumber = ms.ReadUInt8();
byte lastSectionNumber = ms.ReadUInt8();
} }
byte byteA = ms.ReadUInt8();
bool sectionSyntaxIndicator = (byteA & 0x80) != 1;
if (!sectionSyntaxIndicator)
{
Valid = false;
return;
}
bool reservedFutureUse = (byteA & 0x40) != 1;
int reserved = (byteA & 0x30) >> 4;
int sectionLength = (byteA & 0x0f);
sectionLength <<= 8;
sectionLength += ms.ReadUInt8();
if (sectionLength != ms.GetAvailableBytes())
{
Valid = false;
return;
}
NetworkId = ms.ReadUInt16BE();
byte byteB = ms.ReadUInt8();
reserved = (byteB & 0xc0) >> 6;
int versionNumber = (byteB & 0x3e) >> 1;
bool currentNextIndicator = (byteB & 0x01) != 0;
byte sectionNumber = ms.ReadUInt8();
byte lastSectionNumber = ms.ReadUInt8();
byte byteC = ms.ReadUInt8(); byte byteC = ms.ReadUInt8();
int reservedFutureUseB = (byteC & 0xf0) >> 4; int reservedFutureUseB = (byteC & 0xf0) >> 4;
int networkDescriptorsLength = (byteC & 0x0f); int networkDescriptorsLength = (byteC & 0x0f);
@ -85,7 +88,8 @@ namespace skyscraper5.src.InteractionChannel.Model
Linkages.Add((_0x4a_LinkageDescriptor)descriptor); Linkages.Add((_0x4a_LinkageDescriptor)descriptor);
continue; continue;
} }
throw new NotImplementedException();
throw new NotImplementedException(String.Format("Unknown descriptor 0x{0:X2} in RCS Map Table. If this is reproducible, consider submitting a sample of this stream."));
} }
byte byteD = ms.ReadUInt8(); byte byteD = ms.ReadUInt8();
@ -141,7 +145,7 @@ namespace skyscraper5.src.InteractionChannel.Model
child.SatelliteReturnLink = (_0xa9_SatelliteReturnLinkDescriptor)descriptor; child.SatelliteReturnLink = (_0xa9_SatelliteReturnLinkDescriptor)descriptor;
break; break;
default: default:
throw new NotImplementedException(); throw new NotImplementedException(String.Format("Unknown descriptor 0x{0:X2} in RCS Map Table. If this is reproducible, consider submitting a sample of this stream."));
} }
} }
} }