From a7b89f2facebee2127717c280dc01273c70c504e Mon Sep 17 00:00:00 2001 From: feyris-tan <4116042+feyris-tan@users.noreply.github.com> Date: Sun, 22 Mar 2026 21:52:14 +0100 Subject: [PATCH] Patches for passing RCS2 data to the UI. --- .../InteractionChannelHandler.cs | 2 +- .../InteractionChannelPsiGatherer.cs | 7 +- skyscraper8/InteractionChannel/Model/Spt.cs | 21 +++++ .../_0xb7_FramePayloadFormatDescriptor.cs | 2 +- .../NullInteractionChannelHandler.cs | 2 +- .../Descriptors/UserDefinedDescriptor.cs | 5 ++ .../Mpeg2/Psi/Model/ProgramMappingStream.cs | 4 + skyscraper8/Properties/launchSettings.json | 1 - skyscraper8/Skyscraper/Math/Geodesy.cs | 47 ++++++++++ .../Math/SpatialReferenceWithHeight.cs | 35 ++++++++ .../Scraper/ISkyscraperUiJunction.cs | 14 +++ .../Skyscraper/Scraper/SkyscraperContext.cs | 88 ++++++++++++++++--- .../InteractionChannelContestant.cs | 2 +- 13 files changed, 210 insertions(+), 20 deletions(-) create mode 100644 skyscraper8/Skyscraper/Math/Geodesy.cs create mode 100644 skyscraper8/Skyscraper/Math/SpatialReferenceWithHeight.cs diff --git a/skyscraper8/InteractionChannel/InteractionChannelHandler.cs b/skyscraper8/InteractionChannel/InteractionChannelHandler.cs index 1f95fbc..9328a85 100644 --- a/skyscraper8/InteractionChannel/InteractionChannelHandler.cs +++ b/skyscraper8/InteractionChannel/InteractionChannelHandler.cs @@ -33,6 +33,6 @@ namespace skyscraper5.src.InteractionChannel void OnRcs2Nit(ushort interactiveNetworkId, RcsNit nit); void OnRcs2Tdt(ushort interactiveNetworkId, Rcs2Tdt tdt); void OnTransmissionModeSupport2(ushort interactiveNetworkId, Tmst2 tmst2); - void OnTerminalInformationMessage(ushort interactiveNetworkId, PhysicalAddress physicalAddress, Tim tim); + void OnTerminalInformationMessage(ushort? interactiveNetworkId, PhysicalAddress physicalAddress, Tim tim); } } diff --git a/skyscraper8/InteractionChannel/InteractionChannelPsiGatherer.cs b/skyscraper8/InteractionChannel/InteractionChannelPsiGatherer.cs index e385dfe..83692f0 100644 --- a/skyscraper8/InteractionChannel/InteractionChannelPsiGatherer.cs +++ b/skyscraper8/InteractionChannel/InteractionChannelPsiGatherer.cs @@ -280,11 +280,8 @@ namespace skyscraper5.src.InteractionChannel _handler.OnInteractionChannelError(InteractionChannelErrorState.TimInvalid); return; } - if (!NetworkId.HasValue) - { - return; - } - _handler.OnTerminalInformationMessage(NetworkId.Value, timHeader.MacAddress, tim); + + _handler.OnTerminalInformationMessage(NetworkId, timHeader.MacAddress, tim); return; case 0xB1: //LL_FEC_parity_data_table throw new NotImplementedException("LL_FEC_parity_data_table"); diff --git a/skyscraper8/InteractionChannel/Model/Spt.cs b/skyscraper8/InteractionChannel/Model/Spt.cs index 78423d5..10c102e 100644 --- a/skyscraper8/InteractionChannel/Model/Spt.cs +++ b/skyscraper8/InteractionChannel/Model/Spt.cs @@ -30,6 +30,27 @@ namespace skyscraper5.src.InteractionChannel.Model public Satellite[] Satellites { get; } public class Satellite { + public Satellite() + { + + } + + public Satellite(byte id, uint x, uint y, uint z) + { + Id = id; + X = x; + Y = y; + Z = z; + } + + public Satellite(Satellite copy) + { + Id = copy.Id; + X = copy.X; + Y = copy.Y; + Z = copy.Z; + } + public byte Id { get; internal set; } public uint X { get; internal set; } public uint Y { get; internal set; } diff --git a/skyscraper8/InteractionChannel/Model2/Descriptors/_0xb7_FramePayloadFormatDescriptor.cs b/skyscraper8/InteractionChannel/Model2/Descriptors/_0xb7_FramePayloadFormatDescriptor.cs index 511ed15..da991bc 100644 --- a/skyscraper8/InteractionChannel/Model2/Descriptors/_0xb7_FramePayloadFormatDescriptor.cs +++ b/skyscraper8/InteractionChannel/Model2/Descriptors/_0xb7_FramePayloadFormatDescriptor.cs @@ -111,6 +111,6 @@ public class _0xb7_FramePayloadFormatDescriptor : TsDescriptor public override string ToString() { - return String.Format("{0} Frame Payload Formats", Contexts); + return String.Format("{0} Frame Payload Formats", Contexts.Length); } } diff --git a/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs b/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs index 2e94dec..142ed83 100644 --- a/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs +++ b/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs @@ -69,7 +69,7 @@ namespace skyscraper5.src.InteractionChannel { } - public void OnTerminalInformationMessage(ushort interactiveNetworkId, PhysicalAddress physicalAddress, Tim tim) + public void OnTerminalInformationMessage(ushort? interactiveNetworkId, PhysicalAddress physicalAddress, Tim tim) { } diff --git a/skyscraper8/Mpeg2/Descriptors/UserDefinedDescriptor.cs b/skyscraper8/Mpeg2/Descriptors/UserDefinedDescriptor.cs index 1b46b55..22ff7da 100644 --- a/skyscraper8/Mpeg2/Descriptors/UserDefinedDescriptor.cs +++ b/skyscraper8/Mpeg2/Descriptors/UserDefinedDescriptor.cs @@ -39,5 +39,10 @@ namespace skyscraper5.Mpeg2.Descriptors } return true; } + + public override string ToString() + { + return String.Format("Unknown user defined descriptor: 0x{0:X2} ({1} bytes long)", DescriptorTag, Data.Length); + } } } diff --git a/skyscraper8/Mpeg2/Psi/Model/ProgramMappingStream.cs b/skyscraper8/Mpeg2/Psi/Model/ProgramMappingStream.cs index ed81701..ef46d7a 100644 --- a/skyscraper8/Mpeg2/Psi/Model/ProgramMappingStream.cs +++ b/skyscraper8/Mpeg2/Psi/Model/ProgramMappingStream.cs @@ -275,6 +275,10 @@ namespace skyscraper5.Mpeg2.Psi.Model case 0xb1: case 0xb2: continue; + case 0xe4: + case 0xc0: + //User defined, but should be okay. + continue; default: return false; } diff --git a/skyscraper8/Properties/launchSettings.json b/skyscraper8/Properties/launchSettings.json index 2c74556..6513d14 100644 --- a/skyscraper8/Properties/launchSettings.json +++ b/skyscraper8/Properties/launchSettings.json @@ -2,7 +2,6 @@ "profiles": { "skyscraper8": { "commandName": "Project", - "commandLineArgs": "\"C:\\devel\\skyscraper8-testsuite\\cosmo_dsmcc.ts\"", "remoteDebugEnabled": false }, "Container (Dockerfile)": { diff --git a/skyscraper8/Skyscraper/Math/Geodesy.cs b/skyscraper8/Skyscraper/Math/Geodesy.cs new file mode 100644 index 0000000..6f10cb4 --- /dev/null +++ b/skyscraper8/Skyscraper/Math/Geodesy.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Skyscraper.Math +{ + public static class Geodesy + { + const double a = 6378137.0; // WGS84 semi-major axis + const double f = 1.0 / 298.257223563; // WGS84 flattening + const double e2 = 2 * f - f * f; // WGS84eccentricity squared + + public static SpatialReferenceWithHeight EcefToLla(double X, double Y, double Z) + { + // Longitude is straightforward + double lon = System.Math.Atan2(Y, X); + + // Distance from Z-axis + double p = System.Math.Sqrt(X * X + Y * Y); + + // Initial latitude estimate + double lat = System.Math.Atan2(Z, p * (1 - e2)); + + // Iterate to improve latitude + for (int i = 0; i < 10; i++) + { + double sinLat = System.Math.Sin(lat); + double N = a / System.Math.Sqrt(1 - e2 * sinLat * sinLat); + lat = System.Math.Atan2(Z + e2 * N * sinLat, p); + } + + // Compute height + double sinLatFinal = System.Math.Sin(lat); + double Nfinal = a / System.Math.Sqrt(1 - e2 * sinLatFinal * sinLatFinal); + double h = p / System.Math.Cos(lat) - Nfinal; + + // Convert radians → degrees + double latDeg = lat * 180.0 / System.Math.PI; + double lonDeg = lon * 180.0 / System.Math.PI; + + SpatialReferenceWithHeight spatialReferenceWithHeight = new SpatialReferenceWithHeight(latDeg, lonDeg, h); + return spatialReferenceWithHeight; + } + } +} diff --git a/skyscraper8/Skyscraper/Math/SpatialReferenceWithHeight.cs b/skyscraper8/Skyscraper/Math/SpatialReferenceWithHeight.cs new file mode 100644 index 0000000..2aa77ca --- /dev/null +++ b/skyscraper8/Skyscraper/Math/SpatialReferenceWithHeight.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Skyscraper.Math +{ + public struct SpatialReferenceWithHeight + { + public SpatialReferenceWithHeight(double latitude, double longitude, double height) + { + Latitude = latitude; + Longitude = longitude; + Height = height; + } + + public double Latitude { get; set; } + public double Longitude { get; set; } + public double Height { get; set; } + + public override bool Equals(object? obj) + { + return obj is SpatialReferenceWithHeight height && + Latitude == height.Latitude && + Longitude == height.Longitude && + Height == height.Height; + } + + public override int GetHashCode() + { + return HashCode.Combine(Latitude, Longitude, Height); + } + } +} diff --git a/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs b/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs index a5ec85a..84e115b 100644 --- a/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs +++ b/skyscraper8/Skyscraper/Scraper/ISkyscraperUiJunction.cs @@ -18,6 +18,7 @@ using skyscraper5.Skyscraper.Equipment; using skyscraper5.Skyscraper.IO.CrazycatStreamReader; using skyscraper5.Skyscraper.Net; using skyscraper5.src.InteractionChannel.Model; +using skyscraper5.src.InteractionChannel.Model2; using skyscraper5.src.Skyscraper.FrequencyListGenerator; using skyscraper5.T2MI.Packets; using skyscraper5.Teletext.Wss; @@ -27,6 +28,8 @@ using skyscraper8.DvbSis; using skyscraper8.GSE; using skyscraper8.GSE.GSE; using skyscraper8.Ietf.FLUTE; +using skyscraper8.InteractionChannel.Model; +using skyscraper8.InteractionChannel.Model2; using skyscraper8.Ses; using skyscraper8.Skyscraper.Drawing; using skyscraper8.Skyscraper.FrequencyListGenerator; @@ -233,5 +236,16 @@ namespace skyscraper5.Skyscraper.Scraper void OnDvbSisNit(int sourcePid, SisNitContainer nitContainer); void OnDvbSisTdt(int sourcePid, DateTime? utcTime); void OnRcs2Rmt(Rmt rmt); + void OnRcs2Tmst(ushort networkId, Tmst tmst); + void OnRcs2Tmst2(ushort interactiveNetworkId, Tmst2 tmst2); + void OnRcs2Tdt(ushort interactiveNetworkId, Rcs2Tdt tdt); + void OnRcs2Nit(ushort interactiveNetworkId, RcsNit nit); + void OnRcs2Bct(ushort networkId, Bct bct); + void OnRcs2Fct2(ushort networkId, Fct2 fct2); + void OnRcs2Tbtp2(ushort interactiveNetworkId, Tbtp2 tbtp2); + void OnRcs2Tct(ushort interactiveNetworkId, Tct tct); + void OnRcs2Tbtp(ushort interactiveNetworkId, Tbtp tbtp); + void OnRcs2Sct(ushort interactiveNetworkId, Sct sct); + void OnRcs2Spt(ushort interactiveNetworkId, Spt spt); } } diff --git a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs index dcbfd50..2a6a716 100644 --- a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs +++ b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs @@ -2389,7 +2389,9 @@ namespace skyscraper5.Skyscraper.Scraper void InteractionChannelHandler.OnCorrectionMessage(ushort interactiveNetworkId, Cmt cmt) { - foreach(Cmt.CmtEntry entry in cmt.Entries) + SetLikelyNetwork(interactiveNetworkId); + + foreach (Cmt.CmtEntry entry in cmt.Entries) { if (!DataStorage.TestForCmtEntry(interactiveNetworkId,entry)) { @@ -2401,7 +2403,9 @@ namespace skyscraper5.Skyscraper.Scraper void InteractionChannelHandler.OnFrameComposition(ushort interactiveNetworkId, Fct fct) { - foreach(Fct.Frame frame in fct.Frames) + SetLikelyNetwork(interactiveNetworkId); + + foreach (Fct.Frame frame in fct.Frames) { if (!DataStorage.TestForFrameComposition(interactiveNetworkId,frame)) { @@ -2428,8 +2432,16 @@ namespace skyscraper5.Skyscraper.Scraper public void OnRcsMap(Rmt rmt) { - UiJunction?.EnableUiFeature(SkyscraperUiFeature.RcsAnalysis); + if (rmt.Linkages != null) + { + if (rmt.Linkages.Count > 0) + { + SetLikelyNetwork(rmt.Linkages[0].InteractiveNetworkId); + } + } + UiJunction?.EnableUiFeature(SkyscraperUiFeature.RcsAnalysis); UiJunction?.OnRcs2Rmt(rmt); + if (!DataStorage.TestForRmt(rmt)) { DataStorage.InsertRmt(rmt); @@ -2473,7 +2485,10 @@ namespace skyscraper5.Skyscraper.Scraper public void OnSatellitePosition(ushort interactiveNetworkId, Spt spt) { - foreach (Spt.Satellite satellite in spt.Satellites) + SetLikelyNetwork(interactiveNetworkId); + UiJunction?.OnRcs2Spt(interactiveNetworkId, spt); + + foreach (Spt.Satellite satellite in spt.Satellites) { if (!DataStorage.TestForSatellitePosition(interactiveNetworkId,satellite)) { @@ -2485,7 +2500,10 @@ namespace skyscraper5.Skyscraper.Scraper void InteractionChannelHandler.OnSuperframeComposition(ushort interactiveNetworkId, Sct sct) { - foreach(Sct.Superframe superframe in sct.Superframes) + SetLikelyNetwork(interactiveNetworkId); + UiJunction?.OnRcs2Sct(interactiveNetworkId, sct); + + foreach (Sct.Superframe superframe in sct.Superframes) { if (!DataStorage.TestForSuperframeComposition(interactiveNetworkId,superframe)) { @@ -2497,7 +2515,10 @@ namespace skyscraper5.Skyscraper.Scraper void InteractionChannelHandler.OnTerminalBurstTimePlan(ushort interactiveNetworkId, Tbtp tbtp) { - foreach (Tbtp.TbtpFrame frame in tbtp.Frames) + SetLikelyNetwork(interactiveNetworkId); + UiJunction?.OnRcs2Tbtp(interactiveNetworkId, tbtp); + + foreach (Tbtp.TbtpFrame frame in tbtp.Frames) { foreach (Tbtp.TbtpFrame.BtpEntity btp in frame.BTP) { @@ -2512,11 +2533,17 @@ namespace skyscraper5.Skyscraper.Scraper public void OnTimeslotComposition(ushort interactiveNetworkId, Tct tct) { - throw new NotImplementedException(); + SetLikelyNetwork(interactiveNetworkId); + UiJunction?.OnRcs2Tct(interactiveNetworkId, tct); + + throw new NotImplementedException(); } public void OnTerminalBurstTimePlan2(ushort interactiveNetworkId, Tbtp2 tbtp2) { + SetLikelyNetwork(interactiveNetworkId); + UiJunction?.OnRcs2Tbtp2(interactiveNetworkId, tbtp2); + foreach (Tbtp2.Frame frame in tbtp2.Frames) { for (int assignmentOrdinal = 0; assignmentOrdinal < frame.Assignments.Length; assignmentOrdinal++) @@ -2533,6 +2560,9 @@ namespace skyscraper5.Skyscraper.Scraper public void OnFrameComposition2(ushort networkId, Fct2 fct2) { + SetLikelyNetwork(networkId); + UiJunction?.OnRcs2Fct2(networkId, fct2); + foreach (Fct2.Frame frame in fct2.FrameTypes) { if (!DataStorage.TestForFrameComposition2(networkId, frame)) @@ -2545,6 +2575,9 @@ namespace skyscraper5.Skyscraper.Scraper public void OnBroadcastConfiguration(ushort networkId, Bct bct) { + SetLikelyNetwork(networkId); + UiJunction?.OnRcs2Bct(networkId, bct); + foreach (Bct.BroadcastConfiguration txType in bct.TxTypes) { if (!DataStorage.TestForBroadcastConfiguration(networkId, txType.TxType)) @@ -2557,6 +2590,9 @@ namespace skyscraper5.Skyscraper.Scraper public void OnRcs2Nit(ushort interactiveNetworkId, RcsNit nit) { + SetLikelyNetwork(interactiveNetworkId); + UiJunction?.OnRcs2Nit(interactiveNetworkId, nit); + if (!DataStorage.TestForRcs2Nit(nit)) { LogEvent(SkyscraperContextEvent.Rcs2Network, String.Format("Network ID #{0}, ({1}) on {2}", nit.OriginalNetworkId, nit.NetworkName, nit.SatelliteDeliverySystem.ToString())); @@ -2568,10 +2604,15 @@ namespace skyscraper5.Skyscraper.Scraper { LogEvent(SkyscraperContextEvent.Rcs2TdtTime, String.Format("Network ID #{0}, {1}", interactiveNetworkId, tdt.Timestamp)); DataStorage.UpdateRcs2Tdt(interactiveNetworkId, tdt.Timestamp); + SetLikelyNetwork(interactiveNetworkId); + UiJunction?.OnRcs2Tdt(interactiveNetworkId, tdt); } public void OnTransmissionModeSupport2(ushort interactiveNetworkId, Tmst2 tmst2) { + SetLikelyNetwork(interactiveNetworkId); + UiJunction?.OnRcs2Tmst2(interactiveNetworkId, tmst2); + foreach (Tmst2.TransmissionMode mode in tmst2.TransmissionModes) { if (!DataStorage.TestForTmst2(interactiveNetworkId, mode)) @@ -2584,6 +2625,9 @@ namespace skyscraper5.Skyscraper.Scraper void InteractionChannelHandler.OnTransmissionModeSupport(ushort interactiveNetworkId, Tmst tmst) { + SetLikelyNetwork(interactiveNetworkId); + UiJunction?.OnRcs2Tmst(interactiveNetworkId, tmst); + byte[] knownTmst = DataStorage.GetTmst(interactiveNetworkId); if (knownTmst == null) { @@ -3417,16 +3461,40 @@ namespace skyscraper5.Skyscraper.Scraper } } - public void OnTerminalInformationMessage(ushort interactiveNetworkId, PhysicalAddress physicalAddress, Tim currentTim) + private ushort lastKnownInteractiveNetworkId; + private int networkIdChanges; + + private void SetLikelyNetwork(ushort interactiveNetworkId) + { + if (lastKnownInteractiveNetworkId != interactiveNetworkId) + { + lastKnownInteractiveNetworkId = interactiveNetworkId; + networkIdChanges++; + } + } + + public void OnTerminalInformationMessage(ushort? interactiveNetworkId, PhysicalAddress physicalAddress, Tim currentTim) { - Tim lastTim = DataStorage.GetLastTim(interactiveNetworkId, physicalAddress); + if (!interactiveNetworkId.HasValue) + { + if (networkIdChanges != 1) + return; + + interactiveNetworkId = lastKnownInteractiveNetworkId; + } + else + { + SetLikelyNetwork(interactiveNetworkId.Value); + } + + Tim lastTim = DataStorage.GetLastTim(interactiveNetworkId.Value, physicalAddress); if (currentTim.Equals(lastTim)) { return; } - DataStorage.UpsertTim(interactiveNetworkId, physicalAddress, currentTim); + DataStorage.UpsertTim(interactiveNetworkId.Value, physicalAddress, currentTim); LogEvent(SkyscraperContextEvent.Tim, String.Format("Terminal Information Message for participant {0} on network {1}", physicalAddress, interactiveNetworkId)); foreach(TsDescriptor ts in currentTim.Descriptors) diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs index 5ab3756..0d270e7 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs @@ -205,7 +205,7 @@ namespace skyscraper5.src.Skyscraper.Scraper.StreamAutodetection.Contestants } } - public void OnTerminalInformationMessage(ushort interactiveNetworkId, PhysicalAddress physicalAddress, Tim tim) + public void OnTerminalInformationMessage(ushort? interactiveNetworkId, PhysicalAddress physicalAddress, Tim tim) { foreach(TsDescriptor tsDescriptor in tim.Descriptors) {