skyscraper8/skyscraper8/InteractionChannel/InteractionChannelPsiGatherer.cs
feyris-tan ef86554f9a Import
2025-05-12 22:09:16 +02:00

288 lines
9.0 KiB
C#

using skyscraper5.Mpeg2;
using skyscraper5.Mpeg2.Descriptors;
using skyscraper5.Skyscraper.IO;
using skyscraper5.src.InteractionChannel.Model;
using skyscraper5.src.InteractionChannel.Model2;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace skyscraper5.src.InteractionChannel
{
internal class InteractionChannelPsiGatherer : IPsiProcessor
{
private UserDefinedDescriptor _expectedTable;
public UserDefinedDescriptor ExpectedTables
{
get => _expectedTable;
set
{
if (value.DescriptorTag != 0xa7)
{
throw new ArgumentException(String.Format("Expected a {0} descriptor.", 0xa7));
}
_expectedTable = value;
}
}
private InteractionChannelHandler _handler;
public InteractionChannelHandler Handler
{
get => _handler;
set => _handler = value;
}
public ushort? NetworkId { get; private set; }
//Maybe also check ETSI EN 301 545-2 V1.4.0 (2023-10) ?
//en_301790v010501p_RCS_Map.pdf
//page 78
public void GatherPsi(PsiSection section, int sourcePid)
{
if (_handler == null)
{
throw new NoInteractionChannelHandlerException();
}
byte[] buffer = section.GetDataCopy();
if (_expectedTable != null)
{
if (!_expectedTable.Data.Contains(buffer[0]))
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.UnexpectedTable);
return;
}
}
MemoryStream ms = new MemoryStream(buffer, false);
switch (buffer[0])
{
case 0x40: //NIT
//see ETSI EN 301 545-2
throw new NotImplementedException("NIT");
case 0x41: //RMT
Rmt rmt = new Rmt(ms);
if (!rmt.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.RmtInvalid);
return;
}
_handler.OnRcsMap(rmt);
return;
case 0x4D: //SAT
throw new NotImplementedException("SAT");
case 0x70: //TDT
throw new NotImplementedException("TDT");
case 0xA0: //SCT
InteractionChannelSiSectionHeader sctHeader = new InteractionChannelSiSectionHeader(ms);
if (!sctHeader.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.HeaderInvalid);
return;
}
NetworkId = sctHeader.InteractiveNetworkId;
Sct sct = new Sct(ms);
if (!sct.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.SctInvalid);
return;
}
Handler.OnSuperframeComposition(sctHeader.InteractiveNetworkId, sct);
return;
case 0xA1: //FCT
InteractionChannelSiSectionHeader fctHeader = new InteractionChannelSiSectionHeader(ms);
if (!fctHeader.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.HeaderInvalid);
return;
}
NetworkId = fctHeader.InteractiveNetworkId;
Fct fct = new Fct(ms);
if (!fct.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.FctInvalid);
return;
}
Handler.OnFrameComposition(fctHeader.InteractiveNetworkId, fct);
return;
case 0xA2: //TCT
InteractionChannelSiSectionHeader tctHeader = new InteractionChannelSiSectionHeader(ms);
if (!tctHeader.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.HeaderInvalid);
return;
}
NetworkId = tctHeader.InteractiveNetworkId;
Tct tct = new Tct(ms);
if (!tct.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.TctInvalid);
return;
}
Handler.OnTimeslotComposition(tctHeader.InteractiveNetworkId, tct);
return;
case 0xA3: //SPT
InteractionChannelSiSectionHeader sptHeader = new InteractionChannelSiSectionHeader(ms);
if (!sptHeader.Valid)
{
_handler.OnInteractionChannelError (InteractionChannelErrorState.HeaderInvalid);
return;
}
NetworkId = sptHeader.InteractiveNetworkId;
Spt spt = new Spt(ms);
if (!spt.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.SptInvalid);
return;
}
Handler.OnSatellitePosition(sptHeader.InteractiveNetworkId, spt);
return;
case 0xA4: //CMT
InteractionChannelSiSectionHeader cmtHeader = new InteractionChannelSiSectionHeader(ms);
if (!cmtHeader.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.HeaderInvalid);
return;
}
NetworkId = cmtHeader.InteractiveNetworkId;
Cmt cmt = new Cmt(ms);
if (!cmt.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.CmtInvalid);
return;
}
Handler.OnCorrectionMessage(cmtHeader.InteractiveNetworkId, cmt);
return;
case 0xA5: //TBTP
InteractionChannelSiSectionHeader tbtpHeader = new InteractionChannelSiSectionHeader(ms);
if (!tbtpHeader.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.HeaderInvalid);
return;
}
NetworkId = tbtpHeader.InteractiveNetworkId;
Tbtp tbtp = new Tbtp(ms);
if (!tbtp.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.TbtpInvalid);
return;
}
Handler.OnTerminalBurstTimePlan(tbtpHeader.InteractiveNetworkId, tbtp);
return;
case 0xA6: //PCR packet payload
throw new NotImplementedException("PCR packet payload");
case 0xAA: //Transmission Mode Support Table
InteractionChannelSiSectionHeader tmstHeader = new InteractionChannelSiSectionHeader(ms);
if (!tmstHeader.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.HeaderInvalid);
return;
}
NetworkId = tmstHeader.InteractiveNetworkId;
Tmst tmst = new Tmst(ms);
if (!tmst.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.TmstInvalid);
return;
}
Handler.OnTransmissionModeSupport(tmstHeader.InteractiveNetworkId, tmst);
return;
case 0xAB: //FCT2
InteractionChannelSiSectionHeader fct2Header = new InteractionChannelSiSectionHeader(ms);
if (!fct2Header.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.HeaderInvalid);
return;
}
NetworkId = fct2Header.InteractiveNetworkId;
Fct2 fct2 = new Fct2(ms);
if (!fct2.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.Fct2Invalid);
return;
}
throw new NotImplementedException("FCT2");
case 0xAC: //BCT
//see en_30154502v010401p.pdf, page 49
throw new NotImplementedException("BCT");
case 0xAD: //TBTP2
InteractionChannelSiSectionHeader tbtp2Header = new InteractionChannelSiSectionHeader(ms);
if (!tbtp2Header.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.HeaderInvalid);
return;
}
NetworkId = tbtp2Header.InteractiveNetworkId;
Tbtp2 tbtp2 = new Tbtp2(ms);
if (!tbtp2.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.Tbtp2Invalid);
return;
}
throw new NotImplementedException("TBTP2");
case 0xAE: //TMST2
InteractionChannelSiSectionHeader tmst2Header = new InteractionChannelSiSectionHeader(ms);
if (!tmst2Header.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.HeaderInvalid);
return;
}
NetworkId = tmst2Header.InteractiveNetworkId;
int transmissionStandard = _handler.GetRmtTransmissionStandard(NetworkId.Value);
Tmst2 tmst2 = new Tmst2(ms,transmissionStandard);
if (!tmst2.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.Tmst2Invalid);
return;
}
if (tmst2.TransmissionModes.Length == 0)
return;
throw new NotImplementedException("TMST2");
case 0xAF: //FAT
//see en_30154502v010401p.pdf, page 49
throw new NotImplementedException("TMST2");
case 0xB0: //TIM
InteractionChannelDsmCcPrivateSectionHeader timHeader = new InteractionChannelDsmCcPrivateSectionHeader(ms);
if (!timHeader.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.HeaderInvalid);
return;
}
Tim tim = new Tim(ms, timHeader.IsBroadcast);
if (!tim.Valid)
{
_handler.OnInteractionChannelError(InteractionChannelErrorState.TimInvalid);
return;
}
tim.Handle(timHeader.MacAddress, NetworkId, Handler);
return;
case 0xB1: //LL_FEC_parity_data_table
throw new NotImplementedException("LL_FEC_parity_data_table");
case 0xB2: //MMT2
//see en_30154502v010401p.pdf, page 49
throw new NotImplementedException("MMT2");
default:
if (buffer[0] == 0xa7 || buffer[0] == 0xa8 || buffer[0] == 0xa9)
{
//reserved
break;
}
if (buffer[0] >= 0xb2 || buffer[0] <= 0xbf)
{
//reserved for future use
break;
}
if (buffer[0] >= 0xc0 || buffer[0] <= 0xfe)
{
//user defined
break;
}
throw new NotImplementedException(String.Format("ETSI EN 301 790 V1.5.1 0x{0:X2}", buffer[0]));
}
}
}
}