From 30026b2b02d414a0333beaaf12bdd6a1c40e528b Mon Sep 17 00:00:00 2001
From: feyris-tan <4116042+feyris-tan@users.noreply.github.com>
Date: Sun, 23 Nov 2025 00:27:00 +0100
Subject: [PATCH] Added functionality necessary to extract the MPEG-DASH
segments on the Arsat stream.
---
skyscraper8.Tests/Feyllure.cs | 6 +-
.../Properties/Resources.Designer.cs | 63 +++++
skyscraper8.Tests/Properties/Resources.resx | 101 +++++++
.../ResourceTests/DocsisTests.cs | 4 +-
.../ResourceTests/GsType1SanityTest.cs | 3 +
skyscraper8.Tests/ResourceTests/SdpTest.cs | 25 ++
.../ResourceTests/SkyscraperTests.cs | 4 +-
skyscraper8.Tests/Resources/sdpTest.sdp | 10 +
skyscraper8.Tests/Resources1.Designer.cs | 250 +++++++++++-------
skyscraper8.Tests/Resources1.resx | 143 ++++++++--
skyscraper8.Tests/RootTests/DocsisTests.cs | 33 +--
skyscraper8.Tests/RootTests/Mpeg2Tests.cs | 1 +
skyscraper8.Tests/skyscraper8.Tests.csproj | 47 ++++
skyscraper8.sln | 10 +-
skyscraper8.sln.DotSettings.user | 8 +-
skyscraper8/DvbNip/DvbNipReceiver.cs | 131 ++++++---
skyscraper8/DvbNip/DvbNipUtilities.cs | 79 ++++++
.../DvbNip/NipActualCarrierInformation.cs | 9 +
skyscraper8/GS/POC/Pts2Bbf2.cs | 2 +-
skyscraper8/Ietf/FLUTE/FluteException.cs | 23 ++
skyscraper8/Ietf/FLUTE/FluteListener.cs | 7 +-
skyscraper8/Ietf/FLUTE/LctFrame.cs | 19 ++
skyscraper8/Ietf/FluteListenerMime.cs | 24 ++
skyscraper8/Ietf/Rfc4566_SDP/SDP.cs | 159 +++++++++++
.../Ietf/Rfc4566_SDP/SdpAddressType.cs | 14 +
skyscraper8/Ietf/Rfc4566_SDP/SdpAttributes.cs | 208 +++++++++++++++
.../Ietf/Rfc4566_SDP/SdpConnectionData.cs | 45 ++++
skyscraper8/Ietf/Rfc4566_SDP/SdpMedia.cs | 51 ++++
.../Ietf/Rfc4566_SDP/SdpNetworkType.cs | 13 +
skyscraper8/Ietf/Rfc4566_SDP/SdpOriginator.cs | 58 ++++
skyscraper8/Ietf/Rfc4566_SDP/SdpTimes.cs | 51 ++++
skyscraper8/Program.cs | 2 +
skyscraper8/Properties/launchSettings.json | 2 +-
skyscraper8/Skyscraper/DateTimeExtensions.cs | 2 +
skyscraper8/Skyscraper/IO/StreamExtensions.cs | 9 +
skyscraper8/Skyscraper/LongExtensions.cs | 38 +++
.../Skyscraper/Scraper/SkyscraperContext.cs | 32 ++-
.../Text/SkyscraperEncodingProvider.cs | 21 +-
skyscraper8/VersionInfo.cs | 2 +-
skyscraper8/skyscraper8.csproj | 1 +
40 files changed, 1511 insertions(+), 199 deletions(-)
create mode 100644 skyscraper8.Tests/Properties/Resources.Designer.cs
create mode 100644 skyscraper8.Tests/Properties/Resources.resx
create mode 100644 skyscraper8.Tests/ResourceTests/SdpTest.cs
create mode 100644 skyscraper8.Tests/Resources/sdpTest.sdp
create mode 100644 skyscraper8.Tests/skyscraper8.Tests.csproj
create mode 100644 skyscraper8/Ietf/FLUTE/FluteException.cs
create mode 100644 skyscraper8/Ietf/FluteListenerMime.cs
create mode 100644 skyscraper8/Ietf/Rfc4566_SDP/SDP.cs
create mode 100644 skyscraper8/Ietf/Rfc4566_SDP/SdpAddressType.cs
create mode 100644 skyscraper8/Ietf/Rfc4566_SDP/SdpAttributes.cs
create mode 100644 skyscraper8/Ietf/Rfc4566_SDP/SdpConnectionData.cs
create mode 100644 skyscraper8/Ietf/Rfc4566_SDP/SdpMedia.cs
create mode 100644 skyscraper8/Ietf/Rfc4566_SDP/SdpNetworkType.cs
create mode 100644 skyscraper8/Ietf/Rfc4566_SDP/SdpOriginator.cs
create mode 100644 skyscraper8/Ietf/Rfc4566_SDP/SdpTimes.cs
create mode 100644 skyscraper8/Skyscraper/LongExtensions.cs
diff --git a/skyscraper8.Tests/Feyllure.cs b/skyscraper8.Tests/Feyllure.cs
index 8a030e1..70c77a5 100644
--- a/skyscraper8.Tests/Feyllure.cs
+++ b/skyscraper8.Tests/Feyllure.cs
@@ -1,5 +1,9 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
using System.Runtime.InteropServices;
using Allure.Net.Commons;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestResult = Allure.Net.Commons.TestResult;
namespace skyscraper8.Tests;
@@ -28,7 +32,7 @@ public class Feyllure
writer.WriteLine($".NET={Environment.Version}");
writer.WriteLine($"Machine={Environment.MachineName}");
writer.WriteLine($"User={Environment.UserName}");
- writer.WriteLine($"Framework={context.Properties["TargetFramework"] ?? "net8.0"}");
+ writer.WriteLine($"Framework={System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription}");
writer.WriteLine($"BuildDate={DateTime.UtcNow:yyyy-MM-dd HH:mm:ss}");
}
diff --git a/skyscraper8.Tests/Properties/Resources.Designer.cs b/skyscraper8.Tests/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..8b7e9e7
--- /dev/null
+++ b/skyscraper8.Tests/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// Dieser Code wurde von einem Tool generiert.
+// Laufzeitversion:4.0.30319.42000
+//
+// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
+// der Code erneut generiert wird.
+//
+//------------------------------------------------------------------------------
+
+namespace skyscraper8.Tests.Properties {
+ using System;
+
+
+ ///
+ /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
+ ///
+ // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
+ // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
+ // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
+ // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("skyscraper8.Tests.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
+ /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/skyscraper8.Tests/Properties/Resources.resx b/skyscraper8.Tests/Properties/Resources.resx
new file mode 100644
index 0000000..4fdb1b6
--- /dev/null
+++ b/skyscraper8.Tests/Properties/Resources.resx
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/skyscraper8.Tests/ResourceTests/DocsisTests.cs b/skyscraper8.Tests/ResourceTests/DocsisTests.cs
index 220ea87..2b59e6b 100644
--- a/skyscraper8.Tests/ResourceTests/DocsisTests.cs
+++ b/skyscraper8.Tests/ResourceTests/DocsisTests.cs
@@ -1,7 +1,9 @@
-using skyscraper5.Docsis;
+using System;
+using skyscraper5.Docsis;
using skyscraper5.Docsis.AnnexC;
using skyscraper5.Docsis.MacManagement;
using System.Net.NetworkInformation;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace skyscraper8.Tests.ResourceTests
{
diff --git a/skyscraper8.Tests/ResourceTests/GsType1SanityTest.cs b/skyscraper8.Tests/ResourceTests/GsType1SanityTest.cs
index eb7c84d..d9b964a 100644
--- a/skyscraper8.Tests/ResourceTests/GsType1SanityTest.cs
+++ b/skyscraper8.Tests/ResourceTests/GsType1SanityTest.cs
@@ -1,3 +1,6 @@
+using System;
+using System.IO;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
using skyscraper5.Mpeg2;
namespace skyscraper8.Tests.ResourceTests;
diff --git a/skyscraper8.Tests/ResourceTests/SdpTest.cs b/skyscraper8.Tests/ResourceTests/SdpTest.cs
new file mode 100644
index 0000000..7aa47be
--- /dev/null
+++ b/skyscraper8.Tests/ResourceTests/SdpTest.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using skyscraper8.Ietf.Rfc4566_SDP;
+
+namespace skyscraper8.Tests.ResourceTests
+{
+ [TestClass]
+ public class SdpTest : Feyllure
+ {
+ [TestMethod]
+ public void TestSdpParser()
+ {
+ MemoryStream ms = new MemoryStream(Resources1.sdpTest, false);
+ Assert.IsTrue(SDP.IsSDP(ms));
+
+ SDP loaded = SDP.Load(ms);
+ Assert.IsNotNull(loaded);
+ }
+ }
+}
diff --git a/skyscraper8.Tests/ResourceTests/SkyscraperTests.cs b/skyscraper8.Tests/ResourceTests/SkyscraperTests.cs
index f4af5c7..5ae68a4 100644
--- a/skyscraper8.Tests/ResourceTests/SkyscraperTests.cs
+++ b/skyscraper8.Tests/ResourceTests/SkyscraperTests.cs
@@ -1,4 +1,6 @@
-using skyscraper5.Mpeg2;
+using System.IO;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using skyscraper5.Mpeg2;
using skyscraper5.Skyscraper.Scraper;
using skyscraper5.Skyscraper.Scraper.Storage.InMemory;
using skyscraper8.Skyscraper.Scraper.Storage;
diff --git a/skyscraper8.Tests/Resources/sdpTest.sdp b/skyscraper8.Tests/Resources/sdpTest.sdp
new file mode 100644
index 0000000..a44a8d4
--- /dev/null
+++ b/skyscraper8.Tests/Resources/sdpTest.sdp
@@ -0,0 +1,10 @@
+v=0
+o=enensys Announcement-BM-SC 3962468565 IN IP4 10.10.10.20
+s=Announcement delivery session
+t=0 0
+a=mbms-mode:broadcast-mbsfn 61712
+a=source-filter: incl IN IP4 * 10.10.10.20
+a=flute-tsi:9
+m=application 50001 FLUTE/UDP 0
+c=IN IP4 224.0.2.20/10
+b=AS:200
diff --git a/skyscraper8.Tests/Resources1.Designer.cs b/skyscraper8.Tests/Resources1.Designer.cs
index 5de37c6..de7a55d 100644
--- a/skyscraper8.Tests/Resources1.Designer.cs
+++ b/skyscraper8.Tests/Resources1.Designer.cs
@@ -1,9 +1,10 @@
-//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
//
-// This code was generated by a tool.
+// Dieser Code wurde von einem Tool generiert.
+// Laufzeitversion:4.0.30319.42000
//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
+// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
+// der Code erneut generiert wird.
//
//------------------------------------------------------------------------------
@@ -11,32 +12,46 @@ namespace skyscraper8.Tests {
using System;
- [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
- [System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ ///
+ /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
+ ///
+ // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
+ // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
+ // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
+ // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources1 {
- private static System.Resources.ResourceManager resourceMan;
+ private static global::System.Resources.ResourceManager resourceMan;
- private static System.Globalization.CultureInfo resourceCulture;
+ private static global::System.Globalization.CultureInfo resourceCulture;
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources1() {
}
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static System.Resources.ResourceManager ResourceManager {
+ ///
+ /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
get {
- if (object.Equals(null, resourceMan)) {
- System.Resources.ResourceManager temp = new System.Resources.ResourceManager("skyscraper8.Tests.Resources1", typeof(Resources1).Assembly);
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("skyscraper8.Tests.Resources1", typeof(Resources1).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
- [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static System.Globalization.CultureInfo Culture {
+ ///
+ /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
+ /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
@@ -45,83 +60,9 @@ namespace skyscraper8.Tests {
}
}
- internal static byte[] ModemCapabilitiesEncodingTest {
- get {
- object obj = ResourceManager.GetObject("ModemCapabilitiesEncodingTest", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- internal static byte[] MultipartRegistrationResponseTest {
- get {
- object obj = ResourceManager.GetObject("MultipartRegistrationResponseTest", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- internal static byte[] PushMacManagementMessage_Version4_Type45 {
- get {
- object obj = ResourceManager.GetObject("PushMacManagementMessage_Version4_Type45", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- internal static byte[] ranging_response_test {
- get {
- object obj = ResourceManager.GetObject("ranging_response_test", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- internal static byte[] MultipartRegistrationResponseTest2 {
- get {
- object obj = ResourceManager.GetObject("MultipartRegistrationResponseTest2", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- internal static byte[] test_1packet_01 {
- get {
- object obj = ResourceManager.GetObject("test-1packet-01", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- internal static byte[] test_2packets_02_03 {
- get {
- object obj = ResourceManager.GetObject("test-2packets-02-03", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- internal static byte[] test_3packets_04_05_06 {
- get {
- object obj = ResourceManager.GetObject("test-3packets-04-05-06", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- internal static byte[] TransmitChannelConfigurationObject {
- get {
- object obj = ResourceManager.GetObject("TransmitChannelConfigurationObject", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- internal static byte[] UpstreamChannelDescriptorTest {
- get {
- object obj = ResourceManager.GetObject("UpstreamChannelDescriptorTest", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
- internal static byte[] Frame00001343_TSGS1_MIS000_SYNC001 {
- get {
- object obj = ResourceManager.GetObject("Frame00001343_TSGS1_MIS000_SYNC001", resourceCulture);
- return ((byte[])(obj));
- }
- }
-
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
+ ///
internal static byte[] Frame00000008_TSGS1_MIS000_SYNC001 {
get {
object obj = ResourceManager.GetObject("Frame00000008_TSGS1_MIS000_SYNC001", resourceCulture);
@@ -129,11 +70,134 @@ namespace skyscraper8.Tests {
}
}
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
+ ///
internal static byte[] Frame00000012_TSGS1_MIS000_SYNC001 {
get {
object obj = ResourceManager.GetObject("Frame00000012_TSGS1_MIS000_SYNC001", resourceCulture);
return ((byte[])(obj));
}
}
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
+ ///
+ internal static byte[] Frame00001343_TSGS1_MIS000_SYNC001 {
+ get {
+ object obj = ResourceManager.GetObject("Frame00001343_TSGS1_MIS000_SYNC001", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
+ ///
+ internal static byte[] ModemCapabilitiesEncodingTest {
+ get {
+ object obj = ResourceManager.GetObject("ModemCapabilitiesEncodingTest", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
+ ///
+ internal static byte[] MultipartRegistrationResponseTest {
+ get {
+ object obj = ResourceManager.GetObject("MultipartRegistrationResponseTest", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
+ ///
+ internal static byte[] MultipartRegistrationResponseTest2 {
+ get {
+ object obj = ResourceManager.GetObject("MultipartRegistrationResponseTest2", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
+ ///
+ internal static byte[] PushMacManagementMessage_Version4_Type45 {
+ get {
+ object obj = ResourceManager.GetObject("PushMacManagementMessage_Version4_Type45", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
+ ///
+ internal static byte[] ranging_response_test {
+ get {
+ object obj = ResourceManager.GetObject("ranging_response_test", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
+ ///
+ internal static byte[] sdpTest {
+ get {
+ object obj = ResourceManager.GetObject("sdpTest", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
+ ///
+ internal static byte[] test_1packet_01 {
+ get {
+ object obj = ResourceManager.GetObject("test-1packet-01", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
+ ///
+ internal static byte[] test_2packets_02_03 {
+ get {
+ object obj = ResourceManager.GetObject("test-2packets-02-03", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
+ ///
+ internal static byte[] test_3packets_04_05_06 {
+ get {
+ object obj = ResourceManager.GetObject("test-3packets-04-05-06", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
+ ///
+ internal static byte[] TransmitChannelConfigurationObject {
+ get {
+ object obj = ResourceManager.GetObject("TransmitChannelConfigurationObject", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
+ ///
+ internal static byte[] UpstreamChannelDescriptorTest {
+ get {
+ object obj = ResourceManager.GetObject("UpstreamChannelDescriptorTest", resourceCulture);
+ return ((byte[])(obj));
+ }
+ }
}
}
diff --git a/skyscraper8.Tests/Resources1.resx b/skyscraper8.Tests/Resources1.resx
index 19bd9f7..906044f 100644
--- a/skyscraper8.Tests/Resources1.resx
+++ b/skyscraper8.Tests/Resources1.resx
@@ -1,24 +1,124 @@
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 1.3
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
Resources\ModemCapabilitiesEncodingTest.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
@@ -57,4 +157,7 @@
Resources\Frame00000012_TSGS1_MIS000_SYNC001.bbf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
+ Resources\sdpTest.sdp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/skyscraper8.Tests/RootTests/DocsisTests.cs b/skyscraper8.Tests/RootTests/DocsisTests.cs
index 27f6c48..3d83f90 100644
--- a/skyscraper8.Tests/RootTests/DocsisTests.cs
+++ b/skyscraper8.Tests/RootTests/DocsisTests.cs
@@ -1,4 +1,7 @@
+using System;
+using System.IO;
using System.Net.NetworkInformation;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
using skyscraper5.Docsis;
using skyscraper5.Docsis.AnnexC;
@@ -20,7 +23,7 @@ public class DocsisTests : Feyllure
RcpIdEncoding rie = new RcpIdEncoding(new byte[] { 7, 1, 0 });
SimplifiedReceiveChannelAssignmentEncoding simplifiedReceiveChannelAssignmentEncoding = rie.SimplifiedReceiveChannelConfiguration;
Assert.IsNotNull(simplifiedReceiveChannelAssignmentEncoding);
- Assert.ThrowsException(() => new RcpIdEncoding(new byte[] { 255, 1, 0 }));
+ Assert.Throws(() => new RcpIdEncoding(new byte[] { 255, 1, 0 }));
}
[TestMethod]
@@ -30,7 +33,7 @@ public class DocsisTests : Feyllure
ushort epceEProt = epce.EProt;
Assert.AreEqual(1, epce.EProt);
Assert.AreEqual(1, epce.Type);
- Assert.ThrowsException(() => new EthernetLlcPacketClassificationEncoding(new byte[] { 255, 1, 0 }));
+ Assert.Throws(() => new EthernetLlcPacketClassificationEncoding(new byte[] { 255, 1, 0 }));
}
[TestMethod]
@@ -41,7 +44,7 @@ public class DocsisTests : Feyllure
Assert.AreEqual(0,srcae.DownstreamChannelAssignment[0]);
Assert.AreEqual(0, srcae.DownstreamProfileAssignment[0]);
Assert.AreEqual(0, srcae.PrimaryDownstreamChannelAssignment[0]);
- Assert.ThrowsException(() => new SimplifiedReceiveChannelAssignmentEncoding(new byte[] { 254,0,1 }));
+ Assert.Throws(() => new SimplifiedReceiveChannelAssignmentEncoding(new byte[] { 254,0,1 }));
}
[TestMethod]
@@ -71,7 +74,7 @@ public class DocsisTests : Feyllure
Assert.AreEqual(0, tcco.P16Hi);
Assert.AreEqual(0, tcco.ListOfIucs[0]);
- Assert.ThrowsException(() =>
+ Assert.Throws(() =>
new CommonTlvEncodingObject.TransmitChannelConfigurationObject(new byte[] { 254, 1, 0 }));
}
@@ -98,7 +101,7 @@ public class DocsisTests : Feyllure
Assert.AreEqual(new TimeSpan(0, 0, 1), commonTlv.InitializingChannelTimeout);
ms = new MemoryStream(new byte[] { 254, 1, 0 });
- Assert.ThrowsException(() => new CommonTlvEncodingObject(ms));
+ Assert.Throws(() => new CommonTlvEncodingObject(ms));
}
[TestMethod]
@@ -131,13 +134,13 @@ public class DocsisTests : Feyllure
Assert.AreEqual(GeneralPacketClassifierEncoding.DynamicServiceChangeActionEnum.Add, gpce.DynamicServiceChangeAction.Value);
Assert.IsNotNull(gpce.EthernetLlcPacketClassificationEncodings);
- Assert.ThrowsException(() => new GeneralPacketClassifierEncoding(new byte[]
+ Assert.Throws(() => new GeneralPacketClassifierEncoding(new byte[]
{
12, 4,
255, 1, 0, 0
}));
- Assert.ThrowsException(() => new GeneralPacketClassifierEncoding(new byte[]
+ Assert.Throws(() => new GeneralPacketClassifierEncoding(new byte[]
{
254, 1, 0
}));
@@ -169,7 +172,7 @@ public class DocsisTests : Feyllure
Assert.AreEqual(1, ipce.SourcePortStart.Value);
Assert.AreEqual(1, ipce.SourcePortEnd.Value);
- Assert.ThrowsException(() =>
+ Assert.Throws(() =>
new GeneralPacketClassifierEncoding.Ipv4PacketClassificationEncodings(new byte[]
{
255, 1, 0
@@ -189,7 +192,7 @@ public class DocsisTests : Feyllure
Assert.IsNotNull(sfscao.SidClusterEncoding);
Assert.IsNotNull(sfscao.SidClusterSwitchoverCriteria);
- Assert.ThrowsException(() => new ServiceFlowSidClusterAssignmentObject(new byte[]
+ Assert.Throws(() => new ServiceFlowSidClusterAssignmentObject(new byte[]
{
255, 1, 0
}));
@@ -207,7 +210,7 @@ public class DocsisTests : Feyllure
Assert.AreEqual(1, sceo.SidClusterId.Value);
Assert.IsNotNull(sceo.SidToChannelMapping);
- Assert.ThrowsException(() => new ServiceFlowSidClusterAssignmentObject.SidClusterEncodingObject(new byte[]
+ Assert.Throws(() => new ServiceFlowSidClusterAssignmentObject.SidClusterEncodingObject(new byte[]
{
255, 1, 0
}));
@@ -227,7 +230,7 @@ public class DocsisTests : Feyllure
Assert.AreEqual(1, stcmo.SID.Value);
Assert.AreEqual(ServiceFlowSidClusterAssignmentObject.SidClusterEncodingObject.SidToChannelMappingObject.ActionEnum.Add,stcmo.Action.Value);
- Assert.ThrowsException(() =>
+ Assert.Throws(() =>
new ServiceFlowSidClusterAssignmentObject.SidClusterEncodingObject.SidToChannelMappingObject(new byte[]
{
255, 1, 0
@@ -272,7 +275,7 @@ public class DocsisTests : Feyllure
Assert.AreEqual((ushort)1, scsco.MaximumTimeInTheSidCluster);
buffer = new byte[] { 254, 1, 0 };
- Assert.ThrowsException(() =>
+ Assert.Throws(() =>
new ServiceFlowSidClusterAssignmentObject.SidClusterSwitchoverCriteriaObject(buffer));
}
@@ -478,7 +481,7 @@ public class DocsisTests : Feyllure
{
255, 1, 1
};
- Assert.ThrowsException(() => new ModemCapabilitiesEncoding(buffer));
+ Assert.Throws(() => new ModemCapabilitiesEncoding(buffer));
}
[TestMethod]
@@ -555,7 +558,7 @@ public class DocsisTests : Feyllure
{
254, 1, 1
};
- Assert.ThrowsException(() => new GeneralServiceFlowEncoding(buffer));
+ Assert.Throws(() => new GeneralServiceFlowEncoding(buffer));
}
[MacManagementMessageType(0x90,0x01)]
@@ -589,7 +592,7 @@ public class DocsisTests : Feyllure
Assert.AreEqual(srcAddr, tmmm.Source);
Assert.AreEqual(dstAddr, tmmm.Destination);
- Assert.ThrowsException(() => new TestableMacManagementMessage(srcAddr, dstAddr, null));
+ Assert.Throws(() => new TestableMacManagementMessage(srcAddr, dstAddr, null));
UntestableMacManagementMessage ummm = new UntestableMacManagementMessage(srcAddr, dstAddr, dataBuffer);
Assert.IsNull(ummm.MessageType);
diff --git a/skyscraper8.Tests/RootTests/Mpeg2Tests.cs b/skyscraper8.Tests/RootTests/Mpeg2Tests.cs
index 3cc8322..b667b1f 100644
--- a/skyscraper8.Tests/RootTests/Mpeg2Tests.cs
+++ b/skyscraper8.Tests/RootTests/Mpeg2Tests.cs
@@ -1,3 +1,4 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
using skyscraper5.Mpeg2;
namespace skyscraper8.Tests.RootTests;
diff --git a/skyscraper8.Tests/skyscraper8.Tests.csproj b/skyscraper8.Tests/skyscraper8.Tests.csproj
new file mode 100644
index 0000000..b45b07c
--- /dev/null
+++ b/skyscraper8.Tests/skyscraper8.Tests.csproj
@@ -0,0 +1,47 @@
+
+
+
+
+ net8.0
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+ True
+ True
+ Resources1.resx
+
+
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+ ResXFileCodeGenerator
+ Resources1.Designer.cs
+
+
+
+
\ No newline at end of file
diff --git a/skyscraper8.sln b/skyscraper8.sln
index 474c714..fcb92b9 100644
--- a/skyscraper8.sln
+++ b/skyscraper8.sln
@@ -65,7 +65,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "skyscraper8.UI.MonoGame", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "skyscraper8.UI.MonoGame.Bridge", "GUIs\skyscraper8.UI.ImGui.MonoGame.Bridge\skyscraper8.UI.MonoGame.Bridge.csproj", "{1A29F6E6-4B6A-DCCD-1DF1-AA8D020E17D2}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "skyscraper8.Tests", "skyscraper8.Tests\skyscraper8.Tests.csproj", "{011164D8-B6FF-4BAB-B78D-0A174FC691E8}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "skyscraper8.Tests", "skyscraper8.Tests\skyscraper8.Tests.csproj", "{84EE9FCD-2C7F-DF84-C1BA-99D018CE9412}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -165,10 +165,10 @@ Global
{1A29F6E6-4B6A-DCCD-1DF1-AA8D020E17D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A29F6E6-4B6A-DCCD-1DF1-AA8D020E17D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A29F6E6-4B6A-DCCD-1DF1-AA8D020E17D2}.Release|Any CPU.Build.0 = Release|Any CPU
- {011164D8-B6FF-4BAB-B78D-0A174FC691E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {011164D8-B6FF-4BAB-B78D-0A174FC691E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {011164D8-B6FF-4BAB-B78D-0A174FC691E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {011164D8-B6FF-4BAB-B78D-0A174FC691E8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {84EE9FCD-2C7F-DF84-C1BA-99D018CE9412}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {84EE9FCD-2C7F-DF84-C1BA-99D018CE9412}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {84EE9FCD-2C7F-DF84-C1BA-99D018CE9412}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {84EE9FCD-2C7F-DF84-C1BA-99D018CE9412}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/skyscraper8.sln.DotSettings.user b/skyscraper8.sln.DotSettings.user
index a51adfd..5796cc7 100644
--- a/skyscraper8.sln.DotSettings.user
+++ b/skyscraper8.sln.DotSettings.user
@@ -26,11 +26,11 @@
<Assembly Path="/home/schiemas/.nuget/packages/allure.net.commons/2.14.1/lib/netstandard2.0/Allure.Net.Commons.dll" />
</AssemblyExplorer>
/home/schiemas/.cache/JetBrains/Rider2025.1/resharper-host/temp/Rider/vAny/CoverageData/_skyscraper8.1808907683/Snapshot/snapshot.utdcvr
- <SessionState ContinuousTestingMode="0" Name="All tests from <skyscraper8.Tests> #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
- <Project Location="/home/schiemas/RiderProjects/skyscraper8/skyscraper8.Tests" Presentation="<skyscraper8.Tests>" />
+ <SessionState ContinuousTestingMode="0" Name="All tests from <skyscraper8.Tests> #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
+ <Project Location="\home\schiemas\RiderProjects\skyscraper8\skyscraper8.Tests" Presentation="<skyscraper8.Tests>" />
</SessionState>
- <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from <skyscraper8.Tests>" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
- <Project Location="/home/schiemas/RiderProjects/skyscraper8/skyscraper8.Tests" Presentation="<skyscraper8.Tests>" />
+ <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from <skyscraper8.Tests>" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
+ <Project Location="\home\schiemas\RiderProjects\skyscraper8\skyscraper8.Tests" Presentation="<skyscraper8.Tests>" />
</SessionState>
diff --git a/skyscraper8/DvbNip/DvbNipReceiver.cs b/skyscraper8/DvbNip/DvbNipReceiver.cs
index ed89f9d..2a6c6c2 100644
--- a/skyscraper8/DvbNip/DvbNipReceiver.cs
+++ b/skyscraper8/DvbNip/DvbNipReceiver.cs
@@ -13,6 +13,7 @@ using System.Threading.Tasks;
using moe.yo3explorer.skyscraper8.DVBI.Model;
using skyscraper8.DvbI;
using System.Reflection.Metadata.Ecma335;
+using skyscraper8.Ietf.Rfc4566_SDP;
namespace skyscraper8.DvbNip
{
@@ -53,16 +54,28 @@ namespace skyscraper8.DvbNip
if (discoveryUdpPacket.DestinationPort == 3937)
{
LctFrame discoveryLctFrame = new LctFrame(discoveryUdpPacket.Payload);
- if (discoveryLctFrame.LctHeader.NipActualCarrierInformation != null)
+ if (discoveryLctFrame == null)
+ return;
+ LctHeader lctHeader = discoveryLctFrame.LctHeader;
+ if (lctHeader == null)
+ return;
+ if (lctHeader.NipActualCarrierInformation != null)
{
CurrentCarrierInformation = discoveryLctFrame.LctHeader.NipActualCarrierInformation;
EventHandler.OnNipCarrierDetected(CurrentCarrierInformation);
bootstrapped = true;
}
+ else if (discoveryLctFrame.PayloadContainsNativeIpMulticastTransportObject)
+ {
+ CurrentCarrierInformation = new NipActualCarrierInformation(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, "(no NIP carrier name provided)");
+ EventHandler.OnNipCarrierDetected(CurrentCarrierInformation);
+ bootstrapped = true;
+ }
}
}
return;
}
+
UserDatagram udpPacket = new UserDatagram(ipv4Packet);
LctFrame lctFrame = new LctFrame(udpPacket.Payload);
if (lctFrame.LctHeader == null)
@@ -114,6 +127,10 @@ namespace skyscraper8.DvbNip
SetFileAssociations(fluteListener, fdtAnnouncement);
}
}
+ else
+ {
+ Console.WriteLine("aaa");
+ }
fluteStream.Close();
fluteStream.Dispose();
flutes.Remove(fluteCoordinate);
@@ -163,6 +180,7 @@ namespace skyscraper8.DvbNip
}
}
}
+
private DateTime? currentTime;
private bool HandleMetadata(FluteListener fluteListener)
@@ -170,56 +188,83 @@ namespace skyscraper8.DvbNip
switch (fluteListener.FileAssociation.ContentLocation)
{
case "urn:dvb:metadata:cs:NativeIPMulticastTransportObjectTypeCS:2023:bootstrap":
- MulticastGatewayConfigurationType multicastGatewayConfiguration2023 = DvbNipUtilities.UnpackMulticastGatewayConfiguration(fluteListener.ToStream());
- EventHandler?.OnMulticastGatewayConfiguration(CurrentCarrierInformation, multicastGatewayConfiguration2023);
- return true;
- case "urn:dvb:metadata:cs:MulticastTransportObjectTypeCS:2021:gateway-configuration":
- MulticastGatewayConfigurationType multicastGatewayConfiguration2021 = DvbNipUtilities.UnpackMulticastGatewayConfiguration(fluteListener.ToStream());
- EventHandler?.OnMulticastGatewayConfiguration(CurrentCarrierInformation, multicastGatewayConfiguration2021);
- return true;
- case "urn:dvb:metadata:nativeip:PrivateDataSignalling":
- PrivateDataSignallingManifestType privateDataSignallingManifest = DvbNipUtilities.UnpackPrivateDataSignallingManifest(fluteListener.ToStream());
- EventHandler?.OnPrivateDataSignallingManifest(CurrentCarrierInformation, privateDataSignallingManifest);
- return true;
- case "urn:dvb:metadata:nativeip:dvb-i-slep":
- if (currentTime.HasValue)
+ Stream stream = fluteListener.ToStream();
+ if (DvbNipUtilities.IsXml(stream))
{
- Stream rawSlepStream = fluteListener.ToStream();
- byte[] rawSlepBytes = new byte[rawSlepStream.Length];
- rawSlepStream.Read(rawSlepBytes, 0, (int)rawSlepStream.Length);
- string rawSlepString = Encoding.UTF8.GetString(rawSlepBytes);
- rawSlepString = rawSlepString.Replace(" readOnlySpan = new ReadOnlySpan(bbframe, 11, bbframe.Length - 11);
diff --git a/skyscraper8/Ietf/FLUTE/FluteException.cs b/skyscraper8/Ietf/FLUTE/FluteException.cs
new file mode 100644
index 0000000..80969e6
--- /dev/null
+++ b/skyscraper8/Ietf/FLUTE/FluteException.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace skyscraper8.Ietf.FLUTE
+{
+ public class FluteException : IetfException
+ {
+ public FluteException()
+ {
+ }
+
+ public FluteException(string message) : base(message)
+ {
+ }
+
+ public FluteException(string message, Exception inner) : base(message, inner)
+ {
+ }
+ }
+}
diff --git a/skyscraper8/Ietf/FLUTE/FluteListener.cs b/skyscraper8/Ietf/FLUTE/FluteListener.cs
index e830616..1c232c4 100644
--- a/skyscraper8/Ietf/FLUTE/FluteListener.cs
+++ b/skyscraper8/Ietf/FLUTE/FluteListener.cs
@@ -9,6 +9,7 @@ using System.Runtime.Serialization;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
+using MimeKit;
using skyscraper5.Teletext.Wss;
namespace skyscraper8.Ietf.FLUTE
@@ -147,8 +148,8 @@ namespace skyscraper8.Ietf.FLUTE
return _dataWritten;
}
}
-
- public Stream ToStream()
+
+ public virtual Stream ToStream()
{
if (!IsComplete())
throw new InvalidOperationException();
@@ -164,7 +165,7 @@ namespace skyscraper8.Ietf.FLUTE
blockPayloads.Sort(new FluteBlockComparer());
level1 = new FluteListenerStream(blockPayloads);
}
-
+
if (FileAssociation != null)
{
switch(FileAssociation.ContentEncoding)
diff --git a/skyscraper8/Ietf/FLUTE/LctFrame.cs b/skyscraper8/Ietf/FLUTE/LctFrame.cs
index 0ef7fde..02fc666 100644
--- a/skyscraper8/Ietf/FLUTE/LctFrame.cs
+++ b/skyscraper8/Ietf/FLUTE/LctFrame.cs
@@ -53,6 +53,11 @@ namespace skyscraper8.Ietf.FLUTE
return;
Payload = ms.ReadBytes(ms.GetAvailableBytes());
+ if (Payload[0] == 0x3c && Payload[1] == 0x3f && Payload[2] == 0x78 && Payload[3] == 0x6d &&
+ Payload[4] == 0x6c && Payload[5] == 0x20)
+ {
+ PayloadAsString = Encoding.UTF8.GetString(Payload);
+ }
}
public int Version { get; }
@@ -67,5 +72,19 @@ namespace skyscraper8.Ietf.FLUTE
public bool CloseObjectFlag { get; }
public FecHeader FecHeader { get; }
public byte[] Payload { get; }
+
+ public string PayloadAsString { get; private set; }
+
+ public bool PayloadContainsNativeIpMulticastTransportObject
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(PayloadAsString))
+ {
+ return false;
+ }
+ return PayloadAsString.Contains("NativeIPMulticastTransportObjectTypeCS");
+ }
+ }
}
}
diff --git a/skyscraper8/Ietf/FluteListenerMime.cs b/skyscraper8/Ietf/FluteListenerMime.cs
new file mode 100644
index 0000000..db4b936
--- /dev/null
+++ b/skyscraper8/Ietf/FluteListenerMime.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using skyscraper8.Ietf.FLUTE;
+
+namespace skyscraper8.Ietf
+{
+ internal class FluteListenerMime : FluteListener
+ {
+ public FluteListenerMime(IPAddress destinationAddress, ushort destinationPort, ulong destinationTsi, ulong destinationToi) : base(destinationAddress, destinationPort, destinationTsi, destinationToi)
+ {
+ }
+
+ public Stream WrappedStream { get; set; }
+
+ public override Stream ToStream()
+ {
+ return WrappedStream;
+ }
+ }
+}
diff --git a/skyscraper8/Ietf/Rfc4566_SDP/SDP.cs b/skyscraper8/Ietf/Rfc4566_SDP/SDP.cs
new file mode 100644
index 0000000..9bb8a7e
--- /dev/null
+++ b/skyscraper8/Ietf/Rfc4566_SDP/SDP.cs
@@ -0,0 +1,159 @@
+using log4net;
+using skyscraper5.Skyscraper.IO;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using skyscraper8.DvbNip;
+
+namespace skyscraper8.Ietf.Rfc4566_SDP
+{
+ public class SDP
+ {
+ private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
+
+ public static bool IsSDP(Stream ms)
+ {
+ if (ms.GetAvailableBytes() < 3)
+ return false;
+
+ byte byteA = ms.ReadUInt8();
+ byte byteB = ms.ReadUInt8();
+ ms.Position -= 2;
+
+ if (byteA != 'v')
+ return false;
+
+ if (byteB != '=')
+ return false;
+
+ return true;
+ }
+
+ public static SDP Load(Stream stream)
+ {
+ StreamReader sr = new StreamReader(stream);
+ SDP result = null;
+ while (!sr.EndOfStream)
+ {
+ string line = sr.ReadLine();
+ if (line[1] != '=')
+ {
+ logger.ErrorFormat("Invalid SDP description!");
+ return result;
+ }
+
+ if (result == null)
+ result = new SDP();
+ char opcode = line[0];
+ string args = line.Substring(2);
+ switch (opcode)
+ {
+ case 'v':
+ result.Version = new Version(int.Parse(args), 0);
+ break;
+ case 'o':
+ result.Originator = new SdpOriginator(args.Split(' '));
+ break;
+ case 's':
+ result.SessionName = args;
+ break;
+ case 't':
+ result.Times = new SdpTimes(args.Split(' '));
+ break;
+ case 'a':
+ if (result.Attributes == null)
+ result.Attributes = new SdpAttributeCollection();
+ result.Attributes.SetHint(args);
+ break;
+ case 'm':
+ if (result._mediaAnnouncements == null)
+ result._mediaAnnouncements = new List();
+ result._mediaAnnouncements.Add(new SdpMedia(args.Split(' ')));
+ break;
+ case 'c':
+ if (result._connections == null)
+ result._connections = new List();
+ result._connections.Add(new SdpConnectionData(args.Split(' ')));
+ break;
+ case 'b':
+ string bandwidthType = args.Substring(0, 2);
+ string bandwidthValue = args.Substring(3);
+ switch (bandwidthType)
+ {
+ case "CT":
+ result.ConferenceTotalBandwidth = long.Parse(bandwidthValue);
+ break;
+ case "AS":
+ result.ApplicationSpecificMaximumBandwidth = long.Parse(bandwidthValue);
+ break;
+ default:
+ logger.WarnFormat("Unknown bandwidth type: {0}", bandwidthType);
+ break;
+ }
+ break;
+ default:
+ logger.ErrorFormat("Invalid SDP opcode \"{0}\", please consider sharing a sample of this stream for further analysis.", opcode);
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ public long? ApplicationSpecificMaximumBandwidth { get; private set; }
+
+ public long? ConferenceTotalBandwidth { get; private set; }
+
+
+ private List _mediaAnnouncements;
+ private List _connections;
+
+ public IReadOnlyList ConnectionData
+ {
+ get
+ {
+ return _connections.AsReadOnly();
+ }
+ }
+ public IReadOnlyList MediaAnnouncements
+ {
+ get
+ {
+ return _mediaAnnouncements.AsReadOnly();
+ }
+ }
+ public SdpAttributeCollection Attributes { get; private set; }
+ public SdpTimes Times { get; private set; }
+
+ public string SessionName { get; private set; }
+
+ public SdpOriginator Originator { get; private set; }
+
+ public Version Version { get; private set; }
+
+ public MulticastGatewayConfigurationType ToMulticastGatewayConfiguration()
+ {
+ MulticastGatewayConfigurationType result = new MulticastGatewayConfigurationType();
+ result.MulticastSession = new MulticastSessionType[_connections.Count];
+
+ for (int i = 0; i < _connections.Count; i++)
+ {
+ result.MulticastSession[i] = new MulticastSessionType();
+ result.MulticastSession[i].serviceIdentifier = Originator.ToString();
+ result.MulticastSession[i].MulticastTransportSession = new MulticastTransportSessionType[1];
+ result.MulticastSession[i].MulticastTransportSession[0] = new MulticastTransportSessionType();
+ result.MulticastSession[i].MulticastTransportSession[0].EndpointAddress = new MulticastEndpointAddressType[1];
+ result.MulticastSession[i].MulticastTransportSession[0].EndpointAddress[0] = new MulticastEndpointAddressType();
+ result.MulticastSession[i].MulticastTransportSession[0].EndpointAddress[0].NetworkDestinationGroupAddress = _connections[i].DestinationAddress;
+ result.MulticastSession[i].MulticastTransportSession[0].EndpointAddress[0].NetworkSourceAddress = Originator.Address.ToString();
+ result.MulticastSession[i].MulticastTransportSession[0].EndpointAddress[0].TransportDestinationPort = _mediaAnnouncements[i].Port.ToString();
+ }
+
+ return result;
+ }
+ }
+
+
+}
diff --git a/skyscraper8/Ietf/Rfc4566_SDP/SdpAddressType.cs b/skyscraper8/Ietf/Rfc4566_SDP/SdpAddressType.cs
new file mode 100644
index 0000000..8369486
--- /dev/null
+++ b/skyscraper8/Ietf/Rfc4566_SDP/SdpAddressType.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace skyscraper8.Ietf.Rfc4566_SDP
+{
+ public enum SdpAddressType
+ {
+ IP4,
+ IP6
+ }
+}
diff --git a/skyscraper8/Ietf/Rfc4566_SDP/SdpAttributes.cs b/skyscraper8/Ietf/Rfc4566_SDP/SdpAttributes.cs
new file mode 100644
index 0000000..ba359b8
--- /dev/null
+++ b/skyscraper8/Ietf/Rfc4566_SDP/SdpAttributes.cs
@@ -0,0 +1,208 @@
+using log4net;
+using log4net.Repository.Hierarchy;
+using skyscraper5.Skyscraper.IO.TunerInterface;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Net;
+using System.Numerics;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace skyscraper8.Ietf.Rfc4566_SDP
+{
+ public class SdpAttributeCollection : IEnumerable
+ {
+ private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
+ private Dictionary _attributes;
+
+ internal void SetHint(string args)
+ {
+ if (_attributes == null)
+ _attributes = new Dictionary();
+
+ int indexOf = args.IndexOf(':');
+ string key = args.Substring(0, indexOf);
+ string value = args.Substring(indexOf + 1);
+ switch (key)
+ {
+ case "mbms-mode":
+ _attributes.Add(key, new MbmsMode(value));
+ break;
+ case "source-filter":
+ if (!_attributes.ContainsKey(key))
+ _attributes.Add(key, new SourceFilter());
+ SourceFilter sourceFilter = _attributes[key] as SourceFilter;
+ sourceFilter.SetHint(value);
+ break;
+ case "flute-tsi":
+ _attributes.Add(key, new FluteTsi(value));
+ break;
+ default:
+ logger.ErrorFormat("Unknown SDP Attribute: \"{0}\" - please consider sharing a sample of this stream for further analysis.", key);
+ break;
+ }
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return _attributes.Values.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return _attributes.Values.GetEnumerator();
+ }
+ }
+
+ internal class FluteTsi : SdpAttribute
+ {
+ public FluteTsi(string value) : base("flute-tsi")
+ {
+ TSI = long.Parse(value);
+ }
+
+ public long TSI { get; private set; }
+
+ public override string ToString()
+ {
+ return TSI.ToString();
+ }
+ }
+
+ internal class SourceFilter : SdpAttribute
+ {
+ public SourceFilter() : base("source-filter")
+ {
+ }
+
+ public void SetHint(string value)
+ {
+ if (_filterChain == null)
+ _filterChain = new List();
+ _filterChain.Add(new SourceFilterChainLink(value.Split(' ',StringSplitOptions.RemoveEmptyEntries)));
+ }
+
+ private List _filterChain;
+
+ class SourceFilterChainLink
+ {
+ private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
+
+ public SourceFilterChainLink(string[] args)
+ {
+ if (args[0].Equals("incl"))
+ {
+ Include = true;
+ }
+ else if (args[0].Equals("excl"))
+ {
+ Include = false;
+ }
+ else
+ {
+ logger.ErrorFormat("Unknown Filter Mode \"{0}\", assuming exclusion just to be sure.", args[0]);
+ }
+
+ if (!SdpNetworkType.TryParse(args[1], true, out _networkType))
+ {
+ logger.ErrorFormat("Unknown Network Type \"{0}\", assuming \"IN\" - please consider sharing a sample of this stream so this can be implemented.", args[1]);
+ _networkType = SdpNetworkType.IN;
+ }
+
+ if (!SdpAddressType.TryParse(args[2], true, out _addressType))
+ {
+ logger.ErrorFormat("Unknown Address Type \"{0}\", assuming \"IP4\" - please consider sharing a sample of this stream so this can be implemented.", args[2]);
+ _addressType = SdpAddressType.IP4;
+ }
+
+ DestinationAddress = args[3];
+
+ int numSources = args.Length - 4;
+ Sources = new string[numSources];
+ Array.Copy(args, 4, Sources, 0, numSources);
+ }
+
+ ///
+ /// If this is true, an incoming packet is accepted, if not it gets discarded.
+ ///
+ public bool Include { get; private set; }
+
+ public string[] Sources { get; private set; }
+ public string DestinationAddress { get; private set; }
+ private SdpAddressType _addressType;
+ public SdpAddressType AddressType
+ {
+ get => _addressType;
+ }
+
+ private SdpNetworkType _networkType;
+ public SdpNetworkType NetworkType
+ {
+ get => _networkType;
+ }
+ }
+ }
+
+ internal class MbmsMode : SdpAttribute
+ {
+ private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
+
+ public MbmsMode(string value)
+ : base("mbms-mode")
+ {
+ string[] args = value.Split(' ');
+ if (args[0].Equals("broadcast-mbsfn"))
+ {
+ BigInteger tmgi = BigInteger.Parse(args[1]);
+ this.Tmgi = tmgi.ToByteArray();
+ }
+ else if (args[0].Equals("broadcast"))
+ {
+ BigInteger tmgi = BigInteger.Parse(args[1]);
+ this.Tmgi = tmgi.ToByteArray();
+ this.MbmsCountingIndication = int.Parse(args[2]);
+ }
+ else
+ {
+ logger.ErrorFormat("Unknown MBMS Mode: {0} - please consider a sharing a sample of this stream if you'd like the developer to look further into this.", args[0]);
+ }
+ }
+
+ public int? MbmsCountingIndication { get; private set; }
+
+ public byte[] Tmgi { get; private set; }
+
+ internal enum MbmsBearerMode
+ {
+ Unknown,
+ Broadcast,
+ BroadcastMbsfn
+ }
+
+ public MbmsBearerMode BearerMode
+ {
+ get
+ {
+ if (Tmgi == null)
+ return MbmsBearerMode.Unknown;
+ if (MbmsCountingIndication == null)
+ return MbmsBearerMode.BroadcastMbsfn;
+ else
+ return MbmsBearerMode.Broadcast;
+ }
+ }
+ }
+
+ public abstract class SdpAttribute
+ {
+ protected SdpAttribute(string key)
+ {
+ this.SdpAttributeName = key;
+ }
+
+ public string SdpAttributeName { get; private set; }
+ }
+}
diff --git a/skyscraper8/Ietf/Rfc4566_SDP/SdpConnectionData.cs b/skyscraper8/Ietf/Rfc4566_SDP/SdpConnectionData.cs
new file mode 100644
index 0000000..071cf8c
--- /dev/null
+++ b/skyscraper8/Ietf/Rfc4566_SDP/SdpConnectionData.cs
@@ -0,0 +1,45 @@
+using log4net;
+using log4net.Repository.Hierarchy;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace skyscraper8.Ietf.Rfc4566_SDP
+{
+ public class SdpConnectionData
+ {
+ private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
+
+ public SdpConnectionData(string[] args)
+ {
+ if (!SdpNetworkType.TryParse(args[0], true, out _networkType))
+ {
+ logger.ErrorFormat("Unknown Network Type \"{0}\", assuming \"IN\" - please consider sharing a sample of this stream so this can be implemented.", args[0]);
+ _networkType = SdpNetworkType.IN;
+ }
+
+ if (!SdpAddressType.TryParse(args[1], true, out _addressType))
+ {
+ logger.ErrorFormat("Unknown Address Type \"{0}\", assuming \"IP4\" - please consider sharing a sample of this stream so this can be implemented.", args[1]);
+ _addressType = SdpAddressType.IP4;
+ }
+
+ DestinationAddress = args[2];
+ }
+
+ public string DestinationAddress { get; private set; }
+ private SdpAddressType _addressType;
+ public SdpAddressType AddressType
+ {
+ get => _addressType;
+ }
+
+ private SdpNetworkType _networkType;
+ public SdpNetworkType NetworkType
+ {
+ get => _networkType;
+ }
+ }
+}
diff --git a/skyscraper8/Ietf/Rfc4566_SDP/SdpMedia.cs b/skyscraper8/Ietf/Rfc4566_SDP/SdpMedia.cs
new file mode 100644
index 0000000..59ba2f2
--- /dev/null
+++ b/skyscraper8/Ietf/Rfc4566_SDP/SdpMedia.cs
@@ -0,0 +1,51 @@
+using log4net;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace skyscraper8.Ietf.Rfc4566_SDP
+{
+ public class SdpMedia
+ {
+ private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
+
+ public SdpMedia(string[] args)
+ {
+ if (!MediaType.TryParse(args[0], true, out _mediaType))
+ {
+ logger.ErrorFormat("Unknown Media Type \"{0}\", assuming \"data\"", args[0]);
+ _mediaType = MediaType.Data;
+ }
+
+ Port = ushort.Parse(args[1]);
+ Transport = args[2];
+
+ int numFormats = args.Length - 3;
+ FormatList = new string[numFormats];
+ Array.Copy(args, 3, FormatList, 0, numFormats);
+ }
+
+ public string[] FormatList { get; private set; }
+
+ public string Transport { get; private set; }
+
+ public ushort Port { get; private set; }
+
+ private MediaType _mediaType;
+ public MediaType MediaType
+ {
+ get => _mediaType;
+ }
+ }
+
+ public enum MediaType
+ {
+ Audio,
+ Video,
+ Application,
+ Data,
+ Control
+ }
+}
diff --git a/skyscraper8/Ietf/Rfc4566_SDP/SdpNetworkType.cs b/skyscraper8/Ietf/Rfc4566_SDP/SdpNetworkType.cs
new file mode 100644
index 0000000..4939a08
--- /dev/null
+++ b/skyscraper8/Ietf/Rfc4566_SDP/SdpNetworkType.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace skyscraper8.Ietf.Rfc4566_SDP
+{
+ public enum SdpNetworkType
+ {
+ IN
+ }
+}
diff --git a/skyscraper8/Ietf/Rfc4566_SDP/SdpOriginator.cs b/skyscraper8/Ietf/Rfc4566_SDP/SdpOriginator.cs
new file mode 100644
index 0000000..62a95a9
--- /dev/null
+++ b/skyscraper8/Ietf/Rfc4566_SDP/SdpOriginator.cs
@@ -0,0 +1,58 @@
+using log4net;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace skyscraper8.Ietf.Rfc4566_SDP
+{
+ public class SdpOriginator
+ {
+ private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
+
+ public SdpOriginator(string[] args)
+ {
+ Username = args[0];
+ Id = args[1];
+ this.Version = long.Parse(args[2]);
+ if (!SdpNetworkType.TryParse(args[3], true, out _networkType))
+ {
+ logger.ErrorFormat("Unknown Network Type \"{0}\", assuming \"IN\" - please consider sharing a sample of this stream so this can be implemented.", _networkType);
+ _networkType = SdpNetworkType.IN;
+ }
+
+ if (!SdpAddressType.TryParse(args[4], true, out _addressType))
+ {
+ logger.ErrorFormat("Unknown Address Type \"{0}\", assuming \"IP4\" - please consider sharing a sample of this stream so this can be implemented.", _addressType);
+ _addressType = SdpAddressType.IP4;
+ }
+
+ Address = IPAddress.Parse(args[5]);
+ }
+
+ public IPAddress Address { get; private set; }
+ private SdpAddressType _addressType;
+ public SdpAddressType AddressType
+ {
+ get => _addressType;
+ }
+
+ private SdpNetworkType _networkType;
+ public SdpNetworkType NetworkType
+ {
+ get => _networkType;
+ }
+ public long Version { get; set; }
+
+ public string Id { get; set; }
+
+ public string Username { get; set; }
+
+ public override string ToString()
+ {
+ return String.Format("{0} {1} {2} {3} {4}", Username, Id, NetworkType, AddressType, Address);
+ }
+ }
+}
diff --git a/skyscraper8/Ietf/Rfc4566_SDP/SdpTimes.cs b/skyscraper8/Ietf/Rfc4566_SDP/SdpTimes.cs
new file mode 100644
index 0000000..8ebacb8
--- /dev/null
+++ b/skyscraper8/Ietf/Rfc4566_SDP/SdpTimes.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using skyscraper8.Skyscraper;
+
+namespace skyscraper8.Ietf.Rfc4566_SDP
+{
+ public struct SdpTimes
+ {
+ private const long NTP_OFFSET = 2208988800L;
+ private readonly long _startTime;
+ private readonly long _stopTime;
+
+ public SdpTimes(string[] args)
+ {
+ _startTime = long.Parse(args[0]);
+ _stopTime = long.Parse(args[1]);
+ }
+
+ public bool IsNull
+ {
+ get => _startTime == 0;
+ }
+
+ public DateTime? StartTime
+ {
+ get
+ {
+ if (_startTime == 0)
+ return null;
+
+ long tmp = _startTime - NTP_OFFSET;
+ return tmp.AsUnixtime();
+ }
+ }
+
+ public DateTime? EndTime
+ {
+ get
+ {
+ if (_stopTime == 0)
+ return null;
+
+ long tmp = _stopTime - NTP_OFFSET;
+ return tmp.AsUnixtime();
+ }
+ }
+ }
+}
diff --git a/skyscraper8/Program.cs b/skyscraper8/Program.cs
index fac28f2..7a622d8 100644
--- a/skyscraper8/Program.cs
+++ b/skyscraper8/Program.cs
@@ -355,7 +355,9 @@ namespace skyscraper5
if (args[0].ToLowerInvariant().Equals("make-catalogue"))
{
DirectoryInfo di = new DirectoryInfo(args[1]);
+ logger.InfoFormat("Input directory: {0}", di.FullName);
FileInfo fi = new FileInfo(args[2]);
+ logger.InfoFormat("Output File: {0}", fi.FullName);
CatalogueGenerator catalogueGenerator = new CatalogueGenerator(di, fi);
catalogueGenerator.Run();
catalogueGenerator.Dispose();
diff --git a/skyscraper8/Properties/launchSettings.json b/skyscraper8/Properties/launchSettings.json
index 8660a46..3ce0d08 100644
--- a/skyscraper8/Properties/launchSettings.json
+++ b/skyscraper8/Properties/launchSettings.json
@@ -2,7 +2,7 @@
"profiles": {
"skyscraper8": {
"commandName": "Project",
- "commandLineArgs": "make-catalogue \"D:\\\\Stash\\\\\" \"D:\\\\index.csv\"",
+ "commandLineArgs": "\"Z:\\Persönliches\\Satellitescommunity\\65W11304V.TS\"",
"remoteDebugEnabled": false
},
"Container (Dockerfile)": {
diff --git a/skyscraper8/Skyscraper/DateTimeExtensions.cs b/skyscraper8/Skyscraper/DateTimeExtensions.cs
index 18e7891..cf1d109 100644
--- a/skyscraper8/Skyscraper/DateTimeExtensions.cs
+++ b/skyscraper8/Skyscraper/DateTimeExtensions.cs
@@ -19,5 +19,7 @@ namespace skyscraper5.Skyscraper
{
return ToUnixTime(dt) * 1000;
}
+
+
}
}
diff --git a/skyscraper8/Skyscraper/IO/StreamExtensions.cs b/skyscraper8/Skyscraper/IO/StreamExtensions.cs
index 97a04fa..c2d5fe2 100644
--- a/skyscraper8/Skyscraper/IO/StreamExtensions.cs
+++ b/skyscraper8/Skyscraper/IO/StreamExtensions.cs
@@ -333,5 +333,14 @@ namespace skyscraper5.Skyscraper.IO
stream.Position--;
return readUInt8;
}
+
+ public static void DumpToFile(this Stream stream, string filename)
+ {
+ FileStream fileStream = File.OpenWrite(filename);
+ stream.CopyTo(fileStream);
+ fileStream.Flush(true);
+ fileStream.Close();
+ fileStream.Dispose();
+ }
}
}
diff --git a/skyscraper8/Skyscraper/LongExtensions.cs b/skyscraper8/Skyscraper/LongExtensions.cs
new file mode 100644
index 0000000..00f5d4f
--- /dev/null
+++ b/skyscraper8/Skyscraper/LongExtensions.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace skyscraper8.Skyscraper
+{
+ internal static class LongExtensions
+ {
+ ///
+ ///
+ ///
+ ///
+ /// stolen from https://stackoverflow.com/a/250400
+ ///
+ public static DateTime AsUnixtime(this long l)
+ {
+ DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
+ dateTime = dateTime.AddSeconds(l);
+ return dateTime;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// stolen from https://stackoverflow.com/a/250400
+ ///
+ public static DateTime AsJavaMillis(this long javaTimeStamp)
+ {
+ // Java timestamp is milliseconds past epoch
+ DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
+ dateTime = dateTime.AddMilliseconds(javaTimeStamp);
+ return dateTime;
+ }
+ }
+}
diff --git a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs
index 52f4e55..bd98081 100644
--- a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs
+++ b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs
@@ -77,6 +77,7 @@ using System.Net.NetworkInformation;
using System.Reflection;
using System.Security.Policy;
using System.Text;
+using MimeKit;
using skyscraper5.src.InteractionChannel.Model2;
using skyscraper8.Abertis;
using skyscraper8.Experimentals.NdsSsu;
@@ -85,6 +86,7 @@ using skyscraper8.GS;
using skyscraper8.GSE;
using skyscraper8.GSE.GSE;
using skyscraper8.Ieee802_1AB;
+using skyscraper8.Ietf;
using skyscraper8.InteractionChannel.Model;
using skyscraper8.InteractionChannel.Model2;
using skyscraper8.InteractionChannel.Model2.Descriptors;
@@ -2738,7 +2740,35 @@ namespace skyscraper5.Skyscraper.Scraper
public void FluteFileArrival(NipActualCarrierInformation carrier, FluteListener listener)
{
- string extension = Path.GetExtension(listener.FileAssociation.ContentLocation).ToLowerInvariant();
+ Stream stream = listener.ToStream();
+ bool isMime = DvbNipUtilities.IsMime(stream);
+ if (isMime)
+ {
+ MimeMessage message = MimeMessage.Load(stream);
+ foreach (MimeEntity entity in message.BodyParts)
+ {
+ MimePart bodyPart = entity as MimePart;
+ if (bodyPart.ContentLocation == null)
+ continue;
+
+ FluteListenerMime fluteListener = new FluteListenerMime(listener.DestinationAddress, listener.DestinationPort, listener.DestinationTsi, listener.DestinationToi);
+ fluteListener.FileAssociation = new FileType();
+ fluteListener.FileAssociation.ContentLocation = bodyPart.ContentLocation.ToString();
+ fluteListener.FileAssociation.ContentType = bodyPart.ContentType.MimeType;
+ fluteListener.FileAssociation.ContentEncoding = null;
+ fluteListener.WrappedStream = new MemoryStream();
+ bodyPart.Content.DecodeTo(fluteListener.WrappedStream);
+ fluteListener.FileAssociation.ContentLength = (ulong)fluteListener.WrappedStream.Position;
+ fluteListener.FileAssociation.TransferLength = (ulong)fluteListener.WrappedStream.Position;
+ fluteListener.FileAssociation.TransferLengthSpecified = true;
+ fluteListener.WrappedStream.Position = 0;
+
+ FluteFileArrival(carrier, fluteListener);
+ }
+ return;
+ }
+
+ string extension = Path.GetExtension(listener.FileAssociation.ContentLocation).ToLowerInvariant();
if (!DvbNipUtilities.IsContinuousFileType(extension))
LogEvent(SkyscraperContextEvent.FluteFileArrival, listener.FileAssociation.ContentLocation);
else
diff --git a/skyscraper8/Skyscraper/Text/SkyscraperEncodingProvider.cs b/skyscraper8/Skyscraper/Text/SkyscraperEncodingProvider.cs
index 1589a6d..18dccb7 100644
--- a/skyscraper8/Skyscraper/Text/SkyscraperEncodingProvider.cs
+++ b/skyscraper8/Skyscraper/Text/SkyscraperEncodingProvider.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using log4net;
using skyscraper5.Skyscraper.Text.Encodings;
namespace skyscraper5.Skyscraper.Text
@@ -36,18 +37,20 @@ namespace skyscraper5.Skyscraper.Text
}
}
- public override Encoding? GetEncoding(int codepage)
+ private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
+ private List encodings;
+ public override Encoding? GetEncoding(int codepage)
{
- if (codepage == 1200)
- return null;
+ if (encodings == null)
+ encodings = new List();
- if (codepage == 65001)
- return null;
+ if (!encodings.Contains(codepage))
+ {
+ logger.InfoFormat("Detected text encoding: {0}", codepage);
+ encodings.Add(codepage);
+ }
- if (codepage == 0)
- return null;
-
- throw new NotImplementedException();
+ return null;
}
public override Encoding? GetEncoding(string name)
diff --git a/skyscraper8/VersionInfo.cs b/skyscraper8/VersionInfo.cs
index dc9f50e..39a5854 100644
--- a/skyscraper8/VersionInfo.cs
+++ b/skyscraper8/VersionInfo.cs
@@ -4,7 +4,7 @@ namespace skyscraper8;
public class VersionInfo
{
- private const int PUBLIC_RELEASE = 13;
+ private const int PUBLIC_RELEASE = 14;
public static int GetPublicReleaseNumber()
{
diff --git a/skyscraper8/skyscraper8.csproj b/skyscraper8/skyscraper8.csproj
index 98d9846..45804f8 100644
--- a/skyscraper8/skyscraper8.csproj
+++ b/skyscraper8/skyscraper8.csproj
@@ -25,6 +25,7 @@
+