Support for TIM-B in GSE.
Some checks failed
🚀 Pack skyscraper8 / make-zip (push) Failing after 1m32s

This commit is contained in:
feyris-tan 2025-11-10 18:18:39 +01:00
parent f93d5e7f01
commit e4d861ef6e
17 changed files with 221 additions and 20 deletions

View File

@ -12,6 +12,7 @@ using System.Linq;
using System.Net.NetworkInformation;
using System.Security.Cryptography;
using skyscraper8.InteractionChannel.Model;
using skyscraper8.InteractionChannel.Model2.Descriptors;
namespace skyscraper5.Data.PostgreSql
{
@ -975,6 +976,16 @@ namespace skyscraper5.Data.PostgreSql
throw new NotImplementedException();
}
public bool TestForTimFramePayloadFormat(ushort networkId, _0xb7_FramePayloadFormatDescriptor.TransmissionContext transmissionContext)
{
throw new NotImplementedException();
}
public void InsertTimFramePayloadFormat(ushort networkId, _0xb7_FramePayloadFormatDescriptor.TransmissionContext transmissionContext)
{
throw new NotImplementedException();
}
private bool AreArraysEqual(byte[] l, byte[] r)
{
if (l.Length != r.Length)

View File

@ -1,6 +1,7 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AArray_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F57d616db882b441b8c50720b4477e03db2e200_003F6e_003Fd247db11_003FArray_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAssert_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fa840692e98b74557bc005b38213a22c72dad0_003Fc8_003F58c2e0c9_003FAssert_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADictionary_00602_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F57d616db882b441b8c50720b4477e03db2e200_003F83_003Fc73c45bc_003FDictionary_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFileInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fe1ab690537c44e02a014076312b886b7b2e200_003F5a_003Fcf76af61_003FFileInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInterop_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F57d616db882b441b8c50720b4477e03db2e200_003Fea_003F7d70064b_003FInterop_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AList_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F57d616db882b441b8c50720b4477e03db2e200_003F6b_003Fa410ee2c_003FList_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>

View File

@ -114,7 +114,7 @@ namespace skyscraper8.GS.GSE_BFBS
{
if (gsePacket.StartIndicator & gsePacket.EndIndicator)
{
HandleAssembledFrame(gsePacket.ProtocolType.Value, gsePacket.GseDataBytes);
HandleAssembledFrame(gsePacket.ProtocolType.Value, gsePacket.GseDataBytes, gsePacket.Label);
return;
}
@ -137,7 +137,7 @@ namespace skyscraper8.GS.GSE_BFBS
{
byte[] gseDataBytes = fragmentations[gsePacket.FragmentId.Value].GetGseDataBytes();
ushort protocolType = fragmentations[gsePacket.FragmentId.Value].ProtocolType;
HandleAssembledFrame(protocolType, gseDataBytes);
HandleAssembledFrame(protocolType, gseDataBytes, gsePacket.Label);
fragmentations[gsePacket.FragmentId.Value] = null;
return;
}
@ -168,12 +168,15 @@ namespace skyscraper8.GS.GSE_BFBS
return;
}
throw new NotImplementedException("Frames without start and end indicators are not supported yet. Please consider submitting a sample.");
}
throw new NotImplementedException();
fragmentations[gsePacket.FragmentId.Value].AddFragement(gsePacket);
return;
}
private void HandleAssembledFrame(ushort protocolType, byte[] buffer)
throw new NotImplementedException(
"A unknown frame type was encountered. Please share a sample of this stream.");
}
private void HandleAssembledFrame(ushort protocolType, byte[] buffer, GseLabel label)
{
switch (protocolType)
{
@ -183,7 +186,7 @@ namespace skyscraper8.GS.GSE_BFBS
return;
case 0x0082:
//Lower Layer Signalling, see en_30154502v010401p.pdf, page 49
HandleLowerLayerSignalling(buffer);
HandleLowerLayerSignalling(buffer, label);
return;
case 0x0091:
//according to https://www.iana.org/assignments/ule-next-headers/ule-next-headers.xhtml it's private
@ -197,14 +200,14 @@ namespace skyscraper8.GS.GSE_BFBS
}
private GseL2SHandler rcs2;
private void HandleLowerLayerSignalling(byte[] buffer)
private void HandleLowerLayerSignalling(byte[] buffer, GseLabel label)
{
if (rcs2 == null)
{
rcs2 = new GseL2SHandler(Context);
}
rcs2.PushPacket(buffer);
rcs2.PushPacket(buffer, label);
}

View File

@ -1,11 +1,13 @@
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;
@ -21,7 +23,7 @@ namespace skyscraper8.GS.GSE_BFBS
Context = context;
}
public void PushPacket(byte[] buffer)
public void PushPacket(byte[] buffer, GseLabel label)
{
GseTableStructure gseTableStructure = new GseTableStructure(buffer);
if (!gseTableStructure.Valid)
@ -129,6 +131,30 @@ namespace skyscraper8.GS.GSE_BFBS
}
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;

