From 4a90c8751fc9bc10d470733e56472d6d55ae1798 Mon Sep 17 00:00:00 2001 From: feyris-tan <4116042+feyris-tan@users.noreply.github.com> Date: Sat, 18 Oct 2025 22:04:52 +0200 Subject: [PATCH] Added BCT parsing. --- .../InteractionChannelErrorState.cs | 3 +- .../InteractionChannelHandler.cs | 4 +- .../InteractionChannelPsiGatherer.cs | 20 +++++++-- skyscraper8/InteractionChannel/Model2/Bct.cs | 43 +++++++++++++++++++ .../NullInteractionChannelHandler.cs | 12 +++++- .../Skyscraper/Scraper/SkyscraperContext.cs | 21 +++++++-- .../Scraper/SkyscraperContextEvent.cs | 3 +- .../Skyscraper/Scraper/Storage/DataStorage.cs | 3 ++ .../Storage/Filesystem/FilesystemStorage.cs | 11 +++++ .../InMemory/InMemoryScraperStorage.cs | 20 +++++++++ .../InteractionChannelContestant.cs | 22 +++++++++- 11 files changed, 150 insertions(+), 12 deletions(-) create mode 100644 skyscraper8/InteractionChannel/Model2/Bct.cs diff --git a/skyscraper8/InteractionChannel/InteractionChannelErrorState.cs b/skyscraper8/InteractionChannel/InteractionChannelErrorState.cs index 1162d41..ac6faf3 100644 --- a/skyscraper8/InteractionChannel/InteractionChannelErrorState.cs +++ b/skyscraper8/InteractionChannel/InteractionChannelErrorState.cs @@ -21,6 +21,7 @@ namespace skyscraper5.src.InteractionChannel TmstInvalid, Fct2Invalid, Tbtp2Invalid, - Tmst2Invalid + Tmst2Invalid, + BctInvalid } } diff --git a/skyscraper8/InteractionChannel/InteractionChannelHandler.cs b/skyscraper8/InteractionChannel/InteractionChannelHandler.cs index 8a94a1e..11f45c2 100644 --- a/skyscraper8/InteractionChannel/InteractionChannelHandler.cs +++ b/skyscraper8/InteractionChannel/InteractionChannelHandler.cs @@ -8,6 +8,7 @@ using System.Net.NetworkInformation; using System.Text; using System.Threading.Tasks; using skyscraper5.src.InteractionChannel.Model2; +using skyscraper8.InteractionChannel.Model2; namespace skyscraper5.src.InteractionChannel { @@ -30,6 +31,7 @@ namespace skyscraper5.src.InteractionChannel void OnReturnTransmissionMOdes(PhysicalAddress macAddress, _0xb2_ReturnTransmissionModesDescriptor descriptor); void OnConnectionControl(PhysicalAddress macAddress, _0xaf_ConnectionControlDescriptor descriptor); void OnTerminalBurstTimePlan2(ushort interactiveNetworkId, Tbtp2 tbtp2); - void OnFrameComposition2(ushort? networkId, Fct2 fct2); + void OnFrameComposition2(ushort networkId, Fct2 fct2); + void OnBroadcastConfiguration(ushort networkId, Bct bct); } } diff --git a/skyscraper8/InteractionChannel/InteractionChannelPsiGatherer.cs b/skyscraper8/InteractionChannel/InteractionChannelPsiGatherer.cs index 36b5564..11fb9a2 100644 --- a/skyscraper8/InteractionChannel/InteractionChannelPsiGatherer.cs +++ b/skyscraper8/InteractionChannel/InteractionChannelPsiGatherer.cs @@ -9,6 +9,7 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using skyscraper8.InteractionChannel.Model2; namespace skyscraper5.src.InteractionChannel { @@ -205,11 +206,24 @@ namespace skyscraper5.src.InteractionChannel return; } - Handler.OnFrameComposition2(NetworkId, fct2); + Handler.OnFrameComposition2(NetworkId.Value, fct2); return; case 0xAC: //BCT - //see en_30154502v010401p.pdf, page 49 - throw new NotImplementedException("BCT"); + InteractionChannelSiSectionHeader bctHeader = new InteractionChannelSiSectionHeader(ms); + if (!bctHeader.Valid) + { + _handler.OnInteractionChannelError(InteractionChannelErrorState.HeaderInvalid); + return; + } + NetworkId = bctHeader.InteractiveNetworkId; + Bct bct = new Bct(ms); + if (!bct.Valid) + { + _handler.OnInteractionChannelError(InteractionChannelErrorState.BctInvalid); + return; + } + Handler.OnBroadcastConfiguration(NetworkId.Value, bct); + return; case 0xAD: //TBTP2 InteractionChannelSiSectionHeader tbtp2Header = new InteractionChannelSiSectionHeader(ms); if (!tbtp2Header.Valid) diff --git a/skyscraper8/InteractionChannel/Model2/Bct.cs b/skyscraper8/InteractionChannel/Model2/Bct.cs new file mode 100644 index 0000000..586a81c --- /dev/null +++ b/skyscraper8/InteractionChannel/Model2/Bct.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using skyscraper5.Skyscraper; +using skyscraper5.Skyscraper.IO; + +namespace skyscraper8.InteractionChannel.Model2 +{ + /// + /// Broadcast Configuration Table as found on ETSI EN 301 545-2 V1.4.1, page 59 + /// + public class Bct : Validatable + { + public Bct(MemoryStream ms) + { + byte loopCount = ms.ReadUInt8(); + TxTypes = new BroadcastConfiguration[loopCount]; + for (int i = 0; i < loopCount; i++) + { + TxTypes[i] = new BroadcastConfiguration(); + TxTypes[i].TxType = ms.ReadUInt8(); + TxTypes[i].TxContentType = ms.ReadUInt8(); + TxTypes[i].TxFormatClass = ms.ReadUInt8(); + byte txFormatDataLengnth = ms.ReadUInt8(); + TxTypes[i].TxFormatData = ms.ReadBytes(txFormatDataLengnth); + } + + Valid = true; + } + + public BroadcastConfiguration[] TxTypes { get; private set; } + + public class BroadcastConfiguration + { + public byte TxType { get; set; } + public byte TxContentType { get; set; } + public byte TxFormatClass { get; set; } + public byte[] TxFormatData { get; set; } + } + } +} diff --git a/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs b/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs index 906a5f7..0b2732d 100644 --- a/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs +++ b/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs @@ -8,6 +8,7 @@ using System.Net.NetworkInformation; using System.Text; using System.Threading.Tasks; using skyscraper5.src.InteractionChannel.Model2; +using skyscraper8.InteractionChannel.Model2; namespace skyscraper5.src.InteractionChannel { @@ -27,9 +28,18 @@ namespace skyscraper5.src.InteractionChannel } + public void OnFrameComposition2(ushort networkId, Fct2 fct2) + { + + } + + public void OnBroadcastConfiguration(ushort networkId, Bct bct) + { + } + public void OnFrameComposition2(ushort? networkId, Fct2 fct2) { - throw new NotImplementedException(); + } public void OnContentionControl(PhysicalAddress macAddress, _0xab_ContentionControlDescriptor ccd) diff --git a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs index a929c5e..0977e3d 100644 --- a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs +++ b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs @@ -80,6 +80,7 @@ using skyscraper5.src.InteractionChannel.Model2; using skyscraper8.Experimentals.NdsSsu; using skyscraper8.Experimentals.OtvSsu; using skyscraper8.GSE; +using skyscraper8.InteractionChannel.Model2; using skyscraper8.Skyscraper.Net; using skyscraper8.Skyscraper.Scraper; using Tsubasa.IO; @@ -2413,14 +2414,26 @@ namespace skyscraper5.Skyscraper.Scraper } } - public void OnFrameComposition2(ushort? networkId, Fct2 fct2) + public void OnFrameComposition2(ushort networkId, Fct2 fct2) { foreach (Fct2.Frame frame in fct2.FrameTypes) { - if (!DataStorage.TestForFrameComposition2(networkId.Value, frame)) + if (!DataStorage.TestForFrameComposition2(networkId, frame)) { - LogEvent(SkyscraperContextEvent.FrameComposition2,String.Format("Network ID = {0}, Frame Type = {1}",networkId.Value,frame.FrameType)); - DataStorage.InsertFct2Frame(networkId.Value, frame); + LogEvent(SkyscraperContextEvent.FrameComposition2,String.Format("Network ID = {0}, Frame Type = {1}",networkId,frame.FrameType)); + DataStorage.InsertFct2Frame(networkId, frame); + } + } + } + + public void OnBroadcastConfiguration(ushort networkId, Bct bct) + { + foreach (Bct.BroadcastConfiguration txType in bct.TxTypes) + { + if (!DataStorage.TestForBroadcastConfiguration(networkId, txType.TxType)) + { + LogEvent(SkyscraperContextEvent.BroadcastConfiguration, String.Format("Network ID = {0}, Broadcast Configuration #{1}", networkId, txType.TxType)); + DataStorage.InsertBroadcastConfiguration(networkId, txType); } } } diff --git a/skyscraper8/Skyscraper/Scraper/SkyscraperContextEvent.cs b/skyscraper8/Skyscraper/Scraper/SkyscraperContextEvent.cs index 30d04e2..8d3661a 100644 --- a/skyscraper8/Skyscraper/Scraper/SkyscraperContextEvent.cs +++ b/skyscraper8/Skyscraper/Scraper/SkyscraperContextEvent.cs @@ -87,6 +87,7 @@ NdsSsuFileAnnounced, NdsSsuProgress, TerminalBurstTimePlan2, - FrameComposition2 + FrameComposition2, + BroadcastConfiguration } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs index 7a9e3e2..4fcd253 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs @@ -28,6 +28,7 @@ using skyscraper8.Ses; using System.Net; using System.Net.NetworkInformation; using skyscraper5.src.InteractionChannel.Model2; +using skyscraper8.InteractionChannel.Model2; using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform; namespace skyscraper8.Skyscraper.Scraper.Storage @@ -198,5 +199,7 @@ namespace skyscraper8.Skyscraper.Scraper.Storage void StoreTerminalBurstTimePlan2(ushort interactiveNetworkId, byte tbtp2GroupId, Tbtp2.Frame frame); bool TestForFrameComposition2(ushort networkId, Fct2.Frame fct2); void InsertFct2Frame(ushort networkId, Fct2.Frame frame); + bool TestForBroadcastConfiguration(ushort networkId, byte txTypeTxType); + void InsertBroadcastConfiguration(ushort networkId, Bct.BroadcastConfiguration txType); } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs index 5f4af87..f8a9599 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs @@ -38,6 +38,7 @@ using skyscraper8.DvbI; using skyscraper8.DvbNip; using skyscraper8.Experimentals.NdsSsu; using skyscraper8.Ietf.FLUTE; +using skyscraper8.InteractionChannel.Model2; using skyscraper8.Ses; using skyscraper8.SimpleServiceDiscoveryProtocol; using skyscraper8.Skyscraper.Drawing; @@ -1176,6 +1177,16 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem throw new NotImplementedException(); } + public bool TestForBroadcastConfiguration(ushort networkId, byte txTypeTxType) + { + throw new NotImplementedException(); + } + + public void InsertBroadcastConfiguration(ushort networkId, Bct.BroadcastConfiguration txType) + { + throw new NotImplementedException(); + } + public IEnumerable> SelectAllPmt() { throw new NotImplementedException(); diff --git a/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs index cbb1783..d5dbfde 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs @@ -38,6 +38,7 @@ using System.Net; using System.Net.NetworkInformation; using skyscraper5.src.InteractionChannel.Model2; using skyscraper8.Ietf.FLUTE; +using skyscraper8.InteractionChannel.Model2; using skyscraper8.Skyscraper.Scraper.Storage; using skyscraper8.Skyscraper.Scraper.Storage.Utilities; using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform; @@ -1005,6 +1006,25 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory _fct2Frames.Add(key, frame); } + private Dictionary, Bct.BroadcastConfiguration> broadcastConfigurations; + public bool TestForBroadcastConfiguration(ushort networkId, byte txTypeTxType) + { + if (broadcastConfigurations == null) + return false; + + Tuple key = new Tuple(networkId, txTypeTxType); + return broadcastConfigurations.ContainsKey(key); + } + + public void InsertBroadcastConfiguration(ushort networkId, Bct.BroadcastConfiguration txType) + { + if (broadcastConfigurations == null) + broadcastConfigurations = new Dictionary, Bct.BroadcastConfiguration>(); + + Tuple key = new Tuple(networkId, txType.TxType); + broadcastConfigurations.Add(key, txType); + } + public IEnumerable> SelectAllPmt() { for (int x = 0; x < pmtEntries.Length; x++) diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs index 761ae6b..f341f06 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs @@ -12,6 +12,7 @@ using System.Net.NetworkInformation; using System.Text; using System.Threading.Tasks; using skyscraper5.src.InteractionChannel.Model2; +using skyscraper8.InteractionChannel.Model2; namespace skyscraper5.src.Skyscraper.Scraper.StreamAutodetection.Contestants { @@ -193,9 +194,28 @@ namespace skyscraper5.src.Skyscraper.Scraper.StreamAutodetection.Contestants } } + public void OnFrameComposition2(ushort networkId, Fct2 fct2) + { + if (fct2.FrameTypes.Length > 0) + { + Score++; + } + } + + public void OnBroadcastConfiguration(ushort networkId, Bct bct) + { + if (bct.TxTypes.Length > 0) + { + Score++; + } + } + public void OnFrameComposition2(ushort? networkId, Fct2 fct2) { - throw new NotImplementedException(); + if (fct2.FrameTypes.Length > 0) + { + Score++; + } } } }