Added functionality necessary to extract the MPEG-DASH segments on the Arsat stream.
All checks were successful
🚀 Pack skyscraper8 / make-zip (push) Successful in 3m38s

This commit is contained in:
feyris-tan 2025-11-23 00:27:00 +01:00
parent c0f644df1a
commit 30026b2b02
40 changed files with 1511 additions and 199 deletions

View File

@ -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}");
}

View File

@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 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.
// </auto-generated>
//------------------------------------------------------------------------------
namespace skyscraper8.Tests.Properties {
using System;
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// 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() {
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[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;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -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
{

View File

@ -1,3 +1,6 @@
using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using skyscraper5.Mpeg2;
namespace skyscraper8.Tests.ResourceTests;

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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

View File

@ -1,9 +1,10 @@
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// <auto-generated>
// 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.
// </auto-generated>
//------------------------------------------------------------------------------
@ -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()]
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// 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 {
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[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 {
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[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));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] Frame00000008_TSGS1_MIS000_SYNC001 {
get {
object obj = ResourceManager.GetObject("Frame00000008_TSGS1_MIS000_SYNC001", resourceCulture);
@ -129,11 +70,134 @@ namespace skyscraper8.Tests {
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] Frame00000012_TSGS1_MIS000_SYNC001 {
get {
object obj = ResourceManager.GetObject("Frame00000012_TSGS1_MIS000_SYNC001", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] Frame00001343_TSGS1_MIS000_SYNC001 {
get {
object obj = ResourceManager.GetObject("Frame00001343_TSGS1_MIS000_SYNC001", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] ModemCapabilitiesEncodingTest {
get {
object obj = ResourceManager.GetObject("ModemCapabilitiesEncodingTest", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] MultipartRegistrationResponseTest {
get {
object obj = ResourceManager.GetObject("MultipartRegistrationResponseTest", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] MultipartRegistrationResponseTest2 {
get {
object obj = ResourceManager.GetObject("MultipartRegistrationResponseTest2", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] PushMacManagementMessage_Version4_Type45 {
get {
object obj = ResourceManager.GetObject("PushMacManagementMessage_Version4_Type45", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] ranging_response_test {
get {
object obj = ResourceManager.GetObject("ranging_response_test", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] sdpTest {
get {
object obj = ResourceManager.GetObject("sdpTest", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] test_1packet_01 {
get {
object obj = ResourceManager.GetObject("test-1packet-01", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] test_2packets_02_03 {
get {
object obj = ResourceManager.GetObject("test-2packets-02-03", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] test_3packets_04_05_06 {
get {
object obj = ResourceManager.GetObject("test-3packets-04-05-06", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] TransmitChannelConfigurationObject {
get {
object obj = ResourceManager.GetObject("TransmitChannelConfigurationObject", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] UpstreamChannelDescriptorTest {
get {
object obj = ResourceManager.GetObject("UpstreamChannelDescriptorTest", resourceCulture);
return ((byte[])(obj));
}
}
}
}

View File

@ -1,24 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<!--
Microsoft ResX Schema
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ModemCapabilitiesEncodingTest" type="System.Resources.ResXFileRef, System.Windows.Forms">
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="ModemCapabilitiesEncodingTest" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\ModemCapabilitiesEncodingTest.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="MultipartRegistrationResponseTest" type="System.Resources.ResXFileRef, System.Windows.Forms">
@ -57,4 +157,7 @@
<data name="Frame00000012_TSGS1_MIS000_SYNC001" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\Frame00000012_TSGS1_MIS000_SYNC001.bbf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="sdpTest" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\sdpTest.sdp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
</root>

View File

@ -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<NotImplementedException>(() => new RcpIdEncoding(new byte[] { 255, 1, 0 }));
Assert.Throws<NotImplementedException>(() => 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<NotImplementedException>(() => new EthernetLlcPacketClassificationEncoding(new byte[] { 255, 1, 0 }));
Assert.Throws<NotImplementedException>(() => 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<NotImplementedException>(() => new SimplifiedReceiveChannelAssignmentEncoding(new byte[] { 254,0,1 }));
Assert.Throws<NotImplementedException>(() => 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<NotImplementedException>(() =>
Assert.Throws<NotImplementedException>(() =>
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<NotImplementedException>(() => new CommonTlvEncodingObject(ms));
Assert.Throws<NotImplementedException>(() => 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<NotImplementedException>(() => new GeneralPacketClassifierEncoding(new byte[]
Assert.Throws<NotImplementedException>(() => new GeneralPacketClassifierEncoding(new byte[]
{
12, 4,
255, 1, 0, 0
}));
Assert.ThrowsException<NotImplementedException>(() => new GeneralPacketClassifierEncoding(new byte[]
Assert.Throws<NotImplementedException>(() => 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<NotImplementedException>(() =>
Assert.Throws<NotImplementedException>(() =>
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<NotImplementedException>(() => new ServiceFlowSidClusterAssignmentObject(new byte[]
Assert.Throws<NotImplementedException>(() => 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<NotImplementedException>(() => new ServiceFlowSidClusterAssignmentObject.SidClusterEncodingObject(new byte[]
Assert.Throws<NotImplementedException>(() => 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<NotImplementedException>(() =>
Assert.Throws<NotImplementedException>(() =>
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<NotImplementedException>(() =>
Assert.Throws<NotImplementedException>(() =>
new ServiceFlowSidClusterAssignmentObject.SidClusterSwitchoverCriteriaObject(buffer));
}
@ -478,7 +481,7 @@ public class DocsisTests : Feyllure
{
255, 1, 1
};
Assert.ThrowsException<NotImplementedException>(() => new ModemCapabilitiesEncoding(buffer));
Assert.Throws<NotImplementedException>(() => new ModemCapabilitiesEncoding(buffer));
}
[TestMethod]
@ -555,7 +558,7 @@ public class DocsisTests : Feyllure
{
254, 1, 1
};
Assert.ThrowsException<NotImplementedException>(() => new GeneralServiceFlowEncoding(buffer));
Assert.Throws<NotImplementedException>(() => 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<ArgumentNullException>(() => new TestableMacManagementMessage(srcAddr, dstAddr, null));
Assert.Throws<ArgumentNullException>(() => new TestableMacManagementMessage(srcAddr, dstAddr, null));
UntestableMacManagementMessage ummm = new UntestableMacManagementMessage(srcAddr, dstAddr, dataBuffer);
Assert.IsNull(ummm.MessageType);

View File

@ -1,3 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using skyscraper5.Mpeg2;
namespace skyscraper8.Tests.RootTests;

View File

@ -0,0 +1,47 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Target .NET 8 -->
<TargetFramework>net8.0</TargetFramework>
<!-- Mark this as a test project -->
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<!-- MSTest framework -->
<PackageReference Include="Allure.Net.Commons" Version="2.14.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageReference Include="MSTest.TestAdapter" Version="4.0.2" />
<PackageReference Include="MSTest.TestFramework" Version="4.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\skyscraper8\skyscraper8.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Update="Resources1.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources1.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Resources1.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources1.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@ -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

View File

@ -26,11 +26,11 @@
&lt;Assembly Path="/home/schiemas/.nuget/packages/allure.net.commons/2.14.1/lib/netstandard2.0/Allure.Net.Commons.dll" /&gt;
&lt;/AssemblyExplorer&gt;</s:String>
<s:String x:Key="/Default/Environment/Highlighting/HighlightingSourceSnapshotLocation/@EntryValue">/home/schiemas/.cache/JetBrains/Rider2025.1/resharper-host/temp/Rider/vAny/CoverageData/_skyscraper8.1808907683/Snapshot/snapshot.utdcvr</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=92c8346e_002D5416_002D4320_002Dab1d_002D051307b205cd/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="All tests from &amp;lt;skyscraper8.Tests&amp;gt; #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;Project Location="/home/schiemas/RiderProjects/skyscraper8/skyscraper8.Tests" Presentation="&amp;lt;skyscraper8.Tests&amp;gt;" /&gt;
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=92c8346e_002D5416_002D4320_002Dab1d_002D051307b205cd/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="All tests from &amp;lt;skyscraper8.Tests&amp;gt; #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;Project Location="\home\schiemas\RiderProjects\skyscraper8\skyscraper8.Tests" Presentation="&amp;lt;skyscraper8.Tests&amp;gt;" /&gt;&#xD;
&lt;/SessionState&gt;</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=94eea68c_002Dcaa0_002D4657_002Da521_002D7b96c8ead0ec/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &amp;lt;skyscraper8.Tests&amp;gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;Project Location="/home/schiemas/RiderProjects/skyscraper8/skyscraper8.Tests" Presentation="&amp;lt;skyscraper8.Tests&amp;gt;" /&gt;
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=94eea68c_002Dcaa0_002D4657_002Da521_002D7b96c8ead0ec/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &amp;lt;skyscraper8.Tests&amp;gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;Project Location="\home\schiemas\RiderProjects\skyscraper8\skyscraper8.Tests" Presentation="&amp;lt;skyscraper8.Tests&amp;gt;" /&gt;&#xD;
&lt;/SessionState&gt;</s:String>

View File

@ -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);
@ -164,62 +181,90 @@ namespace skyscraper8.DvbNip
}
}
private DateTime? currentTime;
private bool HandleMetadata(FluteListener fluteListener)
{
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("<dvbi-types:", "<");
rawSlepString = rawSlepString.Replace("</dvbi-types:", "</");
rawSlepString = rawSlepString.Replace("<dvbisdt:", "<");
rawSlepString = rawSlepString.Replace("</dvbisdt:", "</");
ServiceListEntryPoints serviceListEntryPoints = DvbIUtils.UnpackServiceListEntryPoints(rawSlepString);
EventHandler?.OnServiceListEntryPoints(CurrentCarrierInformation, serviceListEntryPoints, currentTime.Value, this);
MulticastGatewayConfigurationType multicastGatewayConfiguration2023 = DvbNipUtilities.UnpackMulticastGatewayConfiguration(stream);
EventHandler?.OnMulticastGatewayConfiguration(CurrentCarrierInformation, multicastGatewayConfiguration2023);
return true;
}
else if (DvbNipUtilities.IsMime(stream))
{
stream = DvbNipUtilities.GetFirstMimeBodyPart(stream);
if (SDP.IsSDP(stream))
{
SDP loadedSdp = SDP.Load(stream);
MulticastGatewayConfigurationType convertedSdp = loadedSdp.ToMulticastGatewayConfiguration();
EventHandler?.OnMulticastGatewayConfiguration(CurrentCarrierInformation, convertedSdp);
return true;
}
else
{
stream.DumpToFile("container2.bin");
logger.WarnFormat("Failed to detect the Metadata format of the Native IP Multicast Transport Object.");
return false;
}
}
else
{
logger.WarnFormat("Failed to detect the Metadata format of the Native IP Multicast Transport Object.");
return false;
}
break;
case "urn:dvb:metadata:nativeip:TimeOffsetFile":
TimeOffsetFileType timeOffsetFile = DvbNipUtilities.UnpackTimeOffsetFile(fluteListener.ToStream());
EventHandler?.OnTimeOffsetFile(CurrentCarrierInformation, timeOffsetFile);
return true;
case "urn:dvb:metadata:nativeip:NetworkInformationFile":
NetworkInformationFileType networkInformationFile = DvbNipUtilities.UnpackNetworkInformationFile(fluteListener.ToStream());
EventHandler?.OnNetworkInformationFile(CurrentCarrierInformation, networkInformationFile);
return true;
case "urn:dvb:metadata:nativeip:ServiceInformationFile":
ServiceInformationFileType serviceInformationFile = DvbNipUtilities.UnpackServiceInformationFile(fluteListener.ToStream());
EventHandler?.OnServiceInformationFile(CurrentCarrierInformation, serviceInformationFile);
return true;
case "urn:dvb:metadata:nativeip:ServiceGuide":
//Unfortunately, the NIPServiceGuideManifest does not contain any useful information at all, which is why we ignore it.
//There doesn't seem to be a way to get the actual EIT XML from it.
return true;
default:
throw new NotImplementedException(fluteListener.FileAssociation.ContentLocation);
}
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 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("<dvbi-types:", "<");
rawSlepString = rawSlepString.Replace("</dvbi-types:", "</");
rawSlepString = rawSlepString.Replace("<dvbisdt:", "<");
rawSlepString = rawSlepString.Replace("</dvbisdt:", "</");
ServiceListEntryPoints serviceListEntryPoints = DvbIUtils.UnpackServiceListEntryPoints(rawSlepString);
EventHandler?.OnServiceListEntryPoints(CurrentCarrierInformation, serviceListEntryPoints, currentTime.Value, this);
return true;
}
else
{
return false;
}
break;
case "urn:dvb:metadata:nativeip:TimeOffsetFile":
TimeOffsetFileType timeOffsetFile = DvbNipUtilities.UnpackTimeOffsetFile(fluteListener.ToStream());
EventHandler?.OnTimeOffsetFile(CurrentCarrierInformation, timeOffsetFile);
return true;
case "urn:dvb:metadata:nativeip:NetworkInformationFile":
NetworkInformationFileType networkInformationFile = DvbNipUtilities.UnpackNetworkInformationFile(fluteListener.ToStream());
EventHandler?.OnNetworkInformationFile(CurrentCarrierInformation, networkInformationFile);
return true;
case "urn:dvb:metadata:nativeip:ServiceInformationFile":
ServiceInformationFileType serviceInformationFile = DvbNipUtilities.UnpackServiceInformationFile(fluteListener.ToStream());
EventHandler?.OnServiceInformationFile(CurrentCarrierInformation, serviceInformationFile);
return true;
case "urn:dvb:metadata:nativeip:ServiceGuide":
//Unfortunately, the NIPServiceGuideManifest does not contain any useful information at all, which is why we ignore it.
//There doesn't seem to be a way to get the actual EIT XML from it.
return true;
default:
throw new NotImplementedException(fluteListener.FileAssociation.ContentLocation);
}
}
private void TryPruneCache()
{

View File

@ -1,9 +1,12 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using MimeKit;
using skyscraper5.Skyscraper.IO;
using skyscraper8.Ietf.FLUTE;
namespace skyscraper8.DvbNip
@ -14,6 +17,57 @@ namespace skyscraper8.DvbNip
private static XmlSerializer multicastGatewayConfigurationXmlSerializer;
public static bool IsXml(Stream s)
{
byte byteA = s.ReadUInt8();
byte byteB = s.ReadUInt8();
byte byteC = s.ReadUInt8();
byte byteD = s.ReadUInt8();
byte byteE = s.ReadUInt8();
byte byteF = s.ReadUInt8();
s.Position -= 6;
if (byteA != '<')
return false;
if (byteB != '?')
return false;
if (byteC != 'x')
return false;
if (byteD != 'm')
return false;
if (byteE != 'l')
return false;
if (byteF != ' ')
return false;
return true;
}
private static readonly byte[] MimeVersionMagic = new byte[]
{
0x4D, 0x49, 0x4D, 0x45, 0x2D, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3A, 0x20
};
public static bool IsMime(Stream s)
{
if (s.GetAvailableBytes() <= MimeVersionMagic.Length)
{
return false;
}
byte[] buffer = new byte[MimeVersionMagic.Length];
int bufferReadResult = s.Read(buffer, 0, buffer.Length);
bool isMime = Enumerable.SequenceEqual(buffer, MimeVersionMagic);
s.Position -= bufferReadResult;
return isMime;
}
public static MulticastGatewayConfigurationType UnpackMulticastGatewayConfiguration(Stream stream)
{
if (multicastGatewayConfigurationXmlSerializer == null)
@ -120,6 +174,10 @@ namespace skyscraper8.DvbNip
{
bufferString = bufferString.Replace("urn:dvb:metadata:nativeip:2023", "urn:dvb:metadata:nativeip:2024");
}
else if (bufferString.Contains("urn:dvb:metadata:nativeip:2022"))
{
bufferString = bufferString.Replace("urn:dvb:metadata:nativeip:2022", "urn:dvb:metadata:nativeip:2024");
}
object v = networkInformationFileXmlSerializer.Deserialize(new StringReader(bufferString));
NetworkInformationFileType result = (NetworkInformationFileType)v;
@ -141,10 +199,31 @@ namespace skyscraper8.DvbNip
{
bufferString = bufferString.Replace("urn:dvb:metadata:nativeip:2023", "urn:dvb:metadata:nativeip:2024");
}
else if (bufferString.Contains("urn:dvb:metadata:nativeip:2022"))
{
bufferString = bufferString.Replace("urn:dvb:metadata:nativeip:2022", "urn:dvb:metadata:nativeip:2024");
}
object v = serviceInformationFileXmlSerializer.Deserialize(new StringReader(bufferString));
ServiceInformationFileType result = (ServiceInformationFileType)v;
return result;
}
public static Stream GetFirstMimeBodyPart(Stream stream)
{
MimeMessage message = MimeMessage.Load(stream);
foreach (MimeEntity bodyPart in message.BodyParts)
{
MimePart part = bodyPart as MimePart;
if (part.ContentType.MimeType.Equals("application/mbms-envelope+xml"))
continue;
if (part.ContentType.MimeType.Equals("application/mbms-user-service-description+xml"))
continue;
if (part.ContentType.MimeType.Equals("application/mbms-schedule+xml"))
continue;
return part.Content.Stream;
}
throw new NotImplementedException();
}
}
}

View File

@ -21,6 +21,15 @@ namespace skyscraper8.DvbNip
NipStreamProviderName = Encoding.UTF8.GetString(ms.ReadBytes(length));
}
public NipActualCarrierInformation(ushort nipNetworkId, ushort nipCarrierId, ushort nipLinkId, ushort nipServiceId, string nipStreamProviderName)
{
NipNetworkId = nipNetworkId;
NipCarrierId = nipCarrierId;
NipLinkId = nipLinkId;
NipServiceId = nipServiceId;
NipStreamProviderName = nipStreamProviderName;
}
public ushort NipNetworkId { get; }
public ushort NipCarrierId { get; }
public ushort NipLinkId { get; }

View File

@ -47,7 +47,7 @@ public class Pts2Bbf2 : IBbframeDeencapsulator
if (!bbHeader.Valid)
return;
string fname = String.Format("Frame{0:D8}_TSGS{1}_MIS{2:D3}_SYNC{3:D3}.ts", ++frameNo,bbHeader.TsGs,bbHeader.SisMis ? bbHeader.Matype2 : 0,bbHeader.SyncByte);
string fname = String.Format("Frame{0:D8}_TSGS{1}_MIS{2:D3}_SYNC{3:D3}.bbframe", ++frameNo,bbHeader.TsGs,bbHeader.SisMis ? bbHeader.Matype2 : 0,bbHeader.SyncByte);
string outfname = Path.Combine(outputDir.FullName, fname);
ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(bbframe, 11, bbframe.Length - 11);

View File

@ -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)
{
}
}
}

View File

@ -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
@ -148,7 +149,7 @@ namespace skyscraper8.Ietf.FLUTE
}
}
public Stream ToStream()
public virtual Stream ToStream()
{
if (!IsComplete())
throw new InvalidOperationException();

View File

@ -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");
}
}
}
}

View File

@ -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;
}
}
}

View File

@ -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<SdpMedia>();
result._mediaAnnouncements.Add(new SdpMedia(args.Split(' ')));
break;
case 'c':
if (result._connections == null)
result._connections = new List<SdpConnectionData>();
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<SdpMedia> _mediaAnnouncements;
private List<SdpConnectionData> _connections;
public IReadOnlyList<SdpConnectionData> ConnectionData
{
get
{
return _connections.AsReadOnly();
}
}
public IReadOnlyList<SdpMedia> 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;
}
}
}

View File

@ -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
}
}

View File

@ -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<SdpAttribute>
{
private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
private Dictionary<string, SdpAttribute> _attributes;
internal void SetHint(string args)
{
if (_attributes == null)
_attributes = new Dictionary<string, SdpAttribute>();
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<SdpAttribute> 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<SourceFilterChainLink>();
_filterChain.Add(new SourceFilterChainLink(value.Split(' ',StringSplitOptions.RemoveEmptyEntries)));
}
private List<SourceFilterChainLink> _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);
}
/// <summary>
/// If this is true, an incoming packet is accepted, if not it gets discarded.
/// </summary>
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; }
}
}

View File

@ -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;
}
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}
}
}

View File

@ -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();

View File

@ -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)": {

View File

@ -19,5 +19,7 @@ namespace skyscraper5.Skyscraper
{
return ToUnixTime(dt) * 1000;
}
}
}

View File

@ -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();
}
}
}

View File

@ -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
{
/// <summary>
///
/// </summary>
/// <param name="l"></param>
/// <remarks>stolen from https://stackoverflow.com/a/250400</remarks>
/// <returns></returns>
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;
}
/// <summary>
///
/// </summary>
/// <param name="l"></param>
/// <remarks>stolen from https://stackoverflow.com/a/250400</remarks>
/// <returns></returns>
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;
}
}
}

View File

@ -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

View File

@ -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<int> encodings;
public override Encoding? GetEncoding(int codepage)
{
if (codepage == 1200)
return null;
if (encodings == null)
encodings = new List<int>();
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)

View File

@ -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()
{

View File

@ -25,6 +25,7 @@
<ItemGroup>
<PackageReference Include="Ionic.Zlib.Core" Version="1.0.0" />
<PackageReference Include="log4net" Version="3.1.0" />
<PackageReference Include="MimeKitLite" Version="4.14.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>