View File

@ -8,6 +8,7 @@ public abstract class GseLabel
public abstract string ToString();
public abstract int LabelTypeIndicator { get; }
public abstract bool IsBroadcast();
}
public class _6byteLabel : GseLabel
@ -17,6 +18,11 @@ public class _6byteLabel : GseLabel
MAC = new PhysicalAddress(buffer);
}
public _6byteLabel(PhysicalAddress macAddress)
{
MAC = macAddress;
}
public PhysicalAddress MAC { get; private set; }
override public string ToString()
@ -26,6 +32,12 @@ public class _6byteLabel : GseLabel
public override int Length => 6;
public override int LabelTypeIndicator => 0;
public static PhysicalAddress BROADCAST = new PhysicalAddress(new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff });
public override bool IsBroadcast()
{
return MAC.Equals(BROADCAST);
}
}
public class _3byteLabel : GseLabel
@ -58,6 +70,10 @@ public class _3byteLabel : GseLabel
override public int Length => 3;
public override int LabelTypeIndicator => 1;
public override bool IsBroadcast()
{
return buffer[1] == 0xff && buffer[2] == 0xff;
}
}
public class BroadcastLabel : GseLabel
@ -82,4 +98,9 @@ public class BroadcastLabel : GseLabel
}
public override int LabelTypeIndicator => 2;
public override bool IsBroadcast()
{
return true;
}
}

View File

@ -8,8 +8,10 @@ using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using skyscraper5.src.InteractionChannel.Model2;
using skyscraper8.GSE.GSE;
using skyscraper8.InteractionChannel.Model;
using skyscraper8.InteractionChannel.Model2;
using skyscraper8.InteractionChannel.Model2.Descriptors;
namespace skyscraper5.src.InteractionChannel
{
@ -37,5 +39,6 @@ namespace skyscraper5.src.InteractionChannel
void OnRcs2Nit(ushort interactiveNetworkId, RcsNit nit);
void OnRcs2Tdt(ushort interactiveNetworkId, Rcs2Tdt tdt);
void OnTransmissionModeSupport2(ushort interactiveNetworkId, Tmst2 tmst2);
void OnFramePayloadFormatAnnouncement(ushort networkId, _0xb7_FramePayloadFormatDescriptor descriptor);
}
}

View File

