From 5d0da389a62b73f7880eb2702a250055392d99ca Mon Sep 17 00:00:00 2001 From: feyris-tan <4116042+feyris-tan@users.noreply.github.com> Date: Wed, 18 Mar 2026 20:30:13 +0100 Subject: [PATCH] Fixed a logic bug in RCS2 Handling that would cause the NetworkId in RMT to be always 0 when carried via GSE. --- skyscraper8/GS/GSE-BFBS/GseL2SHandler.cs | 2 +- skyscraper8/InteractionChannel/Model/Rmt.cs | 6 +- .../Scraper/ISkyscraperUiJunction.cs | 5 +- .../Skyscraper/Scraper/SkyscraperContext.cs | 32 ++++----- .../Skyscraper/Scraper/SkyscraperUiFeature.cs | 3 +- .../Skyscraper/Scraper/Storage/DataStorage.cs | 14 ++-- .../Storage/Filesystem/FilesystemStorage.cs | 30 +++----- .../InMemory/InMemoryScraperStorage.cs | 70 ++++++------------- 8 files changed, 65 insertions(+), 97 deletions(-) diff --git a/skyscraper8/GS/GSE-BFBS/GseL2SHandler.cs b/skyscraper8/GS/GSE-BFBS/GseL2SHandler.cs index 6f3278b..19b0821 100644 --- a/skyscraper8/GS/GSE-BFBS/GseL2SHandler.cs +++ b/skyscraper8/GS/GSE-BFBS/GseL2SHandler.cs @@ -46,7 +46,7 @@ namespace skyscraper8.GS.GSE_BFBS Context.Rcs2Output.OnRcs2Nit(gseTableStructure.InteractiveNetworkId, nit); return; case 0x41: - Rmt rmt = new Rmt(ms, true); + Rmt rmt = new Rmt(ms, true, gseTableStructure.InteractiveNetworkId); if (!rmt.Valid) { Context.Rcs2Output.OnInteractionChannelError(InteractionChannelErrorState.RmtInvalid); diff --git a/skyscraper8/InteractionChannel/Model/Rmt.cs b/skyscraper8/InteractionChannel/Model/Rmt.cs index c357df6..39c4ee3 100644 --- a/skyscraper8/InteractionChannel/Model/Rmt.cs +++ b/skyscraper8/InteractionChannel/Model/Rmt.cs @@ -16,7 +16,7 @@ namespace skyscraper5.src.InteractionChannel.Model { private static TsDescriptorUnpacker tsDescriptorUnpacker; - public Rmt(MemoryStream ms, bool gseMode = false) + public Rmt(MemoryStream ms, bool gseMode = false, ushort gseNetworkId = 0x0000) { if (tsDescriptorUnpacker == null) tsDescriptorUnpacker = TsDescriptorUnpacker.GetInstance(); @@ -60,6 +60,10 @@ namespace skyscraper5.src.InteractionChannel.Model byte sectionNumber = ms.ReadUInt8(); byte lastSectionNumber = ms.ReadUInt8(); } + else + { + NetworkId = gseNetworkId; + } byte byteC = ms.ReadUInt8(); int reservedFutureUseB = (byteC & 0xf0) >> 4; diff --git a/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs b/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs index ec504c8..a5ec85a 100644 --- a/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs +++ b/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs @@ -17,6 +17,7 @@ using skyscraper5.Scte35; using skyscraper5.Skyscraper.Equipment; using skyscraper5.Skyscraper.IO.CrazycatStreamReader; using skyscraper5.Skyscraper.Net; +using skyscraper5.src.InteractionChannel.Model; using skyscraper5.src.Skyscraper.FrequencyListGenerator; using skyscraper5.T2MI.Packets; using skyscraper5.Teletext.Wss; @@ -231,6 +232,6 @@ namespace skyscraper5.Skyscraper.Scraper void OnDvbSisPmt(int sourcePid, SisPmtContainer pmtContainer); void OnDvbSisNit(int sourcePid, SisNitContainer nitContainer); void OnDvbSisTdt(int sourcePid, DateTime? utcTime); - - } + void OnRcs2Rmt(Rmt rmt); + } } diff --git a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs index 960fec5..bd8578f 100644 --- a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs +++ b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs @@ -2428,28 +2428,20 @@ namespace skyscraper5.Skyscraper.Scraper public void OnRcsMap(Rmt rmt) { - if (rmt.Linkages != null) + UiJunction?.EnableUiFeature(SkyscraperUiFeature.RcsAnalysis); + UiJunction?.OnRcs2Rmt(rmt); + if (!DataStorage.TestForRmt(rmt)) { - foreach(_0x4a_LinkageDescriptor linkage in rmt.Linkages) - { - if (!DataStorage.TestForRmtLinkage(linkage)) - { - LogEvent(SkyscraperContextEvent.RmtLinkage, String.Format("Interactive Network #{0} -> ONID {1}, TSID {2}", linkage.InteractiveNetworkId, linkage.OriginalNetworkId, linkage.TransportStreamId)); - DataStorage.InsertRmtLinkage(linkage); - } - } - } - if (rmt.TransportStreams != null) - { - foreach(Rmt.TransportStream transportStream in rmt.TransportStreams) - { - if (!DataStorage.TestForRmtTransportStream(rmt.NetworkId, transportStream)) - { - LogEvent(SkyscraperContextEvent.RmtTransportStream, String.Format("{0} -> {1},{2}", rmt.NetworkId, transportStream.OriginalNetworkId, transportStream.TransportStreamId)); - DataStorage.InsertRmtTransportStream(rmt.NetworkId, transportStream); - } + DataStorage.InsertRmt(rmt); + foreach (_0x4a_LinkageDescriptor linkage in rmt.Linkages) + { + LogEvent(SkyscraperContextEvent.RmtLinkage, String.Format("Interactive Network #{0} -> ONID {1}, TSID {2}", linkage.InteractiveNetworkId, linkage.OriginalNetworkId, linkage.TransportStreamId)); } - } + foreach (Rmt.TransportStream transportStream in rmt.TransportStreams) + { + LogEvent(SkyscraperContextEvent.RmtTransportStream, String.Format("{0} -> {1},{2}", rmt.NetworkId, transportStream.OriginalNetworkId, transportStream.TransportStreamId)); + } + } } private void CheckForHiddenMpes() diff --git a/skyscraper8/Skyscraper/Scraper/SkyscraperUiFeature.cs b/skyscraper8/Skyscraper/Scraper/SkyscraperUiFeature.cs index 6731d45..4644621 100644 --- a/skyscraper8/Skyscraper/Scraper/SkyscraperUiFeature.cs +++ b/skyscraper8/Skyscraper/Scraper/SkyscraperUiFeature.cs @@ -13,6 +13,7 @@ namespace skyscraper8.Skyscraper.Scraper BlockstreamAnalysis, IpTrafficAnalysis, GseAnalysis, - DvbNipAnalyis + DvbNipAnalyis, + RcsAnalysis } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs index eb90b9f..d21bea9 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs @@ -137,14 +137,16 @@ namespace skyscraper8.Skyscraper.Scraper.Storage void StoreTerminalBurstTimePlan(ushort interactiveNetworkId, uint gtoupId, uint superframeCount, uint frameNumber, Tbtp.TbtpFrame.BtpEntity btp); bool TestForCmtEntry(ushort interactiveNetworkId, Cmt.CmtEntry entry); void InsertCmtEntry(ushort interactiveNetworkId, Cmt.CmtEntry entry); + + /// + /// Supposed to figure out the Transmission Standard from a stored RMT. + /// + /// The RCS Network ID to figure out the Transmission Standard for + /// 0 if the transmission standard is unknown or couldn't be figured out for any reason. Otherwise according to spec int GetRmtTransmissionStandard(ushort networkId); byte[] GetTmst(ushort interactiveNetworkId); void InsertTmst(ushort interactiveNetworkId, byte[] modes); void UpdateTmst(ushort interactiveNetworkId, byte[] modes); - bool TestForRmtLinkage(_0x4a_LinkageDescriptor linkage); - void InsertRmtLinkage(_0x4a_LinkageDescriptor linkage); - bool TestForRmtTransportStream(ushort networkId, Rmt.TransportStream transportStream); - void InsertRmtTransportStream(ushort networkId, Rmt.TransportStream transportStream); bool TestForSuperframeComposition(ushort interactiveNetworkId, Sct.Superframe superframe); void StoreSuperframeComposition(ushort interactiveNetworkId, Sct.Superframe superframe); bool TestForFrameComposition(ushort interactiveNetworkId, Fct.Frame frame); @@ -224,5 +226,7 @@ namespace skyscraper8.Skyscraper.Scraper.Storage void InsertTimLogonResponse(PhysicalAddress macAddress, _0xb9_LogonResponseDescriptor descriptor); bool TestForTimForwardInteractionPath(PhysicalAddress macAddress, _0xad_ForwardInteractionPathDescriptor.ForwardInteractionPath forwardInteractionPath); void InsertTimForwardInteractionPath(PhysicalAddress macAddress, _0xad_ForwardInteractionPathDescriptor.ForwardInteractionPath forwardInteractionPath); - } + bool TestForRmt(Rmt rmt); + void InsertRmt(Rmt rmt); + } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs index 4d2179f..855d56d 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs @@ -1484,26 +1484,6 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem throw new NotImplementedException(); } - public bool TestForRmtLinkage(_0x4a_LinkageDescriptor linkage) - { - throw new NotImplementedException(); - } - - public void InsertRmtLinkage(_0x4a_LinkageDescriptor linkage) - { - throw new NotImplementedException(); - } - - public bool TestForRmtTransportStream(ushort networkId, Rmt.TransportStream transportStream) - { - throw new NotImplementedException(); - } - - public void InsertRmtTransportStream(ushort networkId, Rmt.TransportStream transportStream) - { - throw new NotImplementedException(); - } - public bool TestForSuperframeComposition(ushort interactiveNetworkId, Sct.Superframe superframe) { throw new NotImplementedException(); @@ -2028,5 +2008,15 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem FileInfo fi = new FileInfo(saneFilename); return File.ReadAllBytes(fi.FullName); } + + public bool TestForRmt(Rmt rmt) + { + throw new NotImplementedException(); + } + + public void InsertRmt(Rmt rmt) + { + throw new NotImplementedException(); + } } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs index 6e8de88..4a11694 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs @@ -1446,20 +1446,21 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory cmtEntries[interactiveNetworkId].Add(entry); } - private bool rmtWasSeen; public int GetRmtTransmissionStandard(ushort networkId) { - if (!rmtWasSeen) + if (rmts == null) return 0; - if (_rmtTransportStreams[networkId] == null) + if (rmts[networkId] == null) return 0; - HashSet rmtSet = _rmtTransportStreams[networkId]; - foreach (Rmt.TransportStream transportStream in rmtSet) + if (rmts[networkId].TransportStreams == null) + return 0; + + foreach(Rmt.TransportStream ts in rmts[networkId].TransportStreams) { - if (transportStream.SatelliteForwardLink != null) - return (int)transportStream.SatelliteForwardLink.TransmissionStandard; + if (ts.SatelliteForwardLink != null) + return (int)ts.SatelliteForwardLink.TransmissionStandard; } return 0; @@ -1487,46 +1488,6 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory throw new NotImplementedException(); } - private HashSet<_0x4a_LinkageDescriptor> _rmtLinkages; - public bool TestForRmtLinkage(_0x4a_LinkageDescriptor linkage) - { - if (_rmtLinkages == null) - return false; - - return _rmtLinkages.Contains(linkage); - } - - public void InsertRmtLinkage(_0x4a_LinkageDescriptor linkage) - { - if (_rmtLinkages == null) - _rmtLinkages = new HashSet<_0x4a_LinkageDescriptor>(); - - _rmtLinkages.Add(linkage); - } - - private HashSet[] _rmtTransportStreams; - public bool TestForRmtTransportStream(ushort networkId, Rmt.TransportStream transportStream) - { - if (_rmtTransportStreams == null) - return false; - if (_rmtTransportStreams[networkId] == null) - return false; - - return _rmtTransportStreams[networkId].Contains(transportStream); - } - - public void InsertRmtTransportStream(ushort networkId, Rmt.TransportStream transportStream) - { - if (_rmtTransportStreams == null) - _rmtTransportStreams = new HashSet[ushort.MaxValue]; - if (_rmtTransportStreams[networkId] == null) - _rmtTransportStreams[networkId] = new HashSet(); - - _rmtTransportStreams[networkId].Add(transportStream); - if (transportStream.SatelliteForwardLink != null) - rmtWasSeen = true; - } - private HashSet[] _sctSuperframes; public bool TestForSuperframeComposition(ushort interactiveNetworkId, Sct.Superframe superframe) { @@ -2137,5 +2098,20 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory _dvbiServices.Add(service); } + + private Rmt[] rmts; + public bool TestForRmt(Rmt rmt) + { + if (rmts == null) + return false; + return rmts[rmt.NetworkId] != null; + } + + public void InsertRmt(Rmt rmt) + { + if (rmts == null) + rmts = new Rmt[ushort.MaxValue]; + rmts[ushort.MaxValue] = rmt; + } } }