skyscraper8/skyscraper8/GS/GSE-BFBS/GseL2SHandler.cs
feyris-tan 5d0da389a6
Some checks failed
🚀 Pack skyscraper8 / make-zip (push) Failing after 1m36s
Fixed a logic bug in RCS2 Handling that would cause the NetworkId in RMT to be always 0 when carried via GSE.
2026-03-18 20:30:13 +01:00

171 lines
5.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using skyscraper5.src.InteractionChannel;
using skyscraper5.src.InteractionChannel.Model;
using skyscraper5.src.InteractionChannel.Model2;
using skyscraper8.GSE.GSE;
using skyscraper8.InteractionChannel;
using skyscraper8.InteractionChannel.Model;
using skyscraper8.InteractionChannel.Model2;
namespace skyscraper8.GS.GSE_BFBS
{
internal class GseL2SHandler
{
public GsContextDto Context { get; }
public GseL2SHandler(GsContextDto context)
{
Context = context;
}
public void PushPacket(byte[] buffer, GseLabel label)
{
GseTableStructure gseTableStructure = new GseTableStructure(buffer);
if (!gseTableStructure.Valid)
{
Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.GseTableStructureInvalid);
return;
}
MemoryStream ms = new MemoryStream(gseTableStructure.TableContent, false);
switch (gseTableStructure.TableId)
{
case 0x40:
RcsNit nit = new RcsNit(ms);
if (!nit.Valid)
{
Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.NitInvalid);
return;
}
Context.Rcs2Output.OnRcs2Nit(gseTableStructure.InteractiveNetworkId, nit);
return;
case 0x41:
Rmt rmt = new Rmt(ms, true, gseTableStructure.InteractiveNetworkId);
if (!rmt.Valid)
{
Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.RmtInvalid);
return;
}
Context.Rcs2Output.OnRcsMap(rmt);
return;
case 0x70:
Rcs2Tdt tdt = new Rcs2Tdt(ms);
if (!tdt.Valid)
{
Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.TdtInvalid);
return;
}
Context.Rcs2Output.OnRcs2Tdt(gseTableStructure.InteractiveNetworkId, tdt);
return;
case 0xa0:
Sct sct = new Sct(ms);
if (!sct.Valid)
{
Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.SctInvalid);
return;
}
Context.Rcs2Output.OnSuperframeComposition(gseTableStructure.InteractiveNetworkId, sct);
return;
case 0xa3:
Spt spt = new Spt(ms);
if (!spt.Valid)
{
Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.SptInvalid);
return;
}
Context.Rcs2Output.OnSatellitePosition(gseTableStructure.InteractiveNetworkId, spt);
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 0xab:
Fct2 fct2 = new Fct2(ms);
if (!fct2.Valid)
{
Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.Fct2Invalid);
return;
}
Context.Rcs2Output.OnFrameComposition2(gseTableStructure.InteractiveNetworkId, fct2);
return;
case 0xac:
Bct bct = new Bct(ms);
if (!bct.Valid)
{
Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.BctInvalid);
return;
}
Context.Rcs2Output.OnBroadcastConfiguration(gseTableStructure.InteractiveNetworkId, bct);
return;
case 0xad:
Tbtp2 tbtp2 = new Tbtp2(ms);
if (!tbtp2.Valid)
{
Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.Tbtp2Invalid);
return;
}
Context.Rcs2Output.OnTerminalBurstTimePlan2(gseTableStructure.InteractiveNetworkId, tbtp2);
return;
case 0xae:
int rmtTransmissionStandard = Context.Rcs2Output.GetRmtTransmissionStandard(gseTableStructure.InteractiveNetworkId);
Tmst2 tmst2 = new Tmst2(ms, rmtTransmissionStandard);
if (!tmst2.Valid)
{
Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.Tmst2Invalid);
return;
}
Context.Rcs2Output.OnTransmissionModeSupport2(gseTableStructure.InteractiveNetworkId, tmst2);
return;
case 0xb0:
Tim tim = new Tim(ms, label.IsBroadcast());
if (!tim.Valid)
{
Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.TimInvalid);
return;
}
PhysicalAddress physicalAddress;
if (label.IsBroadcast())
{
physicalAddress = _6byteLabel.BROADCAST;
}
else if (label.Length == 6)
{
physicalAddress = ((_6byteLabel)label).MAC;
}
else
{
throw new NotImplementedException("Found a TIM-U Table with a 3-byte GSE Label in this stream. This is not supported yet, please share a sample of this stream.");
}
tim.Handle(physicalAddress, gseTableStructure.InteractiveNetworkId, Context.Rcs2Output);
return;
case 0xc0:
//User defined, we have no way of knowing what this is.
return;
default:
//See en_30154502v010401p.pdf
//page 49
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.",
gseTableStructure.TableId));
}
}
}
}