@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace skyscraper5.src.InteractionChannel.Model
{
internal class Tct : Validatable
public class Tct : Validatable
{
public Tct(MemoryStream ms)
{

View File

@ -10,6 +10,8 @@ using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using skyscraper8.GSE.GSE;
using skyscraper8.InteractionChannel.Model2.Descriptors;
namespace skyscraper5.src.InteractionChannel.Model
{
@ -178,6 +180,14 @@ namespace skyscraper5.src.InteractionChannel.Model
return;
}
break;
case 0xb7:
Descriptors[i] = new _0xb7_FramePayloadFormatDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
default:
if (descriptorTag >= 0x00 && descriptorTag <= 0x49)
{
@ -189,7 +199,7 @@ namespace skyscraper5.src.InteractionChannel.Model
//Reserved
continue;
}
if (descriptorTag >= 0xb7 && descriptorTag <= 0xdf)
if (descriptorTag >= 0xcc && descriptorTag <= 0xdf)
{
//Reserved
continue;
@ -282,10 +292,13 @@ namespace skyscraper5.src.InteractionChannel.Model
case 0xb2:
handler.OnReturnTransmissionMOdes(macAddress, (_0xb2_ReturnTransmissionModesDescriptor)descriptor);
break;
case 0xb7:
handler.OnFramePayloadFormatAnnouncement(networkId.Value, (_0xb7_FramePayloadFormatDescriptor)descriptor);
break;
default:
if (id >= 0xe0 && id <= 0xfe)
break;
throw new NotImplementedException(String.Format("TIM Handle 0x{0:X2}", id));
throw new NotImplementedException(String.Format("TIM Descriptor 0x{0:X2} is not fully implemented yet. Please share a sample of this stream.", id));
}
}
}

View File

@ -0,0 +1,52 @@
using skyscraper5.Mpeg2;
using skyscraper5.Skyscraper.IO;
using skyscraper5.Skyscraper.Plugins;
namespace skyscraper8.InteractionChannel.Model2.Descriptors;
[SkyscraperPlugin]
[TsDescriptor(0xb7,"TIM")]
public class _0xb7_FramePayloadFormatDescriptor : TsDescriptor
{
public _0xb7_FramePayloadFormatDescriptor(byte[] buffer)
{
InBitStream bitstream = new InBitStream(buffer);
byte contextLoopCount = bitstream.ReadBitsAsByte(8);
Contexts = new TransmissionContext[contextLoopCount];
for (int i = 0; i < contextLoopCount; i++)
{
TransmissionContext child = new TransmissionContext();
Contexts[i] = child;
child.TransmissionContextId = bitstream.ReadBitsAsByte(8);
bitstream.Reserved(3);
child.AllowPTypeOmission = bitstream.ReadBitAsBoolean();
child.UseCompressedPType = bitstream.ReadBitAsBoolean();
child.AllowAlpduCrc = bitstream.ReadBitAsBoolean();
child.AllowAlpduSequenceNumber = bitstream.ReadBitAsBoolean();
child.UseExplicitPayloadHeaderMap = bitstream.ReadBitAsBoolean();
child.ImplicitProtocolType = bitstream.ReadBitsAsByte(8);
child.ImplicitPpduLabelSize = bitstream.ReadBitsAsByte(4);
child.ImplicitPayloadLabelSize = bitstream.ReadBitsAsByte(4);
bitstream.Reserved(4);
child.Type0AlpduLabelSize = bitstream.ReadBitsAsByte(4);
}
Valid = true;
}
public TransmissionContext[] Contexts;
public class TransmissionContext
{
public byte TransmissionContextId { get; set; }
public bool AllowPTypeOmission { get; set; }
public bool UseCompressedPType { get; set; }
public bool AllowAlpduCrc { get; set; }
public bool AllowAlpduSequenceNumber { get; set; }
public bool UseExplicitPayloadHeaderMap { get; set; }
public byte ImplicitProtocolType { get; set; }
public byte ImplicitPpduLabelSize { get; set; }
public byte ImplicitPayloadLabelSize { get; set; }
public byte Type0AlpduLabelSize { get; set; }
}
}

View File

@ -10,6 +10,7 @@ using System.Threading.Tasks;
using skyscraper5.src.InteractionChannel.Model2;
using skyscraper8.InteractionChannel.Model;
using skyscraper8.InteractionChannel.Model2;
using skyscraper8.InteractionChannel.Model2.Descriptors;
namespace skyscraper5.src.InteractionChannel
{
@ -53,6 +54,11 @@ namespace skyscraper5.src.InteractionChannel
}
public void OnFramePayloadFormatAnnouncement(ushort networkId, _0xb7_FramePayloadFormatDescriptor descriptor)
{
}
public void OnFrameComposition2(ushort? networkId, Fct2 fct2)
{

View File

@ -10,6 +10,11 @@ namespace skyscraper5.Skyscraper.IO
{
class InBitStream
{
public InBitStream(byte[] buffer)
: this(new MemoryStream(buffer,false))
{
}
public InBitStream(MemoryStream wrapped)
{
_wrapped = wrapped;
@ -124,5 +129,10 @@ namespace skyscraper5.Skyscraper.IO
result += (8 - bitPointer);
return result;
}
public void Reserved(byte i)
{
ReadBitsAsULong(i);
}
}
}

View File

@ -83,9 +83,11 @@ using skyscraper8.Experimentals.NdsSsu;
using skyscraper8.Experimentals.OtvSsu;
using skyscraper8.GS;
using skyscraper8.GSE;
using skyscraper8.GSE.GSE;
using skyscraper8.Ieee802_1AB;
using skyscraper8.InteractionChannel.Model;
using skyscraper8.InteractionChannel.Model2;
using skyscraper8.InteractionChannel.Model2.Descriptors;
using skyscraper8.Skyscraper.Net;
using skyscraper8.Skyscraper.Scraper;
using skyscraper8.T2MI;
@ -2449,6 +2451,11 @@ namespace skyscraper5.Skyscraper.Scraper
}
}
public void OnTimeslotComposition(ushort interactiveNetworkId, Tct tct)
{
throw new NotImplementedException();
}
public void OnTerminalBurstTimePlan2(ushort interactiveNetworkId, Tbtp2 tbtp2)
{
foreach (Tbtp2.Frame frame in tbtp2.Frames)
@ -2516,11 +2523,17 @@ namespace skyscraper5.Skyscraper.Scraper
}
}
void InteractionChannelHandler.OnTimeslotComposition(ushort interactiveNetworkId, Tct tct)
public void OnFramePayloadFormatAnnouncement(ushort networkId, _0xb7_FramePayloadFormatDescriptor descriptor)
{
throw new NotImplementedException();
foreach (_0xb7_FramePayloadFormatDescriptor.TransmissionContext transmissionContext in descriptor.Contexts)
{
if (!DataStorage.TestForTimFramePayloadFormat(networkId, transmissionContext))
{
LogEvent(SkyscraperContextEvent.TimFramePayloadFormat,String.Format("Network #{0}, Context ID #{1}",networkId,transmissionContext.TransmissionContextId));
DataStorage.InsertTimFramePayloadFormat(networkId, transmissionContext);
}
}
}
public void OnCorrectionMessage(PhysicalAddress mac, _0xa1_CorrectionMessageDescriptor cmd)
{
if (!DataStorage.TestForTim(mac))

View File

@ -92,6 +92,7 @@
EthernetLinkLayerDiscovery,
Rcs2Network,
Rcs2TdtTime,
TransmissionModeSupport2
TransmissionModeSupport2,
TimFramePayloadFormat
}
}

View File

@ -30,6 +30,7 @@ using System.Net.NetworkInformation;
using skyscraper5.src.InteractionChannel.Model2;
using skyscraper8.InteractionChannel.Model;
using skyscraper8.InteractionChannel.Model2;
using skyscraper8.InteractionChannel.Model2.Descriptors;
using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform;
namespace skyscraper8.Skyscraper.Scraper.Storage
@ -207,5 +208,7 @@ namespace skyscraper8.Skyscraper.Scraper.Storage
bool UpdateRcs2Tdt(ushort interactiveNetworkId, DateTime tdtTimestamp);
bool TestForTmst2(ushort interactiveNetworkId, Tmst2.TransmissionMode mode);
void InsertTmst2(ushort interactiveNetworkId, Tmst2.TransmissionMode mode);
bool TestForTimFramePayloadFormat(ushort networkId, _0xb7_FramePayloadFormatDescriptor.TransmissionContext transmissionContext);
void InsertTimFramePayloadFormat(ushort networkId, _0xb7_FramePayloadFormatDescriptor.TransmissionContext transmissionContext);
}
}

View File

@ -40,6 +40,7 @@ using skyscraper8.Experimentals.NdsSsu;
using skyscraper8.Ietf.FLUTE;
using skyscraper8.InteractionChannel.Model;
using skyscraper8.InteractionChannel.Model2;
using skyscraper8.InteractionChannel.Model2.Descriptors;
using skyscraper8.Ses;
using skyscraper8.SimpleServiceDiscoveryProtocol;
using skyscraper8.Skyscraper.Drawing;
@ -1213,6 +1214,16 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem
throw new NotImplementedException();
}
public bool TestForTimFramePayloadFormat(ushort networkId, _0xb7_FramePayloadFormatDescriptor.TransmissionContext transmissionContext)
{
throw new NotImplementedException();
}
public void InsertTimFramePayloadFormat(ushort networkId, _0xb7_FramePayloadFormatDescriptor.TransmissionContext transmissionContext)
{
throw new NotImplementedException();
}
public IEnumerable<Tuple<int, int, ProgramMapping>> SelectAllPmt()
{
throw new NotImplementedException();

View File

@ -40,6 +40,7 @@ using skyscraper5.src.InteractionChannel.Model2;
using skyscraper8.Ietf.FLUTE;
using skyscraper8.InteractionChannel.Model;
using skyscraper8.InteractionChannel.Model2;
using skyscraper8.InteractionChannel.Model2.Descriptors;
using skyscraper8.Skyscraper.Scraper.Storage;
using skyscraper8.Skyscraper.Scraper.Storage.Utilities;
using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform;
@ -1077,6 +1078,25 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory
_tmst2.Add(key, mode);
}
private Dictionary<Tuple<ushort, byte>, _0xb7_FramePayloadFormatDescriptor.TransmissionContext> _timFramePayloadFormats;
public bool TestForTimFramePayloadFormat(ushort networkId, _0xb7_FramePayloadFormatDescriptor.TransmissionContext transmissionContext)
{
if (_timFramePayloadFormats == null)
return false;
Tuple<ushort, byte> key = new Tuple<ushort, byte>(networkId, transmissionContext.TransmissionContextId);
return _timFramePayloadFormats.ContainsKey(key);
}
public void InsertTimFramePayloadFormat(ushort networkId, _0xb7_FramePayloadFormatDescriptor.TransmissionContext transmissionContext)
{
if (_timFramePayloadFormats == null)
_timFramePayloadFormats = new Dictionary<Tuple<ushort, byte>, _0xb7_FramePayloadFormatDescriptor.TransmissionContext>();
Tuple<ushort, byte> key = new Tuple<ushort, byte>(networkId, transmissionContext.TransmissionContextId);
_timFramePayloadFormats.Add(key, transmissionContext);
}
public IEnumerable<Tuple<int, int, ProgramMapping>> SelectAllPmt()
{
for (int x = 0; x < pmtEntries.Length; x++)

View File

@ -14,6 +14,7 @@ using System.Threading.Tasks;
using skyscraper5.src.InteractionChannel.Model2;
using skyscraper8.InteractionChannel.Model;
using skyscraper8.InteractionChannel.Model2;
using skyscraper8.InteractionChannel.Model2.Descriptors;
namespace skyscraper5.src.Skyscraper.Scraper.StreamAutodetection.Contestants
{
@ -229,6 +230,12 @@ namespace skyscraper5.src.Skyscraper.Scraper.StreamAutodetection.Contestants
}
}
public void OnFramePayloadFormatAnnouncement(ushort networkId, _0xb7_FramePayloadFormatDescriptor descriptor)
{
if (descriptor.Contexts.Length > 0)
Score++;
}
public void OnFrameComposition2(ushort? networkId, Fct2 fct2)
{
if (fct2.FrameTypes.Length > 0)